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 }; 60 61 /// Stack for tracking declarations used in OpenMP directives and 62 /// clauses and their data-sharing attributes. 63 class DSAStackTy { 64 public: 65 struct DSAVarData { 66 OpenMPDirectiveKind DKind = OMPD_unknown; 67 OpenMPClauseKind CKind = OMPC_unknown; 68 unsigned Modifier = 0; 69 const Expr *RefExpr = nullptr; 70 DeclRefExpr *PrivateCopy = nullptr; 71 SourceLocation ImplicitDSALoc; 72 DSAVarData() = default; 73 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 74 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 75 SourceLocation ImplicitDSALoc, unsigned Modifier) 76 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), 77 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 78 }; 79 using OperatorOffsetTy = 80 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 81 using DoacrossDependMapTy = 82 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 83 /// Kind of the declaration used in the uses_allocators clauses. 84 enum class UsesAllocatorsDeclKind { 85 /// Predefined allocator 86 PredefinedAllocator, 87 /// User-defined allocator 88 UserDefinedAllocator, 89 /// The declaration that represent allocator trait 90 AllocatorTrait, 91 }; 92 93 private: 94 struct DSAInfo { 95 OpenMPClauseKind Attributes = OMPC_unknown; 96 unsigned Modifier = 0; 97 /// Pointer to a reference expression and a flag which shows that the 98 /// variable is marked as lastprivate(true) or not (false). 99 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 100 DeclRefExpr *PrivateCopy = nullptr; 101 }; 102 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 103 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 104 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 105 using LoopControlVariablesMapTy = 106 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 107 /// Struct that associates a component with the clause kind where they are 108 /// found. 109 struct MappedExprComponentTy { 110 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 111 OpenMPClauseKind Kind = OMPC_unknown; 112 }; 113 using MappedExprComponentsTy = 114 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 115 using CriticalsWithHintsTy = 116 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 117 struct ReductionData { 118 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 119 SourceRange ReductionRange; 120 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 121 ReductionData() = default; 122 void set(BinaryOperatorKind BO, SourceRange RR) { 123 ReductionRange = RR; 124 ReductionOp = BO; 125 } 126 void set(const Expr *RefExpr, SourceRange RR) { 127 ReductionRange = RR; 128 ReductionOp = RefExpr; 129 } 130 }; 131 using DeclReductionMapTy = 132 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 133 struct DefaultmapInfo { 134 OpenMPDefaultmapClauseModifier ImplicitBehavior = 135 OMPC_DEFAULTMAP_MODIFIER_unknown; 136 SourceLocation SLoc; 137 DefaultmapInfo() = default; 138 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 139 : ImplicitBehavior(M), SLoc(Loc) {} 140 }; 141 142 struct SharingMapTy { 143 DeclSAMapTy SharingMap; 144 DeclReductionMapTy ReductionMap; 145 UsedRefMapTy AlignedMap; 146 UsedRefMapTy NontemporalMap; 147 MappedExprComponentsTy MappedExprComponents; 148 LoopControlVariablesMapTy LCVMap; 149 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 150 SourceLocation DefaultAttrLoc; 151 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 152 OpenMPDirectiveKind Directive = OMPD_unknown; 153 DeclarationNameInfo DirectiveName; 154 Scope *CurScope = nullptr; 155 SourceLocation ConstructLoc; 156 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 157 /// get the data (loop counters etc.) about enclosing loop-based construct. 158 /// This data is required during codegen. 159 DoacrossDependMapTy DoacrossDepends; 160 /// First argument (Expr *) contains optional argument of the 161 /// 'ordered' clause, the second one is true if the regions has 'ordered' 162 /// clause, false otherwise. 163 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 164 unsigned AssociatedLoops = 1; 165 bool HasMutipleLoops = false; 166 const Decl *PossiblyLoopCounter = nullptr; 167 bool NowaitRegion = false; 168 bool CancelRegion = false; 169 bool LoopStart = false; 170 bool BodyComplete = false; 171 SourceLocation PrevScanLocation; 172 SourceLocation InnerTeamsRegionLoc; 173 /// Reference to the taskgroup task_reduction reference expression. 174 Expr *TaskgroupReductionRef = nullptr; 175 llvm::DenseSet<QualType> MappedClassesQualTypes; 176 SmallVector<Expr *, 4> InnerUsedAllocators; 177 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; 178 /// List of globals marked as declare target link in this target region 179 /// (isOpenMPTargetExecutionDirective(Directive) == true). 180 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 181 /// List of decls used in inclusive/exclusive clauses of the scan directive. 182 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; 183 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind> 184 UsesAllocatorsDecls; 185 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 186 Scope *CurScope, SourceLocation Loc) 187 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 188 ConstructLoc(Loc) {} 189 SharingMapTy() = default; 190 }; 191 192 using StackTy = SmallVector<SharingMapTy, 4>; 193 194 /// Stack of used declaration and their data-sharing attributes. 195 DeclSAMapTy Threadprivates; 196 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 197 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 198 /// true, if check for DSA must be from parent directive, false, if 199 /// from current directive. 200 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 201 Sema &SemaRef; 202 bool ForceCapturing = false; 203 /// true if all the variables in the target executable directives must be 204 /// captured by reference. 205 bool ForceCaptureByReferenceInTargetExecutable = false; 206 CriticalsWithHintsTy Criticals; 207 unsigned IgnoredStackElements = 0; 208 209 /// Iterators over the stack iterate in order from innermost to outermost 210 /// directive. 211 using const_iterator = StackTy::const_reverse_iterator; 212 const_iterator begin() const { 213 return Stack.empty() ? const_iterator() 214 : Stack.back().first.rbegin() + IgnoredStackElements; 215 } 216 const_iterator end() const { 217 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 218 } 219 using iterator = StackTy::reverse_iterator; 220 iterator begin() { 221 return Stack.empty() ? iterator() 222 : Stack.back().first.rbegin() + IgnoredStackElements; 223 } 224 iterator end() { 225 return Stack.empty() ? iterator() : Stack.back().first.rend(); 226 } 227 228 // Convenience operations to get at the elements of the stack. 229 230 bool isStackEmpty() const { 231 return Stack.empty() || 232 Stack.back().second != CurrentNonCapturingFunctionScope || 233 Stack.back().first.size() <= IgnoredStackElements; 234 } 235 size_t getStackSize() const { 236 return isStackEmpty() ? 0 237 : Stack.back().first.size() - IgnoredStackElements; 238 } 239 240 SharingMapTy *getTopOfStackOrNull() { 241 size_t Size = getStackSize(); 242 if (Size == 0) 243 return nullptr; 244 return &Stack.back().first[Size - 1]; 245 } 246 const SharingMapTy *getTopOfStackOrNull() const { 247 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 248 } 249 SharingMapTy &getTopOfStack() { 250 assert(!isStackEmpty() && "no current directive"); 251 return *getTopOfStackOrNull(); 252 } 253 const SharingMapTy &getTopOfStack() const { 254 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 255 } 256 257 SharingMapTy *getSecondOnStackOrNull() { 258 size_t Size = getStackSize(); 259 if (Size <= 1) 260 return nullptr; 261 return &Stack.back().first[Size - 2]; 262 } 263 const SharingMapTy *getSecondOnStackOrNull() const { 264 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 265 } 266 267 /// Get the stack element at a certain level (previously returned by 268 /// \c getNestingLevel). 269 /// 270 /// Note that nesting levels count from outermost to innermost, and this is 271 /// the reverse of our iteration order where new inner levels are pushed at 272 /// the front of the stack. 273 SharingMapTy &getStackElemAtLevel(unsigned Level) { 274 assert(Level < getStackSize() && "no such stack element"); 275 return Stack.back().first[Level]; 276 } 277 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 278 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 279 } 280 281 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 282 283 /// Checks if the variable is a local for OpenMP region. 284 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 285 286 /// Vector of previously declared requires directives 287 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 288 /// omp_allocator_handle_t type. 289 QualType OMPAllocatorHandleT; 290 /// omp_depend_t type. 291 QualType OMPDependT; 292 /// omp_event_handle_t type. 293 QualType OMPEventHandleT; 294 /// omp_alloctrait_t type. 295 QualType OMPAlloctraitT; 296 /// Expression for the predefined allocators. 297 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 298 nullptr}; 299 /// Vector of previously encountered target directives 300 SmallVector<SourceLocation, 2> TargetLocations; 301 SourceLocation AtomicLocation; 302 303 public: 304 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 305 306 /// Sets omp_allocator_handle_t type. 307 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 308 /// Gets omp_allocator_handle_t type. 309 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 310 /// Sets omp_alloctrait_t type. 311 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; } 312 /// Gets omp_alloctrait_t type. 313 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; } 314 /// Sets the given default allocator. 315 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 316 Expr *Allocator) { 317 OMPPredefinedAllocators[AllocatorKind] = Allocator; 318 } 319 /// Returns the specified default allocator. 320 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 321 return OMPPredefinedAllocators[AllocatorKind]; 322 } 323 /// Sets omp_depend_t type. 324 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 325 /// Gets omp_depend_t type. 326 QualType getOMPDependT() const { return OMPDependT; } 327 328 /// Sets omp_event_handle_t type. 329 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } 330 /// Gets omp_event_handle_t type. 331 QualType getOMPEventHandleT() const { return OMPEventHandleT; } 332 333 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 334 OpenMPClauseKind getClauseParsingMode() const { 335 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 336 return ClauseKindMode; 337 } 338 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 339 340 bool isBodyComplete() const { 341 const SharingMapTy *Top = getTopOfStackOrNull(); 342 return Top && Top->BodyComplete; 343 } 344 void setBodyComplete() { 345 getTopOfStack().BodyComplete = true; 346 } 347 348 bool isForceVarCapturing() const { return ForceCapturing; } 349 void setForceVarCapturing(bool V) { ForceCapturing = V; } 350 351 void setForceCaptureByReferenceInTargetExecutable(bool V) { 352 ForceCaptureByReferenceInTargetExecutable = V; 353 } 354 bool isForceCaptureByReferenceInTargetExecutable() const { 355 return ForceCaptureByReferenceInTargetExecutable; 356 } 357 358 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 359 Scope *CurScope, SourceLocation Loc) { 360 assert(!IgnoredStackElements && 361 "cannot change stack while ignoring elements"); 362 if (Stack.empty() || 363 Stack.back().second != CurrentNonCapturingFunctionScope) 364 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 365 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 366 Stack.back().first.back().DefaultAttrLoc = Loc; 367 } 368 369 void pop() { 370 assert(!IgnoredStackElements && 371 "cannot change stack while ignoring elements"); 372 assert(!Stack.back().first.empty() && 373 "Data-sharing attributes stack is empty!"); 374 Stack.back().first.pop_back(); 375 } 376 377 /// RAII object to temporarily leave the scope of a directive when we want to 378 /// logically operate in its parent. 379 class ParentDirectiveScope { 380 DSAStackTy &Self; 381 bool Active; 382 public: 383 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 384 : Self(Self), Active(false) { 385 if (Activate) 386 enable(); 387 } 388 ~ParentDirectiveScope() { disable(); } 389 void disable() { 390 if (Active) { 391 --Self.IgnoredStackElements; 392 Active = false; 393 } 394 } 395 void enable() { 396 if (!Active) { 397 ++Self.IgnoredStackElements; 398 Active = true; 399 } 400 } 401 }; 402 403 /// Marks that we're started loop parsing. 404 void loopInit() { 405 assert(isOpenMPLoopDirective(getCurrentDirective()) && 406 "Expected loop-based directive."); 407 getTopOfStack().LoopStart = true; 408 } 409 /// Start capturing of the variables in the loop context. 410 void loopStart() { 411 assert(isOpenMPLoopDirective(getCurrentDirective()) && 412 "Expected loop-based directive."); 413 getTopOfStack().LoopStart = false; 414 } 415 /// true, if variables are captured, false otherwise. 416 bool isLoopStarted() const { 417 assert(isOpenMPLoopDirective(getCurrentDirective()) && 418 "Expected loop-based directive."); 419 return !getTopOfStack().LoopStart; 420 } 421 /// Marks (or clears) declaration as possibly loop counter. 422 void resetPossibleLoopCounter(const Decl *D = nullptr) { 423 getTopOfStack().PossiblyLoopCounter = 424 D ? D->getCanonicalDecl() : D; 425 } 426 /// Gets the possible loop counter decl. 427 const Decl *getPossiblyLoopCunter() const { 428 return getTopOfStack().PossiblyLoopCounter; 429 } 430 /// Start new OpenMP region stack in new non-capturing function. 431 void pushFunction() { 432 assert(!IgnoredStackElements && 433 "cannot change stack while ignoring elements"); 434 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 435 assert(!isa<CapturingScopeInfo>(CurFnScope)); 436 CurrentNonCapturingFunctionScope = CurFnScope; 437 } 438 /// Pop region stack for non-capturing function. 439 void popFunction(const FunctionScopeInfo *OldFSI) { 440 assert(!IgnoredStackElements && 441 "cannot change stack while ignoring elements"); 442 if (!Stack.empty() && Stack.back().second == OldFSI) { 443 assert(Stack.back().first.empty()); 444 Stack.pop_back(); 445 } 446 CurrentNonCapturingFunctionScope = nullptr; 447 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 448 if (!isa<CapturingScopeInfo>(FSI)) { 449 CurrentNonCapturingFunctionScope = FSI; 450 break; 451 } 452 } 453 } 454 455 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 456 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 457 } 458 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 459 getCriticalWithHint(const DeclarationNameInfo &Name) const { 460 auto I = Criticals.find(Name.getAsString()); 461 if (I != Criticals.end()) 462 return I->second; 463 return std::make_pair(nullptr, llvm::APSInt()); 464 } 465 /// If 'aligned' declaration for given variable \a D was not seen yet, 466 /// add it and return NULL; otherwise return previous occurrence's expression 467 /// for diagnostics. 468 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 469 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 470 /// add it and return NULL; otherwise return previous occurrence's expression 471 /// for diagnostics. 472 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 473 474 /// Register specified variable as loop control variable. 475 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 476 /// Check if the specified variable is a loop control variable for 477 /// current region. 478 /// \return The index of the loop control variable in the list of associated 479 /// for-loops (from outer to inner). 480 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 481 /// Check if the specified variable is a loop control variable for 482 /// parent region. 483 /// \return The index of the loop control variable in the list of associated 484 /// for-loops (from outer to inner). 485 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 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, 491 unsigned Level) const; 492 /// Get the loop control variable for the I-th loop (or nullptr) in 493 /// parent directive. 494 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 495 496 /// Marks the specified decl \p D as used in scan directive. 497 void markDeclAsUsedInScanDirective(ValueDecl *D) { 498 if (SharingMapTy *Stack = getSecondOnStackOrNull()) 499 Stack->UsedInScanDirective.insert(D); 500 } 501 502 /// Checks if the specified declaration was used in the inner scan directive. 503 bool isUsedInScanDirective(ValueDecl *D) const { 504 if (const SharingMapTy *Stack = getTopOfStackOrNull()) 505 return Stack->UsedInScanDirective.count(D) > 0; 506 return false; 507 } 508 509 /// Adds explicit data sharing attribute to the specified declaration. 510 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 511 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0); 512 513 /// Adds additional information for the reduction items with the reduction id 514 /// represented as an operator. 515 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 516 BinaryOperatorKind BOK); 517 /// Adds additional information for the reduction items with the reduction id 518 /// represented as reduction identifier. 519 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 520 const Expr *ReductionRef); 521 /// Returns the location and reduction operation from the innermost parent 522 /// region for the given \p D. 523 const DSAVarData 524 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 525 BinaryOperatorKind &BOK, 526 Expr *&TaskgroupDescriptor) const; 527 /// Returns the location and reduction operation from the innermost parent 528 /// region for the given \p D. 529 const DSAVarData 530 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 531 const Expr *&ReductionRef, 532 Expr *&TaskgroupDescriptor) const; 533 /// Return reduction reference expression for the current taskgroup or 534 /// parallel/worksharing directives with task reductions. 535 Expr *getTaskgroupReductionRef() const { 536 assert((getTopOfStack().Directive == OMPD_taskgroup || 537 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 538 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 539 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 540 "taskgroup reference expression requested for non taskgroup or " 541 "parallel/worksharing directive."); 542 return getTopOfStack().TaskgroupReductionRef; 543 } 544 /// Checks if the given \p VD declaration is actually a taskgroup reduction 545 /// descriptor variable at the \p Level of OpenMP regions. 546 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 547 return getStackElemAtLevel(Level).TaskgroupReductionRef && 548 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 549 ->getDecl() == VD; 550 } 551 552 /// Returns data sharing attributes from top of the stack for the 553 /// specified declaration. 554 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 555 /// Returns data-sharing attributes for the specified declaration. 556 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 557 /// Returns data-sharing attributes for the specified declaration. 558 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; 559 /// Checks if the specified variables has data-sharing attributes which 560 /// match specified \a CPred predicate in any directive which matches \a DPred 561 /// predicate. 562 const DSAVarData 563 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 564 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 565 bool FromParent) const; 566 /// Checks if the specified variables has data-sharing attributes which 567 /// match specified \a CPred predicate in any innermost directive which 568 /// matches \a DPred predicate. 569 const DSAVarData 570 hasInnermostDSA(ValueDecl *D, 571 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 572 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 573 bool FromParent) const; 574 /// Checks if the specified variables has explicit data-sharing 575 /// attributes which match specified \a CPred predicate at the specified 576 /// OpenMP region. 577 bool hasExplicitDSA(const ValueDecl *D, 578 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 579 unsigned Level, bool NotLastprivate = false) const; 580 581 /// Returns true if the directive at level \Level matches in the 582 /// specified \a DPred predicate. 583 bool hasExplicitDirective( 584 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 585 unsigned Level) const; 586 587 /// Finds a directive which matches specified \a DPred predicate. 588 bool hasDirective( 589 const llvm::function_ref<bool( 590 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 591 DPred, 592 bool FromParent) const; 593 594 /// Returns currently analyzed directive. 595 OpenMPDirectiveKind getCurrentDirective() const { 596 const SharingMapTy *Top = getTopOfStackOrNull(); 597 return Top ? Top->Directive : OMPD_unknown; 598 } 599 /// Returns directive kind at specified level. 600 OpenMPDirectiveKind getDirective(unsigned Level) const { 601 assert(!isStackEmpty() && "No directive at specified level."); 602 return getStackElemAtLevel(Level).Directive; 603 } 604 /// Returns the capture region at the specified level. 605 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 606 unsigned OpenMPCaptureLevel) const { 607 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 608 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 609 return CaptureRegions[OpenMPCaptureLevel]; 610 } 611 /// Returns parent directive. 612 OpenMPDirectiveKind getParentDirective() const { 613 const SharingMapTy *Parent = getSecondOnStackOrNull(); 614 return Parent ? Parent->Directive : OMPD_unknown; 615 } 616 617 /// Add requires decl to internal vector 618 void addRequiresDecl(OMPRequiresDecl *RD) { 619 RequiresDecls.push_back(RD); 620 } 621 622 /// Checks if the defined 'requires' directive has specified type of clause. 623 template <typename ClauseType> 624 bool hasRequiresDeclWithClause() const { 625 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 626 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 627 return isa<ClauseType>(C); 628 }); 629 }); 630 } 631 632 /// Checks for a duplicate clause amongst previously declared requires 633 /// directives 634 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 635 bool IsDuplicate = false; 636 for (OMPClause *CNew : ClauseList) { 637 for (const OMPRequiresDecl *D : RequiresDecls) { 638 for (const OMPClause *CPrev : D->clauselists()) { 639 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 640 SemaRef.Diag(CNew->getBeginLoc(), 641 diag::err_omp_requires_clause_redeclaration) 642 << getOpenMPClauseName(CNew->getClauseKind()); 643 SemaRef.Diag(CPrev->getBeginLoc(), 644 diag::note_omp_requires_previous_clause) 645 << getOpenMPClauseName(CPrev->getClauseKind()); 646 IsDuplicate = true; 647 } 648 } 649 } 650 } 651 return IsDuplicate; 652 } 653 654 /// Add location of previously encountered target to internal vector 655 void addTargetDirLocation(SourceLocation LocStart) { 656 TargetLocations.push_back(LocStart); 657 } 658 659 /// Add location for the first encountered atomicc directive. 660 void addAtomicDirectiveLoc(SourceLocation Loc) { 661 if (AtomicLocation.isInvalid()) 662 AtomicLocation = Loc; 663 } 664 665 /// Returns the location of the first encountered atomic directive in the 666 /// module. 667 SourceLocation getAtomicDirectiveLoc() const { 668 return AtomicLocation; 669 } 670 671 // Return previously encountered target region locations. 672 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 673 return TargetLocations; 674 } 675 676 /// Set default data sharing attribute to none. 677 void setDefaultDSANone(SourceLocation Loc) { 678 getTopOfStack().DefaultAttr = DSA_none; 679 getTopOfStack().DefaultAttrLoc = Loc; 680 } 681 /// Set default data sharing attribute to shared. 682 void setDefaultDSAShared(SourceLocation Loc) { 683 getTopOfStack().DefaultAttr = DSA_shared; 684 getTopOfStack().DefaultAttrLoc = Loc; 685 } 686 /// Set default data mapping attribute to Modifier:Kind 687 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 688 OpenMPDefaultmapClauseKind Kind, 689 SourceLocation Loc) { 690 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 691 DMI.ImplicitBehavior = M; 692 DMI.SLoc = Loc; 693 } 694 /// Check whether the implicit-behavior has been set in defaultmap 695 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 696 if (VariableCategory == OMPC_DEFAULTMAP_unknown) 697 return getTopOfStack() 698 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] 699 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 700 getTopOfStack() 701 .DefaultmapMap[OMPC_DEFAULTMAP_scalar] 702 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 703 getTopOfStack() 704 .DefaultmapMap[OMPC_DEFAULTMAP_pointer] 705 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; 706 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 707 OMPC_DEFAULTMAP_MODIFIER_unknown; 708 } 709 710 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { 711 return getStackSize() <= Level ? DSA_unspecified 712 : getStackElemAtLevel(Level).DefaultAttr; 713 } 714 DefaultDataSharingAttributes getDefaultDSA() const { 715 return isStackEmpty() ? DSA_unspecified 716 : getTopOfStack().DefaultAttr; 717 } 718 SourceLocation getDefaultDSALocation() const { 719 return isStackEmpty() ? SourceLocation() 720 : getTopOfStack().DefaultAttrLoc; 721 } 722 OpenMPDefaultmapClauseModifier 723 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 724 return isStackEmpty() 725 ? OMPC_DEFAULTMAP_MODIFIER_unknown 726 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 727 } 728 OpenMPDefaultmapClauseModifier 729 getDefaultmapModifierAtLevel(unsigned Level, 730 OpenMPDefaultmapClauseKind Kind) const { 731 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 732 } 733 bool isDefaultmapCapturedByRef(unsigned Level, 734 OpenMPDefaultmapClauseKind Kind) const { 735 OpenMPDefaultmapClauseModifier M = 736 getDefaultmapModifierAtLevel(Level, Kind); 737 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 738 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 739 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 740 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 741 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 742 } 743 return true; 744 } 745 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 746 OpenMPDefaultmapClauseKind Kind) { 747 switch (Kind) { 748 case OMPC_DEFAULTMAP_scalar: 749 case OMPC_DEFAULTMAP_pointer: 750 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 751 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 752 (M == OMPC_DEFAULTMAP_MODIFIER_default); 753 case OMPC_DEFAULTMAP_aggregate: 754 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 755 default: 756 break; 757 } 758 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 759 } 760 bool mustBeFirstprivateAtLevel(unsigned Level, 761 OpenMPDefaultmapClauseKind Kind) const { 762 OpenMPDefaultmapClauseModifier M = 763 getDefaultmapModifierAtLevel(Level, Kind); 764 return mustBeFirstprivateBase(M, Kind); 765 } 766 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 767 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 768 return mustBeFirstprivateBase(M, Kind); 769 } 770 771 /// Checks if the specified variable is a threadprivate. 772 bool isThreadPrivate(VarDecl *D) { 773 const DSAVarData DVar = getTopDSA(D, false); 774 return isOpenMPThreadPrivate(DVar.CKind); 775 } 776 777 /// Marks current region as ordered (it has an 'ordered' clause). 778 void setOrderedRegion(bool IsOrdered, const Expr *Param, 779 OMPOrderedClause *Clause) { 780 if (IsOrdered) 781 getTopOfStack().OrderedRegion.emplace(Param, Clause); 782 else 783 getTopOfStack().OrderedRegion.reset(); 784 } 785 /// Returns true, if region is ordered (has associated 'ordered' clause), 786 /// false - otherwise. 787 bool isOrderedRegion() const { 788 if (const SharingMapTy *Top = getTopOfStackOrNull()) 789 return Top->OrderedRegion.hasValue(); 790 return false; 791 } 792 /// Returns optional parameter for the ordered region. 793 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 794 if (const SharingMapTy *Top = getTopOfStackOrNull()) 795 if (Top->OrderedRegion.hasValue()) 796 return Top->OrderedRegion.getValue(); 797 return std::make_pair(nullptr, nullptr); 798 } 799 /// Returns true, if parent region is ordered (has associated 800 /// 'ordered' clause), false - otherwise. 801 bool isParentOrderedRegion() const { 802 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 803 return Parent->OrderedRegion.hasValue(); 804 return false; 805 } 806 /// Returns optional parameter for the ordered region. 807 std::pair<const Expr *, OMPOrderedClause *> 808 getParentOrderedRegionParam() const { 809 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 810 if (Parent->OrderedRegion.hasValue()) 811 return Parent->OrderedRegion.getValue(); 812 return std::make_pair(nullptr, nullptr); 813 } 814 /// Marks current region as nowait (it has a 'nowait' clause). 815 void setNowaitRegion(bool IsNowait = true) { 816 getTopOfStack().NowaitRegion = IsNowait; 817 } 818 /// Returns true, if parent region is nowait (has associated 819 /// 'nowait' clause), false - otherwise. 820 bool isParentNowaitRegion() const { 821 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 822 return Parent->NowaitRegion; 823 return false; 824 } 825 /// Marks parent region as cancel region. 826 void setParentCancelRegion(bool Cancel = true) { 827 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 828 Parent->CancelRegion |= Cancel; 829 } 830 /// Return true if current region has inner cancel construct. 831 bool isCancelRegion() const { 832 const SharingMapTy *Top = getTopOfStackOrNull(); 833 return Top ? Top->CancelRegion : false; 834 } 835 836 /// Mark that parent region already has scan directive. 837 void setParentHasScanDirective(SourceLocation Loc) { 838 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 839 Parent->PrevScanLocation = Loc; 840 } 841 /// Return true if current region has inner cancel construct. 842 bool doesParentHasScanDirective() const { 843 const SharingMapTy *Top = getSecondOnStackOrNull(); 844 return Top ? Top->PrevScanLocation.isValid() : false; 845 } 846 /// Return true if current region has inner cancel construct. 847 SourceLocation getParentScanDirectiveLoc() const { 848 const SharingMapTy *Top = getSecondOnStackOrNull(); 849 return Top ? Top->PrevScanLocation : SourceLocation(); 850 } 851 852 /// Set collapse value for the region. 853 void setAssociatedLoops(unsigned Val) { 854 getTopOfStack().AssociatedLoops = Val; 855 if (Val > 1) 856 getTopOfStack().HasMutipleLoops = true; 857 } 858 /// Return collapse value for region. 859 unsigned getAssociatedLoops() const { 860 const SharingMapTy *Top = getTopOfStackOrNull(); 861 return Top ? Top->AssociatedLoops : 0; 862 } 863 /// Returns true if the construct is associated with multiple loops. 864 bool hasMutipleLoops() const { 865 const SharingMapTy *Top = getTopOfStackOrNull(); 866 return Top ? Top->HasMutipleLoops : false; 867 } 868 869 /// Marks current target region as one with closely nested teams 870 /// region. 871 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 872 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 873 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 874 } 875 /// Returns true, if current region has closely nested teams region. 876 bool hasInnerTeamsRegion() const { 877 return getInnerTeamsRegionLoc().isValid(); 878 } 879 /// Returns location of the nested teams region (if any). 880 SourceLocation getInnerTeamsRegionLoc() const { 881 const SharingMapTy *Top = getTopOfStackOrNull(); 882 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 883 } 884 885 Scope *getCurScope() const { 886 const SharingMapTy *Top = getTopOfStackOrNull(); 887 return Top ? Top->CurScope : nullptr; 888 } 889 SourceLocation getConstructLoc() const { 890 const SharingMapTy *Top = getTopOfStackOrNull(); 891 return Top ? Top->ConstructLoc : SourceLocation(); 892 } 893 894 /// Do the check specified in \a Check to all component lists and return true 895 /// if any issue is found. 896 bool checkMappableExprComponentListsForDecl( 897 const ValueDecl *VD, bool CurrentRegionOnly, 898 const llvm::function_ref< 899 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 900 OpenMPClauseKind)> 901 Check) const { 902 if (isStackEmpty()) 903 return false; 904 auto SI = begin(); 905 auto SE = end(); 906 907 if (SI == SE) 908 return false; 909 910 if (CurrentRegionOnly) 911 SE = std::next(SI); 912 else 913 std::advance(SI, 1); 914 915 for (; SI != SE; ++SI) { 916 auto MI = SI->MappedExprComponents.find(VD); 917 if (MI != SI->MappedExprComponents.end()) 918 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 919 MI->second.Components) 920 if (Check(L, MI->second.Kind)) 921 return true; 922 } 923 return false; 924 } 925 926 /// Do the check specified in \a Check to all component lists at a given level 927 /// and return true if any issue is found. 928 bool checkMappableExprComponentListsForDeclAtLevel( 929 const ValueDecl *VD, unsigned Level, 930 const llvm::function_ref< 931 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 932 OpenMPClauseKind)> 933 Check) const { 934 if (getStackSize() <= Level) 935 return false; 936 937 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 938 auto MI = StackElem.MappedExprComponents.find(VD); 939 if (MI != StackElem.MappedExprComponents.end()) 940 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 941 MI->second.Components) 942 if (Check(L, MI->second.Kind)) 943 return true; 944 return false; 945 } 946 947 /// Create a new mappable expression component list associated with a given 948 /// declaration and initialize it with the provided list of components. 949 void addMappableExpressionComponents( 950 const ValueDecl *VD, 951 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 952 OpenMPClauseKind WhereFoundClauseKind) { 953 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 954 // Create new entry and append the new components there. 955 MEC.Components.resize(MEC.Components.size() + 1); 956 MEC.Components.back().append(Components.begin(), Components.end()); 957 MEC.Kind = WhereFoundClauseKind; 958 } 959 960 unsigned getNestingLevel() const { 961 assert(!isStackEmpty()); 962 return getStackSize() - 1; 963 } 964 void addDoacrossDependClause(OMPDependClause *C, 965 const OperatorOffsetTy &OpsOffs) { 966 SharingMapTy *Parent = getSecondOnStackOrNull(); 967 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 968 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 969 } 970 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 971 getDoacrossDependClauses() const { 972 const SharingMapTy &StackElem = getTopOfStack(); 973 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 974 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 975 return llvm::make_range(Ref.begin(), Ref.end()); 976 } 977 return llvm::make_range(StackElem.DoacrossDepends.end(), 978 StackElem.DoacrossDepends.end()); 979 } 980 981 // Store types of classes which have been explicitly mapped 982 void addMappedClassesQualTypes(QualType QT) { 983 SharingMapTy &StackElem = getTopOfStack(); 984 StackElem.MappedClassesQualTypes.insert(QT); 985 } 986 987 // Return set of mapped classes types 988 bool isClassPreviouslyMapped(QualType QT) const { 989 const SharingMapTy &StackElem = getTopOfStack(); 990 return StackElem.MappedClassesQualTypes.count(QT) != 0; 991 } 992 993 /// Adds global declare target to the parent target region. 994 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 995 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 996 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 997 "Expected declare target link global."); 998 for (auto &Elem : *this) { 999 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 1000 Elem.DeclareTargetLinkVarDecls.push_back(E); 1001 return; 1002 } 1003 } 1004 } 1005 1006 /// Returns the list of globals with declare target link if current directive 1007 /// is target. 1008 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 1009 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 1010 "Expected target executable directive."); 1011 return getTopOfStack().DeclareTargetLinkVarDecls; 1012 } 1013 1014 /// Adds list of allocators expressions. 1015 void addInnerAllocatorExpr(Expr *E) { 1016 getTopOfStack().InnerUsedAllocators.push_back(E); 1017 } 1018 /// Return list of used allocators. 1019 ArrayRef<Expr *> getInnerAllocators() const { 1020 return getTopOfStack().InnerUsedAllocators; 1021 } 1022 /// Marks the declaration as implicitly firstprivate nin the task-based 1023 /// regions. 1024 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { 1025 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); 1026 } 1027 /// Checks if the decl is implicitly firstprivate in the task-based region. 1028 bool isImplicitTaskFirstprivate(Decl *D) const { 1029 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0; 1030 } 1031 1032 /// Marks decl as used in uses_allocators clause as the allocator. 1033 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) { 1034 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind); 1035 } 1036 /// Checks if specified decl is used in uses allocator clause as the 1037 /// allocator. 1038 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level, 1039 const Decl *D) const { 1040 const SharingMapTy &StackElem = getTopOfStack(); 1041 auto I = StackElem.UsesAllocatorsDecls.find(D); 1042 if (I == StackElem.UsesAllocatorsDecls.end()) 1043 return None; 1044 return I->getSecond(); 1045 } 1046 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const { 1047 const SharingMapTy &StackElem = getTopOfStack(); 1048 auto I = StackElem.UsesAllocatorsDecls.find(D); 1049 if (I == StackElem.UsesAllocatorsDecls.end()) 1050 return None; 1051 return I->getSecond(); 1052 } 1053 }; 1054 1055 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1056 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 1057 } 1058 1059 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1060 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 1061 DKind == OMPD_unknown; 1062 } 1063 1064 } // namespace 1065 1066 static const Expr *getExprAsWritten(const Expr *E) { 1067 if (const auto *FE = dyn_cast<FullExpr>(E)) 1068 E = FE->getSubExpr(); 1069 1070 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 1071 E = MTE->getSubExpr(); 1072 1073 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 1074 E = Binder->getSubExpr(); 1075 1076 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 1077 E = ICE->getSubExprAsWritten(); 1078 return E->IgnoreParens(); 1079 } 1080 1081 static Expr *getExprAsWritten(Expr *E) { 1082 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 1083 } 1084 1085 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 1086 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 1087 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 1088 D = ME->getMemberDecl(); 1089 const auto *VD = dyn_cast<VarDecl>(D); 1090 const auto *FD = dyn_cast<FieldDecl>(D); 1091 if (VD != nullptr) { 1092 VD = VD->getCanonicalDecl(); 1093 D = VD; 1094 } else { 1095 assert(FD); 1096 FD = FD->getCanonicalDecl(); 1097 D = FD; 1098 } 1099 return D; 1100 } 1101 1102 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 1103 return const_cast<ValueDecl *>( 1104 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 1105 } 1106 1107 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 1108 ValueDecl *D) const { 1109 D = getCanonicalDecl(D); 1110 auto *VD = dyn_cast<VarDecl>(D); 1111 const auto *FD = dyn_cast<FieldDecl>(D); 1112 DSAVarData DVar; 1113 if (Iter == end()) { 1114 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1115 // in a region but not in construct] 1116 // File-scope or namespace-scope variables referenced in called routines 1117 // in the region are shared unless they appear in a threadprivate 1118 // directive. 1119 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1120 DVar.CKind = OMPC_shared; 1121 1122 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1123 // in a region but not in construct] 1124 // Variables with static storage duration that are declared in called 1125 // routines in the region are shared. 1126 if (VD && VD->hasGlobalStorage()) 1127 DVar.CKind = OMPC_shared; 1128 1129 // Non-static data members are shared by default. 1130 if (FD) 1131 DVar.CKind = OMPC_shared; 1132 1133 return DVar; 1134 } 1135 1136 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1137 // in a Construct, C/C++, predetermined, p.1] 1138 // Variables with automatic storage duration that are declared in a scope 1139 // inside the construct are private. 1140 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1141 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1142 DVar.CKind = OMPC_private; 1143 return DVar; 1144 } 1145 1146 DVar.DKind = Iter->Directive; 1147 // Explicitly specified attributes and local variables with predetermined 1148 // attributes. 1149 if (Iter->SharingMap.count(D)) { 1150 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1151 DVar.RefExpr = Data.RefExpr.getPointer(); 1152 DVar.PrivateCopy = Data.PrivateCopy; 1153 DVar.CKind = Data.Attributes; 1154 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1155 DVar.Modifier = Data.Modifier; 1156 return DVar; 1157 } 1158 1159 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1160 // in a Construct, C/C++, implicitly determined, p.1] 1161 // In a parallel or task construct, the data-sharing attributes of these 1162 // variables are determined by the default clause, if present. 1163 switch (Iter->DefaultAttr) { 1164 case DSA_shared: 1165 DVar.CKind = OMPC_shared; 1166 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1167 return DVar; 1168 case DSA_none: 1169 return DVar; 1170 case DSA_unspecified: 1171 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1172 // in a Construct, implicitly determined, p.2] 1173 // In a parallel construct, if no default clause is present, these 1174 // variables are shared. 1175 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1176 if ((isOpenMPParallelDirective(DVar.DKind) && 1177 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1178 isOpenMPTeamsDirective(DVar.DKind)) { 1179 DVar.CKind = OMPC_shared; 1180 return DVar; 1181 } 1182 1183 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1184 // in a Construct, implicitly determined, p.4] 1185 // In a task construct, if no default clause is present, a variable that in 1186 // the enclosing context is determined to be shared by all implicit tasks 1187 // bound to the current team is shared. 1188 if (isOpenMPTaskingDirective(DVar.DKind)) { 1189 DSAVarData DVarTemp; 1190 const_iterator I = Iter, E = end(); 1191 do { 1192 ++I; 1193 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1194 // Referenced in a Construct, implicitly determined, p.6] 1195 // In a task construct, if no default clause is present, a variable 1196 // whose data-sharing attribute is not determined by the rules above is 1197 // firstprivate. 1198 DVarTemp = getDSA(I, D); 1199 if (DVarTemp.CKind != OMPC_shared) { 1200 DVar.RefExpr = nullptr; 1201 DVar.CKind = OMPC_firstprivate; 1202 return DVar; 1203 } 1204 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1205 DVar.CKind = 1206 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1207 return DVar; 1208 } 1209 } 1210 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1211 // in a Construct, implicitly determined, p.3] 1212 // For constructs other than task, if no default clause is present, these 1213 // variables inherit their data-sharing attributes from the enclosing 1214 // context. 1215 return getDSA(++Iter, D); 1216 } 1217 1218 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1219 const Expr *NewDE) { 1220 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1221 D = getCanonicalDecl(D); 1222 SharingMapTy &StackElem = getTopOfStack(); 1223 auto It = StackElem.AlignedMap.find(D); 1224 if (It == StackElem.AlignedMap.end()) { 1225 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1226 StackElem.AlignedMap[D] = NewDE; 1227 return nullptr; 1228 } 1229 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1230 return It->second; 1231 } 1232 1233 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1234 const Expr *NewDE) { 1235 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1236 D = getCanonicalDecl(D); 1237 SharingMapTy &StackElem = getTopOfStack(); 1238 auto It = StackElem.NontemporalMap.find(D); 1239 if (It == StackElem.NontemporalMap.end()) { 1240 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1241 StackElem.NontemporalMap[D] = NewDE; 1242 return nullptr; 1243 } 1244 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1245 return It->second; 1246 } 1247 1248 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1249 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1250 D = getCanonicalDecl(D); 1251 SharingMapTy &StackElem = getTopOfStack(); 1252 StackElem.LCVMap.try_emplace( 1253 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1254 } 1255 1256 const DSAStackTy::LCDeclInfo 1257 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1258 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1259 D = getCanonicalDecl(D); 1260 const SharingMapTy &StackElem = getTopOfStack(); 1261 auto It = StackElem.LCVMap.find(D); 1262 if (It != StackElem.LCVMap.end()) 1263 return It->second; 1264 return {0, nullptr}; 1265 } 1266 1267 const DSAStackTy::LCDeclInfo 1268 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { 1269 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1270 D = getCanonicalDecl(D); 1271 for (unsigned I = Level + 1; I > 0; --I) { 1272 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); 1273 auto It = StackElem.LCVMap.find(D); 1274 if (It != StackElem.LCVMap.end()) 1275 return It->second; 1276 } 1277 return {0, nullptr}; 1278 } 1279 1280 const DSAStackTy::LCDeclInfo 1281 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1282 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1283 assert(Parent && "Data-sharing attributes stack is empty"); 1284 D = getCanonicalDecl(D); 1285 auto It = Parent->LCVMap.find(D); 1286 if (It != Parent->LCVMap.end()) 1287 return It->second; 1288 return {0, nullptr}; 1289 } 1290 1291 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1292 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1293 assert(Parent && "Data-sharing attributes stack is empty"); 1294 if (Parent->LCVMap.size() < I) 1295 return nullptr; 1296 for (const auto &Pair : Parent->LCVMap) 1297 if (Pair.second.first == I) 1298 return Pair.first; 1299 return nullptr; 1300 } 1301 1302 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1303 DeclRefExpr *PrivateCopy, unsigned Modifier) { 1304 D = getCanonicalDecl(D); 1305 if (A == OMPC_threadprivate) { 1306 DSAInfo &Data = Threadprivates[D]; 1307 Data.Attributes = A; 1308 Data.RefExpr.setPointer(E); 1309 Data.PrivateCopy = nullptr; 1310 Data.Modifier = Modifier; 1311 } else { 1312 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1313 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1314 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1315 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1316 (isLoopControlVariable(D).first && A == OMPC_private)); 1317 Data.Modifier = Modifier; 1318 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1319 Data.RefExpr.setInt(/*IntVal=*/true); 1320 return; 1321 } 1322 const bool IsLastprivate = 1323 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1324 Data.Attributes = A; 1325 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1326 Data.PrivateCopy = PrivateCopy; 1327 if (PrivateCopy) { 1328 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1329 Data.Modifier = Modifier; 1330 Data.Attributes = A; 1331 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1332 Data.PrivateCopy = nullptr; 1333 } 1334 } 1335 } 1336 1337 /// Build a variable declaration for OpenMP loop iteration variable. 1338 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1339 StringRef Name, const AttrVec *Attrs = nullptr, 1340 DeclRefExpr *OrigRef = nullptr) { 1341 DeclContext *DC = SemaRef.CurContext; 1342 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1343 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1344 auto *Decl = 1345 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1346 if (Attrs) { 1347 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1348 I != E; ++I) 1349 Decl->addAttr(*I); 1350 } 1351 Decl->setImplicit(); 1352 if (OrigRef) { 1353 Decl->addAttr( 1354 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1355 } 1356 return Decl; 1357 } 1358 1359 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1360 SourceLocation Loc, 1361 bool RefersToCapture = false) { 1362 D->setReferenced(); 1363 D->markUsed(S.Context); 1364 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1365 SourceLocation(), D, RefersToCapture, Loc, Ty, 1366 VK_LValue); 1367 } 1368 1369 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1370 BinaryOperatorKind BOK) { 1371 D = getCanonicalDecl(D); 1372 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1373 assert( 1374 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1375 "Additional reduction info may be specified only for reduction items."); 1376 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1377 assert(ReductionData.ReductionRange.isInvalid() && 1378 (getTopOfStack().Directive == OMPD_taskgroup || 1379 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1380 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1381 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1382 "Additional reduction info may be specified only once for reduction " 1383 "items."); 1384 ReductionData.set(BOK, SR); 1385 Expr *&TaskgroupReductionRef = 1386 getTopOfStack().TaskgroupReductionRef; 1387 if (!TaskgroupReductionRef) { 1388 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1389 SemaRef.Context.VoidPtrTy, ".task_red."); 1390 TaskgroupReductionRef = 1391 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1392 } 1393 } 1394 1395 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1396 const Expr *ReductionRef) { 1397 D = getCanonicalDecl(D); 1398 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1399 assert( 1400 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1401 "Additional reduction info may be specified only for reduction items."); 1402 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1403 assert(ReductionData.ReductionRange.isInvalid() && 1404 (getTopOfStack().Directive == OMPD_taskgroup || 1405 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1406 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1407 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1408 "Additional reduction info may be specified only once for reduction " 1409 "items."); 1410 ReductionData.set(ReductionRef, SR); 1411 Expr *&TaskgroupReductionRef = 1412 getTopOfStack().TaskgroupReductionRef; 1413 if (!TaskgroupReductionRef) { 1414 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1415 SemaRef.Context.VoidPtrTy, ".task_red."); 1416 TaskgroupReductionRef = 1417 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1418 } 1419 } 1420 1421 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1422 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1423 Expr *&TaskgroupDescriptor) const { 1424 D = getCanonicalDecl(D); 1425 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1426 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1427 const DSAInfo &Data = I->SharingMap.lookup(D); 1428 if (Data.Attributes != OMPC_reduction || 1429 Data.Modifier != OMPC_REDUCTION_task) 1430 continue; 1431 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1432 if (!ReductionData.ReductionOp || 1433 ReductionData.ReductionOp.is<const Expr *>()) 1434 return DSAVarData(); 1435 SR = ReductionData.ReductionRange; 1436 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1437 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1438 "expression for the descriptor is not " 1439 "set."); 1440 TaskgroupDescriptor = I->TaskgroupReductionRef; 1441 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1442 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task); 1443 } 1444 return DSAVarData(); 1445 } 1446 1447 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1448 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1449 Expr *&TaskgroupDescriptor) const { 1450 D = getCanonicalDecl(D); 1451 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1452 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1453 const DSAInfo &Data = I->SharingMap.lookup(D); 1454 if (Data.Attributes != OMPC_reduction || 1455 Data.Modifier != OMPC_REDUCTION_task) 1456 continue; 1457 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1458 if (!ReductionData.ReductionOp || 1459 !ReductionData.ReductionOp.is<const Expr *>()) 1460 return DSAVarData(); 1461 SR = ReductionData.ReductionRange; 1462 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1463 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1464 "expression for the descriptor is not " 1465 "set."); 1466 TaskgroupDescriptor = I->TaskgroupReductionRef; 1467 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1468 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task); 1469 } 1470 return DSAVarData(); 1471 } 1472 1473 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1474 D = D->getCanonicalDecl(); 1475 for (const_iterator E = end(); I != E; ++I) { 1476 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1477 isOpenMPTargetExecutionDirective(I->Directive)) { 1478 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1479 Scope *CurScope = getCurScope(); 1480 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1481 CurScope = CurScope->getParent(); 1482 return CurScope != TopScope; 1483 } 1484 } 1485 return false; 1486 } 1487 1488 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1489 bool AcceptIfMutable = true, 1490 bool *IsClassType = nullptr) { 1491 ASTContext &Context = SemaRef.getASTContext(); 1492 Type = Type.getNonReferenceType().getCanonicalType(); 1493 bool IsConstant = Type.isConstant(Context); 1494 Type = Context.getBaseElementType(Type); 1495 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1496 ? Type->getAsCXXRecordDecl() 1497 : nullptr; 1498 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1499 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1500 RD = CTD->getTemplatedDecl(); 1501 if (IsClassType) 1502 *IsClassType = RD; 1503 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1504 RD->hasDefinition() && RD->hasMutableFields()); 1505 } 1506 1507 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1508 QualType Type, OpenMPClauseKind CKind, 1509 SourceLocation ELoc, 1510 bool AcceptIfMutable = true, 1511 bool ListItemNotVar = false) { 1512 ASTContext &Context = SemaRef.getASTContext(); 1513 bool IsClassType; 1514 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1515 unsigned Diag = ListItemNotVar 1516 ? diag::err_omp_const_list_item 1517 : IsClassType ? diag::err_omp_const_not_mutable_variable 1518 : diag::err_omp_const_variable; 1519 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1520 if (!ListItemNotVar && D) { 1521 const VarDecl *VD = dyn_cast<VarDecl>(D); 1522 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1523 VarDecl::DeclarationOnly; 1524 SemaRef.Diag(D->getLocation(), 1525 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1526 << D; 1527 } 1528 return true; 1529 } 1530 return false; 1531 } 1532 1533 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1534 bool FromParent) { 1535 D = getCanonicalDecl(D); 1536 DSAVarData DVar; 1537 1538 auto *VD = dyn_cast<VarDecl>(D); 1539 auto TI = Threadprivates.find(D); 1540 if (TI != Threadprivates.end()) { 1541 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1542 DVar.CKind = OMPC_threadprivate; 1543 DVar.Modifier = TI->getSecond().Modifier; 1544 return DVar; 1545 } 1546 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1547 DVar.RefExpr = buildDeclRefExpr( 1548 SemaRef, VD, D->getType().getNonReferenceType(), 1549 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1550 DVar.CKind = OMPC_threadprivate; 1551 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1552 return DVar; 1553 } 1554 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1555 // in a Construct, C/C++, predetermined, p.1] 1556 // Variables appearing in threadprivate directives are threadprivate. 1557 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1558 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1559 SemaRef.getLangOpts().OpenMPUseTLS && 1560 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1561 (VD && VD->getStorageClass() == SC_Register && 1562 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1563 DVar.RefExpr = buildDeclRefExpr( 1564 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1565 DVar.CKind = OMPC_threadprivate; 1566 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1567 return DVar; 1568 } 1569 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1570 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1571 !isLoopControlVariable(D).first) { 1572 const_iterator IterTarget = 1573 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1574 return isOpenMPTargetExecutionDirective(Data.Directive); 1575 }); 1576 if (IterTarget != end()) { 1577 const_iterator ParentIterTarget = IterTarget + 1; 1578 for (const_iterator Iter = begin(); 1579 Iter != ParentIterTarget; ++Iter) { 1580 if (isOpenMPLocal(VD, Iter)) { 1581 DVar.RefExpr = 1582 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1583 D->getLocation()); 1584 DVar.CKind = OMPC_threadprivate; 1585 return DVar; 1586 } 1587 } 1588 if (!isClauseParsingMode() || IterTarget != begin()) { 1589 auto DSAIter = IterTarget->SharingMap.find(D); 1590 if (DSAIter != IterTarget->SharingMap.end() && 1591 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1592 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1593 DVar.CKind = OMPC_threadprivate; 1594 return DVar; 1595 } 1596 const_iterator End = end(); 1597 if (!SemaRef.isOpenMPCapturedByRef( 1598 D, std::distance(ParentIterTarget, End), 1599 /*OpenMPCaptureLevel=*/0)) { 1600 DVar.RefExpr = 1601 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1602 IterTarget->ConstructLoc); 1603 DVar.CKind = OMPC_threadprivate; 1604 return DVar; 1605 } 1606 } 1607 } 1608 } 1609 1610 if (isStackEmpty()) 1611 // Not in OpenMP execution region and top scope was already checked. 1612 return DVar; 1613 1614 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1615 // in a Construct, C/C++, predetermined, p.4] 1616 // Static data members are shared. 1617 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1618 // in a Construct, C/C++, predetermined, p.7] 1619 // Variables with static storage duration that are declared in a scope 1620 // inside the construct are shared. 1621 if (VD && VD->isStaticDataMember()) { 1622 // Check for explicitly specified attributes. 1623 const_iterator I = begin(); 1624 const_iterator EndI = end(); 1625 if (FromParent && I != EndI) 1626 ++I; 1627 if (I != EndI) { 1628 auto It = I->SharingMap.find(D); 1629 if (It != I->SharingMap.end()) { 1630 const DSAInfo &Data = It->getSecond(); 1631 DVar.RefExpr = Data.RefExpr.getPointer(); 1632 DVar.PrivateCopy = Data.PrivateCopy; 1633 DVar.CKind = Data.Attributes; 1634 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1635 DVar.DKind = I->Directive; 1636 DVar.Modifier = Data.Modifier; 1637 return DVar; 1638 } 1639 } 1640 1641 DVar.CKind = OMPC_shared; 1642 return DVar; 1643 } 1644 1645 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1646 // The predetermined shared attribute for const-qualified types having no 1647 // mutable members was removed after OpenMP 3.1. 1648 if (SemaRef.LangOpts.OpenMP <= 31) { 1649 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1650 // in a Construct, C/C++, predetermined, p.6] 1651 // Variables with const qualified type having no mutable member are 1652 // shared. 1653 if (isConstNotMutableType(SemaRef, D->getType())) { 1654 // Variables with const-qualified type having no mutable member may be 1655 // listed in a firstprivate clause, even if they are static data members. 1656 DSAVarData DVarTemp = hasInnermostDSA( 1657 D, 1658 [](OpenMPClauseKind C) { 1659 return C == OMPC_firstprivate || C == OMPC_shared; 1660 }, 1661 MatchesAlways, FromParent); 1662 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1663 return DVarTemp; 1664 1665 DVar.CKind = OMPC_shared; 1666 return DVar; 1667 } 1668 } 1669 1670 // Explicitly specified attributes and local variables with predetermined 1671 // attributes. 1672 const_iterator I = begin(); 1673 const_iterator EndI = end(); 1674 if (FromParent && I != EndI) 1675 ++I; 1676 if (I == EndI) 1677 return DVar; 1678 auto It = I->SharingMap.find(D); 1679 if (It != I->SharingMap.end()) { 1680 const DSAInfo &Data = It->getSecond(); 1681 DVar.RefExpr = Data.RefExpr.getPointer(); 1682 DVar.PrivateCopy = Data.PrivateCopy; 1683 DVar.CKind = Data.Attributes; 1684 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1685 DVar.DKind = I->Directive; 1686 DVar.Modifier = Data.Modifier; 1687 } 1688 1689 return DVar; 1690 } 1691 1692 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1693 bool FromParent) const { 1694 if (isStackEmpty()) { 1695 const_iterator I; 1696 return getDSA(I, D); 1697 } 1698 D = getCanonicalDecl(D); 1699 const_iterator StartI = begin(); 1700 const_iterator EndI = end(); 1701 if (FromParent && StartI != EndI) 1702 ++StartI; 1703 return getDSA(StartI, D); 1704 } 1705 1706 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1707 unsigned Level) const { 1708 if (getStackSize() <= Level) 1709 return DSAVarData(); 1710 D = getCanonicalDecl(D); 1711 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); 1712 return getDSA(StartI, D); 1713 } 1714 1715 const DSAStackTy::DSAVarData 1716 DSAStackTy::hasDSA(ValueDecl *D, 1717 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1718 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1719 bool FromParent) const { 1720 if (isStackEmpty()) 1721 return {}; 1722 D = getCanonicalDecl(D); 1723 const_iterator I = begin(); 1724 const_iterator EndI = end(); 1725 if (FromParent && I != EndI) 1726 ++I; 1727 for (; I != EndI; ++I) { 1728 if (!DPred(I->Directive) && 1729 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1730 continue; 1731 const_iterator NewI = I; 1732 DSAVarData DVar = getDSA(NewI, D); 1733 if (I == NewI && CPred(DVar.CKind)) 1734 return DVar; 1735 } 1736 return {}; 1737 } 1738 1739 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1740 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1741 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1742 bool FromParent) const { 1743 if (isStackEmpty()) 1744 return {}; 1745 D = getCanonicalDecl(D); 1746 const_iterator StartI = begin(); 1747 const_iterator EndI = end(); 1748 if (FromParent && StartI != EndI) 1749 ++StartI; 1750 if (StartI == EndI || !DPred(StartI->Directive)) 1751 return {}; 1752 const_iterator NewI = StartI; 1753 DSAVarData DVar = getDSA(NewI, D); 1754 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1755 } 1756 1757 bool DSAStackTy::hasExplicitDSA( 1758 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1759 unsigned Level, bool NotLastprivate) const { 1760 if (getStackSize() <= Level) 1761 return false; 1762 D = getCanonicalDecl(D); 1763 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1764 auto I = StackElem.SharingMap.find(D); 1765 if (I != StackElem.SharingMap.end() && 1766 I->getSecond().RefExpr.getPointer() && 1767 CPred(I->getSecond().Attributes) && 1768 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1769 return true; 1770 // Check predetermined rules for the loop control variables. 1771 auto LI = StackElem.LCVMap.find(D); 1772 if (LI != StackElem.LCVMap.end()) 1773 return CPred(OMPC_private); 1774 return false; 1775 } 1776 1777 bool DSAStackTy::hasExplicitDirective( 1778 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1779 unsigned Level) const { 1780 if (getStackSize() <= Level) 1781 return false; 1782 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1783 return DPred(StackElem.Directive); 1784 } 1785 1786 bool DSAStackTy::hasDirective( 1787 const llvm::function_ref<bool(OpenMPDirectiveKind, 1788 const DeclarationNameInfo &, SourceLocation)> 1789 DPred, 1790 bool FromParent) const { 1791 // We look only in the enclosing region. 1792 size_t Skip = FromParent ? 2 : 1; 1793 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1794 I != E; ++I) { 1795 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1796 return true; 1797 } 1798 return false; 1799 } 1800 1801 void Sema::InitDataSharingAttributesStack() { 1802 VarDataSharingAttributesStack = new DSAStackTy(*this); 1803 } 1804 1805 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1806 1807 void Sema::pushOpenMPFunctionRegion() { 1808 DSAStack->pushFunction(); 1809 } 1810 1811 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1812 DSAStack->popFunction(OldFSI); 1813 } 1814 1815 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1816 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1817 "Expected OpenMP device compilation."); 1818 return !S.isInOpenMPTargetExecutionDirective() && 1819 !S.isInOpenMPDeclareTargetContext(); 1820 } 1821 1822 namespace { 1823 /// Status of the function emission on the host/device. 1824 enum class FunctionEmissionStatus { 1825 Emitted, 1826 Discarded, 1827 Unknown, 1828 }; 1829 } // anonymous namespace 1830 1831 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1832 unsigned DiagID) { 1833 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1834 "Expected OpenMP device compilation."); 1835 1836 FunctionDecl *FD = getCurFunctionDecl(); 1837 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1838 if (FD) { 1839 FunctionEmissionStatus FES = getEmissionStatus(FD); 1840 switch (FES) { 1841 case FunctionEmissionStatus::Emitted: 1842 Kind = DeviceDiagBuilder::K_Immediate; 1843 break; 1844 case FunctionEmissionStatus::Unknown: 1845 Kind = isOpenMPDeviceDelayedContext(*this) 1846 ? DeviceDiagBuilder::K_Deferred 1847 : DeviceDiagBuilder::K_Immediate; 1848 break; 1849 case FunctionEmissionStatus::TemplateDiscarded: 1850 case FunctionEmissionStatus::OMPDiscarded: 1851 Kind = DeviceDiagBuilder::K_Nop; 1852 break; 1853 case FunctionEmissionStatus::CUDADiscarded: 1854 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1855 break; 1856 } 1857 } 1858 1859 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1860 } 1861 1862 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1863 unsigned DiagID) { 1864 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1865 "Expected OpenMP host compilation."); 1866 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1867 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1868 switch (FES) { 1869 case FunctionEmissionStatus::Emitted: 1870 Kind = DeviceDiagBuilder::K_Immediate; 1871 break; 1872 case FunctionEmissionStatus::Unknown: 1873 Kind = DeviceDiagBuilder::K_Deferred; 1874 break; 1875 case FunctionEmissionStatus::TemplateDiscarded: 1876 case FunctionEmissionStatus::OMPDiscarded: 1877 case FunctionEmissionStatus::CUDADiscarded: 1878 Kind = DeviceDiagBuilder::K_Nop; 1879 break; 1880 } 1881 1882 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1883 } 1884 1885 static OpenMPDefaultmapClauseKind 1886 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1887 if (LO.OpenMP <= 45) { 1888 if (VD->getType().getNonReferenceType()->isScalarType()) 1889 return OMPC_DEFAULTMAP_scalar; 1890 return OMPC_DEFAULTMAP_aggregate; 1891 } 1892 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1893 return OMPC_DEFAULTMAP_pointer; 1894 if (VD->getType().getNonReferenceType()->isScalarType()) 1895 return OMPC_DEFAULTMAP_scalar; 1896 return OMPC_DEFAULTMAP_aggregate; 1897 } 1898 1899 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1900 unsigned OpenMPCaptureLevel) const { 1901 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1902 1903 ASTContext &Ctx = getASTContext(); 1904 bool IsByRef = true; 1905 1906 // Find the directive that is associated with the provided scope. 1907 D = cast<ValueDecl>(D->getCanonicalDecl()); 1908 QualType Ty = D->getType(); 1909 1910 bool IsVariableUsedInMapClause = false; 1911 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1912 // This table summarizes how a given variable should be passed to the device 1913 // given its type and the clauses where it appears. This table is based on 1914 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1915 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1916 // 1917 // ========================================================================= 1918 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1919 // | |(tofrom:scalar)| | pvt | | | | 1920 // ========================================================================= 1921 // | scl | | | | - | | bycopy| 1922 // | scl | | - | x | - | - | bycopy| 1923 // | scl | | x | - | - | - | null | 1924 // | scl | x | | | - | | byref | 1925 // | scl | x | - | x | - | - | bycopy| 1926 // | scl | x | x | - | - | - | null | 1927 // | scl | | - | - | - | x | byref | 1928 // | scl | x | - | - | - | x | byref | 1929 // 1930 // | agg | n.a. | | | - | | byref | 1931 // | agg | n.a. | - | x | - | - | byref | 1932 // | agg | n.a. | x | - | - | - | null | 1933 // | agg | n.a. | - | - | - | x | byref | 1934 // | agg | n.a. | - | - | - | x[] | byref | 1935 // 1936 // | ptr | n.a. | | | - | | bycopy| 1937 // | ptr | n.a. | - | x | - | - | bycopy| 1938 // | ptr | n.a. | x | - | - | - | null | 1939 // | ptr | n.a. | - | - | - | x | byref | 1940 // | ptr | n.a. | - | - | - | x[] | bycopy| 1941 // | ptr | n.a. | - | - | x | | bycopy| 1942 // | ptr | n.a. | - | - | x | x | bycopy| 1943 // | ptr | n.a. | - | - | x | x[] | bycopy| 1944 // ========================================================================= 1945 // Legend: 1946 // scl - scalar 1947 // ptr - pointer 1948 // agg - aggregate 1949 // x - applies 1950 // - - invalid in this combination 1951 // [] - mapped with an array section 1952 // byref - should be mapped by reference 1953 // byval - should be mapped by value 1954 // null - initialize a local variable to null on the device 1955 // 1956 // Observations: 1957 // - All scalar declarations that show up in a map clause have to be passed 1958 // by reference, because they may have been mapped in the enclosing data 1959 // environment. 1960 // - If the scalar value does not fit the size of uintptr, it has to be 1961 // passed by reference, regardless the result in the table above. 1962 // - For pointers mapped by value that have either an implicit map or an 1963 // array section, the runtime library may pass the NULL value to the 1964 // device instead of the value passed to it by the compiler. 1965 1966 if (Ty->isReferenceType()) 1967 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1968 1969 // Locate map clauses and see if the variable being captured is referred to 1970 // in any of those clauses. Here we only care about variables, not fields, 1971 // because fields are part of aggregates. 1972 bool IsVariableAssociatedWithSection = false; 1973 1974 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1975 D, Level, 1976 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1977 OMPClauseMappableExprCommon::MappableExprComponentListRef 1978 MapExprComponents, 1979 OpenMPClauseKind WhereFoundClauseKind) { 1980 // Only the map clause information influences how a variable is 1981 // captured. E.g. is_device_ptr does not require changing the default 1982 // behavior. 1983 if (WhereFoundClauseKind != OMPC_map) 1984 return false; 1985 1986 auto EI = MapExprComponents.rbegin(); 1987 auto EE = MapExprComponents.rend(); 1988 1989 assert(EI != EE && "Invalid map expression!"); 1990 1991 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1992 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1993 1994 ++EI; 1995 if (EI == EE) 1996 return false; 1997 1998 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1999 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 2000 isa<MemberExpr>(EI->getAssociatedExpression()) || 2001 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { 2002 IsVariableAssociatedWithSection = true; 2003 // There is nothing more we need to know about this variable. 2004 return true; 2005 } 2006 2007 // Keep looking for more map info. 2008 return false; 2009 }); 2010 2011 if (IsVariableUsedInMapClause) { 2012 // If variable is identified in a map clause it is always captured by 2013 // reference except if it is a pointer that is dereferenced somehow. 2014 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 2015 } else { 2016 // By default, all the data that has a scalar type is mapped by copy 2017 // (except for reduction variables). 2018 // Defaultmap scalar is mutual exclusive to defaultmap pointer 2019 IsByRef = 2020 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 2021 !Ty->isAnyPointerType()) || 2022 !Ty->isScalarType() || 2023 DSAStack->isDefaultmapCapturedByRef( 2024 Level, getVariableCategoryFromDecl(LangOpts, D)) || 2025 DSAStack->hasExplicitDSA( 2026 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 2027 } 2028 } 2029 2030 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 2031 IsByRef = 2032 ((IsVariableUsedInMapClause && 2033 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 2034 OMPD_target) || 2035 !(DSAStack->hasExplicitDSA( 2036 D, 2037 [](OpenMPClauseKind K) -> bool { 2038 return K == OMPC_firstprivate; 2039 }, 2040 Level, /*NotLastprivate=*/true) || 2041 DSAStack->isUsesAllocatorsDecl(Level, D))) && 2042 // If the variable is artificial and must be captured by value - try to 2043 // capture by value. 2044 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 2045 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 2046 } 2047 2048 // When passing data by copy, we need to make sure it fits the uintptr size 2049 // and alignment, because the runtime library only deals with uintptr types. 2050 // If it does not fit the uintptr size, we need to pass the data by reference 2051 // instead. 2052 if (!IsByRef && 2053 (Ctx.getTypeSizeInChars(Ty) > 2054 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 2055 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 2056 IsByRef = true; 2057 } 2058 2059 return IsByRef; 2060 } 2061 2062 unsigned Sema::getOpenMPNestingLevel() const { 2063 assert(getLangOpts().OpenMP); 2064 return DSAStack->getNestingLevel(); 2065 } 2066 2067 bool Sema::isInOpenMPTargetExecutionDirective() const { 2068 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2069 !DSAStack->isClauseParsingMode()) || 2070 DSAStack->hasDirective( 2071 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2072 SourceLocation) -> bool { 2073 return isOpenMPTargetExecutionDirective(K); 2074 }, 2075 false); 2076 } 2077 2078 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2079 unsigned StopAt) { 2080 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2081 D = getCanonicalDecl(D); 2082 2083 auto *VD = dyn_cast<VarDecl>(D); 2084 // Do not capture constexpr variables. 2085 if (VD && VD->isConstexpr()) 2086 return nullptr; 2087 2088 // If we want to determine whether the variable should be captured from the 2089 // perspective of the current capturing scope, and we've already left all the 2090 // capturing scopes of the top directive on the stack, check from the 2091 // perspective of its parent directive (if any) instead. 2092 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2093 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2094 2095 // If we are attempting to capture a global variable in a directive with 2096 // 'target' we return true so that this global is also mapped to the device. 2097 // 2098 if (VD && !VD->hasLocalStorage() && 2099 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2100 if (isInOpenMPDeclareTargetContext()) { 2101 // Try to mark variable as declare target if it is used in capturing 2102 // regions. 2103 if (LangOpts.OpenMP <= 45 && 2104 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2105 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2106 return nullptr; 2107 } else if (isInOpenMPTargetExecutionDirective()) { 2108 // If the declaration is enclosed in a 'declare target' directive, 2109 // then it should not be captured. 2110 // 2111 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2112 return nullptr; 2113 CapturedRegionScopeInfo *CSI = nullptr; 2114 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2115 llvm::reverse(FunctionScopes), 2116 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2117 if (!isa<CapturingScopeInfo>(FSI)) 2118 return nullptr; 2119 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2120 if (RSI->CapRegionKind == CR_OpenMP) { 2121 CSI = RSI; 2122 break; 2123 } 2124 } 2125 SmallVector<OpenMPDirectiveKind, 4> Regions; 2126 getOpenMPCaptureRegions(Regions, 2127 DSAStack->getDirective(CSI->OpenMPLevel)); 2128 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2129 return VD; 2130 } 2131 } 2132 2133 if (CheckScopeInfo) { 2134 bool OpenMPFound = false; 2135 for (unsigned I = StopAt + 1; I > 0; --I) { 2136 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2137 if(!isa<CapturingScopeInfo>(FSI)) 2138 return nullptr; 2139 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2140 if (RSI->CapRegionKind == CR_OpenMP) { 2141 OpenMPFound = true; 2142 break; 2143 } 2144 } 2145 if (!OpenMPFound) 2146 return nullptr; 2147 } 2148 2149 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2150 (!DSAStack->isClauseParsingMode() || 2151 DSAStack->getParentDirective() != OMPD_unknown)) { 2152 auto &&Info = DSAStack->isLoopControlVariable(D); 2153 if (Info.first || 2154 (VD && VD->hasLocalStorage() && 2155 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2156 (VD && DSAStack->isForceVarCapturing())) 2157 return VD ? VD : Info.second; 2158 DSAStackTy::DSAVarData DVarTop = 2159 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2160 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind)) 2161 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); 2162 // Threadprivate variables must not be captured. 2163 if (isOpenMPThreadPrivate(DVarTop.CKind)) 2164 return nullptr; 2165 // The variable is not private or it is the variable in the directive with 2166 // default(none) clause and not used in any clause. 2167 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2168 D, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 2169 DSAStack->isClauseParsingMode()); 2170 // Global shared must not be captured. 2171 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && 2172 (DSAStack->getDefaultDSA() != DSA_none || DVarTop.CKind == OMPC_shared)) 2173 return nullptr; 2174 if (DVarPrivate.CKind != OMPC_unknown || 2175 (VD && DSAStack->getDefaultDSA() == DSA_none)) 2176 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2177 } 2178 return nullptr; 2179 } 2180 2181 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2182 unsigned Level) const { 2183 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2184 } 2185 2186 void Sema::startOpenMPLoop() { 2187 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2188 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2189 DSAStack->loopInit(); 2190 } 2191 2192 void Sema::startOpenMPCXXRangeFor() { 2193 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2194 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2195 DSAStack->resetPossibleLoopCounter(); 2196 DSAStack->loopStart(); 2197 } 2198 } 2199 2200 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, 2201 unsigned CapLevel) const { 2202 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2203 if (DSAStack->hasExplicitDirective( 2204 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); }, 2205 Level)) { 2206 bool IsTriviallyCopyable = 2207 D->getType().getNonReferenceType().isTriviallyCopyableType(Context); 2208 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level); 2209 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2210 getOpenMPCaptureRegions(CaptureRegions, DKind); 2211 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && 2212 (IsTriviallyCopyable || 2213 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { 2214 if (DSAStack->hasExplicitDSA( 2215 D, [](OpenMPClauseKind K) { return K == OMPC_firstprivate; }, 2216 Level, /*NotLastprivate=*/true)) 2217 return OMPC_firstprivate; 2218 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2219 if (DVar.CKind != OMPC_shared && 2220 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { 2221 DSAStack->addImplicitTaskFirstprivate(Level, D); 2222 return OMPC_firstprivate; 2223 } 2224 } 2225 } 2226 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2227 if (DSAStack->getAssociatedLoops() > 0 && 2228 !DSAStack->isLoopStarted()) { 2229 DSAStack->resetPossibleLoopCounter(D); 2230 DSAStack->loopStart(); 2231 return OMPC_private; 2232 } 2233 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2234 DSAStack->isLoopControlVariable(D).first) && 2235 !DSAStack->hasExplicitDSA( 2236 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2237 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2238 return OMPC_private; 2239 } 2240 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2241 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2242 DSAStack->isForceVarCapturing() && 2243 !DSAStack->hasExplicitDSA( 2244 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2245 return OMPC_private; 2246 } 2247 // User-defined allocators are private since they must be defined in the 2248 // context of target region. 2249 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) && 2250 DSAStack->isUsesAllocatorsDecl(Level, D).getValueOr( 2251 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 2252 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator) 2253 return OMPC_private; 2254 return (DSAStack->hasExplicitDSA( 2255 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2256 (DSAStack->isClauseParsingMode() && 2257 DSAStack->getClauseParsingMode() == OMPC_private) || 2258 // Consider taskgroup reduction descriptor variable a private 2259 // to avoid possible capture in the region. 2260 (DSAStack->hasExplicitDirective( 2261 [](OpenMPDirectiveKind K) { 2262 return K == OMPD_taskgroup || 2263 ((isOpenMPParallelDirective(K) || 2264 isOpenMPWorksharingDirective(K)) && 2265 !isOpenMPSimdDirective(K)); 2266 }, 2267 Level) && 2268 DSAStack->isTaskgroupReductionRef(D, Level))) 2269 ? OMPC_private 2270 : OMPC_unknown; 2271 } 2272 2273 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2274 unsigned Level) { 2275 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2276 D = getCanonicalDecl(D); 2277 OpenMPClauseKind OMPC = OMPC_unknown; 2278 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2279 const unsigned NewLevel = I - 1; 2280 if (DSAStack->hasExplicitDSA(D, 2281 [&OMPC](const OpenMPClauseKind K) { 2282 if (isOpenMPPrivate(K)) { 2283 OMPC = K; 2284 return true; 2285 } 2286 return false; 2287 }, 2288 NewLevel)) 2289 break; 2290 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2291 D, NewLevel, 2292 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2293 OpenMPClauseKind) { return true; })) { 2294 OMPC = OMPC_map; 2295 break; 2296 } 2297 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2298 NewLevel)) { 2299 OMPC = OMPC_map; 2300 if (DSAStack->mustBeFirstprivateAtLevel( 2301 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2302 OMPC = OMPC_firstprivate; 2303 break; 2304 } 2305 } 2306 if (OMPC != OMPC_unknown) 2307 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); 2308 } 2309 2310 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2311 unsigned CaptureLevel) const { 2312 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2313 // Return true if the current level is no longer enclosed in a target region. 2314 2315 SmallVector<OpenMPDirectiveKind, 4> Regions; 2316 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2317 const auto *VD = dyn_cast<VarDecl>(D); 2318 return VD && !VD->hasLocalStorage() && 2319 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2320 Level) && 2321 Regions[CaptureLevel] != OMPD_task; 2322 } 2323 2324 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2325 unsigned CaptureLevel) const { 2326 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2327 // Return true if the current level is no longer enclosed in a target region. 2328 2329 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2330 if (!VD->hasLocalStorage()) { 2331 DSAStackTy::DSAVarData TopDVar = 2332 DSAStack->getTopDSA(D, /*FromParent=*/false); 2333 unsigned NumLevels = 2334 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2335 if (Level == 0) 2336 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared; 2337 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level - 1); 2338 return DVar.CKind != OMPC_shared || 2339 isOpenMPGlobalCapturedDecl( 2340 D, Level - 1, 2341 getOpenMPCaptureLevels(DSAStack->getDirective(Level - 1)) - 1); 2342 } 2343 } 2344 return true; 2345 } 2346 2347 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2348 2349 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2350 OMPTraitInfo &TI) { 2351 if (!OMPDeclareVariantScopes.empty()) { 2352 Diag(Loc, diag::warn_nested_declare_variant); 2353 return; 2354 } 2355 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2356 } 2357 2358 void Sema::ActOnOpenMPEndDeclareVariant() { 2359 assert(isInOpenMPDeclareVariantScope() && 2360 "Not in OpenMP declare variant scope!"); 2361 2362 OMPDeclareVariantScopes.pop_back(); 2363 } 2364 2365 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2366 const FunctionDecl *Callee, 2367 SourceLocation Loc) { 2368 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2369 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2370 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2371 // Ignore host functions during device analyzis. 2372 if (LangOpts.OpenMPIsDevice && DevTy && 2373 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2374 return; 2375 // Ignore nohost functions during host analyzis. 2376 if (!LangOpts.OpenMPIsDevice && DevTy && 2377 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2378 return; 2379 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2380 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2381 if (LangOpts.OpenMPIsDevice && DevTy && 2382 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2383 // Diagnose host function called during device codegen. 2384 StringRef HostDevTy = 2385 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2386 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2387 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2388 diag::note_omp_marked_device_type_here) 2389 << HostDevTy; 2390 return; 2391 } 2392 if (!LangOpts.OpenMPIsDevice && DevTy && 2393 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2394 // Diagnose nohost function called during host codegen. 2395 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2396 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2397 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2398 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2399 diag::note_omp_marked_device_type_here) 2400 << NoHostDevTy; 2401 } 2402 } 2403 2404 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2405 const DeclarationNameInfo &DirName, 2406 Scope *CurScope, SourceLocation Loc) { 2407 DSAStack->push(DKind, DirName, CurScope, Loc); 2408 PushExpressionEvaluationContext( 2409 ExpressionEvaluationContext::PotentiallyEvaluated); 2410 } 2411 2412 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2413 DSAStack->setClauseParsingMode(K); 2414 } 2415 2416 void Sema::EndOpenMPClause() { 2417 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2418 } 2419 2420 static std::pair<ValueDecl *, bool> 2421 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2422 SourceRange &ERange, bool AllowArraySection = false); 2423 2424 /// Check consistency of the reduction clauses. 2425 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2426 ArrayRef<OMPClause *> Clauses) { 2427 bool InscanFound = false; 2428 SourceLocation InscanLoc; 2429 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2430 // A reduction clause without the inscan reduction-modifier may not appear on 2431 // a construct on which a reduction clause with the inscan reduction-modifier 2432 // appears. 2433 for (OMPClause *C : Clauses) { 2434 if (C->getClauseKind() != OMPC_reduction) 2435 continue; 2436 auto *RC = cast<OMPReductionClause>(C); 2437 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2438 InscanFound = true; 2439 InscanLoc = RC->getModifierLoc(); 2440 continue; 2441 } 2442 if (RC->getModifier() == OMPC_REDUCTION_task) { 2443 // OpenMP 5.0, 2.19.5.4 reduction Clause. 2444 // A reduction clause with the task reduction-modifier may only appear on 2445 // a parallel construct, a worksharing construct or a combined or 2446 // composite construct for which any of the aforementioned constructs is a 2447 // constituent construct and simd or loop are not constituent constructs. 2448 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); 2449 if (!(isOpenMPParallelDirective(CurDir) || 2450 isOpenMPWorksharingDirective(CurDir)) || 2451 isOpenMPSimdDirective(CurDir)) 2452 S.Diag(RC->getModifierLoc(), 2453 diag::err_omp_reduction_task_not_parallel_or_worksharing); 2454 continue; 2455 } 2456 } 2457 if (InscanFound) { 2458 for (OMPClause *C : Clauses) { 2459 if (C->getClauseKind() != OMPC_reduction) 2460 continue; 2461 auto *RC = cast<OMPReductionClause>(C); 2462 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2463 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2464 ? RC->getBeginLoc() 2465 : RC->getModifierLoc(), 2466 diag::err_omp_inscan_reduction_expected); 2467 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2468 continue; 2469 } 2470 for (Expr *Ref : RC->varlists()) { 2471 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2472 SourceLocation ELoc; 2473 SourceRange ERange; 2474 Expr *SimpleRefExpr = Ref; 2475 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2476 /*AllowArraySection=*/true); 2477 ValueDecl *D = Res.first; 2478 if (!D) 2479 continue; 2480 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2481 S.Diag(Ref->getExprLoc(), 2482 diag::err_omp_reduction_not_inclusive_exclusive) 2483 << Ref->getSourceRange(); 2484 } 2485 } 2486 } 2487 } 2488 } 2489 2490 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2491 ArrayRef<OMPClause *> Clauses); 2492 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2493 bool WithInit); 2494 2495 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2496 const ValueDecl *D, 2497 const DSAStackTy::DSAVarData &DVar, 2498 bool IsLoopIterVar = false); 2499 2500 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2501 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2502 // A variable of class type (or array thereof) that appears in a lastprivate 2503 // clause requires an accessible, unambiguous default constructor for the 2504 // class type, unless the list item is also specified in a firstprivate 2505 // clause. 2506 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2507 for (OMPClause *C : D->clauses()) { 2508 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2509 SmallVector<Expr *, 8> PrivateCopies; 2510 for (Expr *DE : Clause->varlists()) { 2511 if (DE->isValueDependent() || DE->isTypeDependent()) { 2512 PrivateCopies.push_back(nullptr); 2513 continue; 2514 } 2515 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2516 auto *VD = cast<VarDecl>(DRE->getDecl()); 2517 QualType Type = VD->getType().getNonReferenceType(); 2518 const DSAStackTy::DSAVarData DVar = 2519 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2520 if (DVar.CKind == OMPC_lastprivate) { 2521 // Generate helper private variable and initialize it with the 2522 // default value. The address of the original variable is replaced 2523 // by the address of the new private variable in CodeGen. This new 2524 // variable is not added to IdResolver, so the code in the OpenMP 2525 // region uses original variable for proper diagnostics. 2526 VarDecl *VDPrivate = buildVarDecl( 2527 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2528 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2529 ActOnUninitializedDecl(VDPrivate); 2530 if (VDPrivate->isInvalidDecl()) { 2531 PrivateCopies.push_back(nullptr); 2532 continue; 2533 } 2534 PrivateCopies.push_back(buildDeclRefExpr( 2535 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2536 } else { 2537 // The variable is also a firstprivate, so initialization sequence 2538 // for private copy is generated already. 2539 PrivateCopies.push_back(nullptr); 2540 } 2541 } 2542 Clause->setPrivateCopies(PrivateCopies); 2543 continue; 2544 } 2545 // Finalize nontemporal clause by handling private copies, if any. 2546 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2547 SmallVector<Expr *, 8> PrivateRefs; 2548 for (Expr *RefExpr : Clause->varlists()) { 2549 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2550 SourceLocation ELoc; 2551 SourceRange ERange; 2552 Expr *SimpleRefExpr = RefExpr; 2553 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2554 if (Res.second) 2555 // It will be analyzed later. 2556 PrivateRefs.push_back(RefExpr); 2557 ValueDecl *D = Res.first; 2558 if (!D) 2559 continue; 2560 2561 const DSAStackTy::DSAVarData DVar = 2562 DSAStack->getTopDSA(D, /*FromParent=*/false); 2563 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2564 : SimpleRefExpr); 2565 } 2566 Clause->setPrivateRefs(PrivateRefs); 2567 continue; 2568 } 2569 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { 2570 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { 2571 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); 2572 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); 2573 if (!DRE) 2574 continue; 2575 ValueDecl *VD = DRE->getDecl(); 2576 if (!VD || !isa<VarDecl>(VD)) 2577 continue; 2578 DSAStackTy::DSAVarData DVar = 2579 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2580 // OpenMP [2.12.5, target Construct] 2581 // Memory allocators that appear in a uses_allocators clause cannot 2582 // appear in other data-sharing attribute clauses or data-mapping 2583 // attribute clauses in the same construct. 2584 Expr *MapExpr = nullptr; 2585 if (DVar.RefExpr || 2586 DSAStack->checkMappableExprComponentListsForDecl( 2587 VD, /*CurrentRegionOnly=*/true, 2588 [VD, &MapExpr]( 2589 OMPClauseMappableExprCommon::MappableExprComponentListRef 2590 MapExprComponents, 2591 OpenMPClauseKind C) { 2592 auto MI = MapExprComponents.rbegin(); 2593 auto ME = MapExprComponents.rend(); 2594 if (MI != ME && 2595 MI->getAssociatedDeclaration()->getCanonicalDecl() == 2596 VD->getCanonicalDecl()) { 2597 MapExpr = MI->getAssociatedExpression(); 2598 return true; 2599 } 2600 return false; 2601 })) { 2602 Diag(D.Allocator->getExprLoc(), 2603 diag::err_omp_allocator_used_in_clauses) 2604 << D.Allocator->getSourceRange(); 2605 if (DVar.RefExpr) 2606 reportOriginalDsa(*this, DSAStack, VD, DVar); 2607 else 2608 Diag(MapExpr->getExprLoc(), diag::note_used_here) 2609 << MapExpr->getSourceRange(); 2610 } 2611 } 2612 continue; 2613 } 2614 } 2615 // Check allocate clauses. 2616 if (!CurContext->isDependentContext()) 2617 checkAllocateClauses(*this, DSAStack, D->clauses()); 2618 checkReductionClauses(*this, DSAStack, D->clauses()); 2619 } 2620 2621 DSAStack->pop(); 2622 DiscardCleanupsInEvaluationContext(); 2623 PopExpressionEvaluationContext(); 2624 } 2625 2626 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2627 Expr *NumIterations, Sema &SemaRef, 2628 Scope *S, DSAStackTy *Stack); 2629 2630 namespace { 2631 2632 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2633 private: 2634 Sema &SemaRef; 2635 2636 public: 2637 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2638 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2639 NamedDecl *ND = Candidate.getCorrectionDecl(); 2640 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2641 return VD->hasGlobalStorage() && 2642 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2643 SemaRef.getCurScope()); 2644 } 2645 return false; 2646 } 2647 2648 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2649 return std::make_unique<VarDeclFilterCCC>(*this); 2650 } 2651 2652 }; 2653 2654 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2655 private: 2656 Sema &SemaRef; 2657 2658 public: 2659 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2660 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2661 NamedDecl *ND = Candidate.getCorrectionDecl(); 2662 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2663 isa<FunctionDecl>(ND))) { 2664 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2665 SemaRef.getCurScope()); 2666 } 2667 return false; 2668 } 2669 2670 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2671 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2672 } 2673 }; 2674 2675 } // namespace 2676 2677 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2678 CXXScopeSpec &ScopeSpec, 2679 const DeclarationNameInfo &Id, 2680 OpenMPDirectiveKind Kind) { 2681 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2682 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2683 2684 if (Lookup.isAmbiguous()) 2685 return ExprError(); 2686 2687 VarDecl *VD; 2688 if (!Lookup.isSingleResult()) { 2689 VarDeclFilterCCC CCC(*this); 2690 if (TypoCorrection Corrected = 2691 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2692 CTK_ErrorRecovery)) { 2693 diagnoseTypo(Corrected, 2694 PDiag(Lookup.empty() 2695 ? diag::err_undeclared_var_use_suggest 2696 : diag::err_omp_expected_var_arg_suggest) 2697 << Id.getName()); 2698 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2699 } else { 2700 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2701 : diag::err_omp_expected_var_arg) 2702 << Id.getName(); 2703 return ExprError(); 2704 } 2705 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2706 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2707 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2708 return ExprError(); 2709 } 2710 Lookup.suppressDiagnostics(); 2711 2712 // OpenMP [2.9.2, Syntax, C/C++] 2713 // Variables must be file-scope, namespace-scope, or static block-scope. 2714 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2715 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2716 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2717 bool IsDecl = 2718 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2719 Diag(VD->getLocation(), 2720 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2721 << VD; 2722 return ExprError(); 2723 } 2724 2725 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2726 NamedDecl *ND = CanonicalVD; 2727 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2728 // A threadprivate directive for file-scope variables must appear outside 2729 // any definition or declaration. 2730 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2731 !getCurLexicalContext()->isTranslationUnit()) { 2732 Diag(Id.getLoc(), diag::err_omp_var_scope) 2733 << getOpenMPDirectiveName(Kind) << VD; 2734 bool IsDecl = 2735 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2736 Diag(VD->getLocation(), 2737 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2738 << VD; 2739 return ExprError(); 2740 } 2741 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2742 // A threadprivate directive for static class member variables must appear 2743 // in the class definition, in the same scope in which the member 2744 // variables are declared. 2745 if (CanonicalVD->isStaticDataMember() && 2746 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2747 Diag(Id.getLoc(), diag::err_omp_var_scope) 2748 << getOpenMPDirectiveName(Kind) << VD; 2749 bool IsDecl = 2750 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2751 Diag(VD->getLocation(), 2752 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2753 << VD; 2754 return ExprError(); 2755 } 2756 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2757 // A threadprivate directive for namespace-scope variables must appear 2758 // outside any definition or declaration other than the namespace 2759 // definition itself. 2760 if (CanonicalVD->getDeclContext()->isNamespace() && 2761 (!getCurLexicalContext()->isFileContext() || 2762 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2763 Diag(Id.getLoc(), diag::err_omp_var_scope) 2764 << getOpenMPDirectiveName(Kind) << VD; 2765 bool IsDecl = 2766 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2767 Diag(VD->getLocation(), 2768 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2769 << VD; 2770 return ExprError(); 2771 } 2772 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2773 // A threadprivate directive for static block-scope variables must appear 2774 // in the scope of the variable and not in a nested scope. 2775 if (CanonicalVD->isLocalVarDecl() && CurScope && 2776 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2777 Diag(Id.getLoc(), diag::err_omp_var_scope) 2778 << getOpenMPDirectiveName(Kind) << VD; 2779 bool IsDecl = 2780 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2781 Diag(VD->getLocation(), 2782 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2783 << VD; 2784 return ExprError(); 2785 } 2786 2787 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2788 // A threadprivate directive must lexically precede all references to any 2789 // of the variables in its list. 2790 if (Kind == OMPD_threadprivate && VD->isUsed() && 2791 !DSAStack->isThreadPrivate(VD)) { 2792 Diag(Id.getLoc(), diag::err_omp_var_used) 2793 << getOpenMPDirectiveName(Kind) << VD; 2794 return ExprError(); 2795 } 2796 2797 QualType ExprType = VD->getType().getNonReferenceType(); 2798 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2799 SourceLocation(), VD, 2800 /*RefersToEnclosingVariableOrCapture=*/false, 2801 Id.getLoc(), ExprType, VK_LValue); 2802 } 2803 2804 Sema::DeclGroupPtrTy 2805 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2806 ArrayRef<Expr *> VarList) { 2807 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2808 CurContext->addDecl(D); 2809 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2810 } 2811 return nullptr; 2812 } 2813 2814 namespace { 2815 class LocalVarRefChecker final 2816 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2817 Sema &SemaRef; 2818 2819 public: 2820 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2821 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2822 if (VD->hasLocalStorage()) { 2823 SemaRef.Diag(E->getBeginLoc(), 2824 diag::err_omp_local_var_in_threadprivate_init) 2825 << E->getSourceRange(); 2826 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2827 << VD << VD->getSourceRange(); 2828 return true; 2829 } 2830 } 2831 return false; 2832 } 2833 bool VisitStmt(const Stmt *S) { 2834 for (const Stmt *Child : S->children()) { 2835 if (Child && Visit(Child)) 2836 return true; 2837 } 2838 return false; 2839 } 2840 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2841 }; 2842 } // namespace 2843 2844 OMPThreadPrivateDecl * 2845 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2846 SmallVector<Expr *, 8> Vars; 2847 for (Expr *RefExpr : VarList) { 2848 auto *DE = cast<DeclRefExpr>(RefExpr); 2849 auto *VD = cast<VarDecl>(DE->getDecl()); 2850 SourceLocation ILoc = DE->getExprLoc(); 2851 2852 // Mark variable as used. 2853 VD->setReferenced(); 2854 VD->markUsed(Context); 2855 2856 QualType QType = VD->getType(); 2857 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2858 // It will be analyzed later. 2859 Vars.push_back(DE); 2860 continue; 2861 } 2862 2863 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2864 // A threadprivate variable must not have an incomplete type. 2865 if (RequireCompleteType(ILoc, VD->getType(), 2866 diag::err_omp_threadprivate_incomplete_type)) { 2867 continue; 2868 } 2869 2870 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2871 // A threadprivate variable must not have a reference type. 2872 if (VD->getType()->isReferenceType()) { 2873 Diag(ILoc, diag::err_omp_ref_type_arg) 2874 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2875 bool IsDecl = 2876 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2877 Diag(VD->getLocation(), 2878 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2879 << VD; 2880 continue; 2881 } 2882 2883 // Check if this is a TLS variable. If TLS is not being supported, produce 2884 // the corresponding diagnostic. 2885 if ((VD->getTLSKind() != VarDecl::TLS_None && 2886 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2887 getLangOpts().OpenMPUseTLS && 2888 getASTContext().getTargetInfo().isTLSSupported())) || 2889 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2890 !VD->isLocalVarDecl())) { 2891 Diag(ILoc, diag::err_omp_var_thread_local) 2892 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2893 bool IsDecl = 2894 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2895 Diag(VD->getLocation(), 2896 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2897 << VD; 2898 continue; 2899 } 2900 2901 // Check if initial value of threadprivate variable reference variable with 2902 // local storage (it is not supported by runtime). 2903 if (const Expr *Init = VD->getAnyInitializer()) { 2904 LocalVarRefChecker Checker(*this); 2905 if (Checker.Visit(Init)) 2906 continue; 2907 } 2908 2909 Vars.push_back(RefExpr); 2910 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2911 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2912 Context, SourceRange(Loc, Loc))); 2913 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2914 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2915 } 2916 OMPThreadPrivateDecl *D = nullptr; 2917 if (!Vars.empty()) { 2918 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2919 Vars); 2920 D->setAccess(AS_public); 2921 } 2922 return D; 2923 } 2924 2925 static OMPAllocateDeclAttr::AllocatorTypeTy 2926 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2927 if (!Allocator) 2928 return OMPAllocateDeclAttr::OMPNullMemAlloc; 2929 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2930 Allocator->isInstantiationDependent() || 2931 Allocator->containsUnexpandedParameterPack()) 2932 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2933 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2934 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2935 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2936 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2937 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2938 llvm::FoldingSetNodeID AEId, DAEId; 2939 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2940 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2941 if (AEId == DAEId) { 2942 AllocatorKindRes = AllocatorKind; 2943 break; 2944 } 2945 } 2946 return AllocatorKindRes; 2947 } 2948 2949 static bool checkPreviousOMPAllocateAttribute( 2950 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2951 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2952 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2953 return false; 2954 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2955 Expr *PrevAllocator = A->getAllocator(); 2956 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2957 getAllocatorKind(S, Stack, PrevAllocator); 2958 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2959 if (AllocatorsMatch && 2960 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2961 Allocator && PrevAllocator) { 2962 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2963 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2964 llvm::FoldingSetNodeID AEId, PAEId; 2965 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2966 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2967 AllocatorsMatch = AEId == PAEId; 2968 } 2969 if (!AllocatorsMatch) { 2970 SmallString<256> AllocatorBuffer; 2971 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2972 if (Allocator) 2973 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2974 SmallString<256> PrevAllocatorBuffer; 2975 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2976 if (PrevAllocator) 2977 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2978 S.getPrintingPolicy()); 2979 2980 SourceLocation AllocatorLoc = 2981 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2982 SourceRange AllocatorRange = 2983 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2984 SourceLocation PrevAllocatorLoc = 2985 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2986 SourceRange PrevAllocatorRange = 2987 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2988 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2989 << (Allocator ? 1 : 0) << AllocatorStream.str() 2990 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2991 << AllocatorRange; 2992 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2993 << PrevAllocatorRange; 2994 return true; 2995 } 2996 return false; 2997 } 2998 2999 static void 3000 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 3001 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 3002 Expr *Allocator, SourceRange SR) { 3003 if (VD->hasAttr<OMPAllocateDeclAttr>()) 3004 return; 3005 if (Allocator && 3006 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3007 Allocator->isInstantiationDependent() || 3008 Allocator->containsUnexpandedParameterPack())) 3009 return; 3010 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 3011 Allocator, SR); 3012 VD->addAttr(A); 3013 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 3014 ML->DeclarationMarkedOpenMPAllocate(VD, A); 3015 } 3016 3017 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 3018 SourceLocation Loc, ArrayRef<Expr *> VarList, 3019 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 3020 assert(Clauses.size() <= 1 && "Expected at most one clause."); 3021 Expr *Allocator = nullptr; 3022 if (Clauses.empty()) { 3023 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 3024 // allocate directives that appear in a target region must specify an 3025 // allocator clause unless a requires directive with the dynamic_allocators 3026 // clause is present in the same compilation unit. 3027 if (LangOpts.OpenMPIsDevice && 3028 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 3029 targetDiag(Loc, diag::err_expected_allocator_clause); 3030 } else { 3031 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 3032 } 3033 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3034 getAllocatorKind(*this, DSAStack, Allocator); 3035 SmallVector<Expr *, 8> Vars; 3036 for (Expr *RefExpr : VarList) { 3037 auto *DE = cast<DeclRefExpr>(RefExpr); 3038 auto *VD = cast<VarDecl>(DE->getDecl()); 3039 3040 // Check if this is a TLS variable or global register. 3041 if (VD->getTLSKind() != VarDecl::TLS_None || 3042 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 3043 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3044 !VD->isLocalVarDecl())) 3045 continue; 3046 3047 // If the used several times in the allocate directive, the same allocator 3048 // must be used. 3049 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 3050 AllocatorKind, Allocator)) 3051 continue; 3052 3053 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 3054 // If a list item has a static storage type, the allocator expression in the 3055 // allocator clause must be a constant expression that evaluates to one of 3056 // the predefined memory allocator values. 3057 if (Allocator && VD->hasGlobalStorage()) { 3058 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 3059 Diag(Allocator->getExprLoc(), 3060 diag::err_omp_expected_predefined_allocator) 3061 << Allocator->getSourceRange(); 3062 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 3063 VarDecl::DeclarationOnly; 3064 Diag(VD->getLocation(), 3065 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3066 << VD; 3067 continue; 3068 } 3069 } 3070 3071 Vars.push_back(RefExpr); 3072 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 3073 DE->getSourceRange()); 3074 } 3075 if (Vars.empty()) 3076 return nullptr; 3077 if (!Owner) 3078 Owner = getCurLexicalContext(); 3079 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 3080 D->setAccess(AS_public); 3081 Owner->addDecl(D); 3082 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3083 } 3084 3085 Sema::DeclGroupPtrTy 3086 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 3087 ArrayRef<OMPClause *> ClauseList) { 3088 OMPRequiresDecl *D = nullptr; 3089 if (!CurContext->isFileContext()) { 3090 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 3091 } else { 3092 D = CheckOMPRequiresDecl(Loc, ClauseList); 3093 if (D) { 3094 CurContext->addDecl(D); 3095 DSAStack->addRequiresDecl(D); 3096 } 3097 } 3098 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3099 } 3100 3101 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 3102 ArrayRef<OMPClause *> ClauseList) { 3103 /// For target specific clauses, the requires directive cannot be 3104 /// specified after the handling of any of the target regions in the 3105 /// current compilation unit. 3106 ArrayRef<SourceLocation> TargetLocations = 3107 DSAStack->getEncounteredTargetLocs(); 3108 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 3109 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 3110 for (const OMPClause *CNew : ClauseList) { 3111 // Check if any of the requires clauses affect target regions. 3112 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 3113 isa<OMPUnifiedAddressClause>(CNew) || 3114 isa<OMPReverseOffloadClause>(CNew) || 3115 isa<OMPDynamicAllocatorsClause>(CNew)) { 3116 Diag(Loc, diag::err_omp_directive_before_requires) 3117 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 3118 for (SourceLocation TargetLoc : TargetLocations) { 3119 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 3120 << "target"; 3121 } 3122 } else if (!AtomicLoc.isInvalid() && 3123 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 3124 Diag(Loc, diag::err_omp_directive_before_requires) 3125 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 3126 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 3127 << "atomic"; 3128 } 3129 } 3130 } 3131 3132 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 3133 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3134 ClauseList); 3135 return nullptr; 3136 } 3137 3138 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3139 const ValueDecl *D, 3140 const DSAStackTy::DSAVarData &DVar, 3141 bool IsLoopIterVar) { 3142 if (DVar.RefExpr) { 3143 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3144 << getOpenMPClauseName(DVar.CKind); 3145 return; 3146 } 3147 enum { 3148 PDSA_StaticMemberShared, 3149 PDSA_StaticLocalVarShared, 3150 PDSA_LoopIterVarPrivate, 3151 PDSA_LoopIterVarLinear, 3152 PDSA_LoopIterVarLastprivate, 3153 PDSA_ConstVarShared, 3154 PDSA_GlobalVarShared, 3155 PDSA_TaskVarFirstprivate, 3156 PDSA_LocalVarPrivate, 3157 PDSA_Implicit 3158 } Reason = PDSA_Implicit; 3159 bool ReportHint = false; 3160 auto ReportLoc = D->getLocation(); 3161 auto *VD = dyn_cast<VarDecl>(D); 3162 if (IsLoopIterVar) { 3163 if (DVar.CKind == OMPC_private) 3164 Reason = PDSA_LoopIterVarPrivate; 3165 else if (DVar.CKind == OMPC_lastprivate) 3166 Reason = PDSA_LoopIterVarLastprivate; 3167 else 3168 Reason = PDSA_LoopIterVarLinear; 3169 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3170 DVar.CKind == OMPC_firstprivate) { 3171 Reason = PDSA_TaskVarFirstprivate; 3172 ReportLoc = DVar.ImplicitDSALoc; 3173 } else if (VD && VD->isStaticLocal()) 3174 Reason = PDSA_StaticLocalVarShared; 3175 else if (VD && VD->isStaticDataMember()) 3176 Reason = PDSA_StaticMemberShared; 3177 else if (VD && VD->isFileVarDecl()) 3178 Reason = PDSA_GlobalVarShared; 3179 else if (D->getType().isConstant(SemaRef.getASTContext())) 3180 Reason = PDSA_ConstVarShared; 3181 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3182 ReportHint = true; 3183 Reason = PDSA_LocalVarPrivate; 3184 } 3185 if (Reason != PDSA_Implicit) { 3186 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3187 << Reason << ReportHint 3188 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3189 } else if (DVar.ImplicitDSALoc.isValid()) { 3190 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3191 << getOpenMPClauseName(DVar.CKind); 3192 } 3193 } 3194 3195 static OpenMPMapClauseKind 3196 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3197 bool IsAggregateOrDeclareTarget) { 3198 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3199 switch (M) { 3200 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3201 Kind = OMPC_MAP_alloc; 3202 break; 3203 case OMPC_DEFAULTMAP_MODIFIER_to: 3204 Kind = OMPC_MAP_to; 3205 break; 3206 case OMPC_DEFAULTMAP_MODIFIER_from: 3207 Kind = OMPC_MAP_from; 3208 break; 3209 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3210 Kind = OMPC_MAP_tofrom; 3211 break; 3212 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3213 case OMPC_DEFAULTMAP_MODIFIER_last: 3214 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3215 case OMPC_DEFAULTMAP_MODIFIER_none: 3216 case OMPC_DEFAULTMAP_MODIFIER_default: 3217 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3218 // IsAggregateOrDeclareTarget could be true if: 3219 // 1. the implicit behavior for aggregate is tofrom 3220 // 2. it's a declare target link 3221 if (IsAggregateOrDeclareTarget) { 3222 Kind = OMPC_MAP_tofrom; 3223 break; 3224 } 3225 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3226 } 3227 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3228 return Kind; 3229 } 3230 3231 namespace { 3232 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3233 DSAStackTy *Stack; 3234 Sema &SemaRef; 3235 bool ErrorFound = false; 3236 bool TryCaptureCXXThisMembers = false; 3237 CapturedStmt *CS = nullptr; 3238 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3239 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 3240 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3241 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3242 3243 void VisitSubCaptures(OMPExecutableDirective *S) { 3244 // Check implicitly captured variables. 3245 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 3246 return; 3247 visitSubCaptures(S->getInnermostCapturedStmt()); 3248 // Try to capture inner this->member references to generate correct mappings 3249 // and diagnostics. 3250 if (TryCaptureCXXThisMembers || 3251 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3252 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3253 [](const CapturedStmt::Capture &C) { 3254 return C.capturesThis(); 3255 }))) { 3256 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3257 TryCaptureCXXThisMembers = true; 3258 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3259 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3260 } 3261 // In tasks firstprivates are not captured anymore, need to analyze them 3262 // explicitly. 3263 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3264 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3265 for (OMPClause *C : S->clauses()) 3266 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3267 for (Expr *Ref : FC->varlists()) 3268 Visit(Ref); 3269 } 3270 } 3271 } 3272 3273 public: 3274 void VisitDeclRefExpr(DeclRefExpr *E) { 3275 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3276 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3277 E->isInstantiationDependent()) 3278 return; 3279 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3280 // Check the datasharing rules for the expressions in the clauses. 3281 if (!CS) { 3282 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3283 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3284 Visit(CED->getInit()); 3285 return; 3286 } 3287 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3288 // Do not analyze internal variables and do not enclose them into 3289 // implicit clauses. 3290 return; 3291 VD = VD->getCanonicalDecl(); 3292 // Skip internally declared variables. 3293 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3294 !Stack->isImplicitTaskFirstprivate(VD)) 3295 return; 3296 // Skip allocators in uses_allocators clauses. 3297 if (Stack->isUsesAllocatorsDecl(VD).hasValue()) 3298 return; 3299 3300 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3301 // Check if the variable has explicit DSA set and stop analysis if it so. 3302 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3303 return; 3304 3305 // Skip internally declared static variables. 3306 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3307 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3308 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3309 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3310 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3311 !Stack->isImplicitTaskFirstprivate(VD)) 3312 return; 3313 3314 SourceLocation ELoc = E->getExprLoc(); 3315 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3316 // The default(none) clause requires that each variable that is referenced 3317 // in the construct, and does not have a predetermined data-sharing 3318 // attribute, must have its data-sharing attribute explicitly determined 3319 // by being listed in a data-sharing attribute clause. 3320 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 3321 isImplicitOrExplicitTaskingRegion(DKind) && 3322 VarsWithInheritedDSA.count(VD) == 0) { 3323 VarsWithInheritedDSA[VD] = E; 3324 return; 3325 } 3326 3327 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3328 // If implicit-behavior is none, each variable referenced in the 3329 // construct that does not have a predetermined data-sharing attribute 3330 // and does not appear in a to or link clause on a declare target 3331 // directive must be listed in a data-mapping attribute clause, a 3332 // data-haring attribute clause (including a data-sharing attribute 3333 // clause on a combined construct where target. is one of the 3334 // constituent constructs), or an is_device_ptr clause. 3335 OpenMPDefaultmapClauseKind ClauseKind = 3336 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3337 if (SemaRef.getLangOpts().OpenMP >= 50) { 3338 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3339 OMPC_DEFAULTMAP_MODIFIER_none; 3340 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3341 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3342 // Only check for data-mapping attribute and is_device_ptr here 3343 // since we have already make sure that the declaration does not 3344 // have a data-sharing attribute above 3345 if (!Stack->checkMappableExprComponentListsForDecl( 3346 VD, /*CurrentRegionOnly=*/true, 3347 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3348 MapExprComponents, 3349 OpenMPClauseKind) { 3350 auto MI = MapExprComponents.rbegin(); 3351 auto ME = MapExprComponents.rend(); 3352 return MI != ME && MI->getAssociatedDeclaration() == VD; 3353 })) { 3354 VarsWithInheritedDSA[VD] = E; 3355 return; 3356 } 3357 } 3358 } 3359 3360 if (isOpenMPTargetExecutionDirective(DKind) && 3361 !Stack->isLoopControlVariable(VD).first) { 3362 if (!Stack->checkMappableExprComponentListsForDecl( 3363 VD, /*CurrentRegionOnly=*/true, 3364 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3365 StackComponents, 3366 OpenMPClauseKind) { 3367 // Variable is used if it has been marked as an array, array 3368 // section, array shaping or the variable iself. 3369 return StackComponents.size() == 1 || 3370 std::all_of( 3371 std::next(StackComponents.rbegin()), 3372 StackComponents.rend(), 3373 [](const OMPClauseMappableExprCommon:: 3374 MappableComponent &MC) { 3375 return MC.getAssociatedDeclaration() == 3376 nullptr && 3377 (isa<OMPArraySectionExpr>( 3378 MC.getAssociatedExpression()) || 3379 isa<OMPArrayShapingExpr>( 3380 MC.getAssociatedExpression()) || 3381 isa<ArraySubscriptExpr>( 3382 MC.getAssociatedExpression())); 3383 }); 3384 })) { 3385 bool IsFirstprivate = false; 3386 // By default lambdas are captured as firstprivates. 3387 if (const auto *RD = 3388 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3389 IsFirstprivate = RD->isLambda(); 3390 IsFirstprivate = 3391 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3392 if (IsFirstprivate) { 3393 ImplicitFirstprivate.emplace_back(E); 3394 } else { 3395 OpenMPDefaultmapClauseModifier M = 3396 Stack->getDefaultmapModifier(ClauseKind); 3397 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3398 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3399 ImplicitMap[Kind].emplace_back(E); 3400 } 3401 return; 3402 } 3403 } 3404 3405 // OpenMP [2.9.3.6, Restrictions, p.2] 3406 // A list item that appears in a reduction clause of the innermost 3407 // enclosing worksharing or parallel construct may not be accessed in an 3408 // explicit task. 3409 DVar = Stack->hasInnermostDSA( 3410 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3411 [](OpenMPDirectiveKind K) { 3412 return isOpenMPParallelDirective(K) || 3413 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3414 }, 3415 /*FromParent=*/true); 3416 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3417 ErrorFound = true; 3418 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3419 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3420 return; 3421 } 3422 3423 // Define implicit data-sharing attributes for task. 3424 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3425 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3426 !Stack->isLoopControlVariable(VD).first) { 3427 ImplicitFirstprivate.push_back(E); 3428 return; 3429 } 3430 3431 // Store implicitly used globals with declare target link for parent 3432 // target. 3433 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3434 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3435 Stack->addToParentTargetRegionLinkGlobals(E); 3436 return; 3437 } 3438 } 3439 } 3440 void VisitMemberExpr(MemberExpr *E) { 3441 if (E->isTypeDependent() || E->isValueDependent() || 3442 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3443 return; 3444 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3445 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3446 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3447 if (!FD) 3448 return; 3449 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3450 // Check if the variable has explicit DSA set and stop analysis if it 3451 // so. 3452 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3453 return; 3454 3455 if (isOpenMPTargetExecutionDirective(DKind) && 3456 !Stack->isLoopControlVariable(FD).first && 3457 !Stack->checkMappableExprComponentListsForDecl( 3458 FD, /*CurrentRegionOnly=*/true, 3459 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3460 StackComponents, 3461 OpenMPClauseKind) { 3462 return isa<CXXThisExpr>( 3463 cast<MemberExpr>( 3464 StackComponents.back().getAssociatedExpression()) 3465 ->getBase() 3466 ->IgnoreParens()); 3467 })) { 3468 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3469 // A bit-field cannot appear in a map clause. 3470 // 3471 if (FD->isBitField()) 3472 return; 3473 3474 // Check to see if the member expression is referencing a class that 3475 // has already been explicitly mapped 3476 if (Stack->isClassPreviouslyMapped(TE->getType())) 3477 return; 3478 3479 OpenMPDefaultmapClauseModifier Modifier = 3480 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3481 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3482 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3483 ImplicitMap[Kind].emplace_back(E); 3484 return; 3485 } 3486 3487 SourceLocation ELoc = E->getExprLoc(); 3488 // OpenMP [2.9.3.6, Restrictions, p.2] 3489 // A list item that appears in a reduction clause of the innermost 3490 // enclosing worksharing or parallel construct may not be accessed in 3491 // an explicit task. 3492 DVar = Stack->hasInnermostDSA( 3493 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3494 [](OpenMPDirectiveKind K) { 3495 return isOpenMPParallelDirective(K) || 3496 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3497 }, 3498 /*FromParent=*/true); 3499 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3500 ErrorFound = true; 3501 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3502 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3503 return; 3504 } 3505 3506 // Define implicit data-sharing attributes for task. 3507 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3508 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3509 !Stack->isLoopControlVariable(FD).first) { 3510 // Check if there is a captured expression for the current field in the 3511 // region. Do not mark it as firstprivate unless there is no captured 3512 // expression. 3513 // TODO: try to make it firstprivate. 3514 if (DVar.CKind != OMPC_unknown) 3515 ImplicitFirstprivate.push_back(E); 3516 } 3517 return; 3518 } 3519 if (isOpenMPTargetExecutionDirective(DKind)) { 3520 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3521 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3522 /*NoDiagnose=*/true)) 3523 return; 3524 const auto *VD = cast<ValueDecl>( 3525 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3526 if (!Stack->checkMappableExprComponentListsForDecl( 3527 VD, /*CurrentRegionOnly=*/true, 3528 [&CurComponents]( 3529 OMPClauseMappableExprCommon::MappableExprComponentListRef 3530 StackComponents, 3531 OpenMPClauseKind) { 3532 auto CCI = CurComponents.rbegin(); 3533 auto CCE = CurComponents.rend(); 3534 for (const auto &SC : llvm::reverse(StackComponents)) { 3535 // Do both expressions have the same kind? 3536 if (CCI->getAssociatedExpression()->getStmtClass() != 3537 SC.getAssociatedExpression()->getStmtClass()) 3538 if (!((isa<OMPArraySectionExpr>( 3539 SC.getAssociatedExpression()) || 3540 isa<OMPArrayShapingExpr>( 3541 SC.getAssociatedExpression())) && 3542 isa<ArraySubscriptExpr>( 3543 CCI->getAssociatedExpression()))) 3544 return false; 3545 3546 const Decl *CCD = CCI->getAssociatedDeclaration(); 3547 const Decl *SCD = SC.getAssociatedDeclaration(); 3548 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3549 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3550 if (SCD != CCD) 3551 return false; 3552 std::advance(CCI, 1); 3553 if (CCI == CCE) 3554 break; 3555 } 3556 return true; 3557 })) { 3558 Visit(E->getBase()); 3559 } 3560 } else if (!TryCaptureCXXThisMembers) { 3561 Visit(E->getBase()); 3562 } 3563 } 3564 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3565 for (OMPClause *C : S->clauses()) { 3566 // Skip analysis of arguments of implicitly defined firstprivate clause 3567 // for task|target directives. 3568 // Skip analysis of arguments of implicitly defined map clause for target 3569 // directives. 3570 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3571 C->isImplicit())) { 3572 for (Stmt *CC : C->children()) { 3573 if (CC) 3574 Visit(CC); 3575 } 3576 } 3577 } 3578 // Check implicitly captured variables. 3579 VisitSubCaptures(S); 3580 } 3581 void VisitStmt(Stmt *S) { 3582 for (Stmt *C : S->children()) { 3583 if (C) { 3584 // Check implicitly captured variables in the task-based directives to 3585 // check if they must be firstprivatized. 3586 Visit(C); 3587 } 3588 } 3589 } 3590 3591 void visitSubCaptures(CapturedStmt *S) { 3592 for (const CapturedStmt::Capture &Cap : S->captures()) { 3593 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3594 continue; 3595 VarDecl *VD = Cap.getCapturedVar(); 3596 // Do not try to map the variable if it or its sub-component was mapped 3597 // already. 3598 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3599 Stack->checkMappableExprComponentListsForDecl( 3600 VD, /*CurrentRegionOnly=*/true, 3601 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3602 OpenMPClauseKind) { return true; })) 3603 continue; 3604 DeclRefExpr *DRE = buildDeclRefExpr( 3605 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3606 Cap.getLocation(), /*RefersToCapture=*/true); 3607 Visit(DRE); 3608 } 3609 } 3610 bool isErrorFound() const { return ErrorFound; } 3611 ArrayRef<Expr *> getImplicitFirstprivate() const { 3612 return ImplicitFirstprivate; 3613 } 3614 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3615 return ImplicitMap[Kind]; 3616 } 3617 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3618 return VarsWithInheritedDSA; 3619 } 3620 3621 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3622 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3623 // Process declare target link variables for the target directives. 3624 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3625 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3626 Visit(E); 3627 } 3628 } 3629 }; 3630 } // namespace 3631 3632 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3633 switch (DKind) { 3634 case OMPD_parallel: 3635 case OMPD_parallel_for: 3636 case OMPD_parallel_for_simd: 3637 case OMPD_parallel_sections: 3638 case OMPD_parallel_master: 3639 case OMPD_teams: 3640 case OMPD_teams_distribute: 3641 case OMPD_teams_distribute_simd: { 3642 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3643 QualType KmpInt32PtrTy = 3644 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3645 Sema::CapturedParamNameType Params[] = { 3646 std::make_pair(".global_tid.", KmpInt32PtrTy), 3647 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3648 std::make_pair(StringRef(), QualType()) // __context with shared vars 3649 }; 3650 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3651 Params); 3652 break; 3653 } 3654 case OMPD_target_teams: 3655 case OMPD_target_parallel: 3656 case OMPD_target_parallel_for: 3657 case OMPD_target_parallel_for_simd: 3658 case OMPD_target_teams_distribute: 3659 case OMPD_target_teams_distribute_simd: { 3660 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3661 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3662 QualType KmpInt32PtrTy = 3663 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3664 QualType Args[] = {VoidPtrTy}; 3665 FunctionProtoType::ExtProtoInfo EPI; 3666 EPI.Variadic = true; 3667 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3668 Sema::CapturedParamNameType Params[] = { 3669 std::make_pair(".global_tid.", KmpInt32Ty), 3670 std::make_pair(".part_id.", KmpInt32PtrTy), 3671 std::make_pair(".privates.", VoidPtrTy), 3672 std::make_pair( 3673 ".copy_fn.", 3674 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3675 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3676 std::make_pair(StringRef(), QualType()) // __context with shared vars 3677 }; 3678 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3679 Params, /*OpenMPCaptureLevel=*/0); 3680 // Mark this captured region as inlined, because we don't use outlined 3681 // function directly. 3682 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3683 AlwaysInlineAttr::CreateImplicit( 3684 Context, {}, AttributeCommonInfo::AS_Keyword, 3685 AlwaysInlineAttr::Keyword_forceinline)); 3686 Sema::CapturedParamNameType ParamsTarget[] = { 3687 std::make_pair(StringRef(), QualType()) // __context with shared vars 3688 }; 3689 // Start a captured region for 'target' with no implicit parameters. 3690 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3691 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3692 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3693 std::make_pair(".global_tid.", KmpInt32PtrTy), 3694 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3695 std::make_pair(StringRef(), QualType()) // __context with shared vars 3696 }; 3697 // Start a captured region for 'teams' or 'parallel'. Both regions have 3698 // the same implicit parameters. 3699 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3700 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3701 break; 3702 } 3703 case OMPD_target: 3704 case OMPD_target_simd: { 3705 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3706 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3707 QualType KmpInt32PtrTy = 3708 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3709 QualType Args[] = {VoidPtrTy}; 3710 FunctionProtoType::ExtProtoInfo EPI; 3711 EPI.Variadic = true; 3712 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3713 Sema::CapturedParamNameType Params[] = { 3714 std::make_pair(".global_tid.", KmpInt32Ty), 3715 std::make_pair(".part_id.", KmpInt32PtrTy), 3716 std::make_pair(".privates.", VoidPtrTy), 3717 std::make_pair( 3718 ".copy_fn.", 3719 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3720 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3721 std::make_pair(StringRef(), QualType()) // __context with shared vars 3722 }; 3723 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3724 Params, /*OpenMPCaptureLevel=*/0); 3725 // Mark this captured region as inlined, because we don't use outlined 3726 // function directly. 3727 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3728 AlwaysInlineAttr::CreateImplicit( 3729 Context, {}, AttributeCommonInfo::AS_Keyword, 3730 AlwaysInlineAttr::Keyword_forceinline)); 3731 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3732 std::make_pair(StringRef(), QualType()), 3733 /*OpenMPCaptureLevel=*/1); 3734 break; 3735 } 3736 case OMPD_simd: 3737 case OMPD_for: 3738 case OMPD_for_simd: 3739 case OMPD_sections: 3740 case OMPD_section: 3741 case OMPD_single: 3742 case OMPD_master: 3743 case OMPD_critical: 3744 case OMPD_taskgroup: 3745 case OMPD_distribute: 3746 case OMPD_distribute_simd: 3747 case OMPD_ordered: 3748 case OMPD_atomic: 3749 case OMPD_target_data: { 3750 Sema::CapturedParamNameType Params[] = { 3751 std::make_pair(StringRef(), QualType()) // __context with shared vars 3752 }; 3753 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3754 Params); 3755 break; 3756 } 3757 case OMPD_task: { 3758 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3759 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3760 QualType KmpInt32PtrTy = 3761 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3762 QualType Args[] = {VoidPtrTy}; 3763 FunctionProtoType::ExtProtoInfo EPI; 3764 EPI.Variadic = true; 3765 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3766 Sema::CapturedParamNameType Params[] = { 3767 std::make_pair(".global_tid.", KmpInt32Ty), 3768 std::make_pair(".part_id.", KmpInt32PtrTy), 3769 std::make_pair(".privates.", VoidPtrTy), 3770 std::make_pair( 3771 ".copy_fn.", 3772 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3773 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3774 std::make_pair(StringRef(), QualType()) // __context with shared vars 3775 }; 3776 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3777 Params); 3778 // Mark this captured region as inlined, because we don't use outlined 3779 // function directly. 3780 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3781 AlwaysInlineAttr::CreateImplicit( 3782 Context, {}, AttributeCommonInfo::AS_Keyword, 3783 AlwaysInlineAttr::Keyword_forceinline)); 3784 break; 3785 } 3786 case OMPD_taskloop: 3787 case OMPD_taskloop_simd: 3788 case OMPD_master_taskloop: 3789 case OMPD_master_taskloop_simd: { 3790 QualType KmpInt32Ty = 3791 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3792 .withConst(); 3793 QualType KmpUInt64Ty = 3794 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3795 .withConst(); 3796 QualType KmpInt64Ty = 3797 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3798 .withConst(); 3799 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3800 QualType KmpInt32PtrTy = 3801 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3802 QualType Args[] = {VoidPtrTy}; 3803 FunctionProtoType::ExtProtoInfo EPI; 3804 EPI.Variadic = true; 3805 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3806 Sema::CapturedParamNameType Params[] = { 3807 std::make_pair(".global_tid.", KmpInt32Ty), 3808 std::make_pair(".part_id.", KmpInt32PtrTy), 3809 std::make_pair(".privates.", VoidPtrTy), 3810 std::make_pair( 3811 ".copy_fn.", 3812 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3813 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3814 std::make_pair(".lb.", KmpUInt64Ty), 3815 std::make_pair(".ub.", KmpUInt64Ty), 3816 std::make_pair(".st.", KmpInt64Ty), 3817 std::make_pair(".liter.", KmpInt32Ty), 3818 std::make_pair(".reductions.", VoidPtrTy), 3819 std::make_pair(StringRef(), QualType()) // __context with shared vars 3820 }; 3821 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3822 Params); 3823 // Mark this captured region as inlined, because we don't use outlined 3824 // function directly. 3825 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3826 AlwaysInlineAttr::CreateImplicit( 3827 Context, {}, AttributeCommonInfo::AS_Keyword, 3828 AlwaysInlineAttr::Keyword_forceinline)); 3829 break; 3830 } 3831 case OMPD_parallel_master_taskloop: 3832 case OMPD_parallel_master_taskloop_simd: { 3833 QualType KmpInt32Ty = 3834 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3835 .withConst(); 3836 QualType KmpUInt64Ty = 3837 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3838 .withConst(); 3839 QualType KmpInt64Ty = 3840 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3841 .withConst(); 3842 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3843 QualType KmpInt32PtrTy = 3844 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3845 Sema::CapturedParamNameType ParamsParallel[] = { 3846 std::make_pair(".global_tid.", KmpInt32PtrTy), 3847 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3848 std::make_pair(StringRef(), QualType()) // __context with shared vars 3849 }; 3850 // Start a captured region for 'parallel'. 3851 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3852 ParamsParallel, /*OpenMPCaptureLevel=*/0); 3853 QualType Args[] = {VoidPtrTy}; 3854 FunctionProtoType::ExtProtoInfo EPI; 3855 EPI.Variadic = true; 3856 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3857 Sema::CapturedParamNameType Params[] = { 3858 std::make_pair(".global_tid.", KmpInt32Ty), 3859 std::make_pair(".part_id.", KmpInt32PtrTy), 3860 std::make_pair(".privates.", VoidPtrTy), 3861 std::make_pair( 3862 ".copy_fn.", 3863 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3864 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3865 std::make_pair(".lb.", KmpUInt64Ty), 3866 std::make_pair(".ub.", KmpUInt64Ty), 3867 std::make_pair(".st.", KmpInt64Ty), 3868 std::make_pair(".liter.", KmpInt32Ty), 3869 std::make_pair(".reductions.", VoidPtrTy), 3870 std::make_pair(StringRef(), QualType()) // __context with shared vars 3871 }; 3872 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3873 Params, /*OpenMPCaptureLevel=*/1); 3874 // Mark this captured region as inlined, because we don't use outlined 3875 // function directly. 3876 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3877 AlwaysInlineAttr::CreateImplicit( 3878 Context, {}, AttributeCommonInfo::AS_Keyword, 3879 AlwaysInlineAttr::Keyword_forceinline)); 3880 break; 3881 } 3882 case OMPD_distribute_parallel_for_simd: 3883 case OMPD_distribute_parallel_for: { 3884 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3885 QualType KmpInt32PtrTy = 3886 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3887 Sema::CapturedParamNameType Params[] = { 3888 std::make_pair(".global_tid.", KmpInt32PtrTy), 3889 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3890 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3891 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3892 std::make_pair(StringRef(), QualType()) // __context with shared vars 3893 }; 3894 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3895 Params); 3896 break; 3897 } 3898 case OMPD_target_teams_distribute_parallel_for: 3899 case OMPD_target_teams_distribute_parallel_for_simd: { 3900 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3901 QualType KmpInt32PtrTy = 3902 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3903 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3904 3905 QualType Args[] = {VoidPtrTy}; 3906 FunctionProtoType::ExtProtoInfo EPI; 3907 EPI.Variadic = true; 3908 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3909 Sema::CapturedParamNameType Params[] = { 3910 std::make_pair(".global_tid.", KmpInt32Ty), 3911 std::make_pair(".part_id.", KmpInt32PtrTy), 3912 std::make_pair(".privates.", VoidPtrTy), 3913 std::make_pair( 3914 ".copy_fn.", 3915 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3916 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3917 std::make_pair(StringRef(), QualType()) // __context with shared vars 3918 }; 3919 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3920 Params, /*OpenMPCaptureLevel=*/0); 3921 // Mark this captured region as inlined, because we don't use outlined 3922 // function directly. 3923 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3924 AlwaysInlineAttr::CreateImplicit( 3925 Context, {}, AttributeCommonInfo::AS_Keyword, 3926 AlwaysInlineAttr::Keyword_forceinline)); 3927 Sema::CapturedParamNameType ParamsTarget[] = { 3928 std::make_pair(StringRef(), QualType()) // __context with shared vars 3929 }; 3930 // Start a captured region for 'target' with no implicit parameters. 3931 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3932 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3933 3934 Sema::CapturedParamNameType ParamsTeams[] = { 3935 std::make_pair(".global_tid.", KmpInt32PtrTy), 3936 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3937 std::make_pair(StringRef(), QualType()) // __context with shared vars 3938 }; 3939 // Start a captured region for 'target' with no implicit parameters. 3940 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3941 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3942 3943 Sema::CapturedParamNameType ParamsParallel[] = { 3944 std::make_pair(".global_tid.", KmpInt32PtrTy), 3945 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3946 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3947 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3948 std::make_pair(StringRef(), QualType()) // __context with shared vars 3949 }; 3950 // Start a captured region for 'teams' or 'parallel'. Both regions have 3951 // the same implicit parameters. 3952 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3953 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3954 break; 3955 } 3956 3957 case OMPD_teams_distribute_parallel_for: 3958 case OMPD_teams_distribute_parallel_for_simd: { 3959 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3960 QualType KmpInt32PtrTy = 3961 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3962 3963 Sema::CapturedParamNameType ParamsTeams[] = { 3964 std::make_pair(".global_tid.", KmpInt32PtrTy), 3965 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3966 std::make_pair(StringRef(), QualType()) // __context with shared vars 3967 }; 3968 // Start a captured region for 'target' with no implicit parameters. 3969 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3970 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3971 3972 Sema::CapturedParamNameType ParamsParallel[] = { 3973 std::make_pair(".global_tid.", KmpInt32PtrTy), 3974 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3975 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3976 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3977 std::make_pair(StringRef(), QualType()) // __context with shared vars 3978 }; 3979 // Start a captured region for 'teams' or 'parallel'. Both regions have 3980 // the same implicit parameters. 3981 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3982 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3983 break; 3984 } 3985 case OMPD_target_update: 3986 case OMPD_target_enter_data: 3987 case OMPD_target_exit_data: { 3988 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3989 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3990 QualType KmpInt32PtrTy = 3991 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3992 QualType Args[] = {VoidPtrTy}; 3993 FunctionProtoType::ExtProtoInfo EPI; 3994 EPI.Variadic = true; 3995 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3996 Sema::CapturedParamNameType Params[] = { 3997 std::make_pair(".global_tid.", KmpInt32Ty), 3998 std::make_pair(".part_id.", KmpInt32PtrTy), 3999 std::make_pair(".privates.", VoidPtrTy), 4000 std::make_pair( 4001 ".copy_fn.", 4002 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4003 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4004 std::make_pair(StringRef(), QualType()) // __context with shared vars 4005 }; 4006 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4007 Params); 4008 // Mark this captured region as inlined, because we don't use outlined 4009 // function directly. 4010 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4011 AlwaysInlineAttr::CreateImplicit( 4012 Context, {}, AttributeCommonInfo::AS_Keyword, 4013 AlwaysInlineAttr::Keyword_forceinline)); 4014 break; 4015 } 4016 case OMPD_threadprivate: 4017 case OMPD_allocate: 4018 case OMPD_taskyield: 4019 case OMPD_barrier: 4020 case OMPD_taskwait: 4021 case OMPD_cancellation_point: 4022 case OMPD_cancel: 4023 case OMPD_flush: 4024 case OMPD_depobj: 4025 case OMPD_scan: 4026 case OMPD_declare_reduction: 4027 case OMPD_declare_mapper: 4028 case OMPD_declare_simd: 4029 case OMPD_declare_target: 4030 case OMPD_end_declare_target: 4031 case OMPD_requires: 4032 case OMPD_declare_variant: 4033 case OMPD_begin_declare_variant: 4034 case OMPD_end_declare_variant: 4035 llvm_unreachable("OpenMP Directive is not allowed"); 4036 case OMPD_unknown: 4037 llvm_unreachable("Unknown OpenMP directive"); 4038 } 4039 } 4040 4041 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4042 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4043 } 4044 4045 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4046 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4047 getOpenMPCaptureRegions(CaptureRegions, DKind); 4048 return CaptureRegions.size(); 4049 } 4050 4051 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4052 Expr *CaptureExpr, bool WithInit, 4053 bool AsExpression) { 4054 assert(CaptureExpr); 4055 ASTContext &C = S.getASTContext(); 4056 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4057 QualType Ty = Init->getType(); 4058 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4059 if (S.getLangOpts().CPlusPlus) { 4060 Ty = C.getLValueReferenceType(Ty); 4061 } else { 4062 Ty = C.getPointerType(Ty); 4063 ExprResult Res = 4064 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4065 if (!Res.isUsable()) 4066 return nullptr; 4067 Init = Res.get(); 4068 } 4069 WithInit = true; 4070 } 4071 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 4072 CaptureExpr->getBeginLoc()); 4073 if (!WithInit) 4074 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4075 S.CurContext->addHiddenDecl(CED); 4076 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4077 return CED; 4078 } 4079 4080 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4081 bool WithInit) { 4082 OMPCapturedExprDecl *CD; 4083 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4084 CD = cast<OMPCapturedExprDecl>(VD); 4085 else 4086 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4087 /*AsExpression=*/false); 4088 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4089 CaptureExpr->getExprLoc()); 4090 } 4091 4092 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 4093 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4094 if (!Ref) { 4095 OMPCapturedExprDecl *CD = buildCaptureDecl( 4096 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 4097 /*WithInit=*/true, /*AsExpression=*/true); 4098 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4099 CaptureExpr->getExprLoc()); 4100 } 4101 ExprResult Res = Ref; 4102 if (!S.getLangOpts().CPlusPlus && 4103 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4104 Ref->getType()->isPointerType()) { 4105 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4106 if (!Res.isUsable()) 4107 return ExprError(); 4108 } 4109 return S.DefaultLvalueConversion(Res.get()); 4110 } 4111 4112 namespace { 4113 // OpenMP directives parsed in this section are represented as a 4114 // CapturedStatement with an associated statement. If a syntax error 4115 // is detected during the parsing of the associated statement, the 4116 // compiler must abort processing and close the CapturedStatement. 4117 // 4118 // Combined directives such as 'target parallel' have more than one 4119 // nested CapturedStatements. This RAII ensures that we unwind out 4120 // of all the nested CapturedStatements when an error is found. 4121 class CaptureRegionUnwinderRAII { 4122 private: 4123 Sema &S; 4124 bool &ErrorFound; 4125 OpenMPDirectiveKind DKind = OMPD_unknown; 4126 4127 public: 4128 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4129 OpenMPDirectiveKind DKind) 4130 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4131 ~CaptureRegionUnwinderRAII() { 4132 if (ErrorFound) { 4133 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4134 while (--ThisCaptureLevel >= 0) 4135 S.ActOnCapturedRegionError(); 4136 } 4137 } 4138 }; 4139 } // namespace 4140 4141 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4142 // Capture variables captured by reference in lambdas for target-based 4143 // directives. 4144 if (!CurContext->isDependentContext() && 4145 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4146 isOpenMPTargetDataManagementDirective( 4147 DSAStack->getCurrentDirective()))) { 4148 QualType Type = V->getType(); 4149 if (const auto *RD = Type.getCanonicalType() 4150 .getNonReferenceType() 4151 ->getAsCXXRecordDecl()) { 4152 bool SavedForceCaptureByReferenceInTargetExecutable = 4153 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4154 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4155 /*V=*/true); 4156 if (RD->isLambda()) { 4157 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4158 FieldDecl *ThisCapture; 4159 RD->getCaptureFields(Captures, ThisCapture); 4160 for (const LambdaCapture &LC : RD->captures()) { 4161 if (LC.getCaptureKind() == LCK_ByRef) { 4162 VarDecl *VD = LC.getCapturedVar(); 4163 DeclContext *VDC = VD->getDeclContext(); 4164 if (!VDC->Encloses(CurContext)) 4165 continue; 4166 MarkVariableReferenced(LC.getLocation(), VD); 4167 } else if (LC.getCaptureKind() == LCK_This) { 4168 QualType ThisTy = getCurrentThisType(); 4169 if (!ThisTy.isNull() && 4170 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4171 CheckCXXThisCapture(LC.getLocation()); 4172 } 4173 } 4174 } 4175 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4176 SavedForceCaptureByReferenceInTargetExecutable); 4177 } 4178 } 4179 } 4180 4181 static bool checkOrderedOrderSpecified(Sema &S, 4182 const ArrayRef<OMPClause *> Clauses) { 4183 const OMPOrderedClause *Ordered = nullptr; 4184 const OMPOrderClause *Order = nullptr; 4185 4186 for (const OMPClause *Clause : Clauses) { 4187 if (Clause->getClauseKind() == OMPC_ordered) 4188 Ordered = cast<OMPOrderedClause>(Clause); 4189 else if (Clause->getClauseKind() == OMPC_order) { 4190 Order = cast<OMPOrderClause>(Clause); 4191 if (Order->getKind() != OMPC_ORDER_concurrent) 4192 Order = nullptr; 4193 } 4194 if (Ordered && Order) 4195 break; 4196 } 4197 4198 if (Ordered && Order) { 4199 S.Diag(Order->getKindKwLoc(), 4200 diag::err_omp_simple_clause_incompatible_with_ordered) 4201 << getOpenMPClauseName(OMPC_order) 4202 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4203 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4204 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4205 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4206 return true; 4207 } 4208 return false; 4209 } 4210 4211 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4212 ArrayRef<OMPClause *> Clauses) { 4213 bool ErrorFound = false; 4214 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4215 *this, ErrorFound, DSAStack->getCurrentDirective()); 4216 if (!S.isUsable()) { 4217 ErrorFound = true; 4218 return StmtError(); 4219 } 4220 4221 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4222 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4223 OMPOrderedClause *OC = nullptr; 4224 OMPScheduleClause *SC = nullptr; 4225 SmallVector<const OMPLinearClause *, 4> LCs; 4226 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4227 // This is required for proper codegen. 4228 for (OMPClause *Clause : Clauses) { 4229 if (!LangOpts.OpenMPSimd && 4230 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 4231 Clause->getClauseKind() == OMPC_in_reduction) { 4232 // Capture taskgroup task_reduction descriptors inside the tasking regions 4233 // with the corresponding in_reduction items. 4234 auto *IRC = cast<OMPInReductionClause>(Clause); 4235 for (Expr *E : IRC->taskgroup_descriptors()) 4236 if (E) 4237 MarkDeclarationsReferencedInExpr(E); 4238 } 4239 if (isOpenMPPrivate(Clause->getClauseKind()) || 4240 Clause->getClauseKind() == OMPC_copyprivate || 4241 (getLangOpts().OpenMPUseTLS && 4242 getASTContext().getTargetInfo().isTLSSupported() && 4243 Clause->getClauseKind() == OMPC_copyin)) { 4244 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4245 // Mark all variables in private list clauses as used in inner region. 4246 for (Stmt *VarRef : Clause->children()) { 4247 if (auto *E = cast_or_null<Expr>(VarRef)) { 4248 MarkDeclarationsReferencedInExpr(E); 4249 } 4250 } 4251 DSAStack->setForceVarCapturing(/*V=*/false); 4252 } else if (CaptureRegions.size() > 1 || 4253 CaptureRegions.back() != OMPD_unknown) { 4254 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4255 PICs.push_back(C); 4256 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4257 if (Expr *E = C->getPostUpdateExpr()) 4258 MarkDeclarationsReferencedInExpr(E); 4259 } 4260 } 4261 if (Clause->getClauseKind() == OMPC_schedule) 4262 SC = cast<OMPScheduleClause>(Clause); 4263 else if (Clause->getClauseKind() == OMPC_ordered) 4264 OC = cast<OMPOrderedClause>(Clause); 4265 else if (Clause->getClauseKind() == OMPC_linear) 4266 LCs.push_back(cast<OMPLinearClause>(Clause)); 4267 } 4268 // Capture allocator expressions if used. 4269 for (Expr *E : DSAStack->getInnerAllocators()) 4270 MarkDeclarationsReferencedInExpr(E); 4271 // OpenMP, 2.7.1 Loop Construct, Restrictions 4272 // The nonmonotonic modifier cannot be specified if an ordered clause is 4273 // specified. 4274 if (SC && 4275 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4276 SC->getSecondScheduleModifier() == 4277 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4278 OC) { 4279 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4280 ? SC->getFirstScheduleModifierLoc() 4281 : SC->getSecondScheduleModifierLoc(), 4282 diag::err_omp_simple_clause_incompatible_with_ordered) 4283 << getOpenMPClauseName(OMPC_schedule) 4284 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4285 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4286 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4287 ErrorFound = true; 4288 } 4289 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4290 // If an order(concurrent) clause is present, an ordered clause may not appear 4291 // on the same directive. 4292 if (checkOrderedOrderSpecified(*this, Clauses)) 4293 ErrorFound = true; 4294 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4295 for (const OMPLinearClause *C : LCs) { 4296 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4297 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4298 } 4299 ErrorFound = true; 4300 } 4301 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4302 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4303 OC->getNumForLoops()) { 4304 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4305 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4306 ErrorFound = true; 4307 } 4308 if (ErrorFound) { 4309 return StmtError(); 4310 } 4311 StmtResult SR = S; 4312 unsigned CompletedRegions = 0; 4313 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4314 // Mark all variables in private list clauses as used in inner region. 4315 // Required for proper codegen of combined directives. 4316 // TODO: add processing for other clauses. 4317 if (ThisCaptureRegion != OMPD_unknown) { 4318 for (const clang::OMPClauseWithPreInit *C : PICs) { 4319 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4320 // Find the particular capture region for the clause if the 4321 // directive is a combined one with multiple capture regions. 4322 // If the directive is not a combined one, the capture region 4323 // associated with the clause is OMPD_unknown and is generated 4324 // only once. 4325 if (CaptureRegion == ThisCaptureRegion || 4326 CaptureRegion == OMPD_unknown) { 4327 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4328 for (Decl *D : DS->decls()) 4329 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4330 } 4331 } 4332 } 4333 } 4334 if (ThisCaptureRegion == OMPD_target) { 4335 // Capture allocator traits in the target region. They are used implicitly 4336 // and, thus, are not captured by default. 4337 for (OMPClause *C : Clauses) { 4338 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { 4339 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; 4340 ++I) { 4341 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); 4342 if (Expr *E = D.AllocatorTraits) 4343 MarkDeclarationsReferencedInExpr(E); 4344 } 4345 continue; 4346 } 4347 } 4348 } 4349 if (++CompletedRegions == CaptureRegions.size()) 4350 DSAStack->setBodyComplete(); 4351 SR = ActOnCapturedRegionEnd(SR.get()); 4352 } 4353 return SR; 4354 } 4355 4356 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4357 OpenMPDirectiveKind CancelRegion, 4358 SourceLocation StartLoc) { 4359 // CancelRegion is only needed for cancel and cancellation_point. 4360 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4361 return false; 4362 4363 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4364 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4365 return false; 4366 4367 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4368 << getOpenMPDirectiveName(CancelRegion); 4369 return true; 4370 } 4371 4372 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4373 OpenMPDirectiveKind CurrentRegion, 4374 const DeclarationNameInfo &CurrentName, 4375 OpenMPDirectiveKind CancelRegion, 4376 SourceLocation StartLoc) { 4377 if (Stack->getCurScope()) { 4378 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4379 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4380 bool NestingProhibited = false; 4381 bool CloseNesting = true; 4382 bool OrphanSeen = false; 4383 enum { 4384 NoRecommend, 4385 ShouldBeInParallelRegion, 4386 ShouldBeInOrderedRegion, 4387 ShouldBeInTargetRegion, 4388 ShouldBeInTeamsRegion, 4389 ShouldBeInLoopSimdRegion, 4390 } Recommend = NoRecommend; 4391 if (isOpenMPSimdDirective(ParentRegion) && 4392 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4393 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4394 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4395 CurrentRegion != OMPD_scan))) { 4396 // OpenMP [2.16, Nesting of Regions] 4397 // OpenMP constructs may not be nested inside a simd region. 4398 // OpenMP [2.8.1,simd Construct, Restrictions] 4399 // An ordered construct with the simd clause is the only OpenMP 4400 // construct that can appear in the simd region. 4401 // Allowing a SIMD construct nested in another SIMD construct is an 4402 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4403 // message. 4404 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4405 // The only OpenMP constructs that can be encountered during execution of 4406 // a simd region are the atomic construct, the loop construct, the simd 4407 // construct and the ordered construct with the simd clause. 4408 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4409 ? diag::err_omp_prohibited_region_simd 4410 : diag::warn_omp_nesting_simd) 4411 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4412 return CurrentRegion != OMPD_simd; 4413 } 4414 if (ParentRegion == OMPD_atomic) { 4415 // OpenMP [2.16, Nesting of Regions] 4416 // OpenMP constructs may not be nested inside an atomic region. 4417 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4418 return true; 4419 } 4420 if (CurrentRegion == OMPD_section) { 4421 // OpenMP [2.7.2, sections Construct, Restrictions] 4422 // Orphaned section directives are prohibited. That is, the section 4423 // directives must appear within the sections construct and must not be 4424 // encountered elsewhere in the sections region. 4425 if (ParentRegion != OMPD_sections && 4426 ParentRegion != OMPD_parallel_sections) { 4427 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4428 << (ParentRegion != OMPD_unknown) 4429 << getOpenMPDirectiveName(ParentRegion); 4430 return true; 4431 } 4432 return false; 4433 } 4434 // Allow some constructs (except teams and cancellation constructs) to be 4435 // orphaned (they could be used in functions, called from OpenMP regions 4436 // with the required preconditions). 4437 if (ParentRegion == OMPD_unknown && 4438 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4439 CurrentRegion != OMPD_cancellation_point && 4440 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4441 return false; 4442 if (CurrentRegion == OMPD_cancellation_point || 4443 CurrentRegion == OMPD_cancel) { 4444 // OpenMP [2.16, Nesting of Regions] 4445 // A cancellation point construct for which construct-type-clause is 4446 // taskgroup must be nested inside a task construct. A cancellation 4447 // point construct for which construct-type-clause is not taskgroup must 4448 // be closely nested inside an OpenMP construct that matches the type 4449 // specified in construct-type-clause. 4450 // A cancel construct for which construct-type-clause is taskgroup must be 4451 // nested inside a task construct. A cancel construct for which 4452 // construct-type-clause is not taskgroup must be closely nested inside an 4453 // OpenMP construct that matches the type specified in 4454 // construct-type-clause. 4455 NestingProhibited = 4456 !((CancelRegion == OMPD_parallel && 4457 (ParentRegion == OMPD_parallel || 4458 ParentRegion == OMPD_target_parallel)) || 4459 (CancelRegion == OMPD_for && 4460 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4461 ParentRegion == OMPD_target_parallel_for || 4462 ParentRegion == OMPD_distribute_parallel_for || 4463 ParentRegion == OMPD_teams_distribute_parallel_for || 4464 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4465 (CancelRegion == OMPD_taskgroup && 4466 (ParentRegion == OMPD_task || 4467 (SemaRef.getLangOpts().OpenMP >= 50 && 4468 (ParentRegion == OMPD_taskloop || 4469 ParentRegion == OMPD_master_taskloop || 4470 ParentRegion == OMPD_parallel_master_taskloop)))) || 4471 (CancelRegion == OMPD_sections && 4472 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4473 ParentRegion == OMPD_parallel_sections))); 4474 OrphanSeen = ParentRegion == OMPD_unknown; 4475 } else if (CurrentRegion == OMPD_master) { 4476 // OpenMP [2.16, Nesting of Regions] 4477 // A master region may not be closely nested inside a worksharing, 4478 // atomic, or explicit task region. 4479 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4480 isOpenMPTaskingDirective(ParentRegion); 4481 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4482 // OpenMP [2.16, Nesting of Regions] 4483 // A critical region may not be nested (closely or otherwise) inside a 4484 // critical region with the same name. Note that this restriction is not 4485 // sufficient to prevent deadlock. 4486 SourceLocation PreviousCriticalLoc; 4487 bool DeadLock = Stack->hasDirective( 4488 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4489 const DeclarationNameInfo &DNI, 4490 SourceLocation Loc) { 4491 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4492 PreviousCriticalLoc = Loc; 4493 return true; 4494 } 4495 return false; 4496 }, 4497 false /* skip top directive */); 4498 if (DeadLock) { 4499 SemaRef.Diag(StartLoc, 4500 diag::err_omp_prohibited_region_critical_same_name) 4501 << CurrentName.getName(); 4502 if (PreviousCriticalLoc.isValid()) 4503 SemaRef.Diag(PreviousCriticalLoc, 4504 diag::note_omp_previous_critical_region); 4505 return true; 4506 } 4507 } else if (CurrentRegion == OMPD_barrier) { 4508 // OpenMP [2.16, Nesting of Regions] 4509 // A barrier region may not be closely nested inside a worksharing, 4510 // explicit task, critical, ordered, atomic, or master region. 4511 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4512 isOpenMPTaskingDirective(ParentRegion) || 4513 ParentRegion == OMPD_master || 4514 ParentRegion == OMPD_parallel_master || 4515 ParentRegion == OMPD_critical || 4516 ParentRegion == OMPD_ordered; 4517 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4518 !isOpenMPParallelDirective(CurrentRegion) && 4519 !isOpenMPTeamsDirective(CurrentRegion)) { 4520 // OpenMP [2.16, Nesting of Regions] 4521 // A worksharing region may not be closely nested inside a worksharing, 4522 // explicit task, critical, ordered, atomic, or master region. 4523 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4524 isOpenMPTaskingDirective(ParentRegion) || 4525 ParentRegion == OMPD_master || 4526 ParentRegion == OMPD_parallel_master || 4527 ParentRegion == OMPD_critical || 4528 ParentRegion == OMPD_ordered; 4529 Recommend = ShouldBeInParallelRegion; 4530 } else if (CurrentRegion == OMPD_ordered) { 4531 // OpenMP [2.16, Nesting of Regions] 4532 // An ordered region may not be closely nested inside a critical, 4533 // atomic, or explicit task region. 4534 // An ordered region must be closely nested inside a loop region (or 4535 // parallel loop region) with an ordered clause. 4536 // OpenMP [2.8.1,simd Construct, Restrictions] 4537 // An ordered construct with the simd clause is the only OpenMP construct 4538 // that can appear in the simd region. 4539 NestingProhibited = ParentRegion == OMPD_critical || 4540 isOpenMPTaskingDirective(ParentRegion) || 4541 !(isOpenMPSimdDirective(ParentRegion) || 4542 Stack->isParentOrderedRegion()); 4543 Recommend = ShouldBeInOrderedRegion; 4544 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4545 // OpenMP [2.16, Nesting of Regions] 4546 // If specified, a teams construct must be contained within a target 4547 // construct. 4548 NestingProhibited = 4549 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4550 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4551 ParentRegion != OMPD_target); 4552 OrphanSeen = ParentRegion == OMPD_unknown; 4553 Recommend = ShouldBeInTargetRegion; 4554 } else if (CurrentRegion == OMPD_scan) { 4555 // OpenMP [2.16, Nesting of Regions] 4556 // If specified, a teams construct must be contained within a target 4557 // construct. 4558 NestingProhibited = 4559 SemaRef.LangOpts.OpenMP < 50 || 4560 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4561 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4562 ParentRegion != OMPD_parallel_for_simd); 4563 OrphanSeen = ParentRegion == OMPD_unknown; 4564 Recommend = ShouldBeInLoopSimdRegion; 4565 } 4566 if (!NestingProhibited && 4567 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4568 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4569 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4570 // OpenMP [2.16, Nesting of Regions] 4571 // distribute, parallel, parallel sections, parallel workshare, and the 4572 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4573 // constructs that can be closely nested in the teams region. 4574 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4575 !isOpenMPDistributeDirective(CurrentRegion); 4576 Recommend = ShouldBeInParallelRegion; 4577 } 4578 if (!NestingProhibited && 4579 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4580 // OpenMP 4.5 [2.17 Nesting of Regions] 4581 // The region associated with the distribute construct must be strictly 4582 // nested inside a teams region 4583 NestingProhibited = 4584 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4585 Recommend = ShouldBeInTeamsRegion; 4586 } 4587 if (!NestingProhibited && 4588 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4589 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4590 // OpenMP 4.5 [2.17 Nesting of Regions] 4591 // If a target, target update, target data, target enter data, or 4592 // target exit data construct is encountered during execution of a 4593 // target region, the behavior is unspecified. 4594 NestingProhibited = Stack->hasDirective( 4595 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4596 SourceLocation) { 4597 if (isOpenMPTargetExecutionDirective(K)) { 4598 OffendingRegion = K; 4599 return true; 4600 } 4601 return false; 4602 }, 4603 false /* don't skip top directive */); 4604 CloseNesting = false; 4605 } 4606 if (NestingProhibited) { 4607 if (OrphanSeen) { 4608 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4609 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4610 } else { 4611 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4612 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4613 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4614 } 4615 return true; 4616 } 4617 } 4618 return false; 4619 } 4620 4621 struct Kind2Unsigned { 4622 using argument_type = OpenMPDirectiveKind; 4623 unsigned operator()(argument_type DK) { return unsigned(DK); } 4624 }; 4625 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4626 ArrayRef<OMPClause *> Clauses, 4627 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4628 bool ErrorFound = false; 4629 unsigned NamedModifiersNumber = 0; 4630 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4631 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); 4632 SmallVector<SourceLocation, 4> NameModifierLoc; 4633 for (const OMPClause *C : Clauses) { 4634 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4635 // At most one if clause without a directive-name-modifier can appear on 4636 // the directive. 4637 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4638 if (FoundNameModifiers[CurNM]) { 4639 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4640 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4641 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4642 ErrorFound = true; 4643 } else if (CurNM != OMPD_unknown) { 4644 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4645 ++NamedModifiersNumber; 4646 } 4647 FoundNameModifiers[CurNM] = IC; 4648 if (CurNM == OMPD_unknown) 4649 continue; 4650 // Check if the specified name modifier is allowed for the current 4651 // directive. 4652 // At most one if clause with the particular directive-name-modifier can 4653 // appear on the directive. 4654 bool MatchFound = false; 4655 for (auto NM : AllowedNameModifiers) { 4656 if (CurNM == NM) { 4657 MatchFound = true; 4658 break; 4659 } 4660 } 4661 if (!MatchFound) { 4662 S.Diag(IC->getNameModifierLoc(), 4663 diag::err_omp_wrong_if_directive_name_modifier) 4664 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4665 ErrorFound = true; 4666 } 4667 } 4668 } 4669 // If any if clause on the directive includes a directive-name-modifier then 4670 // all if clauses on the directive must include a directive-name-modifier. 4671 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4672 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4673 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4674 diag::err_omp_no_more_if_clause); 4675 } else { 4676 std::string Values; 4677 std::string Sep(", "); 4678 unsigned AllowedCnt = 0; 4679 unsigned TotalAllowedNum = 4680 AllowedNameModifiers.size() - NamedModifiersNumber; 4681 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4682 ++Cnt) { 4683 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4684 if (!FoundNameModifiers[NM]) { 4685 Values += "'"; 4686 Values += getOpenMPDirectiveName(NM); 4687 Values += "'"; 4688 if (AllowedCnt + 2 == TotalAllowedNum) 4689 Values += " or "; 4690 else if (AllowedCnt + 1 != TotalAllowedNum) 4691 Values += Sep; 4692 ++AllowedCnt; 4693 } 4694 } 4695 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4696 diag::err_omp_unnamed_if_clause) 4697 << (TotalAllowedNum > 1) << Values; 4698 } 4699 for (SourceLocation Loc : NameModifierLoc) { 4700 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4701 } 4702 ErrorFound = true; 4703 } 4704 return ErrorFound; 4705 } 4706 4707 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4708 SourceLocation &ELoc, 4709 SourceRange &ERange, 4710 bool AllowArraySection) { 4711 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4712 RefExpr->containsUnexpandedParameterPack()) 4713 return std::make_pair(nullptr, true); 4714 4715 // OpenMP [3.1, C/C++] 4716 // A list item is a variable name. 4717 // OpenMP [2.9.3.3, Restrictions, p.1] 4718 // A variable that is part of another variable (as an array or 4719 // structure element) cannot appear in a private clause. 4720 RefExpr = RefExpr->IgnoreParens(); 4721 enum { 4722 NoArrayExpr = -1, 4723 ArraySubscript = 0, 4724 OMPArraySection = 1 4725 } IsArrayExpr = NoArrayExpr; 4726 if (AllowArraySection) { 4727 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4728 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4729 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4730 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4731 RefExpr = Base; 4732 IsArrayExpr = ArraySubscript; 4733 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4734 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4735 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4736 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4737 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4738 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4739 RefExpr = Base; 4740 IsArrayExpr = OMPArraySection; 4741 } 4742 } 4743 ELoc = RefExpr->getExprLoc(); 4744 ERange = RefExpr->getSourceRange(); 4745 RefExpr = RefExpr->IgnoreParenImpCasts(); 4746 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4747 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4748 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4749 (S.getCurrentThisType().isNull() || !ME || 4750 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4751 !isa<FieldDecl>(ME->getMemberDecl()))) { 4752 if (IsArrayExpr != NoArrayExpr) { 4753 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4754 << ERange; 4755 } else { 4756 S.Diag(ELoc, 4757 AllowArraySection 4758 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4759 : diag::err_omp_expected_var_name_member_expr) 4760 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4761 } 4762 return std::make_pair(nullptr, false); 4763 } 4764 return std::make_pair( 4765 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4766 } 4767 4768 namespace { 4769 /// Checks if the allocator is used in uses_allocators clause to be allowed in 4770 /// target regions. 4771 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 4772 DSAStackTy *S = nullptr; 4773 4774 public: 4775 bool VisitDeclRefExpr(const DeclRefExpr *E) { 4776 return S->isUsesAllocatorsDecl(E->getDecl()) 4777 .getValueOr( 4778 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 4779 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; 4780 } 4781 bool VisitStmt(const Stmt *S) { 4782 for (const Stmt *Child : S->children()) { 4783 if (Child && Visit(Child)) 4784 return true; 4785 } 4786 return false; 4787 } 4788 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 4789 }; 4790 } // namespace 4791 4792 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4793 ArrayRef<OMPClause *> Clauses) { 4794 assert(!S.CurContext->isDependentContext() && 4795 "Expected non-dependent context."); 4796 auto AllocateRange = 4797 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4798 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4799 DeclToCopy; 4800 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4801 return isOpenMPPrivate(C->getClauseKind()); 4802 }); 4803 for (OMPClause *Cl : PrivateRange) { 4804 MutableArrayRef<Expr *>::iterator I, It, Et; 4805 if (Cl->getClauseKind() == OMPC_private) { 4806 auto *PC = cast<OMPPrivateClause>(Cl); 4807 I = PC->private_copies().begin(); 4808 It = PC->varlist_begin(); 4809 Et = PC->varlist_end(); 4810 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4811 auto *PC = cast<OMPFirstprivateClause>(Cl); 4812 I = PC->private_copies().begin(); 4813 It = PC->varlist_begin(); 4814 Et = PC->varlist_end(); 4815 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4816 auto *PC = cast<OMPLastprivateClause>(Cl); 4817 I = PC->private_copies().begin(); 4818 It = PC->varlist_begin(); 4819 Et = PC->varlist_end(); 4820 } else if (Cl->getClauseKind() == OMPC_linear) { 4821 auto *PC = cast<OMPLinearClause>(Cl); 4822 I = PC->privates().begin(); 4823 It = PC->varlist_begin(); 4824 Et = PC->varlist_end(); 4825 } else if (Cl->getClauseKind() == OMPC_reduction) { 4826 auto *PC = cast<OMPReductionClause>(Cl); 4827 I = PC->privates().begin(); 4828 It = PC->varlist_begin(); 4829 Et = PC->varlist_end(); 4830 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4831 auto *PC = cast<OMPTaskReductionClause>(Cl); 4832 I = PC->privates().begin(); 4833 It = PC->varlist_begin(); 4834 Et = PC->varlist_end(); 4835 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4836 auto *PC = cast<OMPInReductionClause>(Cl); 4837 I = PC->privates().begin(); 4838 It = PC->varlist_begin(); 4839 Et = PC->varlist_end(); 4840 } else { 4841 llvm_unreachable("Expected private clause."); 4842 } 4843 for (Expr *E : llvm::make_range(It, Et)) { 4844 if (!*I) { 4845 ++I; 4846 continue; 4847 } 4848 SourceLocation ELoc; 4849 SourceRange ERange; 4850 Expr *SimpleRefExpr = E; 4851 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4852 /*AllowArraySection=*/true); 4853 DeclToCopy.try_emplace(Res.first, 4854 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4855 ++I; 4856 } 4857 } 4858 for (OMPClause *C : AllocateRange) { 4859 auto *AC = cast<OMPAllocateClause>(C); 4860 if (S.getLangOpts().OpenMP >= 50 && 4861 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 4862 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 4863 AC->getAllocator()) { 4864 Expr *Allocator = AC->getAllocator(); 4865 // OpenMP, 2.12.5 target Construct 4866 // Memory allocators that do not appear in a uses_allocators clause cannot 4867 // appear as an allocator in an allocate clause or be used in the target 4868 // region unless a requires directive with the dynamic_allocators clause 4869 // is present in the same compilation unit. 4870 AllocatorChecker Checker(Stack); 4871 if (Checker.Visit(Allocator)) 4872 S.Diag(Allocator->getExprLoc(), 4873 diag::err_omp_allocator_not_in_uses_allocators) 4874 << Allocator->getSourceRange(); 4875 } 4876 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4877 getAllocatorKind(S, Stack, AC->getAllocator()); 4878 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4879 // For task, taskloop or target directives, allocation requests to memory 4880 // allocators with the trait access set to thread result in unspecified 4881 // behavior. 4882 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4883 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4884 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4885 S.Diag(AC->getAllocator()->getExprLoc(), 4886 diag::warn_omp_allocate_thread_on_task_target_directive) 4887 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4888 } 4889 for (Expr *E : AC->varlists()) { 4890 SourceLocation ELoc; 4891 SourceRange ERange; 4892 Expr *SimpleRefExpr = E; 4893 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4894 ValueDecl *VD = Res.first; 4895 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4896 if (!isOpenMPPrivate(Data.CKind)) { 4897 S.Diag(E->getExprLoc(), 4898 diag::err_omp_expected_private_copy_for_allocate); 4899 continue; 4900 } 4901 VarDecl *PrivateVD = DeclToCopy[VD]; 4902 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4903 AllocatorKind, AC->getAllocator())) 4904 continue; 4905 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4906 E->getSourceRange()); 4907 } 4908 } 4909 } 4910 4911 StmtResult Sema::ActOnOpenMPExecutableDirective( 4912 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4913 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4914 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4915 StmtResult Res = StmtError(); 4916 // First check CancelRegion which is then used in checkNestingOfRegions. 4917 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4918 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4919 StartLoc)) 4920 return StmtError(); 4921 4922 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4923 VarsWithInheritedDSAType VarsWithInheritedDSA; 4924 bool ErrorFound = false; 4925 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4926 if (AStmt && !CurContext->isDependentContext()) { 4927 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4928 4929 // Check default data sharing attributes for referenced variables. 4930 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4931 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4932 Stmt *S = AStmt; 4933 while (--ThisCaptureLevel >= 0) 4934 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4935 DSAChecker.Visit(S); 4936 if (!isOpenMPTargetDataManagementDirective(Kind) && 4937 !isOpenMPTaskingDirective(Kind)) { 4938 // Visit subcaptures to generate implicit clauses for captured vars. 4939 auto *CS = cast<CapturedStmt>(AStmt); 4940 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4941 getOpenMPCaptureRegions(CaptureRegions, Kind); 4942 // Ignore outer tasking regions for target directives. 4943 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4944 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4945 DSAChecker.visitSubCaptures(CS); 4946 } 4947 if (DSAChecker.isErrorFound()) 4948 return StmtError(); 4949 // Generate list of implicitly defined firstprivate variables. 4950 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4951 4952 SmallVector<Expr *, 4> ImplicitFirstprivates( 4953 DSAChecker.getImplicitFirstprivate().begin(), 4954 DSAChecker.getImplicitFirstprivate().end()); 4955 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4956 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4957 ArrayRef<Expr *> ImplicitMap = 4958 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4959 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4960 } 4961 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4962 for (OMPClause *C : Clauses) { 4963 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4964 for (Expr *E : IRC->taskgroup_descriptors()) 4965 if (E) 4966 ImplicitFirstprivates.emplace_back(E); 4967 } 4968 // OpenMP 5.0, 2.10.1 task Construct 4969 // [detach clause]... The event-handle will be considered as if it was 4970 // specified on a firstprivate clause. 4971 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 4972 ImplicitFirstprivates.push_back(DC->getEventHandler()); 4973 } 4974 if (!ImplicitFirstprivates.empty()) { 4975 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4976 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4977 SourceLocation())) { 4978 ClausesWithImplicit.push_back(Implicit); 4979 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4980 ImplicitFirstprivates.size(); 4981 } else { 4982 ErrorFound = true; 4983 } 4984 } 4985 int ClauseKindCnt = -1; 4986 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4987 ++ClauseKindCnt; 4988 if (ImplicitMap.empty()) 4989 continue; 4990 CXXScopeSpec MapperIdScopeSpec; 4991 DeclarationNameInfo MapperId; 4992 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 4993 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4994 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 4995 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 4996 ImplicitMap, OMPVarListLocTy())) { 4997 ClausesWithImplicit.emplace_back(Implicit); 4998 ErrorFound |= 4999 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 5000 } else { 5001 ErrorFound = true; 5002 } 5003 } 5004 } 5005 5006 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 5007 switch (Kind) { 5008 case OMPD_parallel: 5009 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 5010 EndLoc); 5011 AllowedNameModifiers.push_back(OMPD_parallel); 5012 break; 5013 case OMPD_simd: 5014 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 5015 VarsWithInheritedDSA); 5016 if (LangOpts.OpenMP >= 50) 5017 AllowedNameModifiers.push_back(OMPD_simd); 5018 break; 5019 case OMPD_for: 5020 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 5021 VarsWithInheritedDSA); 5022 break; 5023 case OMPD_for_simd: 5024 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5025 EndLoc, VarsWithInheritedDSA); 5026 if (LangOpts.OpenMP >= 50) 5027 AllowedNameModifiers.push_back(OMPD_simd); 5028 break; 5029 case OMPD_sections: 5030 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 5031 EndLoc); 5032 break; 5033 case OMPD_section: 5034 assert(ClausesWithImplicit.empty() && 5035 "No clauses are allowed for 'omp section' directive"); 5036 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 5037 break; 5038 case OMPD_single: 5039 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 5040 EndLoc); 5041 break; 5042 case OMPD_master: 5043 assert(ClausesWithImplicit.empty() && 5044 "No clauses are allowed for 'omp master' directive"); 5045 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 5046 break; 5047 case OMPD_critical: 5048 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 5049 StartLoc, EndLoc); 5050 break; 5051 case OMPD_parallel_for: 5052 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 5053 EndLoc, VarsWithInheritedDSA); 5054 AllowedNameModifiers.push_back(OMPD_parallel); 5055 break; 5056 case OMPD_parallel_for_simd: 5057 Res = ActOnOpenMPParallelForSimdDirective( 5058 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5059 AllowedNameModifiers.push_back(OMPD_parallel); 5060 if (LangOpts.OpenMP >= 50) 5061 AllowedNameModifiers.push_back(OMPD_simd); 5062 break; 5063 case OMPD_parallel_master: 5064 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 5065 StartLoc, EndLoc); 5066 AllowedNameModifiers.push_back(OMPD_parallel); 5067 break; 5068 case OMPD_parallel_sections: 5069 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 5070 StartLoc, EndLoc); 5071 AllowedNameModifiers.push_back(OMPD_parallel); 5072 break; 5073 case OMPD_task: 5074 Res = 5075 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5076 AllowedNameModifiers.push_back(OMPD_task); 5077 break; 5078 case OMPD_taskyield: 5079 assert(ClausesWithImplicit.empty() && 5080 "No clauses are allowed for 'omp taskyield' directive"); 5081 assert(AStmt == nullptr && 5082 "No associated statement allowed for 'omp taskyield' directive"); 5083 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 5084 break; 5085 case OMPD_barrier: 5086 assert(ClausesWithImplicit.empty() && 5087 "No clauses are allowed for 'omp barrier' directive"); 5088 assert(AStmt == nullptr && 5089 "No associated statement allowed for 'omp barrier' directive"); 5090 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 5091 break; 5092 case OMPD_taskwait: 5093 assert(ClausesWithImplicit.empty() && 5094 "No clauses are allowed for 'omp taskwait' directive"); 5095 assert(AStmt == nullptr && 5096 "No associated statement allowed for 'omp taskwait' directive"); 5097 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 5098 break; 5099 case OMPD_taskgroup: 5100 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 5101 EndLoc); 5102 break; 5103 case OMPD_flush: 5104 assert(AStmt == nullptr && 5105 "No associated statement allowed for 'omp flush' directive"); 5106 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 5107 break; 5108 case OMPD_depobj: 5109 assert(AStmt == nullptr && 5110 "No associated statement allowed for 'omp depobj' directive"); 5111 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 5112 break; 5113 case OMPD_scan: 5114 assert(AStmt == nullptr && 5115 "No associated statement allowed for 'omp scan' directive"); 5116 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 5117 break; 5118 case OMPD_ordered: 5119 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 5120 EndLoc); 5121 break; 5122 case OMPD_atomic: 5123 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 5124 EndLoc); 5125 break; 5126 case OMPD_teams: 5127 Res = 5128 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5129 break; 5130 case OMPD_target: 5131 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 5132 EndLoc); 5133 AllowedNameModifiers.push_back(OMPD_target); 5134 break; 5135 case OMPD_target_parallel: 5136 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 5137 StartLoc, EndLoc); 5138 AllowedNameModifiers.push_back(OMPD_target); 5139 AllowedNameModifiers.push_back(OMPD_parallel); 5140 break; 5141 case OMPD_target_parallel_for: 5142 Res = ActOnOpenMPTargetParallelForDirective( 5143 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5144 AllowedNameModifiers.push_back(OMPD_target); 5145 AllowedNameModifiers.push_back(OMPD_parallel); 5146 break; 5147 case OMPD_cancellation_point: 5148 assert(ClausesWithImplicit.empty() && 5149 "No clauses are allowed for 'omp cancellation point' directive"); 5150 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 5151 "cancellation point' directive"); 5152 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 5153 break; 5154 case OMPD_cancel: 5155 assert(AStmt == nullptr && 5156 "No associated statement allowed for 'omp cancel' directive"); 5157 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 5158 CancelRegion); 5159 AllowedNameModifiers.push_back(OMPD_cancel); 5160 break; 5161 case OMPD_target_data: 5162 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 5163 EndLoc); 5164 AllowedNameModifiers.push_back(OMPD_target_data); 5165 break; 5166 case OMPD_target_enter_data: 5167 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 5168 EndLoc, AStmt); 5169 AllowedNameModifiers.push_back(OMPD_target_enter_data); 5170 break; 5171 case OMPD_target_exit_data: 5172 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 5173 EndLoc, AStmt); 5174 AllowedNameModifiers.push_back(OMPD_target_exit_data); 5175 break; 5176 case OMPD_taskloop: 5177 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 5178 EndLoc, VarsWithInheritedDSA); 5179 AllowedNameModifiers.push_back(OMPD_taskloop); 5180 break; 5181 case OMPD_taskloop_simd: 5182 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5183 EndLoc, VarsWithInheritedDSA); 5184 AllowedNameModifiers.push_back(OMPD_taskloop); 5185 if (LangOpts.OpenMP >= 50) 5186 AllowedNameModifiers.push_back(OMPD_simd); 5187 break; 5188 case OMPD_master_taskloop: 5189 Res = ActOnOpenMPMasterTaskLoopDirective( 5190 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5191 AllowedNameModifiers.push_back(OMPD_taskloop); 5192 break; 5193 case OMPD_master_taskloop_simd: 5194 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 5195 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5196 AllowedNameModifiers.push_back(OMPD_taskloop); 5197 if (LangOpts.OpenMP >= 50) 5198 AllowedNameModifiers.push_back(OMPD_simd); 5199 break; 5200 case OMPD_parallel_master_taskloop: 5201 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 5202 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5203 AllowedNameModifiers.push_back(OMPD_taskloop); 5204 AllowedNameModifiers.push_back(OMPD_parallel); 5205 break; 5206 case OMPD_parallel_master_taskloop_simd: 5207 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 5208 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5209 AllowedNameModifiers.push_back(OMPD_taskloop); 5210 AllowedNameModifiers.push_back(OMPD_parallel); 5211 if (LangOpts.OpenMP >= 50) 5212 AllowedNameModifiers.push_back(OMPD_simd); 5213 break; 5214 case OMPD_distribute: 5215 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 5216 EndLoc, VarsWithInheritedDSA); 5217 break; 5218 case OMPD_target_update: 5219 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 5220 EndLoc, AStmt); 5221 AllowedNameModifiers.push_back(OMPD_target_update); 5222 break; 5223 case OMPD_distribute_parallel_for: 5224 Res = ActOnOpenMPDistributeParallelForDirective( 5225 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5226 AllowedNameModifiers.push_back(OMPD_parallel); 5227 break; 5228 case OMPD_distribute_parallel_for_simd: 5229 Res = ActOnOpenMPDistributeParallelForSimdDirective( 5230 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5231 AllowedNameModifiers.push_back(OMPD_parallel); 5232 if (LangOpts.OpenMP >= 50) 5233 AllowedNameModifiers.push_back(OMPD_simd); 5234 break; 5235 case OMPD_distribute_simd: 5236 Res = ActOnOpenMPDistributeSimdDirective( 5237 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5238 if (LangOpts.OpenMP >= 50) 5239 AllowedNameModifiers.push_back(OMPD_simd); 5240 break; 5241 case OMPD_target_parallel_for_simd: 5242 Res = ActOnOpenMPTargetParallelForSimdDirective( 5243 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5244 AllowedNameModifiers.push_back(OMPD_target); 5245 AllowedNameModifiers.push_back(OMPD_parallel); 5246 if (LangOpts.OpenMP >= 50) 5247 AllowedNameModifiers.push_back(OMPD_simd); 5248 break; 5249 case OMPD_target_simd: 5250 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5251 EndLoc, VarsWithInheritedDSA); 5252 AllowedNameModifiers.push_back(OMPD_target); 5253 if (LangOpts.OpenMP >= 50) 5254 AllowedNameModifiers.push_back(OMPD_simd); 5255 break; 5256 case OMPD_teams_distribute: 5257 Res = ActOnOpenMPTeamsDistributeDirective( 5258 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5259 break; 5260 case OMPD_teams_distribute_simd: 5261 Res = ActOnOpenMPTeamsDistributeSimdDirective( 5262 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5263 if (LangOpts.OpenMP >= 50) 5264 AllowedNameModifiers.push_back(OMPD_simd); 5265 break; 5266 case OMPD_teams_distribute_parallel_for_simd: 5267 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 5268 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5269 AllowedNameModifiers.push_back(OMPD_parallel); 5270 if (LangOpts.OpenMP >= 50) 5271 AllowedNameModifiers.push_back(OMPD_simd); 5272 break; 5273 case OMPD_teams_distribute_parallel_for: 5274 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 5275 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5276 AllowedNameModifiers.push_back(OMPD_parallel); 5277 break; 5278 case OMPD_target_teams: 5279 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 5280 EndLoc); 5281 AllowedNameModifiers.push_back(OMPD_target); 5282 break; 5283 case OMPD_target_teams_distribute: 5284 Res = ActOnOpenMPTargetTeamsDistributeDirective( 5285 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5286 AllowedNameModifiers.push_back(OMPD_target); 5287 break; 5288 case OMPD_target_teams_distribute_parallel_for: 5289 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 5290 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5291 AllowedNameModifiers.push_back(OMPD_target); 5292 AllowedNameModifiers.push_back(OMPD_parallel); 5293 break; 5294 case OMPD_target_teams_distribute_parallel_for_simd: 5295 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 5296 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5297 AllowedNameModifiers.push_back(OMPD_target); 5298 AllowedNameModifiers.push_back(OMPD_parallel); 5299 if (LangOpts.OpenMP >= 50) 5300 AllowedNameModifiers.push_back(OMPD_simd); 5301 break; 5302 case OMPD_target_teams_distribute_simd: 5303 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 5304 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5305 AllowedNameModifiers.push_back(OMPD_target); 5306 if (LangOpts.OpenMP >= 50) 5307 AllowedNameModifiers.push_back(OMPD_simd); 5308 break; 5309 case OMPD_declare_target: 5310 case OMPD_end_declare_target: 5311 case OMPD_threadprivate: 5312 case OMPD_allocate: 5313 case OMPD_declare_reduction: 5314 case OMPD_declare_mapper: 5315 case OMPD_declare_simd: 5316 case OMPD_requires: 5317 case OMPD_declare_variant: 5318 case OMPD_begin_declare_variant: 5319 case OMPD_end_declare_variant: 5320 llvm_unreachable("OpenMP Directive is not allowed"); 5321 case OMPD_unknown: 5322 llvm_unreachable("Unknown OpenMP directive"); 5323 } 5324 5325 ErrorFound = Res.isInvalid() || ErrorFound; 5326 5327 // Check variables in the clauses if default(none) was specified. 5328 if (DSAStack->getDefaultDSA() == DSA_none) { 5329 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 5330 for (OMPClause *C : Clauses) { 5331 switch (C->getClauseKind()) { 5332 case OMPC_num_threads: 5333 case OMPC_dist_schedule: 5334 // Do not analyse if no parent teams directive. 5335 if (isOpenMPTeamsDirective(Kind)) 5336 break; 5337 continue; 5338 case OMPC_if: 5339 if (isOpenMPTeamsDirective(Kind) && 5340 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 5341 break; 5342 if (isOpenMPParallelDirective(Kind) && 5343 isOpenMPTaskLoopDirective(Kind) && 5344 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 5345 break; 5346 continue; 5347 case OMPC_schedule: 5348 case OMPC_detach: 5349 break; 5350 case OMPC_grainsize: 5351 case OMPC_num_tasks: 5352 case OMPC_final: 5353 case OMPC_priority: 5354 // Do not analyze if no parent parallel directive. 5355 if (isOpenMPParallelDirective(Kind)) 5356 break; 5357 continue; 5358 case OMPC_ordered: 5359 case OMPC_device: 5360 case OMPC_num_teams: 5361 case OMPC_thread_limit: 5362 case OMPC_hint: 5363 case OMPC_collapse: 5364 case OMPC_safelen: 5365 case OMPC_simdlen: 5366 case OMPC_default: 5367 case OMPC_proc_bind: 5368 case OMPC_private: 5369 case OMPC_firstprivate: 5370 case OMPC_lastprivate: 5371 case OMPC_shared: 5372 case OMPC_reduction: 5373 case OMPC_task_reduction: 5374 case OMPC_in_reduction: 5375 case OMPC_linear: 5376 case OMPC_aligned: 5377 case OMPC_copyin: 5378 case OMPC_copyprivate: 5379 case OMPC_nowait: 5380 case OMPC_untied: 5381 case OMPC_mergeable: 5382 case OMPC_allocate: 5383 case OMPC_read: 5384 case OMPC_write: 5385 case OMPC_update: 5386 case OMPC_capture: 5387 case OMPC_seq_cst: 5388 case OMPC_acq_rel: 5389 case OMPC_acquire: 5390 case OMPC_release: 5391 case OMPC_relaxed: 5392 case OMPC_depend: 5393 case OMPC_threads: 5394 case OMPC_simd: 5395 case OMPC_map: 5396 case OMPC_nogroup: 5397 case OMPC_defaultmap: 5398 case OMPC_to: 5399 case OMPC_from: 5400 case OMPC_use_device_ptr: 5401 case OMPC_use_device_addr: 5402 case OMPC_is_device_ptr: 5403 case OMPC_nontemporal: 5404 case OMPC_order: 5405 case OMPC_destroy: 5406 case OMPC_inclusive: 5407 case OMPC_exclusive: 5408 case OMPC_uses_allocators: 5409 case OMPC_affinity: 5410 continue; 5411 case OMPC_allocator: 5412 case OMPC_flush: 5413 case OMPC_depobj: 5414 case OMPC_threadprivate: 5415 case OMPC_uniform: 5416 case OMPC_unknown: 5417 case OMPC_unified_address: 5418 case OMPC_unified_shared_memory: 5419 case OMPC_reverse_offload: 5420 case OMPC_dynamic_allocators: 5421 case OMPC_atomic_default_mem_order: 5422 case OMPC_device_type: 5423 case OMPC_match: 5424 llvm_unreachable("Unexpected clause"); 5425 } 5426 for (Stmt *CC : C->children()) { 5427 if (CC) 5428 DSAChecker.Visit(CC); 5429 } 5430 } 5431 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5432 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5433 } 5434 for (const auto &P : VarsWithInheritedDSA) { 5435 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5436 continue; 5437 ErrorFound = true; 5438 if (DSAStack->getDefaultDSA() == DSA_none) { 5439 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5440 << P.first << P.second->getSourceRange(); 5441 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5442 } else if (getLangOpts().OpenMP >= 50) { 5443 Diag(P.second->getExprLoc(), 5444 diag::err_omp_defaultmap_no_attr_for_variable) 5445 << P.first << P.second->getSourceRange(); 5446 Diag(DSAStack->getDefaultDSALocation(), 5447 diag::note_omp_defaultmap_attr_none); 5448 } 5449 } 5450 5451 if (!AllowedNameModifiers.empty()) 5452 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5453 ErrorFound; 5454 5455 if (ErrorFound) 5456 return StmtError(); 5457 5458 if (!CurContext->isDependentContext() && 5459 isOpenMPTargetExecutionDirective(Kind) && 5460 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5461 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5462 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5463 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5464 // Register target to DSA Stack. 5465 DSAStack->addTargetDirLocation(StartLoc); 5466 } 5467 5468 return Res; 5469 } 5470 5471 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5472 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5473 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5474 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5475 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5476 assert(Aligneds.size() == Alignments.size()); 5477 assert(Linears.size() == LinModifiers.size()); 5478 assert(Linears.size() == Steps.size()); 5479 if (!DG || DG.get().isNull()) 5480 return DeclGroupPtrTy(); 5481 5482 const int SimdId = 0; 5483 if (!DG.get().isSingleDecl()) { 5484 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5485 << SimdId; 5486 return DG; 5487 } 5488 Decl *ADecl = DG.get().getSingleDecl(); 5489 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5490 ADecl = FTD->getTemplatedDecl(); 5491 5492 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5493 if (!FD) { 5494 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5495 return DeclGroupPtrTy(); 5496 } 5497 5498 // OpenMP [2.8.2, declare simd construct, Description] 5499 // The parameter of the simdlen clause must be a constant positive integer 5500 // expression. 5501 ExprResult SL; 5502 if (Simdlen) 5503 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5504 // OpenMP [2.8.2, declare simd construct, Description] 5505 // The special this pointer can be used as if was one of the arguments to the 5506 // function in any of the linear, aligned, or uniform clauses. 5507 // The uniform clause declares one or more arguments to have an invariant 5508 // value for all concurrent invocations of the function in the execution of a 5509 // single SIMD loop. 5510 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5511 const Expr *UniformedLinearThis = nullptr; 5512 for (const Expr *E : Uniforms) { 5513 E = E->IgnoreParenImpCasts(); 5514 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5515 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5516 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5517 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5518 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5519 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5520 continue; 5521 } 5522 if (isa<CXXThisExpr>(E)) { 5523 UniformedLinearThis = E; 5524 continue; 5525 } 5526 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5527 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5528 } 5529 // OpenMP [2.8.2, declare simd construct, Description] 5530 // The aligned clause declares that the object to which each list item points 5531 // is aligned to the number of bytes expressed in the optional parameter of 5532 // the aligned clause. 5533 // The special this pointer can be used as if was one of the arguments to the 5534 // function in any of the linear, aligned, or uniform clauses. 5535 // The type of list items appearing in the aligned clause must be array, 5536 // pointer, reference to array, or reference to pointer. 5537 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5538 const Expr *AlignedThis = nullptr; 5539 for (const Expr *E : Aligneds) { 5540 E = E->IgnoreParenImpCasts(); 5541 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5542 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5543 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5544 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5545 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5546 ->getCanonicalDecl() == CanonPVD) { 5547 // OpenMP [2.8.1, simd construct, Restrictions] 5548 // A list-item cannot appear in more than one aligned clause. 5549 if (AlignedArgs.count(CanonPVD) > 0) { 5550 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5551 << 1 << getOpenMPClauseName(OMPC_aligned) 5552 << E->getSourceRange(); 5553 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5554 diag::note_omp_explicit_dsa) 5555 << getOpenMPClauseName(OMPC_aligned); 5556 continue; 5557 } 5558 AlignedArgs[CanonPVD] = E; 5559 QualType QTy = PVD->getType() 5560 .getNonReferenceType() 5561 .getUnqualifiedType() 5562 .getCanonicalType(); 5563 const Type *Ty = QTy.getTypePtrOrNull(); 5564 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5565 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5566 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5567 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5568 } 5569 continue; 5570 } 5571 } 5572 if (isa<CXXThisExpr>(E)) { 5573 if (AlignedThis) { 5574 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5575 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5576 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5577 << getOpenMPClauseName(OMPC_aligned); 5578 } 5579 AlignedThis = E; 5580 continue; 5581 } 5582 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5583 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5584 } 5585 // The optional parameter of the aligned clause, alignment, must be a constant 5586 // positive integer expression. If no optional parameter is specified, 5587 // implementation-defined default alignments for SIMD instructions on the 5588 // target platforms are assumed. 5589 SmallVector<const Expr *, 4> NewAligns; 5590 for (Expr *E : Alignments) { 5591 ExprResult Align; 5592 if (E) 5593 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5594 NewAligns.push_back(Align.get()); 5595 } 5596 // OpenMP [2.8.2, declare simd construct, Description] 5597 // The linear clause declares one or more list items to be private to a SIMD 5598 // lane and to have a linear relationship with respect to the iteration space 5599 // of a loop. 5600 // The special this pointer can be used as if was one of the arguments to the 5601 // function in any of the linear, aligned, or uniform clauses. 5602 // When a linear-step expression is specified in a linear clause it must be 5603 // either a constant integer expression or an integer-typed parameter that is 5604 // specified in a uniform clause on the directive. 5605 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5606 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5607 auto MI = LinModifiers.begin(); 5608 for (const Expr *E : Linears) { 5609 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5610 ++MI; 5611 E = E->IgnoreParenImpCasts(); 5612 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5613 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5614 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5615 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5616 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5617 ->getCanonicalDecl() == CanonPVD) { 5618 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5619 // A list-item cannot appear in more than one linear clause. 5620 if (LinearArgs.count(CanonPVD) > 0) { 5621 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5622 << getOpenMPClauseName(OMPC_linear) 5623 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5624 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5625 diag::note_omp_explicit_dsa) 5626 << getOpenMPClauseName(OMPC_linear); 5627 continue; 5628 } 5629 // Each argument can appear in at most one uniform or linear clause. 5630 if (UniformedArgs.count(CanonPVD) > 0) { 5631 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5632 << getOpenMPClauseName(OMPC_linear) 5633 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5634 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5635 diag::note_omp_explicit_dsa) 5636 << getOpenMPClauseName(OMPC_uniform); 5637 continue; 5638 } 5639 LinearArgs[CanonPVD] = E; 5640 if (E->isValueDependent() || E->isTypeDependent() || 5641 E->isInstantiationDependent() || 5642 E->containsUnexpandedParameterPack()) 5643 continue; 5644 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5645 PVD->getOriginalType(), 5646 /*IsDeclareSimd=*/true); 5647 continue; 5648 } 5649 } 5650 if (isa<CXXThisExpr>(E)) { 5651 if (UniformedLinearThis) { 5652 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5653 << getOpenMPClauseName(OMPC_linear) 5654 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5655 << E->getSourceRange(); 5656 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5657 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5658 : OMPC_linear); 5659 continue; 5660 } 5661 UniformedLinearThis = E; 5662 if (E->isValueDependent() || E->isTypeDependent() || 5663 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5664 continue; 5665 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5666 E->getType(), /*IsDeclareSimd=*/true); 5667 continue; 5668 } 5669 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5670 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5671 } 5672 Expr *Step = nullptr; 5673 Expr *NewStep = nullptr; 5674 SmallVector<Expr *, 4> NewSteps; 5675 for (Expr *E : Steps) { 5676 // Skip the same step expression, it was checked already. 5677 if (Step == E || !E) { 5678 NewSteps.push_back(E ? NewStep : nullptr); 5679 continue; 5680 } 5681 Step = E; 5682 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5683 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5684 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5685 if (UniformedArgs.count(CanonPVD) == 0) { 5686 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5687 << Step->getSourceRange(); 5688 } else if (E->isValueDependent() || E->isTypeDependent() || 5689 E->isInstantiationDependent() || 5690 E->containsUnexpandedParameterPack() || 5691 CanonPVD->getType()->hasIntegerRepresentation()) { 5692 NewSteps.push_back(Step); 5693 } else { 5694 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5695 << Step->getSourceRange(); 5696 } 5697 continue; 5698 } 5699 NewStep = Step; 5700 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5701 !Step->isInstantiationDependent() && 5702 !Step->containsUnexpandedParameterPack()) { 5703 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5704 .get(); 5705 if (NewStep) 5706 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5707 } 5708 NewSteps.push_back(NewStep); 5709 } 5710 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5711 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5712 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5713 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5714 const_cast<Expr **>(Linears.data()), Linears.size(), 5715 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5716 NewSteps.data(), NewSteps.size(), SR); 5717 ADecl->addAttr(NewAttr); 5718 return DG; 5719 } 5720 5721 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5722 QualType NewType) { 5723 assert(NewType->isFunctionProtoType() && 5724 "Expected function type with prototype."); 5725 assert(FD->getType()->isFunctionNoProtoType() && 5726 "Expected function with type with no prototype."); 5727 assert(FDWithProto->getType()->isFunctionProtoType() && 5728 "Expected function with prototype."); 5729 // Synthesize parameters with the same types. 5730 FD->setType(NewType); 5731 SmallVector<ParmVarDecl *, 16> Params; 5732 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5733 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5734 SourceLocation(), nullptr, P->getType(), 5735 /*TInfo=*/nullptr, SC_None, nullptr); 5736 Param->setScopeInfo(0, Params.size()); 5737 Param->setImplicit(); 5738 Params.push_back(Param); 5739 } 5740 5741 FD->setParams(Params); 5742 } 5743 5744 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 5745 : TI(&TI), NameSuffix(TI.getMangledName()) {} 5746 5747 FunctionDecl * 5748 Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, 5749 Declarator &D) { 5750 IdentifierInfo *BaseII = D.getIdentifier(); 5751 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 5752 LookupOrdinaryName); 5753 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 5754 5755 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 5756 QualType FType = TInfo->getType(); 5757 5758 bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr; 5759 bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval; 5760 5761 FunctionDecl *BaseFD = nullptr; 5762 for (auto *Candidate : Lookup) { 5763 auto *UDecl = dyn_cast<FunctionDecl>(Candidate->getUnderlyingDecl()); 5764 if (!UDecl) 5765 continue; 5766 5767 // Don't specialize constexpr/consteval functions with 5768 // non-constexpr/consteval functions. 5769 if (UDecl->isConstexpr() && !IsConstexpr) 5770 continue; 5771 if (UDecl->isConsteval() && !IsConsteval) 5772 continue; 5773 5774 QualType NewType = Context.mergeFunctionTypes( 5775 FType, UDecl->getType(), /* OfBlockPointer */ false, 5776 /* Unqualified */ false, /* AllowCXX */ true); 5777 if (NewType.isNull()) 5778 continue; 5779 5780 // Found a base! 5781 BaseFD = UDecl; 5782 break; 5783 } 5784 if (!BaseFD) { 5785 BaseFD = cast<FunctionDecl>(ActOnDeclarator(S, D)); 5786 BaseFD->setImplicit(true); 5787 } 5788 5789 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5790 std::string MangledName; 5791 MangledName += D.getIdentifier()->getName(); 5792 MangledName += getOpenMPVariantManglingSeparatorStr(); 5793 MangledName += DVScope.NameSuffix; 5794 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 5795 5796 VariantII.setMangledOpenMPVariantName(true); 5797 D.SetIdentifier(&VariantII, D.getBeginLoc()); 5798 return BaseFD; 5799 } 5800 5801 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 5802 FunctionDecl *FD, FunctionDecl *BaseFD) { 5803 // Do not mark function as is used to prevent its emission if this is the 5804 // only place where it is used. 5805 EnterExpressionEvaluationContext Unevaluated( 5806 *this, Sema::ExpressionEvaluationContext::Unevaluated); 5807 5808 Expr *VariantFuncRef = DeclRefExpr::Create( 5809 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 5810 /* RefersToEnclosingVariableOrCapture */ false, 5811 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); 5812 5813 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5814 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 5815 Context, VariantFuncRef, DVScope.TI); 5816 BaseFD->addAttr(OMPDeclareVariantA); 5817 } 5818 5819 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 5820 SourceLocation LParenLoc, 5821 MultiExprArg ArgExprs, 5822 SourceLocation RParenLoc, Expr *ExecConfig) { 5823 // The common case is a regular call we do not want to specialize at all. Try 5824 // to make that case fast by bailing early. 5825 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 5826 if (!CE) 5827 return Call; 5828 5829 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 5830 if (!CalleeFnDecl) 5831 return Call; 5832 5833 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 5834 return Call; 5835 5836 ASTContext &Context = getASTContext(); 5837 OMPContext OMPCtx(getLangOpts().OpenMPIsDevice, 5838 Context.getTargetInfo().getTriple()); 5839 5840 SmallVector<Expr *, 4> Exprs; 5841 SmallVector<VariantMatchInfo, 4> VMIs; 5842 while (CalleeFnDecl) { 5843 for (OMPDeclareVariantAttr *A : 5844 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 5845 Expr *VariantRef = A->getVariantFuncRef(); 5846 5847 VariantMatchInfo VMI; 5848 OMPTraitInfo &TI = A->getTraitInfo(); 5849 TI.getAsVariantMatchInfo(Context, VMI); 5850 if (!isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ false)) 5851 continue; 5852 5853 VMIs.push_back(VMI); 5854 Exprs.push_back(VariantRef); 5855 } 5856 5857 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 5858 } 5859 5860 ExprResult NewCall; 5861 do { 5862 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 5863 if (BestIdx < 0) 5864 return Call; 5865 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 5866 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 5867 5868 { 5869 // Try to build a (member) call expression for the current best applicable 5870 // variant expression. We allow this to fail in which case we continue 5871 // with the next best variant expression. The fail case is part of the 5872 // implementation defined behavior in the OpenMP standard when it talks 5873 // about what differences in the function prototypes: "Any differences 5874 // that the specific OpenMP context requires in the prototype of the 5875 // variant from the base function prototype are implementation defined." 5876 // This wording is there to allow the specialized variant to have a 5877 // different type than the base function. This is intended and OK but if 5878 // we cannot create a call the difference is not in the "implementation 5879 // defined range" we allow. 5880 Sema::TentativeAnalysisScope Trap(*this); 5881 5882 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 5883 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 5884 BestExpr = MemberExpr::CreateImplicit( 5885 Context, MemberCall->getImplicitObjectArgument(), 5886 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 5887 MemberCall->getValueKind(), MemberCall->getObjectKind()); 5888 } 5889 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 5890 ExecConfig); 5891 if (NewCall.isUsable()) 5892 break; 5893 } 5894 5895 VMIs.erase(VMIs.begin() + BestIdx); 5896 Exprs.erase(Exprs.begin() + BestIdx); 5897 } while (!VMIs.empty()); 5898 5899 if (!NewCall.isUsable()) 5900 return Call; 5901 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 5902 } 5903 5904 Optional<std::pair<FunctionDecl *, Expr *>> 5905 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5906 Expr *VariantRef, OMPTraitInfo &TI, 5907 SourceRange SR) { 5908 if (!DG || DG.get().isNull()) 5909 return None; 5910 5911 const int VariantId = 1; 5912 // Must be applied only to single decl. 5913 if (!DG.get().isSingleDecl()) { 5914 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5915 << VariantId << SR; 5916 return None; 5917 } 5918 Decl *ADecl = DG.get().getSingleDecl(); 5919 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5920 ADecl = FTD->getTemplatedDecl(); 5921 5922 // Decl must be a function. 5923 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5924 if (!FD) { 5925 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5926 << VariantId << SR; 5927 return None; 5928 } 5929 5930 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5931 return FD->hasAttrs() && 5932 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5933 FD->hasAttr<TargetAttr>()); 5934 }; 5935 // OpenMP is not compatible with CPU-specific attributes. 5936 if (HasMultiVersionAttributes(FD)) { 5937 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5938 << SR; 5939 return None; 5940 } 5941 5942 // Allow #pragma omp declare variant only if the function is not used. 5943 if (FD->isUsed(false)) 5944 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5945 << FD->getLocation(); 5946 5947 // Check if the function was emitted already. 5948 const FunctionDecl *Definition; 5949 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5950 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5951 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5952 << FD->getLocation(); 5953 5954 // The VariantRef must point to function. 5955 if (!VariantRef) { 5956 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5957 return None; 5958 } 5959 5960 auto ShouldDelayChecks = [](Expr *&E, bool) { 5961 return E && (E->isTypeDependent() || E->isValueDependent() || 5962 E->containsUnexpandedParameterPack() || 5963 E->isInstantiationDependent()); 5964 }; 5965 // Do not check templates, wait until instantiation. 5966 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 5967 TI.anyScoreOrCondition(ShouldDelayChecks)) 5968 return std::make_pair(FD, VariantRef); 5969 5970 // Deal with non-constant score and user condition expressions. 5971 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 5972 bool IsScore) -> bool { 5973 llvm::APSInt Result; 5974 if (!E || E->isIntegerConstantExpr(Result, Context)) 5975 return false; 5976 5977 if (IsScore) { 5978 // We warn on non-constant scores and pretend they were not present. 5979 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 5980 << E; 5981 E = nullptr; 5982 } else { 5983 // We could replace a non-constant user condition with "false" but we 5984 // will soon need to handle these anyway for the dynamic version of 5985 // OpenMP context selectors. 5986 Diag(E->getExprLoc(), 5987 diag::err_omp_declare_variant_user_condition_not_constant) 5988 << E; 5989 } 5990 return true; 5991 }; 5992 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 5993 return None; 5994 5995 // Convert VariantRef expression to the type of the original function to 5996 // resolve possible conflicts. 5997 ExprResult VariantRefCast; 5998 if (LangOpts.CPlusPlus) { 5999 QualType FnPtrType; 6000 auto *Method = dyn_cast<CXXMethodDecl>(FD); 6001 if (Method && !Method->isStatic()) { 6002 const Type *ClassType = 6003 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 6004 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 6005 ExprResult ER; 6006 { 6007 // Build adrr_of unary op to correctly handle type checks for member 6008 // functions. 6009 Sema::TentativeAnalysisScope Trap(*this); 6010 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 6011 VariantRef); 6012 } 6013 if (!ER.isUsable()) { 6014 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6015 << VariantId << VariantRef->getSourceRange(); 6016 return None; 6017 } 6018 VariantRef = ER.get(); 6019 } else { 6020 FnPtrType = Context.getPointerType(FD->getType()); 6021 } 6022 ImplicitConversionSequence ICS = 6023 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 6024 /*SuppressUserConversions=*/false, 6025 AllowedExplicit::None, 6026 /*InOverloadResolution=*/false, 6027 /*CStyle=*/false, 6028 /*AllowObjCWritebackConversion=*/false); 6029 if (ICS.isFailure()) { 6030 Diag(VariantRef->getExprLoc(), 6031 diag::err_omp_declare_variant_incompat_types) 6032 << VariantRef->getType() 6033 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 6034 << VariantRef->getSourceRange(); 6035 return None; 6036 } 6037 VariantRefCast = PerformImplicitConversion( 6038 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 6039 if (!VariantRefCast.isUsable()) 6040 return None; 6041 // Drop previously built artificial addr_of unary op for member functions. 6042 if (Method && !Method->isStatic()) { 6043 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 6044 if (auto *UO = dyn_cast<UnaryOperator>( 6045 PossibleAddrOfVariantRef->IgnoreImplicit())) 6046 VariantRefCast = UO->getSubExpr(); 6047 } 6048 } else { 6049 VariantRefCast = VariantRef; 6050 } 6051 6052 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 6053 if (!ER.isUsable() || 6054 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 6055 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6056 << VariantId << VariantRef->getSourceRange(); 6057 return None; 6058 } 6059 6060 // The VariantRef must point to function. 6061 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 6062 if (!DRE) { 6063 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6064 << VariantId << VariantRef->getSourceRange(); 6065 return None; 6066 } 6067 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 6068 if (!NewFD) { 6069 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6070 << VariantId << VariantRef->getSourceRange(); 6071 return None; 6072 } 6073 6074 // Check if function types are compatible in C. 6075 if (!LangOpts.CPlusPlus) { 6076 QualType NewType = 6077 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 6078 if (NewType.isNull()) { 6079 Diag(VariantRef->getExprLoc(), 6080 diag::err_omp_declare_variant_incompat_types) 6081 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 6082 return None; 6083 } 6084 if (NewType->isFunctionProtoType()) { 6085 if (FD->getType()->isFunctionNoProtoType()) 6086 setPrototype(*this, FD, NewFD, NewType); 6087 else if (NewFD->getType()->isFunctionNoProtoType()) 6088 setPrototype(*this, NewFD, FD, NewType); 6089 } 6090 } 6091 6092 // Check if variant function is not marked with declare variant directive. 6093 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 6094 Diag(VariantRef->getExprLoc(), 6095 diag::warn_omp_declare_variant_marked_as_declare_variant) 6096 << VariantRef->getSourceRange(); 6097 SourceRange SR = 6098 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 6099 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 6100 return None; 6101 } 6102 6103 enum DoesntSupport { 6104 VirtFuncs = 1, 6105 Constructors = 3, 6106 Destructors = 4, 6107 DeletedFuncs = 5, 6108 DefaultedFuncs = 6, 6109 ConstexprFuncs = 7, 6110 ConstevalFuncs = 8, 6111 }; 6112 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 6113 if (CXXFD->isVirtual()) { 6114 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6115 << VirtFuncs; 6116 return None; 6117 } 6118 6119 if (isa<CXXConstructorDecl>(FD)) { 6120 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6121 << Constructors; 6122 return None; 6123 } 6124 6125 if (isa<CXXDestructorDecl>(FD)) { 6126 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6127 << Destructors; 6128 return None; 6129 } 6130 } 6131 6132 if (FD->isDeleted()) { 6133 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6134 << DeletedFuncs; 6135 return None; 6136 } 6137 6138 if (FD->isDefaulted()) { 6139 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6140 << DefaultedFuncs; 6141 return None; 6142 } 6143 6144 if (FD->isConstexpr()) { 6145 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6146 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 6147 return None; 6148 } 6149 6150 // Check general compatibility. 6151 if (areMultiversionVariantFunctionsCompatible( 6152 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 6153 PartialDiagnosticAt(SourceLocation(), 6154 PartialDiagnostic::NullDiagnostic()), 6155 PartialDiagnosticAt( 6156 VariantRef->getExprLoc(), 6157 PDiag(diag::err_omp_declare_variant_doesnt_support)), 6158 PartialDiagnosticAt(VariantRef->getExprLoc(), 6159 PDiag(diag::err_omp_declare_variant_diff) 6160 << FD->getLocation()), 6161 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 6162 /*CLinkageMayDiffer=*/true)) 6163 return None; 6164 return std::make_pair(FD, cast<Expr>(DRE)); 6165 } 6166 6167 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 6168 Expr *VariantRef, 6169 OMPTraitInfo &TI, 6170 SourceRange SR) { 6171 auto *NewAttr = 6172 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); 6173 FD->addAttr(NewAttr); 6174 } 6175 6176 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 6177 Stmt *AStmt, 6178 SourceLocation StartLoc, 6179 SourceLocation EndLoc) { 6180 if (!AStmt) 6181 return StmtError(); 6182 6183 auto *CS = cast<CapturedStmt>(AStmt); 6184 // 1.2.2 OpenMP Language Terminology 6185 // Structured block - An executable statement with a single entry at the 6186 // top and a single exit at the bottom. 6187 // The point of exit cannot be a branch out of the structured block. 6188 // longjmp() and throw() must not violate the entry/exit criteria. 6189 CS->getCapturedDecl()->setNothrow(); 6190 6191 setFunctionHasBranchProtectedScope(); 6192 6193 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6194 DSAStack->getTaskgroupReductionRef(), 6195 DSAStack->isCancelRegion()); 6196 } 6197 6198 namespace { 6199 /// Iteration space of a single for loop. 6200 struct LoopIterationSpace final { 6201 /// True if the condition operator is the strict compare operator (<, > or 6202 /// !=). 6203 bool IsStrictCompare = false; 6204 /// Condition of the loop. 6205 Expr *PreCond = nullptr; 6206 /// This expression calculates the number of iterations in the loop. 6207 /// It is always possible to calculate it before starting the loop. 6208 Expr *NumIterations = nullptr; 6209 /// The loop counter variable. 6210 Expr *CounterVar = nullptr; 6211 /// Private loop counter variable. 6212 Expr *PrivateCounterVar = nullptr; 6213 /// This is initializer for the initial value of #CounterVar. 6214 Expr *CounterInit = nullptr; 6215 /// This is step for the #CounterVar used to generate its update: 6216 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 6217 Expr *CounterStep = nullptr; 6218 /// Should step be subtracted? 6219 bool Subtract = false; 6220 /// Source range of the loop init. 6221 SourceRange InitSrcRange; 6222 /// Source range of the loop condition. 6223 SourceRange CondSrcRange; 6224 /// Source range of the loop increment. 6225 SourceRange IncSrcRange; 6226 /// Minimum value that can have the loop control variable. Used to support 6227 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 6228 /// since only such variables can be used in non-loop invariant expressions. 6229 Expr *MinValue = nullptr; 6230 /// Maximum value that can have the loop control variable. Used to support 6231 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 6232 /// since only such variables can be used in non-loop invariant expressions. 6233 Expr *MaxValue = nullptr; 6234 /// true, if the lower bound depends on the outer loop control var. 6235 bool IsNonRectangularLB = false; 6236 /// true, if the upper bound depends on the outer loop control var. 6237 bool IsNonRectangularUB = false; 6238 /// Index of the loop this loop depends on and forms non-rectangular loop 6239 /// nest. 6240 unsigned LoopDependentIdx = 0; 6241 /// Final condition for the non-rectangular loop nest support. It is used to 6242 /// check that the number of iterations for this particular counter must be 6243 /// finished. 6244 Expr *FinalCondition = nullptr; 6245 }; 6246 6247 /// Helper class for checking canonical form of the OpenMP loops and 6248 /// extracting iteration space of each loop in the loop nest, that will be used 6249 /// for IR generation. 6250 class OpenMPIterationSpaceChecker { 6251 /// Reference to Sema. 6252 Sema &SemaRef; 6253 /// Data-sharing stack. 6254 DSAStackTy &Stack; 6255 /// A location for diagnostics (when there is no some better location). 6256 SourceLocation DefaultLoc; 6257 /// A location for diagnostics (when increment is not compatible). 6258 SourceLocation ConditionLoc; 6259 /// A source location for referring to loop init later. 6260 SourceRange InitSrcRange; 6261 /// A source location for referring to condition later. 6262 SourceRange ConditionSrcRange; 6263 /// A source location for referring to increment later. 6264 SourceRange IncrementSrcRange; 6265 /// Loop variable. 6266 ValueDecl *LCDecl = nullptr; 6267 /// Reference to loop variable. 6268 Expr *LCRef = nullptr; 6269 /// Lower bound (initializer for the var). 6270 Expr *LB = nullptr; 6271 /// Upper bound. 6272 Expr *UB = nullptr; 6273 /// Loop step (increment). 6274 Expr *Step = nullptr; 6275 /// This flag is true when condition is one of: 6276 /// Var < UB 6277 /// Var <= UB 6278 /// UB > Var 6279 /// UB >= Var 6280 /// This will have no value when the condition is != 6281 llvm::Optional<bool> TestIsLessOp; 6282 /// This flag is true when condition is strict ( < or > ). 6283 bool TestIsStrictOp = false; 6284 /// This flag is true when step is subtracted on each iteration. 6285 bool SubtractStep = false; 6286 /// The outer loop counter this loop depends on (if any). 6287 const ValueDecl *DepDecl = nullptr; 6288 /// Contains number of loop (starts from 1) on which loop counter init 6289 /// expression of this loop depends on. 6290 Optional<unsigned> InitDependOnLC; 6291 /// Contains number of loop (starts from 1) on which loop counter condition 6292 /// expression of this loop depends on. 6293 Optional<unsigned> CondDependOnLC; 6294 /// Checks if the provide statement depends on the loop counter. 6295 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 6296 /// Original condition required for checking of the exit condition for 6297 /// non-rectangular loop. 6298 Expr *Condition = nullptr; 6299 6300 public: 6301 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 6302 SourceLocation DefaultLoc) 6303 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 6304 ConditionLoc(DefaultLoc) {} 6305 /// Check init-expr for canonical loop form and save loop counter 6306 /// variable - #Var and its initialization value - #LB. 6307 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 6308 /// Check test-expr for canonical form, save upper-bound (#UB), flags 6309 /// for less/greater and for strict/non-strict comparison. 6310 bool checkAndSetCond(Expr *S); 6311 /// Check incr-expr for canonical loop form and return true if it 6312 /// does not conform, otherwise save loop step (#Step). 6313 bool checkAndSetInc(Expr *S); 6314 /// Return the loop counter variable. 6315 ValueDecl *getLoopDecl() const { return LCDecl; } 6316 /// Return the reference expression to loop counter variable. 6317 Expr *getLoopDeclRefExpr() const { return LCRef; } 6318 /// Source range of the loop init. 6319 SourceRange getInitSrcRange() const { return InitSrcRange; } 6320 /// Source range of the loop condition. 6321 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 6322 /// Source range of the loop increment. 6323 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 6324 /// True if the step should be subtracted. 6325 bool shouldSubtractStep() const { return SubtractStep; } 6326 /// True, if the compare operator is strict (<, > or !=). 6327 bool isStrictTestOp() const { return TestIsStrictOp; } 6328 /// Build the expression to calculate the number of iterations. 6329 Expr *buildNumIterations( 6330 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6331 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6332 /// Build the precondition expression for the loops. 6333 Expr * 6334 buildPreCond(Scope *S, Expr *Cond, 6335 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6336 /// Build reference expression to the counter be used for codegen. 6337 DeclRefExpr * 6338 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6339 DSAStackTy &DSA) const; 6340 /// Build reference expression to the private counter be used for 6341 /// codegen. 6342 Expr *buildPrivateCounterVar() const; 6343 /// Build initialization of the counter be used for codegen. 6344 Expr *buildCounterInit() const; 6345 /// Build step of the counter be used for codegen. 6346 Expr *buildCounterStep() const; 6347 /// Build loop data with counter value for depend clauses in ordered 6348 /// directives. 6349 Expr * 6350 buildOrderedLoopData(Scope *S, Expr *Counter, 6351 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6352 SourceLocation Loc, Expr *Inc = nullptr, 6353 OverloadedOperatorKind OOK = OO_Amp); 6354 /// Builds the minimum value for the loop counter. 6355 std::pair<Expr *, Expr *> buildMinMaxValues( 6356 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6357 /// Builds final condition for the non-rectangular loops. 6358 Expr *buildFinalCondition(Scope *S) const; 6359 /// Return true if any expression is dependent. 6360 bool dependent() const; 6361 /// Returns true if the initializer forms non-rectangular loop. 6362 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 6363 /// Returns true if the condition forms non-rectangular loop. 6364 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 6365 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 6366 unsigned getLoopDependentIdx() const { 6367 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 6368 } 6369 6370 private: 6371 /// Check the right-hand side of an assignment in the increment 6372 /// expression. 6373 bool checkAndSetIncRHS(Expr *RHS); 6374 /// Helper to set loop counter variable and its initializer. 6375 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 6376 bool EmitDiags); 6377 /// Helper to set upper bound. 6378 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 6379 SourceRange SR, SourceLocation SL); 6380 /// Helper to set loop increment. 6381 bool setStep(Expr *NewStep, bool Subtract); 6382 }; 6383 6384 bool OpenMPIterationSpaceChecker::dependent() const { 6385 if (!LCDecl) { 6386 assert(!LB && !UB && !Step); 6387 return false; 6388 } 6389 return LCDecl->getType()->isDependentType() || 6390 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 6391 (Step && Step->isValueDependent()); 6392 } 6393 6394 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 6395 Expr *NewLCRefExpr, 6396 Expr *NewLB, bool EmitDiags) { 6397 // State consistency checking to ensure correct usage. 6398 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 6399 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6400 if (!NewLCDecl || !NewLB) 6401 return true; 6402 LCDecl = getCanonicalDecl(NewLCDecl); 6403 LCRef = NewLCRefExpr; 6404 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 6405 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6406 if ((Ctor->isCopyOrMoveConstructor() || 6407 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6408 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6409 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 6410 LB = NewLB; 6411 if (EmitDiags) 6412 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 6413 return false; 6414 } 6415 6416 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 6417 llvm::Optional<bool> LessOp, 6418 bool StrictOp, SourceRange SR, 6419 SourceLocation SL) { 6420 // State consistency checking to ensure correct usage. 6421 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 6422 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6423 if (!NewUB) 6424 return true; 6425 UB = NewUB; 6426 if (LessOp) 6427 TestIsLessOp = LessOp; 6428 TestIsStrictOp = StrictOp; 6429 ConditionSrcRange = SR; 6430 ConditionLoc = SL; 6431 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 6432 return false; 6433 } 6434 6435 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 6436 // State consistency checking to ensure correct usage. 6437 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 6438 if (!NewStep) 6439 return true; 6440 if (!NewStep->isValueDependent()) { 6441 // Check that the step is integer expression. 6442 SourceLocation StepLoc = NewStep->getBeginLoc(); 6443 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 6444 StepLoc, getExprAsWritten(NewStep)); 6445 if (Val.isInvalid()) 6446 return true; 6447 NewStep = Val.get(); 6448 6449 // OpenMP [2.6, Canonical Loop Form, Restrictions] 6450 // If test-expr is of form var relational-op b and relational-op is < or 6451 // <= then incr-expr must cause var to increase on each iteration of the 6452 // loop. If test-expr is of form var relational-op b and relational-op is 6453 // > or >= then incr-expr must cause var to decrease on each iteration of 6454 // the loop. 6455 // If test-expr is of form b relational-op var and relational-op is < or 6456 // <= then incr-expr must cause var to decrease on each iteration of the 6457 // loop. If test-expr is of form b relational-op var and relational-op is 6458 // > or >= then incr-expr must cause var to increase on each iteration of 6459 // the loop. 6460 llvm::APSInt Result; 6461 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 6462 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 6463 bool IsConstNeg = 6464 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 6465 bool IsConstPos = 6466 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 6467 bool IsConstZero = IsConstant && !Result.getBoolValue(); 6468 6469 // != with increment is treated as <; != with decrement is treated as > 6470 if (!TestIsLessOp.hasValue()) 6471 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 6472 if (UB && (IsConstZero || 6473 (TestIsLessOp.getValue() ? 6474 (IsConstNeg || (IsUnsigned && Subtract)) : 6475 (IsConstPos || (IsUnsigned && !Subtract))))) { 6476 SemaRef.Diag(NewStep->getExprLoc(), 6477 diag::err_omp_loop_incr_not_compatible) 6478 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 6479 SemaRef.Diag(ConditionLoc, 6480 diag::note_omp_loop_cond_requres_compatible_incr) 6481 << TestIsLessOp.getValue() << ConditionSrcRange; 6482 return true; 6483 } 6484 if (TestIsLessOp.getValue() == Subtract) { 6485 NewStep = 6486 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 6487 .get(); 6488 Subtract = !Subtract; 6489 } 6490 } 6491 6492 Step = NewStep; 6493 SubtractStep = Subtract; 6494 return false; 6495 } 6496 6497 namespace { 6498 /// Checker for the non-rectangular loops. Checks if the initializer or 6499 /// condition expression references loop counter variable. 6500 class LoopCounterRefChecker final 6501 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 6502 Sema &SemaRef; 6503 DSAStackTy &Stack; 6504 const ValueDecl *CurLCDecl = nullptr; 6505 const ValueDecl *DepDecl = nullptr; 6506 const ValueDecl *PrevDepDecl = nullptr; 6507 bool IsInitializer = true; 6508 unsigned BaseLoopId = 0; 6509 bool checkDecl(const Expr *E, const ValueDecl *VD) { 6510 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 6511 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 6512 << (IsInitializer ? 0 : 1); 6513 return false; 6514 } 6515 const auto &&Data = Stack.isLoopControlVariable(VD); 6516 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6517 // The type of the loop iterator on which we depend may not have a random 6518 // access iterator type. 6519 if (Data.first && VD->getType()->isRecordType()) { 6520 SmallString<128> Name; 6521 llvm::raw_svector_ostream OS(Name); 6522 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6523 /*Qualified=*/true); 6524 SemaRef.Diag(E->getExprLoc(), 6525 diag::err_omp_wrong_dependency_iterator_type) 6526 << OS.str(); 6527 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6528 return false; 6529 } 6530 if (Data.first && 6531 (DepDecl || (PrevDepDecl && 6532 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6533 if (!DepDecl && PrevDepDecl) 6534 DepDecl = PrevDepDecl; 6535 SmallString<128> Name; 6536 llvm::raw_svector_ostream OS(Name); 6537 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6538 /*Qualified=*/true); 6539 SemaRef.Diag(E->getExprLoc(), 6540 diag::err_omp_invariant_or_linear_dependency) 6541 << OS.str(); 6542 return false; 6543 } 6544 if (Data.first) { 6545 DepDecl = VD; 6546 BaseLoopId = Data.first; 6547 } 6548 return Data.first; 6549 } 6550 6551 public: 6552 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6553 const ValueDecl *VD = E->getDecl(); 6554 if (isa<VarDecl>(VD)) 6555 return checkDecl(E, VD); 6556 return false; 6557 } 6558 bool VisitMemberExpr(const MemberExpr *E) { 6559 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6560 const ValueDecl *VD = E->getMemberDecl(); 6561 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6562 return checkDecl(E, VD); 6563 } 6564 return false; 6565 } 6566 bool VisitStmt(const Stmt *S) { 6567 bool Res = false; 6568 for (const Stmt *Child : S->children()) 6569 Res = (Child && Visit(Child)) || Res; 6570 return Res; 6571 } 6572 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6573 const ValueDecl *CurLCDecl, bool IsInitializer, 6574 const ValueDecl *PrevDepDecl = nullptr) 6575 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6576 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6577 unsigned getBaseLoopId() const { 6578 assert(CurLCDecl && "Expected loop dependency."); 6579 return BaseLoopId; 6580 } 6581 const ValueDecl *getDepDecl() const { 6582 assert(CurLCDecl && "Expected loop dependency."); 6583 return DepDecl; 6584 } 6585 }; 6586 } // namespace 6587 6588 Optional<unsigned> 6589 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6590 bool IsInitializer) { 6591 // Check for the non-rectangular loops. 6592 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6593 DepDecl); 6594 if (LoopStmtChecker.Visit(S)) { 6595 DepDecl = LoopStmtChecker.getDepDecl(); 6596 return LoopStmtChecker.getBaseLoopId(); 6597 } 6598 return llvm::None; 6599 } 6600 6601 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6602 // Check init-expr for canonical loop form and save loop counter 6603 // variable - #Var and its initialization value - #LB. 6604 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6605 // var = lb 6606 // integer-type var = lb 6607 // random-access-iterator-type var = lb 6608 // pointer-type var = lb 6609 // 6610 if (!S) { 6611 if (EmitDiags) { 6612 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6613 } 6614 return true; 6615 } 6616 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6617 if (!ExprTemp->cleanupsHaveSideEffects()) 6618 S = ExprTemp->getSubExpr(); 6619 6620 InitSrcRange = S->getSourceRange(); 6621 if (Expr *E = dyn_cast<Expr>(S)) 6622 S = E->IgnoreParens(); 6623 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6624 if (BO->getOpcode() == BO_Assign) { 6625 Expr *LHS = BO->getLHS()->IgnoreParens(); 6626 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6627 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6628 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6629 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6630 EmitDiags); 6631 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6632 } 6633 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6634 if (ME->isArrow() && 6635 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6636 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6637 EmitDiags); 6638 } 6639 } 6640 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6641 if (DS->isSingleDecl()) { 6642 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6643 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6644 // Accept non-canonical init form here but emit ext. warning. 6645 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6646 SemaRef.Diag(S->getBeginLoc(), 6647 diag::ext_omp_loop_not_canonical_init) 6648 << S->getSourceRange(); 6649 return setLCDeclAndLB( 6650 Var, 6651 buildDeclRefExpr(SemaRef, Var, 6652 Var->getType().getNonReferenceType(), 6653 DS->getBeginLoc()), 6654 Var->getInit(), EmitDiags); 6655 } 6656 } 6657 } 6658 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6659 if (CE->getOperator() == OO_Equal) { 6660 Expr *LHS = CE->getArg(0); 6661 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6662 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6663 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6664 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6665 EmitDiags); 6666 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6667 } 6668 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6669 if (ME->isArrow() && 6670 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6671 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6672 EmitDiags); 6673 } 6674 } 6675 } 6676 6677 if (dependent() || SemaRef.CurContext->isDependentContext()) 6678 return false; 6679 if (EmitDiags) { 6680 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6681 << S->getSourceRange(); 6682 } 6683 return true; 6684 } 6685 6686 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6687 /// variable (which may be the loop variable) if possible. 6688 static const ValueDecl *getInitLCDecl(const Expr *E) { 6689 if (!E) 6690 return nullptr; 6691 E = getExprAsWritten(E); 6692 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6693 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6694 if ((Ctor->isCopyOrMoveConstructor() || 6695 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6696 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6697 E = CE->getArg(0)->IgnoreParenImpCasts(); 6698 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6699 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6700 return getCanonicalDecl(VD); 6701 } 6702 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6703 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6704 return getCanonicalDecl(ME->getMemberDecl()); 6705 return nullptr; 6706 } 6707 6708 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6709 // Check test-expr for canonical form, save upper-bound UB, flags for 6710 // less/greater and for strict/non-strict comparison. 6711 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6712 // var relational-op b 6713 // b relational-op var 6714 // 6715 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6716 if (!S) { 6717 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6718 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6719 return true; 6720 } 6721 Condition = S; 6722 S = getExprAsWritten(S); 6723 SourceLocation CondLoc = S->getBeginLoc(); 6724 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6725 if (BO->isRelationalOp()) { 6726 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6727 return setUB(BO->getRHS(), 6728 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6729 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6730 BO->getSourceRange(), BO->getOperatorLoc()); 6731 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6732 return setUB(BO->getLHS(), 6733 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6734 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6735 BO->getSourceRange(), BO->getOperatorLoc()); 6736 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6737 return setUB( 6738 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6739 /*LessOp=*/llvm::None, 6740 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6741 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6742 if (CE->getNumArgs() == 2) { 6743 auto Op = CE->getOperator(); 6744 switch (Op) { 6745 case OO_Greater: 6746 case OO_GreaterEqual: 6747 case OO_Less: 6748 case OO_LessEqual: 6749 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6750 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6751 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6752 CE->getOperatorLoc()); 6753 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6754 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6755 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6756 CE->getOperatorLoc()); 6757 break; 6758 case OO_ExclaimEqual: 6759 if (IneqCondIsCanonical) 6760 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6761 : CE->getArg(0), 6762 /*LessOp=*/llvm::None, 6763 /*StrictOp=*/true, CE->getSourceRange(), 6764 CE->getOperatorLoc()); 6765 break; 6766 default: 6767 break; 6768 } 6769 } 6770 } 6771 if (dependent() || SemaRef.CurContext->isDependentContext()) 6772 return false; 6773 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6774 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6775 return true; 6776 } 6777 6778 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6779 // RHS of canonical loop form increment can be: 6780 // var + incr 6781 // incr + var 6782 // var - incr 6783 // 6784 RHS = RHS->IgnoreParenImpCasts(); 6785 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6786 if (BO->isAdditiveOp()) { 6787 bool IsAdd = BO->getOpcode() == BO_Add; 6788 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6789 return setStep(BO->getRHS(), !IsAdd); 6790 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6791 return setStep(BO->getLHS(), /*Subtract=*/false); 6792 } 6793 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6794 bool IsAdd = CE->getOperator() == OO_Plus; 6795 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6796 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6797 return setStep(CE->getArg(1), !IsAdd); 6798 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6799 return setStep(CE->getArg(0), /*Subtract=*/false); 6800 } 6801 } 6802 if (dependent() || SemaRef.CurContext->isDependentContext()) 6803 return false; 6804 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6805 << RHS->getSourceRange() << LCDecl; 6806 return true; 6807 } 6808 6809 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6810 // Check incr-expr for canonical loop form and return true if it 6811 // does not conform. 6812 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6813 // ++var 6814 // var++ 6815 // --var 6816 // var-- 6817 // var += incr 6818 // var -= incr 6819 // var = var + incr 6820 // var = incr + var 6821 // var = var - incr 6822 // 6823 if (!S) { 6824 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6825 return true; 6826 } 6827 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6828 if (!ExprTemp->cleanupsHaveSideEffects()) 6829 S = ExprTemp->getSubExpr(); 6830 6831 IncrementSrcRange = S->getSourceRange(); 6832 S = S->IgnoreParens(); 6833 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6834 if (UO->isIncrementDecrementOp() && 6835 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6836 return setStep(SemaRef 6837 .ActOnIntegerConstant(UO->getBeginLoc(), 6838 (UO->isDecrementOp() ? -1 : 1)) 6839 .get(), 6840 /*Subtract=*/false); 6841 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6842 switch (BO->getOpcode()) { 6843 case BO_AddAssign: 6844 case BO_SubAssign: 6845 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6846 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6847 break; 6848 case BO_Assign: 6849 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6850 return checkAndSetIncRHS(BO->getRHS()); 6851 break; 6852 default: 6853 break; 6854 } 6855 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6856 switch (CE->getOperator()) { 6857 case OO_PlusPlus: 6858 case OO_MinusMinus: 6859 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6860 return setStep(SemaRef 6861 .ActOnIntegerConstant( 6862 CE->getBeginLoc(), 6863 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6864 .get(), 6865 /*Subtract=*/false); 6866 break; 6867 case OO_PlusEqual: 6868 case OO_MinusEqual: 6869 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6870 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6871 break; 6872 case OO_Equal: 6873 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6874 return checkAndSetIncRHS(CE->getArg(1)); 6875 break; 6876 default: 6877 break; 6878 } 6879 } 6880 if (dependent() || SemaRef.CurContext->isDependentContext()) 6881 return false; 6882 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6883 << S->getSourceRange() << LCDecl; 6884 return true; 6885 } 6886 6887 static ExprResult 6888 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6889 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6890 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) 6891 return Capture; 6892 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6893 return SemaRef.PerformImplicitConversion( 6894 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6895 /*AllowExplicit=*/true); 6896 auto I = Captures.find(Capture); 6897 if (I != Captures.end()) 6898 return buildCapture(SemaRef, Capture, I->second); 6899 DeclRefExpr *Ref = nullptr; 6900 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6901 Captures[Capture] = Ref; 6902 return Res; 6903 } 6904 6905 /// Build the expression to calculate the number of iterations. 6906 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6907 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6908 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6909 ExprResult Diff; 6910 QualType VarType = LCDecl->getType().getNonReferenceType(); 6911 if (VarType->isIntegerType() || VarType->isPointerType() || 6912 SemaRef.getLangOpts().CPlusPlus) { 6913 Expr *LBVal = LB; 6914 Expr *UBVal = UB; 6915 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6916 // max(LB(MinVal), LB(MaxVal)) 6917 if (InitDependOnLC) { 6918 const LoopIterationSpace &IS = 6919 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6920 InitDependOnLC.getValueOr( 6921 CondDependOnLC.getValueOr(0))]; 6922 if (!IS.MinValue || !IS.MaxValue) 6923 return nullptr; 6924 // OuterVar = Min 6925 ExprResult MinValue = 6926 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6927 if (!MinValue.isUsable()) 6928 return nullptr; 6929 6930 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6931 IS.CounterVar, MinValue.get()); 6932 if (!LBMinVal.isUsable()) 6933 return nullptr; 6934 // OuterVar = Min, LBVal 6935 LBMinVal = 6936 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6937 if (!LBMinVal.isUsable()) 6938 return nullptr; 6939 // (OuterVar = Min, LBVal) 6940 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6941 if (!LBMinVal.isUsable()) 6942 return nullptr; 6943 6944 // OuterVar = Max 6945 ExprResult MaxValue = 6946 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6947 if (!MaxValue.isUsable()) 6948 return nullptr; 6949 6950 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6951 IS.CounterVar, MaxValue.get()); 6952 if (!LBMaxVal.isUsable()) 6953 return nullptr; 6954 // OuterVar = Max, LBVal 6955 LBMaxVal = 6956 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6957 if (!LBMaxVal.isUsable()) 6958 return nullptr; 6959 // (OuterVar = Max, LBVal) 6960 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6961 if (!LBMaxVal.isUsable()) 6962 return nullptr; 6963 6964 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6965 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6966 if (!LBMin || !LBMax) 6967 return nullptr; 6968 // LB(MinVal) < LB(MaxVal) 6969 ExprResult MinLessMaxRes = 6970 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6971 if (!MinLessMaxRes.isUsable()) 6972 return nullptr; 6973 Expr *MinLessMax = 6974 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6975 if (!MinLessMax) 6976 return nullptr; 6977 if (TestIsLessOp.getValue()) { 6978 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6979 // LB(MaxVal)) 6980 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6981 MinLessMax, LBMin, LBMax); 6982 if (!MinLB.isUsable()) 6983 return nullptr; 6984 LBVal = MinLB.get(); 6985 } else { 6986 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6987 // LB(MaxVal)) 6988 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6989 MinLessMax, LBMax, LBMin); 6990 if (!MaxLB.isUsable()) 6991 return nullptr; 6992 LBVal = MaxLB.get(); 6993 } 6994 } 6995 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6996 // min(UB(MinVal), UB(MaxVal)) 6997 if (CondDependOnLC) { 6998 const LoopIterationSpace &IS = 6999 ResultIterSpaces[ResultIterSpaces.size() - 1 - 7000 InitDependOnLC.getValueOr( 7001 CondDependOnLC.getValueOr(0))]; 7002 if (!IS.MinValue || !IS.MaxValue) 7003 return nullptr; 7004 // OuterVar = Min 7005 ExprResult MinValue = 7006 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 7007 if (!MinValue.isUsable()) 7008 return nullptr; 7009 7010 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7011 IS.CounterVar, MinValue.get()); 7012 if (!UBMinVal.isUsable()) 7013 return nullptr; 7014 // OuterVar = Min, UBVal 7015 UBMinVal = 7016 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 7017 if (!UBMinVal.isUsable()) 7018 return nullptr; 7019 // (OuterVar = Min, UBVal) 7020 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 7021 if (!UBMinVal.isUsable()) 7022 return nullptr; 7023 7024 // OuterVar = Max 7025 ExprResult MaxValue = 7026 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 7027 if (!MaxValue.isUsable()) 7028 return nullptr; 7029 7030 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 7031 IS.CounterVar, MaxValue.get()); 7032 if (!UBMaxVal.isUsable()) 7033 return nullptr; 7034 // OuterVar = Max, UBVal 7035 UBMaxVal = 7036 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 7037 if (!UBMaxVal.isUsable()) 7038 return nullptr; 7039 // (OuterVar = Max, UBVal) 7040 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 7041 if (!UBMaxVal.isUsable()) 7042 return nullptr; 7043 7044 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 7045 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 7046 if (!UBMin || !UBMax) 7047 return nullptr; 7048 // UB(MinVal) > UB(MaxVal) 7049 ExprResult MinGreaterMaxRes = 7050 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 7051 if (!MinGreaterMaxRes.isUsable()) 7052 return nullptr; 7053 Expr *MinGreaterMax = 7054 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 7055 if (!MinGreaterMax) 7056 return nullptr; 7057 if (TestIsLessOp.getValue()) { 7058 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 7059 // UB(MaxVal)) 7060 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 7061 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 7062 if (!MaxUB.isUsable()) 7063 return nullptr; 7064 UBVal = MaxUB.get(); 7065 } else { 7066 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 7067 // UB(MaxVal)) 7068 ExprResult MinUB = SemaRef.ActOnConditionalOp( 7069 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 7070 if (!MinUB.isUsable()) 7071 return nullptr; 7072 UBVal = MinUB.get(); 7073 } 7074 } 7075 // Upper - Lower 7076 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 7077 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 7078 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7079 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7080 if (!Upper || !Lower) 7081 return nullptr; 7082 7083 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7084 7085 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 7086 // BuildBinOp already emitted error, this one is to point user to upper 7087 // and lower bound, and to tell what is passed to 'operator-'. 7088 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7089 << Upper->getSourceRange() << Lower->getSourceRange(); 7090 return nullptr; 7091 } 7092 } 7093 7094 if (!Diff.isUsable()) 7095 return nullptr; 7096 7097 // Upper - Lower [- 1] 7098 if (TestIsStrictOp) 7099 Diff = SemaRef.BuildBinOp( 7100 S, DefaultLoc, BO_Sub, Diff.get(), 7101 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7102 if (!Diff.isUsable()) 7103 return nullptr; 7104 7105 // Upper - Lower [- 1] + Step 7106 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7107 if (!NewStep.isUsable()) 7108 return nullptr; 7109 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 7110 if (!Diff.isUsable()) 7111 return nullptr; 7112 7113 // Parentheses (for dumping/debugging purposes only). 7114 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7115 if (!Diff.isUsable()) 7116 return nullptr; 7117 7118 // (Upper - Lower [- 1] + Step) / Step 7119 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7120 if (!Diff.isUsable()) 7121 return nullptr; 7122 7123 // OpenMP runtime requires 32-bit or 64-bit loop variables. 7124 QualType Type = Diff.get()->getType(); 7125 ASTContext &C = SemaRef.Context; 7126 bool UseVarType = VarType->hasIntegerRepresentation() && 7127 C.getTypeSize(Type) > C.getTypeSize(VarType); 7128 if (!Type->isIntegerType() || UseVarType) { 7129 unsigned NewSize = 7130 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 7131 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 7132 : Type->hasSignedIntegerRepresentation(); 7133 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 7134 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 7135 Diff = SemaRef.PerformImplicitConversion( 7136 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 7137 if (!Diff.isUsable()) 7138 return nullptr; 7139 } 7140 } 7141 if (LimitedType) { 7142 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 7143 if (NewSize != C.getTypeSize(Type)) { 7144 if (NewSize < C.getTypeSize(Type)) { 7145 assert(NewSize == 64 && "incorrect loop var size"); 7146 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 7147 << InitSrcRange << ConditionSrcRange; 7148 } 7149 QualType NewType = C.getIntTypeForBitwidth( 7150 NewSize, Type->hasSignedIntegerRepresentation() || 7151 C.getTypeSize(Type) < NewSize); 7152 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 7153 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 7154 Sema::AA_Converting, true); 7155 if (!Diff.isUsable()) 7156 return nullptr; 7157 } 7158 } 7159 } 7160 7161 return Diff.get(); 7162 } 7163 7164 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 7165 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7166 // Do not build for iterators, they cannot be used in non-rectangular loop 7167 // nests. 7168 if (LCDecl->getType()->isRecordType()) 7169 return std::make_pair(nullptr, nullptr); 7170 // If we subtract, the min is in the condition, otherwise the min is in the 7171 // init value. 7172 Expr *MinExpr = nullptr; 7173 Expr *MaxExpr = nullptr; 7174 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 7175 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 7176 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 7177 : CondDependOnLC.hasValue(); 7178 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 7179 : InitDependOnLC.hasValue(); 7180 Expr *Lower = 7181 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7182 Expr *Upper = 7183 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7184 if (!Upper || !Lower) 7185 return std::make_pair(nullptr, nullptr); 7186 7187 if (TestIsLessOp.getValue()) 7188 MinExpr = Lower; 7189 else 7190 MaxExpr = Upper; 7191 7192 // Build minimum/maximum value based on number of iterations. 7193 ExprResult Diff; 7194 QualType VarType = LCDecl->getType().getNonReferenceType(); 7195 7196 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7197 if (!Diff.isUsable()) 7198 return std::make_pair(nullptr, nullptr); 7199 7200 // Upper - Lower [- 1] 7201 if (TestIsStrictOp) 7202 Diff = SemaRef.BuildBinOp( 7203 S, DefaultLoc, BO_Sub, Diff.get(), 7204 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7205 if (!Diff.isUsable()) 7206 return std::make_pair(nullptr, nullptr); 7207 7208 // Upper - Lower [- 1] + Step 7209 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7210 if (!NewStep.isUsable()) 7211 return std::make_pair(nullptr, nullptr); 7212 7213 // Parentheses (for dumping/debugging purposes only). 7214 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7215 if (!Diff.isUsable()) 7216 return std::make_pair(nullptr, nullptr); 7217 7218 // (Upper - Lower [- 1]) / Step 7219 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7220 if (!Diff.isUsable()) 7221 return std::make_pair(nullptr, nullptr); 7222 7223 // ((Upper - Lower [- 1]) / Step) * Step 7224 // Parentheses (for dumping/debugging purposes only). 7225 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7226 if (!Diff.isUsable()) 7227 return std::make_pair(nullptr, nullptr); 7228 7229 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 7230 if (!Diff.isUsable()) 7231 return std::make_pair(nullptr, nullptr); 7232 7233 // Convert to the original type or ptrdiff_t, if original type is pointer. 7234 if (!VarType->isAnyPointerType() && 7235 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 7236 Diff = SemaRef.PerformImplicitConversion( 7237 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 7238 } else if (VarType->isAnyPointerType() && 7239 !SemaRef.Context.hasSameType( 7240 Diff.get()->getType(), 7241 SemaRef.Context.getUnsignedPointerDiffType())) { 7242 Diff = SemaRef.PerformImplicitConversion( 7243 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 7244 Sema::AA_Converting, /*AllowExplicit=*/true); 7245 } 7246 if (!Diff.isUsable()) 7247 return std::make_pair(nullptr, nullptr); 7248 7249 // Parentheses (for dumping/debugging purposes only). 7250 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7251 if (!Diff.isUsable()) 7252 return std::make_pair(nullptr, nullptr); 7253 7254 if (TestIsLessOp.getValue()) { 7255 // MinExpr = Lower; 7256 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 7257 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 7258 if (!Diff.isUsable()) 7259 return std::make_pair(nullptr, nullptr); 7260 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7261 if (!Diff.isUsable()) 7262 return std::make_pair(nullptr, nullptr); 7263 MaxExpr = Diff.get(); 7264 } else { 7265 // MaxExpr = Upper; 7266 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 7267 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 7268 if (!Diff.isUsable()) 7269 return std::make_pair(nullptr, nullptr); 7270 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7271 if (!Diff.isUsable()) 7272 return std::make_pair(nullptr, nullptr); 7273 MinExpr = Diff.get(); 7274 } 7275 7276 return std::make_pair(MinExpr, MaxExpr); 7277 } 7278 7279 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 7280 if (InitDependOnLC || CondDependOnLC) 7281 return Condition; 7282 return nullptr; 7283 } 7284 7285 Expr *OpenMPIterationSpaceChecker::buildPreCond( 7286 Scope *S, Expr *Cond, 7287 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7288 // Do not build a precondition when the condition/initialization is dependent 7289 // to prevent pessimistic early loop exit. 7290 // TODO: this can be improved by calculating min/max values but not sure that 7291 // it will be very effective. 7292 if (CondDependOnLC || InitDependOnLC) 7293 return SemaRef.PerformImplicitConversion( 7294 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 7295 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7296 /*AllowExplicit=*/true).get(); 7297 7298 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 7299 Sema::TentativeAnalysisScope Trap(SemaRef); 7300 7301 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 7302 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 7303 if (!NewLB.isUsable() || !NewUB.isUsable()) 7304 return nullptr; 7305 7306 ExprResult CondExpr = 7307 SemaRef.BuildBinOp(S, DefaultLoc, 7308 TestIsLessOp.getValue() ? 7309 (TestIsStrictOp ? BO_LT : BO_LE) : 7310 (TestIsStrictOp ? BO_GT : BO_GE), 7311 NewLB.get(), NewUB.get()); 7312 if (CondExpr.isUsable()) { 7313 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 7314 SemaRef.Context.BoolTy)) 7315 CondExpr = SemaRef.PerformImplicitConversion( 7316 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7317 /*AllowExplicit=*/true); 7318 } 7319 7320 // Otherwise use original loop condition and evaluate it in runtime. 7321 return CondExpr.isUsable() ? CondExpr.get() : Cond; 7322 } 7323 7324 /// Build reference expression to the counter be used for codegen. 7325 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 7326 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7327 DSAStackTy &DSA) const { 7328 auto *VD = dyn_cast<VarDecl>(LCDecl); 7329 if (!VD) { 7330 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 7331 DeclRefExpr *Ref = buildDeclRefExpr( 7332 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 7333 const DSAStackTy::DSAVarData Data = 7334 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 7335 // If the loop control decl is explicitly marked as private, do not mark it 7336 // as captured again. 7337 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 7338 Captures.insert(std::make_pair(LCRef, Ref)); 7339 return Ref; 7340 } 7341 return cast<DeclRefExpr>(LCRef); 7342 } 7343 7344 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 7345 if (LCDecl && !LCDecl->isInvalidDecl()) { 7346 QualType Type = LCDecl->getType().getNonReferenceType(); 7347 VarDecl *PrivateVar = buildVarDecl( 7348 SemaRef, DefaultLoc, Type, LCDecl->getName(), 7349 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 7350 isa<VarDecl>(LCDecl) 7351 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 7352 : nullptr); 7353 if (PrivateVar->isInvalidDecl()) 7354 return nullptr; 7355 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 7356 } 7357 return nullptr; 7358 } 7359 7360 /// Build initialization of the counter to be used for codegen. 7361 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 7362 7363 /// Build step of the counter be used for codegen. 7364 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 7365 7366 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 7367 Scope *S, Expr *Counter, 7368 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 7369 Expr *Inc, OverloadedOperatorKind OOK) { 7370 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 7371 if (!Cnt) 7372 return nullptr; 7373 if (Inc) { 7374 assert((OOK == OO_Plus || OOK == OO_Minus) && 7375 "Expected only + or - operations for depend clauses."); 7376 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 7377 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 7378 if (!Cnt) 7379 return nullptr; 7380 } 7381 ExprResult Diff; 7382 QualType VarType = LCDecl->getType().getNonReferenceType(); 7383 if (VarType->isIntegerType() || VarType->isPointerType() || 7384 SemaRef.getLangOpts().CPlusPlus) { 7385 // Upper - Lower 7386 Expr *Upper = TestIsLessOp.getValue() 7387 ? Cnt 7388 : tryBuildCapture(SemaRef, LB, Captures).get(); 7389 Expr *Lower = TestIsLessOp.getValue() 7390 ? tryBuildCapture(SemaRef, LB, Captures).get() 7391 : Cnt; 7392 if (!Upper || !Lower) 7393 return nullptr; 7394 7395 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7396 7397 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 7398 // BuildBinOp already emitted error, this one is to point user to upper 7399 // and lower bound, and to tell what is passed to 'operator-'. 7400 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7401 << Upper->getSourceRange() << Lower->getSourceRange(); 7402 return nullptr; 7403 } 7404 } 7405 7406 if (!Diff.isUsable()) 7407 return nullptr; 7408 7409 // Parentheses (for dumping/debugging purposes only). 7410 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7411 if (!Diff.isUsable()) 7412 return nullptr; 7413 7414 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7415 if (!NewStep.isUsable()) 7416 return nullptr; 7417 // (Upper - Lower) / Step 7418 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7419 if (!Diff.isUsable()) 7420 return nullptr; 7421 7422 return Diff.get(); 7423 } 7424 } // namespace 7425 7426 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 7427 assert(getLangOpts().OpenMP && "OpenMP is not active."); 7428 assert(Init && "Expected loop in canonical form."); 7429 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 7430 if (AssociatedLoops > 0 && 7431 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 7432 DSAStack->loopStart(); 7433 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 7434 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 7435 if (ValueDecl *D = ISC.getLoopDecl()) { 7436 auto *VD = dyn_cast<VarDecl>(D); 7437 DeclRefExpr *PrivateRef = nullptr; 7438 if (!VD) { 7439 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 7440 VD = Private; 7441 } else { 7442 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 7443 /*WithInit=*/false); 7444 VD = cast<VarDecl>(PrivateRef->getDecl()); 7445 } 7446 } 7447 DSAStack->addLoopControlVariable(D, VD); 7448 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 7449 if (LD != D->getCanonicalDecl()) { 7450 DSAStack->resetPossibleLoopCounter(); 7451 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 7452 MarkDeclarationsReferencedInExpr( 7453 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 7454 Var->getType().getNonLValueExprType(Context), 7455 ForLoc, /*RefersToCapture=*/true)); 7456 } 7457 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7458 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 7459 // Referenced in a Construct, C/C++]. The loop iteration variable in the 7460 // associated for-loop of a simd construct with just one associated 7461 // for-loop may be listed in a linear clause with a constant-linear-step 7462 // that is the increment of the associated for-loop. The loop iteration 7463 // variable(s) in the associated for-loop(s) of a for or parallel for 7464 // construct may be listed in a private or lastprivate clause. 7465 DSAStackTy::DSAVarData DVar = 7466 DSAStack->getTopDSA(D, /*FromParent=*/false); 7467 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 7468 // is declared in the loop and it is predetermined as a private. 7469 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 7470 OpenMPClauseKind PredeterminedCKind = 7471 isOpenMPSimdDirective(DKind) 7472 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 7473 : OMPC_private; 7474 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7475 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 7476 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 7477 DVar.CKind != OMPC_private))) || 7478 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 7479 DKind == OMPD_master_taskloop || 7480 DKind == OMPD_parallel_master_taskloop || 7481 isOpenMPDistributeDirective(DKind)) && 7482 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7483 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 7484 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 7485 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 7486 << getOpenMPClauseName(DVar.CKind) 7487 << getOpenMPDirectiveName(DKind) 7488 << getOpenMPClauseName(PredeterminedCKind); 7489 if (DVar.RefExpr == nullptr) 7490 DVar.CKind = PredeterminedCKind; 7491 reportOriginalDsa(*this, DSAStack, D, DVar, 7492 /*IsLoopIterVar=*/true); 7493 } else if (LoopDeclRefExpr) { 7494 // Make the loop iteration variable private (for worksharing 7495 // constructs), linear (for simd directives with the only one 7496 // associated loop) or lastprivate (for simd directives with several 7497 // collapsed or ordered loops). 7498 if (DVar.CKind == OMPC_unknown) 7499 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 7500 PrivateRef); 7501 } 7502 } 7503 } 7504 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 7505 } 7506 } 7507 7508 /// Called on a for stmt to check and extract its iteration space 7509 /// for further processing (such as collapsing). 7510 static bool checkOpenMPIterationSpace( 7511 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 7512 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 7513 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7514 Expr *OrderedLoopCountExpr, 7515 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7516 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7517 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7518 // OpenMP [2.9.1, Canonical Loop Form] 7519 // for (init-expr; test-expr; incr-expr) structured-block 7520 // for (range-decl: range-expr) structured-block 7521 auto *For = dyn_cast_or_null<ForStmt>(S); 7522 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7523 // Ranged for is supported only in OpenMP 5.0. 7524 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7525 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7526 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7527 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7528 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7529 if (TotalNestedLoopCount > 1) { 7530 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7531 SemaRef.Diag(DSA.getConstructLoc(), 7532 diag::note_omp_collapse_ordered_expr) 7533 << 2 << CollapseLoopCountExpr->getSourceRange() 7534 << OrderedLoopCountExpr->getSourceRange(); 7535 else if (CollapseLoopCountExpr) 7536 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7537 diag::note_omp_collapse_ordered_expr) 7538 << 0 << CollapseLoopCountExpr->getSourceRange(); 7539 else 7540 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7541 diag::note_omp_collapse_ordered_expr) 7542 << 1 << OrderedLoopCountExpr->getSourceRange(); 7543 } 7544 return true; 7545 } 7546 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7547 "No loop body."); 7548 7549 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7550 For ? For->getForLoc() : CXXFor->getForLoc()); 7551 7552 // Check init. 7553 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7554 if (ISC.checkAndSetInit(Init)) 7555 return true; 7556 7557 bool HasErrors = false; 7558 7559 // Check loop variable's type. 7560 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7561 // OpenMP [2.6, Canonical Loop Form] 7562 // Var is one of the following: 7563 // A variable of signed or unsigned integer type. 7564 // For C++, a variable of a random access iterator type. 7565 // For C, a variable of a pointer type. 7566 QualType VarType = LCDecl->getType().getNonReferenceType(); 7567 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7568 !VarType->isPointerType() && 7569 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7570 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7571 << SemaRef.getLangOpts().CPlusPlus; 7572 HasErrors = true; 7573 } 7574 7575 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7576 // a Construct 7577 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7578 // parallel for construct is (are) private. 7579 // The loop iteration variable in the associated for-loop of a simd 7580 // construct with just one associated for-loop is linear with a 7581 // constant-linear-step that is the increment of the associated for-loop. 7582 // Exclude loop var from the list of variables with implicitly defined data 7583 // sharing attributes. 7584 VarsWithImplicitDSA.erase(LCDecl); 7585 7586 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7587 7588 // Check test-expr. 7589 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7590 7591 // Check incr-expr. 7592 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7593 } 7594 7595 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7596 return HasErrors; 7597 7598 // Build the loop's iteration space representation. 7599 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7600 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7601 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7602 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7603 (isOpenMPWorksharingDirective(DKind) || 7604 isOpenMPTaskLoopDirective(DKind) || 7605 isOpenMPDistributeDirective(DKind)), 7606 Captures); 7607 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7608 ISC.buildCounterVar(Captures, DSA); 7609 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7610 ISC.buildPrivateCounterVar(); 7611 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7612 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7613 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7614 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7615 ISC.getConditionSrcRange(); 7616 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7617 ISC.getIncrementSrcRange(); 7618 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7619 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7620 ISC.isStrictTestOp(); 7621 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7622 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7623 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7624 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7625 ISC.buildFinalCondition(DSA.getCurScope()); 7626 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7627 ISC.doesInitDependOnLC(); 7628 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7629 ISC.doesCondDependOnLC(); 7630 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7631 ISC.getLoopDependentIdx(); 7632 7633 HasErrors |= 7634 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7635 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7636 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7637 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7638 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7639 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7640 if (!HasErrors && DSA.isOrderedRegion()) { 7641 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7642 if (CurrentNestedLoopCount < 7643 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7644 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7645 CurrentNestedLoopCount, 7646 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7647 DSA.getOrderedRegionParam().second->setLoopCounter( 7648 CurrentNestedLoopCount, 7649 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7650 } 7651 } 7652 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7653 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7654 // Erroneous case - clause has some problems. 7655 continue; 7656 } 7657 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7658 Pair.second.size() <= CurrentNestedLoopCount) { 7659 // Erroneous case - clause has some problems. 7660 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7661 continue; 7662 } 7663 Expr *CntValue; 7664 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7665 CntValue = ISC.buildOrderedLoopData( 7666 DSA.getCurScope(), 7667 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7668 Pair.first->getDependencyLoc()); 7669 else 7670 CntValue = ISC.buildOrderedLoopData( 7671 DSA.getCurScope(), 7672 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7673 Pair.first->getDependencyLoc(), 7674 Pair.second[CurrentNestedLoopCount].first, 7675 Pair.second[CurrentNestedLoopCount].second); 7676 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7677 } 7678 } 7679 7680 return HasErrors; 7681 } 7682 7683 /// Build 'VarRef = Start. 7684 static ExprResult 7685 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7686 ExprResult Start, bool IsNonRectangularLB, 7687 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7688 // Build 'VarRef = Start. 7689 ExprResult NewStart = IsNonRectangularLB 7690 ? Start.get() 7691 : tryBuildCapture(SemaRef, Start.get(), Captures); 7692 if (!NewStart.isUsable()) 7693 return ExprError(); 7694 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7695 VarRef.get()->getType())) { 7696 NewStart = SemaRef.PerformImplicitConversion( 7697 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7698 /*AllowExplicit=*/true); 7699 if (!NewStart.isUsable()) 7700 return ExprError(); 7701 } 7702 7703 ExprResult Init = 7704 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7705 return Init; 7706 } 7707 7708 /// Build 'VarRef = Start + Iter * Step'. 7709 static ExprResult buildCounterUpdate( 7710 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7711 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7712 bool IsNonRectangularLB, 7713 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7714 // Add parentheses (for debugging purposes only). 7715 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7716 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7717 !Step.isUsable()) 7718 return ExprError(); 7719 7720 ExprResult NewStep = Step; 7721 if (Captures) 7722 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7723 if (NewStep.isInvalid()) 7724 return ExprError(); 7725 ExprResult Update = 7726 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7727 if (!Update.isUsable()) 7728 return ExprError(); 7729 7730 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7731 // 'VarRef = Start (+|-) Iter * Step'. 7732 if (!Start.isUsable()) 7733 return ExprError(); 7734 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7735 if (!NewStart.isUsable()) 7736 return ExprError(); 7737 if (Captures && !IsNonRectangularLB) 7738 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7739 if (NewStart.isInvalid()) 7740 return ExprError(); 7741 7742 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7743 ExprResult SavedUpdate = Update; 7744 ExprResult UpdateVal; 7745 if (VarRef.get()->getType()->isOverloadableType() || 7746 NewStart.get()->getType()->isOverloadableType() || 7747 Update.get()->getType()->isOverloadableType()) { 7748 Sema::TentativeAnalysisScope Trap(SemaRef); 7749 7750 Update = 7751 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7752 if (Update.isUsable()) { 7753 UpdateVal = 7754 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7755 VarRef.get(), SavedUpdate.get()); 7756 if (UpdateVal.isUsable()) { 7757 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7758 UpdateVal.get()); 7759 } 7760 } 7761 } 7762 7763 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7764 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7765 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7766 NewStart.get(), SavedUpdate.get()); 7767 if (!Update.isUsable()) 7768 return ExprError(); 7769 7770 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7771 VarRef.get()->getType())) { 7772 Update = SemaRef.PerformImplicitConversion( 7773 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7774 if (!Update.isUsable()) 7775 return ExprError(); 7776 } 7777 7778 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7779 } 7780 return Update; 7781 } 7782 7783 /// Convert integer expression \a E to make it have at least \a Bits 7784 /// bits. 7785 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7786 if (E == nullptr) 7787 return ExprError(); 7788 ASTContext &C = SemaRef.Context; 7789 QualType OldType = E->getType(); 7790 unsigned HasBits = C.getTypeSize(OldType); 7791 if (HasBits >= Bits) 7792 return ExprResult(E); 7793 // OK to convert to signed, because new type has more bits than old. 7794 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7795 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7796 true); 7797 } 7798 7799 /// Check if the given expression \a E is a constant integer that fits 7800 /// into \a Bits bits. 7801 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7802 if (E == nullptr) 7803 return false; 7804 llvm::APSInt Result; 7805 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7806 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7807 return false; 7808 } 7809 7810 /// Build preinits statement for the given declarations. 7811 static Stmt *buildPreInits(ASTContext &Context, 7812 MutableArrayRef<Decl *> PreInits) { 7813 if (!PreInits.empty()) { 7814 return new (Context) DeclStmt( 7815 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7816 SourceLocation(), SourceLocation()); 7817 } 7818 return nullptr; 7819 } 7820 7821 /// Build preinits statement for the given declarations. 7822 static Stmt * 7823 buildPreInits(ASTContext &Context, 7824 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7825 if (!Captures.empty()) { 7826 SmallVector<Decl *, 16> PreInits; 7827 for (const auto &Pair : Captures) 7828 PreInits.push_back(Pair.second->getDecl()); 7829 return buildPreInits(Context, PreInits); 7830 } 7831 return nullptr; 7832 } 7833 7834 /// Build postupdate expression for the given list of postupdates expressions. 7835 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7836 Expr *PostUpdate = nullptr; 7837 if (!PostUpdates.empty()) { 7838 for (Expr *E : PostUpdates) { 7839 Expr *ConvE = S.BuildCStyleCastExpr( 7840 E->getExprLoc(), 7841 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7842 E->getExprLoc(), E) 7843 .get(); 7844 PostUpdate = PostUpdate 7845 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7846 PostUpdate, ConvE) 7847 .get() 7848 : ConvE; 7849 } 7850 } 7851 return PostUpdate; 7852 } 7853 7854 /// Called on a for stmt to check itself and nested loops (if any). 7855 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7856 /// number of collapsed loops otherwise. 7857 static unsigned 7858 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7859 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7860 DSAStackTy &DSA, 7861 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7862 OMPLoopDirective::HelperExprs &Built) { 7863 unsigned NestedLoopCount = 1; 7864 if (CollapseLoopCountExpr) { 7865 // Found 'collapse' clause - calculate collapse number. 7866 Expr::EvalResult Result; 7867 if (!CollapseLoopCountExpr->isValueDependent() && 7868 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7869 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7870 } else { 7871 Built.clear(/*Size=*/1); 7872 return 1; 7873 } 7874 } 7875 unsigned OrderedLoopCount = 1; 7876 if (OrderedLoopCountExpr) { 7877 // Found 'ordered' clause - calculate collapse number. 7878 Expr::EvalResult EVResult; 7879 if (!OrderedLoopCountExpr->isValueDependent() && 7880 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7881 SemaRef.getASTContext())) { 7882 llvm::APSInt Result = EVResult.Val.getInt(); 7883 if (Result.getLimitedValue() < NestedLoopCount) { 7884 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7885 diag::err_omp_wrong_ordered_loop_count) 7886 << OrderedLoopCountExpr->getSourceRange(); 7887 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7888 diag::note_collapse_loop_count) 7889 << CollapseLoopCountExpr->getSourceRange(); 7890 } 7891 OrderedLoopCount = Result.getLimitedValue(); 7892 } else { 7893 Built.clear(/*Size=*/1); 7894 return 1; 7895 } 7896 } 7897 // This is helper routine for loop directives (e.g., 'for', 'simd', 7898 // 'for simd', etc.). 7899 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7900 SmallVector<LoopIterationSpace, 4> IterSpaces( 7901 std::max(OrderedLoopCount, NestedLoopCount)); 7902 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7903 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7904 if (checkOpenMPIterationSpace( 7905 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7906 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7907 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7908 return 0; 7909 // Move on to the next nested for loop, or to the loop body. 7910 // OpenMP [2.8.1, simd construct, Restrictions] 7911 // All loops associated with the construct must be perfectly nested; that 7912 // is, there must be no intervening code nor any OpenMP directive between 7913 // any two loops. 7914 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7915 CurStmt = For->getBody(); 7916 } else { 7917 assert(isa<CXXForRangeStmt>(CurStmt) && 7918 "Expected canonical for or range-based for loops."); 7919 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7920 } 7921 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7922 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7923 } 7924 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7925 if (checkOpenMPIterationSpace( 7926 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7927 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7928 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7929 return 0; 7930 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7931 // Handle initialization of captured loop iterator variables. 7932 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7933 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7934 Captures[DRE] = DRE; 7935 } 7936 } 7937 // Move on to the next nested for loop, or to the loop body. 7938 // OpenMP [2.8.1, simd construct, Restrictions] 7939 // All loops associated with the construct must be perfectly nested; that 7940 // is, there must be no intervening code nor any OpenMP directive between 7941 // any two loops. 7942 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7943 CurStmt = For->getBody(); 7944 } else { 7945 assert(isa<CXXForRangeStmt>(CurStmt) && 7946 "Expected canonical for or range-based for loops."); 7947 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7948 } 7949 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7950 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7951 } 7952 7953 Built.clear(/* size */ NestedLoopCount); 7954 7955 if (SemaRef.CurContext->isDependentContext()) 7956 return NestedLoopCount; 7957 7958 // An example of what is generated for the following code: 7959 // 7960 // #pragma omp simd collapse(2) ordered(2) 7961 // for (i = 0; i < NI; ++i) 7962 // for (k = 0; k < NK; ++k) 7963 // for (j = J0; j < NJ; j+=2) { 7964 // <loop body> 7965 // } 7966 // 7967 // We generate the code below. 7968 // Note: the loop body may be outlined in CodeGen. 7969 // Note: some counters may be C++ classes, operator- is used to find number of 7970 // iterations and operator+= to calculate counter value. 7971 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7972 // or i64 is currently supported). 7973 // 7974 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7975 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7976 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7977 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7978 // // similar updates for vars in clauses (e.g. 'linear') 7979 // <loop body (using local i and j)> 7980 // } 7981 // i = NI; // assign final values of counters 7982 // j = NJ; 7983 // 7984 7985 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7986 // the iteration counts of the collapsed for loops. 7987 // Precondition tests if there is at least one iteration (all conditions are 7988 // true). 7989 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7990 Expr *N0 = IterSpaces[0].NumIterations; 7991 ExprResult LastIteration32 = 7992 widenIterationCount(/*Bits=*/32, 7993 SemaRef 7994 .PerformImplicitConversion( 7995 N0->IgnoreImpCasts(), N0->getType(), 7996 Sema::AA_Converting, /*AllowExplicit=*/true) 7997 .get(), 7998 SemaRef); 7999 ExprResult LastIteration64 = widenIterationCount( 8000 /*Bits=*/64, 8001 SemaRef 8002 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 8003 Sema::AA_Converting, 8004 /*AllowExplicit=*/true) 8005 .get(), 8006 SemaRef); 8007 8008 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 8009 return NestedLoopCount; 8010 8011 ASTContext &C = SemaRef.Context; 8012 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 8013 8014 Scope *CurScope = DSA.getCurScope(); 8015 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 8016 if (PreCond.isUsable()) { 8017 PreCond = 8018 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 8019 PreCond.get(), IterSpaces[Cnt].PreCond); 8020 } 8021 Expr *N = IterSpaces[Cnt].NumIterations; 8022 SourceLocation Loc = N->getExprLoc(); 8023 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 8024 if (LastIteration32.isUsable()) 8025 LastIteration32 = SemaRef.BuildBinOp( 8026 CurScope, Loc, BO_Mul, LastIteration32.get(), 8027 SemaRef 8028 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 8029 Sema::AA_Converting, 8030 /*AllowExplicit=*/true) 8031 .get()); 8032 if (LastIteration64.isUsable()) 8033 LastIteration64 = SemaRef.BuildBinOp( 8034 CurScope, Loc, BO_Mul, LastIteration64.get(), 8035 SemaRef 8036 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 8037 Sema::AA_Converting, 8038 /*AllowExplicit=*/true) 8039 .get()); 8040 } 8041 8042 // Choose either the 32-bit or 64-bit version. 8043 ExprResult LastIteration = LastIteration64; 8044 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 8045 (LastIteration32.isUsable() && 8046 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 8047 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 8048 fitsInto( 8049 /*Bits=*/32, 8050 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 8051 LastIteration64.get(), SemaRef)))) 8052 LastIteration = LastIteration32; 8053 QualType VType = LastIteration.get()->getType(); 8054 QualType RealVType = VType; 8055 QualType StrideVType = VType; 8056 if (isOpenMPTaskLoopDirective(DKind)) { 8057 VType = 8058 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 8059 StrideVType = 8060 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 8061 } 8062 8063 if (!LastIteration.isUsable()) 8064 return 0; 8065 8066 // Save the number of iterations. 8067 ExprResult NumIterations = LastIteration; 8068 { 8069 LastIteration = SemaRef.BuildBinOp( 8070 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 8071 LastIteration.get(), 8072 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8073 if (!LastIteration.isUsable()) 8074 return 0; 8075 } 8076 8077 // Calculate the last iteration number beforehand instead of doing this on 8078 // each iteration. Do not do this if the number of iterations may be kfold-ed. 8079 llvm::APSInt Result; 8080 bool IsConstant = 8081 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 8082 ExprResult CalcLastIteration; 8083 if (!IsConstant) { 8084 ExprResult SaveRef = 8085 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 8086 LastIteration = SaveRef; 8087 8088 // Prepare SaveRef + 1. 8089 NumIterations = SemaRef.BuildBinOp( 8090 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 8091 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8092 if (!NumIterations.isUsable()) 8093 return 0; 8094 } 8095 8096 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 8097 8098 // Build variables passed into runtime, necessary for worksharing directives. 8099 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 8100 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8101 isOpenMPDistributeDirective(DKind)) { 8102 // Lower bound variable, initialized with zero. 8103 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 8104 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 8105 SemaRef.AddInitializerToDecl(LBDecl, 8106 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8107 /*DirectInit*/ false); 8108 8109 // Upper bound variable, initialized with last iteration number. 8110 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 8111 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 8112 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 8113 /*DirectInit*/ false); 8114 8115 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 8116 // This will be used to implement clause 'lastprivate'. 8117 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 8118 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 8119 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 8120 SemaRef.AddInitializerToDecl(ILDecl, 8121 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8122 /*DirectInit*/ false); 8123 8124 // Stride variable returned by runtime (we initialize it to 1 by default). 8125 VarDecl *STDecl = 8126 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 8127 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 8128 SemaRef.AddInitializerToDecl(STDecl, 8129 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 8130 /*DirectInit*/ false); 8131 8132 // Build expression: UB = min(UB, LastIteration) 8133 // It is necessary for CodeGen of directives with static scheduling. 8134 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 8135 UB.get(), LastIteration.get()); 8136 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8137 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 8138 LastIteration.get(), UB.get()); 8139 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 8140 CondOp.get()); 8141 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 8142 8143 // If we have a combined directive that combines 'distribute', 'for' or 8144 // 'simd' we need to be able to access the bounds of the schedule of the 8145 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 8146 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 8147 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8148 // Lower bound variable, initialized with zero. 8149 VarDecl *CombLBDecl = 8150 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 8151 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 8152 SemaRef.AddInitializerToDecl( 8153 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8154 /*DirectInit*/ false); 8155 8156 // Upper bound variable, initialized with last iteration number. 8157 VarDecl *CombUBDecl = 8158 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 8159 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 8160 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 8161 /*DirectInit*/ false); 8162 8163 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 8164 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 8165 ExprResult CombCondOp = 8166 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 8167 LastIteration.get(), CombUB.get()); 8168 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 8169 CombCondOp.get()); 8170 CombEUB = 8171 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 8172 8173 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 8174 // We expect to have at least 2 more parameters than the 'parallel' 8175 // directive does - the lower and upper bounds of the previous schedule. 8176 assert(CD->getNumParams() >= 4 && 8177 "Unexpected number of parameters in loop combined directive"); 8178 8179 // Set the proper type for the bounds given what we learned from the 8180 // enclosed loops. 8181 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 8182 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 8183 8184 // Previous lower and upper bounds are obtained from the region 8185 // parameters. 8186 PrevLB = 8187 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 8188 PrevUB = 8189 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 8190 } 8191 } 8192 8193 // Build the iteration variable and its initialization before loop. 8194 ExprResult IV; 8195 ExprResult Init, CombInit; 8196 { 8197 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 8198 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 8199 Expr *RHS = 8200 (isOpenMPWorksharingDirective(DKind) || 8201 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8202 ? LB.get() 8203 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8204 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 8205 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 8206 8207 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8208 Expr *CombRHS = 8209 (isOpenMPWorksharingDirective(DKind) || 8210 isOpenMPTaskLoopDirective(DKind) || 8211 isOpenMPDistributeDirective(DKind)) 8212 ? CombLB.get() 8213 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8214 CombInit = 8215 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 8216 CombInit = 8217 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 8218 } 8219 } 8220 8221 bool UseStrictCompare = 8222 RealVType->hasUnsignedIntegerRepresentation() && 8223 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 8224 return LIS.IsStrictCompare; 8225 }); 8226 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 8227 // unsigned IV)) for worksharing loops. 8228 SourceLocation CondLoc = AStmt->getBeginLoc(); 8229 Expr *BoundUB = UB.get(); 8230 if (UseStrictCompare) { 8231 BoundUB = 8232 SemaRef 8233 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 8234 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8235 .get(); 8236 BoundUB = 8237 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 8238 } 8239 ExprResult Cond = 8240 (isOpenMPWorksharingDirective(DKind) || 8241 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8242 ? SemaRef.BuildBinOp(CurScope, CondLoc, 8243 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 8244 BoundUB) 8245 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8246 NumIterations.get()); 8247 ExprResult CombDistCond; 8248 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8249 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8250 NumIterations.get()); 8251 } 8252 8253 ExprResult CombCond; 8254 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8255 Expr *BoundCombUB = CombUB.get(); 8256 if (UseStrictCompare) { 8257 BoundCombUB = 8258 SemaRef 8259 .BuildBinOp( 8260 CurScope, CondLoc, BO_Add, BoundCombUB, 8261 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8262 .get(); 8263 BoundCombUB = 8264 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 8265 .get(); 8266 } 8267 CombCond = 8268 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8269 IV.get(), BoundCombUB); 8270 } 8271 // Loop increment (IV = IV + 1) 8272 SourceLocation IncLoc = AStmt->getBeginLoc(); 8273 ExprResult Inc = 8274 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 8275 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 8276 if (!Inc.isUsable()) 8277 return 0; 8278 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 8279 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 8280 if (!Inc.isUsable()) 8281 return 0; 8282 8283 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 8284 // Used for directives with static scheduling. 8285 // In combined construct, add combined version that use CombLB and CombUB 8286 // base variables for the update 8287 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 8288 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8289 isOpenMPDistributeDirective(DKind)) { 8290 // LB + ST 8291 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 8292 if (!NextLB.isUsable()) 8293 return 0; 8294 // LB = LB + ST 8295 NextLB = 8296 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 8297 NextLB = 8298 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 8299 if (!NextLB.isUsable()) 8300 return 0; 8301 // UB + ST 8302 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 8303 if (!NextUB.isUsable()) 8304 return 0; 8305 // UB = UB + ST 8306 NextUB = 8307 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 8308 NextUB = 8309 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 8310 if (!NextUB.isUsable()) 8311 return 0; 8312 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8313 CombNextLB = 8314 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 8315 if (!NextLB.isUsable()) 8316 return 0; 8317 // LB = LB + ST 8318 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 8319 CombNextLB.get()); 8320 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 8321 /*DiscardedValue*/ false); 8322 if (!CombNextLB.isUsable()) 8323 return 0; 8324 // UB + ST 8325 CombNextUB = 8326 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 8327 if (!CombNextUB.isUsable()) 8328 return 0; 8329 // UB = UB + ST 8330 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 8331 CombNextUB.get()); 8332 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 8333 /*DiscardedValue*/ false); 8334 if (!CombNextUB.isUsable()) 8335 return 0; 8336 } 8337 } 8338 8339 // Create increment expression for distribute loop when combined in a same 8340 // directive with for as IV = IV + ST; ensure upper bound expression based 8341 // on PrevUB instead of NumIterations - used to implement 'for' when found 8342 // in combination with 'distribute', like in 'distribute parallel for' 8343 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 8344 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 8345 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8346 DistCond = SemaRef.BuildBinOp( 8347 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 8348 assert(DistCond.isUsable() && "distribute cond expr was not built"); 8349 8350 DistInc = 8351 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 8352 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8353 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 8354 DistInc.get()); 8355 DistInc = 8356 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 8357 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8358 8359 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 8360 // construct 8361 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 8362 ExprResult IsUBGreater = 8363 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 8364 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8365 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 8366 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 8367 CondOp.get()); 8368 PrevEUB = 8369 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 8370 8371 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 8372 // parallel for is in combination with a distribute directive with 8373 // schedule(static, 1) 8374 Expr *BoundPrevUB = PrevUB.get(); 8375 if (UseStrictCompare) { 8376 BoundPrevUB = 8377 SemaRef 8378 .BuildBinOp( 8379 CurScope, CondLoc, BO_Add, BoundPrevUB, 8380 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8381 .get(); 8382 BoundPrevUB = 8383 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 8384 .get(); 8385 } 8386 ParForInDistCond = 8387 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8388 IV.get(), BoundPrevUB); 8389 } 8390 8391 // Build updates and final values of the loop counters. 8392 bool HasErrors = false; 8393 Built.Counters.resize(NestedLoopCount); 8394 Built.Inits.resize(NestedLoopCount); 8395 Built.Updates.resize(NestedLoopCount); 8396 Built.Finals.resize(NestedLoopCount); 8397 Built.DependentCounters.resize(NestedLoopCount); 8398 Built.DependentInits.resize(NestedLoopCount); 8399 Built.FinalsConditions.resize(NestedLoopCount); 8400 { 8401 // We implement the following algorithm for obtaining the 8402 // original loop iteration variable values based on the 8403 // value of the collapsed loop iteration variable IV. 8404 // 8405 // Let n+1 be the number of collapsed loops in the nest. 8406 // Iteration variables (I0, I1, .... In) 8407 // Iteration counts (N0, N1, ... Nn) 8408 // 8409 // Acc = IV; 8410 // 8411 // To compute Ik for loop k, 0 <= k <= n, generate: 8412 // Prod = N(k+1) * N(k+2) * ... * Nn; 8413 // Ik = Acc / Prod; 8414 // Acc -= Ik * Prod; 8415 // 8416 ExprResult Acc = IV; 8417 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8418 LoopIterationSpace &IS = IterSpaces[Cnt]; 8419 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 8420 ExprResult Iter; 8421 8422 // Compute prod 8423 ExprResult Prod = 8424 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 8425 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 8426 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 8427 IterSpaces[K].NumIterations); 8428 8429 // Iter = Acc / Prod 8430 // If there is at least one more inner loop to avoid 8431 // multiplication by 1. 8432 if (Cnt + 1 < NestedLoopCount) 8433 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 8434 Acc.get(), Prod.get()); 8435 else 8436 Iter = Acc; 8437 if (!Iter.isUsable()) { 8438 HasErrors = true; 8439 break; 8440 } 8441 8442 // Update Acc: 8443 // Acc -= Iter * Prod 8444 // Check if there is at least one more inner loop to avoid 8445 // multiplication by 1. 8446 if (Cnt + 1 < NestedLoopCount) 8447 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 8448 Iter.get(), Prod.get()); 8449 else 8450 Prod = Iter; 8451 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 8452 Acc.get(), Prod.get()); 8453 8454 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 8455 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 8456 DeclRefExpr *CounterVar = buildDeclRefExpr( 8457 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 8458 /*RefersToCapture=*/true); 8459 ExprResult Init = 8460 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 8461 IS.CounterInit, IS.IsNonRectangularLB, Captures); 8462 if (!Init.isUsable()) { 8463 HasErrors = true; 8464 break; 8465 } 8466 ExprResult Update = buildCounterUpdate( 8467 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 8468 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 8469 if (!Update.isUsable()) { 8470 HasErrors = true; 8471 break; 8472 } 8473 8474 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 8475 ExprResult Final = 8476 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 8477 IS.CounterInit, IS.NumIterations, IS.CounterStep, 8478 IS.Subtract, IS.IsNonRectangularLB, &Captures); 8479 if (!Final.isUsable()) { 8480 HasErrors = true; 8481 break; 8482 } 8483 8484 if (!Update.isUsable() || !Final.isUsable()) { 8485 HasErrors = true; 8486 break; 8487 } 8488 // Save results 8489 Built.Counters[Cnt] = IS.CounterVar; 8490 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 8491 Built.Inits[Cnt] = Init.get(); 8492 Built.Updates[Cnt] = Update.get(); 8493 Built.Finals[Cnt] = Final.get(); 8494 Built.DependentCounters[Cnt] = nullptr; 8495 Built.DependentInits[Cnt] = nullptr; 8496 Built.FinalsConditions[Cnt] = nullptr; 8497 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 8498 Built.DependentCounters[Cnt] = 8499 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8500 Built.DependentInits[Cnt] = 8501 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8502 Built.FinalsConditions[Cnt] = IS.FinalCondition; 8503 } 8504 } 8505 } 8506 8507 if (HasErrors) 8508 return 0; 8509 8510 // Save results 8511 Built.IterationVarRef = IV.get(); 8512 Built.LastIteration = LastIteration.get(); 8513 Built.NumIterations = NumIterations.get(); 8514 Built.CalcLastIteration = SemaRef 8515 .ActOnFinishFullExpr(CalcLastIteration.get(), 8516 /*DiscardedValue=*/false) 8517 .get(); 8518 Built.PreCond = PreCond.get(); 8519 Built.PreInits = buildPreInits(C, Captures); 8520 Built.Cond = Cond.get(); 8521 Built.Init = Init.get(); 8522 Built.Inc = Inc.get(); 8523 Built.LB = LB.get(); 8524 Built.UB = UB.get(); 8525 Built.IL = IL.get(); 8526 Built.ST = ST.get(); 8527 Built.EUB = EUB.get(); 8528 Built.NLB = NextLB.get(); 8529 Built.NUB = NextUB.get(); 8530 Built.PrevLB = PrevLB.get(); 8531 Built.PrevUB = PrevUB.get(); 8532 Built.DistInc = DistInc.get(); 8533 Built.PrevEUB = PrevEUB.get(); 8534 Built.DistCombinedFields.LB = CombLB.get(); 8535 Built.DistCombinedFields.UB = CombUB.get(); 8536 Built.DistCombinedFields.EUB = CombEUB.get(); 8537 Built.DistCombinedFields.Init = CombInit.get(); 8538 Built.DistCombinedFields.Cond = CombCond.get(); 8539 Built.DistCombinedFields.NLB = CombNextLB.get(); 8540 Built.DistCombinedFields.NUB = CombNextUB.get(); 8541 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8542 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8543 8544 return NestedLoopCount; 8545 } 8546 8547 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8548 auto CollapseClauses = 8549 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8550 if (CollapseClauses.begin() != CollapseClauses.end()) 8551 return (*CollapseClauses.begin())->getNumForLoops(); 8552 return nullptr; 8553 } 8554 8555 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8556 auto OrderedClauses = 8557 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8558 if (OrderedClauses.begin() != OrderedClauses.end()) 8559 return (*OrderedClauses.begin())->getNumForLoops(); 8560 return nullptr; 8561 } 8562 8563 static bool checkSimdlenSafelenSpecified(Sema &S, 8564 const ArrayRef<OMPClause *> Clauses) { 8565 const OMPSafelenClause *Safelen = nullptr; 8566 const OMPSimdlenClause *Simdlen = nullptr; 8567 8568 for (const OMPClause *Clause : Clauses) { 8569 if (Clause->getClauseKind() == OMPC_safelen) 8570 Safelen = cast<OMPSafelenClause>(Clause); 8571 else if (Clause->getClauseKind() == OMPC_simdlen) 8572 Simdlen = cast<OMPSimdlenClause>(Clause); 8573 if (Safelen && Simdlen) 8574 break; 8575 } 8576 8577 if (Simdlen && Safelen) { 8578 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8579 const Expr *SafelenLength = Safelen->getSafelen(); 8580 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8581 SimdlenLength->isInstantiationDependent() || 8582 SimdlenLength->containsUnexpandedParameterPack()) 8583 return false; 8584 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8585 SafelenLength->isInstantiationDependent() || 8586 SafelenLength->containsUnexpandedParameterPack()) 8587 return false; 8588 Expr::EvalResult SimdlenResult, SafelenResult; 8589 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8590 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8591 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8592 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8593 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8594 // If both simdlen and safelen clauses are specified, the value of the 8595 // simdlen parameter must be less than or equal to the value of the safelen 8596 // parameter. 8597 if (SimdlenRes > SafelenRes) { 8598 S.Diag(SimdlenLength->getExprLoc(), 8599 diag::err_omp_wrong_simdlen_safelen_values) 8600 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8601 return true; 8602 } 8603 } 8604 return false; 8605 } 8606 8607 StmtResult 8608 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8609 SourceLocation StartLoc, SourceLocation EndLoc, 8610 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8611 if (!AStmt) 8612 return StmtError(); 8613 8614 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8615 OMPLoopDirective::HelperExprs B; 8616 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8617 // define the nested loops number. 8618 unsigned NestedLoopCount = checkOpenMPLoop( 8619 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8620 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8621 if (NestedLoopCount == 0) 8622 return StmtError(); 8623 8624 assert((CurContext->isDependentContext() || B.builtAll()) && 8625 "omp simd loop exprs were not built"); 8626 8627 if (!CurContext->isDependentContext()) { 8628 // Finalize the clauses that need pre-built expressions for CodeGen. 8629 for (OMPClause *C : Clauses) { 8630 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8631 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8632 B.NumIterations, *this, CurScope, 8633 DSAStack)) 8634 return StmtError(); 8635 } 8636 } 8637 8638 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8639 return StmtError(); 8640 8641 setFunctionHasBranchProtectedScope(); 8642 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8643 Clauses, AStmt, B); 8644 } 8645 8646 StmtResult 8647 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8648 SourceLocation StartLoc, SourceLocation EndLoc, 8649 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8650 if (!AStmt) 8651 return StmtError(); 8652 8653 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8654 OMPLoopDirective::HelperExprs B; 8655 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8656 // define the nested loops number. 8657 unsigned NestedLoopCount = checkOpenMPLoop( 8658 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8659 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8660 if (NestedLoopCount == 0) 8661 return StmtError(); 8662 8663 assert((CurContext->isDependentContext() || B.builtAll()) && 8664 "omp for loop exprs were not built"); 8665 8666 if (!CurContext->isDependentContext()) { 8667 // Finalize the clauses that need pre-built expressions for CodeGen. 8668 for (OMPClause *C : Clauses) { 8669 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8670 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8671 B.NumIterations, *this, CurScope, 8672 DSAStack)) 8673 return StmtError(); 8674 } 8675 } 8676 8677 setFunctionHasBranchProtectedScope(); 8678 return OMPForDirective::Create( 8679 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8680 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 8681 } 8682 8683 StmtResult Sema::ActOnOpenMPForSimdDirective( 8684 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8685 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8686 if (!AStmt) 8687 return StmtError(); 8688 8689 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8690 OMPLoopDirective::HelperExprs B; 8691 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8692 // define the nested loops number. 8693 unsigned NestedLoopCount = 8694 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8695 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8696 VarsWithImplicitDSA, B); 8697 if (NestedLoopCount == 0) 8698 return StmtError(); 8699 8700 assert((CurContext->isDependentContext() || B.builtAll()) && 8701 "omp for simd loop exprs were not built"); 8702 8703 if (!CurContext->isDependentContext()) { 8704 // Finalize the clauses that need pre-built expressions for CodeGen. 8705 for (OMPClause *C : Clauses) { 8706 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8707 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8708 B.NumIterations, *this, CurScope, 8709 DSAStack)) 8710 return StmtError(); 8711 } 8712 } 8713 8714 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8715 return StmtError(); 8716 8717 setFunctionHasBranchProtectedScope(); 8718 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8719 Clauses, AStmt, B); 8720 } 8721 8722 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8723 Stmt *AStmt, 8724 SourceLocation StartLoc, 8725 SourceLocation EndLoc) { 8726 if (!AStmt) 8727 return StmtError(); 8728 8729 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8730 auto BaseStmt = AStmt; 8731 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8732 BaseStmt = CS->getCapturedStmt(); 8733 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8734 auto S = C->children(); 8735 if (S.begin() == S.end()) 8736 return StmtError(); 8737 // All associated statements must be '#pragma omp section' except for 8738 // the first one. 8739 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8740 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8741 if (SectionStmt) 8742 Diag(SectionStmt->getBeginLoc(), 8743 diag::err_omp_sections_substmt_not_section); 8744 return StmtError(); 8745 } 8746 cast<OMPSectionDirective>(SectionStmt) 8747 ->setHasCancel(DSAStack->isCancelRegion()); 8748 } 8749 } else { 8750 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8751 return StmtError(); 8752 } 8753 8754 setFunctionHasBranchProtectedScope(); 8755 8756 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8757 DSAStack->getTaskgroupReductionRef(), 8758 DSAStack->isCancelRegion()); 8759 } 8760 8761 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8762 SourceLocation StartLoc, 8763 SourceLocation EndLoc) { 8764 if (!AStmt) 8765 return StmtError(); 8766 8767 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8768 8769 setFunctionHasBranchProtectedScope(); 8770 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8771 8772 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8773 DSAStack->isCancelRegion()); 8774 } 8775 8776 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8777 Stmt *AStmt, 8778 SourceLocation StartLoc, 8779 SourceLocation EndLoc) { 8780 if (!AStmt) 8781 return StmtError(); 8782 8783 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8784 8785 setFunctionHasBranchProtectedScope(); 8786 8787 // OpenMP [2.7.3, single Construct, Restrictions] 8788 // The copyprivate clause must not be used with the nowait clause. 8789 const OMPClause *Nowait = nullptr; 8790 const OMPClause *Copyprivate = nullptr; 8791 for (const OMPClause *Clause : Clauses) { 8792 if (Clause->getClauseKind() == OMPC_nowait) 8793 Nowait = Clause; 8794 else if (Clause->getClauseKind() == OMPC_copyprivate) 8795 Copyprivate = Clause; 8796 if (Copyprivate && Nowait) { 8797 Diag(Copyprivate->getBeginLoc(), 8798 diag::err_omp_single_copyprivate_with_nowait); 8799 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8800 return StmtError(); 8801 } 8802 } 8803 8804 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8805 } 8806 8807 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8808 SourceLocation StartLoc, 8809 SourceLocation EndLoc) { 8810 if (!AStmt) 8811 return StmtError(); 8812 8813 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8814 8815 setFunctionHasBranchProtectedScope(); 8816 8817 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8818 } 8819 8820 StmtResult Sema::ActOnOpenMPCriticalDirective( 8821 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8822 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8823 if (!AStmt) 8824 return StmtError(); 8825 8826 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8827 8828 bool ErrorFound = false; 8829 llvm::APSInt Hint; 8830 SourceLocation HintLoc; 8831 bool DependentHint = false; 8832 for (const OMPClause *C : Clauses) { 8833 if (C->getClauseKind() == OMPC_hint) { 8834 if (!DirName.getName()) { 8835 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8836 ErrorFound = true; 8837 } 8838 Expr *E = cast<OMPHintClause>(C)->getHint(); 8839 if (E->isTypeDependent() || E->isValueDependent() || 8840 E->isInstantiationDependent()) { 8841 DependentHint = true; 8842 } else { 8843 Hint = E->EvaluateKnownConstInt(Context); 8844 HintLoc = C->getBeginLoc(); 8845 } 8846 } 8847 } 8848 if (ErrorFound) 8849 return StmtError(); 8850 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8851 if (Pair.first && DirName.getName() && !DependentHint) { 8852 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8853 Diag(StartLoc, diag::err_omp_critical_with_hint); 8854 if (HintLoc.isValid()) 8855 Diag(HintLoc, diag::note_omp_critical_hint_here) 8856 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8857 else 8858 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8859 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8860 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8861 << 1 8862 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8863 /*Radix=*/10, /*Signed=*/false); 8864 } else { 8865 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8866 } 8867 } 8868 } 8869 8870 setFunctionHasBranchProtectedScope(); 8871 8872 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8873 Clauses, AStmt); 8874 if (!Pair.first && DirName.getName() && !DependentHint) 8875 DSAStack->addCriticalWithHint(Dir, Hint); 8876 return Dir; 8877 } 8878 8879 StmtResult Sema::ActOnOpenMPParallelForDirective( 8880 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8881 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8882 if (!AStmt) 8883 return StmtError(); 8884 8885 auto *CS = cast<CapturedStmt>(AStmt); 8886 // 1.2.2 OpenMP Language Terminology 8887 // Structured block - An executable statement with a single entry at the 8888 // top and a single exit at the bottom. 8889 // The point of exit cannot be a branch out of the structured block. 8890 // longjmp() and throw() must not violate the entry/exit criteria. 8891 CS->getCapturedDecl()->setNothrow(); 8892 8893 OMPLoopDirective::HelperExprs B; 8894 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8895 // define the nested loops number. 8896 unsigned NestedLoopCount = 8897 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8898 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8899 VarsWithImplicitDSA, B); 8900 if (NestedLoopCount == 0) 8901 return StmtError(); 8902 8903 assert((CurContext->isDependentContext() || B.builtAll()) && 8904 "omp parallel for loop exprs were not built"); 8905 8906 if (!CurContext->isDependentContext()) { 8907 // Finalize the clauses that need pre-built expressions for CodeGen. 8908 for (OMPClause *C : Clauses) { 8909 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8910 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8911 B.NumIterations, *this, CurScope, 8912 DSAStack)) 8913 return StmtError(); 8914 } 8915 } 8916 8917 setFunctionHasBranchProtectedScope(); 8918 return OMPParallelForDirective::Create( 8919 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8920 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 8921 } 8922 8923 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8924 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8925 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8926 if (!AStmt) 8927 return StmtError(); 8928 8929 auto *CS = cast<CapturedStmt>(AStmt); 8930 // 1.2.2 OpenMP Language Terminology 8931 // Structured block - An executable statement with a single entry at the 8932 // top and a single exit at the bottom. 8933 // The point of exit cannot be a branch out of the structured block. 8934 // longjmp() and throw() must not violate the entry/exit criteria. 8935 CS->getCapturedDecl()->setNothrow(); 8936 8937 OMPLoopDirective::HelperExprs B; 8938 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8939 // define the nested loops number. 8940 unsigned NestedLoopCount = 8941 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8942 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8943 VarsWithImplicitDSA, B); 8944 if (NestedLoopCount == 0) 8945 return StmtError(); 8946 8947 if (!CurContext->isDependentContext()) { 8948 // Finalize the clauses that need pre-built expressions for CodeGen. 8949 for (OMPClause *C : Clauses) { 8950 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8951 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8952 B.NumIterations, *this, CurScope, 8953 DSAStack)) 8954 return StmtError(); 8955 } 8956 } 8957 8958 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8959 return StmtError(); 8960 8961 setFunctionHasBranchProtectedScope(); 8962 return OMPParallelForSimdDirective::Create( 8963 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8964 } 8965 8966 StmtResult 8967 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8968 Stmt *AStmt, SourceLocation StartLoc, 8969 SourceLocation EndLoc) { 8970 if (!AStmt) 8971 return StmtError(); 8972 8973 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8974 auto *CS = cast<CapturedStmt>(AStmt); 8975 // 1.2.2 OpenMP Language Terminology 8976 // Structured block - An executable statement with a single entry at the 8977 // top and a single exit at the bottom. 8978 // The point of exit cannot be a branch out of the structured block. 8979 // longjmp() and throw() must not violate the entry/exit criteria. 8980 CS->getCapturedDecl()->setNothrow(); 8981 8982 setFunctionHasBranchProtectedScope(); 8983 8984 return OMPParallelMasterDirective::Create( 8985 Context, StartLoc, EndLoc, Clauses, AStmt, 8986 DSAStack->getTaskgroupReductionRef()); 8987 } 8988 8989 StmtResult 8990 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8991 Stmt *AStmt, SourceLocation StartLoc, 8992 SourceLocation EndLoc) { 8993 if (!AStmt) 8994 return StmtError(); 8995 8996 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8997 auto BaseStmt = AStmt; 8998 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8999 BaseStmt = CS->getCapturedStmt(); 9000 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 9001 auto S = C->children(); 9002 if (S.begin() == S.end()) 9003 return StmtError(); 9004 // All associated statements must be '#pragma omp section' except for 9005 // the first one. 9006 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 9007 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 9008 if (SectionStmt) 9009 Diag(SectionStmt->getBeginLoc(), 9010 diag::err_omp_parallel_sections_substmt_not_section); 9011 return StmtError(); 9012 } 9013 cast<OMPSectionDirective>(SectionStmt) 9014 ->setHasCancel(DSAStack->isCancelRegion()); 9015 } 9016 } else { 9017 Diag(AStmt->getBeginLoc(), 9018 diag::err_omp_parallel_sections_not_compound_stmt); 9019 return StmtError(); 9020 } 9021 9022 setFunctionHasBranchProtectedScope(); 9023 9024 return OMPParallelSectionsDirective::Create( 9025 Context, StartLoc, EndLoc, Clauses, AStmt, 9026 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 9027 } 9028 9029 /// detach and mergeable clauses are mutially exclusive, check for it. 9030 static bool checkDetachMergeableClauses(Sema &S, 9031 ArrayRef<OMPClause *> Clauses) { 9032 const OMPClause *PrevClause = nullptr; 9033 bool ErrorFound = false; 9034 for (const OMPClause *C : Clauses) { 9035 if (C->getClauseKind() == OMPC_detach || 9036 C->getClauseKind() == OMPC_mergeable) { 9037 if (!PrevClause) { 9038 PrevClause = C; 9039 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9040 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 9041 << getOpenMPClauseName(C->getClauseKind()) 9042 << getOpenMPClauseName(PrevClause->getClauseKind()); 9043 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 9044 << getOpenMPClauseName(PrevClause->getClauseKind()); 9045 ErrorFound = true; 9046 } 9047 } 9048 } 9049 return ErrorFound; 9050 } 9051 9052 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 9053 Stmt *AStmt, SourceLocation StartLoc, 9054 SourceLocation EndLoc) { 9055 if (!AStmt) 9056 return StmtError(); 9057 9058 // OpenMP 5.0, 2.10.1 task Construct 9059 // If a detach clause appears on the directive, then a mergeable clause cannot 9060 // appear on the same directive. 9061 if (checkDetachMergeableClauses(*this, Clauses)) 9062 return StmtError(); 9063 9064 auto *CS = cast<CapturedStmt>(AStmt); 9065 // 1.2.2 OpenMP Language Terminology 9066 // Structured block - An executable statement with a single entry at the 9067 // top and a single exit at the bottom. 9068 // The point of exit cannot be a branch out of the structured block. 9069 // longjmp() and throw() must not violate the entry/exit criteria. 9070 CS->getCapturedDecl()->setNothrow(); 9071 9072 setFunctionHasBranchProtectedScope(); 9073 9074 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9075 DSAStack->isCancelRegion()); 9076 } 9077 9078 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 9079 SourceLocation EndLoc) { 9080 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 9081 } 9082 9083 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 9084 SourceLocation EndLoc) { 9085 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 9086 } 9087 9088 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 9089 SourceLocation EndLoc) { 9090 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 9091 } 9092 9093 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 9094 Stmt *AStmt, 9095 SourceLocation StartLoc, 9096 SourceLocation EndLoc) { 9097 if (!AStmt) 9098 return StmtError(); 9099 9100 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9101 9102 setFunctionHasBranchProtectedScope(); 9103 9104 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 9105 AStmt, 9106 DSAStack->getTaskgroupReductionRef()); 9107 } 9108 9109 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 9110 SourceLocation StartLoc, 9111 SourceLocation EndLoc) { 9112 OMPFlushClause *FC = nullptr; 9113 OMPClause *OrderClause = nullptr; 9114 for (OMPClause *C : Clauses) { 9115 if (C->getClauseKind() == OMPC_flush) 9116 FC = cast<OMPFlushClause>(C); 9117 else 9118 OrderClause = C; 9119 } 9120 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9121 SourceLocation MemOrderLoc; 9122 for (const OMPClause *C : Clauses) { 9123 if (C->getClauseKind() == OMPC_acq_rel || 9124 C->getClauseKind() == OMPC_acquire || 9125 C->getClauseKind() == OMPC_release) { 9126 if (MemOrderKind != OMPC_unknown) { 9127 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9128 << getOpenMPDirectiveName(OMPD_flush) << 1 9129 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9130 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9131 << getOpenMPClauseName(MemOrderKind); 9132 } else { 9133 MemOrderKind = C->getClauseKind(); 9134 MemOrderLoc = C->getBeginLoc(); 9135 } 9136 } 9137 } 9138 if (FC && OrderClause) { 9139 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 9140 << getOpenMPClauseName(OrderClause->getClauseKind()); 9141 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 9142 << getOpenMPClauseName(OrderClause->getClauseKind()); 9143 return StmtError(); 9144 } 9145 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 9146 } 9147 9148 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 9149 SourceLocation StartLoc, 9150 SourceLocation EndLoc) { 9151 if (Clauses.empty()) { 9152 Diag(StartLoc, diag::err_omp_depobj_expected); 9153 return StmtError(); 9154 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 9155 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 9156 return StmtError(); 9157 } 9158 // Only depobj expression and another single clause is allowed. 9159 if (Clauses.size() > 2) { 9160 Diag(Clauses[2]->getBeginLoc(), 9161 diag::err_omp_depobj_single_clause_expected); 9162 return StmtError(); 9163 } else if (Clauses.size() < 1) { 9164 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 9165 return StmtError(); 9166 } 9167 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 9168 } 9169 9170 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 9171 SourceLocation StartLoc, 9172 SourceLocation EndLoc) { 9173 // Check that exactly one clause is specified. 9174 if (Clauses.size() != 1) { 9175 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 9176 diag::err_omp_scan_single_clause_expected); 9177 return StmtError(); 9178 } 9179 // Check that scan directive is used in the scopeof the OpenMP loop body. 9180 if (Scope *S = DSAStack->getCurScope()) { 9181 Scope *ParentS = S->getParent(); 9182 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || 9183 !ParentS->getBreakParent()->isOpenMPLoopScope()) 9184 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) 9185 << getOpenMPDirectiveName(OMPD_scan) << 5); 9186 } 9187 // Check that only one instance of scan directives is used in the same outer 9188 // region. 9189 if (DSAStack->doesParentHasScanDirective()) { 9190 Diag(StartLoc, diag::err_omp_several_scan_directives_in_region); 9191 Diag(DSAStack->getParentScanDirectiveLoc(), 9192 diag::note_omp_previous_scan_directive); 9193 return StmtError(); 9194 } 9195 DSAStack->setParentHasScanDirective(StartLoc); 9196 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 9197 } 9198 9199 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 9200 Stmt *AStmt, 9201 SourceLocation StartLoc, 9202 SourceLocation EndLoc) { 9203 const OMPClause *DependFound = nullptr; 9204 const OMPClause *DependSourceClause = nullptr; 9205 const OMPClause *DependSinkClause = nullptr; 9206 bool ErrorFound = false; 9207 const OMPThreadsClause *TC = nullptr; 9208 const OMPSIMDClause *SC = nullptr; 9209 for (const OMPClause *C : Clauses) { 9210 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 9211 DependFound = C; 9212 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 9213 if (DependSourceClause) { 9214 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 9215 << getOpenMPDirectiveName(OMPD_ordered) 9216 << getOpenMPClauseName(OMPC_depend) << 2; 9217 ErrorFound = true; 9218 } else { 9219 DependSourceClause = C; 9220 } 9221 if (DependSinkClause) { 9222 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9223 << 0; 9224 ErrorFound = true; 9225 } 9226 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 9227 if (DependSourceClause) { 9228 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9229 << 1; 9230 ErrorFound = true; 9231 } 9232 DependSinkClause = C; 9233 } 9234 } else if (C->getClauseKind() == OMPC_threads) { 9235 TC = cast<OMPThreadsClause>(C); 9236 } else if (C->getClauseKind() == OMPC_simd) { 9237 SC = cast<OMPSIMDClause>(C); 9238 } 9239 } 9240 if (!ErrorFound && !SC && 9241 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 9242 // OpenMP [2.8.1,simd Construct, Restrictions] 9243 // An ordered construct with the simd clause is the only OpenMP construct 9244 // that can appear in the simd region. 9245 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 9246 << (LangOpts.OpenMP >= 50 ? 1 : 0); 9247 ErrorFound = true; 9248 } else if (DependFound && (TC || SC)) { 9249 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 9250 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 9251 ErrorFound = true; 9252 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 9253 Diag(DependFound->getBeginLoc(), 9254 diag::err_omp_ordered_directive_without_param); 9255 ErrorFound = true; 9256 } else if (TC || Clauses.empty()) { 9257 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 9258 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 9259 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 9260 << (TC != nullptr); 9261 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 9262 ErrorFound = true; 9263 } 9264 } 9265 if ((!AStmt && !DependFound) || ErrorFound) 9266 return StmtError(); 9267 9268 if (AStmt) { 9269 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9270 9271 setFunctionHasBranchProtectedScope(); 9272 } 9273 9274 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9275 } 9276 9277 namespace { 9278 /// Helper class for checking expression in 'omp atomic [update]' 9279 /// construct. 9280 class OpenMPAtomicUpdateChecker { 9281 /// Error results for atomic update expressions. 9282 enum ExprAnalysisErrorCode { 9283 /// A statement is not an expression statement. 9284 NotAnExpression, 9285 /// Expression is not builtin binary or unary operation. 9286 NotABinaryOrUnaryExpression, 9287 /// Unary operation is not post-/pre- increment/decrement operation. 9288 NotAnUnaryIncDecExpression, 9289 /// An expression is not of scalar type. 9290 NotAScalarType, 9291 /// A binary operation is not an assignment operation. 9292 NotAnAssignmentOp, 9293 /// RHS part of the binary operation is not a binary expression. 9294 NotABinaryExpression, 9295 /// RHS part is not additive/multiplicative/shift/biwise binary 9296 /// expression. 9297 NotABinaryOperator, 9298 /// RHS binary operation does not have reference to the updated LHS 9299 /// part. 9300 NotAnUpdateExpression, 9301 /// No errors is found. 9302 NoError 9303 }; 9304 /// Reference to Sema. 9305 Sema &SemaRef; 9306 /// A location for note diagnostics (when error is found). 9307 SourceLocation NoteLoc; 9308 /// 'x' lvalue part of the source atomic expression. 9309 Expr *X; 9310 /// 'expr' rvalue part of the source atomic expression. 9311 Expr *E; 9312 /// Helper expression of the form 9313 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9314 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9315 Expr *UpdateExpr; 9316 /// Is 'x' a LHS in a RHS part of full update expression. It is 9317 /// important for non-associative operations. 9318 bool IsXLHSInRHSPart; 9319 BinaryOperatorKind Op; 9320 SourceLocation OpLoc; 9321 /// true if the source expression is a postfix unary operation, false 9322 /// if it is a prefix unary operation. 9323 bool IsPostfixUpdate; 9324 9325 public: 9326 OpenMPAtomicUpdateChecker(Sema &SemaRef) 9327 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 9328 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 9329 /// Check specified statement that it is suitable for 'atomic update' 9330 /// constructs and extract 'x', 'expr' and Operation from the original 9331 /// expression. If DiagId and NoteId == 0, then only check is performed 9332 /// without error notification. 9333 /// \param DiagId Diagnostic which should be emitted if error is found. 9334 /// \param NoteId Diagnostic note for the main error message. 9335 /// \return true if statement is not an update expression, false otherwise. 9336 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 9337 /// Return the 'x' lvalue part of the source atomic expression. 9338 Expr *getX() const { return X; } 9339 /// Return the 'expr' rvalue part of the source atomic expression. 9340 Expr *getExpr() const { return E; } 9341 /// Return the update expression used in calculation of the updated 9342 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9343 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9344 Expr *getUpdateExpr() const { return UpdateExpr; } 9345 /// Return true if 'x' is LHS in RHS part of full update expression, 9346 /// false otherwise. 9347 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 9348 9349 /// true if the source expression is a postfix unary operation, false 9350 /// if it is a prefix unary operation. 9351 bool isPostfixUpdate() const { return IsPostfixUpdate; } 9352 9353 private: 9354 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 9355 unsigned NoteId = 0); 9356 }; 9357 } // namespace 9358 9359 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 9360 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 9361 ExprAnalysisErrorCode ErrorFound = NoError; 9362 SourceLocation ErrorLoc, NoteLoc; 9363 SourceRange ErrorRange, NoteRange; 9364 // Allowed constructs are: 9365 // x = x binop expr; 9366 // x = expr binop x; 9367 if (AtomicBinOp->getOpcode() == BO_Assign) { 9368 X = AtomicBinOp->getLHS(); 9369 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 9370 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 9371 if (AtomicInnerBinOp->isMultiplicativeOp() || 9372 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 9373 AtomicInnerBinOp->isBitwiseOp()) { 9374 Op = AtomicInnerBinOp->getOpcode(); 9375 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 9376 Expr *LHS = AtomicInnerBinOp->getLHS(); 9377 Expr *RHS = AtomicInnerBinOp->getRHS(); 9378 llvm::FoldingSetNodeID XId, LHSId, RHSId; 9379 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 9380 /*Canonical=*/true); 9381 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 9382 /*Canonical=*/true); 9383 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 9384 /*Canonical=*/true); 9385 if (XId == LHSId) { 9386 E = RHS; 9387 IsXLHSInRHSPart = true; 9388 } else if (XId == RHSId) { 9389 E = LHS; 9390 IsXLHSInRHSPart = false; 9391 } else { 9392 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9393 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9394 NoteLoc = X->getExprLoc(); 9395 NoteRange = X->getSourceRange(); 9396 ErrorFound = NotAnUpdateExpression; 9397 } 9398 } else { 9399 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9400 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9401 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 9402 NoteRange = SourceRange(NoteLoc, NoteLoc); 9403 ErrorFound = NotABinaryOperator; 9404 } 9405 } else { 9406 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 9407 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 9408 ErrorFound = NotABinaryExpression; 9409 } 9410 } else { 9411 ErrorLoc = AtomicBinOp->getExprLoc(); 9412 ErrorRange = AtomicBinOp->getSourceRange(); 9413 NoteLoc = AtomicBinOp->getOperatorLoc(); 9414 NoteRange = SourceRange(NoteLoc, NoteLoc); 9415 ErrorFound = NotAnAssignmentOp; 9416 } 9417 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9418 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9419 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9420 return true; 9421 } 9422 if (SemaRef.CurContext->isDependentContext()) 9423 E = X = UpdateExpr = nullptr; 9424 return ErrorFound != NoError; 9425 } 9426 9427 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 9428 unsigned NoteId) { 9429 ExprAnalysisErrorCode ErrorFound = NoError; 9430 SourceLocation ErrorLoc, NoteLoc; 9431 SourceRange ErrorRange, NoteRange; 9432 // Allowed constructs are: 9433 // x++; 9434 // x--; 9435 // ++x; 9436 // --x; 9437 // x binop= expr; 9438 // x = x binop expr; 9439 // x = expr binop x; 9440 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 9441 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 9442 if (AtomicBody->getType()->isScalarType() || 9443 AtomicBody->isInstantiationDependent()) { 9444 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 9445 AtomicBody->IgnoreParenImpCasts())) { 9446 // Check for Compound Assignment Operation 9447 Op = BinaryOperator::getOpForCompoundAssignment( 9448 AtomicCompAssignOp->getOpcode()); 9449 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 9450 E = AtomicCompAssignOp->getRHS(); 9451 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 9452 IsXLHSInRHSPart = true; 9453 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 9454 AtomicBody->IgnoreParenImpCasts())) { 9455 // Check for Binary Operation 9456 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 9457 return true; 9458 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 9459 AtomicBody->IgnoreParenImpCasts())) { 9460 // Check for Unary Operation 9461 if (AtomicUnaryOp->isIncrementDecrementOp()) { 9462 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 9463 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 9464 OpLoc = AtomicUnaryOp->getOperatorLoc(); 9465 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 9466 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 9467 IsXLHSInRHSPart = true; 9468 } else { 9469 ErrorFound = NotAnUnaryIncDecExpression; 9470 ErrorLoc = AtomicUnaryOp->getExprLoc(); 9471 ErrorRange = AtomicUnaryOp->getSourceRange(); 9472 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 9473 NoteRange = SourceRange(NoteLoc, NoteLoc); 9474 } 9475 } else if (!AtomicBody->isInstantiationDependent()) { 9476 ErrorFound = NotABinaryOrUnaryExpression; 9477 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 9478 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 9479 } 9480 } else { 9481 ErrorFound = NotAScalarType; 9482 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 9483 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9484 } 9485 } else { 9486 ErrorFound = NotAnExpression; 9487 NoteLoc = ErrorLoc = S->getBeginLoc(); 9488 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9489 } 9490 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9491 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9492 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9493 return true; 9494 } 9495 if (SemaRef.CurContext->isDependentContext()) 9496 E = X = UpdateExpr = nullptr; 9497 if (ErrorFound == NoError && E && X) { 9498 // Build an update expression of form 'OpaqueValueExpr(x) binop 9499 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 9500 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 9501 auto *OVEX = new (SemaRef.getASTContext()) 9502 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 9503 auto *OVEExpr = new (SemaRef.getASTContext()) 9504 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 9505 ExprResult Update = 9506 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 9507 IsXLHSInRHSPart ? OVEExpr : OVEX); 9508 if (Update.isInvalid()) 9509 return true; 9510 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 9511 Sema::AA_Casting); 9512 if (Update.isInvalid()) 9513 return true; 9514 UpdateExpr = Update.get(); 9515 } 9516 return ErrorFound != NoError; 9517 } 9518 9519 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 9520 Stmt *AStmt, 9521 SourceLocation StartLoc, 9522 SourceLocation EndLoc) { 9523 // Register location of the first atomic directive. 9524 DSAStack->addAtomicDirectiveLoc(StartLoc); 9525 if (!AStmt) 9526 return StmtError(); 9527 9528 auto *CS = cast<CapturedStmt>(AStmt); 9529 // 1.2.2 OpenMP Language Terminology 9530 // Structured block - An executable statement with a single entry at the 9531 // top and a single exit at the bottom. 9532 // The point of exit cannot be a branch out of the structured block. 9533 // longjmp() and throw() must not violate the entry/exit criteria. 9534 OpenMPClauseKind AtomicKind = OMPC_unknown; 9535 SourceLocation AtomicKindLoc; 9536 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9537 SourceLocation MemOrderLoc; 9538 for (const OMPClause *C : Clauses) { 9539 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 9540 C->getClauseKind() == OMPC_update || 9541 C->getClauseKind() == OMPC_capture) { 9542 if (AtomicKind != OMPC_unknown) { 9543 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 9544 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9545 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 9546 << getOpenMPClauseName(AtomicKind); 9547 } else { 9548 AtomicKind = C->getClauseKind(); 9549 AtomicKindLoc = C->getBeginLoc(); 9550 } 9551 } 9552 if (C->getClauseKind() == OMPC_seq_cst || 9553 C->getClauseKind() == OMPC_acq_rel || 9554 C->getClauseKind() == OMPC_acquire || 9555 C->getClauseKind() == OMPC_release || 9556 C->getClauseKind() == OMPC_relaxed) { 9557 if (MemOrderKind != OMPC_unknown) { 9558 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9559 << getOpenMPDirectiveName(OMPD_atomic) << 0 9560 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9561 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9562 << getOpenMPClauseName(MemOrderKind); 9563 } else { 9564 MemOrderKind = C->getClauseKind(); 9565 MemOrderLoc = C->getBeginLoc(); 9566 } 9567 } 9568 } 9569 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 9570 // If atomic-clause is read then memory-order-clause must not be acq_rel or 9571 // release. 9572 // If atomic-clause is write then memory-order-clause must not be acq_rel or 9573 // acquire. 9574 // If atomic-clause is update or not present then memory-order-clause must not 9575 // be acq_rel or acquire. 9576 if ((AtomicKind == OMPC_read && 9577 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 9578 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 9579 AtomicKind == OMPC_unknown) && 9580 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 9581 SourceLocation Loc = AtomicKindLoc; 9582 if (AtomicKind == OMPC_unknown) 9583 Loc = StartLoc; 9584 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 9585 << getOpenMPClauseName(AtomicKind) 9586 << (AtomicKind == OMPC_unknown ? 1 : 0) 9587 << getOpenMPClauseName(MemOrderKind); 9588 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9589 << getOpenMPClauseName(MemOrderKind); 9590 } 9591 9592 Stmt *Body = CS->getCapturedStmt(); 9593 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 9594 Body = EWC->getSubExpr(); 9595 9596 Expr *X = nullptr; 9597 Expr *V = nullptr; 9598 Expr *E = nullptr; 9599 Expr *UE = nullptr; 9600 bool IsXLHSInRHSPart = false; 9601 bool IsPostfixUpdate = false; 9602 // OpenMP [2.12.6, atomic Construct] 9603 // In the next expressions: 9604 // * x and v (as applicable) are both l-value expressions with scalar type. 9605 // * During the execution of an atomic region, multiple syntactic 9606 // occurrences of x must designate the same storage location. 9607 // * Neither of v and expr (as applicable) may access the storage location 9608 // designated by x. 9609 // * Neither of x and expr (as applicable) may access the storage location 9610 // designated by v. 9611 // * expr is an expression with scalar type. 9612 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 9613 // * binop, binop=, ++, and -- are not overloaded operators. 9614 // * The expression x binop expr must be numerically equivalent to x binop 9615 // (expr). This requirement is satisfied if the operators in expr have 9616 // precedence greater than binop, or by using parentheses around expr or 9617 // subexpressions of expr. 9618 // * The expression expr binop x must be numerically equivalent to (expr) 9619 // binop x. This requirement is satisfied if the operators in expr have 9620 // precedence equal to or greater than binop, or by using parentheses around 9621 // expr or subexpressions of expr. 9622 // * For forms that allow multiple occurrences of x, the number of times 9623 // that x is evaluated is unspecified. 9624 if (AtomicKind == OMPC_read) { 9625 enum { 9626 NotAnExpression, 9627 NotAnAssignmentOp, 9628 NotAScalarType, 9629 NotAnLValue, 9630 NoError 9631 } ErrorFound = NoError; 9632 SourceLocation ErrorLoc, NoteLoc; 9633 SourceRange ErrorRange, NoteRange; 9634 // If clause is read: 9635 // v = x; 9636 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9637 const auto *AtomicBinOp = 9638 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9639 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9640 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9641 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 9642 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9643 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9644 if (!X->isLValue() || !V->isLValue()) { 9645 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9646 ErrorFound = NotAnLValue; 9647 ErrorLoc = AtomicBinOp->getExprLoc(); 9648 ErrorRange = AtomicBinOp->getSourceRange(); 9649 NoteLoc = NotLValueExpr->getExprLoc(); 9650 NoteRange = NotLValueExpr->getSourceRange(); 9651 } 9652 } else if (!X->isInstantiationDependent() || 9653 !V->isInstantiationDependent()) { 9654 const Expr *NotScalarExpr = 9655 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9656 ? V 9657 : X; 9658 ErrorFound = NotAScalarType; 9659 ErrorLoc = AtomicBinOp->getExprLoc(); 9660 ErrorRange = AtomicBinOp->getSourceRange(); 9661 NoteLoc = NotScalarExpr->getExprLoc(); 9662 NoteRange = NotScalarExpr->getSourceRange(); 9663 } 9664 } else if (!AtomicBody->isInstantiationDependent()) { 9665 ErrorFound = NotAnAssignmentOp; 9666 ErrorLoc = AtomicBody->getExprLoc(); 9667 ErrorRange = AtomicBody->getSourceRange(); 9668 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9669 : AtomicBody->getExprLoc(); 9670 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9671 : AtomicBody->getSourceRange(); 9672 } 9673 } else { 9674 ErrorFound = NotAnExpression; 9675 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9676 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9677 } 9678 if (ErrorFound != NoError) { 9679 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9680 << ErrorRange; 9681 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9682 << NoteRange; 9683 return StmtError(); 9684 } 9685 if (CurContext->isDependentContext()) 9686 V = X = nullptr; 9687 } else if (AtomicKind == OMPC_write) { 9688 enum { 9689 NotAnExpression, 9690 NotAnAssignmentOp, 9691 NotAScalarType, 9692 NotAnLValue, 9693 NoError 9694 } ErrorFound = NoError; 9695 SourceLocation ErrorLoc, NoteLoc; 9696 SourceRange ErrorRange, NoteRange; 9697 // If clause is write: 9698 // x = expr; 9699 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9700 const auto *AtomicBinOp = 9701 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9702 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9703 X = AtomicBinOp->getLHS(); 9704 E = AtomicBinOp->getRHS(); 9705 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9706 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9707 if (!X->isLValue()) { 9708 ErrorFound = NotAnLValue; 9709 ErrorLoc = AtomicBinOp->getExprLoc(); 9710 ErrorRange = AtomicBinOp->getSourceRange(); 9711 NoteLoc = X->getExprLoc(); 9712 NoteRange = X->getSourceRange(); 9713 } 9714 } else if (!X->isInstantiationDependent() || 9715 !E->isInstantiationDependent()) { 9716 const Expr *NotScalarExpr = 9717 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9718 ? E 9719 : X; 9720 ErrorFound = NotAScalarType; 9721 ErrorLoc = AtomicBinOp->getExprLoc(); 9722 ErrorRange = AtomicBinOp->getSourceRange(); 9723 NoteLoc = NotScalarExpr->getExprLoc(); 9724 NoteRange = NotScalarExpr->getSourceRange(); 9725 } 9726 } else if (!AtomicBody->isInstantiationDependent()) { 9727 ErrorFound = NotAnAssignmentOp; 9728 ErrorLoc = AtomicBody->getExprLoc(); 9729 ErrorRange = AtomicBody->getSourceRange(); 9730 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9731 : AtomicBody->getExprLoc(); 9732 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9733 : AtomicBody->getSourceRange(); 9734 } 9735 } else { 9736 ErrorFound = NotAnExpression; 9737 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9738 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9739 } 9740 if (ErrorFound != NoError) { 9741 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 9742 << ErrorRange; 9743 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9744 << NoteRange; 9745 return StmtError(); 9746 } 9747 if (CurContext->isDependentContext()) 9748 E = X = nullptr; 9749 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9750 // If clause is update: 9751 // x++; 9752 // x--; 9753 // ++x; 9754 // --x; 9755 // x binop= expr; 9756 // x = x binop expr; 9757 // x = expr binop x; 9758 OpenMPAtomicUpdateChecker Checker(*this); 9759 if (Checker.checkStatement( 9760 Body, (AtomicKind == OMPC_update) 9761 ? diag::err_omp_atomic_update_not_expression_statement 9762 : diag::err_omp_atomic_not_expression_statement, 9763 diag::note_omp_atomic_update)) 9764 return StmtError(); 9765 if (!CurContext->isDependentContext()) { 9766 E = Checker.getExpr(); 9767 X = Checker.getX(); 9768 UE = Checker.getUpdateExpr(); 9769 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9770 } 9771 } else if (AtomicKind == OMPC_capture) { 9772 enum { 9773 NotAnAssignmentOp, 9774 NotACompoundStatement, 9775 NotTwoSubstatements, 9776 NotASpecificExpression, 9777 NoError 9778 } ErrorFound = NoError; 9779 SourceLocation ErrorLoc, NoteLoc; 9780 SourceRange ErrorRange, NoteRange; 9781 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9782 // If clause is a capture: 9783 // v = x++; 9784 // v = x--; 9785 // v = ++x; 9786 // v = --x; 9787 // v = x binop= expr; 9788 // v = x = x binop expr; 9789 // v = x = expr binop x; 9790 const auto *AtomicBinOp = 9791 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9792 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9793 V = AtomicBinOp->getLHS(); 9794 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9795 OpenMPAtomicUpdateChecker Checker(*this); 9796 if (Checker.checkStatement( 9797 Body, diag::err_omp_atomic_capture_not_expression_statement, 9798 diag::note_omp_atomic_update)) 9799 return StmtError(); 9800 E = Checker.getExpr(); 9801 X = Checker.getX(); 9802 UE = Checker.getUpdateExpr(); 9803 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9804 IsPostfixUpdate = Checker.isPostfixUpdate(); 9805 } else if (!AtomicBody->isInstantiationDependent()) { 9806 ErrorLoc = AtomicBody->getExprLoc(); 9807 ErrorRange = AtomicBody->getSourceRange(); 9808 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9809 : AtomicBody->getExprLoc(); 9810 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9811 : AtomicBody->getSourceRange(); 9812 ErrorFound = NotAnAssignmentOp; 9813 } 9814 if (ErrorFound != NoError) { 9815 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9816 << ErrorRange; 9817 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9818 return StmtError(); 9819 } 9820 if (CurContext->isDependentContext()) 9821 UE = V = E = X = nullptr; 9822 } else { 9823 // If clause is a capture: 9824 // { v = x; x = expr; } 9825 // { v = x; x++; } 9826 // { v = x; x--; } 9827 // { v = x; ++x; } 9828 // { v = x; --x; } 9829 // { v = x; x binop= expr; } 9830 // { v = x; x = x binop expr; } 9831 // { v = x; x = expr binop x; } 9832 // { x++; v = x; } 9833 // { x--; v = x; } 9834 // { ++x; v = x; } 9835 // { --x; v = x; } 9836 // { x binop= expr; v = x; } 9837 // { x = x binop expr; v = x; } 9838 // { x = expr binop x; v = x; } 9839 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9840 // Check that this is { expr1; expr2; } 9841 if (CS->size() == 2) { 9842 Stmt *First = CS->body_front(); 9843 Stmt *Second = CS->body_back(); 9844 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9845 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9846 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9847 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9848 // Need to find what subexpression is 'v' and what is 'x'. 9849 OpenMPAtomicUpdateChecker Checker(*this); 9850 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9851 BinaryOperator *BinOp = nullptr; 9852 if (IsUpdateExprFound) { 9853 BinOp = dyn_cast<BinaryOperator>(First); 9854 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9855 } 9856 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9857 // { v = x; x++; } 9858 // { v = x; x--; } 9859 // { v = x; ++x; } 9860 // { v = x; --x; } 9861 // { v = x; x binop= expr; } 9862 // { v = x; x = x binop expr; } 9863 // { v = x; x = expr binop x; } 9864 // Check that the first expression has form v = x. 9865 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9866 llvm::FoldingSetNodeID XId, PossibleXId; 9867 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9868 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9869 IsUpdateExprFound = XId == PossibleXId; 9870 if (IsUpdateExprFound) { 9871 V = BinOp->getLHS(); 9872 X = Checker.getX(); 9873 E = Checker.getExpr(); 9874 UE = Checker.getUpdateExpr(); 9875 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9876 IsPostfixUpdate = true; 9877 } 9878 } 9879 if (!IsUpdateExprFound) { 9880 IsUpdateExprFound = !Checker.checkStatement(First); 9881 BinOp = nullptr; 9882 if (IsUpdateExprFound) { 9883 BinOp = dyn_cast<BinaryOperator>(Second); 9884 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9885 } 9886 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9887 // { x++; v = x; } 9888 // { x--; v = x; } 9889 // { ++x; v = x; } 9890 // { --x; v = x; } 9891 // { x binop= expr; v = x; } 9892 // { x = x binop expr; v = x; } 9893 // { x = expr binop x; v = x; } 9894 // Check that the second expression has form v = x. 9895 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9896 llvm::FoldingSetNodeID XId, PossibleXId; 9897 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9898 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9899 IsUpdateExprFound = XId == PossibleXId; 9900 if (IsUpdateExprFound) { 9901 V = BinOp->getLHS(); 9902 X = Checker.getX(); 9903 E = Checker.getExpr(); 9904 UE = Checker.getUpdateExpr(); 9905 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9906 IsPostfixUpdate = false; 9907 } 9908 } 9909 } 9910 if (!IsUpdateExprFound) { 9911 // { v = x; x = expr; } 9912 auto *FirstExpr = dyn_cast<Expr>(First); 9913 auto *SecondExpr = dyn_cast<Expr>(Second); 9914 if (!FirstExpr || !SecondExpr || 9915 !(FirstExpr->isInstantiationDependent() || 9916 SecondExpr->isInstantiationDependent())) { 9917 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9918 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9919 ErrorFound = NotAnAssignmentOp; 9920 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9921 : First->getBeginLoc(); 9922 NoteRange = ErrorRange = FirstBinOp 9923 ? FirstBinOp->getSourceRange() 9924 : SourceRange(ErrorLoc, ErrorLoc); 9925 } else { 9926 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9927 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9928 ErrorFound = NotAnAssignmentOp; 9929 NoteLoc = ErrorLoc = SecondBinOp 9930 ? SecondBinOp->getOperatorLoc() 9931 : Second->getBeginLoc(); 9932 NoteRange = ErrorRange = 9933 SecondBinOp ? SecondBinOp->getSourceRange() 9934 : SourceRange(ErrorLoc, ErrorLoc); 9935 } else { 9936 Expr *PossibleXRHSInFirst = 9937 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9938 Expr *PossibleXLHSInSecond = 9939 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9940 llvm::FoldingSetNodeID X1Id, X2Id; 9941 PossibleXRHSInFirst->Profile(X1Id, Context, 9942 /*Canonical=*/true); 9943 PossibleXLHSInSecond->Profile(X2Id, Context, 9944 /*Canonical=*/true); 9945 IsUpdateExprFound = X1Id == X2Id; 9946 if (IsUpdateExprFound) { 9947 V = FirstBinOp->getLHS(); 9948 X = SecondBinOp->getLHS(); 9949 E = SecondBinOp->getRHS(); 9950 UE = nullptr; 9951 IsXLHSInRHSPart = false; 9952 IsPostfixUpdate = true; 9953 } else { 9954 ErrorFound = NotASpecificExpression; 9955 ErrorLoc = FirstBinOp->getExprLoc(); 9956 ErrorRange = FirstBinOp->getSourceRange(); 9957 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9958 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9959 } 9960 } 9961 } 9962 } 9963 } 9964 } else { 9965 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9966 NoteRange = ErrorRange = 9967 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9968 ErrorFound = NotTwoSubstatements; 9969 } 9970 } else { 9971 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9972 NoteRange = ErrorRange = 9973 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9974 ErrorFound = NotACompoundStatement; 9975 } 9976 if (ErrorFound != NoError) { 9977 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9978 << ErrorRange; 9979 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9980 return StmtError(); 9981 } 9982 if (CurContext->isDependentContext()) 9983 UE = V = E = X = nullptr; 9984 } 9985 } 9986 9987 setFunctionHasBranchProtectedScope(); 9988 9989 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9990 X, V, E, UE, IsXLHSInRHSPart, 9991 IsPostfixUpdate); 9992 } 9993 9994 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9995 Stmt *AStmt, 9996 SourceLocation StartLoc, 9997 SourceLocation EndLoc) { 9998 if (!AStmt) 9999 return StmtError(); 10000 10001 auto *CS = cast<CapturedStmt>(AStmt); 10002 // 1.2.2 OpenMP Language Terminology 10003 // Structured block - An executable statement with a single entry at the 10004 // top and a single exit at the bottom. 10005 // The point of exit cannot be a branch out of the structured block. 10006 // longjmp() and throw() must not violate the entry/exit criteria. 10007 CS->getCapturedDecl()->setNothrow(); 10008 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 10009 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10010 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10011 // 1.2.2 OpenMP Language Terminology 10012 // Structured block - An executable statement with a single entry at the 10013 // top and a single exit at the bottom. 10014 // The point of exit cannot be a branch out of the structured block. 10015 // longjmp() and throw() must not violate the entry/exit criteria. 10016 CS->getCapturedDecl()->setNothrow(); 10017 } 10018 10019 // OpenMP [2.16, Nesting of Regions] 10020 // If specified, a teams construct must be contained within a target 10021 // construct. That target construct must contain no statements or directives 10022 // outside of the teams construct. 10023 if (DSAStack->hasInnerTeamsRegion()) { 10024 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 10025 bool OMPTeamsFound = true; 10026 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 10027 auto I = CS->body_begin(); 10028 while (I != CS->body_end()) { 10029 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 10030 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 10031 OMPTeamsFound) { 10032 10033 OMPTeamsFound = false; 10034 break; 10035 } 10036 ++I; 10037 } 10038 assert(I != CS->body_end() && "Not found statement"); 10039 S = *I; 10040 } else { 10041 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 10042 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 10043 } 10044 if (!OMPTeamsFound) { 10045 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 10046 Diag(DSAStack->getInnerTeamsRegionLoc(), 10047 diag::note_omp_nested_teams_construct_here); 10048 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 10049 << isa<OMPExecutableDirective>(S); 10050 return StmtError(); 10051 } 10052 } 10053 10054 setFunctionHasBranchProtectedScope(); 10055 10056 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10057 } 10058 10059 StmtResult 10060 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 10061 Stmt *AStmt, SourceLocation StartLoc, 10062 SourceLocation EndLoc) { 10063 if (!AStmt) 10064 return StmtError(); 10065 10066 auto *CS = cast<CapturedStmt>(AStmt); 10067 // 1.2.2 OpenMP Language Terminology 10068 // Structured block - An executable statement with a single entry at the 10069 // top and a single exit at the bottom. 10070 // The point of exit cannot be a branch out of the structured block. 10071 // longjmp() and throw() must not violate the entry/exit criteria. 10072 CS->getCapturedDecl()->setNothrow(); 10073 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 10074 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10075 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10076 // 1.2.2 OpenMP Language Terminology 10077 // Structured block - An executable statement with a single entry at the 10078 // top and a single exit at the bottom. 10079 // The point of exit cannot be a branch out of the structured block. 10080 // longjmp() and throw() must not violate the entry/exit criteria. 10081 CS->getCapturedDecl()->setNothrow(); 10082 } 10083 10084 setFunctionHasBranchProtectedScope(); 10085 10086 return OMPTargetParallelDirective::Create( 10087 Context, StartLoc, EndLoc, Clauses, AStmt, 10088 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10089 } 10090 10091 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 10092 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10093 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10094 if (!AStmt) 10095 return StmtError(); 10096 10097 auto *CS = cast<CapturedStmt>(AStmt); 10098 // 1.2.2 OpenMP Language Terminology 10099 // Structured block - An executable statement with a single entry at the 10100 // top and a single exit at the bottom. 10101 // The point of exit cannot be a branch out of the structured block. 10102 // longjmp() and throw() must not violate the entry/exit criteria. 10103 CS->getCapturedDecl()->setNothrow(); 10104 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10105 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10106 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10107 // 1.2.2 OpenMP Language Terminology 10108 // Structured block - An executable statement with a single entry at the 10109 // top and a single exit at the bottom. 10110 // The point of exit cannot be a branch out of the structured block. 10111 // longjmp() and throw() must not violate the entry/exit criteria. 10112 CS->getCapturedDecl()->setNothrow(); 10113 } 10114 10115 OMPLoopDirective::HelperExprs B; 10116 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10117 // define the nested loops number. 10118 unsigned NestedLoopCount = 10119 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 10120 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10121 VarsWithImplicitDSA, B); 10122 if (NestedLoopCount == 0) 10123 return StmtError(); 10124 10125 assert((CurContext->isDependentContext() || B.builtAll()) && 10126 "omp target parallel for loop exprs were not built"); 10127 10128 if (!CurContext->isDependentContext()) { 10129 // Finalize the clauses that need pre-built expressions for CodeGen. 10130 for (OMPClause *C : Clauses) { 10131 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10132 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10133 B.NumIterations, *this, CurScope, 10134 DSAStack)) 10135 return StmtError(); 10136 } 10137 } 10138 10139 setFunctionHasBranchProtectedScope(); 10140 return OMPTargetParallelForDirective::Create( 10141 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10142 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10143 } 10144 10145 /// Check for existence of a map clause in the list of clauses. 10146 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 10147 const OpenMPClauseKind K) { 10148 return llvm::any_of( 10149 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 10150 } 10151 10152 template <typename... Params> 10153 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 10154 const Params... ClauseTypes) { 10155 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 10156 } 10157 10158 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 10159 Stmt *AStmt, 10160 SourceLocation StartLoc, 10161 SourceLocation EndLoc) { 10162 if (!AStmt) 10163 return StmtError(); 10164 10165 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10166 10167 // OpenMP [2.12.2, target data Construct, Restrictions] 10168 // At least one map, use_device_addr or use_device_ptr clause must appear on 10169 // the directive. 10170 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && 10171 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { 10172 StringRef Expected; 10173 if (LangOpts.OpenMP < 50) 10174 Expected = "'map' or 'use_device_ptr'"; 10175 else 10176 Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; 10177 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10178 << Expected << getOpenMPDirectiveName(OMPD_target_data); 10179 return StmtError(); 10180 } 10181 10182 setFunctionHasBranchProtectedScope(); 10183 10184 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10185 AStmt); 10186 } 10187 10188 StmtResult 10189 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 10190 SourceLocation StartLoc, 10191 SourceLocation EndLoc, Stmt *AStmt) { 10192 if (!AStmt) 10193 return StmtError(); 10194 10195 auto *CS = cast<CapturedStmt>(AStmt); 10196 // 1.2.2 OpenMP Language Terminology 10197 // Structured block - An executable statement with a single entry at the 10198 // top and a single exit at the bottom. 10199 // The point of exit cannot be a branch out of the structured block. 10200 // longjmp() and throw() must not violate the entry/exit criteria. 10201 CS->getCapturedDecl()->setNothrow(); 10202 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 10203 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10204 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10205 // 1.2.2 OpenMP Language Terminology 10206 // Structured block - An executable statement with a single entry at the 10207 // top and a single exit at the bottom. 10208 // The point of exit cannot be a branch out of the structured block. 10209 // longjmp() and throw() must not violate the entry/exit criteria. 10210 CS->getCapturedDecl()->setNothrow(); 10211 } 10212 10213 // OpenMP [2.10.2, Restrictions, p. 99] 10214 // At least one map clause must appear on the directive. 10215 if (!hasClauses(Clauses, OMPC_map)) { 10216 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10217 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 10218 return StmtError(); 10219 } 10220 10221 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10222 AStmt); 10223 } 10224 10225 StmtResult 10226 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 10227 SourceLocation StartLoc, 10228 SourceLocation EndLoc, Stmt *AStmt) { 10229 if (!AStmt) 10230 return StmtError(); 10231 10232 auto *CS = cast<CapturedStmt>(AStmt); 10233 // 1.2.2 OpenMP Language Terminology 10234 // Structured block - An executable statement with a single entry at the 10235 // top and a single exit at the bottom. 10236 // The point of exit cannot be a branch out of the structured block. 10237 // longjmp() and throw() must not violate the entry/exit criteria. 10238 CS->getCapturedDecl()->setNothrow(); 10239 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 10240 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10241 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10242 // 1.2.2 OpenMP Language Terminology 10243 // Structured block - An executable statement with a single entry at the 10244 // top and a single exit at the bottom. 10245 // The point of exit cannot be a branch out of the structured block. 10246 // longjmp() and throw() must not violate the entry/exit criteria. 10247 CS->getCapturedDecl()->setNothrow(); 10248 } 10249 10250 // OpenMP [2.10.3, Restrictions, p. 102] 10251 // At least one map clause must appear on the directive. 10252 if (!hasClauses(Clauses, OMPC_map)) { 10253 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10254 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 10255 return StmtError(); 10256 } 10257 10258 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10259 AStmt); 10260 } 10261 10262 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 10263 SourceLocation StartLoc, 10264 SourceLocation EndLoc, 10265 Stmt *AStmt) { 10266 if (!AStmt) 10267 return StmtError(); 10268 10269 auto *CS = cast<CapturedStmt>(AStmt); 10270 // 1.2.2 OpenMP Language Terminology 10271 // Structured block - An executable statement with a single entry at the 10272 // top and a single exit at the bottom. 10273 // The point of exit cannot be a branch out of the structured block. 10274 // longjmp() and throw() must not violate the entry/exit criteria. 10275 CS->getCapturedDecl()->setNothrow(); 10276 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 10277 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10278 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10279 // 1.2.2 OpenMP Language Terminology 10280 // Structured block - An executable statement with a single entry at the 10281 // top and a single exit at the bottom. 10282 // The point of exit cannot be a branch out of the structured block. 10283 // longjmp() and throw() must not violate the entry/exit criteria. 10284 CS->getCapturedDecl()->setNothrow(); 10285 } 10286 10287 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 10288 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 10289 return StmtError(); 10290 } 10291 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 10292 AStmt); 10293 } 10294 10295 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 10296 Stmt *AStmt, SourceLocation StartLoc, 10297 SourceLocation EndLoc) { 10298 if (!AStmt) 10299 return StmtError(); 10300 10301 auto *CS = cast<CapturedStmt>(AStmt); 10302 // 1.2.2 OpenMP Language Terminology 10303 // Structured block - An executable statement with a single entry at the 10304 // top and a single exit at the bottom. 10305 // The point of exit cannot be a branch out of the structured block. 10306 // longjmp() and throw() must not violate the entry/exit criteria. 10307 CS->getCapturedDecl()->setNothrow(); 10308 10309 setFunctionHasBranchProtectedScope(); 10310 10311 DSAStack->setParentTeamsRegionLoc(StartLoc); 10312 10313 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10314 } 10315 10316 StmtResult 10317 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 10318 SourceLocation EndLoc, 10319 OpenMPDirectiveKind CancelRegion) { 10320 if (DSAStack->isParentNowaitRegion()) { 10321 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 10322 return StmtError(); 10323 } 10324 if (DSAStack->isParentOrderedRegion()) { 10325 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 10326 return StmtError(); 10327 } 10328 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 10329 CancelRegion); 10330 } 10331 10332 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 10333 SourceLocation StartLoc, 10334 SourceLocation EndLoc, 10335 OpenMPDirectiveKind CancelRegion) { 10336 if (DSAStack->isParentNowaitRegion()) { 10337 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 10338 return StmtError(); 10339 } 10340 if (DSAStack->isParentOrderedRegion()) { 10341 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 10342 return StmtError(); 10343 } 10344 DSAStack->setParentCancelRegion(/*Cancel=*/true); 10345 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 10346 CancelRegion); 10347 } 10348 10349 static bool checkGrainsizeNumTasksClauses(Sema &S, 10350 ArrayRef<OMPClause *> Clauses) { 10351 const OMPClause *PrevClause = nullptr; 10352 bool ErrorFound = false; 10353 for (const OMPClause *C : Clauses) { 10354 if (C->getClauseKind() == OMPC_grainsize || 10355 C->getClauseKind() == OMPC_num_tasks) { 10356 if (!PrevClause) 10357 PrevClause = C; 10358 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10359 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10360 << getOpenMPClauseName(C->getClauseKind()) 10361 << getOpenMPClauseName(PrevClause->getClauseKind()); 10362 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10363 << getOpenMPClauseName(PrevClause->getClauseKind()); 10364 ErrorFound = true; 10365 } 10366 } 10367 } 10368 return ErrorFound; 10369 } 10370 10371 static bool checkReductionClauseWithNogroup(Sema &S, 10372 ArrayRef<OMPClause *> Clauses) { 10373 const OMPClause *ReductionClause = nullptr; 10374 const OMPClause *NogroupClause = nullptr; 10375 for (const OMPClause *C : Clauses) { 10376 if (C->getClauseKind() == OMPC_reduction) { 10377 ReductionClause = C; 10378 if (NogroupClause) 10379 break; 10380 continue; 10381 } 10382 if (C->getClauseKind() == OMPC_nogroup) { 10383 NogroupClause = C; 10384 if (ReductionClause) 10385 break; 10386 continue; 10387 } 10388 } 10389 if (ReductionClause && NogroupClause) { 10390 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 10391 << SourceRange(NogroupClause->getBeginLoc(), 10392 NogroupClause->getEndLoc()); 10393 return true; 10394 } 10395 return false; 10396 } 10397 10398 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 10399 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10400 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10401 if (!AStmt) 10402 return StmtError(); 10403 10404 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10405 OMPLoopDirective::HelperExprs B; 10406 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10407 // define the nested loops number. 10408 unsigned NestedLoopCount = 10409 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 10410 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10411 VarsWithImplicitDSA, B); 10412 if (NestedLoopCount == 0) 10413 return StmtError(); 10414 10415 assert((CurContext->isDependentContext() || B.builtAll()) && 10416 "omp for loop exprs were not built"); 10417 10418 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10419 // The grainsize clause and num_tasks clause are mutually exclusive and may 10420 // not appear on the same taskloop directive. 10421 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10422 return StmtError(); 10423 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10424 // If a reduction clause is present on the taskloop directive, the nogroup 10425 // clause must not be specified. 10426 if (checkReductionClauseWithNogroup(*this, Clauses)) 10427 return StmtError(); 10428 10429 setFunctionHasBranchProtectedScope(); 10430 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10431 NestedLoopCount, Clauses, AStmt, B, 10432 DSAStack->isCancelRegion()); 10433 } 10434 10435 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 10436 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10437 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10438 if (!AStmt) 10439 return StmtError(); 10440 10441 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10442 OMPLoopDirective::HelperExprs B; 10443 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10444 // define the nested loops number. 10445 unsigned NestedLoopCount = 10446 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 10447 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10448 VarsWithImplicitDSA, B); 10449 if (NestedLoopCount == 0) 10450 return StmtError(); 10451 10452 assert((CurContext->isDependentContext() || B.builtAll()) && 10453 "omp for loop exprs were not built"); 10454 10455 if (!CurContext->isDependentContext()) { 10456 // Finalize the clauses that need pre-built expressions for CodeGen. 10457 for (OMPClause *C : Clauses) { 10458 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10459 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10460 B.NumIterations, *this, CurScope, 10461 DSAStack)) 10462 return StmtError(); 10463 } 10464 } 10465 10466 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10467 // The grainsize clause and num_tasks clause are mutually exclusive and may 10468 // not appear on the same taskloop directive. 10469 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10470 return StmtError(); 10471 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10472 // If a reduction clause is present on the taskloop directive, the nogroup 10473 // clause must not be specified. 10474 if (checkReductionClauseWithNogroup(*this, Clauses)) 10475 return StmtError(); 10476 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10477 return StmtError(); 10478 10479 setFunctionHasBranchProtectedScope(); 10480 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 10481 NestedLoopCount, Clauses, AStmt, B); 10482 } 10483 10484 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 10485 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10486 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10487 if (!AStmt) 10488 return StmtError(); 10489 10490 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10491 OMPLoopDirective::HelperExprs B; 10492 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10493 // define the nested loops number. 10494 unsigned NestedLoopCount = 10495 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 10496 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10497 VarsWithImplicitDSA, B); 10498 if (NestedLoopCount == 0) 10499 return StmtError(); 10500 10501 assert((CurContext->isDependentContext() || B.builtAll()) && 10502 "omp for loop exprs were not built"); 10503 10504 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10505 // The grainsize clause and num_tasks clause are mutually exclusive and may 10506 // not appear on the same taskloop directive. 10507 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10508 return StmtError(); 10509 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10510 // If a reduction clause is present on the taskloop directive, the nogroup 10511 // clause must not be specified. 10512 if (checkReductionClauseWithNogroup(*this, Clauses)) 10513 return StmtError(); 10514 10515 setFunctionHasBranchProtectedScope(); 10516 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10517 NestedLoopCount, Clauses, AStmt, B, 10518 DSAStack->isCancelRegion()); 10519 } 10520 10521 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 10522 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10523 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10524 if (!AStmt) 10525 return StmtError(); 10526 10527 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10528 OMPLoopDirective::HelperExprs B; 10529 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10530 // define the nested loops number. 10531 unsigned NestedLoopCount = 10532 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10533 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10534 VarsWithImplicitDSA, B); 10535 if (NestedLoopCount == 0) 10536 return StmtError(); 10537 10538 assert((CurContext->isDependentContext() || B.builtAll()) && 10539 "omp for loop exprs were not built"); 10540 10541 if (!CurContext->isDependentContext()) { 10542 // Finalize the clauses that need pre-built expressions for CodeGen. 10543 for (OMPClause *C : Clauses) { 10544 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10545 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10546 B.NumIterations, *this, CurScope, 10547 DSAStack)) 10548 return StmtError(); 10549 } 10550 } 10551 10552 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10553 // The grainsize clause and num_tasks clause are mutually exclusive and may 10554 // not appear on the same taskloop directive. 10555 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10556 return StmtError(); 10557 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10558 // If a reduction clause is present on the taskloop directive, the nogroup 10559 // clause must not be specified. 10560 if (checkReductionClauseWithNogroup(*this, Clauses)) 10561 return StmtError(); 10562 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10563 return StmtError(); 10564 10565 setFunctionHasBranchProtectedScope(); 10566 return OMPMasterTaskLoopSimdDirective::Create( 10567 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10568 } 10569 10570 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 10571 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10572 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10573 if (!AStmt) 10574 return StmtError(); 10575 10576 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10577 auto *CS = cast<CapturedStmt>(AStmt); 10578 // 1.2.2 OpenMP Language Terminology 10579 // Structured block - An executable statement with a single entry at the 10580 // top and a single exit at the bottom. 10581 // The point of exit cannot be a branch out of the structured block. 10582 // longjmp() and throw() must not violate the entry/exit criteria. 10583 CS->getCapturedDecl()->setNothrow(); 10584 for (int ThisCaptureLevel = 10585 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 10586 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10587 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 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 10596 OMPLoopDirective::HelperExprs B; 10597 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10598 // define the nested loops number. 10599 unsigned NestedLoopCount = checkOpenMPLoop( 10600 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 10601 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10602 VarsWithImplicitDSA, B); 10603 if (NestedLoopCount == 0) 10604 return StmtError(); 10605 10606 assert((CurContext->isDependentContext() || B.builtAll()) && 10607 "omp for loop exprs were not built"); 10608 10609 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10610 // The grainsize clause and num_tasks clause are mutually exclusive and may 10611 // not appear on the same taskloop directive. 10612 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10613 return StmtError(); 10614 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10615 // If a reduction clause is present on the taskloop directive, the nogroup 10616 // clause must not be specified. 10617 if (checkReductionClauseWithNogroup(*this, Clauses)) 10618 return StmtError(); 10619 10620 setFunctionHasBranchProtectedScope(); 10621 return OMPParallelMasterTaskLoopDirective::Create( 10622 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10623 DSAStack->isCancelRegion()); 10624 } 10625 10626 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 10627 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10628 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10629 if (!AStmt) 10630 return StmtError(); 10631 10632 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10633 auto *CS = cast<CapturedStmt>(AStmt); 10634 // 1.2.2 OpenMP Language Terminology 10635 // Structured block - An executable statement with a single entry at the 10636 // top and a single exit at the bottom. 10637 // The point of exit cannot be a branch out of the structured block. 10638 // longjmp() and throw() must not violate the entry/exit criteria. 10639 CS->getCapturedDecl()->setNothrow(); 10640 for (int ThisCaptureLevel = 10641 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 10642 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10643 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10644 // 1.2.2 OpenMP Language Terminology 10645 // Structured block - An executable statement with a single entry at the 10646 // top and a single exit at the bottom. 10647 // The point of exit cannot be a branch out of the structured block. 10648 // longjmp() and throw() must not violate the entry/exit criteria. 10649 CS->getCapturedDecl()->setNothrow(); 10650 } 10651 10652 OMPLoopDirective::HelperExprs B; 10653 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10654 // define the nested loops number. 10655 unsigned NestedLoopCount = checkOpenMPLoop( 10656 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10657 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10658 VarsWithImplicitDSA, B); 10659 if (NestedLoopCount == 0) 10660 return StmtError(); 10661 10662 assert((CurContext->isDependentContext() || B.builtAll()) && 10663 "omp for loop exprs were not built"); 10664 10665 if (!CurContext->isDependentContext()) { 10666 // Finalize the clauses that need pre-built expressions for CodeGen. 10667 for (OMPClause *C : Clauses) { 10668 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10669 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10670 B.NumIterations, *this, CurScope, 10671 DSAStack)) 10672 return StmtError(); 10673 } 10674 } 10675 10676 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10677 // The grainsize clause and num_tasks clause are mutually exclusive and may 10678 // not appear on the same taskloop directive. 10679 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10680 return StmtError(); 10681 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10682 // If a reduction clause is present on the taskloop directive, the nogroup 10683 // clause must not be specified. 10684 if (checkReductionClauseWithNogroup(*this, Clauses)) 10685 return StmtError(); 10686 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10687 return StmtError(); 10688 10689 setFunctionHasBranchProtectedScope(); 10690 return OMPParallelMasterTaskLoopSimdDirective::Create( 10691 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10692 } 10693 10694 StmtResult Sema::ActOnOpenMPDistributeDirective( 10695 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10696 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10697 if (!AStmt) 10698 return StmtError(); 10699 10700 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10701 OMPLoopDirective::HelperExprs B; 10702 // In presence of clause 'collapse' with number of loops, it will 10703 // define the nested loops number. 10704 unsigned NestedLoopCount = 10705 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10706 nullptr /*ordered not a clause on distribute*/, AStmt, 10707 *this, *DSAStack, VarsWithImplicitDSA, B); 10708 if (NestedLoopCount == 0) 10709 return StmtError(); 10710 10711 assert((CurContext->isDependentContext() || B.builtAll()) && 10712 "omp for loop exprs were not built"); 10713 10714 setFunctionHasBranchProtectedScope(); 10715 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 10716 NestedLoopCount, Clauses, AStmt, B); 10717 } 10718 10719 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 10720 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10721 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10722 if (!AStmt) 10723 return StmtError(); 10724 10725 auto *CS = cast<CapturedStmt>(AStmt); 10726 // 1.2.2 OpenMP Language Terminology 10727 // Structured block - An executable statement with a single entry at the 10728 // top and a single exit at the bottom. 10729 // The point of exit cannot be a branch out of the structured block. 10730 // longjmp() and throw() must not violate the entry/exit criteria. 10731 CS->getCapturedDecl()->setNothrow(); 10732 for (int ThisCaptureLevel = 10733 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 10734 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10735 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10736 // 1.2.2 OpenMP Language Terminology 10737 // Structured block - An executable statement with a single entry at the 10738 // top and a single exit at the bottom. 10739 // The point of exit cannot be a branch out of the structured block. 10740 // longjmp() and throw() must not violate the entry/exit criteria. 10741 CS->getCapturedDecl()->setNothrow(); 10742 } 10743 10744 OMPLoopDirective::HelperExprs B; 10745 // In presence of clause 'collapse' with number of loops, it will 10746 // define the nested loops number. 10747 unsigned NestedLoopCount = checkOpenMPLoop( 10748 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10749 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10750 VarsWithImplicitDSA, B); 10751 if (NestedLoopCount == 0) 10752 return StmtError(); 10753 10754 assert((CurContext->isDependentContext() || B.builtAll()) && 10755 "omp for loop exprs were not built"); 10756 10757 setFunctionHasBranchProtectedScope(); 10758 return OMPDistributeParallelForDirective::Create( 10759 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10760 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10761 } 10762 10763 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10764 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10765 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10766 if (!AStmt) 10767 return StmtError(); 10768 10769 auto *CS = cast<CapturedStmt>(AStmt); 10770 // 1.2.2 OpenMP Language Terminology 10771 // Structured block - An executable statement with a single entry at the 10772 // top and a single exit at the bottom. 10773 // The point of exit cannot be a branch out of the structured block. 10774 // longjmp() and throw() must not violate the entry/exit criteria. 10775 CS->getCapturedDecl()->setNothrow(); 10776 for (int ThisCaptureLevel = 10777 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10778 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10779 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10780 // 1.2.2 OpenMP Language Terminology 10781 // Structured block - An executable statement with a single entry at the 10782 // top and a single exit at the bottom. 10783 // The point of exit cannot be a branch out of the structured block. 10784 // longjmp() and throw() must not violate the entry/exit criteria. 10785 CS->getCapturedDecl()->setNothrow(); 10786 } 10787 10788 OMPLoopDirective::HelperExprs B; 10789 // In presence of clause 'collapse' with number of loops, it will 10790 // define the nested loops number. 10791 unsigned NestedLoopCount = checkOpenMPLoop( 10792 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10793 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10794 VarsWithImplicitDSA, B); 10795 if (NestedLoopCount == 0) 10796 return StmtError(); 10797 10798 assert((CurContext->isDependentContext() || B.builtAll()) && 10799 "omp for loop exprs were not built"); 10800 10801 if (!CurContext->isDependentContext()) { 10802 // Finalize the clauses that need pre-built expressions for CodeGen. 10803 for (OMPClause *C : Clauses) { 10804 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10805 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10806 B.NumIterations, *this, CurScope, 10807 DSAStack)) 10808 return StmtError(); 10809 } 10810 } 10811 10812 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10813 return StmtError(); 10814 10815 setFunctionHasBranchProtectedScope(); 10816 return OMPDistributeParallelForSimdDirective::Create( 10817 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10818 } 10819 10820 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10821 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10822 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10823 if (!AStmt) 10824 return StmtError(); 10825 10826 auto *CS = cast<CapturedStmt>(AStmt); 10827 // 1.2.2 OpenMP Language Terminology 10828 // Structured block - An executable statement with a single entry at the 10829 // top and a single exit at the bottom. 10830 // The point of exit cannot be a branch out of the structured block. 10831 // longjmp() and throw() must not violate the entry/exit criteria. 10832 CS->getCapturedDecl()->setNothrow(); 10833 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10834 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10835 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10836 // 1.2.2 OpenMP Language Terminology 10837 // Structured block - An executable statement with a single entry at the 10838 // top and a single exit at the bottom. 10839 // The point of exit cannot be a branch out of the structured block. 10840 // longjmp() and throw() must not violate the entry/exit criteria. 10841 CS->getCapturedDecl()->setNothrow(); 10842 } 10843 10844 OMPLoopDirective::HelperExprs B; 10845 // In presence of clause 'collapse' with number of loops, it will 10846 // define the nested loops number. 10847 unsigned NestedLoopCount = 10848 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10849 nullptr /*ordered not a clause on distribute*/, CS, *this, 10850 *DSAStack, VarsWithImplicitDSA, B); 10851 if (NestedLoopCount == 0) 10852 return StmtError(); 10853 10854 assert((CurContext->isDependentContext() || B.builtAll()) && 10855 "omp for loop exprs were not built"); 10856 10857 if (!CurContext->isDependentContext()) { 10858 // Finalize the clauses that need pre-built expressions for CodeGen. 10859 for (OMPClause *C : Clauses) { 10860 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10861 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10862 B.NumIterations, *this, CurScope, 10863 DSAStack)) 10864 return StmtError(); 10865 } 10866 } 10867 10868 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10869 return StmtError(); 10870 10871 setFunctionHasBranchProtectedScope(); 10872 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10873 NestedLoopCount, Clauses, AStmt, B); 10874 } 10875 10876 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10877 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10878 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10879 if (!AStmt) 10880 return StmtError(); 10881 10882 auto *CS = cast<CapturedStmt>(AStmt); 10883 // 1.2.2 OpenMP Language Terminology 10884 // Structured block - An executable statement with a single entry at the 10885 // top and a single exit at the bottom. 10886 // The point of exit cannot be a branch out of the structured block. 10887 // longjmp() and throw() must not violate the entry/exit criteria. 10888 CS->getCapturedDecl()->setNothrow(); 10889 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10890 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10891 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10892 // 1.2.2 OpenMP Language Terminology 10893 // Structured block - An executable statement with a single entry at the 10894 // top and a single exit at the bottom. 10895 // The point of exit cannot be a branch out of the structured block. 10896 // longjmp() and throw() must not violate the entry/exit criteria. 10897 CS->getCapturedDecl()->setNothrow(); 10898 } 10899 10900 OMPLoopDirective::HelperExprs B; 10901 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10902 // define the nested loops number. 10903 unsigned NestedLoopCount = checkOpenMPLoop( 10904 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10905 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10906 VarsWithImplicitDSA, B); 10907 if (NestedLoopCount == 0) 10908 return StmtError(); 10909 10910 assert((CurContext->isDependentContext() || B.builtAll()) && 10911 "omp target parallel for simd loop exprs were not built"); 10912 10913 if (!CurContext->isDependentContext()) { 10914 // Finalize the clauses that need pre-built expressions for CodeGen. 10915 for (OMPClause *C : Clauses) { 10916 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10917 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10918 B.NumIterations, *this, CurScope, 10919 DSAStack)) 10920 return StmtError(); 10921 } 10922 } 10923 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10924 return StmtError(); 10925 10926 setFunctionHasBranchProtectedScope(); 10927 return OMPTargetParallelForSimdDirective::Create( 10928 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10929 } 10930 10931 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10932 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10933 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10934 if (!AStmt) 10935 return StmtError(); 10936 10937 auto *CS = cast<CapturedStmt>(AStmt); 10938 // 1.2.2 OpenMP Language Terminology 10939 // Structured block - An executable statement with a single entry at the 10940 // top and a single exit at the bottom. 10941 // The point of exit cannot be a branch out of the structured block. 10942 // longjmp() and throw() must not violate the entry/exit criteria. 10943 CS->getCapturedDecl()->setNothrow(); 10944 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10945 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10946 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10947 // 1.2.2 OpenMP Language Terminology 10948 // Structured block - An executable statement with a single entry at the 10949 // top and a single exit at the bottom. 10950 // The point of exit cannot be a branch out of the structured block. 10951 // longjmp() and throw() must not violate the entry/exit criteria. 10952 CS->getCapturedDecl()->setNothrow(); 10953 } 10954 10955 OMPLoopDirective::HelperExprs B; 10956 // In presence of clause 'collapse' with number of loops, it will define the 10957 // nested loops number. 10958 unsigned NestedLoopCount = 10959 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10960 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10961 VarsWithImplicitDSA, B); 10962 if (NestedLoopCount == 0) 10963 return StmtError(); 10964 10965 assert((CurContext->isDependentContext() || B.builtAll()) && 10966 "omp target simd loop exprs were not built"); 10967 10968 if (!CurContext->isDependentContext()) { 10969 // Finalize the clauses that need pre-built expressions for CodeGen. 10970 for (OMPClause *C : Clauses) { 10971 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10972 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10973 B.NumIterations, *this, CurScope, 10974 DSAStack)) 10975 return StmtError(); 10976 } 10977 } 10978 10979 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10980 return StmtError(); 10981 10982 setFunctionHasBranchProtectedScope(); 10983 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10984 NestedLoopCount, Clauses, AStmt, B); 10985 } 10986 10987 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10988 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10989 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10990 if (!AStmt) 10991 return StmtError(); 10992 10993 auto *CS = cast<CapturedStmt>(AStmt); 10994 // 1.2.2 OpenMP Language Terminology 10995 // Structured block - An executable statement with a single entry at the 10996 // top and a single exit at the bottom. 10997 // The point of exit cannot be a branch out of the structured block. 10998 // longjmp() and throw() must not violate the entry/exit criteria. 10999 CS->getCapturedDecl()->setNothrow(); 11000 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 11001 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11002 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11003 // 1.2.2 OpenMP Language Terminology 11004 // Structured block - An executable statement with a single entry at the 11005 // top and a single exit at the bottom. 11006 // The point of exit cannot be a branch out of the structured block. 11007 // longjmp() and throw() must not violate the entry/exit criteria. 11008 CS->getCapturedDecl()->setNothrow(); 11009 } 11010 11011 OMPLoopDirective::HelperExprs B; 11012 // In presence of clause 'collapse' with number of loops, it will 11013 // define the nested loops number. 11014 unsigned NestedLoopCount = 11015 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 11016 nullptr /*ordered not a clause on distribute*/, CS, *this, 11017 *DSAStack, VarsWithImplicitDSA, B); 11018 if (NestedLoopCount == 0) 11019 return StmtError(); 11020 11021 assert((CurContext->isDependentContext() || B.builtAll()) && 11022 "omp teams distribute loop exprs were not built"); 11023 11024 setFunctionHasBranchProtectedScope(); 11025 11026 DSAStack->setParentTeamsRegionLoc(StartLoc); 11027 11028 return OMPTeamsDistributeDirective::Create( 11029 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11030 } 11031 11032 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 11033 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11034 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11035 if (!AStmt) 11036 return StmtError(); 11037 11038 auto *CS = cast<CapturedStmt>(AStmt); 11039 // 1.2.2 OpenMP Language Terminology 11040 // Structured block - An executable statement with a single entry at the 11041 // top and a single exit at the bottom. 11042 // The point of exit cannot be a branch out of the structured block. 11043 // longjmp() and throw() must not violate the entry/exit criteria. 11044 CS->getCapturedDecl()->setNothrow(); 11045 for (int ThisCaptureLevel = 11046 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 11047 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11048 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11049 // 1.2.2 OpenMP Language Terminology 11050 // Structured block - An executable statement with a single entry at the 11051 // top and a single exit at the bottom. 11052 // The point of exit cannot be a branch out of the structured block. 11053 // longjmp() and throw() must not violate the entry/exit criteria. 11054 CS->getCapturedDecl()->setNothrow(); 11055 } 11056 11057 OMPLoopDirective::HelperExprs B; 11058 // In presence of clause 'collapse' with number of loops, it will 11059 // define the nested loops number. 11060 unsigned NestedLoopCount = checkOpenMPLoop( 11061 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11062 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11063 VarsWithImplicitDSA, B); 11064 11065 if (NestedLoopCount == 0) 11066 return StmtError(); 11067 11068 assert((CurContext->isDependentContext() || B.builtAll()) && 11069 "omp teams distribute simd loop exprs were not built"); 11070 11071 if (!CurContext->isDependentContext()) { 11072 // Finalize the clauses that need pre-built expressions for CodeGen. 11073 for (OMPClause *C : Clauses) { 11074 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11075 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11076 B.NumIterations, *this, CurScope, 11077 DSAStack)) 11078 return StmtError(); 11079 } 11080 } 11081 11082 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11083 return StmtError(); 11084 11085 setFunctionHasBranchProtectedScope(); 11086 11087 DSAStack->setParentTeamsRegionLoc(StartLoc); 11088 11089 return OMPTeamsDistributeSimdDirective::Create( 11090 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11091 } 11092 11093 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 11094 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11095 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11096 if (!AStmt) 11097 return StmtError(); 11098 11099 auto *CS = cast<CapturedStmt>(AStmt); 11100 // 1.2.2 OpenMP Language Terminology 11101 // Structured block - An executable statement with a single entry at the 11102 // top and a single exit at the bottom. 11103 // The point of exit cannot be a branch out of the structured block. 11104 // longjmp() and throw() must not violate the entry/exit criteria. 11105 CS->getCapturedDecl()->setNothrow(); 11106 11107 for (int ThisCaptureLevel = 11108 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 11109 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11110 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11111 // 1.2.2 OpenMP Language Terminology 11112 // Structured block - An executable statement with a single entry at the 11113 // top and a single exit at the bottom. 11114 // The point of exit cannot be a branch out of the structured block. 11115 // longjmp() and throw() must not violate the entry/exit criteria. 11116 CS->getCapturedDecl()->setNothrow(); 11117 } 11118 11119 OMPLoopDirective::HelperExprs B; 11120 // In presence of clause 'collapse' with number of loops, it will 11121 // define the nested loops number. 11122 unsigned NestedLoopCount = checkOpenMPLoop( 11123 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 11124 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11125 VarsWithImplicitDSA, B); 11126 11127 if (NestedLoopCount == 0) 11128 return StmtError(); 11129 11130 assert((CurContext->isDependentContext() || B.builtAll()) && 11131 "omp for loop exprs were not built"); 11132 11133 if (!CurContext->isDependentContext()) { 11134 // Finalize the clauses that need pre-built expressions for CodeGen. 11135 for (OMPClause *C : Clauses) { 11136 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11137 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11138 B.NumIterations, *this, CurScope, 11139 DSAStack)) 11140 return StmtError(); 11141 } 11142 } 11143 11144 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11145 return StmtError(); 11146 11147 setFunctionHasBranchProtectedScope(); 11148 11149 DSAStack->setParentTeamsRegionLoc(StartLoc); 11150 11151 return OMPTeamsDistributeParallelForSimdDirective::Create( 11152 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11153 } 11154 11155 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 11156 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11157 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11158 if (!AStmt) 11159 return StmtError(); 11160 11161 auto *CS = cast<CapturedStmt>(AStmt); 11162 // 1.2.2 OpenMP Language Terminology 11163 // Structured block - An executable statement with a single entry at the 11164 // top and a single exit at the bottom. 11165 // The point of exit cannot be a branch out of the structured block. 11166 // longjmp() and throw() must not violate the entry/exit criteria. 11167 CS->getCapturedDecl()->setNothrow(); 11168 11169 for (int ThisCaptureLevel = 11170 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 11171 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11172 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11173 // 1.2.2 OpenMP Language Terminology 11174 // Structured block - An executable statement with a single entry at the 11175 // top and a single exit at the bottom. 11176 // The point of exit cannot be a branch out of the structured block. 11177 // longjmp() and throw() must not violate the entry/exit criteria. 11178 CS->getCapturedDecl()->setNothrow(); 11179 } 11180 11181 OMPLoopDirective::HelperExprs B; 11182 // In presence of clause 'collapse' with number of loops, it will 11183 // define the nested loops number. 11184 unsigned NestedLoopCount = checkOpenMPLoop( 11185 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11186 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11187 VarsWithImplicitDSA, B); 11188 11189 if (NestedLoopCount == 0) 11190 return StmtError(); 11191 11192 assert((CurContext->isDependentContext() || B.builtAll()) && 11193 "omp for loop exprs were not built"); 11194 11195 setFunctionHasBranchProtectedScope(); 11196 11197 DSAStack->setParentTeamsRegionLoc(StartLoc); 11198 11199 return OMPTeamsDistributeParallelForDirective::Create( 11200 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11201 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11202 } 11203 11204 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 11205 Stmt *AStmt, 11206 SourceLocation StartLoc, 11207 SourceLocation EndLoc) { 11208 if (!AStmt) 11209 return StmtError(); 11210 11211 auto *CS = cast<CapturedStmt>(AStmt); 11212 // 1.2.2 OpenMP Language Terminology 11213 // Structured block - An executable statement with a single entry at the 11214 // top and a single exit at the bottom. 11215 // The point of exit cannot be a branch out of the structured block. 11216 // longjmp() and throw() must not violate the entry/exit criteria. 11217 CS->getCapturedDecl()->setNothrow(); 11218 11219 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 11220 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11221 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11222 // 1.2.2 OpenMP Language Terminology 11223 // Structured block - An executable statement with a single entry at the 11224 // top and a single exit at the bottom. 11225 // The point of exit cannot be a branch out of the structured block. 11226 // longjmp() and throw() must not violate the entry/exit criteria. 11227 CS->getCapturedDecl()->setNothrow(); 11228 } 11229 setFunctionHasBranchProtectedScope(); 11230 11231 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 11232 AStmt); 11233 } 11234 11235 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 11236 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11237 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11238 if (!AStmt) 11239 return StmtError(); 11240 11241 auto *CS = cast<CapturedStmt>(AStmt); 11242 // 1.2.2 OpenMP Language Terminology 11243 // Structured block - An executable statement with a single entry at the 11244 // top and a single exit at the bottom. 11245 // The point of exit cannot be a branch out of the structured block. 11246 // longjmp() and throw() must not violate the entry/exit criteria. 11247 CS->getCapturedDecl()->setNothrow(); 11248 for (int ThisCaptureLevel = 11249 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 11250 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11251 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11252 // 1.2.2 OpenMP Language Terminology 11253 // Structured block - An executable statement with a single entry at the 11254 // top and a single exit at the bottom. 11255 // The point of exit cannot be a branch out of the structured block. 11256 // longjmp() and throw() must not violate the entry/exit criteria. 11257 CS->getCapturedDecl()->setNothrow(); 11258 } 11259 11260 OMPLoopDirective::HelperExprs B; 11261 // In presence of clause 'collapse' with number of loops, it will 11262 // define the nested loops number. 11263 unsigned NestedLoopCount = checkOpenMPLoop( 11264 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 11265 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11266 VarsWithImplicitDSA, B); 11267 if (NestedLoopCount == 0) 11268 return StmtError(); 11269 11270 assert((CurContext->isDependentContext() || B.builtAll()) && 11271 "omp target teams distribute loop exprs were not built"); 11272 11273 setFunctionHasBranchProtectedScope(); 11274 return OMPTargetTeamsDistributeDirective::Create( 11275 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11276 } 11277 11278 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 11279 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11280 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11281 if (!AStmt) 11282 return StmtError(); 11283 11284 auto *CS = cast<CapturedStmt>(AStmt); 11285 // 1.2.2 OpenMP Language Terminology 11286 // Structured block - An executable statement with a single entry at the 11287 // top and a single exit at the bottom. 11288 // The point of exit cannot be a branch out of the structured block. 11289 // longjmp() and throw() must not violate the entry/exit criteria. 11290 CS->getCapturedDecl()->setNothrow(); 11291 for (int ThisCaptureLevel = 11292 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 11293 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11294 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11295 // 1.2.2 OpenMP Language Terminology 11296 // Structured block - An executable statement with a single entry at the 11297 // top and a single exit at the bottom. 11298 // The point of exit cannot be a branch out of the structured block. 11299 // longjmp() and throw() must not violate the entry/exit criteria. 11300 CS->getCapturedDecl()->setNothrow(); 11301 } 11302 11303 OMPLoopDirective::HelperExprs B; 11304 // In presence of clause 'collapse' with number of loops, it will 11305 // define the nested loops number. 11306 unsigned NestedLoopCount = checkOpenMPLoop( 11307 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11308 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11309 VarsWithImplicitDSA, B); 11310 if (NestedLoopCount == 0) 11311 return StmtError(); 11312 11313 assert((CurContext->isDependentContext() || B.builtAll()) && 11314 "omp target teams distribute parallel for loop exprs were not built"); 11315 11316 if (!CurContext->isDependentContext()) { 11317 // Finalize the clauses that need pre-built expressions for CodeGen. 11318 for (OMPClause *C : Clauses) { 11319 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11320 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11321 B.NumIterations, *this, CurScope, 11322 DSAStack)) 11323 return StmtError(); 11324 } 11325 } 11326 11327 setFunctionHasBranchProtectedScope(); 11328 return OMPTargetTeamsDistributeParallelForDirective::Create( 11329 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11330 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11331 } 11332 11333 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 11334 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11335 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11336 if (!AStmt) 11337 return StmtError(); 11338 11339 auto *CS = cast<CapturedStmt>(AStmt); 11340 // 1.2.2 OpenMP Language Terminology 11341 // Structured block - An executable statement with a single entry at the 11342 // top and a single exit at the bottom. 11343 // The point of exit cannot be a branch out of the structured block. 11344 // longjmp() and throw() must not violate the entry/exit criteria. 11345 CS->getCapturedDecl()->setNothrow(); 11346 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 11347 OMPD_target_teams_distribute_parallel_for_simd); 11348 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11349 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11350 // 1.2.2 OpenMP Language Terminology 11351 // Structured block - An executable statement with a single entry at the 11352 // top and a single exit at the bottom. 11353 // The point of exit cannot be a branch out of the structured block. 11354 // longjmp() and throw() must not violate the entry/exit criteria. 11355 CS->getCapturedDecl()->setNothrow(); 11356 } 11357 11358 OMPLoopDirective::HelperExprs B; 11359 // In presence of clause 'collapse' with number of loops, it will 11360 // define the nested loops number. 11361 unsigned NestedLoopCount = 11362 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 11363 getCollapseNumberExpr(Clauses), 11364 nullptr /*ordered not a clause on distribute*/, CS, *this, 11365 *DSAStack, VarsWithImplicitDSA, B); 11366 if (NestedLoopCount == 0) 11367 return StmtError(); 11368 11369 assert((CurContext->isDependentContext() || B.builtAll()) && 11370 "omp target teams distribute parallel for simd loop exprs were not " 11371 "built"); 11372 11373 if (!CurContext->isDependentContext()) { 11374 // Finalize the clauses that need pre-built expressions for CodeGen. 11375 for (OMPClause *C : Clauses) { 11376 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11377 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11378 B.NumIterations, *this, CurScope, 11379 DSAStack)) 11380 return StmtError(); 11381 } 11382 } 11383 11384 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11385 return StmtError(); 11386 11387 setFunctionHasBranchProtectedScope(); 11388 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 11389 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11390 } 11391 11392 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 11393 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11394 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11395 if (!AStmt) 11396 return StmtError(); 11397 11398 auto *CS = cast<CapturedStmt>(AStmt); 11399 // 1.2.2 OpenMP Language Terminology 11400 // Structured block - An executable statement with a single entry at the 11401 // top and a single exit at the bottom. 11402 // The point of exit cannot be a branch out of the structured block. 11403 // longjmp() and throw() must not violate the entry/exit criteria. 11404 CS->getCapturedDecl()->setNothrow(); 11405 for (int ThisCaptureLevel = 11406 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 11407 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11408 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11409 // 1.2.2 OpenMP Language Terminology 11410 // Structured block - An executable statement with a single entry at the 11411 // top and a single exit at the bottom. 11412 // The point of exit cannot be a branch out of the structured block. 11413 // longjmp() and throw() must not violate the entry/exit criteria. 11414 CS->getCapturedDecl()->setNothrow(); 11415 } 11416 11417 OMPLoopDirective::HelperExprs B; 11418 // In presence of clause 'collapse' with number of loops, it will 11419 // define the nested loops number. 11420 unsigned NestedLoopCount = checkOpenMPLoop( 11421 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11422 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11423 VarsWithImplicitDSA, B); 11424 if (NestedLoopCount == 0) 11425 return StmtError(); 11426 11427 assert((CurContext->isDependentContext() || B.builtAll()) && 11428 "omp target teams distribute simd loop exprs were not built"); 11429 11430 if (!CurContext->isDependentContext()) { 11431 // Finalize the clauses that need pre-built expressions for CodeGen. 11432 for (OMPClause *C : Clauses) { 11433 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11434 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11435 B.NumIterations, *this, CurScope, 11436 DSAStack)) 11437 return StmtError(); 11438 } 11439 } 11440 11441 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11442 return StmtError(); 11443 11444 setFunctionHasBranchProtectedScope(); 11445 return OMPTargetTeamsDistributeSimdDirective::Create( 11446 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11447 } 11448 11449 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 11450 SourceLocation StartLoc, 11451 SourceLocation LParenLoc, 11452 SourceLocation EndLoc) { 11453 OMPClause *Res = nullptr; 11454 switch (Kind) { 11455 case OMPC_final: 11456 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 11457 break; 11458 case OMPC_num_threads: 11459 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 11460 break; 11461 case OMPC_safelen: 11462 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 11463 break; 11464 case OMPC_simdlen: 11465 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 11466 break; 11467 case OMPC_allocator: 11468 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 11469 break; 11470 case OMPC_collapse: 11471 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 11472 break; 11473 case OMPC_ordered: 11474 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 11475 break; 11476 case OMPC_num_teams: 11477 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 11478 break; 11479 case OMPC_thread_limit: 11480 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 11481 break; 11482 case OMPC_priority: 11483 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 11484 break; 11485 case OMPC_grainsize: 11486 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 11487 break; 11488 case OMPC_num_tasks: 11489 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 11490 break; 11491 case OMPC_hint: 11492 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 11493 break; 11494 case OMPC_depobj: 11495 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 11496 break; 11497 case OMPC_detach: 11498 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 11499 break; 11500 case OMPC_device: 11501 case OMPC_if: 11502 case OMPC_default: 11503 case OMPC_proc_bind: 11504 case OMPC_schedule: 11505 case OMPC_private: 11506 case OMPC_firstprivate: 11507 case OMPC_lastprivate: 11508 case OMPC_shared: 11509 case OMPC_reduction: 11510 case OMPC_task_reduction: 11511 case OMPC_in_reduction: 11512 case OMPC_linear: 11513 case OMPC_aligned: 11514 case OMPC_copyin: 11515 case OMPC_copyprivate: 11516 case OMPC_nowait: 11517 case OMPC_untied: 11518 case OMPC_mergeable: 11519 case OMPC_threadprivate: 11520 case OMPC_allocate: 11521 case OMPC_flush: 11522 case OMPC_read: 11523 case OMPC_write: 11524 case OMPC_update: 11525 case OMPC_capture: 11526 case OMPC_seq_cst: 11527 case OMPC_acq_rel: 11528 case OMPC_acquire: 11529 case OMPC_release: 11530 case OMPC_relaxed: 11531 case OMPC_depend: 11532 case OMPC_threads: 11533 case OMPC_simd: 11534 case OMPC_map: 11535 case OMPC_nogroup: 11536 case OMPC_dist_schedule: 11537 case OMPC_defaultmap: 11538 case OMPC_unknown: 11539 case OMPC_uniform: 11540 case OMPC_to: 11541 case OMPC_from: 11542 case OMPC_use_device_ptr: 11543 case OMPC_use_device_addr: 11544 case OMPC_is_device_ptr: 11545 case OMPC_unified_address: 11546 case OMPC_unified_shared_memory: 11547 case OMPC_reverse_offload: 11548 case OMPC_dynamic_allocators: 11549 case OMPC_atomic_default_mem_order: 11550 case OMPC_device_type: 11551 case OMPC_match: 11552 case OMPC_nontemporal: 11553 case OMPC_order: 11554 case OMPC_destroy: 11555 case OMPC_inclusive: 11556 case OMPC_exclusive: 11557 case OMPC_uses_allocators: 11558 case OMPC_affinity: 11559 llvm_unreachable("Clause is not allowed."); 11560 } 11561 return Res; 11562 } 11563 11564 // An OpenMP directive such as 'target parallel' has two captured regions: 11565 // for the 'target' and 'parallel' respectively. This function returns 11566 // the region in which to capture expressions associated with a clause. 11567 // A return value of OMPD_unknown signifies that the expression should not 11568 // be captured. 11569 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 11570 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 11571 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 11572 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11573 switch (CKind) { 11574 case OMPC_if: 11575 switch (DKind) { 11576 case OMPD_target_parallel_for_simd: 11577 if (OpenMPVersion >= 50 && 11578 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11579 CaptureRegion = OMPD_parallel; 11580 break; 11581 } 11582 LLVM_FALLTHROUGH; 11583 case OMPD_target_parallel: 11584 case OMPD_target_parallel_for: 11585 // If this clause applies to the nested 'parallel' region, capture within 11586 // the 'target' region, otherwise do not capture. 11587 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11588 CaptureRegion = OMPD_target; 11589 break; 11590 case OMPD_target_teams_distribute_parallel_for_simd: 11591 if (OpenMPVersion >= 50 && 11592 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11593 CaptureRegion = OMPD_parallel; 11594 break; 11595 } 11596 LLVM_FALLTHROUGH; 11597 case OMPD_target_teams_distribute_parallel_for: 11598 // If this clause applies to the nested 'parallel' region, capture within 11599 // the 'teams' region, otherwise do not capture. 11600 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11601 CaptureRegion = OMPD_teams; 11602 break; 11603 case OMPD_teams_distribute_parallel_for_simd: 11604 if (OpenMPVersion >= 50 && 11605 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11606 CaptureRegion = OMPD_parallel; 11607 break; 11608 } 11609 LLVM_FALLTHROUGH; 11610 case OMPD_teams_distribute_parallel_for: 11611 CaptureRegion = OMPD_teams; 11612 break; 11613 case OMPD_target_update: 11614 case OMPD_target_enter_data: 11615 case OMPD_target_exit_data: 11616 CaptureRegion = OMPD_task; 11617 break; 11618 case OMPD_parallel_master_taskloop: 11619 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 11620 CaptureRegion = OMPD_parallel; 11621 break; 11622 case OMPD_parallel_master_taskloop_simd: 11623 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 11624 NameModifier == OMPD_taskloop) { 11625 CaptureRegion = OMPD_parallel; 11626 break; 11627 } 11628 if (OpenMPVersion <= 45) 11629 break; 11630 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11631 CaptureRegion = OMPD_taskloop; 11632 break; 11633 case OMPD_parallel_for_simd: 11634 if (OpenMPVersion <= 45) 11635 break; 11636 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11637 CaptureRegion = OMPD_parallel; 11638 break; 11639 case OMPD_taskloop_simd: 11640 case OMPD_master_taskloop_simd: 11641 if (OpenMPVersion <= 45) 11642 break; 11643 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11644 CaptureRegion = OMPD_taskloop; 11645 break; 11646 case OMPD_distribute_parallel_for_simd: 11647 if (OpenMPVersion <= 45) 11648 break; 11649 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11650 CaptureRegion = OMPD_parallel; 11651 break; 11652 case OMPD_target_simd: 11653 if (OpenMPVersion >= 50 && 11654 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11655 CaptureRegion = OMPD_target; 11656 break; 11657 case OMPD_teams_distribute_simd: 11658 case OMPD_target_teams_distribute_simd: 11659 if (OpenMPVersion >= 50 && 11660 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11661 CaptureRegion = OMPD_teams; 11662 break; 11663 case OMPD_cancel: 11664 case OMPD_parallel: 11665 case OMPD_parallel_master: 11666 case OMPD_parallel_sections: 11667 case OMPD_parallel_for: 11668 case OMPD_target: 11669 case OMPD_target_teams: 11670 case OMPD_target_teams_distribute: 11671 case OMPD_distribute_parallel_for: 11672 case OMPD_task: 11673 case OMPD_taskloop: 11674 case OMPD_master_taskloop: 11675 case OMPD_target_data: 11676 case OMPD_simd: 11677 case OMPD_for_simd: 11678 case OMPD_distribute_simd: 11679 // Do not capture if-clause expressions. 11680 break; 11681 case OMPD_threadprivate: 11682 case OMPD_allocate: 11683 case OMPD_taskyield: 11684 case OMPD_barrier: 11685 case OMPD_taskwait: 11686 case OMPD_cancellation_point: 11687 case OMPD_flush: 11688 case OMPD_depobj: 11689 case OMPD_scan: 11690 case OMPD_declare_reduction: 11691 case OMPD_declare_mapper: 11692 case OMPD_declare_simd: 11693 case OMPD_declare_variant: 11694 case OMPD_begin_declare_variant: 11695 case OMPD_end_declare_variant: 11696 case OMPD_declare_target: 11697 case OMPD_end_declare_target: 11698 case OMPD_teams: 11699 case OMPD_for: 11700 case OMPD_sections: 11701 case OMPD_section: 11702 case OMPD_single: 11703 case OMPD_master: 11704 case OMPD_critical: 11705 case OMPD_taskgroup: 11706 case OMPD_distribute: 11707 case OMPD_ordered: 11708 case OMPD_atomic: 11709 case OMPD_teams_distribute: 11710 case OMPD_requires: 11711 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 11712 case OMPD_unknown: 11713 llvm_unreachable("Unknown OpenMP directive"); 11714 } 11715 break; 11716 case OMPC_num_threads: 11717 switch (DKind) { 11718 case OMPD_target_parallel: 11719 case OMPD_target_parallel_for: 11720 case OMPD_target_parallel_for_simd: 11721 CaptureRegion = OMPD_target; 11722 break; 11723 case OMPD_teams_distribute_parallel_for: 11724 case OMPD_teams_distribute_parallel_for_simd: 11725 case OMPD_target_teams_distribute_parallel_for: 11726 case OMPD_target_teams_distribute_parallel_for_simd: 11727 CaptureRegion = OMPD_teams; 11728 break; 11729 case OMPD_parallel: 11730 case OMPD_parallel_master: 11731 case OMPD_parallel_sections: 11732 case OMPD_parallel_for: 11733 case OMPD_parallel_for_simd: 11734 case OMPD_distribute_parallel_for: 11735 case OMPD_distribute_parallel_for_simd: 11736 case OMPD_parallel_master_taskloop: 11737 case OMPD_parallel_master_taskloop_simd: 11738 // Do not capture num_threads-clause expressions. 11739 break; 11740 case OMPD_target_data: 11741 case OMPD_target_enter_data: 11742 case OMPD_target_exit_data: 11743 case OMPD_target_update: 11744 case OMPD_target: 11745 case OMPD_target_simd: 11746 case OMPD_target_teams: 11747 case OMPD_target_teams_distribute: 11748 case OMPD_target_teams_distribute_simd: 11749 case OMPD_cancel: 11750 case OMPD_task: 11751 case OMPD_taskloop: 11752 case OMPD_taskloop_simd: 11753 case OMPD_master_taskloop: 11754 case OMPD_master_taskloop_simd: 11755 case OMPD_threadprivate: 11756 case OMPD_allocate: 11757 case OMPD_taskyield: 11758 case OMPD_barrier: 11759 case OMPD_taskwait: 11760 case OMPD_cancellation_point: 11761 case OMPD_flush: 11762 case OMPD_depobj: 11763 case OMPD_scan: 11764 case OMPD_declare_reduction: 11765 case OMPD_declare_mapper: 11766 case OMPD_declare_simd: 11767 case OMPD_declare_variant: 11768 case OMPD_begin_declare_variant: 11769 case OMPD_end_declare_variant: 11770 case OMPD_declare_target: 11771 case OMPD_end_declare_target: 11772 case OMPD_teams: 11773 case OMPD_simd: 11774 case OMPD_for: 11775 case OMPD_for_simd: 11776 case OMPD_sections: 11777 case OMPD_section: 11778 case OMPD_single: 11779 case OMPD_master: 11780 case OMPD_critical: 11781 case OMPD_taskgroup: 11782 case OMPD_distribute: 11783 case OMPD_ordered: 11784 case OMPD_atomic: 11785 case OMPD_distribute_simd: 11786 case OMPD_teams_distribute: 11787 case OMPD_teams_distribute_simd: 11788 case OMPD_requires: 11789 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11790 case OMPD_unknown: 11791 llvm_unreachable("Unknown OpenMP directive"); 11792 } 11793 break; 11794 case OMPC_num_teams: 11795 switch (DKind) { 11796 case OMPD_target_teams: 11797 case OMPD_target_teams_distribute: 11798 case OMPD_target_teams_distribute_simd: 11799 case OMPD_target_teams_distribute_parallel_for: 11800 case OMPD_target_teams_distribute_parallel_for_simd: 11801 CaptureRegion = OMPD_target; 11802 break; 11803 case OMPD_teams_distribute_parallel_for: 11804 case OMPD_teams_distribute_parallel_for_simd: 11805 case OMPD_teams: 11806 case OMPD_teams_distribute: 11807 case OMPD_teams_distribute_simd: 11808 // Do not capture num_teams-clause expressions. 11809 break; 11810 case OMPD_distribute_parallel_for: 11811 case OMPD_distribute_parallel_for_simd: 11812 case OMPD_task: 11813 case OMPD_taskloop: 11814 case OMPD_taskloop_simd: 11815 case OMPD_master_taskloop: 11816 case OMPD_master_taskloop_simd: 11817 case OMPD_parallel_master_taskloop: 11818 case OMPD_parallel_master_taskloop_simd: 11819 case OMPD_target_data: 11820 case OMPD_target_enter_data: 11821 case OMPD_target_exit_data: 11822 case OMPD_target_update: 11823 case OMPD_cancel: 11824 case OMPD_parallel: 11825 case OMPD_parallel_master: 11826 case OMPD_parallel_sections: 11827 case OMPD_parallel_for: 11828 case OMPD_parallel_for_simd: 11829 case OMPD_target: 11830 case OMPD_target_simd: 11831 case OMPD_target_parallel: 11832 case OMPD_target_parallel_for: 11833 case OMPD_target_parallel_for_simd: 11834 case OMPD_threadprivate: 11835 case OMPD_allocate: 11836 case OMPD_taskyield: 11837 case OMPD_barrier: 11838 case OMPD_taskwait: 11839 case OMPD_cancellation_point: 11840 case OMPD_flush: 11841 case OMPD_depobj: 11842 case OMPD_scan: 11843 case OMPD_declare_reduction: 11844 case OMPD_declare_mapper: 11845 case OMPD_declare_simd: 11846 case OMPD_declare_variant: 11847 case OMPD_begin_declare_variant: 11848 case OMPD_end_declare_variant: 11849 case OMPD_declare_target: 11850 case OMPD_end_declare_target: 11851 case OMPD_simd: 11852 case OMPD_for: 11853 case OMPD_for_simd: 11854 case OMPD_sections: 11855 case OMPD_section: 11856 case OMPD_single: 11857 case OMPD_master: 11858 case OMPD_critical: 11859 case OMPD_taskgroup: 11860 case OMPD_distribute: 11861 case OMPD_ordered: 11862 case OMPD_atomic: 11863 case OMPD_distribute_simd: 11864 case OMPD_requires: 11865 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11866 case OMPD_unknown: 11867 llvm_unreachable("Unknown OpenMP directive"); 11868 } 11869 break; 11870 case OMPC_thread_limit: 11871 switch (DKind) { 11872 case OMPD_target_teams: 11873 case OMPD_target_teams_distribute: 11874 case OMPD_target_teams_distribute_simd: 11875 case OMPD_target_teams_distribute_parallel_for: 11876 case OMPD_target_teams_distribute_parallel_for_simd: 11877 CaptureRegion = OMPD_target; 11878 break; 11879 case OMPD_teams_distribute_parallel_for: 11880 case OMPD_teams_distribute_parallel_for_simd: 11881 case OMPD_teams: 11882 case OMPD_teams_distribute: 11883 case OMPD_teams_distribute_simd: 11884 // Do not capture thread_limit-clause expressions. 11885 break; 11886 case OMPD_distribute_parallel_for: 11887 case OMPD_distribute_parallel_for_simd: 11888 case OMPD_task: 11889 case OMPD_taskloop: 11890 case OMPD_taskloop_simd: 11891 case OMPD_master_taskloop: 11892 case OMPD_master_taskloop_simd: 11893 case OMPD_parallel_master_taskloop: 11894 case OMPD_parallel_master_taskloop_simd: 11895 case OMPD_target_data: 11896 case OMPD_target_enter_data: 11897 case OMPD_target_exit_data: 11898 case OMPD_target_update: 11899 case OMPD_cancel: 11900 case OMPD_parallel: 11901 case OMPD_parallel_master: 11902 case OMPD_parallel_sections: 11903 case OMPD_parallel_for: 11904 case OMPD_parallel_for_simd: 11905 case OMPD_target: 11906 case OMPD_target_simd: 11907 case OMPD_target_parallel: 11908 case OMPD_target_parallel_for: 11909 case OMPD_target_parallel_for_simd: 11910 case OMPD_threadprivate: 11911 case OMPD_allocate: 11912 case OMPD_taskyield: 11913 case OMPD_barrier: 11914 case OMPD_taskwait: 11915 case OMPD_cancellation_point: 11916 case OMPD_flush: 11917 case OMPD_depobj: 11918 case OMPD_scan: 11919 case OMPD_declare_reduction: 11920 case OMPD_declare_mapper: 11921 case OMPD_declare_simd: 11922 case OMPD_declare_variant: 11923 case OMPD_begin_declare_variant: 11924 case OMPD_end_declare_variant: 11925 case OMPD_declare_target: 11926 case OMPD_end_declare_target: 11927 case OMPD_simd: 11928 case OMPD_for: 11929 case OMPD_for_simd: 11930 case OMPD_sections: 11931 case OMPD_section: 11932 case OMPD_single: 11933 case OMPD_master: 11934 case OMPD_critical: 11935 case OMPD_taskgroup: 11936 case OMPD_distribute: 11937 case OMPD_ordered: 11938 case OMPD_atomic: 11939 case OMPD_distribute_simd: 11940 case OMPD_requires: 11941 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11942 case OMPD_unknown: 11943 llvm_unreachable("Unknown OpenMP directive"); 11944 } 11945 break; 11946 case OMPC_schedule: 11947 switch (DKind) { 11948 case OMPD_parallel_for: 11949 case OMPD_parallel_for_simd: 11950 case OMPD_distribute_parallel_for: 11951 case OMPD_distribute_parallel_for_simd: 11952 case OMPD_teams_distribute_parallel_for: 11953 case OMPD_teams_distribute_parallel_for_simd: 11954 case OMPD_target_parallel_for: 11955 case OMPD_target_parallel_for_simd: 11956 case OMPD_target_teams_distribute_parallel_for: 11957 case OMPD_target_teams_distribute_parallel_for_simd: 11958 CaptureRegion = OMPD_parallel; 11959 break; 11960 case OMPD_for: 11961 case OMPD_for_simd: 11962 // Do not capture schedule-clause expressions. 11963 break; 11964 case OMPD_task: 11965 case OMPD_taskloop: 11966 case OMPD_taskloop_simd: 11967 case OMPD_master_taskloop: 11968 case OMPD_master_taskloop_simd: 11969 case OMPD_parallel_master_taskloop: 11970 case OMPD_parallel_master_taskloop_simd: 11971 case OMPD_target_data: 11972 case OMPD_target_enter_data: 11973 case OMPD_target_exit_data: 11974 case OMPD_target_update: 11975 case OMPD_teams: 11976 case OMPD_teams_distribute: 11977 case OMPD_teams_distribute_simd: 11978 case OMPD_target_teams_distribute: 11979 case OMPD_target_teams_distribute_simd: 11980 case OMPD_target: 11981 case OMPD_target_simd: 11982 case OMPD_target_parallel: 11983 case OMPD_cancel: 11984 case OMPD_parallel: 11985 case OMPD_parallel_master: 11986 case OMPD_parallel_sections: 11987 case OMPD_threadprivate: 11988 case OMPD_allocate: 11989 case OMPD_taskyield: 11990 case OMPD_barrier: 11991 case OMPD_taskwait: 11992 case OMPD_cancellation_point: 11993 case OMPD_flush: 11994 case OMPD_depobj: 11995 case OMPD_scan: 11996 case OMPD_declare_reduction: 11997 case OMPD_declare_mapper: 11998 case OMPD_declare_simd: 11999 case OMPD_declare_variant: 12000 case OMPD_begin_declare_variant: 12001 case OMPD_end_declare_variant: 12002 case OMPD_declare_target: 12003 case OMPD_end_declare_target: 12004 case OMPD_simd: 12005 case OMPD_sections: 12006 case OMPD_section: 12007 case OMPD_single: 12008 case OMPD_master: 12009 case OMPD_critical: 12010 case OMPD_taskgroup: 12011 case OMPD_distribute: 12012 case OMPD_ordered: 12013 case OMPD_atomic: 12014 case OMPD_distribute_simd: 12015 case OMPD_target_teams: 12016 case OMPD_requires: 12017 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 12018 case OMPD_unknown: 12019 llvm_unreachable("Unknown OpenMP directive"); 12020 } 12021 break; 12022 case OMPC_dist_schedule: 12023 switch (DKind) { 12024 case OMPD_teams_distribute_parallel_for: 12025 case OMPD_teams_distribute_parallel_for_simd: 12026 case OMPD_teams_distribute: 12027 case OMPD_teams_distribute_simd: 12028 case OMPD_target_teams_distribute_parallel_for: 12029 case OMPD_target_teams_distribute_parallel_for_simd: 12030 case OMPD_target_teams_distribute: 12031 case OMPD_target_teams_distribute_simd: 12032 CaptureRegion = OMPD_teams; 12033 break; 12034 case OMPD_distribute_parallel_for: 12035 case OMPD_distribute_parallel_for_simd: 12036 case OMPD_distribute: 12037 case OMPD_distribute_simd: 12038 // Do not capture thread_limit-clause expressions. 12039 break; 12040 case OMPD_parallel_for: 12041 case OMPD_parallel_for_simd: 12042 case OMPD_target_parallel_for_simd: 12043 case OMPD_target_parallel_for: 12044 case OMPD_task: 12045 case OMPD_taskloop: 12046 case OMPD_taskloop_simd: 12047 case OMPD_master_taskloop: 12048 case OMPD_master_taskloop_simd: 12049 case OMPD_parallel_master_taskloop: 12050 case OMPD_parallel_master_taskloop_simd: 12051 case OMPD_target_data: 12052 case OMPD_target_enter_data: 12053 case OMPD_target_exit_data: 12054 case OMPD_target_update: 12055 case OMPD_teams: 12056 case OMPD_target: 12057 case OMPD_target_simd: 12058 case OMPD_target_parallel: 12059 case OMPD_cancel: 12060 case OMPD_parallel: 12061 case OMPD_parallel_master: 12062 case OMPD_parallel_sections: 12063 case OMPD_threadprivate: 12064 case OMPD_allocate: 12065 case OMPD_taskyield: 12066 case OMPD_barrier: 12067 case OMPD_taskwait: 12068 case OMPD_cancellation_point: 12069 case OMPD_flush: 12070 case OMPD_depobj: 12071 case OMPD_scan: 12072 case OMPD_declare_reduction: 12073 case OMPD_declare_mapper: 12074 case OMPD_declare_simd: 12075 case OMPD_declare_variant: 12076 case OMPD_begin_declare_variant: 12077 case OMPD_end_declare_variant: 12078 case OMPD_declare_target: 12079 case OMPD_end_declare_target: 12080 case OMPD_simd: 12081 case OMPD_for: 12082 case OMPD_for_simd: 12083 case OMPD_sections: 12084 case OMPD_section: 12085 case OMPD_single: 12086 case OMPD_master: 12087 case OMPD_critical: 12088 case OMPD_taskgroup: 12089 case OMPD_ordered: 12090 case OMPD_atomic: 12091 case OMPD_target_teams: 12092 case OMPD_requires: 12093 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 12094 case OMPD_unknown: 12095 llvm_unreachable("Unknown OpenMP directive"); 12096 } 12097 break; 12098 case OMPC_device: 12099 switch (DKind) { 12100 case OMPD_target_update: 12101 case OMPD_target_enter_data: 12102 case OMPD_target_exit_data: 12103 case OMPD_target: 12104 case OMPD_target_simd: 12105 case OMPD_target_teams: 12106 case OMPD_target_parallel: 12107 case OMPD_target_teams_distribute: 12108 case OMPD_target_teams_distribute_simd: 12109 case OMPD_target_parallel_for: 12110 case OMPD_target_parallel_for_simd: 12111 case OMPD_target_teams_distribute_parallel_for: 12112 case OMPD_target_teams_distribute_parallel_for_simd: 12113 CaptureRegion = OMPD_task; 12114 break; 12115 case OMPD_target_data: 12116 // Do not capture device-clause expressions. 12117 break; 12118 case OMPD_teams_distribute_parallel_for: 12119 case OMPD_teams_distribute_parallel_for_simd: 12120 case OMPD_teams: 12121 case OMPD_teams_distribute: 12122 case OMPD_teams_distribute_simd: 12123 case OMPD_distribute_parallel_for: 12124 case OMPD_distribute_parallel_for_simd: 12125 case OMPD_task: 12126 case OMPD_taskloop: 12127 case OMPD_taskloop_simd: 12128 case OMPD_master_taskloop: 12129 case OMPD_master_taskloop_simd: 12130 case OMPD_parallel_master_taskloop: 12131 case OMPD_parallel_master_taskloop_simd: 12132 case OMPD_cancel: 12133 case OMPD_parallel: 12134 case OMPD_parallel_master: 12135 case OMPD_parallel_sections: 12136 case OMPD_parallel_for: 12137 case OMPD_parallel_for_simd: 12138 case OMPD_threadprivate: 12139 case OMPD_allocate: 12140 case OMPD_taskyield: 12141 case OMPD_barrier: 12142 case OMPD_taskwait: 12143 case OMPD_cancellation_point: 12144 case OMPD_flush: 12145 case OMPD_depobj: 12146 case OMPD_scan: 12147 case OMPD_declare_reduction: 12148 case OMPD_declare_mapper: 12149 case OMPD_declare_simd: 12150 case OMPD_declare_variant: 12151 case OMPD_begin_declare_variant: 12152 case OMPD_end_declare_variant: 12153 case OMPD_declare_target: 12154 case OMPD_end_declare_target: 12155 case OMPD_simd: 12156 case OMPD_for: 12157 case OMPD_for_simd: 12158 case OMPD_sections: 12159 case OMPD_section: 12160 case OMPD_single: 12161 case OMPD_master: 12162 case OMPD_critical: 12163 case OMPD_taskgroup: 12164 case OMPD_distribute: 12165 case OMPD_ordered: 12166 case OMPD_atomic: 12167 case OMPD_distribute_simd: 12168 case OMPD_requires: 12169 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 12170 case OMPD_unknown: 12171 llvm_unreachable("Unknown OpenMP directive"); 12172 } 12173 break; 12174 case OMPC_grainsize: 12175 case OMPC_num_tasks: 12176 case OMPC_final: 12177 case OMPC_priority: 12178 switch (DKind) { 12179 case OMPD_task: 12180 case OMPD_taskloop: 12181 case OMPD_taskloop_simd: 12182 case OMPD_master_taskloop: 12183 case OMPD_master_taskloop_simd: 12184 break; 12185 case OMPD_parallel_master_taskloop: 12186 case OMPD_parallel_master_taskloop_simd: 12187 CaptureRegion = OMPD_parallel; 12188 break; 12189 case OMPD_target_update: 12190 case OMPD_target_enter_data: 12191 case OMPD_target_exit_data: 12192 case OMPD_target: 12193 case OMPD_target_simd: 12194 case OMPD_target_teams: 12195 case OMPD_target_parallel: 12196 case OMPD_target_teams_distribute: 12197 case OMPD_target_teams_distribute_simd: 12198 case OMPD_target_parallel_for: 12199 case OMPD_target_parallel_for_simd: 12200 case OMPD_target_teams_distribute_parallel_for: 12201 case OMPD_target_teams_distribute_parallel_for_simd: 12202 case OMPD_target_data: 12203 case OMPD_teams_distribute_parallel_for: 12204 case OMPD_teams_distribute_parallel_for_simd: 12205 case OMPD_teams: 12206 case OMPD_teams_distribute: 12207 case OMPD_teams_distribute_simd: 12208 case OMPD_distribute_parallel_for: 12209 case OMPD_distribute_parallel_for_simd: 12210 case OMPD_cancel: 12211 case OMPD_parallel: 12212 case OMPD_parallel_master: 12213 case OMPD_parallel_sections: 12214 case OMPD_parallel_for: 12215 case OMPD_parallel_for_simd: 12216 case OMPD_threadprivate: 12217 case OMPD_allocate: 12218 case OMPD_taskyield: 12219 case OMPD_barrier: 12220 case OMPD_taskwait: 12221 case OMPD_cancellation_point: 12222 case OMPD_flush: 12223 case OMPD_depobj: 12224 case OMPD_scan: 12225 case OMPD_declare_reduction: 12226 case OMPD_declare_mapper: 12227 case OMPD_declare_simd: 12228 case OMPD_declare_variant: 12229 case OMPD_begin_declare_variant: 12230 case OMPD_end_declare_variant: 12231 case OMPD_declare_target: 12232 case OMPD_end_declare_target: 12233 case OMPD_simd: 12234 case OMPD_for: 12235 case OMPD_for_simd: 12236 case OMPD_sections: 12237 case OMPD_section: 12238 case OMPD_single: 12239 case OMPD_master: 12240 case OMPD_critical: 12241 case OMPD_taskgroup: 12242 case OMPD_distribute: 12243 case OMPD_ordered: 12244 case OMPD_atomic: 12245 case OMPD_distribute_simd: 12246 case OMPD_requires: 12247 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 12248 case OMPD_unknown: 12249 llvm_unreachable("Unknown OpenMP directive"); 12250 } 12251 break; 12252 case OMPC_firstprivate: 12253 case OMPC_lastprivate: 12254 case OMPC_reduction: 12255 case OMPC_task_reduction: 12256 case OMPC_in_reduction: 12257 case OMPC_linear: 12258 case OMPC_default: 12259 case OMPC_proc_bind: 12260 case OMPC_safelen: 12261 case OMPC_simdlen: 12262 case OMPC_allocator: 12263 case OMPC_collapse: 12264 case OMPC_private: 12265 case OMPC_shared: 12266 case OMPC_aligned: 12267 case OMPC_copyin: 12268 case OMPC_copyprivate: 12269 case OMPC_ordered: 12270 case OMPC_nowait: 12271 case OMPC_untied: 12272 case OMPC_mergeable: 12273 case OMPC_threadprivate: 12274 case OMPC_allocate: 12275 case OMPC_flush: 12276 case OMPC_depobj: 12277 case OMPC_read: 12278 case OMPC_write: 12279 case OMPC_update: 12280 case OMPC_capture: 12281 case OMPC_seq_cst: 12282 case OMPC_acq_rel: 12283 case OMPC_acquire: 12284 case OMPC_release: 12285 case OMPC_relaxed: 12286 case OMPC_depend: 12287 case OMPC_threads: 12288 case OMPC_simd: 12289 case OMPC_map: 12290 case OMPC_nogroup: 12291 case OMPC_hint: 12292 case OMPC_defaultmap: 12293 case OMPC_unknown: 12294 case OMPC_uniform: 12295 case OMPC_to: 12296 case OMPC_from: 12297 case OMPC_use_device_ptr: 12298 case OMPC_use_device_addr: 12299 case OMPC_is_device_ptr: 12300 case OMPC_unified_address: 12301 case OMPC_unified_shared_memory: 12302 case OMPC_reverse_offload: 12303 case OMPC_dynamic_allocators: 12304 case OMPC_atomic_default_mem_order: 12305 case OMPC_device_type: 12306 case OMPC_match: 12307 case OMPC_nontemporal: 12308 case OMPC_order: 12309 case OMPC_destroy: 12310 case OMPC_detach: 12311 case OMPC_inclusive: 12312 case OMPC_exclusive: 12313 case OMPC_uses_allocators: 12314 case OMPC_affinity: 12315 llvm_unreachable("Unexpected OpenMP clause."); 12316 } 12317 return CaptureRegion; 12318 } 12319 12320 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 12321 Expr *Condition, SourceLocation StartLoc, 12322 SourceLocation LParenLoc, 12323 SourceLocation NameModifierLoc, 12324 SourceLocation ColonLoc, 12325 SourceLocation EndLoc) { 12326 Expr *ValExpr = Condition; 12327 Stmt *HelperValStmt = nullptr; 12328 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12329 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12330 !Condition->isInstantiationDependent() && 12331 !Condition->containsUnexpandedParameterPack()) { 12332 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12333 if (Val.isInvalid()) 12334 return nullptr; 12335 12336 ValExpr = Val.get(); 12337 12338 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12339 CaptureRegion = getOpenMPCaptureRegionForClause( 12340 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 12341 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12342 ValExpr = MakeFullExpr(ValExpr).get(); 12343 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12344 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12345 HelperValStmt = buildPreInits(Context, Captures); 12346 } 12347 } 12348 12349 return new (Context) 12350 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 12351 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 12352 } 12353 12354 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 12355 SourceLocation StartLoc, 12356 SourceLocation LParenLoc, 12357 SourceLocation EndLoc) { 12358 Expr *ValExpr = Condition; 12359 Stmt *HelperValStmt = nullptr; 12360 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12361 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12362 !Condition->isInstantiationDependent() && 12363 !Condition->containsUnexpandedParameterPack()) { 12364 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12365 if (Val.isInvalid()) 12366 return nullptr; 12367 12368 ValExpr = MakeFullExpr(Val.get()).get(); 12369 12370 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12371 CaptureRegion = 12372 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 12373 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12374 ValExpr = MakeFullExpr(ValExpr).get(); 12375 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12376 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12377 HelperValStmt = buildPreInits(Context, Captures); 12378 } 12379 } 12380 12381 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 12382 StartLoc, LParenLoc, EndLoc); 12383 } 12384 12385 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 12386 Expr *Op) { 12387 if (!Op) 12388 return ExprError(); 12389 12390 class IntConvertDiagnoser : public ICEConvertDiagnoser { 12391 public: 12392 IntConvertDiagnoser() 12393 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 12394 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 12395 QualType T) override { 12396 return S.Diag(Loc, diag::err_omp_not_integral) << T; 12397 } 12398 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 12399 QualType T) override { 12400 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 12401 } 12402 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 12403 QualType T, 12404 QualType ConvTy) override { 12405 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 12406 } 12407 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 12408 QualType ConvTy) override { 12409 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12410 << ConvTy->isEnumeralType() << ConvTy; 12411 } 12412 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 12413 QualType T) override { 12414 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 12415 } 12416 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 12417 QualType ConvTy) override { 12418 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12419 << ConvTy->isEnumeralType() << ConvTy; 12420 } 12421 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 12422 QualType) override { 12423 llvm_unreachable("conversion functions are permitted"); 12424 } 12425 } ConvertDiagnoser; 12426 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 12427 } 12428 12429 static bool 12430 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 12431 bool StrictlyPositive, bool BuildCapture = false, 12432 OpenMPDirectiveKind DKind = OMPD_unknown, 12433 OpenMPDirectiveKind *CaptureRegion = nullptr, 12434 Stmt **HelperValStmt = nullptr) { 12435 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 12436 !ValExpr->isInstantiationDependent()) { 12437 SourceLocation Loc = ValExpr->getExprLoc(); 12438 ExprResult Value = 12439 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 12440 if (Value.isInvalid()) 12441 return false; 12442 12443 ValExpr = Value.get(); 12444 // The expression must evaluate to a non-negative integer value. 12445 llvm::APSInt Result; 12446 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 12447 Result.isSigned() && 12448 !((!StrictlyPositive && Result.isNonNegative()) || 12449 (StrictlyPositive && Result.isStrictlyPositive()))) { 12450 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 12451 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12452 << ValExpr->getSourceRange(); 12453 return false; 12454 } 12455 if (!BuildCapture) 12456 return true; 12457 *CaptureRegion = 12458 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 12459 if (*CaptureRegion != OMPD_unknown && 12460 !SemaRef.CurContext->isDependentContext()) { 12461 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 12462 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12463 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 12464 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 12465 } 12466 } 12467 return true; 12468 } 12469 12470 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 12471 SourceLocation StartLoc, 12472 SourceLocation LParenLoc, 12473 SourceLocation EndLoc) { 12474 Expr *ValExpr = NumThreads; 12475 Stmt *HelperValStmt = nullptr; 12476 12477 // OpenMP [2.5, Restrictions] 12478 // The num_threads expression must evaluate to a positive integer value. 12479 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 12480 /*StrictlyPositive=*/true)) 12481 return nullptr; 12482 12483 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12484 OpenMPDirectiveKind CaptureRegion = 12485 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 12486 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12487 ValExpr = MakeFullExpr(ValExpr).get(); 12488 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12489 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12490 HelperValStmt = buildPreInits(Context, Captures); 12491 } 12492 12493 return new (Context) OMPNumThreadsClause( 12494 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 12495 } 12496 12497 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 12498 OpenMPClauseKind CKind, 12499 bool StrictlyPositive) { 12500 if (!E) 12501 return ExprError(); 12502 if (E->isValueDependent() || E->isTypeDependent() || 12503 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 12504 return E; 12505 llvm::APSInt Result; 12506 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 12507 if (ICE.isInvalid()) 12508 return ExprError(); 12509 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 12510 (!StrictlyPositive && !Result.isNonNegative())) { 12511 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 12512 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12513 << E->getSourceRange(); 12514 return ExprError(); 12515 } 12516 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 12517 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 12518 << E->getSourceRange(); 12519 return ExprError(); 12520 } 12521 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 12522 DSAStack->setAssociatedLoops(Result.getExtValue()); 12523 else if (CKind == OMPC_ordered) 12524 DSAStack->setAssociatedLoops(Result.getExtValue()); 12525 return ICE; 12526 } 12527 12528 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 12529 SourceLocation LParenLoc, 12530 SourceLocation EndLoc) { 12531 // OpenMP [2.8.1, simd construct, Description] 12532 // The parameter of the safelen clause must be a constant 12533 // positive integer expression. 12534 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 12535 if (Safelen.isInvalid()) 12536 return nullptr; 12537 return new (Context) 12538 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 12539 } 12540 12541 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 12542 SourceLocation LParenLoc, 12543 SourceLocation EndLoc) { 12544 // OpenMP [2.8.1, simd construct, Description] 12545 // The parameter of the simdlen clause must be a constant 12546 // positive integer expression. 12547 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 12548 if (Simdlen.isInvalid()) 12549 return nullptr; 12550 return new (Context) 12551 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 12552 } 12553 12554 /// Tries to find omp_allocator_handle_t type. 12555 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 12556 DSAStackTy *Stack) { 12557 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 12558 if (!OMPAllocatorHandleT.isNull()) 12559 return true; 12560 // Build the predefined allocator expressions. 12561 bool ErrorFound = false; 12562 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 12563 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 12564 StringRef Allocator = 12565 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 12566 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 12567 auto *VD = dyn_cast_or_null<ValueDecl>( 12568 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 12569 if (!VD) { 12570 ErrorFound = true; 12571 break; 12572 } 12573 QualType AllocatorType = 12574 VD->getType().getNonLValueExprType(S.getASTContext()); 12575 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 12576 if (!Res.isUsable()) { 12577 ErrorFound = true; 12578 break; 12579 } 12580 if (OMPAllocatorHandleT.isNull()) 12581 OMPAllocatorHandleT = AllocatorType; 12582 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 12583 ErrorFound = true; 12584 break; 12585 } 12586 Stack->setAllocator(AllocatorKind, Res.get()); 12587 } 12588 if (ErrorFound) { 12589 S.Diag(Loc, diag::err_omp_implied_type_not_found) 12590 << "omp_allocator_handle_t"; 12591 return false; 12592 } 12593 OMPAllocatorHandleT.addConst(); 12594 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 12595 return true; 12596 } 12597 12598 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 12599 SourceLocation LParenLoc, 12600 SourceLocation EndLoc) { 12601 // OpenMP [2.11.3, allocate Directive, Description] 12602 // allocator is an expression of omp_allocator_handle_t type. 12603 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 12604 return nullptr; 12605 12606 ExprResult Allocator = DefaultLvalueConversion(A); 12607 if (Allocator.isInvalid()) 12608 return nullptr; 12609 Allocator = PerformImplicitConversion(Allocator.get(), 12610 DSAStack->getOMPAllocatorHandleT(), 12611 Sema::AA_Initializing, 12612 /*AllowExplicit=*/true); 12613 if (Allocator.isInvalid()) 12614 return nullptr; 12615 return new (Context) 12616 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 12617 } 12618 12619 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 12620 SourceLocation StartLoc, 12621 SourceLocation LParenLoc, 12622 SourceLocation EndLoc) { 12623 // OpenMP [2.7.1, loop construct, Description] 12624 // OpenMP [2.8.1, simd construct, Description] 12625 // OpenMP [2.9.6, distribute construct, Description] 12626 // The parameter of the collapse clause must be a constant 12627 // positive integer expression. 12628 ExprResult NumForLoopsResult = 12629 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 12630 if (NumForLoopsResult.isInvalid()) 12631 return nullptr; 12632 return new (Context) 12633 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 12634 } 12635 12636 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 12637 SourceLocation EndLoc, 12638 SourceLocation LParenLoc, 12639 Expr *NumForLoops) { 12640 // OpenMP [2.7.1, loop construct, Description] 12641 // OpenMP [2.8.1, simd construct, Description] 12642 // OpenMP [2.9.6, distribute construct, Description] 12643 // The parameter of the ordered clause must be a constant 12644 // positive integer expression if any. 12645 if (NumForLoops && LParenLoc.isValid()) { 12646 ExprResult NumForLoopsResult = 12647 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 12648 if (NumForLoopsResult.isInvalid()) 12649 return nullptr; 12650 NumForLoops = NumForLoopsResult.get(); 12651 } else { 12652 NumForLoops = nullptr; 12653 } 12654 auto *Clause = OMPOrderedClause::Create( 12655 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 12656 StartLoc, LParenLoc, EndLoc); 12657 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 12658 return Clause; 12659 } 12660 12661 OMPClause *Sema::ActOnOpenMPSimpleClause( 12662 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 12663 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12664 OMPClause *Res = nullptr; 12665 switch (Kind) { 12666 case OMPC_default: 12667 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 12668 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12669 break; 12670 case OMPC_proc_bind: 12671 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 12672 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12673 break; 12674 case OMPC_atomic_default_mem_order: 12675 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 12676 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 12677 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12678 break; 12679 case OMPC_order: 12680 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 12681 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12682 break; 12683 case OMPC_update: 12684 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 12685 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12686 break; 12687 case OMPC_if: 12688 case OMPC_final: 12689 case OMPC_num_threads: 12690 case OMPC_safelen: 12691 case OMPC_simdlen: 12692 case OMPC_allocator: 12693 case OMPC_collapse: 12694 case OMPC_schedule: 12695 case OMPC_private: 12696 case OMPC_firstprivate: 12697 case OMPC_lastprivate: 12698 case OMPC_shared: 12699 case OMPC_reduction: 12700 case OMPC_task_reduction: 12701 case OMPC_in_reduction: 12702 case OMPC_linear: 12703 case OMPC_aligned: 12704 case OMPC_copyin: 12705 case OMPC_copyprivate: 12706 case OMPC_ordered: 12707 case OMPC_nowait: 12708 case OMPC_untied: 12709 case OMPC_mergeable: 12710 case OMPC_threadprivate: 12711 case OMPC_allocate: 12712 case OMPC_flush: 12713 case OMPC_depobj: 12714 case OMPC_read: 12715 case OMPC_write: 12716 case OMPC_capture: 12717 case OMPC_seq_cst: 12718 case OMPC_acq_rel: 12719 case OMPC_acquire: 12720 case OMPC_release: 12721 case OMPC_relaxed: 12722 case OMPC_depend: 12723 case OMPC_device: 12724 case OMPC_threads: 12725 case OMPC_simd: 12726 case OMPC_map: 12727 case OMPC_num_teams: 12728 case OMPC_thread_limit: 12729 case OMPC_priority: 12730 case OMPC_grainsize: 12731 case OMPC_nogroup: 12732 case OMPC_num_tasks: 12733 case OMPC_hint: 12734 case OMPC_dist_schedule: 12735 case OMPC_defaultmap: 12736 case OMPC_unknown: 12737 case OMPC_uniform: 12738 case OMPC_to: 12739 case OMPC_from: 12740 case OMPC_use_device_ptr: 12741 case OMPC_use_device_addr: 12742 case OMPC_is_device_ptr: 12743 case OMPC_unified_address: 12744 case OMPC_unified_shared_memory: 12745 case OMPC_reverse_offload: 12746 case OMPC_dynamic_allocators: 12747 case OMPC_device_type: 12748 case OMPC_match: 12749 case OMPC_nontemporal: 12750 case OMPC_destroy: 12751 case OMPC_detach: 12752 case OMPC_inclusive: 12753 case OMPC_exclusive: 12754 case OMPC_uses_allocators: 12755 case OMPC_affinity: 12756 llvm_unreachable("Clause is not allowed."); 12757 } 12758 return Res; 12759 } 12760 12761 static std::string 12762 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 12763 ArrayRef<unsigned> Exclude = llvm::None) { 12764 SmallString<256> Buffer; 12765 llvm::raw_svector_ostream Out(Buffer); 12766 unsigned Skipped = Exclude.size(); 12767 auto S = Exclude.begin(), E = Exclude.end(); 12768 for (unsigned I = First; I < Last; ++I) { 12769 if (std::find(S, E, I) != E) { 12770 --Skipped; 12771 continue; 12772 } 12773 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 12774 if (I + Skipped + 2 == Last) 12775 Out << " or "; 12776 else if (I + Skipped + 1 != Last) 12777 Out << ", "; 12778 } 12779 return std::string(Out.str()); 12780 } 12781 12782 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 12783 SourceLocation KindKwLoc, 12784 SourceLocation StartLoc, 12785 SourceLocation LParenLoc, 12786 SourceLocation EndLoc) { 12787 if (Kind == OMP_DEFAULT_unknown) { 12788 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12789 << getListOfPossibleValues(OMPC_default, /*First=*/0, 12790 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 12791 << getOpenMPClauseName(OMPC_default); 12792 return nullptr; 12793 } 12794 if (Kind == OMP_DEFAULT_none) 12795 DSAStack->setDefaultDSANone(KindKwLoc); 12796 else if (Kind == OMP_DEFAULT_shared) 12797 DSAStack->setDefaultDSAShared(KindKwLoc); 12798 12799 return new (Context) 12800 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12801 } 12802 12803 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 12804 SourceLocation KindKwLoc, 12805 SourceLocation StartLoc, 12806 SourceLocation LParenLoc, 12807 SourceLocation EndLoc) { 12808 if (Kind == OMP_PROC_BIND_unknown) { 12809 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12810 << getListOfPossibleValues(OMPC_proc_bind, 12811 /*First=*/unsigned(OMP_PROC_BIND_master), 12812 /*Last=*/5) 12813 << getOpenMPClauseName(OMPC_proc_bind); 12814 return nullptr; 12815 } 12816 return new (Context) 12817 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12818 } 12819 12820 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 12821 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 12822 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12823 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 12824 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12825 << getListOfPossibleValues( 12826 OMPC_atomic_default_mem_order, /*First=*/0, 12827 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 12828 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 12829 return nullptr; 12830 } 12831 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 12832 LParenLoc, EndLoc); 12833 } 12834 12835 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 12836 SourceLocation KindKwLoc, 12837 SourceLocation StartLoc, 12838 SourceLocation LParenLoc, 12839 SourceLocation EndLoc) { 12840 if (Kind == OMPC_ORDER_unknown) { 12841 static_assert(OMPC_ORDER_unknown > 0, 12842 "OMPC_ORDER_unknown not greater than 0"); 12843 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12844 << getListOfPossibleValues(OMPC_order, /*First=*/0, 12845 /*Last=*/OMPC_ORDER_unknown) 12846 << getOpenMPClauseName(OMPC_order); 12847 return nullptr; 12848 } 12849 return new (Context) 12850 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12851 } 12852 12853 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 12854 SourceLocation KindKwLoc, 12855 SourceLocation StartLoc, 12856 SourceLocation LParenLoc, 12857 SourceLocation EndLoc) { 12858 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 12859 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 12860 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 12861 OMPC_DEPEND_depobj}; 12862 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12863 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12864 /*Last=*/OMPC_DEPEND_unknown, Except) 12865 << getOpenMPClauseName(OMPC_update); 12866 return nullptr; 12867 } 12868 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 12869 EndLoc); 12870 } 12871 12872 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 12873 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 12874 SourceLocation StartLoc, SourceLocation LParenLoc, 12875 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 12876 SourceLocation EndLoc) { 12877 OMPClause *Res = nullptr; 12878 switch (Kind) { 12879 case OMPC_schedule: 12880 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 12881 assert(Argument.size() == NumberOfElements && 12882 ArgumentLoc.size() == NumberOfElements); 12883 Res = ActOnOpenMPScheduleClause( 12884 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 12885 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 12886 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 12887 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 12888 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12889 break; 12890 case OMPC_if: 12891 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12892 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12893 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12894 DelimLoc, EndLoc); 12895 break; 12896 case OMPC_dist_schedule: 12897 Res = ActOnOpenMPDistScheduleClause( 12898 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12899 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12900 break; 12901 case OMPC_defaultmap: 12902 enum { Modifier, DefaultmapKind }; 12903 Res = ActOnOpenMPDefaultmapClause( 12904 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12905 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12906 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12907 EndLoc); 12908 break; 12909 case OMPC_device: 12910 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12911 Res = ActOnOpenMPDeviceClause( 12912 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 12913 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 12914 break; 12915 case OMPC_final: 12916 case OMPC_num_threads: 12917 case OMPC_safelen: 12918 case OMPC_simdlen: 12919 case OMPC_allocator: 12920 case OMPC_collapse: 12921 case OMPC_default: 12922 case OMPC_proc_bind: 12923 case OMPC_private: 12924 case OMPC_firstprivate: 12925 case OMPC_lastprivate: 12926 case OMPC_shared: 12927 case OMPC_reduction: 12928 case OMPC_task_reduction: 12929 case OMPC_in_reduction: 12930 case OMPC_linear: 12931 case OMPC_aligned: 12932 case OMPC_copyin: 12933 case OMPC_copyprivate: 12934 case OMPC_ordered: 12935 case OMPC_nowait: 12936 case OMPC_untied: 12937 case OMPC_mergeable: 12938 case OMPC_threadprivate: 12939 case OMPC_allocate: 12940 case OMPC_flush: 12941 case OMPC_depobj: 12942 case OMPC_read: 12943 case OMPC_write: 12944 case OMPC_update: 12945 case OMPC_capture: 12946 case OMPC_seq_cst: 12947 case OMPC_acq_rel: 12948 case OMPC_acquire: 12949 case OMPC_release: 12950 case OMPC_relaxed: 12951 case OMPC_depend: 12952 case OMPC_threads: 12953 case OMPC_simd: 12954 case OMPC_map: 12955 case OMPC_num_teams: 12956 case OMPC_thread_limit: 12957 case OMPC_priority: 12958 case OMPC_grainsize: 12959 case OMPC_nogroup: 12960 case OMPC_num_tasks: 12961 case OMPC_hint: 12962 case OMPC_unknown: 12963 case OMPC_uniform: 12964 case OMPC_to: 12965 case OMPC_from: 12966 case OMPC_use_device_ptr: 12967 case OMPC_use_device_addr: 12968 case OMPC_is_device_ptr: 12969 case OMPC_unified_address: 12970 case OMPC_unified_shared_memory: 12971 case OMPC_reverse_offload: 12972 case OMPC_dynamic_allocators: 12973 case OMPC_atomic_default_mem_order: 12974 case OMPC_device_type: 12975 case OMPC_match: 12976 case OMPC_nontemporal: 12977 case OMPC_order: 12978 case OMPC_destroy: 12979 case OMPC_detach: 12980 case OMPC_inclusive: 12981 case OMPC_exclusive: 12982 case OMPC_uses_allocators: 12983 case OMPC_affinity: 12984 llvm_unreachable("Clause is not allowed."); 12985 } 12986 return Res; 12987 } 12988 12989 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12990 OpenMPScheduleClauseModifier M2, 12991 SourceLocation M1Loc, SourceLocation M2Loc) { 12992 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12993 SmallVector<unsigned, 2> Excluded; 12994 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12995 Excluded.push_back(M2); 12996 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12997 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12998 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12999 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 13000 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 13001 << getListOfPossibleValues(OMPC_schedule, 13002 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 13003 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 13004 Excluded) 13005 << getOpenMPClauseName(OMPC_schedule); 13006 return true; 13007 } 13008 return false; 13009 } 13010 13011 OMPClause *Sema::ActOnOpenMPScheduleClause( 13012 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 13013 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 13014 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 13015 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 13016 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 13017 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 13018 return nullptr; 13019 // OpenMP, 2.7.1, Loop Construct, Restrictions 13020 // Either the monotonic modifier or the nonmonotonic modifier can be specified 13021 // but not both. 13022 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 13023 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 13024 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 13025 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 13026 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 13027 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 13028 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 13029 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 13030 return nullptr; 13031 } 13032 if (Kind == OMPC_SCHEDULE_unknown) { 13033 std::string Values; 13034 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 13035 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 13036 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 13037 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 13038 Exclude); 13039 } else { 13040 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 13041 /*Last=*/OMPC_SCHEDULE_unknown); 13042 } 13043 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 13044 << Values << getOpenMPClauseName(OMPC_schedule); 13045 return nullptr; 13046 } 13047 // OpenMP, 2.7.1, Loop Construct, Restrictions 13048 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 13049 // schedule(guided). 13050 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 13051 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 13052 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 13053 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 13054 diag::err_omp_schedule_nonmonotonic_static); 13055 return nullptr; 13056 } 13057 Expr *ValExpr = ChunkSize; 13058 Stmt *HelperValStmt = nullptr; 13059 if (ChunkSize) { 13060 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 13061 !ChunkSize->isInstantiationDependent() && 13062 !ChunkSize->containsUnexpandedParameterPack()) { 13063 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 13064 ExprResult Val = 13065 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 13066 if (Val.isInvalid()) 13067 return nullptr; 13068 13069 ValExpr = Val.get(); 13070 13071 // OpenMP [2.7.1, Restrictions] 13072 // chunk_size must be a loop invariant integer expression with a positive 13073 // value. 13074 llvm::APSInt Result; 13075 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 13076 if (Result.isSigned() && !Result.isStrictlyPositive()) { 13077 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 13078 << "schedule" << 1 << ChunkSize->getSourceRange(); 13079 return nullptr; 13080 } 13081 } else if (getOpenMPCaptureRegionForClause( 13082 DSAStack->getCurrentDirective(), OMPC_schedule, 13083 LangOpts.OpenMP) != OMPD_unknown && 13084 !CurContext->isDependentContext()) { 13085 ValExpr = MakeFullExpr(ValExpr).get(); 13086 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13087 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13088 HelperValStmt = buildPreInits(Context, Captures); 13089 } 13090 } 13091 } 13092 13093 return new (Context) 13094 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 13095 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 13096 } 13097 13098 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 13099 SourceLocation StartLoc, 13100 SourceLocation EndLoc) { 13101 OMPClause *Res = nullptr; 13102 switch (Kind) { 13103 case OMPC_ordered: 13104 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 13105 break; 13106 case OMPC_nowait: 13107 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 13108 break; 13109 case OMPC_untied: 13110 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 13111 break; 13112 case OMPC_mergeable: 13113 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 13114 break; 13115 case OMPC_read: 13116 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 13117 break; 13118 case OMPC_write: 13119 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 13120 break; 13121 case OMPC_update: 13122 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 13123 break; 13124 case OMPC_capture: 13125 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 13126 break; 13127 case OMPC_seq_cst: 13128 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 13129 break; 13130 case OMPC_acq_rel: 13131 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 13132 break; 13133 case OMPC_acquire: 13134 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 13135 break; 13136 case OMPC_release: 13137 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 13138 break; 13139 case OMPC_relaxed: 13140 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 13141 break; 13142 case OMPC_threads: 13143 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 13144 break; 13145 case OMPC_simd: 13146 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 13147 break; 13148 case OMPC_nogroup: 13149 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 13150 break; 13151 case OMPC_unified_address: 13152 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 13153 break; 13154 case OMPC_unified_shared_memory: 13155 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13156 break; 13157 case OMPC_reverse_offload: 13158 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 13159 break; 13160 case OMPC_dynamic_allocators: 13161 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 13162 break; 13163 case OMPC_destroy: 13164 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); 13165 break; 13166 case OMPC_if: 13167 case OMPC_final: 13168 case OMPC_num_threads: 13169 case OMPC_safelen: 13170 case OMPC_simdlen: 13171 case OMPC_allocator: 13172 case OMPC_collapse: 13173 case OMPC_schedule: 13174 case OMPC_private: 13175 case OMPC_firstprivate: 13176 case OMPC_lastprivate: 13177 case OMPC_shared: 13178 case OMPC_reduction: 13179 case OMPC_task_reduction: 13180 case OMPC_in_reduction: 13181 case OMPC_linear: 13182 case OMPC_aligned: 13183 case OMPC_copyin: 13184 case OMPC_copyprivate: 13185 case OMPC_default: 13186 case OMPC_proc_bind: 13187 case OMPC_threadprivate: 13188 case OMPC_allocate: 13189 case OMPC_flush: 13190 case OMPC_depobj: 13191 case OMPC_depend: 13192 case OMPC_device: 13193 case OMPC_map: 13194 case OMPC_num_teams: 13195 case OMPC_thread_limit: 13196 case OMPC_priority: 13197 case OMPC_grainsize: 13198 case OMPC_num_tasks: 13199 case OMPC_hint: 13200 case OMPC_dist_schedule: 13201 case OMPC_defaultmap: 13202 case OMPC_unknown: 13203 case OMPC_uniform: 13204 case OMPC_to: 13205 case OMPC_from: 13206 case OMPC_use_device_ptr: 13207 case OMPC_use_device_addr: 13208 case OMPC_is_device_ptr: 13209 case OMPC_atomic_default_mem_order: 13210 case OMPC_device_type: 13211 case OMPC_match: 13212 case OMPC_nontemporal: 13213 case OMPC_order: 13214 case OMPC_detach: 13215 case OMPC_inclusive: 13216 case OMPC_exclusive: 13217 case OMPC_uses_allocators: 13218 case OMPC_affinity: 13219 llvm_unreachable("Clause is not allowed."); 13220 } 13221 return Res; 13222 } 13223 13224 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 13225 SourceLocation EndLoc) { 13226 DSAStack->setNowaitRegion(); 13227 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 13228 } 13229 13230 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 13231 SourceLocation EndLoc) { 13232 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 13233 } 13234 13235 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 13236 SourceLocation EndLoc) { 13237 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 13238 } 13239 13240 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 13241 SourceLocation EndLoc) { 13242 return new (Context) OMPReadClause(StartLoc, EndLoc); 13243 } 13244 13245 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 13246 SourceLocation EndLoc) { 13247 return new (Context) OMPWriteClause(StartLoc, EndLoc); 13248 } 13249 13250 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 13251 SourceLocation EndLoc) { 13252 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 13253 } 13254 13255 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 13256 SourceLocation EndLoc) { 13257 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 13258 } 13259 13260 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 13261 SourceLocation EndLoc) { 13262 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 13263 } 13264 13265 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 13266 SourceLocation EndLoc) { 13267 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 13268 } 13269 13270 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 13271 SourceLocation EndLoc) { 13272 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 13273 } 13274 13275 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 13276 SourceLocation EndLoc) { 13277 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 13278 } 13279 13280 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 13281 SourceLocation EndLoc) { 13282 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 13283 } 13284 13285 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 13286 SourceLocation EndLoc) { 13287 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 13288 } 13289 13290 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 13291 SourceLocation EndLoc) { 13292 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 13293 } 13294 13295 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 13296 SourceLocation EndLoc) { 13297 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 13298 } 13299 13300 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 13301 SourceLocation EndLoc) { 13302 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 13303 } 13304 13305 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 13306 SourceLocation EndLoc) { 13307 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13308 } 13309 13310 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 13311 SourceLocation EndLoc) { 13312 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 13313 } 13314 13315 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 13316 SourceLocation EndLoc) { 13317 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 13318 } 13319 13320 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, 13321 SourceLocation EndLoc) { 13322 return new (Context) OMPDestroyClause(StartLoc, EndLoc); 13323 } 13324 13325 OMPClause *Sema::ActOnOpenMPVarListClause( 13326 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr, 13327 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 13328 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 13329 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 13330 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13331 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 13332 SourceLocation ExtraModifierLoc) { 13333 SourceLocation StartLoc = Locs.StartLoc; 13334 SourceLocation LParenLoc = Locs.LParenLoc; 13335 SourceLocation EndLoc = Locs.EndLoc; 13336 OMPClause *Res = nullptr; 13337 switch (Kind) { 13338 case OMPC_private: 13339 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13340 break; 13341 case OMPC_firstprivate: 13342 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13343 break; 13344 case OMPC_lastprivate: 13345 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 13346 "Unexpected lastprivate modifier."); 13347 Res = ActOnOpenMPLastprivateClause( 13348 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 13349 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 13350 break; 13351 case OMPC_shared: 13352 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 13353 break; 13354 case OMPC_reduction: 13355 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 13356 "Unexpected lastprivate modifier."); 13357 Res = ActOnOpenMPReductionClause( 13358 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 13359 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 13360 ReductionOrMapperIdScopeSpec, ReductionOrMapperId); 13361 break; 13362 case OMPC_task_reduction: 13363 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13364 EndLoc, ReductionOrMapperIdScopeSpec, 13365 ReductionOrMapperId); 13366 break; 13367 case OMPC_in_reduction: 13368 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13369 EndLoc, ReductionOrMapperIdScopeSpec, 13370 ReductionOrMapperId); 13371 break; 13372 case OMPC_linear: 13373 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 13374 "Unexpected linear modifier."); 13375 Res = ActOnOpenMPLinearClause( 13376 VarList, DepModOrTailExpr, StartLoc, LParenLoc, 13377 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 13378 ColonLoc, EndLoc); 13379 break; 13380 case OMPC_aligned: 13381 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, 13382 LParenLoc, ColonLoc, EndLoc); 13383 break; 13384 case OMPC_copyin: 13385 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 13386 break; 13387 case OMPC_copyprivate: 13388 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13389 break; 13390 case OMPC_flush: 13391 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 13392 break; 13393 case OMPC_depend: 13394 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 13395 "Unexpected depend modifier."); 13396 Res = ActOnOpenMPDependClause( 13397 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier), 13398 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 13399 break; 13400 case OMPC_map: 13401 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 13402 "Unexpected map modifier."); 13403 Res = ActOnOpenMPMapClause( 13404 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 13405 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 13406 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); 13407 break; 13408 case OMPC_to: 13409 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 13410 ReductionOrMapperId, Locs); 13411 break; 13412 case OMPC_from: 13413 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 13414 ReductionOrMapperId, Locs); 13415 break; 13416 case OMPC_use_device_ptr: 13417 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 13418 break; 13419 case OMPC_use_device_addr: 13420 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); 13421 break; 13422 case OMPC_is_device_ptr: 13423 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 13424 break; 13425 case OMPC_allocate: 13426 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, 13427 LParenLoc, ColonLoc, EndLoc); 13428 break; 13429 case OMPC_nontemporal: 13430 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 13431 break; 13432 case OMPC_inclusive: 13433 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13434 break; 13435 case OMPC_exclusive: 13436 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13437 break; 13438 case OMPC_affinity: 13439 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, 13440 DepModOrTailExpr, VarList); 13441 break; 13442 case OMPC_if: 13443 case OMPC_depobj: 13444 case OMPC_final: 13445 case OMPC_num_threads: 13446 case OMPC_safelen: 13447 case OMPC_simdlen: 13448 case OMPC_allocator: 13449 case OMPC_collapse: 13450 case OMPC_default: 13451 case OMPC_proc_bind: 13452 case OMPC_schedule: 13453 case OMPC_ordered: 13454 case OMPC_nowait: 13455 case OMPC_untied: 13456 case OMPC_mergeable: 13457 case OMPC_threadprivate: 13458 case OMPC_read: 13459 case OMPC_write: 13460 case OMPC_update: 13461 case OMPC_capture: 13462 case OMPC_seq_cst: 13463 case OMPC_acq_rel: 13464 case OMPC_acquire: 13465 case OMPC_release: 13466 case OMPC_relaxed: 13467 case OMPC_device: 13468 case OMPC_threads: 13469 case OMPC_simd: 13470 case OMPC_num_teams: 13471 case OMPC_thread_limit: 13472 case OMPC_priority: 13473 case OMPC_grainsize: 13474 case OMPC_nogroup: 13475 case OMPC_num_tasks: 13476 case OMPC_hint: 13477 case OMPC_dist_schedule: 13478 case OMPC_defaultmap: 13479 case OMPC_unknown: 13480 case OMPC_uniform: 13481 case OMPC_unified_address: 13482 case OMPC_unified_shared_memory: 13483 case OMPC_reverse_offload: 13484 case OMPC_dynamic_allocators: 13485 case OMPC_atomic_default_mem_order: 13486 case OMPC_device_type: 13487 case OMPC_match: 13488 case OMPC_order: 13489 case OMPC_destroy: 13490 case OMPC_detach: 13491 case OMPC_uses_allocators: 13492 llvm_unreachable("Clause is not allowed."); 13493 } 13494 return Res; 13495 } 13496 13497 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 13498 ExprObjectKind OK, SourceLocation Loc) { 13499 ExprResult Res = BuildDeclRefExpr( 13500 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 13501 if (!Res.isUsable()) 13502 return ExprError(); 13503 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 13504 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 13505 if (!Res.isUsable()) 13506 return ExprError(); 13507 } 13508 if (VK != VK_LValue && Res.get()->isGLValue()) { 13509 Res = DefaultLvalueConversion(Res.get()); 13510 if (!Res.isUsable()) 13511 return ExprError(); 13512 } 13513 return Res; 13514 } 13515 13516 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 13517 SourceLocation StartLoc, 13518 SourceLocation LParenLoc, 13519 SourceLocation EndLoc) { 13520 SmallVector<Expr *, 8> Vars; 13521 SmallVector<Expr *, 8> PrivateCopies; 13522 for (Expr *RefExpr : VarList) { 13523 assert(RefExpr && "NULL expr in OpenMP private clause."); 13524 SourceLocation ELoc; 13525 SourceRange ERange; 13526 Expr *SimpleRefExpr = RefExpr; 13527 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13528 if (Res.second) { 13529 // It will be analyzed later. 13530 Vars.push_back(RefExpr); 13531 PrivateCopies.push_back(nullptr); 13532 } 13533 ValueDecl *D = Res.first; 13534 if (!D) 13535 continue; 13536 13537 QualType Type = D->getType(); 13538 auto *VD = dyn_cast<VarDecl>(D); 13539 13540 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13541 // A variable that appears in a private clause must not have an incomplete 13542 // type or a reference type. 13543 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 13544 continue; 13545 Type = Type.getNonReferenceType(); 13546 13547 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13548 // A variable that is privatized must not have a const-qualified type 13549 // unless it is of class type with a mutable member. This restriction does 13550 // not apply to the firstprivate clause. 13551 // 13552 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 13553 // A variable that appears in a private clause must not have a 13554 // const-qualified type unless it is of class type with a mutable member. 13555 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 13556 continue; 13557 13558 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13559 // in a Construct] 13560 // Variables with the predetermined data-sharing attributes may not be 13561 // listed in data-sharing attributes clauses, except for the cases 13562 // listed below. For these exceptions only, listing a predetermined 13563 // variable in a data-sharing attribute clause is allowed and overrides 13564 // the variable's predetermined data-sharing attributes. 13565 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13566 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 13567 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13568 << getOpenMPClauseName(OMPC_private); 13569 reportOriginalDsa(*this, DSAStack, D, DVar); 13570 continue; 13571 } 13572 13573 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13574 // Variably modified types are not supported for tasks. 13575 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13576 isOpenMPTaskingDirective(CurrDir)) { 13577 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13578 << getOpenMPClauseName(OMPC_private) << Type 13579 << getOpenMPDirectiveName(CurrDir); 13580 bool IsDecl = 13581 !VD || 13582 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13583 Diag(D->getLocation(), 13584 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13585 << D; 13586 continue; 13587 } 13588 13589 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13590 // A list item cannot appear in both a map clause and a data-sharing 13591 // attribute clause on the same construct 13592 // 13593 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13594 // A list item cannot appear in both a map clause and a data-sharing 13595 // attribute clause on the same construct unless the construct is a 13596 // combined construct. 13597 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 13598 CurrDir == OMPD_target) { 13599 OpenMPClauseKind ConflictKind; 13600 if (DSAStack->checkMappableExprComponentListsForDecl( 13601 VD, /*CurrentRegionOnly=*/true, 13602 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 13603 OpenMPClauseKind WhereFoundClauseKind) -> bool { 13604 ConflictKind = WhereFoundClauseKind; 13605 return true; 13606 })) { 13607 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13608 << getOpenMPClauseName(OMPC_private) 13609 << getOpenMPClauseName(ConflictKind) 13610 << getOpenMPDirectiveName(CurrDir); 13611 reportOriginalDsa(*this, DSAStack, D, DVar); 13612 continue; 13613 } 13614 } 13615 13616 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 13617 // A variable of class type (or array thereof) that appears in a private 13618 // clause requires an accessible, unambiguous default constructor for the 13619 // class type. 13620 // Generate helper private variable and initialize it with the default 13621 // value. The address of the original variable is replaced by the address of 13622 // the new private variable in CodeGen. This new variable is not added to 13623 // IdResolver, so the code in the OpenMP region uses original variable for 13624 // proper diagnostics. 13625 Type = Type.getUnqualifiedType(); 13626 VarDecl *VDPrivate = 13627 buildVarDecl(*this, ELoc, Type, D->getName(), 13628 D->hasAttrs() ? &D->getAttrs() : nullptr, 13629 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13630 ActOnUninitializedDecl(VDPrivate); 13631 if (VDPrivate->isInvalidDecl()) 13632 continue; 13633 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13634 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13635 13636 DeclRefExpr *Ref = nullptr; 13637 if (!VD && !CurContext->isDependentContext()) 13638 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13639 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 13640 Vars.push_back((VD || CurContext->isDependentContext()) 13641 ? RefExpr->IgnoreParens() 13642 : Ref); 13643 PrivateCopies.push_back(VDPrivateRefExpr); 13644 } 13645 13646 if (Vars.empty()) 13647 return nullptr; 13648 13649 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13650 PrivateCopies); 13651 } 13652 13653 namespace { 13654 class DiagsUninitializedSeveretyRAII { 13655 private: 13656 DiagnosticsEngine &Diags; 13657 SourceLocation SavedLoc; 13658 bool IsIgnored = false; 13659 13660 public: 13661 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 13662 bool IsIgnored) 13663 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 13664 if (!IsIgnored) { 13665 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 13666 /*Map*/ diag::Severity::Ignored, Loc); 13667 } 13668 } 13669 ~DiagsUninitializedSeveretyRAII() { 13670 if (!IsIgnored) 13671 Diags.popMappings(SavedLoc); 13672 } 13673 }; 13674 } 13675 13676 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 13677 SourceLocation StartLoc, 13678 SourceLocation LParenLoc, 13679 SourceLocation EndLoc) { 13680 SmallVector<Expr *, 8> Vars; 13681 SmallVector<Expr *, 8> PrivateCopies; 13682 SmallVector<Expr *, 8> Inits; 13683 SmallVector<Decl *, 4> ExprCaptures; 13684 bool IsImplicitClause = 13685 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 13686 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 13687 13688 for (Expr *RefExpr : VarList) { 13689 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 13690 SourceLocation ELoc; 13691 SourceRange ERange; 13692 Expr *SimpleRefExpr = RefExpr; 13693 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13694 if (Res.second) { 13695 // It will be analyzed later. 13696 Vars.push_back(RefExpr); 13697 PrivateCopies.push_back(nullptr); 13698 Inits.push_back(nullptr); 13699 } 13700 ValueDecl *D = Res.first; 13701 if (!D) 13702 continue; 13703 13704 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 13705 QualType Type = D->getType(); 13706 auto *VD = dyn_cast<VarDecl>(D); 13707 13708 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13709 // A variable that appears in a private clause must not have an incomplete 13710 // type or a reference type. 13711 if (RequireCompleteType(ELoc, Type, 13712 diag::err_omp_firstprivate_incomplete_type)) 13713 continue; 13714 Type = Type.getNonReferenceType(); 13715 13716 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 13717 // A variable of class type (or array thereof) that appears in a private 13718 // clause requires an accessible, unambiguous copy constructor for the 13719 // class type. 13720 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13721 13722 // If an implicit firstprivate variable found it was checked already. 13723 DSAStackTy::DSAVarData TopDVar; 13724 if (!IsImplicitClause) { 13725 DSAStackTy::DSAVarData DVar = 13726 DSAStack->getTopDSA(D, /*FromParent=*/false); 13727 TopDVar = DVar; 13728 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13729 bool IsConstant = ElemType.isConstant(Context); 13730 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 13731 // A list item that specifies a given variable may not appear in more 13732 // than one clause on the same directive, except that a variable may be 13733 // specified in both firstprivate and lastprivate clauses. 13734 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13735 // A list item may appear in a firstprivate or lastprivate clause but not 13736 // both. 13737 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 13738 (isOpenMPDistributeDirective(CurrDir) || 13739 DVar.CKind != OMPC_lastprivate) && 13740 DVar.RefExpr) { 13741 Diag(ELoc, diag::err_omp_wrong_dsa) 13742 << getOpenMPClauseName(DVar.CKind) 13743 << getOpenMPClauseName(OMPC_firstprivate); 13744 reportOriginalDsa(*this, DSAStack, D, DVar); 13745 continue; 13746 } 13747 13748 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13749 // in a Construct] 13750 // Variables with the predetermined data-sharing attributes may not be 13751 // listed in data-sharing attributes clauses, except for the cases 13752 // listed below. For these exceptions only, listing a predetermined 13753 // variable in a data-sharing attribute clause is allowed and overrides 13754 // the variable's predetermined data-sharing attributes. 13755 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13756 // in a Construct, C/C++, p.2] 13757 // Variables with const-qualified type having no mutable member may be 13758 // listed in a firstprivate clause, even if they are static data members. 13759 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 13760 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 13761 Diag(ELoc, diag::err_omp_wrong_dsa) 13762 << getOpenMPClauseName(DVar.CKind) 13763 << getOpenMPClauseName(OMPC_firstprivate); 13764 reportOriginalDsa(*this, DSAStack, D, DVar); 13765 continue; 13766 } 13767 13768 // OpenMP [2.9.3.4, Restrictions, p.2] 13769 // A list item that is private within a parallel region must not appear 13770 // in a firstprivate clause on a worksharing construct if any of the 13771 // worksharing regions arising from the worksharing construct ever bind 13772 // to any of the parallel regions arising from the parallel construct. 13773 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13774 // A list item that is private within a teams region must not appear in a 13775 // firstprivate clause on a distribute construct if any of the distribute 13776 // regions arising from the distribute construct ever bind to any of the 13777 // teams regions arising from the teams construct. 13778 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13779 // A list item that appears in a reduction clause of a teams construct 13780 // must not appear in a firstprivate clause on a distribute construct if 13781 // any of the distribute regions arising from the distribute construct 13782 // ever bind to any of the teams regions arising from the teams construct. 13783 if ((isOpenMPWorksharingDirective(CurrDir) || 13784 isOpenMPDistributeDirective(CurrDir)) && 13785 !isOpenMPParallelDirective(CurrDir) && 13786 !isOpenMPTeamsDirective(CurrDir)) { 13787 DVar = DSAStack->getImplicitDSA(D, true); 13788 if (DVar.CKind != OMPC_shared && 13789 (isOpenMPParallelDirective(DVar.DKind) || 13790 isOpenMPTeamsDirective(DVar.DKind) || 13791 DVar.DKind == OMPD_unknown)) { 13792 Diag(ELoc, diag::err_omp_required_access) 13793 << getOpenMPClauseName(OMPC_firstprivate) 13794 << getOpenMPClauseName(OMPC_shared); 13795 reportOriginalDsa(*this, DSAStack, D, DVar); 13796 continue; 13797 } 13798 } 13799 // OpenMP [2.9.3.4, Restrictions, p.3] 13800 // A list item that appears in a reduction clause of a parallel construct 13801 // must not appear in a firstprivate clause on a worksharing or task 13802 // construct if any of the worksharing or task regions arising from the 13803 // worksharing or task construct ever bind to any of the parallel regions 13804 // arising from the parallel construct. 13805 // OpenMP [2.9.3.4, Restrictions, p.4] 13806 // A list item that appears in a reduction clause in worksharing 13807 // construct must not appear in a firstprivate clause in a task construct 13808 // encountered during execution of any of the worksharing regions arising 13809 // from the worksharing construct. 13810 if (isOpenMPTaskingDirective(CurrDir)) { 13811 DVar = DSAStack->hasInnermostDSA( 13812 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 13813 [](OpenMPDirectiveKind K) { 13814 return isOpenMPParallelDirective(K) || 13815 isOpenMPWorksharingDirective(K) || 13816 isOpenMPTeamsDirective(K); 13817 }, 13818 /*FromParent=*/true); 13819 if (DVar.CKind == OMPC_reduction && 13820 (isOpenMPParallelDirective(DVar.DKind) || 13821 isOpenMPWorksharingDirective(DVar.DKind) || 13822 isOpenMPTeamsDirective(DVar.DKind))) { 13823 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 13824 << getOpenMPDirectiveName(DVar.DKind); 13825 reportOriginalDsa(*this, DSAStack, D, DVar); 13826 continue; 13827 } 13828 } 13829 13830 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13831 // A list item cannot appear in both a map clause and a data-sharing 13832 // attribute clause on the same construct 13833 // 13834 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13835 // A list item cannot appear in both a map clause and a data-sharing 13836 // attribute clause on the same construct unless the construct is a 13837 // combined construct. 13838 if ((LangOpts.OpenMP <= 45 && 13839 isOpenMPTargetExecutionDirective(CurrDir)) || 13840 CurrDir == OMPD_target) { 13841 OpenMPClauseKind ConflictKind; 13842 if (DSAStack->checkMappableExprComponentListsForDecl( 13843 VD, /*CurrentRegionOnly=*/true, 13844 [&ConflictKind]( 13845 OMPClauseMappableExprCommon::MappableExprComponentListRef, 13846 OpenMPClauseKind WhereFoundClauseKind) { 13847 ConflictKind = WhereFoundClauseKind; 13848 return true; 13849 })) { 13850 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13851 << getOpenMPClauseName(OMPC_firstprivate) 13852 << getOpenMPClauseName(ConflictKind) 13853 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13854 reportOriginalDsa(*this, DSAStack, D, DVar); 13855 continue; 13856 } 13857 } 13858 } 13859 13860 // Variably modified types are not supported for tasks. 13861 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13862 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 13863 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13864 << getOpenMPClauseName(OMPC_firstprivate) << Type 13865 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13866 bool IsDecl = 13867 !VD || 13868 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13869 Diag(D->getLocation(), 13870 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13871 << D; 13872 continue; 13873 } 13874 13875 Type = Type.getUnqualifiedType(); 13876 VarDecl *VDPrivate = 13877 buildVarDecl(*this, ELoc, Type, D->getName(), 13878 D->hasAttrs() ? &D->getAttrs() : nullptr, 13879 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13880 // Generate helper private variable and initialize it with the value of the 13881 // original variable. The address of the original variable is replaced by 13882 // the address of the new private variable in the CodeGen. This new variable 13883 // is not added to IdResolver, so the code in the OpenMP region uses 13884 // original variable for proper diagnostics and variable capturing. 13885 Expr *VDInitRefExpr = nullptr; 13886 // For arrays generate initializer for single element and replace it by the 13887 // original array element in CodeGen. 13888 if (Type->isArrayType()) { 13889 VarDecl *VDInit = 13890 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 13891 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 13892 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 13893 ElemType = ElemType.getUnqualifiedType(); 13894 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 13895 ".firstprivate.temp"); 13896 InitializedEntity Entity = 13897 InitializedEntity::InitializeVariable(VDInitTemp); 13898 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 13899 13900 InitializationSequence InitSeq(*this, Entity, Kind, Init); 13901 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 13902 if (Result.isInvalid()) 13903 VDPrivate->setInvalidDecl(); 13904 else 13905 VDPrivate->setInit(Result.getAs<Expr>()); 13906 // Remove temp variable declaration. 13907 Context.Deallocate(VDInitTemp); 13908 } else { 13909 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 13910 ".firstprivate.temp"); 13911 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 13912 RefExpr->getExprLoc()); 13913 AddInitializerToDecl(VDPrivate, 13914 DefaultLvalueConversion(VDInitRefExpr).get(), 13915 /*DirectInit=*/false); 13916 } 13917 if (VDPrivate->isInvalidDecl()) { 13918 if (IsImplicitClause) { 13919 Diag(RefExpr->getExprLoc(), 13920 diag::note_omp_task_predetermined_firstprivate_here); 13921 } 13922 continue; 13923 } 13924 CurContext->addDecl(VDPrivate); 13925 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13926 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 13927 RefExpr->getExprLoc()); 13928 DeclRefExpr *Ref = nullptr; 13929 if (!VD && !CurContext->isDependentContext()) { 13930 if (TopDVar.CKind == OMPC_lastprivate) { 13931 Ref = TopDVar.PrivateCopy; 13932 } else { 13933 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13934 if (!isOpenMPCapturedDecl(D)) 13935 ExprCaptures.push_back(Ref->getDecl()); 13936 } 13937 } 13938 if (!IsImplicitClause) 13939 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13940 Vars.push_back((VD || CurContext->isDependentContext()) 13941 ? RefExpr->IgnoreParens() 13942 : Ref); 13943 PrivateCopies.push_back(VDPrivateRefExpr); 13944 Inits.push_back(VDInitRefExpr); 13945 } 13946 13947 if (Vars.empty()) 13948 return nullptr; 13949 13950 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13951 Vars, PrivateCopies, Inits, 13952 buildPreInits(Context, ExprCaptures)); 13953 } 13954 13955 OMPClause *Sema::ActOnOpenMPLastprivateClause( 13956 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 13957 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 13958 SourceLocation LParenLoc, SourceLocation EndLoc) { 13959 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 13960 assert(ColonLoc.isValid() && "Colon location must be valid."); 13961 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 13962 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 13963 /*Last=*/OMPC_LASTPRIVATE_unknown) 13964 << getOpenMPClauseName(OMPC_lastprivate); 13965 return nullptr; 13966 } 13967 13968 SmallVector<Expr *, 8> Vars; 13969 SmallVector<Expr *, 8> SrcExprs; 13970 SmallVector<Expr *, 8> DstExprs; 13971 SmallVector<Expr *, 8> AssignmentOps; 13972 SmallVector<Decl *, 4> ExprCaptures; 13973 SmallVector<Expr *, 4> ExprPostUpdates; 13974 for (Expr *RefExpr : VarList) { 13975 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13976 SourceLocation ELoc; 13977 SourceRange ERange; 13978 Expr *SimpleRefExpr = RefExpr; 13979 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13980 if (Res.second) { 13981 // It will be analyzed later. 13982 Vars.push_back(RefExpr); 13983 SrcExprs.push_back(nullptr); 13984 DstExprs.push_back(nullptr); 13985 AssignmentOps.push_back(nullptr); 13986 } 13987 ValueDecl *D = Res.first; 13988 if (!D) 13989 continue; 13990 13991 QualType Type = D->getType(); 13992 auto *VD = dyn_cast<VarDecl>(D); 13993 13994 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 13995 // A variable that appears in a lastprivate clause must not have an 13996 // incomplete type or a reference type. 13997 if (RequireCompleteType(ELoc, Type, 13998 diag::err_omp_lastprivate_incomplete_type)) 13999 continue; 14000 Type = Type.getNonReferenceType(); 14001 14002 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 14003 // A variable that is privatized must not have a const-qualified type 14004 // unless it is of class type with a mutable member. This restriction does 14005 // not apply to the firstprivate clause. 14006 // 14007 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 14008 // A variable that appears in a lastprivate clause must not have a 14009 // const-qualified type unless it is of class type with a mutable member. 14010 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 14011 continue; 14012 14013 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 14014 // A list item that appears in a lastprivate clause with the conditional 14015 // modifier must be a scalar variable. 14016 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 14017 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 14018 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14019 VarDecl::DeclarationOnly; 14020 Diag(D->getLocation(), 14021 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14022 << D; 14023 continue; 14024 } 14025 14026 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 14027 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14028 // in a Construct] 14029 // Variables with the predetermined data-sharing attributes may not be 14030 // listed in data-sharing attributes clauses, except for the cases 14031 // listed below. 14032 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 14033 // A list item may appear in a firstprivate or lastprivate clause but not 14034 // both. 14035 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14036 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 14037 (isOpenMPDistributeDirective(CurrDir) || 14038 DVar.CKind != OMPC_firstprivate) && 14039 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 14040 Diag(ELoc, diag::err_omp_wrong_dsa) 14041 << getOpenMPClauseName(DVar.CKind) 14042 << getOpenMPClauseName(OMPC_lastprivate); 14043 reportOriginalDsa(*this, DSAStack, D, DVar); 14044 continue; 14045 } 14046 14047 // OpenMP [2.14.3.5, Restrictions, p.2] 14048 // A list item that is private within a parallel region, or that appears in 14049 // the reduction clause of a parallel construct, must not appear in a 14050 // lastprivate clause on a worksharing construct if any of the corresponding 14051 // worksharing regions ever binds to any of the corresponding parallel 14052 // regions. 14053 DSAStackTy::DSAVarData TopDVar = DVar; 14054 if (isOpenMPWorksharingDirective(CurrDir) && 14055 !isOpenMPParallelDirective(CurrDir) && 14056 !isOpenMPTeamsDirective(CurrDir)) { 14057 DVar = DSAStack->getImplicitDSA(D, true); 14058 if (DVar.CKind != OMPC_shared) { 14059 Diag(ELoc, diag::err_omp_required_access) 14060 << getOpenMPClauseName(OMPC_lastprivate) 14061 << getOpenMPClauseName(OMPC_shared); 14062 reportOriginalDsa(*this, DSAStack, D, DVar); 14063 continue; 14064 } 14065 } 14066 14067 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 14068 // A variable of class type (or array thereof) that appears in a 14069 // lastprivate clause requires an accessible, unambiguous default 14070 // constructor for the class type, unless the list item is also specified 14071 // in a firstprivate clause. 14072 // A variable of class type (or array thereof) that appears in a 14073 // lastprivate clause requires an accessible, unambiguous copy assignment 14074 // operator for the class type. 14075 Type = Context.getBaseElementType(Type).getNonReferenceType(); 14076 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 14077 Type.getUnqualifiedType(), ".lastprivate.src", 14078 D->hasAttrs() ? &D->getAttrs() : nullptr); 14079 DeclRefExpr *PseudoSrcExpr = 14080 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 14081 VarDecl *DstVD = 14082 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 14083 D->hasAttrs() ? &D->getAttrs() : nullptr); 14084 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14085 // For arrays generate assignment operation for single element and replace 14086 // it by the original array element in CodeGen. 14087 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 14088 PseudoDstExpr, PseudoSrcExpr); 14089 if (AssignmentOp.isInvalid()) 14090 continue; 14091 AssignmentOp = 14092 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14093 if (AssignmentOp.isInvalid()) 14094 continue; 14095 14096 DeclRefExpr *Ref = nullptr; 14097 if (!VD && !CurContext->isDependentContext()) { 14098 if (TopDVar.CKind == OMPC_firstprivate) { 14099 Ref = TopDVar.PrivateCopy; 14100 } else { 14101 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14102 if (!isOpenMPCapturedDecl(D)) 14103 ExprCaptures.push_back(Ref->getDecl()); 14104 } 14105 if (TopDVar.CKind == OMPC_firstprivate || 14106 (!isOpenMPCapturedDecl(D) && 14107 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 14108 ExprResult RefRes = DefaultLvalueConversion(Ref); 14109 if (!RefRes.isUsable()) 14110 continue; 14111 ExprResult PostUpdateRes = 14112 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14113 RefRes.get()); 14114 if (!PostUpdateRes.isUsable()) 14115 continue; 14116 ExprPostUpdates.push_back( 14117 IgnoredValueConversions(PostUpdateRes.get()).get()); 14118 } 14119 } 14120 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 14121 Vars.push_back((VD || CurContext->isDependentContext()) 14122 ? RefExpr->IgnoreParens() 14123 : Ref); 14124 SrcExprs.push_back(PseudoSrcExpr); 14125 DstExprs.push_back(PseudoDstExpr); 14126 AssignmentOps.push_back(AssignmentOp.get()); 14127 } 14128 14129 if (Vars.empty()) 14130 return nullptr; 14131 14132 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14133 Vars, SrcExprs, DstExprs, AssignmentOps, 14134 LPKind, LPKindLoc, ColonLoc, 14135 buildPreInits(Context, ExprCaptures), 14136 buildPostUpdate(*this, ExprPostUpdates)); 14137 } 14138 14139 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 14140 SourceLocation StartLoc, 14141 SourceLocation LParenLoc, 14142 SourceLocation EndLoc) { 14143 SmallVector<Expr *, 8> Vars; 14144 for (Expr *RefExpr : VarList) { 14145 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 14146 SourceLocation ELoc; 14147 SourceRange ERange; 14148 Expr *SimpleRefExpr = RefExpr; 14149 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14150 if (Res.second) { 14151 // It will be analyzed later. 14152 Vars.push_back(RefExpr); 14153 } 14154 ValueDecl *D = Res.first; 14155 if (!D) 14156 continue; 14157 14158 auto *VD = dyn_cast<VarDecl>(D); 14159 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 14160 // in a Construct] 14161 // Variables with the predetermined data-sharing attributes may not be 14162 // listed in data-sharing attributes clauses, except for the cases 14163 // listed below. For these exceptions only, listing a predetermined 14164 // variable in a data-sharing attribute clause is allowed and overrides 14165 // the variable's predetermined data-sharing attributes. 14166 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14167 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 14168 DVar.RefExpr) { 14169 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14170 << getOpenMPClauseName(OMPC_shared); 14171 reportOriginalDsa(*this, DSAStack, D, DVar); 14172 continue; 14173 } 14174 14175 DeclRefExpr *Ref = nullptr; 14176 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 14177 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14178 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 14179 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 14180 ? RefExpr->IgnoreParens() 14181 : Ref); 14182 } 14183 14184 if (Vars.empty()) 14185 return nullptr; 14186 14187 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 14188 } 14189 14190 namespace { 14191 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 14192 DSAStackTy *Stack; 14193 14194 public: 14195 bool VisitDeclRefExpr(DeclRefExpr *E) { 14196 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 14197 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 14198 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 14199 return false; 14200 if (DVar.CKind != OMPC_unknown) 14201 return true; 14202 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 14203 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 14204 /*FromParent=*/true); 14205 return DVarPrivate.CKind != OMPC_unknown; 14206 } 14207 return false; 14208 } 14209 bool VisitStmt(Stmt *S) { 14210 for (Stmt *Child : S->children()) { 14211 if (Child && Visit(Child)) 14212 return true; 14213 } 14214 return false; 14215 } 14216 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 14217 }; 14218 } // namespace 14219 14220 namespace { 14221 // Transform MemberExpression for specified FieldDecl of current class to 14222 // DeclRefExpr to specified OMPCapturedExprDecl. 14223 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 14224 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 14225 ValueDecl *Field = nullptr; 14226 DeclRefExpr *CapturedExpr = nullptr; 14227 14228 public: 14229 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 14230 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 14231 14232 ExprResult TransformMemberExpr(MemberExpr *E) { 14233 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 14234 E->getMemberDecl() == Field) { 14235 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 14236 return CapturedExpr; 14237 } 14238 return BaseTransform::TransformMemberExpr(E); 14239 } 14240 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 14241 }; 14242 } // namespace 14243 14244 template <typename T, typename U> 14245 static T filterLookupForUDReductionAndMapper( 14246 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 14247 for (U &Set : Lookups) { 14248 for (auto *D : Set) { 14249 if (T Res = Gen(cast<ValueDecl>(D))) 14250 return Res; 14251 } 14252 } 14253 return T(); 14254 } 14255 14256 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 14257 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 14258 14259 for (auto RD : D->redecls()) { 14260 // Don't bother with extra checks if we already know this one isn't visible. 14261 if (RD == D) 14262 continue; 14263 14264 auto ND = cast<NamedDecl>(RD); 14265 if (LookupResult::isVisible(SemaRef, ND)) 14266 return ND; 14267 } 14268 14269 return nullptr; 14270 } 14271 14272 static void 14273 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 14274 SourceLocation Loc, QualType Ty, 14275 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 14276 // Find all of the associated namespaces and classes based on the 14277 // arguments we have. 14278 Sema::AssociatedNamespaceSet AssociatedNamespaces; 14279 Sema::AssociatedClassSet AssociatedClasses; 14280 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 14281 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 14282 AssociatedClasses); 14283 14284 // C++ [basic.lookup.argdep]p3: 14285 // Let X be the lookup set produced by unqualified lookup (3.4.1) 14286 // and let Y be the lookup set produced by argument dependent 14287 // lookup (defined as follows). If X contains [...] then Y is 14288 // empty. Otherwise Y is the set of declarations found in the 14289 // namespaces associated with the argument types as described 14290 // below. The set of declarations found by the lookup of the name 14291 // is the union of X and Y. 14292 // 14293 // Here, we compute Y and add its members to the overloaded 14294 // candidate set. 14295 for (auto *NS : AssociatedNamespaces) { 14296 // When considering an associated namespace, the lookup is the 14297 // same as the lookup performed when the associated namespace is 14298 // used as a qualifier (3.4.3.2) except that: 14299 // 14300 // -- Any using-directives in the associated namespace are 14301 // ignored. 14302 // 14303 // -- Any namespace-scope friend functions declared in 14304 // associated classes are visible within their respective 14305 // namespaces even if they are not visible during an ordinary 14306 // lookup (11.4). 14307 DeclContext::lookup_result R = NS->lookup(Id.getName()); 14308 for (auto *D : R) { 14309 auto *Underlying = D; 14310 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14311 Underlying = USD->getTargetDecl(); 14312 14313 if (!isa<OMPDeclareReductionDecl>(Underlying) && 14314 !isa<OMPDeclareMapperDecl>(Underlying)) 14315 continue; 14316 14317 if (!SemaRef.isVisible(D)) { 14318 D = findAcceptableDecl(SemaRef, D); 14319 if (!D) 14320 continue; 14321 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14322 Underlying = USD->getTargetDecl(); 14323 } 14324 Lookups.emplace_back(); 14325 Lookups.back().addDecl(Underlying); 14326 } 14327 } 14328 } 14329 14330 static ExprResult 14331 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 14332 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 14333 const DeclarationNameInfo &ReductionId, QualType Ty, 14334 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 14335 if (ReductionIdScopeSpec.isInvalid()) 14336 return ExprError(); 14337 SmallVector<UnresolvedSet<8>, 4> Lookups; 14338 if (S) { 14339 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14340 Lookup.suppressDiagnostics(); 14341 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 14342 NamedDecl *D = Lookup.getRepresentativeDecl(); 14343 do { 14344 S = S->getParent(); 14345 } while (S && !S->isDeclScope(D)); 14346 if (S) 14347 S = S->getParent(); 14348 Lookups.emplace_back(); 14349 Lookups.back().append(Lookup.begin(), Lookup.end()); 14350 Lookup.clear(); 14351 } 14352 } else if (auto *ULE = 14353 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 14354 Lookups.push_back(UnresolvedSet<8>()); 14355 Decl *PrevD = nullptr; 14356 for (NamedDecl *D : ULE->decls()) { 14357 if (D == PrevD) 14358 Lookups.push_back(UnresolvedSet<8>()); 14359 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 14360 Lookups.back().addDecl(DRD); 14361 PrevD = D; 14362 } 14363 } 14364 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 14365 Ty->isInstantiationDependentType() || 14366 Ty->containsUnexpandedParameterPack() || 14367 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14368 return !D->isInvalidDecl() && 14369 (D->getType()->isDependentType() || 14370 D->getType()->isInstantiationDependentType() || 14371 D->getType()->containsUnexpandedParameterPack()); 14372 })) { 14373 UnresolvedSet<8> ResSet; 14374 for (const UnresolvedSet<8> &Set : Lookups) { 14375 if (Set.empty()) 14376 continue; 14377 ResSet.append(Set.begin(), Set.end()); 14378 // The last item marks the end of all declarations at the specified scope. 14379 ResSet.addDecl(Set[Set.size() - 1]); 14380 } 14381 return UnresolvedLookupExpr::Create( 14382 SemaRef.Context, /*NamingClass=*/nullptr, 14383 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 14384 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 14385 } 14386 // Lookup inside the classes. 14387 // C++ [over.match.oper]p3: 14388 // For a unary operator @ with an operand of a type whose 14389 // cv-unqualified version is T1, and for a binary operator @ with 14390 // a left operand of a type whose cv-unqualified version is T1 and 14391 // a right operand of a type whose cv-unqualified version is T2, 14392 // three sets of candidate functions, designated member 14393 // candidates, non-member candidates and built-in candidates, are 14394 // constructed as follows: 14395 // -- If T1 is a complete class type or a class currently being 14396 // defined, the set of member candidates is the result of the 14397 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 14398 // the set of member candidates is empty. 14399 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14400 Lookup.suppressDiagnostics(); 14401 if (const auto *TyRec = Ty->getAs<RecordType>()) { 14402 // Complete the type if it can be completed. 14403 // If the type is neither complete nor being defined, bail out now. 14404 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 14405 TyRec->getDecl()->getDefinition()) { 14406 Lookup.clear(); 14407 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 14408 if (Lookup.empty()) { 14409 Lookups.emplace_back(); 14410 Lookups.back().append(Lookup.begin(), Lookup.end()); 14411 } 14412 } 14413 } 14414 // Perform ADL. 14415 if (SemaRef.getLangOpts().CPlusPlus) 14416 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 14417 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14418 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 14419 if (!D->isInvalidDecl() && 14420 SemaRef.Context.hasSameType(D->getType(), Ty)) 14421 return D; 14422 return nullptr; 14423 })) 14424 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 14425 VK_LValue, Loc); 14426 if (SemaRef.getLangOpts().CPlusPlus) { 14427 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14428 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 14429 if (!D->isInvalidDecl() && 14430 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 14431 !Ty.isMoreQualifiedThan(D->getType())) 14432 return D; 14433 return nullptr; 14434 })) { 14435 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14436 /*DetectVirtual=*/false); 14437 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 14438 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14439 VD->getType().getUnqualifiedType()))) { 14440 if (SemaRef.CheckBaseClassAccess( 14441 Loc, VD->getType(), Ty, Paths.front(), 14442 /*DiagID=*/0) != Sema::AR_inaccessible) { 14443 SemaRef.BuildBasePathArray(Paths, BasePath); 14444 return SemaRef.BuildDeclRefExpr( 14445 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 14446 } 14447 } 14448 } 14449 } 14450 } 14451 if (ReductionIdScopeSpec.isSet()) { 14452 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 14453 << Ty << Range; 14454 return ExprError(); 14455 } 14456 return ExprEmpty(); 14457 } 14458 14459 namespace { 14460 /// Data for the reduction-based clauses. 14461 struct ReductionData { 14462 /// List of original reduction items. 14463 SmallVector<Expr *, 8> Vars; 14464 /// List of private copies of the reduction items. 14465 SmallVector<Expr *, 8> Privates; 14466 /// LHS expressions for the reduction_op expressions. 14467 SmallVector<Expr *, 8> LHSs; 14468 /// RHS expressions for the reduction_op expressions. 14469 SmallVector<Expr *, 8> RHSs; 14470 /// Reduction operation expression. 14471 SmallVector<Expr *, 8> ReductionOps; 14472 /// inscan copy operation expressions. 14473 SmallVector<Expr *, 8> InscanCopyOps; 14474 /// inscan copy temp array expressions for prefix sums. 14475 SmallVector<Expr *, 8> InscanCopyArrayTemps; 14476 /// inscan copy temp array element expressions for prefix sums. 14477 SmallVector<Expr *, 8> InscanCopyArrayElems; 14478 /// Taskgroup descriptors for the corresponding reduction items in 14479 /// in_reduction clauses. 14480 SmallVector<Expr *, 8> TaskgroupDescriptors; 14481 /// List of captures for clause. 14482 SmallVector<Decl *, 4> ExprCaptures; 14483 /// List of postupdate expressions. 14484 SmallVector<Expr *, 4> ExprPostUpdates; 14485 /// Reduction modifier. 14486 unsigned RedModifier = 0; 14487 ReductionData() = delete; 14488 /// Reserves required memory for the reduction data. 14489 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 14490 Vars.reserve(Size); 14491 Privates.reserve(Size); 14492 LHSs.reserve(Size); 14493 RHSs.reserve(Size); 14494 ReductionOps.reserve(Size); 14495 if (RedModifier == OMPC_REDUCTION_inscan) { 14496 InscanCopyOps.reserve(Size); 14497 InscanCopyArrayTemps.reserve(Size); 14498 InscanCopyArrayElems.reserve(Size); 14499 } 14500 TaskgroupDescriptors.reserve(Size); 14501 ExprCaptures.reserve(Size); 14502 ExprPostUpdates.reserve(Size); 14503 } 14504 /// Stores reduction item and reduction operation only (required for dependent 14505 /// reduction item). 14506 void push(Expr *Item, Expr *ReductionOp) { 14507 Vars.emplace_back(Item); 14508 Privates.emplace_back(nullptr); 14509 LHSs.emplace_back(nullptr); 14510 RHSs.emplace_back(nullptr); 14511 ReductionOps.emplace_back(ReductionOp); 14512 TaskgroupDescriptors.emplace_back(nullptr); 14513 if (RedModifier == OMPC_REDUCTION_inscan) { 14514 InscanCopyOps.push_back(nullptr); 14515 InscanCopyArrayTemps.push_back(nullptr); 14516 InscanCopyArrayElems.push_back(nullptr); 14517 } 14518 } 14519 /// Stores reduction data. 14520 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 14521 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, 14522 Expr *CopyArrayElem) { 14523 Vars.emplace_back(Item); 14524 Privates.emplace_back(Private); 14525 LHSs.emplace_back(LHS); 14526 RHSs.emplace_back(RHS); 14527 ReductionOps.emplace_back(ReductionOp); 14528 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 14529 if (RedModifier == OMPC_REDUCTION_inscan) { 14530 InscanCopyOps.push_back(CopyOp); 14531 InscanCopyArrayTemps.push_back(CopyArrayTemp); 14532 InscanCopyArrayElems.push_back(CopyArrayElem); 14533 } else { 14534 assert(CopyOp == nullptr && CopyArrayTemp == nullptr && 14535 CopyArrayElem == nullptr && 14536 "Copy operation must be used for inscan reductions only."); 14537 } 14538 } 14539 }; 14540 } // namespace 14541 14542 static bool checkOMPArraySectionConstantForReduction( 14543 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 14544 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 14545 const Expr *Length = OASE->getLength(); 14546 if (Length == nullptr) { 14547 // For array sections of the form [1:] or [:], we would need to analyze 14548 // the lower bound... 14549 if (OASE->getColonLoc().isValid()) 14550 return false; 14551 14552 // This is an array subscript which has implicit length 1! 14553 SingleElement = true; 14554 ArraySizes.push_back(llvm::APSInt::get(1)); 14555 } else { 14556 Expr::EvalResult Result; 14557 if (!Length->EvaluateAsInt(Result, Context)) 14558 return false; 14559 14560 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14561 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 14562 ArraySizes.push_back(ConstantLengthValue); 14563 } 14564 14565 // Get the base of this array section and walk up from there. 14566 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 14567 14568 // We require length = 1 for all array sections except the right-most to 14569 // guarantee that the memory region is contiguous and has no holes in it. 14570 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 14571 Length = TempOASE->getLength(); 14572 if (Length == nullptr) { 14573 // For array sections of the form [1:] or [:], we would need to analyze 14574 // the lower bound... 14575 if (OASE->getColonLoc().isValid()) 14576 return false; 14577 14578 // This is an array subscript which has implicit length 1! 14579 ArraySizes.push_back(llvm::APSInt::get(1)); 14580 } else { 14581 Expr::EvalResult Result; 14582 if (!Length->EvaluateAsInt(Result, Context)) 14583 return false; 14584 14585 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14586 if (ConstantLengthValue.getSExtValue() != 1) 14587 return false; 14588 14589 ArraySizes.push_back(ConstantLengthValue); 14590 } 14591 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 14592 } 14593 14594 // If we have a single element, we don't need to add the implicit lengths. 14595 if (!SingleElement) { 14596 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 14597 // Has implicit length 1! 14598 ArraySizes.push_back(llvm::APSInt::get(1)); 14599 Base = TempASE->getBase()->IgnoreParenImpCasts(); 14600 } 14601 } 14602 14603 // This array section can be privatized as a single value or as a constant 14604 // sized array. 14605 return true; 14606 } 14607 14608 static bool actOnOMPReductionKindClause( 14609 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 14610 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14611 SourceLocation ColonLoc, SourceLocation EndLoc, 14612 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14613 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 14614 DeclarationName DN = ReductionId.getName(); 14615 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 14616 BinaryOperatorKind BOK = BO_Comma; 14617 14618 ASTContext &Context = S.Context; 14619 // OpenMP [2.14.3.6, reduction clause] 14620 // C 14621 // reduction-identifier is either an identifier or one of the following 14622 // operators: +, -, *, &, |, ^, && and || 14623 // C++ 14624 // reduction-identifier is either an id-expression or one of the following 14625 // operators: +, -, *, &, |, ^, && and || 14626 switch (OOK) { 14627 case OO_Plus: 14628 case OO_Minus: 14629 BOK = BO_Add; 14630 break; 14631 case OO_Star: 14632 BOK = BO_Mul; 14633 break; 14634 case OO_Amp: 14635 BOK = BO_And; 14636 break; 14637 case OO_Pipe: 14638 BOK = BO_Or; 14639 break; 14640 case OO_Caret: 14641 BOK = BO_Xor; 14642 break; 14643 case OO_AmpAmp: 14644 BOK = BO_LAnd; 14645 break; 14646 case OO_PipePipe: 14647 BOK = BO_LOr; 14648 break; 14649 case OO_New: 14650 case OO_Delete: 14651 case OO_Array_New: 14652 case OO_Array_Delete: 14653 case OO_Slash: 14654 case OO_Percent: 14655 case OO_Tilde: 14656 case OO_Exclaim: 14657 case OO_Equal: 14658 case OO_Less: 14659 case OO_Greater: 14660 case OO_LessEqual: 14661 case OO_GreaterEqual: 14662 case OO_PlusEqual: 14663 case OO_MinusEqual: 14664 case OO_StarEqual: 14665 case OO_SlashEqual: 14666 case OO_PercentEqual: 14667 case OO_CaretEqual: 14668 case OO_AmpEqual: 14669 case OO_PipeEqual: 14670 case OO_LessLess: 14671 case OO_GreaterGreater: 14672 case OO_LessLessEqual: 14673 case OO_GreaterGreaterEqual: 14674 case OO_EqualEqual: 14675 case OO_ExclaimEqual: 14676 case OO_Spaceship: 14677 case OO_PlusPlus: 14678 case OO_MinusMinus: 14679 case OO_Comma: 14680 case OO_ArrowStar: 14681 case OO_Arrow: 14682 case OO_Call: 14683 case OO_Subscript: 14684 case OO_Conditional: 14685 case OO_Coawait: 14686 case NUM_OVERLOADED_OPERATORS: 14687 llvm_unreachable("Unexpected reduction identifier"); 14688 case OO_None: 14689 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 14690 if (II->isStr("max")) 14691 BOK = BO_GT; 14692 else if (II->isStr("min")) 14693 BOK = BO_LT; 14694 } 14695 break; 14696 } 14697 SourceRange ReductionIdRange; 14698 if (ReductionIdScopeSpec.isValid()) 14699 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 14700 else 14701 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 14702 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 14703 14704 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 14705 bool FirstIter = true; 14706 for (Expr *RefExpr : VarList) { 14707 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 14708 // OpenMP [2.1, C/C++] 14709 // A list item is a variable or array section, subject to the restrictions 14710 // specified in Section 2.4 on page 42 and in each of the sections 14711 // describing clauses and directives for which a list appears. 14712 // OpenMP [2.14.3.3, Restrictions, p.1] 14713 // A variable that is part of another variable (as an array or 14714 // structure element) cannot appear in a private clause. 14715 if (!FirstIter && IR != ER) 14716 ++IR; 14717 FirstIter = false; 14718 SourceLocation ELoc; 14719 SourceRange ERange; 14720 Expr *SimpleRefExpr = RefExpr; 14721 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 14722 /*AllowArraySection=*/true); 14723 if (Res.second) { 14724 // Try to find 'declare reduction' corresponding construct before using 14725 // builtin/overloaded operators. 14726 QualType Type = Context.DependentTy; 14727 CXXCastPath BasePath; 14728 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14729 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14730 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14731 Expr *ReductionOp = nullptr; 14732 if (S.CurContext->isDependentContext() && 14733 (DeclareReductionRef.isUnset() || 14734 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 14735 ReductionOp = DeclareReductionRef.get(); 14736 // It will be analyzed later. 14737 RD.push(RefExpr, ReductionOp); 14738 } 14739 ValueDecl *D = Res.first; 14740 if (!D) 14741 continue; 14742 14743 Expr *TaskgroupDescriptor = nullptr; 14744 QualType Type; 14745 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 14746 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 14747 if (ASE) { 14748 Type = ASE->getType().getNonReferenceType(); 14749 } else if (OASE) { 14750 QualType BaseType = 14751 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 14752 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 14753 Type = ATy->getElementType(); 14754 else 14755 Type = BaseType->getPointeeType(); 14756 Type = Type.getNonReferenceType(); 14757 } else { 14758 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 14759 } 14760 auto *VD = dyn_cast<VarDecl>(D); 14761 14762 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 14763 // A variable that appears in a private clause must not have an incomplete 14764 // type or a reference type. 14765 if (S.RequireCompleteType(ELoc, D->getType(), 14766 diag::err_omp_reduction_incomplete_type)) 14767 continue; 14768 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14769 // A list item that appears in a reduction clause must not be 14770 // const-qualified. 14771 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 14772 /*AcceptIfMutable*/ false, ASE || OASE)) 14773 continue; 14774 14775 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 14776 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 14777 // If a list-item is a reference type then it must bind to the same object 14778 // for all threads of the team. 14779 if (!ASE && !OASE) { 14780 if (VD) { 14781 VarDecl *VDDef = VD->getDefinition(); 14782 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 14783 DSARefChecker Check(Stack); 14784 if (Check.Visit(VDDef->getInit())) { 14785 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 14786 << getOpenMPClauseName(ClauseKind) << ERange; 14787 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 14788 continue; 14789 } 14790 } 14791 } 14792 14793 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14794 // in a Construct] 14795 // Variables with the predetermined data-sharing attributes may not be 14796 // listed in data-sharing attributes clauses, except for the cases 14797 // listed below. For these exceptions only, listing a predetermined 14798 // variable in a data-sharing attribute clause is allowed and overrides 14799 // the variable's predetermined data-sharing attributes. 14800 // OpenMP [2.14.3.6, Restrictions, p.3] 14801 // Any number of reduction clauses can be specified on the directive, 14802 // but a list item can appear only once in the reduction clauses for that 14803 // directive. 14804 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 14805 if (DVar.CKind == OMPC_reduction) { 14806 S.Diag(ELoc, diag::err_omp_once_referenced) 14807 << getOpenMPClauseName(ClauseKind); 14808 if (DVar.RefExpr) 14809 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 14810 continue; 14811 } 14812 if (DVar.CKind != OMPC_unknown) { 14813 S.Diag(ELoc, diag::err_omp_wrong_dsa) 14814 << getOpenMPClauseName(DVar.CKind) 14815 << getOpenMPClauseName(OMPC_reduction); 14816 reportOriginalDsa(S, Stack, D, DVar); 14817 continue; 14818 } 14819 14820 // OpenMP [2.14.3.6, Restrictions, p.1] 14821 // A list item that appears in a reduction clause of a worksharing 14822 // construct must be shared in the parallel regions to which any of the 14823 // worksharing regions arising from the worksharing construct bind. 14824 if (isOpenMPWorksharingDirective(CurrDir) && 14825 !isOpenMPParallelDirective(CurrDir) && 14826 !isOpenMPTeamsDirective(CurrDir)) { 14827 DVar = Stack->getImplicitDSA(D, true); 14828 if (DVar.CKind != OMPC_shared) { 14829 S.Diag(ELoc, diag::err_omp_required_access) 14830 << getOpenMPClauseName(OMPC_reduction) 14831 << getOpenMPClauseName(OMPC_shared); 14832 reportOriginalDsa(S, Stack, D, DVar); 14833 continue; 14834 } 14835 } 14836 } 14837 14838 // Try to find 'declare reduction' corresponding construct before using 14839 // builtin/overloaded operators. 14840 CXXCastPath BasePath; 14841 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14842 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14843 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14844 if (DeclareReductionRef.isInvalid()) 14845 continue; 14846 if (S.CurContext->isDependentContext() && 14847 (DeclareReductionRef.isUnset() || 14848 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 14849 RD.push(RefExpr, DeclareReductionRef.get()); 14850 continue; 14851 } 14852 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 14853 // Not allowed reduction identifier is found. 14854 S.Diag(ReductionId.getBeginLoc(), 14855 diag::err_omp_unknown_reduction_identifier) 14856 << Type << ReductionIdRange; 14857 continue; 14858 } 14859 14860 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14861 // The type of a list item that appears in a reduction clause must be valid 14862 // for the reduction-identifier. For a max or min reduction in C, the type 14863 // of the list item must be an allowed arithmetic data type: char, int, 14864 // float, double, or _Bool, possibly modified with long, short, signed, or 14865 // unsigned. For a max or min reduction in C++, the type of the list item 14866 // must be an allowed arithmetic data type: char, wchar_t, int, float, 14867 // double, or bool, possibly modified with long, short, signed, or unsigned. 14868 if (DeclareReductionRef.isUnset()) { 14869 if ((BOK == BO_GT || BOK == BO_LT) && 14870 !(Type->isScalarType() || 14871 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 14872 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 14873 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 14874 if (!ASE && !OASE) { 14875 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14876 VarDecl::DeclarationOnly; 14877 S.Diag(D->getLocation(), 14878 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14879 << D; 14880 } 14881 continue; 14882 } 14883 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 14884 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 14885 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 14886 << getOpenMPClauseName(ClauseKind); 14887 if (!ASE && !OASE) { 14888 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14889 VarDecl::DeclarationOnly; 14890 S.Diag(D->getLocation(), 14891 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14892 << D; 14893 } 14894 continue; 14895 } 14896 } 14897 14898 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 14899 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 14900 D->hasAttrs() ? &D->getAttrs() : nullptr); 14901 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 14902 D->hasAttrs() ? &D->getAttrs() : nullptr); 14903 QualType PrivateTy = Type; 14904 14905 // Try if we can determine constant lengths for all array sections and avoid 14906 // the VLA. 14907 bool ConstantLengthOASE = false; 14908 if (OASE) { 14909 bool SingleElement; 14910 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 14911 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 14912 Context, OASE, SingleElement, ArraySizes); 14913 14914 // If we don't have a single element, we must emit a constant array type. 14915 if (ConstantLengthOASE && !SingleElement) { 14916 for (llvm::APSInt &Size : ArraySizes) 14917 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 14918 ArrayType::Normal, 14919 /*IndexTypeQuals=*/0); 14920 } 14921 } 14922 14923 if ((OASE && !ConstantLengthOASE) || 14924 (!OASE && !ASE && 14925 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 14926 if (!Context.getTargetInfo().isVLASupported()) { 14927 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 14928 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14929 S.Diag(ELoc, diag::note_vla_unsupported); 14930 continue; 14931 } else { 14932 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14933 S.targetDiag(ELoc, diag::note_vla_unsupported); 14934 } 14935 } 14936 // For arrays/array sections only: 14937 // Create pseudo array type for private copy. The size for this array will 14938 // be generated during codegen. 14939 // For array subscripts or single variables Private Ty is the same as Type 14940 // (type of the variable or single array element). 14941 PrivateTy = Context.getVariableArrayType( 14942 Type, 14943 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 14944 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 14945 } else if (!ASE && !OASE && 14946 Context.getAsArrayType(D->getType().getNonReferenceType())) { 14947 PrivateTy = D->getType().getNonReferenceType(); 14948 } 14949 // Private copy. 14950 VarDecl *PrivateVD = 14951 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 14952 D->hasAttrs() ? &D->getAttrs() : nullptr, 14953 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14954 // Add initializer for private variable. 14955 Expr *Init = nullptr; 14956 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 14957 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 14958 if (DeclareReductionRef.isUsable()) { 14959 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 14960 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 14961 if (DRD->getInitializer()) { 14962 Init = DRDRef; 14963 RHSVD->setInit(DRDRef); 14964 RHSVD->setInitStyle(VarDecl::CallInit); 14965 } 14966 } else { 14967 switch (BOK) { 14968 case BO_Add: 14969 case BO_Xor: 14970 case BO_Or: 14971 case BO_LOr: 14972 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 14973 if (Type->isScalarType() || Type->isAnyComplexType()) 14974 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 14975 break; 14976 case BO_Mul: 14977 case BO_LAnd: 14978 if (Type->isScalarType() || Type->isAnyComplexType()) { 14979 // '*' and '&&' reduction ops - initializer is '1'. 14980 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 14981 } 14982 break; 14983 case BO_And: { 14984 // '&' reduction op - initializer is '~0'. 14985 QualType OrigType = Type; 14986 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 14987 Type = ComplexTy->getElementType(); 14988 if (Type->isRealFloatingType()) { 14989 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( 14990 Context.getFloatTypeSemantics(Type), 14991 Context.getTypeSize(Type)); 14992 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14993 Type, ELoc); 14994 } else if (Type->isScalarType()) { 14995 uint64_t Size = Context.getTypeSize(Type); 14996 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 14997 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 14998 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14999 } 15000 if (Init && OrigType->isAnyComplexType()) { 15001 // Init = 0xFFFF + 0xFFFFi; 15002 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 15003 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 15004 } 15005 Type = OrigType; 15006 break; 15007 } 15008 case BO_LT: 15009 case BO_GT: { 15010 // 'min' reduction op - initializer is 'Largest representable number in 15011 // the reduction list item type'. 15012 // 'max' reduction op - initializer is 'Least representable number in 15013 // the reduction list item type'. 15014 if (Type->isIntegerType() || Type->isPointerType()) { 15015 bool IsSigned = Type->hasSignedIntegerRepresentation(); 15016 uint64_t Size = Context.getTypeSize(Type); 15017 QualType IntTy = 15018 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 15019 llvm::APInt InitValue = 15020 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 15021 : llvm::APInt::getMinValue(Size) 15022 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 15023 : llvm::APInt::getMaxValue(Size); 15024 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 15025 if (Type->isPointerType()) { 15026 // Cast to pointer type. 15027 ExprResult CastExpr = S.BuildCStyleCastExpr( 15028 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 15029 if (CastExpr.isInvalid()) 15030 continue; 15031 Init = CastExpr.get(); 15032 } 15033 } else if (Type->isRealFloatingType()) { 15034 llvm::APFloat InitValue = llvm::APFloat::getLargest( 15035 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 15036 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 15037 Type, ELoc); 15038 } 15039 break; 15040 } 15041 case BO_PtrMemD: 15042 case BO_PtrMemI: 15043 case BO_MulAssign: 15044 case BO_Div: 15045 case BO_Rem: 15046 case BO_Sub: 15047 case BO_Shl: 15048 case BO_Shr: 15049 case BO_LE: 15050 case BO_GE: 15051 case BO_EQ: 15052 case BO_NE: 15053 case BO_Cmp: 15054 case BO_AndAssign: 15055 case BO_XorAssign: 15056 case BO_OrAssign: 15057 case BO_Assign: 15058 case BO_AddAssign: 15059 case BO_SubAssign: 15060 case BO_DivAssign: 15061 case BO_RemAssign: 15062 case BO_ShlAssign: 15063 case BO_ShrAssign: 15064 case BO_Comma: 15065 llvm_unreachable("Unexpected reduction operation"); 15066 } 15067 } 15068 if (Init && DeclareReductionRef.isUnset()) 15069 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 15070 else if (!Init) 15071 S.ActOnUninitializedDecl(RHSVD); 15072 if (RHSVD->isInvalidDecl()) 15073 continue; 15074 if (!RHSVD->hasInit() && 15075 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 15076 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 15077 << Type << ReductionIdRange; 15078 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 15079 VarDecl::DeclarationOnly; 15080 S.Diag(D->getLocation(), 15081 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15082 << D; 15083 continue; 15084 } 15085 // Store initializer for single element in private copy. Will be used during 15086 // codegen. 15087 PrivateVD->setInit(RHSVD->getInit()); 15088 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 15089 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 15090 ExprResult ReductionOp; 15091 if (DeclareReductionRef.isUsable()) { 15092 QualType RedTy = DeclareReductionRef.get()->getType(); 15093 QualType PtrRedTy = Context.getPointerType(RedTy); 15094 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 15095 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 15096 if (!BasePath.empty()) { 15097 LHS = S.DefaultLvalueConversion(LHS.get()); 15098 RHS = S.DefaultLvalueConversion(RHS.get()); 15099 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 15100 CK_UncheckedDerivedToBase, LHS.get(), 15101 &BasePath, LHS.get()->getValueKind()); 15102 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 15103 CK_UncheckedDerivedToBase, RHS.get(), 15104 &BasePath, RHS.get()->getValueKind()); 15105 } 15106 FunctionProtoType::ExtProtoInfo EPI; 15107 QualType Params[] = {PtrRedTy, PtrRedTy}; 15108 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 15109 auto *OVE = new (Context) OpaqueValueExpr( 15110 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 15111 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 15112 Expr *Args[] = {LHS.get(), RHS.get()}; 15113 ReductionOp = 15114 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 15115 } else { 15116 ReductionOp = S.BuildBinOp( 15117 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 15118 if (ReductionOp.isUsable()) { 15119 if (BOK != BO_LT && BOK != BO_GT) { 15120 ReductionOp = 15121 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15122 BO_Assign, LHSDRE, ReductionOp.get()); 15123 } else { 15124 auto *ConditionalOp = new (Context) 15125 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 15126 Type, VK_LValue, OK_Ordinary); 15127 ReductionOp = 15128 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15129 BO_Assign, LHSDRE, ConditionalOp); 15130 } 15131 if (ReductionOp.isUsable()) 15132 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 15133 /*DiscardedValue*/ false); 15134 } 15135 if (!ReductionOp.isUsable()) 15136 continue; 15137 } 15138 15139 // Add copy operations for inscan reductions. 15140 // LHS = RHS; 15141 ExprResult CopyOpRes, TempArrayRes, TempArrayElem; 15142 if (ClauseKind == OMPC_reduction && 15143 RD.RedModifier == OMPC_REDUCTION_inscan) { 15144 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); 15145 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, 15146 RHS.get()); 15147 if (!CopyOpRes.isUsable()) 15148 continue; 15149 CopyOpRes = 15150 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); 15151 if (!CopyOpRes.isUsable()) 15152 continue; 15153 // For simd directive and simd-based directives in simd mode no need to 15154 // construct temp array, need just a single temp element. 15155 if (Stack->getCurrentDirective() == OMPD_simd || 15156 (S.getLangOpts().OpenMPSimd && 15157 isOpenMPSimdDirective(Stack->getCurrentDirective()))) { 15158 VarDecl *TempArrayVD = 15159 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 15160 D->hasAttrs() ? &D->getAttrs() : nullptr); 15161 // Add a constructor to the temp decl. 15162 S.ActOnUninitializedDecl(TempArrayVD); 15163 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); 15164 } else { 15165 // Build temp array for prefix sum. 15166 auto *Dim = new (S.Context) 15167 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); 15168 QualType ArrayTy = 15169 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal, 15170 /*IndexTypeQuals=*/0, {ELoc, ELoc}); 15171 VarDecl *TempArrayVD = 15172 buildVarDecl(S, ELoc, ArrayTy, D->getName(), 15173 D->hasAttrs() ? &D->getAttrs() : nullptr); 15174 // Add a constructor to the temp decl. 15175 S.ActOnUninitializedDecl(TempArrayVD); 15176 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); 15177 TempArrayElem = 15178 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); 15179 auto *Idx = new (S.Context) 15180 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_RValue); 15181 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), 15182 ELoc, Idx, ELoc); 15183 } 15184 } 15185 15186 // OpenMP [2.15.4.6, Restrictions, p.2] 15187 // A list item that appears in an in_reduction clause of a task construct 15188 // must appear in a task_reduction clause of a construct associated with a 15189 // taskgroup region that includes the participating task in its taskgroup 15190 // set. The construct associated with the innermost region that meets this 15191 // condition must specify the same reduction-identifier as the in_reduction 15192 // clause. 15193 if (ClauseKind == OMPC_in_reduction) { 15194 SourceRange ParentSR; 15195 BinaryOperatorKind ParentBOK; 15196 const Expr *ParentReductionOp = nullptr; 15197 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 15198 DSAStackTy::DSAVarData ParentBOKDSA = 15199 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 15200 ParentBOKTD); 15201 DSAStackTy::DSAVarData ParentReductionOpDSA = 15202 Stack->getTopMostTaskgroupReductionData( 15203 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 15204 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 15205 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 15206 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 15207 (DeclareReductionRef.isUsable() && IsParentBOK) || 15208 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 15209 bool EmitError = true; 15210 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 15211 llvm::FoldingSetNodeID RedId, ParentRedId; 15212 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 15213 DeclareReductionRef.get()->Profile(RedId, Context, 15214 /*Canonical=*/true); 15215 EmitError = RedId != ParentRedId; 15216 } 15217 if (EmitError) { 15218 S.Diag(ReductionId.getBeginLoc(), 15219 diag::err_omp_reduction_identifier_mismatch) 15220 << ReductionIdRange << RefExpr->getSourceRange(); 15221 S.Diag(ParentSR.getBegin(), 15222 diag::note_omp_previous_reduction_identifier) 15223 << ParentSR 15224 << (IsParentBOK ? ParentBOKDSA.RefExpr 15225 : ParentReductionOpDSA.RefExpr) 15226 ->getSourceRange(); 15227 continue; 15228 } 15229 } 15230 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 15231 } 15232 15233 DeclRefExpr *Ref = nullptr; 15234 Expr *VarsExpr = RefExpr->IgnoreParens(); 15235 if (!VD && !S.CurContext->isDependentContext()) { 15236 if (ASE || OASE) { 15237 TransformExprToCaptures RebuildToCapture(S, D); 15238 VarsExpr = 15239 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 15240 Ref = RebuildToCapture.getCapturedExpr(); 15241 } else { 15242 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 15243 } 15244 if (!S.isOpenMPCapturedDecl(D)) { 15245 RD.ExprCaptures.emplace_back(Ref->getDecl()); 15246 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15247 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 15248 if (!RefRes.isUsable()) 15249 continue; 15250 ExprResult PostUpdateRes = 15251 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 15252 RefRes.get()); 15253 if (!PostUpdateRes.isUsable()) 15254 continue; 15255 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 15256 Stack->getCurrentDirective() == OMPD_taskgroup) { 15257 S.Diag(RefExpr->getExprLoc(), 15258 diag::err_omp_reduction_non_addressable_expression) 15259 << RefExpr->getSourceRange(); 15260 continue; 15261 } 15262 RD.ExprPostUpdates.emplace_back( 15263 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 15264 } 15265 } 15266 } 15267 // All reduction items are still marked as reduction (to do not increase 15268 // code base size). 15269 unsigned Modifier = RD.RedModifier; 15270 // Consider task_reductions as reductions with task modifier. Required for 15271 // correct analysis of in_reduction clauses. 15272 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 15273 Modifier = OMPC_REDUCTION_task; 15274 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier); 15275 if (Modifier == OMPC_REDUCTION_task && 15276 (CurrDir == OMPD_taskgroup || 15277 ((isOpenMPParallelDirective(CurrDir) || 15278 isOpenMPWorksharingDirective(CurrDir)) && 15279 !isOpenMPSimdDirective(CurrDir)))) { 15280 if (DeclareReductionRef.isUsable()) 15281 Stack->addTaskgroupReductionData(D, ReductionIdRange, 15282 DeclareReductionRef.get()); 15283 else 15284 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 15285 } 15286 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 15287 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), 15288 TempArrayElem.get()); 15289 } 15290 return RD.Vars.empty(); 15291 } 15292 15293 OMPClause *Sema::ActOnOpenMPReductionClause( 15294 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 15295 SourceLocation StartLoc, SourceLocation LParenLoc, 15296 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 15297 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15298 ArrayRef<Expr *> UnresolvedReductions) { 15299 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 15300 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 15301 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 15302 /*Last=*/OMPC_REDUCTION_unknown) 15303 << getOpenMPClauseName(OMPC_reduction); 15304 return nullptr; 15305 } 15306 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 15307 // A reduction clause with the inscan reduction-modifier may only appear on a 15308 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 15309 // construct, a parallel worksharing-loop construct or a parallel 15310 // worksharing-loop SIMD construct. 15311 if (Modifier == OMPC_REDUCTION_inscan && 15312 (DSAStack->getCurrentDirective() != OMPD_for && 15313 DSAStack->getCurrentDirective() != OMPD_for_simd && 15314 DSAStack->getCurrentDirective() != OMPD_simd && 15315 DSAStack->getCurrentDirective() != OMPD_parallel_for && 15316 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 15317 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 15318 return nullptr; 15319 } 15320 15321 ReductionData RD(VarList.size(), Modifier); 15322 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 15323 StartLoc, LParenLoc, ColonLoc, EndLoc, 15324 ReductionIdScopeSpec, ReductionId, 15325 UnresolvedReductions, RD)) 15326 return nullptr; 15327 15328 return OMPReductionClause::Create( 15329 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 15330 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15331 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, 15332 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, 15333 buildPreInits(Context, RD.ExprCaptures), 15334 buildPostUpdate(*this, RD.ExprPostUpdates)); 15335 } 15336 15337 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 15338 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15339 SourceLocation ColonLoc, SourceLocation EndLoc, 15340 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15341 ArrayRef<Expr *> UnresolvedReductions) { 15342 ReductionData RD(VarList.size()); 15343 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 15344 StartLoc, LParenLoc, ColonLoc, EndLoc, 15345 ReductionIdScopeSpec, ReductionId, 15346 UnresolvedReductions, RD)) 15347 return nullptr; 15348 15349 return OMPTaskReductionClause::Create( 15350 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15351 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15352 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 15353 buildPreInits(Context, RD.ExprCaptures), 15354 buildPostUpdate(*this, RD.ExprPostUpdates)); 15355 } 15356 15357 OMPClause *Sema::ActOnOpenMPInReductionClause( 15358 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15359 SourceLocation ColonLoc, SourceLocation EndLoc, 15360 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15361 ArrayRef<Expr *> UnresolvedReductions) { 15362 ReductionData RD(VarList.size()); 15363 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 15364 StartLoc, LParenLoc, ColonLoc, EndLoc, 15365 ReductionIdScopeSpec, ReductionId, 15366 UnresolvedReductions, RD)) 15367 return nullptr; 15368 15369 return OMPInReductionClause::Create( 15370 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15371 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15372 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 15373 buildPreInits(Context, RD.ExprCaptures), 15374 buildPostUpdate(*this, RD.ExprPostUpdates)); 15375 } 15376 15377 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 15378 SourceLocation LinLoc) { 15379 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 15380 LinKind == OMPC_LINEAR_unknown) { 15381 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 15382 return true; 15383 } 15384 return false; 15385 } 15386 15387 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 15388 OpenMPLinearClauseKind LinKind, QualType Type, 15389 bool IsDeclareSimd) { 15390 const auto *VD = dyn_cast_or_null<VarDecl>(D); 15391 // A variable must not have an incomplete type or a reference type. 15392 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 15393 return true; 15394 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 15395 !Type->isReferenceType()) { 15396 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 15397 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 15398 return true; 15399 } 15400 Type = Type.getNonReferenceType(); 15401 15402 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 15403 // A variable that is privatized must not have a const-qualified type 15404 // unless it is of class type with a mutable member. This restriction does 15405 // not apply to the firstprivate clause, nor to the linear clause on 15406 // declarative directives (like declare simd). 15407 if (!IsDeclareSimd && 15408 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 15409 return true; 15410 15411 // A list item must be of integral or pointer type. 15412 Type = Type.getUnqualifiedType().getCanonicalType(); 15413 const auto *Ty = Type.getTypePtrOrNull(); 15414 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 15415 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 15416 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 15417 if (D) { 15418 bool IsDecl = 15419 !VD || 15420 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15421 Diag(D->getLocation(), 15422 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15423 << D; 15424 } 15425 return true; 15426 } 15427 return false; 15428 } 15429 15430 OMPClause *Sema::ActOnOpenMPLinearClause( 15431 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 15432 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 15433 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15434 SmallVector<Expr *, 8> Vars; 15435 SmallVector<Expr *, 8> Privates; 15436 SmallVector<Expr *, 8> Inits; 15437 SmallVector<Decl *, 4> ExprCaptures; 15438 SmallVector<Expr *, 4> ExprPostUpdates; 15439 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 15440 LinKind = OMPC_LINEAR_val; 15441 for (Expr *RefExpr : VarList) { 15442 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15443 SourceLocation ELoc; 15444 SourceRange ERange; 15445 Expr *SimpleRefExpr = RefExpr; 15446 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15447 if (Res.second) { 15448 // It will be analyzed later. 15449 Vars.push_back(RefExpr); 15450 Privates.push_back(nullptr); 15451 Inits.push_back(nullptr); 15452 } 15453 ValueDecl *D = Res.first; 15454 if (!D) 15455 continue; 15456 15457 QualType Type = D->getType(); 15458 auto *VD = dyn_cast<VarDecl>(D); 15459 15460 // OpenMP [2.14.3.7, linear clause] 15461 // A list-item cannot appear in more than one linear clause. 15462 // A list-item that appears in a linear clause cannot appear in any 15463 // other data-sharing attribute clause. 15464 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15465 if (DVar.RefExpr) { 15466 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 15467 << getOpenMPClauseName(OMPC_linear); 15468 reportOriginalDsa(*this, DSAStack, D, DVar); 15469 continue; 15470 } 15471 15472 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 15473 continue; 15474 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15475 15476 // Build private copy of original var. 15477 VarDecl *Private = 15478 buildVarDecl(*this, ELoc, Type, D->getName(), 15479 D->hasAttrs() ? &D->getAttrs() : nullptr, 15480 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15481 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 15482 // Build var to save initial value. 15483 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 15484 Expr *InitExpr; 15485 DeclRefExpr *Ref = nullptr; 15486 if (!VD && !CurContext->isDependentContext()) { 15487 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15488 if (!isOpenMPCapturedDecl(D)) { 15489 ExprCaptures.push_back(Ref->getDecl()); 15490 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15491 ExprResult RefRes = DefaultLvalueConversion(Ref); 15492 if (!RefRes.isUsable()) 15493 continue; 15494 ExprResult PostUpdateRes = 15495 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 15496 SimpleRefExpr, RefRes.get()); 15497 if (!PostUpdateRes.isUsable()) 15498 continue; 15499 ExprPostUpdates.push_back( 15500 IgnoredValueConversions(PostUpdateRes.get()).get()); 15501 } 15502 } 15503 } 15504 if (LinKind == OMPC_LINEAR_uval) 15505 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 15506 else 15507 InitExpr = VD ? SimpleRefExpr : Ref; 15508 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 15509 /*DirectInit=*/false); 15510 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 15511 15512 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 15513 Vars.push_back((VD || CurContext->isDependentContext()) 15514 ? RefExpr->IgnoreParens() 15515 : Ref); 15516 Privates.push_back(PrivateRef); 15517 Inits.push_back(InitRef); 15518 } 15519 15520 if (Vars.empty()) 15521 return nullptr; 15522 15523 Expr *StepExpr = Step; 15524 Expr *CalcStepExpr = nullptr; 15525 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 15526 !Step->isInstantiationDependent() && 15527 !Step->containsUnexpandedParameterPack()) { 15528 SourceLocation StepLoc = Step->getBeginLoc(); 15529 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 15530 if (Val.isInvalid()) 15531 return nullptr; 15532 StepExpr = Val.get(); 15533 15534 // Build var to save the step value. 15535 VarDecl *SaveVar = 15536 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 15537 ExprResult SaveRef = 15538 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 15539 ExprResult CalcStep = 15540 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 15541 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 15542 15543 // Warn about zero linear step (it would be probably better specified as 15544 // making corresponding variables 'const'). 15545 llvm::APSInt Result; 15546 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 15547 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 15548 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 15549 << (Vars.size() > 1); 15550 if (!IsConstant && CalcStep.isUsable()) { 15551 // Calculate the step beforehand instead of doing this on each iteration. 15552 // (This is not used if the number of iterations may be kfold-ed). 15553 CalcStepExpr = CalcStep.get(); 15554 } 15555 } 15556 15557 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 15558 ColonLoc, EndLoc, Vars, Privates, Inits, 15559 StepExpr, CalcStepExpr, 15560 buildPreInits(Context, ExprCaptures), 15561 buildPostUpdate(*this, ExprPostUpdates)); 15562 } 15563 15564 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 15565 Expr *NumIterations, Sema &SemaRef, 15566 Scope *S, DSAStackTy *Stack) { 15567 // Walk the vars and build update/final expressions for the CodeGen. 15568 SmallVector<Expr *, 8> Updates; 15569 SmallVector<Expr *, 8> Finals; 15570 SmallVector<Expr *, 8> UsedExprs; 15571 Expr *Step = Clause.getStep(); 15572 Expr *CalcStep = Clause.getCalcStep(); 15573 // OpenMP [2.14.3.7, linear clause] 15574 // If linear-step is not specified it is assumed to be 1. 15575 if (!Step) 15576 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 15577 else if (CalcStep) 15578 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 15579 bool HasErrors = false; 15580 auto CurInit = Clause.inits().begin(); 15581 auto CurPrivate = Clause.privates().begin(); 15582 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 15583 for (Expr *RefExpr : Clause.varlists()) { 15584 SourceLocation ELoc; 15585 SourceRange ERange; 15586 Expr *SimpleRefExpr = RefExpr; 15587 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 15588 ValueDecl *D = Res.first; 15589 if (Res.second || !D) { 15590 Updates.push_back(nullptr); 15591 Finals.push_back(nullptr); 15592 HasErrors = true; 15593 continue; 15594 } 15595 auto &&Info = Stack->isLoopControlVariable(D); 15596 // OpenMP [2.15.11, distribute simd Construct] 15597 // A list item may not appear in a linear clause, unless it is the loop 15598 // iteration variable. 15599 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 15600 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 15601 SemaRef.Diag(ELoc, 15602 diag::err_omp_linear_distribute_var_non_loop_iteration); 15603 Updates.push_back(nullptr); 15604 Finals.push_back(nullptr); 15605 HasErrors = true; 15606 continue; 15607 } 15608 Expr *InitExpr = *CurInit; 15609 15610 // Build privatized reference to the current linear var. 15611 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 15612 Expr *CapturedRef; 15613 if (LinKind == OMPC_LINEAR_uval) 15614 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 15615 else 15616 CapturedRef = 15617 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 15618 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 15619 /*RefersToCapture=*/true); 15620 15621 // Build update: Var = InitExpr + IV * Step 15622 ExprResult Update; 15623 if (!Info.first) 15624 Update = buildCounterUpdate( 15625 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 15626 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 15627 else 15628 Update = *CurPrivate; 15629 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 15630 /*DiscardedValue*/ false); 15631 15632 // Build final: Var = InitExpr + NumIterations * Step 15633 ExprResult Final; 15634 if (!Info.first) 15635 Final = 15636 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 15637 InitExpr, NumIterations, Step, /*Subtract=*/false, 15638 /*IsNonRectangularLB=*/false); 15639 else 15640 Final = *CurPrivate; 15641 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 15642 /*DiscardedValue*/ false); 15643 15644 if (!Update.isUsable() || !Final.isUsable()) { 15645 Updates.push_back(nullptr); 15646 Finals.push_back(nullptr); 15647 UsedExprs.push_back(nullptr); 15648 HasErrors = true; 15649 } else { 15650 Updates.push_back(Update.get()); 15651 Finals.push_back(Final.get()); 15652 if (!Info.first) 15653 UsedExprs.push_back(SimpleRefExpr); 15654 } 15655 ++CurInit; 15656 ++CurPrivate; 15657 } 15658 if (Expr *S = Clause.getStep()) 15659 UsedExprs.push_back(S); 15660 // Fill the remaining part with the nullptr. 15661 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 15662 Clause.setUpdates(Updates); 15663 Clause.setFinals(Finals); 15664 Clause.setUsedExprs(UsedExprs); 15665 return HasErrors; 15666 } 15667 15668 OMPClause *Sema::ActOnOpenMPAlignedClause( 15669 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 15670 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15671 SmallVector<Expr *, 8> Vars; 15672 for (Expr *RefExpr : VarList) { 15673 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15674 SourceLocation ELoc; 15675 SourceRange ERange; 15676 Expr *SimpleRefExpr = RefExpr; 15677 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15678 if (Res.second) { 15679 // It will be analyzed later. 15680 Vars.push_back(RefExpr); 15681 } 15682 ValueDecl *D = Res.first; 15683 if (!D) 15684 continue; 15685 15686 QualType QType = D->getType(); 15687 auto *VD = dyn_cast<VarDecl>(D); 15688 15689 // OpenMP [2.8.1, simd construct, Restrictions] 15690 // The type of list items appearing in the aligned clause must be 15691 // array, pointer, reference to array, or reference to pointer. 15692 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15693 const Type *Ty = QType.getTypePtrOrNull(); 15694 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 15695 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 15696 << QType << getLangOpts().CPlusPlus << ERange; 15697 bool IsDecl = 15698 !VD || 15699 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15700 Diag(D->getLocation(), 15701 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15702 << D; 15703 continue; 15704 } 15705 15706 // OpenMP [2.8.1, simd construct, Restrictions] 15707 // A list-item cannot appear in more than one aligned clause. 15708 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 15709 Diag(ELoc, diag::err_omp_used_in_clause_twice) 15710 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 15711 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 15712 << getOpenMPClauseName(OMPC_aligned); 15713 continue; 15714 } 15715 15716 DeclRefExpr *Ref = nullptr; 15717 if (!VD && isOpenMPCapturedDecl(D)) 15718 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15719 Vars.push_back(DefaultFunctionArrayConversion( 15720 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 15721 .get()); 15722 } 15723 15724 // OpenMP [2.8.1, simd construct, Description] 15725 // The parameter of the aligned clause, alignment, must be a constant 15726 // positive integer expression. 15727 // If no optional parameter is specified, implementation-defined default 15728 // alignments for SIMD instructions on the target platforms are assumed. 15729 if (Alignment != nullptr) { 15730 ExprResult AlignResult = 15731 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 15732 if (AlignResult.isInvalid()) 15733 return nullptr; 15734 Alignment = AlignResult.get(); 15735 } 15736 if (Vars.empty()) 15737 return nullptr; 15738 15739 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 15740 EndLoc, Vars, Alignment); 15741 } 15742 15743 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 15744 SourceLocation StartLoc, 15745 SourceLocation LParenLoc, 15746 SourceLocation EndLoc) { 15747 SmallVector<Expr *, 8> Vars; 15748 SmallVector<Expr *, 8> SrcExprs; 15749 SmallVector<Expr *, 8> DstExprs; 15750 SmallVector<Expr *, 8> AssignmentOps; 15751 for (Expr *RefExpr : VarList) { 15752 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 15753 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15754 // It will be analyzed later. 15755 Vars.push_back(RefExpr); 15756 SrcExprs.push_back(nullptr); 15757 DstExprs.push_back(nullptr); 15758 AssignmentOps.push_back(nullptr); 15759 continue; 15760 } 15761 15762 SourceLocation ELoc = RefExpr->getExprLoc(); 15763 // OpenMP [2.1, C/C++] 15764 // A list item is a variable name. 15765 // OpenMP [2.14.4.1, Restrictions, p.1] 15766 // A list item that appears in a copyin clause must be threadprivate. 15767 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 15768 if (!DE || !isa<VarDecl>(DE->getDecl())) { 15769 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 15770 << 0 << RefExpr->getSourceRange(); 15771 continue; 15772 } 15773 15774 Decl *D = DE->getDecl(); 15775 auto *VD = cast<VarDecl>(D); 15776 15777 QualType Type = VD->getType(); 15778 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 15779 // It will be analyzed later. 15780 Vars.push_back(DE); 15781 SrcExprs.push_back(nullptr); 15782 DstExprs.push_back(nullptr); 15783 AssignmentOps.push_back(nullptr); 15784 continue; 15785 } 15786 15787 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 15788 // A list item that appears in a copyin clause must be threadprivate. 15789 if (!DSAStack->isThreadPrivate(VD)) { 15790 Diag(ELoc, diag::err_omp_required_access) 15791 << getOpenMPClauseName(OMPC_copyin) 15792 << getOpenMPDirectiveName(OMPD_threadprivate); 15793 continue; 15794 } 15795 15796 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15797 // A variable of class type (or array thereof) that appears in a 15798 // copyin clause requires an accessible, unambiguous copy assignment 15799 // operator for the class type. 15800 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 15801 VarDecl *SrcVD = 15802 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 15803 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15804 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 15805 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 15806 VarDecl *DstVD = 15807 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 15808 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15809 DeclRefExpr *PseudoDstExpr = 15810 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 15811 // For arrays generate assignment operation for single element and replace 15812 // it by the original array element in CodeGen. 15813 ExprResult AssignmentOp = 15814 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 15815 PseudoSrcExpr); 15816 if (AssignmentOp.isInvalid()) 15817 continue; 15818 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 15819 /*DiscardedValue*/ false); 15820 if (AssignmentOp.isInvalid()) 15821 continue; 15822 15823 DSAStack->addDSA(VD, DE, OMPC_copyin); 15824 Vars.push_back(DE); 15825 SrcExprs.push_back(PseudoSrcExpr); 15826 DstExprs.push_back(PseudoDstExpr); 15827 AssignmentOps.push_back(AssignmentOp.get()); 15828 } 15829 15830 if (Vars.empty()) 15831 return nullptr; 15832 15833 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 15834 SrcExprs, DstExprs, AssignmentOps); 15835 } 15836 15837 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 15838 SourceLocation StartLoc, 15839 SourceLocation LParenLoc, 15840 SourceLocation EndLoc) { 15841 SmallVector<Expr *, 8> Vars; 15842 SmallVector<Expr *, 8> SrcExprs; 15843 SmallVector<Expr *, 8> DstExprs; 15844 SmallVector<Expr *, 8> AssignmentOps; 15845 for (Expr *RefExpr : VarList) { 15846 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15847 SourceLocation ELoc; 15848 SourceRange ERange; 15849 Expr *SimpleRefExpr = RefExpr; 15850 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15851 if (Res.second) { 15852 // It will be analyzed later. 15853 Vars.push_back(RefExpr); 15854 SrcExprs.push_back(nullptr); 15855 DstExprs.push_back(nullptr); 15856 AssignmentOps.push_back(nullptr); 15857 } 15858 ValueDecl *D = Res.first; 15859 if (!D) 15860 continue; 15861 15862 QualType Type = D->getType(); 15863 auto *VD = dyn_cast<VarDecl>(D); 15864 15865 // OpenMP [2.14.4.2, Restrictions, p.2] 15866 // A list item that appears in a copyprivate clause may not appear in a 15867 // private or firstprivate clause on the single construct. 15868 if (!VD || !DSAStack->isThreadPrivate(VD)) { 15869 DSAStackTy::DSAVarData DVar = 15870 DSAStack->getTopDSA(D, /*FromParent=*/false); 15871 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 15872 DVar.RefExpr) { 15873 Diag(ELoc, diag::err_omp_wrong_dsa) 15874 << getOpenMPClauseName(DVar.CKind) 15875 << getOpenMPClauseName(OMPC_copyprivate); 15876 reportOriginalDsa(*this, DSAStack, D, DVar); 15877 continue; 15878 } 15879 15880 // OpenMP [2.11.4.2, Restrictions, p.1] 15881 // All list items that appear in a copyprivate clause must be either 15882 // threadprivate or private in the enclosing context. 15883 if (DVar.CKind == OMPC_unknown) { 15884 DVar = DSAStack->getImplicitDSA(D, false); 15885 if (DVar.CKind == OMPC_shared) { 15886 Diag(ELoc, diag::err_omp_required_access) 15887 << getOpenMPClauseName(OMPC_copyprivate) 15888 << "threadprivate or private in the enclosing context"; 15889 reportOriginalDsa(*this, DSAStack, D, DVar); 15890 continue; 15891 } 15892 } 15893 } 15894 15895 // Variably modified types are not supported. 15896 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 15897 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 15898 << getOpenMPClauseName(OMPC_copyprivate) << Type 15899 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15900 bool IsDecl = 15901 !VD || 15902 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15903 Diag(D->getLocation(), 15904 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15905 << D; 15906 continue; 15907 } 15908 15909 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15910 // A variable of class type (or array thereof) that appears in a 15911 // copyin clause requires an accessible, unambiguous copy assignment 15912 // operator for the class type. 15913 Type = Context.getBaseElementType(Type.getNonReferenceType()) 15914 .getUnqualifiedType(); 15915 VarDecl *SrcVD = 15916 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 15917 D->hasAttrs() ? &D->getAttrs() : nullptr); 15918 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 15919 VarDecl *DstVD = 15920 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 15921 D->hasAttrs() ? &D->getAttrs() : nullptr); 15922 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 15923 ExprResult AssignmentOp = BuildBinOp( 15924 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 15925 if (AssignmentOp.isInvalid()) 15926 continue; 15927 AssignmentOp = 15928 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 15929 if (AssignmentOp.isInvalid()) 15930 continue; 15931 15932 // No need to mark vars as copyprivate, they are already threadprivate or 15933 // implicitly private. 15934 assert(VD || isOpenMPCapturedDecl(D)); 15935 Vars.push_back( 15936 VD ? RefExpr->IgnoreParens() 15937 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 15938 SrcExprs.push_back(PseudoSrcExpr); 15939 DstExprs.push_back(PseudoDstExpr); 15940 AssignmentOps.push_back(AssignmentOp.get()); 15941 } 15942 15943 if (Vars.empty()) 15944 return nullptr; 15945 15946 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15947 Vars, SrcExprs, DstExprs, AssignmentOps); 15948 } 15949 15950 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 15951 SourceLocation StartLoc, 15952 SourceLocation LParenLoc, 15953 SourceLocation EndLoc) { 15954 if (VarList.empty()) 15955 return nullptr; 15956 15957 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 15958 } 15959 15960 /// Tries to find omp_depend_t. type. 15961 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 15962 bool Diagnose = true) { 15963 QualType OMPDependT = Stack->getOMPDependT(); 15964 if (!OMPDependT.isNull()) 15965 return true; 15966 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 15967 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 15968 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 15969 if (Diagnose) 15970 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 15971 return false; 15972 } 15973 Stack->setOMPDependT(PT.get()); 15974 return true; 15975 } 15976 15977 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 15978 SourceLocation LParenLoc, 15979 SourceLocation EndLoc) { 15980 if (!Depobj) 15981 return nullptr; 15982 15983 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 15984 15985 // OpenMP 5.0, 2.17.10.1 depobj Construct 15986 // depobj is an lvalue expression of type omp_depend_t. 15987 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 15988 !Depobj->isInstantiationDependent() && 15989 !Depobj->containsUnexpandedParameterPack() && 15990 (OMPDependTFound && 15991 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 15992 /*CompareUnqualified=*/true))) { 15993 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15994 << 0 << Depobj->getType() << Depobj->getSourceRange(); 15995 } 15996 15997 if (!Depobj->isLValue()) { 15998 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15999 << 1 << Depobj->getSourceRange(); 16000 } 16001 16002 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 16003 } 16004 16005 OMPClause * 16006 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, 16007 SourceLocation DepLoc, SourceLocation ColonLoc, 16008 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 16009 SourceLocation LParenLoc, SourceLocation EndLoc) { 16010 if (DSAStack->getCurrentDirective() == OMPD_ordered && 16011 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 16012 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 16013 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 16014 return nullptr; 16015 } 16016 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 16017 DSAStack->getCurrentDirective() == OMPD_depobj) && 16018 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 16019 DepKind == OMPC_DEPEND_sink || 16020 ((LangOpts.OpenMP < 50 || 16021 DSAStack->getCurrentDirective() == OMPD_depobj) && 16022 DepKind == OMPC_DEPEND_depobj))) { 16023 SmallVector<unsigned, 3> Except; 16024 Except.push_back(OMPC_DEPEND_source); 16025 Except.push_back(OMPC_DEPEND_sink); 16026 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 16027 Except.push_back(OMPC_DEPEND_depobj); 16028 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 16029 ? "depend modifier(iterator) or " 16030 : ""; 16031 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 16032 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 16033 /*Last=*/OMPC_DEPEND_unknown, 16034 Except) 16035 << getOpenMPClauseName(OMPC_depend); 16036 return nullptr; 16037 } 16038 if (DepModifier && 16039 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 16040 Diag(DepModifier->getExprLoc(), 16041 diag::err_omp_depend_sink_source_with_modifier); 16042 return nullptr; 16043 } 16044 if (DepModifier && 16045 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 16046 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 16047 16048 SmallVector<Expr *, 8> Vars; 16049 DSAStackTy::OperatorOffsetTy OpsOffs; 16050 llvm::APSInt DepCounter(/*BitWidth=*/32); 16051 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 16052 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 16053 if (const Expr *OrderedCountExpr = 16054 DSAStack->getParentOrderedRegionParam().first) { 16055 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 16056 TotalDepCount.setIsUnsigned(/*Val=*/true); 16057 } 16058 } 16059 for (Expr *RefExpr : VarList) { 16060 assert(RefExpr && "NULL expr in OpenMP shared clause."); 16061 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 16062 // It will be analyzed later. 16063 Vars.push_back(RefExpr); 16064 continue; 16065 } 16066 16067 SourceLocation ELoc = RefExpr->getExprLoc(); 16068 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 16069 if (DepKind == OMPC_DEPEND_sink) { 16070 if (DSAStack->getParentOrderedRegionParam().first && 16071 DepCounter >= TotalDepCount) { 16072 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 16073 continue; 16074 } 16075 ++DepCounter; 16076 // OpenMP [2.13.9, Summary] 16077 // depend(dependence-type : vec), where dependence-type is: 16078 // 'sink' and where vec is the iteration vector, which has the form: 16079 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 16080 // where n is the value specified by the ordered clause in the loop 16081 // directive, xi denotes the loop iteration variable of the i-th nested 16082 // loop associated with the loop directive, and di is a constant 16083 // non-negative integer. 16084 if (CurContext->isDependentContext()) { 16085 // It will be analyzed later. 16086 Vars.push_back(RefExpr); 16087 continue; 16088 } 16089 SimpleExpr = SimpleExpr->IgnoreImplicit(); 16090 OverloadedOperatorKind OOK = OO_None; 16091 SourceLocation OOLoc; 16092 Expr *LHS = SimpleExpr; 16093 Expr *RHS = nullptr; 16094 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 16095 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 16096 OOLoc = BO->getOperatorLoc(); 16097 LHS = BO->getLHS()->IgnoreParenImpCasts(); 16098 RHS = BO->getRHS()->IgnoreParenImpCasts(); 16099 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 16100 OOK = OCE->getOperator(); 16101 OOLoc = OCE->getOperatorLoc(); 16102 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 16103 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 16104 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 16105 OOK = MCE->getMethodDecl() 16106 ->getNameInfo() 16107 .getName() 16108 .getCXXOverloadedOperator(); 16109 OOLoc = MCE->getCallee()->getExprLoc(); 16110 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 16111 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 16112 } 16113 SourceLocation ELoc; 16114 SourceRange ERange; 16115 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 16116 if (Res.second) { 16117 // It will be analyzed later. 16118 Vars.push_back(RefExpr); 16119 } 16120 ValueDecl *D = Res.first; 16121 if (!D) 16122 continue; 16123 16124 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 16125 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 16126 continue; 16127 } 16128 if (RHS) { 16129 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 16130 RHS, OMPC_depend, /*StrictlyPositive=*/false); 16131 if (RHSRes.isInvalid()) 16132 continue; 16133 } 16134 if (!CurContext->isDependentContext() && 16135 DSAStack->getParentOrderedRegionParam().first && 16136 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 16137 const ValueDecl *VD = 16138 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 16139 if (VD) 16140 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 16141 << 1 << VD; 16142 else 16143 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 16144 continue; 16145 } 16146 OpsOffs.emplace_back(RHS, OOK); 16147 } else { 16148 bool OMPDependTFound = LangOpts.OpenMP >= 50; 16149 if (OMPDependTFound) 16150 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 16151 DepKind == OMPC_DEPEND_depobj); 16152 if (DepKind == OMPC_DEPEND_depobj) { 16153 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16154 // List items used in depend clauses with the depobj dependence type 16155 // must be expressions of the omp_depend_t type. 16156 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16157 !RefExpr->isInstantiationDependent() && 16158 !RefExpr->containsUnexpandedParameterPack() && 16159 (OMPDependTFound && 16160 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 16161 RefExpr->getType()))) { 16162 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16163 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 16164 continue; 16165 } 16166 if (!RefExpr->isLValue()) { 16167 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16168 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 16169 continue; 16170 } 16171 } else { 16172 // OpenMP 5.0 [2.17.11, Restrictions] 16173 // List items used in depend clauses cannot be zero-length array 16174 // sections. 16175 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 16176 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 16177 if (OASE) { 16178 QualType BaseType = 16179 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16180 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16181 ExprTy = ATy->getElementType(); 16182 else 16183 ExprTy = BaseType->getPointeeType(); 16184 ExprTy = ExprTy.getNonReferenceType(); 16185 const Expr *Length = OASE->getLength(); 16186 Expr::EvalResult Result; 16187 if (Length && !Length->isValueDependent() && 16188 Length->EvaluateAsInt(Result, Context) && 16189 Result.Val.getInt().isNullValue()) { 16190 Diag(ELoc, 16191 diag::err_omp_depend_zero_length_array_section_not_allowed) 16192 << SimpleExpr->getSourceRange(); 16193 continue; 16194 } 16195 } 16196 16197 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16198 // List items used in depend clauses with the in, out, inout or 16199 // mutexinoutset dependence types cannot be expressions of the 16200 // omp_depend_t type. 16201 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16202 !RefExpr->isInstantiationDependent() && 16203 !RefExpr->containsUnexpandedParameterPack() && 16204 (OMPDependTFound && 16205 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { 16206 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16207 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 16208 << RefExpr->getSourceRange(); 16209 continue; 16210 } 16211 16212 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 16213 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 16214 (ASE && !ASE->getBase()->isTypeDependent() && 16215 !ASE->getBase() 16216 ->getType() 16217 .getNonReferenceType() 16218 ->isPointerType() && 16219 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 16220 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16221 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16222 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16223 continue; 16224 } 16225 16226 ExprResult Res; 16227 { 16228 Sema::TentativeAnalysisScope Trap(*this); 16229 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 16230 RefExpr->IgnoreParenImpCasts()); 16231 } 16232 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 16233 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 16234 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16235 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16236 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16237 continue; 16238 } 16239 } 16240 } 16241 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 16242 } 16243 16244 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 16245 TotalDepCount > VarList.size() && 16246 DSAStack->getParentOrderedRegionParam().first && 16247 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 16248 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 16249 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 16250 } 16251 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 16252 Vars.empty()) 16253 return nullptr; 16254 16255 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16256 DepModifier, DepKind, DepLoc, ColonLoc, 16257 Vars, TotalDepCount.getZExtValue()); 16258 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 16259 DSAStack->isParentOrderedRegion()) 16260 DSAStack->addDoacrossDependClause(C, OpsOffs); 16261 return C; 16262 } 16263 16264 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 16265 Expr *Device, SourceLocation StartLoc, 16266 SourceLocation LParenLoc, 16267 SourceLocation ModifierLoc, 16268 SourceLocation EndLoc) { 16269 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 16270 "Unexpected device modifier in OpenMP < 50."); 16271 16272 bool ErrorFound = false; 16273 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 16274 std::string Values = 16275 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 16276 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 16277 << Values << getOpenMPClauseName(OMPC_device); 16278 ErrorFound = true; 16279 } 16280 16281 Expr *ValExpr = Device; 16282 Stmt *HelperValStmt = nullptr; 16283 16284 // OpenMP [2.9.1, Restrictions] 16285 // The device expression must evaluate to a non-negative integer value. 16286 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 16287 /*StrictlyPositive=*/false) || 16288 ErrorFound; 16289 if (ErrorFound) 16290 return nullptr; 16291 16292 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16293 OpenMPDirectiveKind CaptureRegion = 16294 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 16295 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16296 ValExpr = MakeFullExpr(ValExpr).get(); 16297 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16298 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16299 HelperValStmt = buildPreInits(Context, Captures); 16300 } 16301 16302 return new (Context) 16303 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 16304 LParenLoc, ModifierLoc, EndLoc); 16305 } 16306 16307 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 16308 DSAStackTy *Stack, QualType QTy, 16309 bool FullCheck = true) { 16310 NamedDecl *ND; 16311 if (QTy->isIncompleteType(&ND)) { 16312 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 16313 return false; 16314 } 16315 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 16316 !QTy.isTriviallyCopyableType(SemaRef.Context)) 16317 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 16318 return true; 16319 } 16320 16321 /// Return true if it can be proven that the provided array expression 16322 /// (array section or array subscript) does NOT specify the whole size of the 16323 /// array whose base type is \a BaseQTy. 16324 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 16325 const Expr *E, 16326 QualType BaseQTy) { 16327 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16328 16329 // If this is an array subscript, it refers to the whole size if the size of 16330 // the dimension is constant and equals 1. Also, an array section assumes the 16331 // format of an array subscript if no colon is used. 16332 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 16333 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16334 return ATy->getSize().getSExtValue() != 1; 16335 // Size can't be evaluated statically. 16336 return false; 16337 } 16338 16339 assert(OASE && "Expecting array section if not an array subscript."); 16340 const Expr *LowerBound = OASE->getLowerBound(); 16341 const Expr *Length = OASE->getLength(); 16342 16343 // If there is a lower bound that does not evaluates to zero, we are not 16344 // covering the whole dimension. 16345 if (LowerBound) { 16346 Expr::EvalResult Result; 16347 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 16348 return false; // Can't get the integer value as a constant. 16349 16350 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 16351 if (ConstLowerBound.getSExtValue()) 16352 return true; 16353 } 16354 16355 // If we don't have a length we covering the whole dimension. 16356 if (!Length) 16357 return false; 16358 16359 // If the base is a pointer, we don't have a way to get the size of the 16360 // pointee. 16361 if (BaseQTy->isPointerType()) 16362 return false; 16363 16364 // We can only check if the length is the same as the size of the dimension 16365 // if we have a constant array. 16366 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 16367 if (!CATy) 16368 return false; 16369 16370 Expr::EvalResult Result; 16371 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16372 return false; // Can't get the integer value as a constant. 16373 16374 llvm::APSInt ConstLength = Result.Val.getInt(); 16375 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 16376 } 16377 16378 // Return true if it can be proven that the provided array expression (array 16379 // section or array subscript) does NOT specify a single element of the array 16380 // whose base type is \a BaseQTy. 16381 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 16382 const Expr *E, 16383 QualType BaseQTy) { 16384 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16385 16386 // An array subscript always refer to a single element. Also, an array section 16387 // assumes the format of an array subscript if no colon is used. 16388 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 16389 return false; 16390 16391 assert(OASE && "Expecting array section if not an array subscript."); 16392 const Expr *Length = OASE->getLength(); 16393 16394 // If we don't have a length we have to check if the array has unitary size 16395 // for this dimension. Also, we should always expect a length if the base type 16396 // is pointer. 16397 if (!Length) { 16398 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16399 return ATy->getSize().getSExtValue() != 1; 16400 // We cannot assume anything. 16401 return false; 16402 } 16403 16404 // Check if the length evaluates to 1. 16405 Expr::EvalResult Result; 16406 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16407 return false; // Can't get the integer value as a constant. 16408 16409 llvm::APSInt ConstLength = Result.Val.getInt(); 16410 return ConstLength.getSExtValue() != 1; 16411 } 16412 16413 // The base of elements of list in a map clause have to be either: 16414 // - a reference to variable or field. 16415 // - a member expression. 16416 // - an array expression. 16417 // 16418 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 16419 // reference to 'r'. 16420 // 16421 // If we have: 16422 // 16423 // struct SS { 16424 // Bla S; 16425 // foo() { 16426 // #pragma omp target map (S.Arr[:12]); 16427 // } 16428 // } 16429 // 16430 // We want to retrieve the member expression 'this->S'; 16431 16432 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 16433 // If a list item is an array section, it must specify contiguous storage. 16434 // 16435 // For this restriction it is sufficient that we make sure only references 16436 // to variables or fields and array expressions, and that no array sections 16437 // exist except in the rightmost expression (unless they cover the whole 16438 // dimension of the array). E.g. these would be invalid: 16439 // 16440 // r.ArrS[3:5].Arr[6:7] 16441 // 16442 // r.ArrS[3:5].x 16443 // 16444 // but these would be valid: 16445 // r.ArrS[3].Arr[6:7] 16446 // 16447 // r.ArrS[3].x 16448 namespace { 16449 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 16450 Sema &SemaRef; 16451 OpenMPClauseKind CKind = OMPC_unknown; 16452 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 16453 bool NoDiagnose = false; 16454 const Expr *RelevantExpr = nullptr; 16455 bool AllowUnitySizeArraySection = true; 16456 bool AllowWholeSizeArraySection = true; 16457 SourceLocation ELoc; 16458 SourceRange ERange; 16459 16460 void emitErrorMsg() { 16461 // If nothing else worked, this is not a valid map clause expression. 16462 if (SemaRef.getLangOpts().OpenMP < 50) { 16463 SemaRef.Diag(ELoc, 16464 diag::err_omp_expected_named_var_member_or_array_expression) 16465 << ERange; 16466 } else { 16467 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16468 << getOpenMPClauseName(CKind) << ERange; 16469 } 16470 } 16471 16472 public: 16473 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 16474 if (!isa<VarDecl>(DRE->getDecl())) { 16475 emitErrorMsg(); 16476 return false; 16477 } 16478 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16479 RelevantExpr = DRE; 16480 // Record the component. 16481 Components.emplace_back(DRE, DRE->getDecl()); 16482 return true; 16483 } 16484 16485 bool VisitMemberExpr(MemberExpr *ME) { 16486 Expr *E = ME; 16487 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 16488 16489 if (isa<CXXThisExpr>(BaseE)) { 16490 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16491 // We found a base expression: this->Val. 16492 RelevantExpr = ME; 16493 } else { 16494 E = BaseE; 16495 } 16496 16497 if (!isa<FieldDecl>(ME->getMemberDecl())) { 16498 if (!NoDiagnose) { 16499 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 16500 << ME->getSourceRange(); 16501 return false; 16502 } 16503 if (RelevantExpr) 16504 return false; 16505 return Visit(E); 16506 } 16507 16508 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 16509 16510 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 16511 // A bit-field cannot appear in a map clause. 16512 // 16513 if (FD->isBitField()) { 16514 if (!NoDiagnose) { 16515 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 16516 << ME->getSourceRange() << getOpenMPClauseName(CKind); 16517 return false; 16518 } 16519 if (RelevantExpr) 16520 return false; 16521 return Visit(E); 16522 } 16523 16524 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16525 // If the type of a list item is a reference to a type T then the type 16526 // will be considered to be T for all purposes of this clause. 16527 QualType CurType = BaseE->getType().getNonReferenceType(); 16528 16529 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 16530 // A list item cannot be a variable that is a member of a structure with 16531 // a union type. 16532 // 16533 if (CurType->isUnionType()) { 16534 if (!NoDiagnose) { 16535 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 16536 << ME->getSourceRange(); 16537 return false; 16538 } 16539 return RelevantExpr || Visit(E); 16540 } 16541 16542 // If we got a member expression, we should not expect any array section 16543 // before that: 16544 // 16545 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 16546 // If a list item is an element of a structure, only the rightmost symbol 16547 // of the variable reference can be an array section. 16548 // 16549 AllowUnitySizeArraySection = false; 16550 AllowWholeSizeArraySection = false; 16551 16552 // Record the component. 16553 Components.emplace_back(ME, FD); 16554 return RelevantExpr || Visit(E); 16555 } 16556 16557 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 16558 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 16559 16560 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 16561 if (!NoDiagnose) { 16562 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16563 << 0 << AE->getSourceRange(); 16564 return false; 16565 } 16566 return RelevantExpr || Visit(E); 16567 } 16568 16569 // If we got an array subscript that express the whole dimension we 16570 // can have any array expressions before. If it only expressing part of 16571 // the dimension, we can only have unitary-size array expressions. 16572 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, 16573 E->getType())) 16574 AllowWholeSizeArraySection = false; 16575 16576 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 16577 Expr::EvalResult Result; 16578 if (!AE->getIdx()->isValueDependent() && 16579 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 16580 !Result.Val.getInt().isNullValue()) { 16581 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16582 diag::err_omp_invalid_map_this_expr); 16583 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16584 diag::note_omp_invalid_subscript_on_this_ptr_map); 16585 } 16586 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16587 RelevantExpr = TE; 16588 } 16589 16590 // Record the component - we don't have any declaration associated. 16591 Components.emplace_back(AE, nullptr); 16592 16593 return RelevantExpr || Visit(E); 16594 } 16595 16596 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 16597 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 16598 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16599 QualType CurType = 16600 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16601 16602 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16603 // If the type of a list item is a reference to a type T then the type 16604 // will be considered to be T for all purposes of this clause. 16605 if (CurType->isReferenceType()) 16606 CurType = CurType->getPointeeType(); 16607 16608 bool IsPointer = CurType->isAnyPointerType(); 16609 16610 if (!IsPointer && !CurType->isArrayType()) { 16611 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16612 << 0 << OASE->getSourceRange(); 16613 return false; 16614 } 16615 16616 bool NotWhole = 16617 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 16618 bool NotUnity = 16619 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 16620 16621 if (AllowWholeSizeArraySection) { 16622 // Any array section is currently allowed. Allowing a whole size array 16623 // section implies allowing a unity array section as well. 16624 // 16625 // If this array section refers to the whole dimension we can still 16626 // accept other array sections before this one, except if the base is a 16627 // pointer. Otherwise, only unitary sections are accepted. 16628 if (NotWhole || IsPointer) 16629 AllowWholeSizeArraySection = false; 16630 } else if (AllowUnitySizeArraySection && NotUnity) { 16631 // A unity or whole array section is not allowed and that is not 16632 // compatible with the properties of the current array section. 16633 SemaRef.Diag( 16634 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 16635 << OASE->getSourceRange(); 16636 return false; 16637 } 16638 16639 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 16640 Expr::EvalResult ResultR; 16641 Expr::EvalResult ResultL; 16642 if (!OASE->getLength()->isValueDependent() && 16643 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 16644 !ResultR.Val.getInt().isOneValue()) { 16645 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16646 diag::err_omp_invalid_map_this_expr); 16647 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16648 diag::note_omp_invalid_length_on_this_ptr_mapping); 16649 } 16650 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 16651 OASE->getLowerBound()->EvaluateAsInt(ResultL, 16652 SemaRef.getASTContext()) && 16653 !ResultL.Val.getInt().isNullValue()) { 16654 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16655 diag::err_omp_invalid_map_this_expr); 16656 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16657 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 16658 } 16659 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16660 RelevantExpr = TE; 16661 } 16662 16663 // Record the component - we don't have any declaration associated. 16664 Components.emplace_back(OASE, nullptr); 16665 return RelevantExpr || Visit(E); 16666 } 16667 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 16668 Expr *Base = E->getBase(); 16669 16670 // Record the component - we don't have any declaration associated. 16671 Components.emplace_back(E, nullptr); 16672 16673 return Visit(Base->IgnoreParenImpCasts()); 16674 } 16675 16676 bool VisitUnaryOperator(UnaryOperator *UO) { 16677 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 16678 UO->getOpcode() != UO_Deref) { 16679 emitErrorMsg(); 16680 return false; 16681 } 16682 if (!RelevantExpr) { 16683 // Record the component if haven't found base decl. 16684 Components.emplace_back(UO, nullptr); 16685 } 16686 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 16687 } 16688 bool VisitBinaryOperator(BinaryOperator *BO) { 16689 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 16690 emitErrorMsg(); 16691 return false; 16692 } 16693 16694 // Pointer arithmetic is the only thing we expect to happen here so after we 16695 // make sure the binary operator is a pointer type, the we only thing need 16696 // to to is to visit the subtree that has the same type as root (so that we 16697 // know the other subtree is just an offset) 16698 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 16699 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 16700 Components.emplace_back(BO, nullptr); 16701 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 16702 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 16703 "Either LHS or RHS have base decl inside"); 16704 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 16705 return RelevantExpr || Visit(LE); 16706 return RelevantExpr || Visit(RE); 16707 } 16708 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 16709 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16710 RelevantExpr = CTE; 16711 Components.emplace_back(CTE, nullptr); 16712 return true; 16713 } 16714 bool VisitStmt(Stmt *) { 16715 emitErrorMsg(); 16716 return false; 16717 } 16718 const Expr *getFoundBase() const { 16719 return RelevantExpr; 16720 } 16721 explicit MapBaseChecker( 16722 Sema &SemaRef, OpenMPClauseKind CKind, 16723 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 16724 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 16725 : SemaRef(SemaRef), CKind(CKind), Components(Components), 16726 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 16727 }; 16728 } // namespace 16729 16730 /// Return the expression of the base of the mappable expression or null if it 16731 /// cannot be determined and do all the necessary checks to see if the expression 16732 /// is valid as a standalone mappable expression. In the process, record all the 16733 /// components of the expression. 16734 static const Expr *checkMapClauseExpressionBase( 16735 Sema &SemaRef, Expr *E, 16736 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 16737 OpenMPClauseKind CKind, bool NoDiagnose) { 16738 SourceLocation ELoc = E->getExprLoc(); 16739 SourceRange ERange = E->getSourceRange(); 16740 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc, 16741 ERange); 16742 if (Checker.Visit(E->IgnoreParens())) 16743 return Checker.getFoundBase(); 16744 return nullptr; 16745 } 16746 16747 // Return true if expression E associated with value VD has conflicts with other 16748 // map information. 16749 static bool checkMapConflicts( 16750 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 16751 bool CurrentRegionOnly, 16752 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 16753 OpenMPClauseKind CKind) { 16754 assert(VD && E); 16755 SourceLocation ELoc = E->getExprLoc(); 16756 SourceRange ERange = E->getSourceRange(); 16757 16758 // In order to easily check the conflicts we need to match each component of 16759 // the expression under test with the components of the expressions that are 16760 // already in the stack. 16761 16762 assert(!CurComponents.empty() && "Map clause expression with no components!"); 16763 assert(CurComponents.back().getAssociatedDeclaration() == VD && 16764 "Map clause expression with unexpected base!"); 16765 16766 // Variables to help detecting enclosing problems in data environment nests. 16767 bool IsEnclosedByDataEnvironmentExpr = false; 16768 const Expr *EnclosingExpr = nullptr; 16769 16770 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 16771 VD, CurrentRegionOnly, 16772 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 16773 ERange, CKind, &EnclosingExpr, 16774 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 16775 StackComponents, 16776 OpenMPClauseKind) { 16777 assert(!StackComponents.empty() && 16778 "Map clause expression with no components!"); 16779 assert(StackComponents.back().getAssociatedDeclaration() == VD && 16780 "Map clause expression with unexpected base!"); 16781 (void)VD; 16782 16783 // The whole expression in the stack. 16784 const Expr *RE = StackComponents.front().getAssociatedExpression(); 16785 16786 // Expressions must start from the same base. Here we detect at which 16787 // point both expressions diverge from each other and see if we can 16788 // detect if the memory referred to both expressions is contiguous and 16789 // do not overlap. 16790 auto CI = CurComponents.rbegin(); 16791 auto CE = CurComponents.rend(); 16792 auto SI = StackComponents.rbegin(); 16793 auto SE = StackComponents.rend(); 16794 for (; CI != CE && SI != SE; ++CI, ++SI) { 16795 16796 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 16797 // At most one list item can be an array item derived from a given 16798 // variable in map clauses of the same construct. 16799 if (CurrentRegionOnly && 16800 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 16801 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 16802 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 16803 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 16804 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 16805 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 16806 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 16807 diag::err_omp_multiple_array_items_in_map_clause) 16808 << CI->getAssociatedExpression()->getSourceRange(); 16809 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 16810 diag::note_used_here) 16811 << SI->getAssociatedExpression()->getSourceRange(); 16812 return true; 16813 } 16814 16815 // Do both expressions have the same kind? 16816 if (CI->getAssociatedExpression()->getStmtClass() != 16817 SI->getAssociatedExpression()->getStmtClass()) 16818 break; 16819 16820 // Are we dealing with different variables/fields? 16821 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 16822 break; 16823 } 16824 // Check if the extra components of the expressions in the enclosing 16825 // data environment are redundant for the current base declaration. 16826 // If they are, the maps completely overlap, which is legal. 16827 for (; SI != SE; ++SI) { 16828 QualType Type; 16829 if (const auto *ASE = 16830 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 16831 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 16832 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 16833 SI->getAssociatedExpression())) { 16834 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16835 Type = 16836 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16837 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 16838 SI->getAssociatedExpression())) { 16839 Type = OASE->getBase()->getType()->getPointeeType(); 16840 } 16841 if (Type.isNull() || Type->isAnyPointerType() || 16842 checkArrayExpressionDoesNotReferToWholeSize( 16843 SemaRef, SI->getAssociatedExpression(), Type)) 16844 break; 16845 } 16846 16847 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16848 // List items of map clauses in the same construct must not share 16849 // original storage. 16850 // 16851 // If the expressions are exactly the same or one is a subset of the 16852 // other, it means they are sharing storage. 16853 if (CI == CE && SI == SE) { 16854 if (CurrentRegionOnly) { 16855 if (CKind == OMPC_map) { 16856 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16857 } else { 16858 assert(CKind == OMPC_to || CKind == OMPC_from); 16859 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16860 << ERange; 16861 } 16862 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16863 << RE->getSourceRange(); 16864 return true; 16865 } 16866 // If we find the same expression in the enclosing data environment, 16867 // that is legal. 16868 IsEnclosedByDataEnvironmentExpr = true; 16869 return false; 16870 } 16871 16872 QualType DerivedType = 16873 std::prev(CI)->getAssociatedDeclaration()->getType(); 16874 SourceLocation DerivedLoc = 16875 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 16876 16877 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16878 // If the type of a list item is a reference to a type T then the type 16879 // will be considered to be T for all purposes of this clause. 16880 DerivedType = DerivedType.getNonReferenceType(); 16881 16882 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 16883 // A variable for which the type is pointer and an array section 16884 // derived from that variable must not appear as list items of map 16885 // clauses of the same construct. 16886 // 16887 // Also, cover one of the cases in: 16888 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16889 // If any part of the original storage of a list item has corresponding 16890 // storage in the device data environment, all of the original storage 16891 // must have corresponding storage in the device data environment. 16892 // 16893 if (DerivedType->isAnyPointerType()) { 16894 if (CI == CE || SI == SE) { 16895 SemaRef.Diag( 16896 DerivedLoc, 16897 diag::err_omp_pointer_mapped_along_with_derived_section) 16898 << DerivedLoc; 16899 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16900 << RE->getSourceRange(); 16901 return true; 16902 } 16903 if (CI->getAssociatedExpression()->getStmtClass() != 16904 SI->getAssociatedExpression()->getStmtClass() || 16905 CI->getAssociatedDeclaration()->getCanonicalDecl() == 16906 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 16907 assert(CI != CE && SI != SE); 16908 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 16909 << DerivedLoc; 16910 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16911 << RE->getSourceRange(); 16912 return true; 16913 } 16914 } 16915 16916 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16917 // List items of map clauses in the same construct must not share 16918 // original storage. 16919 // 16920 // An expression is a subset of the other. 16921 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 16922 if (CKind == OMPC_map) { 16923 if (CI != CE || SI != SE) { 16924 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 16925 // a pointer. 16926 auto Begin = 16927 CI != CE ? CurComponents.begin() : StackComponents.begin(); 16928 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 16929 auto It = Begin; 16930 while (It != End && !It->getAssociatedDeclaration()) 16931 std::advance(It, 1); 16932 assert(It != End && 16933 "Expected at least one component with the declaration."); 16934 if (It != Begin && It->getAssociatedDeclaration() 16935 ->getType() 16936 .getCanonicalType() 16937 ->isAnyPointerType()) { 16938 IsEnclosedByDataEnvironmentExpr = false; 16939 EnclosingExpr = nullptr; 16940 return false; 16941 } 16942 } 16943 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16944 } else { 16945 assert(CKind == OMPC_to || CKind == OMPC_from); 16946 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16947 << ERange; 16948 } 16949 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16950 << RE->getSourceRange(); 16951 return true; 16952 } 16953 16954 // The current expression uses the same base as other expression in the 16955 // data environment but does not contain it completely. 16956 if (!CurrentRegionOnly && SI != SE) 16957 EnclosingExpr = RE; 16958 16959 // The current expression is a subset of the expression in the data 16960 // environment. 16961 IsEnclosedByDataEnvironmentExpr |= 16962 (!CurrentRegionOnly && CI != CE && SI == SE); 16963 16964 return false; 16965 }); 16966 16967 if (CurrentRegionOnly) 16968 return FoundError; 16969 16970 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16971 // If any part of the original storage of a list item has corresponding 16972 // storage in the device data environment, all of the original storage must 16973 // have corresponding storage in the device data environment. 16974 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 16975 // If a list item is an element of a structure, and a different element of 16976 // the structure has a corresponding list item in the device data environment 16977 // prior to a task encountering the construct associated with the map clause, 16978 // then the list item must also have a corresponding list item in the device 16979 // data environment prior to the task encountering the construct. 16980 // 16981 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 16982 SemaRef.Diag(ELoc, 16983 diag::err_omp_original_storage_is_shared_and_does_not_contain) 16984 << ERange; 16985 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 16986 << EnclosingExpr->getSourceRange(); 16987 return true; 16988 } 16989 16990 return FoundError; 16991 } 16992 16993 // Look up the user-defined mapper given the mapper name and mapped type, and 16994 // build a reference to it. 16995 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 16996 CXXScopeSpec &MapperIdScopeSpec, 16997 const DeclarationNameInfo &MapperId, 16998 QualType Type, 16999 Expr *UnresolvedMapper) { 17000 if (MapperIdScopeSpec.isInvalid()) 17001 return ExprError(); 17002 // Get the actual type for the array type. 17003 if (Type->isArrayType()) { 17004 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 17005 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 17006 } 17007 // Find all user-defined mappers with the given MapperId. 17008 SmallVector<UnresolvedSet<8>, 4> Lookups; 17009 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 17010 Lookup.suppressDiagnostics(); 17011 if (S) { 17012 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 17013 NamedDecl *D = Lookup.getRepresentativeDecl(); 17014 while (S && !S->isDeclScope(D)) 17015 S = S->getParent(); 17016 if (S) 17017 S = S->getParent(); 17018 Lookups.emplace_back(); 17019 Lookups.back().append(Lookup.begin(), Lookup.end()); 17020 Lookup.clear(); 17021 } 17022 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 17023 // Extract the user-defined mappers with the given MapperId. 17024 Lookups.push_back(UnresolvedSet<8>()); 17025 for (NamedDecl *D : ULE->decls()) { 17026 auto *DMD = cast<OMPDeclareMapperDecl>(D); 17027 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 17028 Lookups.back().addDecl(DMD); 17029 } 17030 } 17031 // Defer the lookup for dependent types. The results will be passed through 17032 // UnresolvedMapper on instantiation. 17033 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 17034 Type->isInstantiationDependentType() || 17035 Type->containsUnexpandedParameterPack() || 17036 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 17037 return !D->isInvalidDecl() && 17038 (D->getType()->isDependentType() || 17039 D->getType()->isInstantiationDependentType() || 17040 D->getType()->containsUnexpandedParameterPack()); 17041 })) { 17042 UnresolvedSet<8> URS; 17043 for (const UnresolvedSet<8> &Set : Lookups) { 17044 if (Set.empty()) 17045 continue; 17046 URS.append(Set.begin(), Set.end()); 17047 } 17048 return UnresolvedLookupExpr::Create( 17049 SemaRef.Context, /*NamingClass=*/nullptr, 17050 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 17051 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 17052 } 17053 SourceLocation Loc = MapperId.getLoc(); 17054 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17055 // The type must be of struct, union or class type in C and C++ 17056 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 17057 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 17058 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 17059 return ExprError(); 17060 } 17061 // Perform argument dependent lookup. 17062 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 17063 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 17064 // Return the first user-defined mapper with the desired type. 17065 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 17066 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 17067 if (!D->isInvalidDecl() && 17068 SemaRef.Context.hasSameType(D->getType(), Type)) 17069 return D; 17070 return nullptr; 17071 })) 17072 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 17073 // Find the first user-defined mapper with a type derived from the desired 17074 // type. 17075 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 17076 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 17077 if (!D->isInvalidDecl() && 17078 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 17079 !Type.isMoreQualifiedThan(D->getType())) 17080 return D; 17081 return nullptr; 17082 })) { 17083 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 17084 /*DetectVirtual=*/false); 17085 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 17086 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 17087 VD->getType().getUnqualifiedType()))) { 17088 if (SemaRef.CheckBaseClassAccess( 17089 Loc, VD->getType(), Type, Paths.front(), 17090 /*DiagID=*/0) != Sema::AR_inaccessible) { 17091 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 17092 } 17093 } 17094 } 17095 } 17096 // Report error if a mapper is specified, but cannot be found. 17097 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 17098 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 17099 << Type << MapperId.getName(); 17100 return ExprError(); 17101 } 17102 return ExprEmpty(); 17103 } 17104 17105 namespace { 17106 // Utility struct that gathers all the related lists associated with a mappable 17107 // expression. 17108 struct MappableVarListInfo { 17109 // The list of expressions. 17110 ArrayRef<Expr *> VarList; 17111 // The list of processed expressions. 17112 SmallVector<Expr *, 16> ProcessedVarList; 17113 // The mappble components for each expression. 17114 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 17115 // The base declaration of the variable. 17116 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 17117 // The reference to the user-defined mapper associated with every expression. 17118 SmallVector<Expr *, 16> UDMapperList; 17119 17120 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 17121 // We have a list of components and base declarations for each entry in the 17122 // variable list. 17123 VarComponents.reserve(VarList.size()); 17124 VarBaseDeclarations.reserve(VarList.size()); 17125 } 17126 }; 17127 } 17128 17129 // Check the validity of the provided variable list for the provided clause kind 17130 // \a CKind. In the check process the valid expressions, mappable expression 17131 // components, variables, and user-defined mappers are extracted and used to 17132 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 17133 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 17134 // and \a MapperId are expected to be valid if the clause kind is 'map'. 17135 static void checkMappableExpressionList( 17136 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 17137 MappableVarListInfo &MVLI, SourceLocation StartLoc, 17138 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 17139 ArrayRef<Expr *> UnresolvedMappers, 17140 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 17141 bool IsMapTypeImplicit = false) { 17142 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 17143 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 17144 "Unexpected clause kind with mappable expressions!"); 17145 17146 // If the identifier of user-defined mapper is not specified, it is "default". 17147 // We do not change the actual name in this clause to distinguish whether a 17148 // mapper is specified explicitly, i.e., it is not explicitly specified when 17149 // MapperId.getName() is empty. 17150 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 17151 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 17152 MapperId.setName(DeclNames.getIdentifier( 17153 &SemaRef.getASTContext().Idents.get("default"))); 17154 } 17155 17156 // Iterators to find the current unresolved mapper expression. 17157 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 17158 bool UpdateUMIt = false; 17159 Expr *UnresolvedMapper = nullptr; 17160 17161 // Keep track of the mappable components and base declarations in this clause. 17162 // Each entry in the list is going to have a list of components associated. We 17163 // record each set of the components so that we can build the clause later on. 17164 // In the end we should have the same amount of declarations and component 17165 // lists. 17166 17167 for (Expr *RE : MVLI.VarList) { 17168 assert(RE && "Null expr in omp to/from/map clause"); 17169 SourceLocation ELoc = RE->getExprLoc(); 17170 17171 // Find the current unresolved mapper expression. 17172 if (UpdateUMIt && UMIt != UMEnd) { 17173 UMIt++; 17174 assert( 17175 UMIt != UMEnd && 17176 "Expect the size of UnresolvedMappers to match with that of VarList"); 17177 } 17178 UpdateUMIt = true; 17179 if (UMIt != UMEnd) 17180 UnresolvedMapper = *UMIt; 17181 17182 const Expr *VE = RE->IgnoreParenLValueCasts(); 17183 17184 if (VE->isValueDependent() || VE->isTypeDependent() || 17185 VE->isInstantiationDependent() || 17186 VE->containsUnexpandedParameterPack()) { 17187 // Try to find the associated user-defined mapper. 17188 ExprResult ER = buildUserDefinedMapperRef( 17189 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17190 VE->getType().getCanonicalType(), UnresolvedMapper); 17191 if (ER.isInvalid()) 17192 continue; 17193 MVLI.UDMapperList.push_back(ER.get()); 17194 // We can only analyze this information once the missing information is 17195 // resolved. 17196 MVLI.ProcessedVarList.push_back(RE); 17197 continue; 17198 } 17199 17200 Expr *SimpleExpr = RE->IgnoreParenCasts(); 17201 17202 if (!RE->isLValue()) { 17203 if (SemaRef.getLangOpts().OpenMP < 50) { 17204 SemaRef.Diag( 17205 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 17206 << RE->getSourceRange(); 17207 } else { 17208 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 17209 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 17210 } 17211 continue; 17212 } 17213 17214 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 17215 ValueDecl *CurDeclaration = nullptr; 17216 17217 // Obtain the array or member expression bases if required. Also, fill the 17218 // components array with all the components identified in the process. 17219 const Expr *BE = checkMapClauseExpressionBase( 17220 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 17221 if (!BE) 17222 continue; 17223 17224 assert(!CurComponents.empty() && 17225 "Invalid mappable expression information."); 17226 17227 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 17228 // Add store "this" pointer to class in DSAStackTy for future checking 17229 DSAS->addMappedClassesQualTypes(TE->getType()); 17230 // Try to find the associated user-defined mapper. 17231 ExprResult ER = buildUserDefinedMapperRef( 17232 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17233 VE->getType().getCanonicalType(), UnresolvedMapper); 17234 if (ER.isInvalid()) 17235 continue; 17236 MVLI.UDMapperList.push_back(ER.get()); 17237 // Skip restriction checking for variable or field declarations 17238 MVLI.ProcessedVarList.push_back(RE); 17239 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17240 MVLI.VarComponents.back().append(CurComponents.begin(), 17241 CurComponents.end()); 17242 MVLI.VarBaseDeclarations.push_back(nullptr); 17243 continue; 17244 } 17245 17246 // For the following checks, we rely on the base declaration which is 17247 // expected to be associated with the last component. The declaration is 17248 // expected to be a variable or a field (if 'this' is being mapped). 17249 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 17250 assert(CurDeclaration && "Null decl on map clause."); 17251 assert( 17252 CurDeclaration->isCanonicalDecl() && 17253 "Expecting components to have associated only canonical declarations."); 17254 17255 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 17256 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 17257 17258 assert((VD || FD) && "Only variables or fields are expected here!"); 17259 (void)FD; 17260 17261 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 17262 // threadprivate variables cannot appear in a map clause. 17263 // OpenMP 4.5 [2.10.5, target update Construct] 17264 // threadprivate variables cannot appear in a from clause. 17265 if (VD && DSAS->isThreadPrivate(VD)) { 17266 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17267 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 17268 << getOpenMPClauseName(CKind); 17269 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 17270 continue; 17271 } 17272 17273 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17274 // A list item cannot appear in both a map clause and a data-sharing 17275 // attribute clause on the same construct. 17276 17277 // Check conflicts with other map clause expressions. We check the conflicts 17278 // with the current construct separately from the enclosing data 17279 // environment, because the restrictions are different. We only have to 17280 // check conflicts across regions for the map clauses. 17281 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17282 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 17283 break; 17284 if (CKind == OMPC_map && 17285 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17286 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 17287 break; 17288 17289 // OpenMP 4.5 [2.10.5, target update Construct] 17290 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 17291 // If the type of a list item is a reference to a type T then the type will 17292 // be considered to be T for all purposes of this clause. 17293 auto I = llvm::find_if( 17294 CurComponents, 17295 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 17296 return MC.getAssociatedDeclaration(); 17297 }); 17298 assert(I != CurComponents.end() && "Null decl on map clause."); 17299 QualType Type; 17300 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 17301 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 17302 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 17303 if (ASE) { 17304 Type = ASE->getType().getNonReferenceType(); 17305 } else if (OASE) { 17306 QualType BaseType = 17307 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 17308 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 17309 Type = ATy->getElementType(); 17310 else 17311 Type = BaseType->getPointeeType(); 17312 Type = Type.getNonReferenceType(); 17313 } else if (OAShE) { 17314 Type = OAShE->getBase()->getType()->getPointeeType(); 17315 } else { 17316 Type = VE->getType(); 17317 } 17318 17319 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 17320 // A list item in a to or from clause must have a mappable type. 17321 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17322 // A list item must have a mappable type. 17323 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 17324 DSAS, Type)) 17325 continue; 17326 17327 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 17328 17329 if (CKind == OMPC_map) { 17330 // target enter data 17331 // OpenMP [2.10.2, Restrictions, p. 99] 17332 // A map-type must be specified in all map clauses and must be either 17333 // to or alloc. 17334 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 17335 if (DKind == OMPD_target_enter_data && 17336 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 17337 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17338 << (IsMapTypeImplicit ? 1 : 0) 17339 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17340 << getOpenMPDirectiveName(DKind); 17341 continue; 17342 } 17343 17344 // target exit_data 17345 // OpenMP [2.10.3, Restrictions, p. 102] 17346 // A map-type must be specified in all map clauses and must be either 17347 // from, release, or delete. 17348 if (DKind == OMPD_target_exit_data && 17349 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 17350 MapType == OMPC_MAP_delete)) { 17351 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17352 << (IsMapTypeImplicit ? 1 : 0) 17353 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17354 << getOpenMPDirectiveName(DKind); 17355 continue; 17356 } 17357 17358 // target, target data 17359 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 17360 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 17361 // A map-type in a map clause must be to, from, tofrom or alloc 17362 if ((DKind == OMPD_target_data || 17363 isOpenMPTargetExecutionDirective(DKind)) && 17364 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 17365 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 17366 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17367 << (IsMapTypeImplicit ? 1 : 0) 17368 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17369 << getOpenMPDirectiveName(DKind); 17370 continue; 17371 } 17372 17373 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17374 // A list item cannot appear in both a map clause and a data-sharing 17375 // attribute clause on the same construct 17376 // 17377 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17378 // A list item cannot appear in both a map clause and a data-sharing 17379 // attribute clause on the same construct unless the construct is a 17380 // combined construct. 17381 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 17382 isOpenMPTargetExecutionDirective(DKind)) || 17383 DKind == OMPD_target)) { 17384 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17385 if (isOpenMPPrivate(DVar.CKind)) { 17386 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17387 << getOpenMPClauseName(DVar.CKind) 17388 << getOpenMPClauseName(OMPC_map) 17389 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 17390 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 17391 continue; 17392 } 17393 } 17394 } 17395 17396 // Try to find the associated user-defined mapper. 17397 ExprResult ER = buildUserDefinedMapperRef( 17398 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17399 Type.getCanonicalType(), UnresolvedMapper); 17400 if (ER.isInvalid()) 17401 continue; 17402 MVLI.UDMapperList.push_back(ER.get()); 17403 17404 // Save the current expression. 17405 MVLI.ProcessedVarList.push_back(RE); 17406 17407 // Store the components in the stack so that they can be used to check 17408 // against other clauses later on. 17409 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 17410 /*WhereFoundClauseKind=*/OMPC_map); 17411 17412 // Save the components and declaration to create the clause. For purposes of 17413 // the clause creation, any component list that has has base 'this' uses 17414 // null as base declaration. 17415 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17416 MVLI.VarComponents.back().append(CurComponents.begin(), 17417 CurComponents.end()); 17418 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 17419 : CurDeclaration); 17420 } 17421 } 17422 17423 OMPClause *Sema::ActOnOpenMPMapClause( 17424 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 17425 ArrayRef<SourceLocation> MapTypeModifiersLoc, 17426 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 17427 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 17428 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 17429 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 17430 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 17431 OMPC_MAP_MODIFIER_unknown, 17432 OMPC_MAP_MODIFIER_unknown}; 17433 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 17434 17435 // Process map-type-modifiers, flag errors for duplicate modifiers. 17436 unsigned Count = 0; 17437 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 17438 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 17439 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 17440 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 17441 continue; 17442 } 17443 assert(Count < NumberOfOMPMapClauseModifiers && 17444 "Modifiers exceed the allowed number of map type modifiers"); 17445 Modifiers[Count] = MapTypeModifiers[I]; 17446 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 17447 ++Count; 17448 } 17449 17450 MappableVarListInfo MVLI(VarList); 17451 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 17452 MapperIdScopeSpec, MapperId, UnresolvedMappers, 17453 MapType, IsMapTypeImplicit); 17454 17455 // We need to produce a map clause even if we don't have variables so that 17456 // other diagnostics related with non-existing map clauses are accurate. 17457 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 17458 MVLI.VarBaseDeclarations, MVLI.VarComponents, 17459 MVLI.UDMapperList, Modifiers, ModifiersLoc, 17460 MapperIdScopeSpec.getWithLocInContext(Context), 17461 MapperId, MapType, IsMapTypeImplicit, MapLoc); 17462 } 17463 17464 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 17465 TypeResult ParsedType) { 17466 assert(ParsedType.isUsable()); 17467 17468 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 17469 if (ReductionType.isNull()) 17470 return QualType(); 17471 17472 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 17473 // A type name in a declare reduction directive cannot be a function type, an 17474 // array type, a reference type, or a type qualified with const, volatile or 17475 // restrict. 17476 if (ReductionType.hasQualifiers()) { 17477 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 17478 return QualType(); 17479 } 17480 17481 if (ReductionType->isFunctionType()) { 17482 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 17483 return QualType(); 17484 } 17485 if (ReductionType->isReferenceType()) { 17486 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 17487 return QualType(); 17488 } 17489 if (ReductionType->isArrayType()) { 17490 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 17491 return QualType(); 17492 } 17493 return ReductionType; 17494 } 17495 17496 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 17497 Scope *S, DeclContext *DC, DeclarationName Name, 17498 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 17499 AccessSpecifier AS, Decl *PrevDeclInScope) { 17500 SmallVector<Decl *, 8> Decls; 17501 Decls.reserve(ReductionTypes.size()); 17502 17503 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 17504 forRedeclarationInCurContext()); 17505 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 17506 // A reduction-identifier may not be re-declared in the current scope for the 17507 // same type or for a type that is compatible according to the base language 17508 // rules. 17509 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17510 OMPDeclareReductionDecl *PrevDRD = nullptr; 17511 bool InCompoundScope = true; 17512 if (S != nullptr) { 17513 // Find previous declaration with the same name not referenced in other 17514 // declarations. 17515 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17516 InCompoundScope = 17517 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17518 LookupName(Lookup, S); 17519 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17520 /*AllowInlineNamespace=*/false); 17521 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 17522 LookupResult::Filter Filter = Lookup.makeFilter(); 17523 while (Filter.hasNext()) { 17524 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 17525 if (InCompoundScope) { 17526 auto I = UsedAsPrevious.find(PrevDecl); 17527 if (I == UsedAsPrevious.end()) 17528 UsedAsPrevious[PrevDecl] = false; 17529 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 17530 UsedAsPrevious[D] = true; 17531 } 17532 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17533 PrevDecl->getLocation(); 17534 } 17535 Filter.done(); 17536 if (InCompoundScope) { 17537 for (const auto &PrevData : UsedAsPrevious) { 17538 if (!PrevData.second) { 17539 PrevDRD = PrevData.first; 17540 break; 17541 } 17542 } 17543 } 17544 } else if (PrevDeclInScope != nullptr) { 17545 auto *PrevDRDInScope = PrevDRD = 17546 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 17547 do { 17548 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 17549 PrevDRDInScope->getLocation(); 17550 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 17551 } while (PrevDRDInScope != nullptr); 17552 } 17553 for (const auto &TyData : ReductionTypes) { 17554 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 17555 bool Invalid = false; 17556 if (I != PreviousRedeclTypes.end()) { 17557 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 17558 << TyData.first; 17559 Diag(I->second, diag::note_previous_definition); 17560 Invalid = true; 17561 } 17562 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 17563 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 17564 Name, TyData.first, PrevDRD); 17565 DC->addDecl(DRD); 17566 DRD->setAccess(AS); 17567 Decls.push_back(DRD); 17568 if (Invalid) 17569 DRD->setInvalidDecl(); 17570 else 17571 PrevDRD = DRD; 17572 } 17573 17574 return DeclGroupPtrTy::make( 17575 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 17576 } 17577 17578 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 17579 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17580 17581 // Enter new function scope. 17582 PushFunctionScope(); 17583 setFunctionHasBranchProtectedScope(); 17584 getCurFunction()->setHasOMPDeclareReductionCombiner(); 17585 17586 if (S != nullptr) 17587 PushDeclContext(S, DRD); 17588 else 17589 CurContext = DRD; 17590 17591 PushExpressionEvaluationContext( 17592 ExpressionEvaluationContext::PotentiallyEvaluated); 17593 17594 QualType ReductionType = DRD->getType(); 17595 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 17596 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 17597 // uses semantics of argument handles by value, but it should be passed by 17598 // reference. C lang does not support references, so pass all parameters as 17599 // pointers. 17600 // Create 'T omp_in;' variable. 17601 VarDecl *OmpInParm = 17602 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 17603 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 17604 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 17605 // uses semantics of argument handles by value, but it should be passed by 17606 // reference. C lang does not support references, so pass all parameters as 17607 // pointers. 17608 // Create 'T omp_out;' variable. 17609 VarDecl *OmpOutParm = 17610 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 17611 if (S != nullptr) { 17612 PushOnScopeChains(OmpInParm, S); 17613 PushOnScopeChains(OmpOutParm, S); 17614 } else { 17615 DRD->addDecl(OmpInParm); 17616 DRD->addDecl(OmpOutParm); 17617 } 17618 Expr *InE = 17619 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 17620 Expr *OutE = 17621 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 17622 DRD->setCombinerData(InE, OutE); 17623 } 17624 17625 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 17626 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17627 DiscardCleanupsInEvaluationContext(); 17628 PopExpressionEvaluationContext(); 17629 17630 PopDeclContext(); 17631 PopFunctionScopeInfo(); 17632 17633 if (Combiner != nullptr) 17634 DRD->setCombiner(Combiner); 17635 else 17636 DRD->setInvalidDecl(); 17637 } 17638 17639 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 17640 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17641 17642 // Enter new function scope. 17643 PushFunctionScope(); 17644 setFunctionHasBranchProtectedScope(); 17645 17646 if (S != nullptr) 17647 PushDeclContext(S, DRD); 17648 else 17649 CurContext = DRD; 17650 17651 PushExpressionEvaluationContext( 17652 ExpressionEvaluationContext::PotentiallyEvaluated); 17653 17654 QualType ReductionType = DRD->getType(); 17655 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 17656 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 17657 // uses semantics of argument handles by value, but it should be passed by 17658 // reference. C lang does not support references, so pass all parameters as 17659 // pointers. 17660 // Create 'T omp_priv;' variable. 17661 VarDecl *OmpPrivParm = 17662 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 17663 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 17664 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 17665 // uses semantics of argument handles by value, but it should be passed by 17666 // reference. C lang does not support references, so pass all parameters as 17667 // pointers. 17668 // Create 'T omp_orig;' variable. 17669 VarDecl *OmpOrigParm = 17670 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 17671 if (S != nullptr) { 17672 PushOnScopeChains(OmpPrivParm, S); 17673 PushOnScopeChains(OmpOrigParm, S); 17674 } else { 17675 DRD->addDecl(OmpPrivParm); 17676 DRD->addDecl(OmpOrigParm); 17677 } 17678 Expr *OrigE = 17679 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 17680 Expr *PrivE = 17681 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 17682 DRD->setInitializerData(OrigE, PrivE); 17683 return OmpPrivParm; 17684 } 17685 17686 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 17687 VarDecl *OmpPrivParm) { 17688 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17689 DiscardCleanupsInEvaluationContext(); 17690 PopExpressionEvaluationContext(); 17691 17692 PopDeclContext(); 17693 PopFunctionScopeInfo(); 17694 17695 if (Initializer != nullptr) { 17696 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 17697 } else if (OmpPrivParm->hasInit()) { 17698 DRD->setInitializer(OmpPrivParm->getInit(), 17699 OmpPrivParm->isDirectInit() 17700 ? OMPDeclareReductionDecl::DirectInit 17701 : OMPDeclareReductionDecl::CopyInit); 17702 } else { 17703 DRD->setInvalidDecl(); 17704 } 17705 } 17706 17707 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 17708 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 17709 for (Decl *D : DeclReductions.get()) { 17710 if (IsValid) { 17711 if (S) 17712 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 17713 /*AddToContext=*/false); 17714 } else { 17715 D->setInvalidDecl(); 17716 } 17717 } 17718 return DeclReductions; 17719 } 17720 17721 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 17722 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 17723 QualType T = TInfo->getType(); 17724 if (D.isInvalidType()) 17725 return true; 17726 17727 if (getLangOpts().CPlusPlus) { 17728 // Check that there are no default arguments (C++ only). 17729 CheckExtraCXXDefaultArguments(D); 17730 } 17731 17732 return CreateParsedType(T, TInfo); 17733 } 17734 17735 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 17736 TypeResult ParsedType) { 17737 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 17738 17739 QualType MapperType = GetTypeFromParser(ParsedType.get()); 17740 assert(!MapperType.isNull() && "Expect valid mapper type"); 17741 17742 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17743 // The type must be of struct, union or class type in C and C++ 17744 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 17745 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 17746 return QualType(); 17747 } 17748 return MapperType; 17749 } 17750 17751 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 17752 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 17753 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 17754 Decl *PrevDeclInScope) { 17755 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 17756 forRedeclarationInCurContext()); 17757 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17758 // A mapper-identifier may not be redeclared in the current scope for the 17759 // same type or for a type that is compatible according to the base language 17760 // rules. 17761 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17762 OMPDeclareMapperDecl *PrevDMD = nullptr; 17763 bool InCompoundScope = true; 17764 if (S != nullptr) { 17765 // Find previous declaration with the same name not referenced in other 17766 // declarations. 17767 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17768 InCompoundScope = 17769 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17770 LookupName(Lookup, S); 17771 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17772 /*AllowInlineNamespace=*/false); 17773 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 17774 LookupResult::Filter Filter = Lookup.makeFilter(); 17775 while (Filter.hasNext()) { 17776 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 17777 if (InCompoundScope) { 17778 auto I = UsedAsPrevious.find(PrevDecl); 17779 if (I == UsedAsPrevious.end()) 17780 UsedAsPrevious[PrevDecl] = false; 17781 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 17782 UsedAsPrevious[D] = true; 17783 } 17784 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17785 PrevDecl->getLocation(); 17786 } 17787 Filter.done(); 17788 if (InCompoundScope) { 17789 for (const auto &PrevData : UsedAsPrevious) { 17790 if (!PrevData.second) { 17791 PrevDMD = PrevData.first; 17792 break; 17793 } 17794 } 17795 } 17796 } else if (PrevDeclInScope) { 17797 auto *PrevDMDInScope = PrevDMD = 17798 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 17799 do { 17800 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 17801 PrevDMDInScope->getLocation(); 17802 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 17803 } while (PrevDMDInScope != nullptr); 17804 } 17805 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 17806 bool Invalid = false; 17807 if (I != PreviousRedeclTypes.end()) { 17808 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 17809 << MapperType << Name; 17810 Diag(I->second, diag::note_previous_definition); 17811 Invalid = true; 17812 } 17813 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 17814 MapperType, VN, PrevDMD); 17815 DC->addDecl(DMD); 17816 DMD->setAccess(AS); 17817 if (Invalid) 17818 DMD->setInvalidDecl(); 17819 17820 // Enter new function scope. 17821 PushFunctionScope(); 17822 setFunctionHasBranchProtectedScope(); 17823 17824 CurContext = DMD; 17825 17826 return DMD; 17827 } 17828 17829 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 17830 Scope *S, 17831 QualType MapperType, 17832 SourceLocation StartLoc, 17833 DeclarationName VN) { 17834 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 17835 if (S) 17836 PushOnScopeChains(VD, S); 17837 else 17838 DMD->addDecl(VD); 17839 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 17840 DMD->setMapperVarRef(MapperVarRefExpr); 17841 } 17842 17843 Sema::DeclGroupPtrTy 17844 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 17845 ArrayRef<OMPClause *> ClauseList) { 17846 PopDeclContext(); 17847 PopFunctionScopeInfo(); 17848 17849 if (D) { 17850 if (S) 17851 PushOnScopeChains(D, S, /*AddToContext=*/false); 17852 D->CreateClauses(Context, ClauseList); 17853 } 17854 17855 return DeclGroupPtrTy::make(DeclGroupRef(D)); 17856 } 17857 17858 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 17859 SourceLocation StartLoc, 17860 SourceLocation LParenLoc, 17861 SourceLocation EndLoc) { 17862 Expr *ValExpr = NumTeams; 17863 Stmt *HelperValStmt = nullptr; 17864 17865 // OpenMP [teams Constrcut, Restrictions] 17866 // The num_teams expression must evaluate to a positive integer value. 17867 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 17868 /*StrictlyPositive=*/true)) 17869 return nullptr; 17870 17871 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17872 OpenMPDirectiveKind CaptureRegion = 17873 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 17874 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17875 ValExpr = MakeFullExpr(ValExpr).get(); 17876 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17877 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17878 HelperValStmt = buildPreInits(Context, Captures); 17879 } 17880 17881 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 17882 StartLoc, LParenLoc, EndLoc); 17883 } 17884 17885 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 17886 SourceLocation StartLoc, 17887 SourceLocation LParenLoc, 17888 SourceLocation EndLoc) { 17889 Expr *ValExpr = ThreadLimit; 17890 Stmt *HelperValStmt = nullptr; 17891 17892 // OpenMP [teams Constrcut, Restrictions] 17893 // The thread_limit expression must evaluate to a positive integer value. 17894 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 17895 /*StrictlyPositive=*/true)) 17896 return nullptr; 17897 17898 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17899 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 17900 DKind, OMPC_thread_limit, LangOpts.OpenMP); 17901 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17902 ValExpr = MakeFullExpr(ValExpr).get(); 17903 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17904 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17905 HelperValStmt = buildPreInits(Context, Captures); 17906 } 17907 17908 return new (Context) OMPThreadLimitClause( 17909 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 17910 } 17911 17912 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 17913 SourceLocation StartLoc, 17914 SourceLocation LParenLoc, 17915 SourceLocation EndLoc) { 17916 Expr *ValExpr = Priority; 17917 Stmt *HelperValStmt = nullptr; 17918 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17919 17920 // OpenMP [2.9.1, task Constrcut] 17921 // The priority-value is a non-negative numerical scalar expression. 17922 if (!isNonNegativeIntegerValue( 17923 ValExpr, *this, OMPC_priority, 17924 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 17925 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17926 return nullptr; 17927 17928 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 17929 StartLoc, LParenLoc, EndLoc); 17930 } 17931 17932 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 17933 SourceLocation StartLoc, 17934 SourceLocation LParenLoc, 17935 SourceLocation EndLoc) { 17936 Expr *ValExpr = Grainsize; 17937 Stmt *HelperValStmt = nullptr; 17938 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17939 17940 // OpenMP [2.9.2, taskloop Constrcut] 17941 // The parameter of the grainsize clause must be a positive integer 17942 // expression. 17943 if (!isNonNegativeIntegerValue( 17944 ValExpr, *this, OMPC_grainsize, 17945 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17946 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17947 return nullptr; 17948 17949 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 17950 StartLoc, LParenLoc, EndLoc); 17951 } 17952 17953 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 17954 SourceLocation StartLoc, 17955 SourceLocation LParenLoc, 17956 SourceLocation EndLoc) { 17957 Expr *ValExpr = NumTasks; 17958 Stmt *HelperValStmt = nullptr; 17959 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17960 17961 // OpenMP [2.9.2, taskloop Constrcut] 17962 // The parameter of the num_tasks clause must be a positive integer 17963 // expression. 17964 if (!isNonNegativeIntegerValue( 17965 ValExpr, *this, OMPC_num_tasks, 17966 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17967 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17968 return nullptr; 17969 17970 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 17971 StartLoc, LParenLoc, EndLoc); 17972 } 17973 17974 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 17975 SourceLocation LParenLoc, 17976 SourceLocation EndLoc) { 17977 // OpenMP [2.13.2, critical construct, Description] 17978 // ... where hint-expression is an integer constant expression that evaluates 17979 // to a valid lock hint. 17980 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 17981 if (HintExpr.isInvalid()) 17982 return nullptr; 17983 return new (Context) 17984 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 17985 } 17986 17987 /// Tries to find omp_event_handle_t type. 17988 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 17989 DSAStackTy *Stack) { 17990 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 17991 if (!OMPEventHandleT.isNull()) 17992 return true; 17993 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 17994 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 17995 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 17996 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 17997 return false; 17998 } 17999 Stack->setOMPEventHandleT(PT.get()); 18000 return true; 18001 } 18002 18003 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 18004 SourceLocation LParenLoc, 18005 SourceLocation EndLoc) { 18006 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 18007 !Evt->isInstantiationDependent() && 18008 !Evt->containsUnexpandedParameterPack()) { 18009 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 18010 return nullptr; 18011 // OpenMP 5.0, 2.10.1 task Construct. 18012 // event-handle is a variable of the omp_event_handle_t type. 18013 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 18014 if (!Ref) { 18015 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 18016 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 18017 return nullptr; 18018 } 18019 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 18020 if (!VD) { 18021 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 18022 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 18023 return nullptr; 18024 } 18025 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 18026 VD->getType()) || 18027 VD->getType().isConstant(Context)) { 18028 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 18029 << "omp_event_handle_t" << 1 << VD->getType() 18030 << Evt->getSourceRange(); 18031 return nullptr; 18032 } 18033 // OpenMP 5.0, 2.10.1 task Construct 18034 // [detach clause]... The event-handle will be considered as if it was 18035 // specified on a firstprivate clause. 18036 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 18037 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 18038 DVar.RefExpr) { 18039 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 18040 << getOpenMPClauseName(DVar.CKind) 18041 << getOpenMPClauseName(OMPC_firstprivate); 18042 reportOriginalDsa(*this, DSAStack, VD, DVar); 18043 return nullptr; 18044 } 18045 } 18046 18047 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 18048 } 18049 18050 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 18051 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 18052 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 18053 SourceLocation EndLoc) { 18054 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 18055 std::string Values; 18056 Values += "'"; 18057 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 18058 Values += "'"; 18059 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18060 << Values << getOpenMPClauseName(OMPC_dist_schedule); 18061 return nullptr; 18062 } 18063 Expr *ValExpr = ChunkSize; 18064 Stmt *HelperValStmt = nullptr; 18065 if (ChunkSize) { 18066 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 18067 !ChunkSize->isInstantiationDependent() && 18068 !ChunkSize->containsUnexpandedParameterPack()) { 18069 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 18070 ExprResult Val = 18071 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 18072 if (Val.isInvalid()) 18073 return nullptr; 18074 18075 ValExpr = Val.get(); 18076 18077 // OpenMP [2.7.1, Restrictions] 18078 // chunk_size must be a loop invariant integer expression with a positive 18079 // value. 18080 llvm::APSInt Result; 18081 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 18082 if (Result.isSigned() && !Result.isStrictlyPositive()) { 18083 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 18084 << "dist_schedule" << ChunkSize->getSourceRange(); 18085 return nullptr; 18086 } 18087 } else if (getOpenMPCaptureRegionForClause( 18088 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 18089 LangOpts.OpenMP) != OMPD_unknown && 18090 !CurContext->isDependentContext()) { 18091 ValExpr = MakeFullExpr(ValExpr).get(); 18092 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 18093 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 18094 HelperValStmt = buildPreInits(Context, Captures); 18095 } 18096 } 18097 } 18098 18099 return new (Context) 18100 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 18101 Kind, ValExpr, HelperValStmt); 18102 } 18103 18104 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 18105 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 18106 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 18107 SourceLocation KindLoc, SourceLocation EndLoc) { 18108 if (getLangOpts().OpenMP < 50) { 18109 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 18110 Kind != OMPC_DEFAULTMAP_scalar) { 18111 std::string Value; 18112 SourceLocation Loc; 18113 Value += "'"; 18114 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 18115 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 18116 OMPC_DEFAULTMAP_MODIFIER_tofrom); 18117 Loc = MLoc; 18118 } else { 18119 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 18120 OMPC_DEFAULTMAP_scalar); 18121 Loc = KindLoc; 18122 } 18123 Value += "'"; 18124 Diag(Loc, diag::err_omp_unexpected_clause_value) 18125 << Value << getOpenMPClauseName(OMPC_defaultmap); 18126 return nullptr; 18127 } 18128 } else { 18129 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 18130 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 18131 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 18132 if (!isDefaultmapKind || !isDefaultmapModifier) { 18133 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 18134 "'firstprivate', 'none', 'default'"; 18135 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 18136 if (!isDefaultmapKind && isDefaultmapModifier) { 18137 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18138 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 18139 } else if (isDefaultmapKind && !isDefaultmapModifier) { 18140 Diag(MLoc, diag::err_omp_unexpected_clause_value) 18141 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 18142 } else { 18143 Diag(MLoc, diag::err_omp_unexpected_clause_value) 18144 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 18145 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18146 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 18147 } 18148 return nullptr; 18149 } 18150 18151 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 18152 // At most one defaultmap clause for each category can appear on the 18153 // directive. 18154 if (DSAStack->checkDefaultmapCategory(Kind)) { 18155 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 18156 return nullptr; 18157 } 18158 } 18159 if (Kind == OMPC_DEFAULTMAP_unknown) { 18160 // Variable category is not specified - mark all categories. 18161 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 18162 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 18163 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 18164 } else { 18165 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 18166 } 18167 18168 return new (Context) 18169 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 18170 } 18171 18172 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 18173 DeclContext *CurLexicalContext = getCurLexicalContext(); 18174 if (!CurLexicalContext->isFileContext() && 18175 !CurLexicalContext->isExternCContext() && 18176 !CurLexicalContext->isExternCXXContext() && 18177 !isa<CXXRecordDecl>(CurLexicalContext) && 18178 !isa<ClassTemplateDecl>(CurLexicalContext) && 18179 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 18180 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 18181 Diag(Loc, diag::err_omp_region_not_file_context); 18182 return false; 18183 } 18184 ++DeclareTargetNestingLevel; 18185 return true; 18186 } 18187 18188 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 18189 assert(DeclareTargetNestingLevel > 0 && 18190 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 18191 --DeclareTargetNestingLevel; 18192 } 18193 18194 NamedDecl * 18195 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 18196 const DeclarationNameInfo &Id, 18197 NamedDeclSetType &SameDirectiveDecls) { 18198 LookupResult Lookup(*this, Id, LookupOrdinaryName); 18199 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 18200 18201 if (Lookup.isAmbiguous()) 18202 return nullptr; 18203 Lookup.suppressDiagnostics(); 18204 18205 if (!Lookup.isSingleResult()) { 18206 VarOrFuncDeclFilterCCC CCC(*this); 18207 if (TypoCorrection Corrected = 18208 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 18209 CTK_ErrorRecovery)) { 18210 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 18211 << Id.getName()); 18212 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 18213 return nullptr; 18214 } 18215 18216 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 18217 return nullptr; 18218 } 18219 18220 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 18221 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 18222 !isa<FunctionTemplateDecl>(ND)) { 18223 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 18224 return nullptr; 18225 } 18226 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 18227 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 18228 return ND; 18229 } 18230 18231 void Sema::ActOnOpenMPDeclareTargetName( 18232 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 18233 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 18234 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 18235 isa<FunctionTemplateDecl>(ND)) && 18236 "Expected variable, function or function template."); 18237 18238 // Diagnose marking after use as it may lead to incorrect diagnosis and 18239 // codegen. 18240 if (LangOpts.OpenMP >= 50 && 18241 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 18242 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 18243 18244 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 18245 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 18246 if (DevTy.hasValue() && *DevTy != DT) { 18247 Diag(Loc, diag::err_omp_device_type_mismatch) 18248 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 18249 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 18250 return; 18251 } 18252 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18253 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 18254 if (!Res) { 18255 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 18256 SourceRange(Loc, Loc)); 18257 ND->addAttr(A); 18258 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18259 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 18260 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 18261 } else if (*Res != MT) { 18262 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 18263 } 18264 } 18265 18266 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 18267 Sema &SemaRef, Decl *D) { 18268 if (!D || !isa<VarDecl>(D)) 18269 return; 18270 auto *VD = cast<VarDecl>(D); 18271 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18272 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18273 if (SemaRef.LangOpts.OpenMP >= 50 && 18274 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 18275 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 18276 VD->hasGlobalStorage()) { 18277 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18278 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18279 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 18280 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 18281 // If a lambda declaration and definition appears between a 18282 // declare target directive and the matching end declare target 18283 // directive, all variables that are captured by the lambda 18284 // expression must also appear in a to clause. 18285 SemaRef.Diag(VD->getLocation(), 18286 diag::err_omp_lambda_capture_in_declare_target_not_to); 18287 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 18288 << VD << 0 << SR; 18289 return; 18290 } 18291 } 18292 if (MapTy.hasValue()) 18293 return; 18294 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 18295 SemaRef.Diag(SL, diag::note_used_here) << SR; 18296 } 18297 18298 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 18299 Sema &SemaRef, DSAStackTy *Stack, 18300 ValueDecl *VD) { 18301 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 18302 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 18303 /*FullCheck=*/false); 18304 } 18305 18306 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 18307 SourceLocation IdLoc) { 18308 if (!D || D->isInvalidDecl()) 18309 return; 18310 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 18311 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 18312 if (auto *VD = dyn_cast<VarDecl>(D)) { 18313 // Only global variables can be marked as declare target. 18314 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 18315 !VD->isStaticDataMember()) 18316 return; 18317 // 2.10.6: threadprivate variable cannot appear in a declare target 18318 // directive. 18319 if (DSAStack->isThreadPrivate(VD)) { 18320 Diag(SL, diag::err_omp_threadprivate_in_target); 18321 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 18322 return; 18323 } 18324 } 18325 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 18326 D = FTD->getTemplatedDecl(); 18327 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 18328 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18329 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 18330 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 18331 Diag(IdLoc, diag::err_omp_function_in_link_clause); 18332 Diag(FD->getLocation(), diag::note_defined_here) << FD; 18333 return; 18334 } 18335 } 18336 if (auto *VD = dyn_cast<ValueDecl>(D)) { 18337 // Problem if any with var declared with incomplete type will be reported 18338 // as normal, so no need to check it here. 18339 if ((E || !VD->getType()->isIncompleteType()) && 18340 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 18341 return; 18342 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 18343 // Checking declaration inside declare target region. 18344 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 18345 isa<FunctionTemplateDecl>(D)) { 18346 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 18347 Context, OMPDeclareTargetDeclAttr::MT_To, 18348 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 18349 D->addAttr(A); 18350 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18351 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 18352 } 18353 return; 18354 } 18355 } 18356 if (!E) 18357 return; 18358 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 18359 } 18360 18361 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 18362 CXXScopeSpec &MapperIdScopeSpec, 18363 DeclarationNameInfo &MapperId, 18364 const OMPVarListLocTy &Locs, 18365 ArrayRef<Expr *> UnresolvedMappers) { 18366 MappableVarListInfo MVLI(VarList); 18367 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 18368 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18369 if (MVLI.ProcessedVarList.empty()) 18370 return nullptr; 18371 18372 return OMPToClause::Create( 18373 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18374 MVLI.VarComponents, MVLI.UDMapperList, 18375 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18376 } 18377 18378 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 18379 CXXScopeSpec &MapperIdScopeSpec, 18380 DeclarationNameInfo &MapperId, 18381 const OMPVarListLocTy &Locs, 18382 ArrayRef<Expr *> UnresolvedMappers) { 18383 MappableVarListInfo MVLI(VarList); 18384 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 18385 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18386 if (MVLI.ProcessedVarList.empty()) 18387 return nullptr; 18388 18389 return OMPFromClause::Create( 18390 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18391 MVLI.VarComponents, MVLI.UDMapperList, 18392 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18393 } 18394 18395 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 18396 const OMPVarListLocTy &Locs) { 18397 MappableVarListInfo MVLI(VarList); 18398 SmallVector<Expr *, 8> PrivateCopies; 18399 SmallVector<Expr *, 8> Inits; 18400 18401 for (Expr *RefExpr : VarList) { 18402 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 18403 SourceLocation ELoc; 18404 SourceRange ERange; 18405 Expr *SimpleRefExpr = RefExpr; 18406 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18407 if (Res.second) { 18408 // It will be analyzed later. 18409 MVLI.ProcessedVarList.push_back(RefExpr); 18410 PrivateCopies.push_back(nullptr); 18411 Inits.push_back(nullptr); 18412 } 18413 ValueDecl *D = Res.first; 18414 if (!D) 18415 continue; 18416 18417 QualType Type = D->getType(); 18418 Type = Type.getNonReferenceType().getUnqualifiedType(); 18419 18420 auto *VD = dyn_cast<VarDecl>(D); 18421 18422 // Item should be a pointer or reference to pointer. 18423 if (!Type->isPointerType()) { 18424 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 18425 << 0 << RefExpr->getSourceRange(); 18426 continue; 18427 } 18428 18429 // Build the private variable and the expression that refers to it. 18430 auto VDPrivate = 18431 buildVarDecl(*this, ELoc, Type, D->getName(), 18432 D->hasAttrs() ? &D->getAttrs() : nullptr, 18433 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18434 if (VDPrivate->isInvalidDecl()) 18435 continue; 18436 18437 CurContext->addDecl(VDPrivate); 18438 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18439 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 18440 18441 // Add temporary variable to initialize the private copy of the pointer. 18442 VarDecl *VDInit = 18443 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 18444 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 18445 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 18446 AddInitializerToDecl(VDPrivate, 18447 DefaultLvalueConversion(VDInitRefExpr).get(), 18448 /*DirectInit=*/false); 18449 18450 // If required, build a capture to implement the privatization initialized 18451 // with the current list item value. 18452 DeclRefExpr *Ref = nullptr; 18453 if (!VD) 18454 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18455 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18456 PrivateCopies.push_back(VDPrivateRefExpr); 18457 Inits.push_back(VDInitRefExpr); 18458 18459 // We need to add a data sharing attribute for this variable to make sure it 18460 // is correctly captured. A variable that shows up in a use_device_ptr has 18461 // similar properties of a first private variable. 18462 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18463 18464 // Create a mappable component for the list item. List items in this clause 18465 // only need a component. 18466 MVLI.VarBaseDeclarations.push_back(D); 18467 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18468 MVLI.VarComponents.back().push_back( 18469 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 18470 } 18471 18472 if (MVLI.ProcessedVarList.empty()) 18473 return nullptr; 18474 18475 return OMPUseDevicePtrClause::Create( 18476 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 18477 MVLI.VarBaseDeclarations, MVLI.VarComponents); 18478 } 18479 18480 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, 18481 const OMPVarListLocTy &Locs) { 18482 MappableVarListInfo MVLI(VarList); 18483 18484 for (Expr *RefExpr : VarList) { 18485 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause."); 18486 SourceLocation ELoc; 18487 SourceRange ERange; 18488 Expr *SimpleRefExpr = RefExpr; 18489 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18490 /*AllowArraySection=*/true); 18491 if (Res.second) { 18492 // It will be analyzed later. 18493 MVLI.ProcessedVarList.push_back(RefExpr); 18494 } 18495 ValueDecl *D = Res.first; 18496 if (!D) 18497 continue; 18498 auto *VD = dyn_cast<VarDecl>(D); 18499 18500 // If required, build a capture to implement the privatization initialized 18501 // with the current list item value. 18502 DeclRefExpr *Ref = nullptr; 18503 if (!VD) 18504 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18505 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18506 18507 // We need to add a data sharing attribute for this variable to make sure it 18508 // is correctly captured. A variable that shows up in a use_device_addr has 18509 // similar properties of a first private variable. 18510 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18511 18512 // Create a mappable component for the list item. List items in this clause 18513 // only need a component. 18514 MVLI.VarBaseDeclarations.push_back(D); 18515 MVLI.VarComponents.emplace_back(); 18516 Expr *Component = SimpleRefExpr; 18517 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || 18518 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) 18519 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); 18520 MVLI.VarComponents.back().push_back( 18521 OMPClauseMappableExprCommon::MappableComponent(Component, D)); 18522 } 18523 18524 if (MVLI.ProcessedVarList.empty()) 18525 return nullptr; 18526 18527 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 18528 MVLI.VarBaseDeclarations, 18529 MVLI.VarComponents); 18530 } 18531 18532 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 18533 const OMPVarListLocTy &Locs) { 18534 MappableVarListInfo MVLI(VarList); 18535 for (Expr *RefExpr : VarList) { 18536 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 18537 SourceLocation ELoc; 18538 SourceRange ERange; 18539 Expr *SimpleRefExpr = RefExpr; 18540 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18541 if (Res.second) { 18542 // It will be analyzed later. 18543 MVLI.ProcessedVarList.push_back(RefExpr); 18544 } 18545 ValueDecl *D = Res.first; 18546 if (!D) 18547 continue; 18548 18549 QualType Type = D->getType(); 18550 // item should be a pointer or array or reference to pointer or array 18551 if (!Type.getNonReferenceType()->isPointerType() && 18552 !Type.getNonReferenceType()->isArrayType()) { 18553 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 18554 << 0 << RefExpr->getSourceRange(); 18555 continue; 18556 } 18557 18558 // Check if the declaration in the clause does not show up in any data 18559 // sharing attribute. 18560 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18561 if (isOpenMPPrivate(DVar.CKind)) { 18562 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 18563 << getOpenMPClauseName(DVar.CKind) 18564 << getOpenMPClauseName(OMPC_is_device_ptr) 18565 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18566 reportOriginalDsa(*this, DSAStack, D, DVar); 18567 continue; 18568 } 18569 18570 const Expr *ConflictExpr; 18571 if (DSAStack->checkMappableExprComponentListsForDecl( 18572 D, /*CurrentRegionOnly=*/true, 18573 [&ConflictExpr]( 18574 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 18575 OpenMPClauseKind) -> bool { 18576 ConflictExpr = R.front().getAssociatedExpression(); 18577 return true; 18578 })) { 18579 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 18580 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 18581 << ConflictExpr->getSourceRange(); 18582 continue; 18583 } 18584 18585 // Store the components in the stack so that they can be used to check 18586 // against other clauses later on. 18587 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 18588 DSAStack->addMappableExpressionComponents( 18589 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 18590 18591 // Record the expression we've just processed. 18592 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 18593 18594 // Create a mappable component for the list item. List items in this clause 18595 // only need a component. We use a null declaration to signal fields in 18596 // 'this'. 18597 assert((isa<DeclRefExpr>(SimpleRefExpr) || 18598 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 18599 "Unexpected device pointer expression!"); 18600 MVLI.VarBaseDeclarations.push_back( 18601 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 18602 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18603 MVLI.VarComponents.back().push_back(MC); 18604 } 18605 18606 if (MVLI.ProcessedVarList.empty()) 18607 return nullptr; 18608 18609 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 18610 MVLI.VarBaseDeclarations, 18611 MVLI.VarComponents); 18612 } 18613 18614 OMPClause *Sema::ActOnOpenMPAllocateClause( 18615 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 18616 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 18617 if (Allocator) { 18618 // OpenMP [2.11.4 allocate Clause, Description] 18619 // allocator is an expression of omp_allocator_handle_t type. 18620 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 18621 return nullptr; 18622 18623 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 18624 if (AllocatorRes.isInvalid()) 18625 return nullptr; 18626 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 18627 DSAStack->getOMPAllocatorHandleT(), 18628 Sema::AA_Initializing, 18629 /*AllowExplicit=*/true); 18630 if (AllocatorRes.isInvalid()) 18631 return nullptr; 18632 Allocator = AllocatorRes.get(); 18633 } else { 18634 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 18635 // allocate clauses that appear on a target construct or on constructs in a 18636 // target region must specify an allocator expression unless a requires 18637 // directive with the dynamic_allocators clause is present in the same 18638 // compilation unit. 18639 if (LangOpts.OpenMPIsDevice && 18640 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 18641 targetDiag(StartLoc, diag::err_expected_allocator_expression); 18642 } 18643 // Analyze and build list of variables. 18644 SmallVector<Expr *, 8> Vars; 18645 for (Expr *RefExpr : VarList) { 18646 assert(RefExpr && "NULL expr in OpenMP private clause."); 18647 SourceLocation ELoc; 18648 SourceRange ERange; 18649 Expr *SimpleRefExpr = RefExpr; 18650 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18651 if (Res.second) { 18652 // It will be analyzed later. 18653 Vars.push_back(RefExpr); 18654 } 18655 ValueDecl *D = Res.first; 18656 if (!D) 18657 continue; 18658 18659 auto *VD = dyn_cast<VarDecl>(D); 18660 DeclRefExpr *Ref = nullptr; 18661 if (!VD && !CurContext->isDependentContext()) 18662 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 18663 Vars.push_back((VD || CurContext->isDependentContext()) 18664 ? RefExpr->IgnoreParens() 18665 : Ref); 18666 } 18667 18668 if (Vars.empty()) 18669 return nullptr; 18670 18671 if (Allocator) 18672 DSAStack->addInnerAllocatorExpr(Allocator); 18673 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 18674 ColonLoc, EndLoc, Vars); 18675 } 18676 18677 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 18678 SourceLocation StartLoc, 18679 SourceLocation LParenLoc, 18680 SourceLocation EndLoc) { 18681 SmallVector<Expr *, 8> Vars; 18682 for (Expr *RefExpr : VarList) { 18683 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18684 SourceLocation ELoc; 18685 SourceRange ERange; 18686 Expr *SimpleRefExpr = RefExpr; 18687 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18688 if (Res.second) 18689 // It will be analyzed later. 18690 Vars.push_back(RefExpr); 18691 ValueDecl *D = Res.first; 18692 if (!D) 18693 continue; 18694 18695 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 18696 // A list-item cannot appear in more than one nontemporal clause. 18697 if (const Expr *PrevRef = 18698 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 18699 Diag(ELoc, diag::err_omp_used_in_clause_twice) 18700 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 18701 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 18702 << getOpenMPClauseName(OMPC_nontemporal); 18703 continue; 18704 } 18705 18706 Vars.push_back(RefExpr); 18707 } 18708 18709 if (Vars.empty()) 18710 return nullptr; 18711 18712 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18713 Vars); 18714 } 18715 18716 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 18717 SourceLocation StartLoc, 18718 SourceLocation LParenLoc, 18719 SourceLocation EndLoc) { 18720 SmallVector<Expr *, 8> Vars; 18721 for (Expr *RefExpr : VarList) { 18722 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18723 SourceLocation ELoc; 18724 SourceRange ERange; 18725 Expr *SimpleRefExpr = RefExpr; 18726 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18727 /*AllowArraySection=*/true); 18728 if (Res.second) 18729 // It will be analyzed later. 18730 Vars.push_back(RefExpr); 18731 ValueDecl *D = Res.first; 18732 if (!D) 18733 continue; 18734 18735 const DSAStackTy::DSAVarData DVar = 18736 DSAStack->getTopDSA(D, /*FromParent=*/true); 18737 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18738 // A list item that appears in the inclusive or exclusive clause must appear 18739 // in a reduction clause with the inscan modifier on the enclosing 18740 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18741 if (DVar.CKind != OMPC_reduction || 18742 DVar.Modifier != OMPC_REDUCTION_inscan) 18743 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18744 << RefExpr->getSourceRange(); 18745 18746 if (DSAStack->getParentDirective() != OMPD_unknown) 18747 DSAStack->markDeclAsUsedInScanDirective(D); 18748 Vars.push_back(RefExpr); 18749 } 18750 18751 if (Vars.empty()) 18752 return nullptr; 18753 18754 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18755 } 18756 18757 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 18758 SourceLocation StartLoc, 18759 SourceLocation LParenLoc, 18760 SourceLocation EndLoc) { 18761 SmallVector<Expr *, 8> Vars; 18762 for (Expr *RefExpr : VarList) { 18763 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18764 SourceLocation ELoc; 18765 SourceRange ERange; 18766 Expr *SimpleRefExpr = RefExpr; 18767 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18768 /*AllowArraySection=*/true); 18769 if (Res.second) 18770 // It will be analyzed later. 18771 Vars.push_back(RefExpr); 18772 ValueDecl *D = Res.first; 18773 if (!D) 18774 continue; 18775 18776 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 18777 DSAStackTy::DSAVarData DVar; 18778 if (ParentDirective != OMPD_unknown) 18779 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 18780 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18781 // A list item that appears in the inclusive or exclusive clause must appear 18782 // in a reduction clause with the inscan modifier on the enclosing 18783 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18784 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 18785 DVar.Modifier != OMPC_REDUCTION_inscan) { 18786 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18787 << RefExpr->getSourceRange(); 18788 } else { 18789 DSAStack->markDeclAsUsedInScanDirective(D); 18790 } 18791 Vars.push_back(RefExpr); 18792 } 18793 18794 if (Vars.empty()) 18795 return nullptr; 18796 18797 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18798 } 18799 18800 /// Tries to find omp_alloctrait_t type. 18801 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 18802 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 18803 if (!OMPAlloctraitT.isNull()) 18804 return true; 18805 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 18806 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 18807 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 18808 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 18809 return false; 18810 } 18811 Stack->setOMPAlloctraitT(PT.get()); 18812 return true; 18813 } 18814 18815 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 18816 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 18817 ArrayRef<UsesAllocatorsData> Data) { 18818 // OpenMP [2.12.5, target Construct] 18819 // allocator is an identifier of omp_allocator_handle_t type. 18820 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 18821 return nullptr; 18822 // OpenMP [2.12.5, target Construct] 18823 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 18824 if (llvm::any_of( 18825 Data, 18826 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 18827 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 18828 return nullptr; 18829 llvm::SmallSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 18830 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 18831 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 18832 StringRef Allocator = 18833 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 18834 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 18835 PredefinedAllocators.insert(LookupSingleName( 18836 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 18837 } 18838 18839 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 18840 for (const UsesAllocatorsData &D : Data) { 18841 Expr *AllocatorExpr = nullptr; 18842 // Check allocator expression. 18843 if (D.Allocator->isTypeDependent()) { 18844 AllocatorExpr = D.Allocator; 18845 } else { 18846 // Traits were specified - need to assign new allocator to the specified 18847 // allocator, so it must be an lvalue. 18848 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 18849 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 18850 bool IsPredefinedAllocator = false; 18851 if (DRE) 18852 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); 18853 if (!DRE || 18854 !(Context.hasSameUnqualifiedType( 18855 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) || 18856 Context.typesAreCompatible(AllocatorExpr->getType(), 18857 DSAStack->getOMPAllocatorHandleT(), 18858 /*CompareUnqualified=*/true)) || 18859 (!IsPredefinedAllocator && 18860 (AllocatorExpr->getType().isConstant(Context) || 18861 !AllocatorExpr->isLValue()))) { 18862 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 18863 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 18864 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 18865 continue; 18866 } 18867 // OpenMP [2.12.5, target Construct] 18868 // Predefined allocators appearing in a uses_allocators clause cannot have 18869 // traits specified. 18870 if (IsPredefinedAllocator && D.AllocatorTraits) { 18871 Diag(D.AllocatorTraits->getExprLoc(), 18872 diag::err_omp_predefined_allocator_with_traits) 18873 << D.AllocatorTraits->getSourceRange(); 18874 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 18875 << cast<NamedDecl>(DRE->getDecl())->getName() 18876 << D.Allocator->getSourceRange(); 18877 continue; 18878 } 18879 // OpenMP [2.12.5, target Construct] 18880 // Non-predefined allocators appearing in a uses_allocators clause must 18881 // have traits specified. 18882 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 18883 Diag(D.Allocator->getExprLoc(), 18884 diag::err_omp_nonpredefined_allocator_without_traits); 18885 continue; 18886 } 18887 // No allocator traits - just convert it to rvalue. 18888 if (!D.AllocatorTraits) 18889 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 18890 DSAStack->addUsesAllocatorsDecl( 18891 DRE->getDecl(), 18892 IsPredefinedAllocator 18893 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator 18894 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); 18895 } 18896 Expr *AllocatorTraitsExpr = nullptr; 18897 if (D.AllocatorTraits) { 18898 if (D.AllocatorTraits->isTypeDependent()) { 18899 AllocatorTraitsExpr = D.AllocatorTraits; 18900 } else { 18901 // OpenMP [2.12.5, target Construct] 18902 // Arrays that contain allocator traits that appear in a uses_allocators 18903 // clause must be constant arrays, have constant values and be defined 18904 // in the same scope as the construct in which the clause appears. 18905 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 18906 // Check that traits expr is a constant array. 18907 QualType TraitTy; 18908 if (const ArrayType *Ty = 18909 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 18910 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 18911 TraitTy = ConstArrayTy->getElementType(); 18912 if (TraitTy.isNull() || 18913 !(Context.hasSameUnqualifiedType(TraitTy, 18914 DSAStack->getOMPAlloctraitT()) || 18915 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 18916 /*CompareUnqualified=*/true))) { 18917 Diag(D.AllocatorTraits->getExprLoc(), 18918 diag::err_omp_expected_array_alloctraits) 18919 << AllocatorTraitsExpr->getType(); 18920 continue; 18921 } 18922 // Do not map by default allocator traits if it is a standalone 18923 // variable. 18924 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) 18925 DSAStack->addUsesAllocatorsDecl( 18926 DRE->getDecl(), 18927 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); 18928 } 18929 } 18930 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 18931 NewD.Allocator = AllocatorExpr; 18932 NewD.AllocatorTraits = AllocatorTraitsExpr; 18933 NewD.LParenLoc = D.LParenLoc; 18934 NewD.RParenLoc = D.RParenLoc; 18935 } 18936 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18937 NewData); 18938 } 18939 18940 OMPClause *Sema::ActOnOpenMPAffinityClause( 18941 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 18942 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { 18943 SmallVector<Expr *, 8> Vars; 18944 for (Expr *RefExpr : Locators) { 18945 assert(RefExpr && "NULL expr in OpenMP shared clause."); 18946 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { 18947 // It will be analyzed later. 18948 Vars.push_back(RefExpr); 18949 continue; 18950 } 18951 18952 SourceLocation ELoc = RefExpr->getExprLoc(); 18953 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); 18954 18955 if (!SimpleExpr->isLValue()) { 18956 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 18957 << 1 << 0 << RefExpr->getSourceRange(); 18958 continue; 18959 } 18960 18961 ExprResult Res; 18962 { 18963 Sema::TentativeAnalysisScope Trap(*this); 18964 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); 18965 } 18966 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 18967 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 18968 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 18969 << 1 << 0 << RefExpr->getSourceRange(); 18970 continue; 18971 } 18972 Vars.push_back(SimpleExpr); 18973 } 18974 18975 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 18976 EndLoc, Modifier, Vars); 18977 } 18978