1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/DiagnosticSema.h" 26 #include "clang/Basic/OpenMPKinds.h" 27 #include "clang/Basic/PartialDiagnostic.h" 28 #include "clang/Basic/TargetInfo.h" 29 #include "clang/Sema/Initialization.h" 30 #include "clang/Sema/Lookup.h" 31 #include "clang/Sema/Scope.h" 32 #include "clang/Sema/ScopeInfo.h" 33 #include "clang/Sema/SemaInternal.h" 34 #include "llvm/ADT/IndexedMap.h" 35 #include "llvm/ADT/PointerEmbeddedInt.h" 36 #include "llvm/ADT/STLExtras.h" 37 #include "llvm/Frontend/OpenMP/OMPConstants.h" 38 #include <set> 39 40 using namespace clang; 41 using namespace llvm::omp; 42 43 //===----------------------------------------------------------------------===// 44 // Stack of data-sharing attributes for variables 45 //===----------------------------------------------------------------------===// 46 47 static const Expr *checkMapClauseExpressionBase( 48 Sema &SemaRef, Expr *E, 49 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 50 OpenMPClauseKind CKind, bool NoDiagnose); 51 52 namespace { 53 /// Default data sharing attributes, which can be applied to directive. 54 enum DefaultDataSharingAttributes { 55 DSA_unspecified = 0, /// Data sharing attribute not specified. 56 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 57 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 58 }; 59 60 /// Stack for tracking declarations used in OpenMP directives and 61 /// clauses and their data-sharing attributes. 62 class DSAStackTy { 63 public: 64 struct DSAVarData { 65 OpenMPDirectiveKind DKind = OMPD_unknown; 66 OpenMPClauseKind CKind = OMPC_unknown; 67 unsigned Modifier = 0; 68 const Expr *RefExpr = nullptr; 69 DeclRefExpr *PrivateCopy = nullptr; 70 SourceLocation ImplicitDSALoc; 71 DSAVarData() = default; 72 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 73 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 74 SourceLocation ImplicitDSALoc, unsigned Modifier) 75 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), 76 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 77 }; 78 using OperatorOffsetTy = 79 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 80 using DoacrossDependMapTy = 81 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 82 83 private: 84 struct DSAInfo { 85 OpenMPClauseKind Attributes = OMPC_unknown; 86 unsigned Modifier = 0; 87 /// Pointer to a reference expression and a flag which shows that the 88 /// variable is marked as lastprivate(true) or not (false). 89 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 90 DeclRefExpr *PrivateCopy = nullptr; 91 }; 92 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 93 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 94 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 95 using LoopControlVariablesMapTy = 96 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 97 /// Struct that associates a component with the clause kind where they are 98 /// found. 99 struct MappedExprComponentTy { 100 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 101 OpenMPClauseKind Kind = OMPC_unknown; 102 }; 103 using MappedExprComponentsTy = 104 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 105 using CriticalsWithHintsTy = 106 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 107 struct ReductionData { 108 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 109 SourceRange ReductionRange; 110 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 111 ReductionData() = default; 112 void set(BinaryOperatorKind BO, SourceRange RR) { 113 ReductionRange = RR; 114 ReductionOp = BO; 115 } 116 void set(const Expr *RefExpr, SourceRange RR) { 117 ReductionRange = RR; 118 ReductionOp = RefExpr; 119 } 120 }; 121 using DeclReductionMapTy = 122 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 123 struct DefaultmapInfo { 124 OpenMPDefaultmapClauseModifier ImplicitBehavior = 125 OMPC_DEFAULTMAP_MODIFIER_unknown; 126 SourceLocation SLoc; 127 DefaultmapInfo() = default; 128 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 129 : ImplicitBehavior(M), SLoc(Loc) {} 130 }; 131 132 struct SharingMapTy { 133 DeclSAMapTy SharingMap; 134 DeclReductionMapTy ReductionMap; 135 UsedRefMapTy AlignedMap; 136 UsedRefMapTy NontemporalMap; 137 MappedExprComponentsTy MappedExprComponents; 138 LoopControlVariablesMapTy LCVMap; 139 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 140 SourceLocation DefaultAttrLoc; 141 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 142 OpenMPDirectiveKind Directive = OMPD_unknown; 143 DeclarationNameInfo DirectiveName; 144 Scope *CurScope = nullptr; 145 SourceLocation ConstructLoc; 146 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 147 /// get the data (loop counters etc.) about enclosing loop-based construct. 148 /// This data is required during codegen. 149 DoacrossDependMapTy DoacrossDepends; 150 /// First argument (Expr *) contains optional argument of the 151 /// 'ordered' clause, the second one is true if the regions has 'ordered' 152 /// clause, false otherwise. 153 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 154 unsigned AssociatedLoops = 1; 155 bool HasMutipleLoops = false; 156 const Decl *PossiblyLoopCounter = nullptr; 157 bool NowaitRegion = false; 158 bool CancelRegion = false; 159 bool LoopStart = false; 160 bool BodyComplete = false; 161 SourceLocation PrevScanLocation; 162 SourceLocation InnerTeamsRegionLoc; 163 /// Reference to the taskgroup task_reduction reference expression. 164 Expr *TaskgroupReductionRef = nullptr; 165 llvm::DenseSet<QualType> MappedClassesQualTypes; 166 SmallVector<Expr *, 4> InnerUsedAllocators; 167 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; 168 /// List of globals marked as declare target link in this target region 169 /// (isOpenMPTargetExecutionDirective(Directive) == true). 170 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 171 /// List of decls used in inclusive/exclusive clauses of the scan directive. 172 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; 173 llvm::DenseSet<CanonicalDeclPtr<const Decl>> UsesAllocatorsDecls; 174 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 175 Scope *CurScope, SourceLocation Loc) 176 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 177 ConstructLoc(Loc) {} 178 SharingMapTy() = default; 179 }; 180 181 using StackTy = SmallVector<SharingMapTy, 4>; 182 183 /// Stack of used declaration and their data-sharing attributes. 184 DeclSAMapTy Threadprivates; 185 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 186 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 187 /// true, if check for DSA must be from parent directive, false, if 188 /// from current directive. 189 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 190 Sema &SemaRef; 191 bool ForceCapturing = false; 192 /// true if all the variables in the target executable directives must be 193 /// captured by reference. 194 bool ForceCaptureByReferenceInTargetExecutable = false; 195 CriticalsWithHintsTy Criticals; 196 unsigned IgnoredStackElements = 0; 197 198 /// Iterators over the stack iterate in order from innermost to outermost 199 /// directive. 200 using const_iterator = StackTy::const_reverse_iterator; 201 const_iterator begin() const { 202 return Stack.empty() ? const_iterator() 203 : Stack.back().first.rbegin() + IgnoredStackElements; 204 } 205 const_iterator end() const { 206 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 207 } 208 using iterator = StackTy::reverse_iterator; 209 iterator begin() { 210 return Stack.empty() ? iterator() 211 : Stack.back().first.rbegin() + IgnoredStackElements; 212 } 213 iterator end() { 214 return Stack.empty() ? iterator() : Stack.back().first.rend(); 215 } 216 217 // Convenience operations to get at the elements of the stack. 218 219 bool isStackEmpty() const { 220 return Stack.empty() || 221 Stack.back().second != CurrentNonCapturingFunctionScope || 222 Stack.back().first.size() <= IgnoredStackElements; 223 } 224 size_t getStackSize() const { 225 return isStackEmpty() ? 0 226 : Stack.back().first.size() - IgnoredStackElements; 227 } 228 229 SharingMapTy *getTopOfStackOrNull() { 230 size_t Size = getStackSize(); 231 if (Size == 0) 232 return nullptr; 233 return &Stack.back().first[Size - 1]; 234 } 235 const SharingMapTy *getTopOfStackOrNull() const { 236 return const_cast<DSAStackTy&>(*this).getTopOfStackOrNull(); 237 } 238 SharingMapTy &getTopOfStack() { 239 assert(!isStackEmpty() && "no current directive"); 240 return *getTopOfStackOrNull(); 241 } 242 const SharingMapTy &getTopOfStack() const { 243 return const_cast<DSAStackTy&>(*this).getTopOfStack(); 244 } 245 246 SharingMapTy *getSecondOnStackOrNull() { 247 size_t Size = getStackSize(); 248 if (Size <= 1) 249 return nullptr; 250 return &Stack.back().first[Size - 2]; 251 } 252 const SharingMapTy *getSecondOnStackOrNull() const { 253 return const_cast<DSAStackTy&>(*this).getSecondOnStackOrNull(); 254 } 255 256 /// Get the stack element at a certain level (previously returned by 257 /// \c getNestingLevel). 258 /// 259 /// Note that nesting levels count from outermost to innermost, and this is 260 /// the reverse of our iteration order where new inner levels are pushed at 261 /// the front of the stack. 262 SharingMapTy &getStackElemAtLevel(unsigned Level) { 263 assert(Level < getStackSize() && "no such stack element"); 264 return Stack.back().first[Level]; 265 } 266 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 267 return const_cast<DSAStackTy&>(*this).getStackElemAtLevel(Level); 268 } 269 270 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 271 272 /// Checks if the variable is a local for OpenMP region. 273 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 274 275 /// Vector of previously declared requires directives 276 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 277 /// omp_allocator_handle_t type. 278 QualType OMPAllocatorHandleT; 279 /// omp_depend_t type. 280 QualType OMPDependT; 281 /// omp_event_handle_t type. 282 QualType OMPEventHandleT; 283 /// omp_alloctrait_t type. 284 QualType OMPAlloctraitT; 285 /// Expression for the predefined allocators. 286 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 287 nullptr}; 288 /// Vector of previously encountered target directives 289 SmallVector<SourceLocation, 2> TargetLocations; 290 SourceLocation AtomicLocation; 291 292 public: 293 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 294 295 /// Sets omp_allocator_handle_t type. 296 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 297 /// Gets omp_allocator_handle_t type. 298 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 299 /// Sets omp_alloctrait_t type. 300 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; } 301 /// Gets omp_alloctrait_t type. 302 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; } 303 /// Sets the given default allocator. 304 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 305 Expr *Allocator) { 306 OMPPredefinedAllocators[AllocatorKind] = Allocator; 307 } 308 /// Returns the specified default allocator. 309 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 310 return OMPPredefinedAllocators[AllocatorKind]; 311 } 312 /// Sets omp_depend_t type. 313 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 314 /// Gets omp_depend_t type. 315 QualType getOMPDependT() const { return OMPDependT; } 316 317 /// Sets omp_event_handle_t type. 318 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } 319 /// Gets omp_event_handle_t type. 320 QualType getOMPEventHandleT() const { return OMPEventHandleT; } 321 322 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 323 OpenMPClauseKind getClauseParsingMode() const { 324 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 325 return ClauseKindMode; 326 } 327 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 328 329 bool isBodyComplete() const { 330 const SharingMapTy *Top = getTopOfStackOrNull(); 331 return Top && Top->BodyComplete; 332 } 333 void setBodyComplete() { 334 getTopOfStack().BodyComplete = true; 335 } 336 337 bool isForceVarCapturing() const { return ForceCapturing; } 338 void setForceVarCapturing(bool V) { ForceCapturing = V; } 339 340 void setForceCaptureByReferenceInTargetExecutable(bool V) { 341 ForceCaptureByReferenceInTargetExecutable = V; 342 } 343 bool isForceCaptureByReferenceInTargetExecutable() const { 344 return ForceCaptureByReferenceInTargetExecutable; 345 } 346 347 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 348 Scope *CurScope, SourceLocation Loc) { 349 assert(!IgnoredStackElements && 350 "cannot change stack while ignoring elements"); 351 if (Stack.empty() || 352 Stack.back().second != CurrentNonCapturingFunctionScope) 353 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 354 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 355 Stack.back().first.back().DefaultAttrLoc = Loc; 356 } 357 358 void pop() { 359 assert(!IgnoredStackElements && 360 "cannot change stack while ignoring elements"); 361 assert(!Stack.back().first.empty() && 362 "Data-sharing attributes stack is empty!"); 363 Stack.back().first.pop_back(); 364 } 365 366 /// RAII object to temporarily leave the scope of a directive when we want to 367 /// logically operate in its parent. 368 class ParentDirectiveScope { 369 DSAStackTy &Self; 370 bool Active; 371 public: 372 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 373 : Self(Self), Active(false) { 374 if (Activate) 375 enable(); 376 } 377 ~ParentDirectiveScope() { disable(); } 378 void disable() { 379 if (Active) { 380 --Self.IgnoredStackElements; 381 Active = false; 382 } 383 } 384 void enable() { 385 if (!Active) { 386 ++Self.IgnoredStackElements; 387 Active = true; 388 } 389 } 390 }; 391 392 /// Marks that we're started loop parsing. 393 void loopInit() { 394 assert(isOpenMPLoopDirective(getCurrentDirective()) && 395 "Expected loop-based directive."); 396 getTopOfStack().LoopStart = true; 397 } 398 /// Start capturing of the variables in the loop context. 399 void loopStart() { 400 assert(isOpenMPLoopDirective(getCurrentDirective()) && 401 "Expected loop-based directive."); 402 getTopOfStack().LoopStart = false; 403 } 404 /// true, if variables are captured, false otherwise. 405 bool isLoopStarted() const { 406 assert(isOpenMPLoopDirective(getCurrentDirective()) && 407 "Expected loop-based directive."); 408 return !getTopOfStack().LoopStart; 409 } 410 /// Marks (or clears) declaration as possibly loop counter. 411 void resetPossibleLoopCounter(const Decl *D = nullptr) { 412 getTopOfStack().PossiblyLoopCounter = 413 D ? D->getCanonicalDecl() : D; 414 } 415 /// Gets the possible loop counter decl. 416 const Decl *getPossiblyLoopCunter() const { 417 return getTopOfStack().PossiblyLoopCounter; 418 } 419 /// Start new OpenMP region stack in new non-capturing function. 420 void pushFunction() { 421 assert(!IgnoredStackElements && 422 "cannot change stack while ignoring elements"); 423 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 424 assert(!isa<CapturingScopeInfo>(CurFnScope)); 425 CurrentNonCapturingFunctionScope = CurFnScope; 426 } 427 /// Pop region stack for non-capturing function. 428 void popFunction(const FunctionScopeInfo *OldFSI) { 429 assert(!IgnoredStackElements && 430 "cannot change stack while ignoring elements"); 431 if (!Stack.empty() && Stack.back().second == OldFSI) { 432 assert(Stack.back().first.empty()); 433 Stack.pop_back(); 434 } 435 CurrentNonCapturingFunctionScope = nullptr; 436 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 437 if (!isa<CapturingScopeInfo>(FSI)) { 438 CurrentNonCapturingFunctionScope = FSI; 439 break; 440 } 441 } 442 } 443 444 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 445 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 446 } 447 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 448 getCriticalWithHint(const DeclarationNameInfo &Name) const { 449 auto I = Criticals.find(Name.getAsString()); 450 if (I != Criticals.end()) 451 return I->second; 452 return std::make_pair(nullptr, llvm::APSInt()); 453 } 454 /// If 'aligned' declaration for given variable \a D was not seen yet, 455 /// add it and return NULL; otherwise return previous occurrence's expression 456 /// for diagnostics. 457 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 458 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 459 /// add it and return NULL; otherwise return previous occurrence's expression 460 /// for diagnostics. 461 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 462 463 /// Register specified variable as loop control variable. 464 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 465 /// Check if the specified variable is a loop control variable for 466 /// current region. 467 /// \return The index of the loop control variable in the list of associated 468 /// for-loops (from outer to inner). 469 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 470 /// Check if the specified variable is a loop control variable for 471 /// parent region. 472 /// \return The index of the loop control variable in the list of associated 473 /// for-loops (from outer to inner). 474 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 475 /// Check if the specified variable is a loop control variable for 476 /// current region. 477 /// \return The index of the loop control variable in the list of associated 478 /// for-loops (from outer to inner). 479 const LCDeclInfo isLoopControlVariable(const ValueDecl *D, 480 unsigned Level) const; 481 /// Get the loop control variable for the I-th loop (or nullptr) in 482 /// parent directive. 483 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 484 485 /// Marks the specified decl \p D as used in scan directive. 486 void markDeclAsUsedInScanDirective(ValueDecl *D) { 487 if (SharingMapTy *Stack = getSecondOnStackOrNull()) 488 Stack->UsedInScanDirective.insert(D); 489 } 490 491 /// Checks if the specified declaration was used in the inner scan directive. 492 bool isUsedInScanDirective(ValueDecl *D) const { 493 if (const SharingMapTy *Stack = getTopOfStackOrNull()) 494 return Stack->UsedInScanDirective.count(D) > 0; 495 return false; 496 } 497 498 /// Adds explicit data sharing attribute to the specified declaration. 499 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 500 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0); 501 502 /// Adds additional information for the reduction items with the reduction id 503 /// represented as an operator. 504 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 505 BinaryOperatorKind BOK); 506 /// Adds additional information for the reduction items with the reduction id 507 /// represented as reduction identifier. 508 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 509 const Expr *ReductionRef); 510 /// Returns the location and reduction operation from the innermost parent 511 /// region for the given \p D. 512 const DSAVarData 513 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 514 BinaryOperatorKind &BOK, 515 Expr *&TaskgroupDescriptor) const; 516 /// Returns the location and reduction operation from the innermost parent 517 /// region for the given \p D. 518 const DSAVarData 519 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 520 const Expr *&ReductionRef, 521 Expr *&TaskgroupDescriptor) const; 522 /// Return reduction reference expression for the current taskgroup or 523 /// parallel/worksharing directives with task reductions. 524 Expr *getTaskgroupReductionRef() const { 525 assert((getTopOfStack().Directive == OMPD_taskgroup || 526 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 527 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 528 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 529 "taskgroup reference expression requested for non taskgroup or " 530 "parallel/worksharing directive."); 531 return getTopOfStack().TaskgroupReductionRef; 532 } 533 /// Checks if the given \p VD declaration is actually a taskgroup reduction 534 /// descriptor variable at the \p Level of OpenMP regions. 535 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 536 return getStackElemAtLevel(Level).TaskgroupReductionRef && 537 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 538 ->getDecl() == VD; 539 } 540 541 /// Returns data sharing attributes from top of the stack for the 542 /// specified declaration. 543 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 544 /// Returns data-sharing attributes for the specified declaration. 545 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 546 /// Returns data-sharing attributes for the specified declaration. 547 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; 548 /// Checks if the specified variables has data-sharing attributes which 549 /// match specified \a CPred predicate in any directive which matches \a DPred 550 /// predicate. 551 const DSAVarData 552 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 553 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 554 bool FromParent) const; 555 /// Checks if the specified variables has data-sharing attributes which 556 /// match specified \a CPred predicate in any innermost directive which 557 /// matches \a DPred predicate. 558 const DSAVarData 559 hasInnermostDSA(ValueDecl *D, 560 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 561 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 562 bool FromParent) const; 563 /// Checks if the specified variables has explicit data-sharing 564 /// attributes which match specified \a CPred predicate at the specified 565 /// OpenMP region. 566 bool hasExplicitDSA(const ValueDecl *D, 567 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 568 unsigned Level, bool NotLastprivate = false) const; 569 570 /// Returns true if the directive at level \Level matches in the 571 /// specified \a DPred predicate. 572 bool hasExplicitDirective( 573 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 574 unsigned Level) const; 575 576 /// Finds a directive which matches specified \a DPred predicate. 577 bool hasDirective( 578 const llvm::function_ref<bool( 579 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 580 DPred, 581 bool FromParent) const; 582 583 /// Returns currently analyzed directive. 584 OpenMPDirectiveKind getCurrentDirective() const { 585 const SharingMapTy *Top = getTopOfStackOrNull(); 586 return Top ? Top->Directive : OMPD_unknown; 587 } 588 /// Returns directive kind at specified level. 589 OpenMPDirectiveKind getDirective(unsigned Level) const { 590 assert(!isStackEmpty() && "No directive at specified level."); 591 return getStackElemAtLevel(Level).Directive; 592 } 593 /// Returns the capture region at the specified level. 594 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 595 unsigned OpenMPCaptureLevel) const { 596 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 597 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 598 return CaptureRegions[OpenMPCaptureLevel]; 599 } 600 /// Returns parent directive. 601 OpenMPDirectiveKind getParentDirective() const { 602 const SharingMapTy *Parent = getSecondOnStackOrNull(); 603 return Parent ? Parent->Directive : OMPD_unknown; 604 } 605 606 /// Add requires decl to internal vector 607 void addRequiresDecl(OMPRequiresDecl *RD) { 608 RequiresDecls.push_back(RD); 609 } 610 611 /// Checks if the defined 'requires' directive has specified type of clause. 612 template <typename ClauseType> 613 bool hasRequiresDeclWithClause() const { 614 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 615 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 616 return isa<ClauseType>(C); 617 }); 618 }); 619 } 620 621 /// Checks for a duplicate clause amongst previously declared requires 622 /// directives 623 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 624 bool IsDuplicate = false; 625 for (OMPClause *CNew : ClauseList) { 626 for (const OMPRequiresDecl *D : RequiresDecls) { 627 for (const OMPClause *CPrev : D->clauselists()) { 628 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 629 SemaRef.Diag(CNew->getBeginLoc(), 630 diag::err_omp_requires_clause_redeclaration) 631 << getOpenMPClauseName(CNew->getClauseKind()); 632 SemaRef.Diag(CPrev->getBeginLoc(), 633 diag::note_omp_requires_previous_clause) 634 << getOpenMPClauseName(CPrev->getClauseKind()); 635 IsDuplicate = true; 636 } 637 } 638 } 639 } 640 return IsDuplicate; 641 } 642 643 /// Add location of previously encountered target to internal vector 644 void addTargetDirLocation(SourceLocation LocStart) { 645 TargetLocations.push_back(LocStart); 646 } 647 648 /// Add location for the first encountered atomicc directive. 649 void addAtomicDirectiveLoc(SourceLocation Loc) { 650 if (AtomicLocation.isInvalid()) 651 AtomicLocation = Loc; 652 } 653 654 /// Returns the location of the first encountered atomic directive in the 655 /// module. 656 SourceLocation getAtomicDirectiveLoc() const { 657 return AtomicLocation; 658 } 659 660 // Return previously encountered target region locations. 661 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 662 return TargetLocations; 663 } 664 665 /// Set default data sharing attribute to none. 666 void setDefaultDSANone(SourceLocation Loc) { 667 getTopOfStack().DefaultAttr = DSA_none; 668 getTopOfStack().DefaultAttrLoc = Loc; 669 } 670 /// Set default data sharing attribute to shared. 671 void setDefaultDSAShared(SourceLocation Loc) { 672 getTopOfStack().DefaultAttr = DSA_shared; 673 getTopOfStack().DefaultAttrLoc = Loc; 674 } 675 /// Set default data mapping attribute to Modifier:Kind 676 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 677 OpenMPDefaultmapClauseKind Kind, 678 SourceLocation Loc) { 679 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 680 DMI.ImplicitBehavior = M; 681 DMI.SLoc = Loc; 682 } 683 /// Check whether the implicit-behavior has been set in defaultmap 684 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 685 if (VariableCategory == OMPC_DEFAULTMAP_unknown) 686 return getTopOfStack() 687 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] 688 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 689 getTopOfStack() 690 .DefaultmapMap[OMPC_DEFAULTMAP_scalar] 691 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 692 getTopOfStack() 693 .DefaultmapMap[OMPC_DEFAULTMAP_pointer] 694 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; 695 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 696 OMPC_DEFAULTMAP_MODIFIER_unknown; 697 } 698 699 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { 700 return getStackSize() <= Level ? DSA_unspecified 701 : getStackElemAtLevel(Level).DefaultAttr; 702 } 703 DefaultDataSharingAttributes getDefaultDSA() const { 704 return isStackEmpty() ? DSA_unspecified 705 : getTopOfStack().DefaultAttr; 706 } 707 SourceLocation getDefaultDSALocation() const { 708 return isStackEmpty() ? SourceLocation() 709 : getTopOfStack().DefaultAttrLoc; 710 } 711 OpenMPDefaultmapClauseModifier 712 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 713 return isStackEmpty() 714 ? OMPC_DEFAULTMAP_MODIFIER_unknown 715 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 716 } 717 OpenMPDefaultmapClauseModifier 718 getDefaultmapModifierAtLevel(unsigned Level, 719 OpenMPDefaultmapClauseKind Kind) const { 720 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 721 } 722 bool isDefaultmapCapturedByRef(unsigned Level, 723 OpenMPDefaultmapClauseKind Kind) const { 724 OpenMPDefaultmapClauseModifier M = 725 getDefaultmapModifierAtLevel(Level, Kind); 726 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 727 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 728 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 729 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 730 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 731 } 732 return true; 733 } 734 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 735 OpenMPDefaultmapClauseKind Kind) { 736 switch (Kind) { 737 case OMPC_DEFAULTMAP_scalar: 738 case OMPC_DEFAULTMAP_pointer: 739 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 740 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 741 (M == OMPC_DEFAULTMAP_MODIFIER_default); 742 case OMPC_DEFAULTMAP_aggregate: 743 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 744 default: 745 break; 746 } 747 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 748 } 749 bool mustBeFirstprivateAtLevel(unsigned Level, 750 OpenMPDefaultmapClauseKind Kind) const { 751 OpenMPDefaultmapClauseModifier M = 752 getDefaultmapModifierAtLevel(Level, Kind); 753 return mustBeFirstprivateBase(M, Kind); 754 } 755 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 756 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 757 return mustBeFirstprivateBase(M, Kind); 758 } 759 760 /// Checks if the specified variable is a threadprivate. 761 bool isThreadPrivate(VarDecl *D) { 762 const DSAVarData DVar = getTopDSA(D, false); 763 return isOpenMPThreadPrivate(DVar.CKind); 764 } 765 766 /// Marks current region as ordered (it has an 'ordered' clause). 767 void setOrderedRegion(bool IsOrdered, const Expr *Param, 768 OMPOrderedClause *Clause) { 769 if (IsOrdered) 770 getTopOfStack().OrderedRegion.emplace(Param, Clause); 771 else 772 getTopOfStack().OrderedRegion.reset(); 773 } 774 /// Returns true, if region is ordered (has associated 'ordered' clause), 775 /// false - otherwise. 776 bool isOrderedRegion() const { 777 if (const SharingMapTy *Top = getTopOfStackOrNull()) 778 return Top->OrderedRegion.hasValue(); 779 return false; 780 } 781 /// Returns optional parameter for the ordered region. 782 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 783 if (const SharingMapTy *Top = getTopOfStackOrNull()) 784 if (Top->OrderedRegion.hasValue()) 785 return Top->OrderedRegion.getValue(); 786 return std::make_pair(nullptr, nullptr); 787 } 788 /// Returns true, if parent region is ordered (has associated 789 /// 'ordered' clause), false - otherwise. 790 bool isParentOrderedRegion() const { 791 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 792 return Parent->OrderedRegion.hasValue(); 793 return false; 794 } 795 /// Returns optional parameter for the ordered region. 796 std::pair<const Expr *, OMPOrderedClause *> 797 getParentOrderedRegionParam() const { 798 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 799 if (Parent->OrderedRegion.hasValue()) 800 return Parent->OrderedRegion.getValue(); 801 return std::make_pair(nullptr, nullptr); 802 } 803 /// Marks current region as nowait (it has a 'nowait' clause). 804 void setNowaitRegion(bool IsNowait = true) { 805 getTopOfStack().NowaitRegion = IsNowait; 806 } 807 /// Returns true, if parent region is nowait (has associated 808 /// 'nowait' clause), false - otherwise. 809 bool isParentNowaitRegion() const { 810 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 811 return Parent->NowaitRegion; 812 return false; 813 } 814 /// Marks parent region as cancel region. 815 void setParentCancelRegion(bool Cancel = true) { 816 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 817 Parent->CancelRegion |= Cancel; 818 } 819 /// Return true if current region has inner cancel construct. 820 bool isCancelRegion() const { 821 const SharingMapTy *Top = getTopOfStackOrNull(); 822 return Top ? Top->CancelRegion : false; 823 } 824 825 /// Mark that parent region already has scan directive. 826 void setParentHasScanDirective(SourceLocation Loc) { 827 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 828 Parent->PrevScanLocation = Loc; 829 } 830 /// Return true if current region has inner cancel construct. 831 bool doesParentHasScanDirective() const { 832 const SharingMapTy *Top = getSecondOnStackOrNull(); 833 return Top ? Top->PrevScanLocation.isValid() : false; 834 } 835 /// Return true if current region has inner cancel construct. 836 SourceLocation getParentScanDirectiveLoc() const { 837 const SharingMapTy *Top = getSecondOnStackOrNull(); 838 return Top ? Top->PrevScanLocation : SourceLocation(); 839 } 840 841 /// Set collapse value for the region. 842 void setAssociatedLoops(unsigned Val) { 843 getTopOfStack().AssociatedLoops = Val; 844 if (Val > 1) 845 getTopOfStack().HasMutipleLoops = true; 846 } 847 /// Return collapse value for region. 848 unsigned getAssociatedLoops() const { 849 const SharingMapTy *Top = getTopOfStackOrNull(); 850 return Top ? Top->AssociatedLoops : 0; 851 } 852 /// Returns true if the construct is associated with multiple loops. 853 bool hasMutipleLoops() const { 854 const SharingMapTy *Top = getTopOfStackOrNull(); 855 return Top ? Top->HasMutipleLoops : false; 856 } 857 858 /// Marks current target region as one with closely nested teams 859 /// region. 860 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 861 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 862 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 863 } 864 /// Returns true, if current region has closely nested teams region. 865 bool hasInnerTeamsRegion() const { 866 return getInnerTeamsRegionLoc().isValid(); 867 } 868 /// Returns location of the nested teams region (if any). 869 SourceLocation getInnerTeamsRegionLoc() const { 870 const SharingMapTy *Top = getTopOfStackOrNull(); 871 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 872 } 873 874 Scope *getCurScope() const { 875 const SharingMapTy *Top = getTopOfStackOrNull(); 876 return Top ? Top->CurScope : nullptr; 877 } 878 SourceLocation getConstructLoc() const { 879 const SharingMapTy *Top = getTopOfStackOrNull(); 880 return Top ? Top->ConstructLoc : SourceLocation(); 881 } 882 883 /// Do the check specified in \a Check to all component lists and return true 884 /// if any issue is found. 885 bool checkMappableExprComponentListsForDecl( 886 const ValueDecl *VD, bool CurrentRegionOnly, 887 const llvm::function_ref< 888 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 889 OpenMPClauseKind)> 890 Check) const { 891 if (isStackEmpty()) 892 return false; 893 auto SI = begin(); 894 auto SE = end(); 895 896 if (SI == SE) 897 return false; 898 899 if (CurrentRegionOnly) 900 SE = std::next(SI); 901 else 902 std::advance(SI, 1); 903 904 for (; SI != SE; ++SI) { 905 auto MI = SI->MappedExprComponents.find(VD); 906 if (MI != SI->MappedExprComponents.end()) 907 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 908 MI->second.Components) 909 if (Check(L, MI->second.Kind)) 910 return true; 911 } 912 return false; 913 } 914 915 /// Do the check specified in \a Check to all component lists at a given level 916 /// and return true if any issue is found. 917 bool checkMappableExprComponentListsForDeclAtLevel( 918 const ValueDecl *VD, unsigned Level, 919 const llvm::function_ref< 920 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 921 OpenMPClauseKind)> 922 Check) const { 923 if (getStackSize() <= Level) 924 return false; 925 926 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 927 auto MI = StackElem.MappedExprComponents.find(VD); 928 if (MI != StackElem.MappedExprComponents.end()) 929 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 930 MI->second.Components) 931 if (Check(L, MI->second.Kind)) 932 return true; 933 return false; 934 } 935 936 /// Create a new mappable expression component list associated with a given 937 /// declaration and initialize it with the provided list of components. 938 void addMappableExpressionComponents( 939 const ValueDecl *VD, 940 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 941 OpenMPClauseKind WhereFoundClauseKind) { 942 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 943 // Create new entry and append the new components there. 944 MEC.Components.resize(MEC.Components.size() + 1); 945 MEC.Components.back().append(Components.begin(), Components.end()); 946 MEC.Kind = WhereFoundClauseKind; 947 } 948 949 unsigned getNestingLevel() const { 950 assert(!isStackEmpty()); 951 return getStackSize() - 1; 952 } 953 void addDoacrossDependClause(OMPDependClause *C, 954 const OperatorOffsetTy &OpsOffs) { 955 SharingMapTy *Parent = getSecondOnStackOrNull(); 956 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 957 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 958 } 959 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 960 getDoacrossDependClauses() const { 961 const SharingMapTy &StackElem = getTopOfStack(); 962 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 963 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 964 return llvm::make_range(Ref.begin(), Ref.end()); 965 } 966 return llvm::make_range(StackElem.DoacrossDepends.end(), 967 StackElem.DoacrossDepends.end()); 968 } 969 970 // Store types of classes which have been explicitly mapped 971 void addMappedClassesQualTypes(QualType QT) { 972 SharingMapTy &StackElem = getTopOfStack(); 973 StackElem.MappedClassesQualTypes.insert(QT); 974 } 975 976 // Return set of mapped classes types 977 bool isClassPreviouslyMapped(QualType QT) const { 978 const SharingMapTy &StackElem = getTopOfStack(); 979 return StackElem.MappedClassesQualTypes.count(QT) != 0; 980 } 981 982 /// Adds global declare target to the parent target region. 983 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 984 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 985 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 986 "Expected declare target link global."); 987 for (auto &Elem : *this) { 988 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 989 Elem.DeclareTargetLinkVarDecls.push_back(E); 990 return; 991 } 992 } 993 } 994 995 /// Returns the list of globals with declare target link if current directive 996 /// is target. 997 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 998 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 999 "Expected target executable directive."); 1000 return getTopOfStack().DeclareTargetLinkVarDecls; 1001 } 1002 1003 /// Adds list of allocators expressions. 1004 void addInnerAllocatorExpr(Expr *E) { 1005 getTopOfStack().InnerUsedAllocators.push_back(E); 1006 } 1007 /// Return list of used allocators. 1008 ArrayRef<Expr *> getInnerAllocators() const { 1009 return getTopOfStack().InnerUsedAllocators; 1010 } 1011 /// Marks the declaration as implicitly firstprivate nin the task-based 1012 /// regions. 1013 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { 1014 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); 1015 } 1016 /// Checks if the decl is implicitly firstprivate in the task-based region. 1017 bool isImplicitTaskFirstprivate(Decl *D) const { 1018 return getTopOfStack().ImplicitTaskFirstprivates.count(D) > 0; 1019 } 1020 1021 /// Marks decl as used in uses_allocators clause as the allocator. 1022 void addUsesAllocatorsDecl(const Decl *D) { 1023 getTopOfStack().UsesAllocatorsDecls.insert(D); 1024 } 1025 /// Checks if specified decl is used in uses allocator clause as the 1026 /// allocator. 1027 bool isUsesAllocatorsDecl(unsigned Level, const Decl *D) const { 1028 return getStackElemAtLevel(Level).UsesAllocatorsDecls.count(D) > 0; 1029 } 1030 bool isUsesAllocatorsDecl(const Decl *D) const { 1031 return getTopOfStack().UsesAllocatorsDecls.count(D) > 0; 1032 } 1033 }; 1034 1035 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1036 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 1037 } 1038 1039 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1040 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 1041 DKind == OMPD_unknown; 1042 } 1043 1044 } // namespace 1045 1046 static const Expr *getExprAsWritten(const Expr *E) { 1047 if (const auto *FE = dyn_cast<FullExpr>(E)) 1048 E = FE->getSubExpr(); 1049 1050 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 1051 E = MTE->getSubExpr(); 1052 1053 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 1054 E = Binder->getSubExpr(); 1055 1056 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 1057 E = ICE->getSubExprAsWritten(); 1058 return E->IgnoreParens(); 1059 } 1060 1061 static Expr *getExprAsWritten(Expr *E) { 1062 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 1063 } 1064 1065 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 1066 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 1067 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 1068 D = ME->getMemberDecl(); 1069 const auto *VD = dyn_cast<VarDecl>(D); 1070 const auto *FD = dyn_cast<FieldDecl>(D); 1071 if (VD != nullptr) { 1072 VD = VD->getCanonicalDecl(); 1073 D = VD; 1074 } else { 1075 assert(FD); 1076 FD = FD->getCanonicalDecl(); 1077 D = FD; 1078 } 1079 return D; 1080 } 1081 1082 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 1083 return const_cast<ValueDecl *>( 1084 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 1085 } 1086 1087 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 1088 ValueDecl *D) const { 1089 D = getCanonicalDecl(D); 1090 auto *VD = dyn_cast<VarDecl>(D); 1091 const auto *FD = dyn_cast<FieldDecl>(D); 1092 DSAVarData DVar; 1093 if (Iter == end()) { 1094 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1095 // in a region but not in construct] 1096 // File-scope or namespace-scope variables referenced in called routines 1097 // in the region are shared unless they appear in a threadprivate 1098 // directive. 1099 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1100 DVar.CKind = OMPC_shared; 1101 1102 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1103 // in a region but not in construct] 1104 // Variables with static storage duration that are declared in called 1105 // routines in the region are shared. 1106 if (VD && VD->hasGlobalStorage()) 1107 DVar.CKind = OMPC_shared; 1108 1109 // Non-static data members are shared by default. 1110 if (FD) 1111 DVar.CKind = OMPC_shared; 1112 1113 return DVar; 1114 } 1115 1116 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1117 // in a Construct, C/C++, predetermined, p.1] 1118 // Variables with automatic storage duration that are declared in a scope 1119 // inside the construct are private. 1120 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1121 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1122 DVar.CKind = OMPC_private; 1123 return DVar; 1124 } 1125 1126 DVar.DKind = Iter->Directive; 1127 // Explicitly specified attributes and local variables with predetermined 1128 // attributes. 1129 if (Iter->SharingMap.count(D)) { 1130 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1131 DVar.RefExpr = Data.RefExpr.getPointer(); 1132 DVar.PrivateCopy = Data.PrivateCopy; 1133 DVar.CKind = Data.Attributes; 1134 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1135 DVar.Modifier = Data.Modifier; 1136 return DVar; 1137 } 1138 1139 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1140 // in a Construct, C/C++, implicitly determined, p.1] 1141 // In a parallel or task construct, the data-sharing attributes of these 1142 // variables are determined by the default clause, if present. 1143 switch (Iter->DefaultAttr) { 1144 case DSA_shared: 1145 DVar.CKind = OMPC_shared; 1146 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1147 return DVar; 1148 case DSA_none: 1149 return DVar; 1150 case DSA_unspecified: 1151 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1152 // in a Construct, implicitly determined, p.2] 1153 // In a parallel construct, if no default clause is present, these 1154 // variables are shared. 1155 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1156 if ((isOpenMPParallelDirective(DVar.DKind) && 1157 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1158 isOpenMPTeamsDirective(DVar.DKind)) { 1159 DVar.CKind = OMPC_shared; 1160 return DVar; 1161 } 1162 1163 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1164 // in a Construct, implicitly determined, p.4] 1165 // In a task construct, if no default clause is present, a variable that in 1166 // the enclosing context is determined to be shared by all implicit tasks 1167 // bound to the current team is shared. 1168 if (isOpenMPTaskingDirective(DVar.DKind)) { 1169 DSAVarData DVarTemp; 1170 const_iterator I = Iter, E = end(); 1171 do { 1172 ++I; 1173 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1174 // Referenced in a Construct, implicitly determined, p.6] 1175 // In a task construct, if no default clause is present, a variable 1176 // whose data-sharing attribute is not determined by the rules above is 1177 // firstprivate. 1178 DVarTemp = getDSA(I, D); 1179 if (DVarTemp.CKind != OMPC_shared) { 1180 DVar.RefExpr = nullptr; 1181 DVar.CKind = OMPC_firstprivate; 1182 return DVar; 1183 } 1184 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1185 DVar.CKind = 1186 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1187 return DVar; 1188 } 1189 } 1190 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1191 // in a Construct, implicitly determined, p.3] 1192 // For constructs other than task, if no default clause is present, these 1193 // variables inherit their data-sharing attributes from the enclosing 1194 // context. 1195 return getDSA(++Iter, D); 1196 } 1197 1198 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1199 const Expr *NewDE) { 1200 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1201 D = getCanonicalDecl(D); 1202 SharingMapTy &StackElem = getTopOfStack(); 1203 auto It = StackElem.AlignedMap.find(D); 1204 if (It == StackElem.AlignedMap.end()) { 1205 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1206 StackElem.AlignedMap[D] = NewDE; 1207 return nullptr; 1208 } 1209 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1210 return It->second; 1211 } 1212 1213 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1214 const Expr *NewDE) { 1215 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1216 D = getCanonicalDecl(D); 1217 SharingMapTy &StackElem = getTopOfStack(); 1218 auto It = StackElem.NontemporalMap.find(D); 1219 if (It == StackElem.NontemporalMap.end()) { 1220 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1221 StackElem.NontemporalMap[D] = NewDE; 1222 return nullptr; 1223 } 1224 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1225 return It->second; 1226 } 1227 1228 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1229 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1230 D = getCanonicalDecl(D); 1231 SharingMapTy &StackElem = getTopOfStack(); 1232 StackElem.LCVMap.try_emplace( 1233 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1234 } 1235 1236 const DSAStackTy::LCDeclInfo 1237 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1238 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1239 D = getCanonicalDecl(D); 1240 const SharingMapTy &StackElem = getTopOfStack(); 1241 auto It = StackElem.LCVMap.find(D); 1242 if (It != StackElem.LCVMap.end()) 1243 return It->second; 1244 return {0, nullptr}; 1245 } 1246 1247 const DSAStackTy::LCDeclInfo 1248 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { 1249 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1250 D = getCanonicalDecl(D); 1251 for (unsigned I = Level + 1; I > 0; --I) { 1252 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); 1253 auto It = StackElem.LCVMap.find(D); 1254 if (It != StackElem.LCVMap.end()) 1255 return It->second; 1256 } 1257 return {0, nullptr}; 1258 } 1259 1260 const DSAStackTy::LCDeclInfo 1261 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1262 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1263 assert(Parent && "Data-sharing attributes stack is empty"); 1264 D = getCanonicalDecl(D); 1265 auto It = Parent->LCVMap.find(D); 1266 if (It != Parent->LCVMap.end()) 1267 return It->second; 1268 return {0, nullptr}; 1269 } 1270 1271 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1272 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1273 assert(Parent && "Data-sharing attributes stack is empty"); 1274 if (Parent->LCVMap.size() < I) 1275 return nullptr; 1276 for (const auto &Pair : Parent->LCVMap) 1277 if (Pair.second.first == I) 1278 return Pair.first; 1279 return nullptr; 1280 } 1281 1282 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1283 DeclRefExpr *PrivateCopy, unsigned Modifier) { 1284 D = getCanonicalDecl(D); 1285 if (A == OMPC_threadprivate) { 1286 DSAInfo &Data = Threadprivates[D]; 1287 Data.Attributes = A; 1288 Data.RefExpr.setPointer(E); 1289 Data.PrivateCopy = nullptr; 1290 Data.Modifier = Modifier; 1291 } else { 1292 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1293 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1294 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1295 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1296 (isLoopControlVariable(D).first && A == OMPC_private)); 1297 Data.Modifier = Modifier; 1298 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1299 Data.RefExpr.setInt(/*IntVal=*/true); 1300 return; 1301 } 1302 const bool IsLastprivate = 1303 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1304 Data.Attributes = A; 1305 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1306 Data.PrivateCopy = PrivateCopy; 1307 if (PrivateCopy) { 1308 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1309 Data.Modifier = Modifier; 1310 Data.Attributes = A; 1311 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1312 Data.PrivateCopy = nullptr; 1313 } 1314 } 1315 } 1316 1317 /// Build a variable declaration for OpenMP loop iteration variable. 1318 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1319 StringRef Name, const AttrVec *Attrs = nullptr, 1320 DeclRefExpr *OrigRef = nullptr) { 1321 DeclContext *DC = SemaRef.CurContext; 1322 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1323 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1324 auto *Decl = 1325 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1326 if (Attrs) { 1327 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1328 I != E; ++I) 1329 Decl->addAttr(*I); 1330 } 1331 Decl->setImplicit(); 1332 if (OrigRef) { 1333 Decl->addAttr( 1334 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1335 } 1336 return Decl; 1337 } 1338 1339 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1340 SourceLocation Loc, 1341 bool RefersToCapture = false) { 1342 D->setReferenced(); 1343 D->markUsed(S.Context); 1344 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1345 SourceLocation(), D, RefersToCapture, Loc, Ty, 1346 VK_LValue); 1347 } 1348 1349 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1350 BinaryOperatorKind BOK) { 1351 D = getCanonicalDecl(D); 1352 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1353 assert( 1354 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1355 "Additional reduction info may be specified only for reduction items."); 1356 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1357 assert(ReductionData.ReductionRange.isInvalid() && 1358 (getTopOfStack().Directive == OMPD_taskgroup || 1359 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1360 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1361 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1362 "Additional reduction info may be specified only once for reduction " 1363 "items."); 1364 ReductionData.set(BOK, SR); 1365 Expr *&TaskgroupReductionRef = 1366 getTopOfStack().TaskgroupReductionRef; 1367 if (!TaskgroupReductionRef) { 1368 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1369 SemaRef.Context.VoidPtrTy, ".task_red."); 1370 TaskgroupReductionRef = 1371 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1372 } 1373 } 1374 1375 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1376 const Expr *ReductionRef) { 1377 D = getCanonicalDecl(D); 1378 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1379 assert( 1380 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1381 "Additional reduction info may be specified only for reduction items."); 1382 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1383 assert(ReductionData.ReductionRange.isInvalid() && 1384 (getTopOfStack().Directive == OMPD_taskgroup || 1385 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1386 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1387 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1388 "Additional reduction info may be specified only once for reduction " 1389 "items."); 1390 ReductionData.set(ReductionRef, SR); 1391 Expr *&TaskgroupReductionRef = 1392 getTopOfStack().TaskgroupReductionRef; 1393 if (!TaskgroupReductionRef) { 1394 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1395 SemaRef.Context.VoidPtrTy, ".task_red."); 1396 TaskgroupReductionRef = 1397 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1398 } 1399 } 1400 1401 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1402 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1403 Expr *&TaskgroupDescriptor) const { 1404 D = getCanonicalDecl(D); 1405 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1406 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1407 const DSAInfo &Data = I->SharingMap.lookup(D); 1408 if (Data.Attributes != OMPC_reduction || 1409 Data.Modifier != OMPC_REDUCTION_task) 1410 continue; 1411 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1412 if (!ReductionData.ReductionOp || 1413 ReductionData.ReductionOp.is<const Expr *>()) 1414 return DSAVarData(); 1415 SR = ReductionData.ReductionRange; 1416 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1417 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1418 "expression for the descriptor is not " 1419 "set."); 1420 TaskgroupDescriptor = I->TaskgroupReductionRef; 1421 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1422 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task); 1423 } 1424 return DSAVarData(); 1425 } 1426 1427 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1428 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1429 Expr *&TaskgroupDescriptor) const { 1430 D = getCanonicalDecl(D); 1431 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1432 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1433 const DSAInfo &Data = I->SharingMap.lookup(D); 1434 if (Data.Attributes != OMPC_reduction || 1435 Data.Modifier != OMPC_REDUCTION_task) 1436 continue; 1437 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1438 if (!ReductionData.ReductionOp || 1439 !ReductionData.ReductionOp.is<const Expr *>()) 1440 return DSAVarData(); 1441 SR = ReductionData.ReductionRange; 1442 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1443 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1444 "expression for the descriptor is not " 1445 "set."); 1446 TaskgroupDescriptor = I->TaskgroupReductionRef; 1447 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1448 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task); 1449 } 1450 return DSAVarData(); 1451 } 1452 1453 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1454 D = D->getCanonicalDecl(); 1455 for (const_iterator E = end(); I != E; ++I) { 1456 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1457 isOpenMPTargetExecutionDirective(I->Directive)) { 1458 Scope *TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1459 Scope *CurScope = getCurScope(); 1460 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1461 CurScope = CurScope->getParent(); 1462 return CurScope != TopScope; 1463 } 1464 } 1465 return false; 1466 } 1467 1468 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1469 bool AcceptIfMutable = true, 1470 bool *IsClassType = nullptr) { 1471 ASTContext &Context = SemaRef.getASTContext(); 1472 Type = Type.getNonReferenceType().getCanonicalType(); 1473 bool IsConstant = Type.isConstant(Context); 1474 Type = Context.getBaseElementType(Type); 1475 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1476 ? Type->getAsCXXRecordDecl() 1477 : nullptr; 1478 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1479 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1480 RD = CTD->getTemplatedDecl(); 1481 if (IsClassType) 1482 *IsClassType = RD; 1483 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1484 RD->hasDefinition() && RD->hasMutableFields()); 1485 } 1486 1487 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1488 QualType Type, OpenMPClauseKind CKind, 1489 SourceLocation ELoc, 1490 bool AcceptIfMutable = true, 1491 bool ListItemNotVar = false) { 1492 ASTContext &Context = SemaRef.getASTContext(); 1493 bool IsClassType; 1494 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1495 unsigned Diag = ListItemNotVar 1496 ? diag::err_omp_const_list_item 1497 : IsClassType ? diag::err_omp_const_not_mutable_variable 1498 : diag::err_omp_const_variable; 1499 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1500 if (!ListItemNotVar && D) { 1501 const VarDecl *VD = dyn_cast<VarDecl>(D); 1502 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1503 VarDecl::DeclarationOnly; 1504 SemaRef.Diag(D->getLocation(), 1505 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1506 << D; 1507 } 1508 return true; 1509 } 1510 return false; 1511 } 1512 1513 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1514 bool FromParent) { 1515 D = getCanonicalDecl(D); 1516 DSAVarData DVar; 1517 1518 auto *VD = dyn_cast<VarDecl>(D); 1519 auto TI = Threadprivates.find(D); 1520 if (TI != Threadprivates.end()) { 1521 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1522 DVar.CKind = OMPC_threadprivate; 1523 DVar.Modifier = TI->getSecond().Modifier; 1524 return DVar; 1525 } 1526 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1527 DVar.RefExpr = buildDeclRefExpr( 1528 SemaRef, VD, D->getType().getNonReferenceType(), 1529 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1530 DVar.CKind = OMPC_threadprivate; 1531 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1532 return DVar; 1533 } 1534 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1535 // in a Construct, C/C++, predetermined, p.1] 1536 // Variables appearing in threadprivate directives are threadprivate. 1537 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1538 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1539 SemaRef.getLangOpts().OpenMPUseTLS && 1540 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1541 (VD && VD->getStorageClass() == SC_Register && 1542 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1543 DVar.RefExpr = buildDeclRefExpr( 1544 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1545 DVar.CKind = OMPC_threadprivate; 1546 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1547 return DVar; 1548 } 1549 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1550 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1551 !isLoopControlVariable(D).first) { 1552 const_iterator IterTarget = 1553 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1554 return isOpenMPTargetExecutionDirective(Data.Directive); 1555 }); 1556 if (IterTarget != end()) { 1557 const_iterator ParentIterTarget = IterTarget + 1; 1558 for (const_iterator Iter = begin(); 1559 Iter != ParentIterTarget; ++Iter) { 1560 if (isOpenMPLocal(VD, Iter)) { 1561 DVar.RefExpr = 1562 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1563 D->getLocation()); 1564 DVar.CKind = OMPC_threadprivate; 1565 return DVar; 1566 } 1567 } 1568 if (!isClauseParsingMode() || IterTarget != begin()) { 1569 auto DSAIter = IterTarget->SharingMap.find(D); 1570 if (DSAIter != IterTarget->SharingMap.end() && 1571 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1572 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1573 DVar.CKind = OMPC_threadprivate; 1574 return DVar; 1575 } 1576 const_iterator End = end(); 1577 if (!SemaRef.isOpenMPCapturedByRef( 1578 D, std::distance(ParentIterTarget, End), 1579 /*OpenMPCaptureLevel=*/0)) { 1580 DVar.RefExpr = 1581 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1582 IterTarget->ConstructLoc); 1583 DVar.CKind = OMPC_threadprivate; 1584 return DVar; 1585 } 1586 } 1587 } 1588 } 1589 1590 if (isStackEmpty()) 1591 // Not in OpenMP execution region and top scope was already checked. 1592 return DVar; 1593 1594 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1595 // in a Construct, C/C++, predetermined, p.4] 1596 // Static data members are shared. 1597 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1598 // in a Construct, C/C++, predetermined, p.7] 1599 // Variables with static storage duration that are declared in a scope 1600 // inside the construct are shared. 1601 if (VD && VD->isStaticDataMember()) { 1602 // Check for explicitly specified attributes. 1603 const_iterator I = begin(); 1604 const_iterator EndI = end(); 1605 if (FromParent && I != EndI) 1606 ++I; 1607 if (I != EndI) { 1608 auto It = I->SharingMap.find(D); 1609 if (It != I->SharingMap.end()) { 1610 const DSAInfo &Data = It->getSecond(); 1611 DVar.RefExpr = Data.RefExpr.getPointer(); 1612 DVar.PrivateCopy = Data.PrivateCopy; 1613 DVar.CKind = Data.Attributes; 1614 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1615 DVar.DKind = I->Directive; 1616 DVar.Modifier = Data.Modifier; 1617 return DVar; 1618 } 1619 } 1620 1621 DVar.CKind = OMPC_shared; 1622 return DVar; 1623 } 1624 1625 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1626 // The predetermined shared attribute for const-qualified types having no 1627 // mutable members was removed after OpenMP 3.1. 1628 if (SemaRef.LangOpts.OpenMP <= 31) { 1629 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1630 // in a Construct, C/C++, predetermined, p.6] 1631 // Variables with const qualified type having no mutable member are 1632 // shared. 1633 if (isConstNotMutableType(SemaRef, D->getType())) { 1634 // Variables with const-qualified type having no mutable member may be 1635 // listed in a firstprivate clause, even if they are static data members. 1636 DSAVarData DVarTemp = hasInnermostDSA( 1637 D, 1638 [](OpenMPClauseKind C) { 1639 return C == OMPC_firstprivate || C == OMPC_shared; 1640 }, 1641 MatchesAlways, FromParent); 1642 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1643 return DVarTemp; 1644 1645 DVar.CKind = OMPC_shared; 1646 return DVar; 1647 } 1648 } 1649 1650 // Explicitly specified attributes and local variables with predetermined 1651 // attributes. 1652 const_iterator I = begin(); 1653 const_iterator EndI = end(); 1654 if (FromParent && I != EndI) 1655 ++I; 1656 if (I == EndI) 1657 return DVar; 1658 auto It = I->SharingMap.find(D); 1659 if (It != I->SharingMap.end()) { 1660 const DSAInfo &Data = It->getSecond(); 1661 DVar.RefExpr = Data.RefExpr.getPointer(); 1662 DVar.PrivateCopy = Data.PrivateCopy; 1663 DVar.CKind = Data.Attributes; 1664 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1665 DVar.DKind = I->Directive; 1666 DVar.Modifier = Data.Modifier; 1667 } 1668 1669 return DVar; 1670 } 1671 1672 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1673 bool FromParent) const { 1674 if (isStackEmpty()) { 1675 const_iterator I; 1676 return getDSA(I, D); 1677 } 1678 D = getCanonicalDecl(D); 1679 const_iterator StartI = begin(); 1680 const_iterator EndI = end(); 1681 if (FromParent && StartI != EndI) 1682 ++StartI; 1683 return getDSA(StartI, D); 1684 } 1685 1686 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1687 unsigned Level) const { 1688 if (getStackSize() <= Level) 1689 return DSAVarData(); 1690 D = getCanonicalDecl(D); 1691 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); 1692 return getDSA(StartI, D); 1693 } 1694 1695 const DSAStackTy::DSAVarData 1696 DSAStackTy::hasDSA(ValueDecl *D, 1697 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1698 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1699 bool FromParent) const { 1700 if (isStackEmpty()) 1701 return {}; 1702 D = getCanonicalDecl(D); 1703 const_iterator I = begin(); 1704 const_iterator EndI = end(); 1705 if (FromParent && I != EndI) 1706 ++I; 1707 for (; I != EndI; ++I) { 1708 if (!DPred(I->Directive) && 1709 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1710 continue; 1711 const_iterator NewI = I; 1712 DSAVarData DVar = getDSA(NewI, D); 1713 if (I == NewI && CPred(DVar.CKind)) 1714 return DVar; 1715 } 1716 return {}; 1717 } 1718 1719 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1720 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1721 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1722 bool FromParent) const { 1723 if (isStackEmpty()) 1724 return {}; 1725 D = getCanonicalDecl(D); 1726 const_iterator StartI = begin(); 1727 const_iterator EndI = end(); 1728 if (FromParent && StartI != EndI) 1729 ++StartI; 1730 if (StartI == EndI || !DPred(StartI->Directive)) 1731 return {}; 1732 const_iterator NewI = StartI; 1733 DSAVarData DVar = getDSA(NewI, D); 1734 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1735 } 1736 1737 bool DSAStackTy::hasExplicitDSA( 1738 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1739 unsigned Level, bool NotLastprivate) const { 1740 if (getStackSize() <= Level) 1741 return false; 1742 D = getCanonicalDecl(D); 1743 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1744 auto I = StackElem.SharingMap.find(D); 1745 if (I != StackElem.SharingMap.end() && 1746 I->getSecond().RefExpr.getPointer() && 1747 CPred(I->getSecond().Attributes) && 1748 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1749 return true; 1750 // Check predetermined rules for the loop control variables. 1751 auto LI = StackElem.LCVMap.find(D); 1752 if (LI != StackElem.LCVMap.end()) 1753 return CPred(OMPC_private); 1754 return false; 1755 } 1756 1757 bool DSAStackTy::hasExplicitDirective( 1758 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1759 unsigned Level) const { 1760 if (getStackSize() <= Level) 1761 return false; 1762 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1763 return DPred(StackElem.Directive); 1764 } 1765 1766 bool DSAStackTy::hasDirective( 1767 const llvm::function_ref<bool(OpenMPDirectiveKind, 1768 const DeclarationNameInfo &, SourceLocation)> 1769 DPred, 1770 bool FromParent) const { 1771 // We look only in the enclosing region. 1772 size_t Skip = FromParent ? 2 : 1; 1773 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1774 I != E; ++I) { 1775 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1776 return true; 1777 } 1778 return false; 1779 } 1780 1781 void Sema::InitDataSharingAttributesStack() { 1782 VarDataSharingAttributesStack = new DSAStackTy(*this); 1783 } 1784 1785 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1786 1787 void Sema::pushOpenMPFunctionRegion() { 1788 DSAStack->pushFunction(); 1789 } 1790 1791 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1792 DSAStack->popFunction(OldFSI); 1793 } 1794 1795 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1796 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1797 "Expected OpenMP device compilation."); 1798 return !S.isInOpenMPTargetExecutionDirective() && 1799 !S.isInOpenMPDeclareTargetContext(); 1800 } 1801 1802 namespace { 1803 /// Status of the function emission on the host/device. 1804 enum class FunctionEmissionStatus { 1805 Emitted, 1806 Discarded, 1807 Unknown, 1808 }; 1809 } // anonymous namespace 1810 1811 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1812 unsigned DiagID) { 1813 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1814 "Expected OpenMP device compilation."); 1815 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1816 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1817 switch (FES) { 1818 case FunctionEmissionStatus::Emitted: 1819 Kind = DeviceDiagBuilder::K_Immediate; 1820 break; 1821 case FunctionEmissionStatus::Unknown: 1822 Kind = isOpenMPDeviceDelayedContext(*this) ? DeviceDiagBuilder::K_Deferred 1823 : DeviceDiagBuilder::K_Immediate; 1824 break; 1825 case FunctionEmissionStatus::TemplateDiscarded: 1826 case FunctionEmissionStatus::OMPDiscarded: 1827 Kind = DeviceDiagBuilder::K_Nop; 1828 break; 1829 case FunctionEmissionStatus::CUDADiscarded: 1830 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1831 break; 1832 } 1833 1834 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1835 } 1836 1837 Sema::DeviceDiagBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1838 unsigned DiagID) { 1839 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1840 "Expected OpenMP host compilation."); 1841 FunctionEmissionStatus FES = getEmissionStatus(getCurFunctionDecl()); 1842 DeviceDiagBuilder::Kind Kind = DeviceDiagBuilder::K_Nop; 1843 switch (FES) { 1844 case FunctionEmissionStatus::Emitted: 1845 Kind = DeviceDiagBuilder::K_Immediate; 1846 break; 1847 case FunctionEmissionStatus::Unknown: 1848 Kind = DeviceDiagBuilder::K_Deferred; 1849 break; 1850 case FunctionEmissionStatus::TemplateDiscarded: 1851 case FunctionEmissionStatus::OMPDiscarded: 1852 case FunctionEmissionStatus::CUDADiscarded: 1853 Kind = DeviceDiagBuilder::K_Nop; 1854 break; 1855 } 1856 1857 return DeviceDiagBuilder(Kind, Loc, DiagID, getCurFunctionDecl(), *this); 1858 } 1859 1860 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1861 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1862 "OpenMP device compilation mode is expected."); 1863 QualType Ty = E->getType(); 1864 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1865 ((Ty->isFloat128Type() || 1866 (Ty->isRealFloatingType() && Context.getTypeSize(Ty) == 128)) && 1867 !Context.getTargetInfo().hasFloat128Type()) || 1868 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1869 !Context.getTargetInfo().hasInt128Type())) 1870 targetDiag(E->getExprLoc(), diag::err_omp_unsupported_type) 1871 << static_cast<unsigned>(Context.getTypeSize(Ty)) << Ty 1872 << Context.getTargetInfo().getTriple().str() << E->getSourceRange(); 1873 } 1874 1875 static OpenMPDefaultmapClauseKind 1876 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1877 if (LO.OpenMP <= 45) { 1878 if (VD->getType().getNonReferenceType()->isScalarType()) 1879 return OMPC_DEFAULTMAP_scalar; 1880 return OMPC_DEFAULTMAP_aggregate; 1881 } 1882 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 1883 return OMPC_DEFAULTMAP_pointer; 1884 if (VD->getType().getNonReferenceType()->isScalarType()) 1885 return OMPC_DEFAULTMAP_scalar; 1886 return OMPC_DEFAULTMAP_aggregate; 1887 } 1888 1889 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 1890 unsigned OpenMPCaptureLevel) const { 1891 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1892 1893 ASTContext &Ctx = getASTContext(); 1894 bool IsByRef = true; 1895 1896 // Find the directive that is associated with the provided scope. 1897 D = cast<ValueDecl>(D->getCanonicalDecl()); 1898 QualType Ty = D->getType(); 1899 1900 bool IsVariableUsedInMapClause = false; 1901 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1902 // This table summarizes how a given variable should be passed to the device 1903 // given its type and the clauses where it appears. This table is based on 1904 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1905 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1906 // 1907 // ========================================================================= 1908 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1909 // | |(tofrom:scalar)| | pvt | | | | 1910 // ========================================================================= 1911 // | scl | | | | - | | bycopy| 1912 // | scl | | - | x | - | - | bycopy| 1913 // | scl | | x | - | - | - | null | 1914 // | scl | x | | | - | | byref | 1915 // | scl | x | - | x | - | - | bycopy| 1916 // | scl | x | x | - | - | - | null | 1917 // | scl | | - | - | - | x | byref | 1918 // | scl | x | - | - | - | x | byref | 1919 // 1920 // | agg | n.a. | | | - | | byref | 1921 // | agg | n.a. | - | x | - | - | byref | 1922 // | agg | n.a. | x | - | - | - | null | 1923 // | agg | n.a. | - | - | - | x | byref | 1924 // | agg | n.a. | - | - | - | x[] | byref | 1925 // 1926 // | ptr | n.a. | | | - | | bycopy| 1927 // | ptr | n.a. | - | x | - | - | bycopy| 1928 // | ptr | n.a. | x | - | - | - | null | 1929 // | ptr | n.a. | - | - | - | x | byref | 1930 // | ptr | n.a. | - | - | - | x[] | bycopy| 1931 // | ptr | n.a. | - | - | x | | bycopy| 1932 // | ptr | n.a. | - | - | x | x | bycopy| 1933 // | ptr | n.a. | - | - | x | x[] | bycopy| 1934 // ========================================================================= 1935 // Legend: 1936 // scl - scalar 1937 // ptr - pointer 1938 // agg - aggregate 1939 // x - applies 1940 // - - invalid in this combination 1941 // [] - mapped with an array section 1942 // byref - should be mapped by reference 1943 // byval - should be mapped by value 1944 // null - initialize a local variable to null on the device 1945 // 1946 // Observations: 1947 // - All scalar declarations that show up in a map clause have to be passed 1948 // by reference, because they may have been mapped in the enclosing data 1949 // environment. 1950 // - If the scalar value does not fit the size of uintptr, it has to be 1951 // passed by reference, regardless the result in the table above. 1952 // - For pointers mapped by value that have either an implicit map or an 1953 // array section, the runtime library may pass the NULL value to the 1954 // device instead of the value passed to it by the compiler. 1955 1956 if (Ty->isReferenceType()) 1957 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1958 1959 // Locate map clauses and see if the variable being captured is referred to 1960 // in any of those clauses. Here we only care about variables, not fields, 1961 // because fields are part of aggregates. 1962 bool IsVariableAssociatedWithSection = false; 1963 1964 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1965 D, Level, 1966 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1967 OMPClauseMappableExprCommon::MappableExprComponentListRef 1968 MapExprComponents, 1969 OpenMPClauseKind WhereFoundClauseKind) { 1970 // Only the map clause information influences how a variable is 1971 // captured. E.g. is_device_ptr does not require changing the default 1972 // behavior. 1973 if (WhereFoundClauseKind != OMPC_map) 1974 return false; 1975 1976 auto EI = MapExprComponents.rbegin(); 1977 auto EE = MapExprComponents.rend(); 1978 1979 assert(EI != EE && "Invalid map expression!"); 1980 1981 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1982 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1983 1984 ++EI; 1985 if (EI == EE) 1986 return false; 1987 1988 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1989 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1990 isa<MemberExpr>(EI->getAssociatedExpression()) || 1991 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { 1992 IsVariableAssociatedWithSection = true; 1993 // There is nothing more we need to know about this variable. 1994 return true; 1995 } 1996 1997 // Keep looking for more map info. 1998 return false; 1999 }); 2000 2001 if (IsVariableUsedInMapClause) { 2002 // If variable is identified in a map clause it is always captured by 2003 // reference except if it is a pointer that is dereferenced somehow. 2004 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 2005 } else { 2006 // By default, all the data that has a scalar type is mapped by copy 2007 // (except for reduction variables). 2008 // Defaultmap scalar is mutual exclusive to defaultmap pointer 2009 IsByRef = 2010 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 2011 !Ty->isAnyPointerType()) || 2012 !Ty->isScalarType() || 2013 DSAStack->isDefaultmapCapturedByRef( 2014 Level, getVariableCategoryFromDecl(LangOpts, D)) || 2015 DSAStack->hasExplicitDSA( 2016 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 2017 } 2018 } 2019 2020 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 2021 IsByRef = 2022 ((IsVariableUsedInMapClause && 2023 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 2024 OMPD_target) || 2025 !(DSAStack->hasExplicitDSA( 2026 D, 2027 [](OpenMPClauseKind K) -> bool { 2028 return K == OMPC_firstprivate; 2029 }, 2030 Level, /*NotLastprivate=*/true) || 2031 DSAStack->isUsesAllocatorsDecl(Level, D))) && 2032 // If the variable is artificial and must be captured by value - try to 2033 // capture by value. 2034 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 2035 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 2036 } 2037 2038 // When passing data by copy, we need to make sure it fits the uintptr size 2039 // and alignment, because the runtime library only deals with uintptr types. 2040 // If it does not fit the uintptr size, we need to pass the data by reference 2041 // instead. 2042 if (!IsByRef && 2043 (Ctx.getTypeSizeInChars(Ty) > 2044 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 2045 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 2046 IsByRef = true; 2047 } 2048 2049 return IsByRef; 2050 } 2051 2052 unsigned Sema::getOpenMPNestingLevel() const { 2053 assert(getLangOpts().OpenMP); 2054 return DSAStack->getNestingLevel(); 2055 } 2056 2057 bool Sema::isInOpenMPTargetExecutionDirective() const { 2058 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2059 !DSAStack->isClauseParsingMode()) || 2060 DSAStack->hasDirective( 2061 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2062 SourceLocation) -> bool { 2063 return isOpenMPTargetExecutionDirective(K); 2064 }, 2065 false); 2066 } 2067 2068 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2069 unsigned StopAt) { 2070 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2071 D = getCanonicalDecl(D); 2072 2073 auto *VD = dyn_cast<VarDecl>(D); 2074 // Do not capture constexpr variables. 2075 if (VD && VD->isConstexpr()) 2076 return nullptr; 2077 2078 // If we want to determine whether the variable should be captured from the 2079 // perspective of the current capturing scope, and we've already left all the 2080 // capturing scopes of the top directive on the stack, check from the 2081 // perspective of its parent directive (if any) instead. 2082 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2083 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2084 2085 // If we are attempting to capture a global variable in a directive with 2086 // 'target' we return true so that this global is also mapped to the device. 2087 // 2088 if (VD && !VD->hasLocalStorage() && 2089 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2090 if (isInOpenMPDeclareTargetContext()) { 2091 // Try to mark variable as declare target if it is used in capturing 2092 // regions. 2093 if (LangOpts.OpenMP <= 45 && 2094 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2095 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2096 return nullptr; 2097 } else if (isInOpenMPTargetExecutionDirective()) { 2098 // If the declaration is enclosed in a 'declare target' directive, 2099 // then it should not be captured. 2100 // 2101 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2102 return nullptr; 2103 CapturedRegionScopeInfo *CSI = nullptr; 2104 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2105 llvm::reverse(FunctionScopes), 2106 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2107 if (!isa<CapturingScopeInfo>(FSI)) 2108 return nullptr; 2109 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2110 if (RSI->CapRegionKind == CR_OpenMP) { 2111 CSI = RSI; 2112 break; 2113 } 2114 } 2115 SmallVector<OpenMPDirectiveKind, 4> Regions; 2116 getOpenMPCaptureRegions(Regions, 2117 DSAStack->getDirective(CSI->OpenMPLevel)); 2118 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2119 return VD; 2120 } 2121 } 2122 2123 if (CheckScopeInfo) { 2124 bool OpenMPFound = false; 2125 for (unsigned I = StopAt + 1; I > 0; --I) { 2126 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2127 if(!isa<CapturingScopeInfo>(FSI)) 2128 return nullptr; 2129 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2130 if (RSI->CapRegionKind == CR_OpenMP) { 2131 OpenMPFound = true; 2132 break; 2133 } 2134 } 2135 if (!OpenMPFound) 2136 return nullptr; 2137 } 2138 2139 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2140 (!DSAStack->isClauseParsingMode() || 2141 DSAStack->getParentDirective() != OMPD_unknown)) { 2142 auto &&Info = DSAStack->isLoopControlVariable(D); 2143 if (Info.first || 2144 (VD && VD->hasLocalStorage() && 2145 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2146 (VD && DSAStack->isForceVarCapturing())) 2147 return VD ? VD : Info.second; 2148 DSAStackTy::DSAVarData DVarTop = 2149 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2150 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind)) 2151 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); 2152 // Threadprivate variables must not be captured. 2153 if (isOpenMPThreadPrivate(DVarTop.CKind)) 2154 return nullptr; 2155 // The variable is not private or it is the variable in the directive with 2156 // default(none) clause and not used in any clause. 2157 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2158 D, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 2159 DSAStack->isClauseParsingMode()); 2160 // Global shared must not be captured. 2161 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && 2162 (DSAStack->getDefaultDSA() != DSA_none || DVarTop.CKind == OMPC_shared)) 2163 return nullptr; 2164 if (DVarPrivate.CKind != OMPC_unknown || 2165 (VD && DSAStack->getDefaultDSA() == DSA_none)) 2166 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2167 } 2168 return nullptr; 2169 } 2170 2171 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2172 unsigned Level) const { 2173 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2174 } 2175 2176 void Sema::startOpenMPLoop() { 2177 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2178 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2179 DSAStack->loopInit(); 2180 } 2181 2182 void Sema::startOpenMPCXXRangeFor() { 2183 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2184 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2185 DSAStack->resetPossibleLoopCounter(); 2186 DSAStack->loopStart(); 2187 } 2188 } 2189 2190 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, 2191 unsigned CapLevel) const { 2192 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2193 if (DSAStack->hasExplicitDirective( 2194 [](OpenMPDirectiveKind K) { return isOpenMPTaskingDirective(K); }, 2195 Level)) { 2196 bool IsTriviallyCopyable = 2197 D->getType().getNonReferenceType().isTriviallyCopyableType(Context); 2198 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level); 2199 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2200 getOpenMPCaptureRegions(CaptureRegions, DKind); 2201 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && 2202 (IsTriviallyCopyable || 2203 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { 2204 if (DSAStack->hasExplicitDSA( 2205 D, [](OpenMPClauseKind K) { return K == OMPC_firstprivate; }, 2206 Level, /*NotLastprivate=*/true)) 2207 return OMPC_firstprivate; 2208 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2209 if (DVar.CKind != OMPC_shared && 2210 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { 2211 DSAStack->addImplicitTaskFirstprivate(Level, D); 2212 return OMPC_firstprivate; 2213 } 2214 } 2215 } 2216 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2217 if (DSAStack->getAssociatedLoops() > 0 && 2218 !DSAStack->isLoopStarted()) { 2219 DSAStack->resetPossibleLoopCounter(D); 2220 DSAStack->loopStart(); 2221 return OMPC_private; 2222 } 2223 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2224 DSAStack->isLoopControlVariable(D).first) && 2225 !DSAStack->hasExplicitDSA( 2226 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 2227 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2228 return OMPC_private; 2229 } 2230 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2231 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2232 DSAStack->isForceVarCapturing() && 2233 !DSAStack->hasExplicitDSA( 2234 D, [](OpenMPClauseKind K) { return K == OMPC_copyin; }, Level)) 2235 return OMPC_private; 2236 } 2237 return (DSAStack->hasExplicitDSA( 2238 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 2239 (DSAStack->isClauseParsingMode() && 2240 DSAStack->getClauseParsingMode() == OMPC_private) || 2241 // Consider taskgroup reduction descriptor variable a private 2242 // to avoid possible capture in the region. 2243 (DSAStack->hasExplicitDirective( 2244 [](OpenMPDirectiveKind K) { 2245 return K == OMPD_taskgroup || 2246 ((isOpenMPParallelDirective(K) || 2247 isOpenMPWorksharingDirective(K)) && 2248 !isOpenMPSimdDirective(K)); 2249 }, 2250 Level) && 2251 DSAStack->isTaskgroupReductionRef(D, Level))) 2252 ? OMPC_private 2253 : OMPC_unknown; 2254 } 2255 2256 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2257 unsigned Level) { 2258 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2259 D = getCanonicalDecl(D); 2260 OpenMPClauseKind OMPC = OMPC_unknown; 2261 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2262 const unsigned NewLevel = I - 1; 2263 if (DSAStack->hasExplicitDSA(D, 2264 [&OMPC](const OpenMPClauseKind K) { 2265 if (isOpenMPPrivate(K)) { 2266 OMPC = K; 2267 return true; 2268 } 2269 return false; 2270 }, 2271 NewLevel)) 2272 break; 2273 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2274 D, NewLevel, 2275 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2276 OpenMPClauseKind) { return true; })) { 2277 OMPC = OMPC_map; 2278 break; 2279 } 2280 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2281 NewLevel)) { 2282 OMPC = OMPC_map; 2283 if (DSAStack->mustBeFirstprivateAtLevel( 2284 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2285 OMPC = OMPC_firstprivate; 2286 break; 2287 } 2288 } 2289 if (OMPC != OMPC_unknown) 2290 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); 2291 } 2292 2293 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2294 unsigned CaptureLevel) const { 2295 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2296 // Return true if the current level is no longer enclosed in a target region. 2297 2298 SmallVector<OpenMPDirectiveKind, 4> Regions; 2299 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2300 const auto *VD = dyn_cast<VarDecl>(D); 2301 return VD && !VD->hasLocalStorage() && 2302 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2303 Level) && 2304 Regions[CaptureLevel] != OMPD_task; 2305 } 2306 2307 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2308 unsigned CaptureLevel) const { 2309 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2310 // Return true if the current level is no longer enclosed in a target region. 2311 2312 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2313 if (!VD->hasLocalStorage()) { 2314 DSAStackTy::DSAVarData TopDVar = 2315 DSAStack->getTopDSA(D, /*FromParent=*/false); 2316 unsigned NumLevels = 2317 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2318 if (Level == 0) 2319 return (NumLevels == CaptureLevel + 1) && TopDVar.CKind != OMPC_shared; 2320 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level - 1); 2321 return DVar.CKind != OMPC_shared || 2322 isOpenMPGlobalCapturedDecl( 2323 D, Level - 1, 2324 getOpenMPCaptureLevels(DSAStack->getDirective(Level - 1)) - 1); 2325 } 2326 } 2327 return true; 2328 } 2329 2330 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2331 2332 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2333 OMPTraitInfo &TI) { 2334 if (!OMPDeclareVariantScopes.empty()) { 2335 Diag(Loc, diag::warn_nested_declare_variant); 2336 return; 2337 } 2338 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2339 } 2340 2341 void Sema::ActOnOpenMPEndDeclareVariant() { 2342 assert(isInOpenMPDeclareVariantScope() && 2343 "Not in OpenMP declare variant scope!"); 2344 2345 OMPDeclareVariantScopes.pop_back(); 2346 } 2347 2348 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2349 const FunctionDecl *Callee, 2350 SourceLocation Loc) { 2351 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2352 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2353 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2354 // Ignore host functions during device analyzis. 2355 if (LangOpts.OpenMPIsDevice && DevTy && 2356 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) 2357 return; 2358 // Ignore nohost functions during host analyzis. 2359 if (!LangOpts.OpenMPIsDevice && DevTy && 2360 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2361 return; 2362 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2363 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2364 if (LangOpts.OpenMPIsDevice && DevTy && 2365 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2366 // Diagnose host function called during device codegen. 2367 StringRef HostDevTy = 2368 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2369 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2370 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2371 diag::note_omp_marked_device_type_here) 2372 << HostDevTy; 2373 return; 2374 } 2375 if (!LangOpts.OpenMPIsDevice && DevTy && 2376 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2377 // Diagnose nohost function called during host codegen. 2378 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2379 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2380 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2381 Diag(FD->getAttr<OMPDeclareTargetDeclAttr>()->getLocation(), 2382 diag::note_omp_marked_device_type_here) 2383 << NoHostDevTy; 2384 } 2385 } 2386 2387 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2388 const DeclarationNameInfo &DirName, 2389 Scope *CurScope, SourceLocation Loc) { 2390 DSAStack->push(DKind, DirName, CurScope, Loc); 2391 PushExpressionEvaluationContext( 2392 ExpressionEvaluationContext::PotentiallyEvaluated); 2393 } 2394 2395 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2396 DSAStack->setClauseParsingMode(K); 2397 } 2398 2399 void Sema::EndOpenMPClause() { 2400 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2401 } 2402 2403 static std::pair<ValueDecl *, bool> 2404 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2405 SourceRange &ERange, bool AllowArraySection = false); 2406 2407 /// Check consistency of the reduction clauses. 2408 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2409 ArrayRef<OMPClause *> Clauses) { 2410 bool InscanFound = false; 2411 SourceLocation InscanLoc; 2412 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2413 // A reduction clause without the inscan reduction-modifier may not appear on 2414 // a construct on which a reduction clause with the inscan reduction-modifier 2415 // appears. 2416 for (OMPClause *C : Clauses) { 2417 if (C->getClauseKind() != OMPC_reduction) 2418 continue; 2419 auto *RC = cast<OMPReductionClause>(C); 2420 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2421 InscanFound = true; 2422 InscanLoc = RC->getModifierLoc(); 2423 continue; 2424 } 2425 if (RC->getModifier() == OMPC_REDUCTION_task) { 2426 // OpenMP 5.0, 2.19.5.4 reduction Clause. 2427 // A reduction clause with the task reduction-modifier may only appear on 2428 // a parallel construct, a worksharing construct or a combined or 2429 // composite construct for which any of the aforementioned constructs is a 2430 // constituent construct and simd or loop are not constituent constructs. 2431 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); 2432 if (!(isOpenMPParallelDirective(CurDir) || 2433 isOpenMPWorksharingDirective(CurDir)) || 2434 isOpenMPSimdDirective(CurDir)) 2435 S.Diag(RC->getModifierLoc(), 2436 diag::err_omp_reduction_task_not_parallel_or_worksharing); 2437 continue; 2438 } 2439 } 2440 if (InscanFound) { 2441 for (OMPClause *C : Clauses) { 2442 if (C->getClauseKind() != OMPC_reduction) 2443 continue; 2444 auto *RC = cast<OMPReductionClause>(C); 2445 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2446 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2447 ? RC->getBeginLoc() 2448 : RC->getModifierLoc(), 2449 diag::err_omp_inscan_reduction_expected); 2450 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2451 continue; 2452 } 2453 for (Expr *Ref : RC->varlists()) { 2454 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2455 SourceLocation ELoc; 2456 SourceRange ERange; 2457 Expr *SimpleRefExpr = Ref; 2458 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2459 /*AllowArraySection=*/true); 2460 ValueDecl *D = Res.first; 2461 if (!D) 2462 continue; 2463 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2464 S.Diag(Ref->getExprLoc(), 2465 diag::err_omp_reduction_not_inclusive_exclusive) 2466 << Ref->getSourceRange(); 2467 } 2468 } 2469 } 2470 } 2471 } 2472 2473 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2474 ArrayRef<OMPClause *> Clauses); 2475 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2476 bool WithInit); 2477 2478 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2479 const ValueDecl *D, 2480 const DSAStackTy::DSAVarData &DVar, 2481 bool IsLoopIterVar = false); 2482 2483 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2484 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2485 // A variable of class type (or array thereof) that appears in a lastprivate 2486 // clause requires an accessible, unambiguous default constructor for the 2487 // class type, unless the list item is also specified in a firstprivate 2488 // clause. 2489 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2490 for (OMPClause *C : D->clauses()) { 2491 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2492 SmallVector<Expr *, 8> PrivateCopies; 2493 for (Expr *DE : Clause->varlists()) { 2494 if (DE->isValueDependent() || DE->isTypeDependent()) { 2495 PrivateCopies.push_back(nullptr); 2496 continue; 2497 } 2498 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2499 auto *VD = cast<VarDecl>(DRE->getDecl()); 2500 QualType Type = VD->getType().getNonReferenceType(); 2501 const DSAStackTy::DSAVarData DVar = 2502 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2503 if (DVar.CKind == OMPC_lastprivate) { 2504 // Generate helper private variable and initialize it with the 2505 // default value. The address of the original variable is replaced 2506 // by the address of the new private variable in CodeGen. This new 2507 // variable is not added to IdResolver, so the code in the OpenMP 2508 // region uses original variable for proper diagnostics. 2509 VarDecl *VDPrivate = buildVarDecl( 2510 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2511 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2512 ActOnUninitializedDecl(VDPrivate); 2513 if (VDPrivate->isInvalidDecl()) { 2514 PrivateCopies.push_back(nullptr); 2515 continue; 2516 } 2517 PrivateCopies.push_back(buildDeclRefExpr( 2518 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2519 } else { 2520 // The variable is also a firstprivate, so initialization sequence 2521 // for private copy is generated already. 2522 PrivateCopies.push_back(nullptr); 2523 } 2524 } 2525 Clause->setPrivateCopies(PrivateCopies); 2526 continue; 2527 } 2528 // Finalize nontemporal clause by handling private copies, if any. 2529 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2530 SmallVector<Expr *, 8> PrivateRefs; 2531 for (Expr *RefExpr : Clause->varlists()) { 2532 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2533 SourceLocation ELoc; 2534 SourceRange ERange; 2535 Expr *SimpleRefExpr = RefExpr; 2536 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2537 if (Res.second) 2538 // It will be analyzed later. 2539 PrivateRefs.push_back(RefExpr); 2540 ValueDecl *D = Res.first; 2541 if (!D) 2542 continue; 2543 2544 const DSAStackTy::DSAVarData DVar = 2545 DSAStack->getTopDSA(D, /*FromParent=*/false); 2546 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2547 : SimpleRefExpr); 2548 } 2549 Clause->setPrivateRefs(PrivateRefs); 2550 continue; 2551 } 2552 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { 2553 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { 2554 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); 2555 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); 2556 if (!DRE) 2557 continue; 2558 ValueDecl *VD = DRE->getDecl(); 2559 if (!VD) 2560 continue; 2561 DSAStackTy::DSAVarData DVar = 2562 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2563 // OpenMP [2.12.5, target Construct] 2564 // Memory allocators that appear in a uses_allocators clause cannot 2565 // appear in other data-sharing attribute clauses or data-mapping 2566 // attribute clauses in the same construct. 2567 Expr *MapExpr = nullptr; 2568 if (DVar.RefExpr || 2569 DSAStack->checkMappableExprComponentListsForDecl( 2570 VD, /*CurrentRegionOnly=*/true, 2571 [VD, &MapExpr]( 2572 OMPClauseMappableExprCommon::MappableExprComponentListRef 2573 MapExprComponents, 2574 OpenMPClauseKind C) { 2575 auto MI = MapExprComponents.rbegin(); 2576 auto ME = MapExprComponents.rend(); 2577 if (MI != ME && 2578 MI->getAssociatedDeclaration()->getCanonicalDecl() == 2579 VD->getCanonicalDecl()) { 2580 MapExpr = MI->getAssociatedExpression(); 2581 return true; 2582 } 2583 return false; 2584 })) { 2585 Diag(D.Allocator->getExprLoc(), 2586 diag::err_omp_allocator_used_in_clauses) 2587 << D.Allocator->getSourceRange(); 2588 if (DVar.RefExpr) 2589 reportOriginalDsa(*this, DSAStack, VD, DVar); 2590 else 2591 Diag(MapExpr->getExprLoc(), diag::note_used_here) 2592 << MapExpr->getSourceRange(); 2593 } 2594 } 2595 continue; 2596 } 2597 } 2598 // Check allocate clauses. 2599 if (!CurContext->isDependentContext()) 2600 checkAllocateClauses(*this, DSAStack, D->clauses()); 2601 checkReductionClauses(*this, DSAStack, D->clauses()); 2602 } 2603 2604 DSAStack->pop(); 2605 DiscardCleanupsInEvaluationContext(); 2606 PopExpressionEvaluationContext(); 2607 } 2608 2609 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2610 Expr *NumIterations, Sema &SemaRef, 2611 Scope *S, DSAStackTy *Stack); 2612 2613 namespace { 2614 2615 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2616 private: 2617 Sema &SemaRef; 2618 2619 public: 2620 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2621 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2622 NamedDecl *ND = Candidate.getCorrectionDecl(); 2623 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2624 return VD->hasGlobalStorage() && 2625 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2626 SemaRef.getCurScope()); 2627 } 2628 return false; 2629 } 2630 2631 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2632 return std::make_unique<VarDeclFilterCCC>(*this); 2633 } 2634 2635 }; 2636 2637 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2638 private: 2639 Sema &SemaRef; 2640 2641 public: 2642 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2643 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2644 NamedDecl *ND = Candidate.getCorrectionDecl(); 2645 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2646 isa<FunctionDecl>(ND))) { 2647 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2648 SemaRef.getCurScope()); 2649 } 2650 return false; 2651 } 2652 2653 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2654 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2655 } 2656 }; 2657 2658 } // namespace 2659 2660 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2661 CXXScopeSpec &ScopeSpec, 2662 const DeclarationNameInfo &Id, 2663 OpenMPDirectiveKind Kind) { 2664 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2665 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2666 2667 if (Lookup.isAmbiguous()) 2668 return ExprError(); 2669 2670 VarDecl *VD; 2671 if (!Lookup.isSingleResult()) { 2672 VarDeclFilterCCC CCC(*this); 2673 if (TypoCorrection Corrected = 2674 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2675 CTK_ErrorRecovery)) { 2676 diagnoseTypo(Corrected, 2677 PDiag(Lookup.empty() 2678 ? diag::err_undeclared_var_use_suggest 2679 : diag::err_omp_expected_var_arg_suggest) 2680 << Id.getName()); 2681 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2682 } else { 2683 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2684 : diag::err_omp_expected_var_arg) 2685 << Id.getName(); 2686 return ExprError(); 2687 } 2688 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2689 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2690 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2691 return ExprError(); 2692 } 2693 Lookup.suppressDiagnostics(); 2694 2695 // OpenMP [2.9.2, Syntax, C/C++] 2696 // Variables must be file-scope, namespace-scope, or static block-scope. 2697 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2698 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2699 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2700 bool IsDecl = 2701 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2702 Diag(VD->getLocation(), 2703 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2704 << VD; 2705 return ExprError(); 2706 } 2707 2708 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2709 NamedDecl *ND = CanonicalVD; 2710 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2711 // A threadprivate directive for file-scope variables must appear outside 2712 // any definition or declaration. 2713 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2714 !getCurLexicalContext()->isTranslationUnit()) { 2715 Diag(Id.getLoc(), diag::err_omp_var_scope) 2716 << getOpenMPDirectiveName(Kind) << VD; 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 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2725 // A threadprivate directive for static class member variables must appear 2726 // in the class definition, in the same scope in which the member 2727 // variables are declared. 2728 if (CanonicalVD->isStaticDataMember() && 2729 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2730 Diag(Id.getLoc(), diag::err_omp_var_scope) 2731 << getOpenMPDirectiveName(Kind) << VD; 2732 bool IsDecl = 2733 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2734 Diag(VD->getLocation(), 2735 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2736 << VD; 2737 return ExprError(); 2738 } 2739 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2740 // A threadprivate directive for namespace-scope variables must appear 2741 // outside any definition or declaration other than the namespace 2742 // definition itself. 2743 if (CanonicalVD->getDeclContext()->isNamespace() && 2744 (!getCurLexicalContext()->isFileContext() || 2745 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2746 Diag(Id.getLoc(), diag::err_omp_var_scope) 2747 << getOpenMPDirectiveName(Kind) << VD; 2748 bool IsDecl = 2749 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2750 Diag(VD->getLocation(), 2751 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2752 << VD; 2753 return ExprError(); 2754 } 2755 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2756 // A threadprivate directive for static block-scope variables must appear 2757 // in the scope of the variable and not in a nested scope. 2758 if (CanonicalVD->isLocalVarDecl() && CurScope && 2759 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2760 Diag(Id.getLoc(), diag::err_omp_var_scope) 2761 << getOpenMPDirectiveName(Kind) << VD; 2762 bool IsDecl = 2763 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2764 Diag(VD->getLocation(), 2765 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2766 << VD; 2767 return ExprError(); 2768 } 2769 2770 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2771 // A threadprivate directive must lexically precede all references to any 2772 // of the variables in its list. 2773 if (Kind == OMPD_threadprivate && VD->isUsed() && 2774 !DSAStack->isThreadPrivate(VD)) { 2775 Diag(Id.getLoc(), diag::err_omp_var_used) 2776 << getOpenMPDirectiveName(Kind) << VD; 2777 return ExprError(); 2778 } 2779 2780 QualType ExprType = VD->getType().getNonReferenceType(); 2781 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2782 SourceLocation(), VD, 2783 /*RefersToEnclosingVariableOrCapture=*/false, 2784 Id.getLoc(), ExprType, VK_LValue); 2785 } 2786 2787 Sema::DeclGroupPtrTy 2788 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2789 ArrayRef<Expr *> VarList) { 2790 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2791 CurContext->addDecl(D); 2792 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2793 } 2794 return nullptr; 2795 } 2796 2797 namespace { 2798 class LocalVarRefChecker final 2799 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2800 Sema &SemaRef; 2801 2802 public: 2803 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2804 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2805 if (VD->hasLocalStorage()) { 2806 SemaRef.Diag(E->getBeginLoc(), 2807 diag::err_omp_local_var_in_threadprivate_init) 2808 << E->getSourceRange(); 2809 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2810 << VD << VD->getSourceRange(); 2811 return true; 2812 } 2813 } 2814 return false; 2815 } 2816 bool VisitStmt(const Stmt *S) { 2817 for (const Stmt *Child : S->children()) { 2818 if (Child && Visit(Child)) 2819 return true; 2820 } 2821 return false; 2822 } 2823 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2824 }; 2825 } // namespace 2826 2827 OMPThreadPrivateDecl * 2828 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2829 SmallVector<Expr *, 8> Vars; 2830 for (Expr *RefExpr : VarList) { 2831 auto *DE = cast<DeclRefExpr>(RefExpr); 2832 auto *VD = cast<VarDecl>(DE->getDecl()); 2833 SourceLocation ILoc = DE->getExprLoc(); 2834 2835 // Mark variable as used. 2836 VD->setReferenced(); 2837 VD->markUsed(Context); 2838 2839 QualType QType = VD->getType(); 2840 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2841 // It will be analyzed later. 2842 Vars.push_back(DE); 2843 continue; 2844 } 2845 2846 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2847 // A threadprivate variable must not have an incomplete type. 2848 if (RequireCompleteType(ILoc, VD->getType(), 2849 diag::err_omp_threadprivate_incomplete_type)) { 2850 continue; 2851 } 2852 2853 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2854 // A threadprivate variable must not have a reference type. 2855 if (VD->getType()->isReferenceType()) { 2856 Diag(ILoc, diag::err_omp_ref_type_arg) 2857 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2858 bool IsDecl = 2859 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2860 Diag(VD->getLocation(), 2861 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2862 << VD; 2863 continue; 2864 } 2865 2866 // Check if this is a TLS variable. If TLS is not being supported, produce 2867 // the corresponding diagnostic. 2868 if ((VD->getTLSKind() != VarDecl::TLS_None && 2869 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2870 getLangOpts().OpenMPUseTLS && 2871 getASTContext().getTargetInfo().isTLSSupported())) || 2872 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2873 !VD->isLocalVarDecl())) { 2874 Diag(ILoc, diag::err_omp_var_thread_local) 2875 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2876 bool IsDecl = 2877 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2878 Diag(VD->getLocation(), 2879 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2880 << VD; 2881 continue; 2882 } 2883 2884 // Check if initial value of threadprivate variable reference variable with 2885 // local storage (it is not supported by runtime). 2886 if (const Expr *Init = VD->getAnyInitializer()) { 2887 LocalVarRefChecker Checker(*this); 2888 if (Checker.Visit(Init)) 2889 continue; 2890 } 2891 2892 Vars.push_back(RefExpr); 2893 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2894 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2895 Context, SourceRange(Loc, Loc))); 2896 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2897 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2898 } 2899 OMPThreadPrivateDecl *D = nullptr; 2900 if (!Vars.empty()) { 2901 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2902 Vars); 2903 D->setAccess(AS_public); 2904 } 2905 return D; 2906 } 2907 2908 static OMPAllocateDeclAttr::AllocatorTypeTy 2909 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2910 if (!Allocator) 2911 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2912 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2913 Allocator->isInstantiationDependent() || 2914 Allocator->containsUnexpandedParameterPack()) 2915 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2916 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2917 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2918 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2919 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2920 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2921 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2922 llvm::FoldingSetNodeID AEId, DAEId; 2923 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2924 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2925 if (AEId == DAEId) { 2926 AllocatorKindRes = AllocatorKind; 2927 break; 2928 } 2929 } 2930 return AllocatorKindRes; 2931 } 2932 2933 static bool checkPreviousOMPAllocateAttribute( 2934 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2935 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2936 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2937 return false; 2938 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2939 Expr *PrevAllocator = A->getAllocator(); 2940 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2941 getAllocatorKind(S, Stack, PrevAllocator); 2942 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2943 if (AllocatorsMatch && 2944 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2945 Allocator && PrevAllocator) { 2946 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2947 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2948 llvm::FoldingSetNodeID AEId, PAEId; 2949 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2950 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2951 AllocatorsMatch = AEId == PAEId; 2952 } 2953 if (!AllocatorsMatch) { 2954 SmallString<256> AllocatorBuffer; 2955 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2956 if (Allocator) 2957 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2958 SmallString<256> PrevAllocatorBuffer; 2959 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2960 if (PrevAllocator) 2961 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2962 S.getPrintingPolicy()); 2963 2964 SourceLocation AllocatorLoc = 2965 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2966 SourceRange AllocatorRange = 2967 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2968 SourceLocation PrevAllocatorLoc = 2969 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2970 SourceRange PrevAllocatorRange = 2971 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2972 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2973 << (Allocator ? 1 : 0) << AllocatorStream.str() 2974 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2975 << AllocatorRange; 2976 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2977 << PrevAllocatorRange; 2978 return true; 2979 } 2980 return false; 2981 } 2982 2983 static void 2984 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2985 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2986 Expr *Allocator, SourceRange SR) { 2987 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2988 return; 2989 if (Allocator && 2990 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2991 Allocator->isInstantiationDependent() || 2992 Allocator->containsUnexpandedParameterPack())) 2993 return; 2994 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2995 Allocator, SR); 2996 VD->addAttr(A); 2997 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2998 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2999 } 3000 3001 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 3002 SourceLocation Loc, ArrayRef<Expr *> VarList, 3003 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 3004 assert(Clauses.size() <= 1 && "Expected at most one clause."); 3005 Expr *Allocator = nullptr; 3006 if (Clauses.empty()) { 3007 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 3008 // allocate directives that appear in a target region must specify an 3009 // allocator clause unless a requires directive with the dynamic_allocators 3010 // clause is present in the same compilation unit. 3011 if (LangOpts.OpenMPIsDevice && 3012 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 3013 targetDiag(Loc, diag::err_expected_allocator_clause); 3014 } else { 3015 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 3016 } 3017 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3018 getAllocatorKind(*this, DSAStack, Allocator); 3019 SmallVector<Expr *, 8> Vars; 3020 for (Expr *RefExpr : VarList) { 3021 auto *DE = cast<DeclRefExpr>(RefExpr); 3022 auto *VD = cast<VarDecl>(DE->getDecl()); 3023 3024 // Check if this is a TLS variable or global register. 3025 if (VD->getTLSKind() != VarDecl::TLS_None || 3026 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 3027 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3028 !VD->isLocalVarDecl())) 3029 continue; 3030 3031 // If the used several times in the allocate directive, the same allocator 3032 // must be used. 3033 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 3034 AllocatorKind, Allocator)) 3035 continue; 3036 3037 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 3038 // If a list item has a static storage type, the allocator expression in the 3039 // allocator clause must be a constant expression that evaluates to one of 3040 // the predefined memory allocator values. 3041 if (Allocator && VD->hasGlobalStorage()) { 3042 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 3043 Diag(Allocator->getExprLoc(), 3044 diag::err_omp_expected_predefined_allocator) 3045 << Allocator->getSourceRange(); 3046 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 3047 VarDecl::DeclarationOnly; 3048 Diag(VD->getLocation(), 3049 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3050 << VD; 3051 continue; 3052 } 3053 } 3054 3055 Vars.push_back(RefExpr); 3056 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 3057 DE->getSourceRange()); 3058 } 3059 if (Vars.empty()) 3060 return nullptr; 3061 if (!Owner) 3062 Owner = getCurLexicalContext(); 3063 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 3064 D->setAccess(AS_public); 3065 Owner->addDecl(D); 3066 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3067 } 3068 3069 Sema::DeclGroupPtrTy 3070 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 3071 ArrayRef<OMPClause *> ClauseList) { 3072 OMPRequiresDecl *D = nullptr; 3073 if (!CurContext->isFileContext()) { 3074 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 3075 } else { 3076 D = CheckOMPRequiresDecl(Loc, ClauseList); 3077 if (D) { 3078 CurContext->addDecl(D); 3079 DSAStack->addRequiresDecl(D); 3080 } 3081 } 3082 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3083 } 3084 3085 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 3086 ArrayRef<OMPClause *> ClauseList) { 3087 /// For target specific clauses, the requires directive cannot be 3088 /// specified after the handling of any of the target regions in the 3089 /// current compilation unit. 3090 ArrayRef<SourceLocation> TargetLocations = 3091 DSAStack->getEncounteredTargetLocs(); 3092 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 3093 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 3094 for (const OMPClause *CNew : ClauseList) { 3095 // Check if any of the requires clauses affect target regions. 3096 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 3097 isa<OMPUnifiedAddressClause>(CNew) || 3098 isa<OMPReverseOffloadClause>(CNew) || 3099 isa<OMPDynamicAllocatorsClause>(CNew)) { 3100 Diag(Loc, diag::err_omp_directive_before_requires) 3101 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 3102 for (SourceLocation TargetLoc : TargetLocations) { 3103 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 3104 << "target"; 3105 } 3106 } else if (!AtomicLoc.isInvalid() && 3107 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 3108 Diag(Loc, diag::err_omp_directive_before_requires) 3109 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 3110 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 3111 << "atomic"; 3112 } 3113 } 3114 } 3115 3116 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 3117 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3118 ClauseList); 3119 return nullptr; 3120 } 3121 3122 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3123 const ValueDecl *D, 3124 const DSAStackTy::DSAVarData &DVar, 3125 bool IsLoopIterVar) { 3126 if (DVar.RefExpr) { 3127 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3128 << getOpenMPClauseName(DVar.CKind); 3129 return; 3130 } 3131 enum { 3132 PDSA_StaticMemberShared, 3133 PDSA_StaticLocalVarShared, 3134 PDSA_LoopIterVarPrivate, 3135 PDSA_LoopIterVarLinear, 3136 PDSA_LoopIterVarLastprivate, 3137 PDSA_ConstVarShared, 3138 PDSA_GlobalVarShared, 3139 PDSA_TaskVarFirstprivate, 3140 PDSA_LocalVarPrivate, 3141 PDSA_Implicit 3142 } Reason = PDSA_Implicit; 3143 bool ReportHint = false; 3144 auto ReportLoc = D->getLocation(); 3145 auto *VD = dyn_cast<VarDecl>(D); 3146 if (IsLoopIterVar) { 3147 if (DVar.CKind == OMPC_private) 3148 Reason = PDSA_LoopIterVarPrivate; 3149 else if (DVar.CKind == OMPC_lastprivate) 3150 Reason = PDSA_LoopIterVarLastprivate; 3151 else 3152 Reason = PDSA_LoopIterVarLinear; 3153 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3154 DVar.CKind == OMPC_firstprivate) { 3155 Reason = PDSA_TaskVarFirstprivate; 3156 ReportLoc = DVar.ImplicitDSALoc; 3157 } else if (VD && VD->isStaticLocal()) 3158 Reason = PDSA_StaticLocalVarShared; 3159 else if (VD && VD->isStaticDataMember()) 3160 Reason = PDSA_StaticMemberShared; 3161 else if (VD && VD->isFileVarDecl()) 3162 Reason = PDSA_GlobalVarShared; 3163 else if (D->getType().isConstant(SemaRef.getASTContext())) 3164 Reason = PDSA_ConstVarShared; 3165 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3166 ReportHint = true; 3167 Reason = PDSA_LocalVarPrivate; 3168 } 3169 if (Reason != PDSA_Implicit) { 3170 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3171 << Reason << ReportHint 3172 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3173 } else if (DVar.ImplicitDSALoc.isValid()) { 3174 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3175 << getOpenMPClauseName(DVar.CKind); 3176 } 3177 } 3178 3179 static OpenMPMapClauseKind 3180 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3181 bool IsAggregateOrDeclareTarget) { 3182 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3183 switch (M) { 3184 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3185 Kind = OMPC_MAP_alloc; 3186 break; 3187 case OMPC_DEFAULTMAP_MODIFIER_to: 3188 Kind = OMPC_MAP_to; 3189 break; 3190 case OMPC_DEFAULTMAP_MODIFIER_from: 3191 Kind = OMPC_MAP_from; 3192 break; 3193 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3194 Kind = OMPC_MAP_tofrom; 3195 break; 3196 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3197 case OMPC_DEFAULTMAP_MODIFIER_last: 3198 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3199 case OMPC_DEFAULTMAP_MODIFIER_none: 3200 case OMPC_DEFAULTMAP_MODIFIER_default: 3201 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3202 // IsAggregateOrDeclareTarget could be true if: 3203 // 1. the implicit behavior for aggregate is tofrom 3204 // 2. it's a declare target link 3205 if (IsAggregateOrDeclareTarget) { 3206 Kind = OMPC_MAP_tofrom; 3207 break; 3208 } 3209 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3210 } 3211 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3212 return Kind; 3213 } 3214 3215 namespace { 3216 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3217 DSAStackTy *Stack; 3218 Sema &SemaRef; 3219 bool ErrorFound = false; 3220 bool TryCaptureCXXThisMembers = false; 3221 CapturedStmt *CS = nullptr; 3222 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3223 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 3224 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3225 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3226 3227 void VisitSubCaptures(OMPExecutableDirective *S) { 3228 // Check implicitly captured variables. 3229 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 3230 return; 3231 visitSubCaptures(S->getInnermostCapturedStmt()); 3232 // Try to capture inner this->member references to generate correct mappings 3233 // and diagnostics. 3234 if (TryCaptureCXXThisMembers || 3235 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3236 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3237 [](const CapturedStmt::Capture &C) { 3238 return C.capturesThis(); 3239 }))) { 3240 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3241 TryCaptureCXXThisMembers = true; 3242 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3243 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3244 } 3245 // In tasks firstprivates are not captured anymore, need to analyze them 3246 // explicitly. 3247 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3248 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3249 for (OMPClause *C : S->clauses()) 3250 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3251 for (Expr *Ref : FC->varlists()) 3252 Visit(Ref); 3253 } 3254 } 3255 } 3256 3257 public: 3258 void VisitDeclRefExpr(DeclRefExpr *E) { 3259 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3260 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3261 E->isInstantiationDependent()) 3262 return; 3263 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3264 // Check the datasharing rules for the expressions in the clauses. 3265 if (!CS) { 3266 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3267 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3268 Visit(CED->getInit()); 3269 return; 3270 } 3271 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3272 // Do not analyze internal variables and do not enclose them into 3273 // implicit clauses. 3274 return; 3275 VD = VD->getCanonicalDecl(); 3276 // Skip internally declared variables. 3277 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3278 !Stack->isImplicitTaskFirstprivate(VD)) 3279 return; 3280 // Skip allocators in uses_allocators clauses. 3281 if (Stack->isUsesAllocatorsDecl(VD)) 3282 return; 3283 3284 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3285 // Check if the variable has explicit DSA set and stop analysis if it so. 3286 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3287 return; 3288 3289 // Skip internally declared static variables. 3290 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3291 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3292 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3293 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3294 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3295 !Stack->isImplicitTaskFirstprivate(VD)) 3296 return; 3297 3298 SourceLocation ELoc = E->getExprLoc(); 3299 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3300 // The default(none) clause requires that each variable that is referenced 3301 // in the construct, and does not have a predetermined data-sharing 3302 // attribute, must have its data-sharing attribute explicitly determined 3303 // by being listed in a data-sharing attribute clause. 3304 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 3305 isImplicitOrExplicitTaskingRegion(DKind) && 3306 VarsWithInheritedDSA.count(VD) == 0) { 3307 VarsWithInheritedDSA[VD] = E; 3308 return; 3309 } 3310 3311 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3312 // If implicit-behavior is none, each variable referenced in the 3313 // construct that does not have a predetermined data-sharing attribute 3314 // and does not appear in a to or link clause on a declare target 3315 // directive must be listed in a data-mapping attribute clause, a 3316 // data-haring attribute clause (including a data-sharing attribute 3317 // clause on a combined construct where target. is one of the 3318 // constituent constructs), or an is_device_ptr clause. 3319 OpenMPDefaultmapClauseKind ClauseKind = 3320 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3321 if (SemaRef.getLangOpts().OpenMP >= 50) { 3322 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3323 OMPC_DEFAULTMAP_MODIFIER_none; 3324 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3325 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3326 // Only check for data-mapping attribute and is_device_ptr here 3327 // since we have already make sure that the declaration does not 3328 // have a data-sharing attribute above 3329 if (!Stack->checkMappableExprComponentListsForDecl( 3330 VD, /*CurrentRegionOnly=*/true, 3331 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3332 MapExprComponents, 3333 OpenMPClauseKind) { 3334 auto MI = MapExprComponents.rbegin(); 3335 auto ME = MapExprComponents.rend(); 3336 return MI != ME && MI->getAssociatedDeclaration() == VD; 3337 })) { 3338 VarsWithInheritedDSA[VD] = E; 3339 return; 3340 } 3341 } 3342 } 3343 3344 if (isOpenMPTargetExecutionDirective(DKind) && 3345 !Stack->isLoopControlVariable(VD).first) { 3346 if (!Stack->checkMappableExprComponentListsForDecl( 3347 VD, /*CurrentRegionOnly=*/true, 3348 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3349 StackComponents, 3350 OpenMPClauseKind) { 3351 // Variable is used if it has been marked as an array, array 3352 // section, array shaping or the variable iself. 3353 return StackComponents.size() == 1 || 3354 std::all_of( 3355 std::next(StackComponents.rbegin()), 3356 StackComponents.rend(), 3357 [](const OMPClauseMappableExprCommon:: 3358 MappableComponent &MC) { 3359 return MC.getAssociatedDeclaration() == 3360 nullptr && 3361 (isa<OMPArraySectionExpr>( 3362 MC.getAssociatedExpression()) || 3363 isa<OMPArrayShapingExpr>( 3364 MC.getAssociatedExpression()) || 3365 isa<ArraySubscriptExpr>( 3366 MC.getAssociatedExpression())); 3367 }); 3368 })) { 3369 bool IsFirstprivate = false; 3370 // By default lambdas are captured as firstprivates. 3371 if (const auto *RD = 3372 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3373 IsFirstprivate = RD->isLambda(); 3374 IsFirstprivate = 3375 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3376 if (IsFirstprivate) { 3377 ImplicitFirstprivate.emplace_back(E); 3378 } else { 3379 OpenMPDefaultmapClauseModifier M = 3380 Stack->getDefaultmapModifier(ClauseKind); 3381 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3382 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3383 ImplicitMap[Kind].emplace_back(E); 3384 } 3385 return; 3386 } 3387 } 3388 3389 // OpenMP [2.9.3.6, Restrictions, p.2] 3390 // A list item that appears in a reduction clause of the innermost 3391 // enclosing worksharing or parallel construct may not be accessed in an 3392 // explicit task. 3393 DVar = Stack->hasInnermostDSA( 3394 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3395 [](OpenMPDirectiveKind K) { 3396 return isOpenMPParallelDirective(K) || 3397 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3398 }, 3399 /*FromParent=*/true); 3400 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3401 ErrorFound = true; 3402 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3403 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3404 return; 3405 } 3406 3407 // Define implicit data-sharing attributes for task. 3408 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3409 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3410 !Stack->isLoopControlVariable(VD).first) { 3411 ImplicitFirstprivate.push_back(E); 3412 return; 3413 } 3414 3415 // Store implicitly used globals with declare target link for parent 3416 // target. 3417 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3418 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3419 Stack->addToParentTargetRegionLinkGlobals(E); 3420 return; 3421 } 3422 } 3423 } 3424 void VisitMemberExpr(MemberExpr *E) { 3425 if (E->isTypeDependent() || E->isValueDependent() || 3426 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3427 return; 3428 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3429 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3430 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3431 if (!FD) 3432 return; 3433 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3434 // Check if the variable has explicit DSA set and stop analysis if it 3435 // so. 3436 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3437 return; 3438 3439 if (isOpenMPTargetExecutionDirective(DKind) && 3440 !Stack->isLoopControlVariable(FD).first && 3441 !Stack->checkMappableExprComponentListsForDecl( 3442 FD, /*CurrentRegionOnly=*/true, 3443 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3444 StackComponents, 3445 OpenMPClauseKind) { 3446 return isa<CXXThisExpr>( 3447 cast<MemberExpr>( 3448 StackComponents.back().getAssociatedExpression()) 3449 ->getBase() 3450 ->IgnoreParens()); 3451 })) { 3452 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3453 // A bit-field cannot appear in a map clause. 3454 // 3455 if (FD->isBitField()) 3456 return; 3457 3458 // Check to see if the member expression is referencing a class that 3459 // has already been explicitly mapped 3460 if (Stack->isClassPreviouslyMapped(TE->getType())) 3461 return; 3462 3463 OpenMPDefaultmapClauseModifier Modifier = 3464 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3465 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3466 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3467 ImplicitMap[Kind].emplace_back(E); 3468 return; 3469 } 3470 3471 SourceLocation ELoc = E->getExprLoc(); 3472 // OpenMP [2.9.3.6, Restrictions, p.2] 3473 // A list item that appears in a reduction clause of the innermost 3474 // enclosing worksharing or parallel construct may not be accessed in 3475 // an explicit task. 3476 DVar = Stack->hasInnermostDSA( 3477 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3478 [](OpenMPDirectiveKind K) { 3479 return isOpenMPParallelDirective(K) || 3480 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3481 }, 3482 /*FromParent=*/true); 3483 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3484 ErrorFound = true; 3485 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3486 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3487 return; 3488 } 3489 3490 // Define implicit data-sharing attributes for task. 3491 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3492 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3493 !Stack->isLoopControlVariable(FD).first) { 3494 // Check if there is a captured expression for the current field in the 3495 // region. Do not mark it as firstprivate unless there is no captured 3496 // expression. 3497 // TODO: try to make it firstprivate. 3498 if (DVar.CKind != OMPC_unknown) 3499 ImplicitFirstprivate.push_back(E); 3500 } 3501 return; 3502 } 3503 if (isOpenMPTargetExecutionDirective(DKind)) { 3504 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3505 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3506 /*NoDiagnose=*/true)) 3507 return; 3508 const auto *VD = cast<ValueDecl>( 3509 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3510 if (!Stack->checkMappableExprComponentListsForDecl( 3511 VD, /*CurrentRegionOnly=*/true, 3512 [&CurComponents]( 3513 OMPClauseMappableExprCommon::MappableExprComponentListRef 3514 StackComponents, 3515 OpenMPClauseKind) { 3516 auto CCI = CurComponents.rbegin(); 3517 auto CCE = CurComponents.rend(); 3518 for (const auto &SC : llvm::reverse(StackComponents)) { 3519 // Do both expressions have the same kind? 3520 if (CCI->getAssociatedExpression()->getStmtClass() != 3521 SC.getAssociatedExpression()->getStmtClass()) 3522 if (!((isa<OMPArraySectionExpr>( 3523 SC.getAssociatedExpression()) || 3524 isa<OMPArrayShapingExpr>( 3525 SC.getAssociatedExpression())) && 3526 isa<ArraySubscriptExpr>( 3527 CCI->getAssociatedExpression()))) 3528 return false; 3529 3530 const Decl *CCD = CCI->getAssociatedDeclaration(); 3531 const Decl *SCD = SC.getAssociatedDeclaration(); 3532 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3533 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3534 if (SCD != CCD) 3535 return false; 3536 std::advance(CCI, 1); 3537 if (CCI == CCE) 3538 break; 3539 } 3540 return true; 3541 })) { 3542 Visit(E->getBase()); 3543 } 3544 } else if (!TryCaptureCXXThisMembers) { 3545 Visit(E->getBase()); 3546 } 3547 } 3548 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3549 for (OMPClause *C : S->clauses()) { 3550 // Skip analysis of arguments of implicitly defined firstprivate clause 3551 // for task|target directives. 3552 // Skip analysis of arguments of implicitly defined map clause for target 3553 // directives. 3554 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3555 C->isImplicit())) { 3556 for (Stmt *CC : C->children()) { 3557 if (CC) 3558 Visit(CC); 3559 } 3560 } 3561 } 3562 // Check implicitly captured variables. 3563 VisitSubCaptures(S); 3564 } 3565 void VisitStmt(Stmt *S) { 3566 for (Stmt *C : S->children()) { 3567 if (C) { 3568 // Check implicitly captured variables in the task-based directives to 3569 // check if they must be firstprivatized. 3570 Visit(C); 3571 } 3572 } 3573 } 3574 3575 void visitSubCaptures(CapturedStmt *S) { 3576 for (const CapturedStmt::Capture &Cap : S->captures()) { 3577 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3578 continue; 3579 VarDecl *VD = Cap.getCapturedVar(); 3580 // Do not try to map the variable if it or its sub-component was mapped 3581 // already. 3582 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3583 Stack->checkMappableExprComponentListsForDecl( 3584 VD, /*CurrentRegionOnly=*/true, 3585 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3586 OpenMPClauseKind) { return true; })) 3587 continue; 3588 DeclRefExpr *DRE = buildDeclRefExpr( 3589 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3590 Cap.getLocation(), /*RefersToCapture=*/true); 3591 Visit(DRE); 3592 } 3593 } 3594 bool isErrorFound() const { return ErrorFound; } 3595 ArrayRef<Expr *> getImplicitFirstprivate() const { 3596 return ImplicitFirstprivate; 3597 } 3598 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3599 return ImplicitMap[Kind]; 3600 } 3601 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3602 return VarsWithInheritedDSA; 3603 } 3604 3605 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3606 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3607 // Process declare target link variables for the target directives. 3608 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3609 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3610 Visit(E); 3611 } 3612 } 3613 }; 3614 } // namespace 3615 3616 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3617 switch (DKind) { 3618 case OMPD_parallel: 3619 case OMPD_parallel_for: 3620 case OMPD_parallel_for_simd: 3621 case OMPD_parallel_sections: 3622 case OMPD_parallel_master: 3623 case OMPD_teams: 3624 case OMPD_teams_distribute: 3625 case OMPD_teams_distribute_simd: { 3626 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3627 QualType KmpInt32PtrTy = 3628 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3629 Sema::CapturedParamNameType Params[] = { 3630 std::make_pair(".global_tid.", KmpInt32PtrTy), 3631 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3632 std::make_pair(StringRef(), QualType()) // __context with shared vars 3633 }; 3634 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3635 Params); 3636 break; 3637 } 3638 case OMPD_target_teams: 3639 case OMPD_target_parallel: 3640 case OMPD_target_parallel_for: 3641 case OMPD_target_parallel_for_simd: 3642 case OMPD_target_teams_distribute: 3643 case OMPD_target_teams_distribute_simd: { 3644 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3645 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3646 QualType KmpInt32PtrTy = 3647 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3648 QualType Args[] = {VoidPtrTy}; 3649 FunctionProtoType::ExtProtoInfo EPI; 3650 EPI.Variadic = true; 3651 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3652 Sema::CapturedParamNameType Params[] = { 3653 std::make_pair(".global_tid.", KmpInt32Ty), 3654 std::make_pair(".part_id.", KmpInt32PtrTy), 3655 std::make_pair(".privates.", VoidPtrTy), 3656 std::make_pair( 3657 ".copy_fn.", 3658 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3659 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3660 std::make_pair(StringRef(), QualType()) // __context with shared vars 3661 }; 3662 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3663 Params, /*OpenMPCaptureLevel=*/0); 3664 // Mark this captured region as inlined, because we don't use outlined 3665 // function directly. 3666 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3667 AlwaysInlineAttr::CreateImplicit( 3668 Context, {}, AttributeCommonInfo::AS_Keyword, 3669 AlwaysInlineAttr::Keyword_forceinline)); 3670 Sema::CapturedParamNameType ParamsTarget[] = { 3671 std::make_pair(StringRef(), QualType()) // __context with shared vars 3672 }; 3673 // Start a captured region for 'target' with no implicit parameters. 3674 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3675 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3676 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3677 std::make_pair(".global_tid.", KmpInt32PtrTy), 3678 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3679 std::make_pair(StringRef(), QualType()) // __context with shared vars 3680 }; 3681 // Start a captured region for 'teams' or 'parallel'. Both regions have 3682 // the same implicit parameters. 3683 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3684 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3685 break; 3686 } 3687 case OMPD_target: 3688 case OMPD_target_simd: { 3689 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3690 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3691 QualType KmpInt32PtrTy = 3692 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3693 QualType Args[] = {VoidPtrTy}; 3694 FunctionProtoType::ExtProtoInfo EPI; 3695 EPI.Variadic = true; 3696 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3697 Sema::CapturedParamNameType Params[] = { 3698 std::make_pair(".global_tid.", KmpInt32Ty), 3699 std::make_pair(".part_id.", KmpInt32PtrTy), 3700 std::make_pair(".privates.", VoidPtrTy), 3701 std::make_pair( 3702 ".copy_fn.", 3703 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3704 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3705 std::make_pair(StringRef(), QualType()) // __context with shared vars 3706 }; 3707 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3708 Params, /*OpenMPCaptureLevel=*/0); 3709 // Mark this captured region as inlined, because we don't use outlined 3710 // function directly. 3711 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3712 AlwaysInlineAttr::CreateImplicit( 3713 Context, {}, AttributeCommonInfo::AS_Keyword, 3714 AlwaysInlineAttr::Keyword_forceinline)); 3715 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3716 std::make_pair(StringRef(), QualType()), 3717 /*OpenMPCaptureLevel=*/1); 3718 break; 3719 } 3720 case OMPD_simd: 3721 case OMPD_for: 3722 case OMPD_for_simd: 3723 case OMPD_sections: 3724 case OMPD_section: 3725 case OMPD_single: 3726 case OMPD_master: 3727 case OMPD_critical: 3728 case OMPD_taskgroup: 3729 case OMPD_distribute: 3730 case OMPD_distribute_simd: 3731 case OMPD_ordered: 3732 case OMPD_atomic: 3733 case OMPD_target_data: { 3734 Sema::CapturedParamNameType Params[] = { 3735 std::make_pair(StringRef(), QualType()) // __context with shared vars 3736 }; 3737 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3738 Params); 3739 break; 3740 } 3741 case OMPD_task: { 3742 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3743 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3744 QualType KmpInt32PtrTy = 3745 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3746 QualType Args[] = {VoidPtrTy}; 3747 FunctionProtoType::ExtProtoInfo EPI; 3748 EPI.Variadic = true; 3749 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3750 Sema::CapturedParamNameType Params[] = { 3751 std::make_pair(".global_tid.", KmpInt32Ty), 3752 std::make_pair(".part_id.", KmpInt32PtrTy), 3753 std::make_pair(".privates.", VoidPtrTy), 3754 std::make_pair( 3755 ".copy_fn.", 3756 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3757 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3758 std::make_pair(StringRef(), QualType()) // __context with shared vars 3759 }; 3760 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3761 Params); 3762 // Mark this captured region as inlined, because we don't use outlined 3763 // function directly. 3764 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3765 AlwaysInlineAttr::CreateImplicit( 3766 Context, {}, AttributeCommonInfo::AS_Keyword, 3767 AlwaysInlineAttr::Keyword_forceinline)); 3768 break; 3769 } 3770 case OMPD_taskloop: 3771 case OMPD_taskloop_simd: 3772 case OMPD_master_taskloop: 3773 case OMPD_master_taskloop_simd: { 3774 QualType KmpInt32Ty = 3775 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3776 .withConst(); 3777 QualType KmpUInt64Ty = 3778 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3779 .withConst(); 3780 QualType KmpInt64Ty = 3781 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3782 .withConst(); 3783 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3784 QualType KmpInt32PtrTy = 3785 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3786 QualType Args[] = {VoidPtrTy}; 3787 FunctionProtoType::ExtProtoInfo EPI; 3788 EPI.Variadic = true; 3789 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3790 Sema::CapturedParamNameType Params[] = { 3791 std::make_pair(".global_tid.", KmpInt32Ty), 3792 std::make_pair(".part_id.", KmpInt32PtrTy), 3793 std::make_pair(".privates.", VoidPtrTy), 3794 std::make_pair( 3795 ".copy_fn.", 3796 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3797 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3798 std::make_pair(".lb.", KmpUInt64Ty), 3799 std::make_pair(".ub.", KmpUInt64Ty), 3800 std::make_pair(".st.", KmpInt64Ty), 3801 std::make_pair(".liter.", KmpInt32Ty), 3802 std::make_pair(".reductions.", VoidPtrTy), 3803 std::make_pair(StringRef(), QualType()) // __context with shared vars 3804 }; 3805 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3806 Params); 3807 // Mark this captured region as inlined, because we don't use outlined 3808 // function directly. 3809 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3810 AlwaysInlineAttr::CreateImplicit( 3811 Context, {}, AttributeCommonInfo::AS_Keyword, 3812 AlwaysInlineAttr::Keyword_forceinline)); 3813 break; 3814 } 3815 case OMPD_parallel_master_taskloop: 3816 case OMPD_parallel_master_taskloop_simd: { 3817 QualType KmpInt32Ty = 3818 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3819 .withConst(); 3820 QualType KmpUInt64Ty = 3821 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3822 .withConst(); 3823 QualType KmpInt64Ty = 3824 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3825 .withConst(); 3826 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3827 QualType KmpInt32PtrTy = 3828 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3829 Sema::CapturedParamNameType ParamsParallel[] = { 3830 std::make_pair(".global_tid.", KmpInt32PtrTy), 3831 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3832 std::make_pair(StringRef(), QualType()) // __context with shared vars 3833 }; 3834 // Start a captured region for 'parallel'. 3835 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3836 ParamsParallel, /*OpenMPCaptureLevel=*/0); 3837 QualType Args[] = {VoidPtrTy}; 3838 FunctionProtoType::ExtProtoInfo EPI; 3839 EPI.Variadic = true; 3840 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3841 Sema::CapturedParamNameType Params[] = { 3842 std::make_pair(".global_tid.", KmpInt32Ty), 3843 std::make_pair(".part_id.", KmpInt32PtrTy), 3844 std::make_pair(".privates.", VoidPtrTy), 3845 std::make_pair( 3846 ".copy_fn.", 3847 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3848 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3849 std::make_pair(".lb.", KmpUInt64Ty), 3850 std::make_pair(".ub.", KmpUInt64Ty), 3851 std::make_pair(".st.", KmpInt64Ty), 3852 std::make_pair(".liter.", KmpInt32Ty), 3853 std::make_pair(".reductions.", VoidPtrTy), 3854 std::make_pair(StringRef(), QualType()) // __context with shared vars 3855 }; 3856 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3857 Params, /*OpenMPCaptureLevel=*/1); 3858 // Mark this captured region as inlined, because we don't use outlined 3859 // function directly. 3860 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3861 AlwaysInlineAttr::CreateImplicit( 3862 Context, {}, AttributeCommonInfo::AS_Keyword, 3863 AlwaysInlineAttr::Keyword_forceinline)); 3864 break; 3865 } 3866 case OMPD_distribute_parallel_for_simd: 3867 case OMPD_distribute_parallel_for: { 3868 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3869 QualType KmpInt32PtrTy = 3870 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3871 Sema::CapturedParamNameType Params[] = { 3872 std::make_pair(".global_tid.", KmpInt32PtrTy), 3873 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3874 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3875 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3876 std::make_pair(StringRef(), QualType()) // __context with shared vars 3877 }; 3878 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3879 Params); 3880 break; 3881 } 3882 case OMPD_target_teams_distribute_parallel_for: 3883 case OMPD_target_teams_distribute_parallel_for_simd: { 3884 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3885 QualType KmpInt32PtrTy = 3886 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3887 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3888 3889 QualType Args[] = {VoidPtrTy}; 3890 FunctionProtoType::ExtProtoInfo EPI; 3891 EPI.Variadic = true; 3892 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3893 Sema::CapturedParamNameType Params[] = { 3894 std::make_pair(".global_tid.", KmpInt32Ty), 3895 std::make_pair(".part_id.", KmpInt32PtrTy), 3896 std::make_pair(".privates.", VoidPtrTy), 3897 std::make_pair( 3898 ".copy_fn.", 3899 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3900 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3901 std::make_pair(StringRef(), QualType()) // __context with shared vars 3902 }; 3903 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3904 Params, /*OpenMPCaptureLevel=*/0); 3905 // Mark this captured region as inlined, because we don't use outlined 3906 // function directly. 3907 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3908 AlwaysInlineAttr::CreateImplicit( 3909 Context, {}, AttributeCommonInfo::AS_Keyword, 3910 AlwaysInlineAttr::Keyword_forceinline)); 3911 Sema::CapturedParamNameType ParamsTarget[] = { 3912 std::make_pair(StringRef(), QualType()) // __context with shared vars 3913 }; 3914 // Start a captured region for 'target' with no implicit parameters. 3915 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3916 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3917 3918 Sema::CapturedParamNameType ParamsTeams[] = { 3919 std::make_pair(".global_tid.", KmpInt32PtrTy), 3920 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3921 std::make_pair(StringRef(), QualType()) // __context with shared vars 3922 }; 3923 // Start a captured region for 'target' with no implicit parameters. 3924 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3925 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3926 3927 Sema::CapturedParamNameType ParamsParallel[] = { 3928 std::make_pair(".global_tid.", KmpInt32PtrTy), 3929 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3930 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3931 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3932 std::make_pair(StringRef(), QualType()) // __context with shared vars 3933 }; 3934 // Start a captured region for 'teams' or 'parallel'. Both regions have 3935 // the same implicit parameters. 3936 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3937 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3938 break; 3939 } 3940 3941 case OMPD_teams_distribute_parallel_for: 3942 case OMPD_teams_distribute_parallel_for_simd: { 3943 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3944 QualType KmpInt32PtrTy = 3945 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3946 3947 Sema::CapturedParamNameType ParamsTeams[] = { 3948 std::make_pair(".global_tid.", KmpInt32PtrTy), 3949 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3950 std::make_pair(StringRef(), QualType()) // __context with shared vars 3951 }; 3952 // Start a captured region for 'target' with no implicit parameters. 3953 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3954 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3955 3956 Sema::CapturedParamNameType ParamsParallel[] = { 3957 std::make_pair(".global_tid.", KmpInt32PtrTy), 3958 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3959 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3960 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3961 std::make_pair(StringRef(), QualType()) // __context with shared vars 3962 }; 3963 // Start a captured region for 'teams' or 'parallel'. Both regions have 3964 // the same implicit parameters. 3965 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3966 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3967 break; 3968 } 3969 case OMPD_target_update: 3970 case OMPD_target_enter_data: 3971 case OMPD_target_exit_data: { 3972 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3973 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3974 QualType KmpInt32PtrTy = 3975 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3976 QualType Args[] = {VoidPtrTy}; 3977 FunctionProtoType::ExtProtoInfo EPI; 3978 EPI.Variadic = true; 3979 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3980 Sema::CapturedParamNameType Params[] = { 3981 std::make_pair(".global_tid.", KmpInt32Ty), 3982 std::make_pair(".part_id.", KmpInt32PtrTy), 3983 std::make_pair(".privates.", VoidPtrTy), 3984 std::make_pair( 3985 ".copy_fn.", 3986 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3987 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3988 std::make_pair(StringRef(), QualType()) // __context with shared vars 3989 }; 3990 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3991 Params); 3992 // Mark this captured region as inlined, because we don't use outlined 3993 // function directly. 3994 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3995 AlwaysInlineAttr::CreateImplicit( 3996 Context, {}, AttributeCommonInfo::AS_Keyword, 3997 AlwaysInlineAttr::Keyword_forceinline)); 3998 break; 3999 } 4000 case OMPD_threadprivate: 4001 case OMPD_allocate: 4002 case OMPD_taskyield: 4003 case OMPD_barrier: 4004 case OMPD_taskwait: 4005 case OMPD_cancellation_point: 4006 case OMPD_cancel: 4007 case OMPD_flush: 4008 case OMPD_depobj: 4009 case OMPD_scan: 4010 case OMPD_declare_reduction: 4011 case OMPD_declare_mapper: 4012 case OMPD_declare_simd: 4013 case OMPD_declare_target: 4014 case OMPD_end_declare_target: 4015 case OMPD_requires: 4016 case OMPD_declare_variant: 4017 case OMPD_begin_declare_variant: 4018 case OMPD_end_declare_variant: 4019 llvm_unreachable("OpenMP Directive is not allowed"); 4020 case OMPD_unknown: 4021 llvm_unreachable("Unknown OpenMP directive"); 4022 } 4023 } 4024 4025 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4026 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4027 } 4028 4029 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4030 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4031 getOpenMPCaptureRegions(CaptureRegions, DKind); 4032 return CaptureRegions.size(); 4033 } 4034 4035 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4036 Expr *CaptureExpr, bool WithInit, 4037 bool AsExpression) { 4038 assert(CaptureExpr); 4039 ASTContext &C = S.getASTContext(); 4040 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4041 QualType Ty = Init->getType(); 4042 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4043 if (S.getLangOpts().CPlusPlus) { 4044 Ty = C.getLValueReferenceType(Ty); 4045 } else { 4046 Ty = C.getPointerType(Ty); 4047 ExprResult Res = 4048 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4049 if (!Res.isUsable()) 4050 return nullptr; 4051 Init = Res.get(); 4052 } 4053 WithInit = true; 4054 } 4055 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 4056 CaptureExpr->getBeginLoc()); 4057 if (!WithInit) 4058 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4059 S.CurContext->addHiddenDecl(CED); 4060 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4061 return CED; 4062 } 4063 4064 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4065 bool WithInit) { 4066 OMPCapturedExprDecl *CD; 4067 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4068 CD = cast<OMPCapturedExprDecl>(VD); 4069 else 4070 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4071 /*AsExpression=*/false); 4072 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4073 CaptureExpr->getExprLoc()); 4074 } 4075 4076 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 4077 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4078 if (!Ref) { 4079 OMPCapturedExprDecl *CD = buildCaptureDecl( 4080 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 4081 /*WithInit=*/true, /*AsExpression=*/true); 4082 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4083 CaptureExpr->getExprLoc()); 4084 } 4085 ExprResult Res = Ref; 4086 if (!S.getLangOpts().CPlusPlus && 4087 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4088 Ref->getType()->isPointerType()) { 4089 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4090 if (!Res.isUsable()) 4091 return ExprError(); 4092 } 4093 return S.DefaultLvalueConversion(Res.get()); 4094 } 4095 4096 namespace { 4097 // OpenMP directives parsed in this section are represented as a 4098 // CapturedStatement with an associated statement. If a syntax error 4099 // is detected during the parsing of the associated statement, the 4100 // compiler must abort processing and close the CapturedStatement. 4101 // 4102 // Combined directives such as 'target parallel' have more than one 4103 // nested CapturedStatements. This RAII ensures that we unwind out 4104 // of all the nested CapturedStatements when an error is found. 4105 class CaptureRegionUnwinderRAII { 4106 private: 4107 Sema &S; 4108 bool &ErrorFound; 4109 OpenMPDirectiveKind DKind = OMPD_unknown; 4110 4111 public: 4112 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4113 OpenMPDirectiveKind DKind) 4114 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4115 ~CaptureRegionUnwinderRAII() { 4116 if (ErrorFound) { 4117 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4118 while (--ThisCaptureLevel >= 0) 4119 S.ActOnCapturedRegionError(); 4120 } 4121 } 4122 }; 4123 } // namespace 4124 4125 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4126 // Capture variables captured by reference in lambdas for target-based 4127 // directives. 4128 if (!CurContext->isDependentContext() && 4129 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4130 isOpenMPTargetDataManagementDirective( 4131 DSAStack->getCurrentDirective()))) { 4132 QualType Type = V->getType(); 4133 if (const auto *RD = Type.getCanonicalType() 4134 .getNonReferenceType() 4135 ->getAsCXXRecordDecl()) { 4136 bool SavedForceCaptureByReferenceInTargetExecutable = 4137 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4138 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4139 /*V=*/true); 4140 if (RD->isLambda()) { 4141 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4142 FieldDecl *ThisCapture; 4143 RD->getCaptureFields(Captures, ThisCapture); 4144 for (const LambdaCapture &LC : RD->captures()) { 4145 if (LC.getCaptureKind() == LCK_ByRef) { 4146 VarDecl *VD = LC.getCapturedVar(); 4147 DeclContext *VDC = VD->getDeclContext(); 4148 if (!VDC->Encloses(CurContext)) 4149 continue; 4150 MarkVariableReferenced(LC.getLocation(), VD); 4151 } else if (LC.getCaptureKind() == LCK_This) { 4152 QualType ThisTy = getCurrentThisType(); 4153 if (!ThisTy.isNull() && 4154 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4155 CheckCXXThisCapture(LC.getLocation()); 4156 } 4157 } 4158 } 4159 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4160 SavedForceCaptureByReferenceInTargetExecutable); 4161 } 4162 } 4163 } 4164 4165 static bool checkOrderedOrderSpecified(Sema &S, 4166 const ArrayRef<OMPClause *> Clauses) { 4167 const OMPOrderedClause *Ordered = nullptr; 4168 const OMPOrderClause *Order = nullptr; 4169 4170 for (const OMPClause *Clause : Clauses) { 4171 if (Clause->getClauseKind() == OMPC_ordered) 4172 Ordered = cast<OMPOrderedClause>(Clause); 4173 else if (Clause->getClauseKind() == OMPC_order) { 4174 Order = cast<OMPOrderClause>(Clause); 4175 if (Order->getKind() != OMPC_ORDER_concurrent) 4176 Order = nullptr; 4177 } 4178 if (Ordered && Order) 4179 break; 4180 } 4181 4182 if (Ordered && Order) { 4183 S.Diag(Order->getKindKwLoc(), 4184 diag::err_omp_simple_clause_incompatible_with_ordered) 4185 << getOpenMPClauseName(OMPC_order) 4186 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4187 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4188 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4189 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4190 return true; 4191 } 4192 return false; 4193 } 4194 4195 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4196 ArrayRef<OMPClause *> Clauses) { 4197 bool ErrorFound = false; 4198 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4199 *this, ErrorFound, DSAStack->getCurrentDirective()); 4200 if (!S.isUsable()) { 4201 ErrorFound = true; 4202 return StmtError(); 4203 } 4204 4205 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4206 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4207 OMPOrderedClause *OC = nullptr; 4208 OMPScheduleClause *SC = nullptr; 4209 SmallVector<const OMPLinearClause *, 4> LCs; 4210 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4211 // This is required for proper codegen. 4212 for (OMPClause *Clause : Clauses) { 4213 if (!LangOpts.OpenMPSimd && 4214 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 4215 Clause->getClauseKind() == OMPC_in_reduction) { 4216 // Capture taskgroup task_reduction descriptors inside the tasking regions 4217 // with the corresponding in_reduction items. 4218 auto *IRC = cast<OMPInReductionClause>(Clause); 4219 for (Expr *E : IRC->taskgroup_descriptors()) 4220 if (E) 4221 MarkDeclarationsReferencedInExpr(E); 4222 } 4223 if (isOpenMPPrivate(Clause->getClauseKind()) || 4224 Clause->getClauseKind() == OMPC_copyprivate || 4225 (getLangOpts().OpenMPUseTLS && 4226 getASTContext().getTargetInfo().isTLSSupported() && 4227 Clause->getClauseKind() == OMPC_copyin)) { 4228 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4229 // Mark all variables in private list clauses as used in inner region. 4230 for (Stmt *VarRef : Clause->children()) { 4231 if (auto *E = cast_or_null<Expr>(VarRef)) { 4232 MarkDeclarationsReferencedInExpr(E); 4233 } 4234 } 4235 DSAStack->setForceVarCapturing(/*V=*/false); 4236 } else if (CaptureRegions.size() > 1 || 4237 CaptureRegions.back() != OMPD_unknown) { 4238 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4239 PICs.push_back(C); 4240 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4241 if (Expr *E = C->getPostUpdateExpr()) 4242 MarkDeclarationsReferencedInExpr(E); 4243 } 4244 } 4245 if (Clause->getClauseKind() == OMPC_schedule) 4246 SC = cast<OMPScheduleClause>(Clause); 4247 else if (Clause->getClauseKind() == OMPC_ordered) 4248 OC = cast<OMPOrderedClause>(Clause); 4249 else if (Clause->getClauseKind() == OMPC_linear) 4250 LCs.push_back(cast<OMPLinearClause>(Clause)); 4251 } 4252 // Capture allocator expressions if used. 4253 for (Expr *E : DSAStack->getInnerAllocators()) 4254 MarkDeclarationsReferencedInExpr(E); 4255 // OpenMP, 2.7.1 Loop Construct, Restrictions 4256 // The nonmonotonic modifier cannot be specified if an ordered clause is 4257 // specified. 4258 if (SC && 4259 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4260 SC->getSecondScheduleModifier() == 4261 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4262 OC) { 4263 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4264 ? SC->getFirstScheduleModifierLoc() 4265 : SC->getSecondScheduleModifierLoc(), 4266 diag::err_omp_simple_clause_incompatible_with_ordered) 4267 << getOpenMPClauseName(OMPC_schedule) 4268 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4269 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4270 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4271 ErrorFound = true; 4272 } 4273 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4274 // If an order(concurrent) clause is present, an ordered clause may not appear 4275 // on the same directive. 4276 if (checkOrderedOrderSpecified(*this, Clauses)) 4277 ErrorFound = true; 4278 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4279 for (const OMPLinearClause *C : LCs) { 4280 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4281 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4282 } 4283 ErrorFound = true; 4284 } 4285 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4286 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4287 OC->getNumForLoops()) { 4288 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4289 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4290 ErrorFound = true; 4291 } 4292 if (ErrorFound) { 4293 return StmtError(); 4294 } 4295 StmtResult SR = S; 4296 unsigned CompletedRegions = 0; 4297 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4298 // Mark all variables in private list clauses as used in inner region. 4299 // Required for proper codegen of combined directives. 4300 // TODO: add processing for other clauses. 4301 if (ThisCaptureRegion != OMPD_unknown) { 4302 for (const clang::OMPClauseWithPreInit *C : PICs) { 4303 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4304 // Find the particular capture region for the clause if the 4305 // directive is a combined one with multiple capture regions. 4306 // If the directive is not a combined one, the capture region 4307 // associated with the clause is OMPD_unknown and is generated 4308 // only once. 4309 if (CaptureRegion == ThisCaptureRegion || 4310 CaptureRegion == OMPD_unknown) { 4311 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4312 for (Decl *D : DS->decls()) 4313 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4314 } 4315 } 4316 } 4317 } 4318 if (++CompletedRegions == CaptureRegions.size()) 4319 DSAStack->setBodyComplete(); 4320 SR = ActOnCapturedRegionEnd(SR.get()); 4321 } 4322 return SR; 4323 } 4324 4325 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4326 OpenMPDirectiveKind CancelRegion, 4327 SourceLocation StartLoc) { 4328 // CancelRegion is only needed for cancel and cancellation_point. 4329 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4330 return false; 4331 4332 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4333 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4334 return false; 4335 4336 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4337 << getOpenMPDirectiveName(CancelRegion); 4338 return true; 4339 } 4340 4341 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4342 OpenMPDirectiveKind CurrentRegion, 4343 const DeclarationNameInfo &CurrentName, 4344 OpenMPDirectiveKind CancelRegion, 4345 SourceLocation StartLoc) { 4346 if (Stack->getCurScope()) { 4347 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4348 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4349 bool NestingProhibited = false; 4350 bool CloseNesting = true; 4351 bool OrphanSeen = false; 4352 enum { 4353 NoRecommend, 4354 ShouldBeInParallelRegion, 4355 ShouldBeInOrderedRegion, 4356 ShouldBeInTargetRegion, 4357 ShouldBeInTeamsRegion, 4358 ShouldBeInLoopSimdRegion, 4359 } Recommend = NoRecommend; 4360 if (isOpenMPSimdDirective(ParentRegion) && 4361 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4362 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4363 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4364 CurrentRegion != OMPD_scan))) { 4365 // OpenMP [2.16, Nesting of Regions] 4366 // OpenMP constructs may not be nested inside a simd region. 4367 // OpenMP [2.8.1,simd Construct, Restrictions] 4368 // An ordered construct with the simd clause is the only OpenMP 4369 // construct that can appear in the simd region. 4370 // Allowing a SIMD construct nested in another SIMD construct is an 4371 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4372 // message. 4373 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4374 // The only OpenMP constructs that can be encountered during execution of 4375 // a simd region are the atomic construct, the loop construct, the simd 4376 // construct and the ordered construct with the simd clause. 4377 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4378 ? diag::err_omp_prohibited_region_simd 4379 : diag::warn_omp_nesting_simd) 4380 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4381 return CurrentRegion != OMPD_simd; 4382 } 4383 if (ParentRegion == OMPD_atomic) { 4384 // OpenMP [2.16, Nesting of Regions] 4385 // OpenMP constructs may not be nested inside an atomic region. 4386 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4387 return true; 4388 } 4389 if (CurrentRegion == OMPD_section) { 4390 // OpenMP [2.7.2, sections Construct, Restrictions] 4391 // Orphaned section directives are prohibited. That is, the section 4392 // directives must appear within the sections construct and must not be 4393 // encountered elsewhere in the sections region. 4394 if (ParentRegion != OMPD_sections && 4395 ParentRegion != OMPD_parallel_sections) { 4396 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4397 << (ParentRegion != OMPD_unknown) 4398 << getOpenMPDirectiveName(ParentRegion); 4399 return true; 4400 } 4401 return false; 4402 } 4403 // Allow some constructs (except teams and cancellation constructs) to be 4404 // orphaned (they could be used in functions, called from OpenMP regions 4405 // with the required preconditions). 4406 if (ParentRegion == OMPD_unknown && 4407 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4408 CurrentRegion != OMPD_cancellation_point && 4409 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4410 return false; 4411 if (CurrentRegion == OMPD_cancellation_point || 4412 CurrentRegion == OMPD_cancel) { 4413 // OpenMP [2.16, Nesting of Regions] 4414 // A cancellation point construct for which construct-type-clause is 4415 // taskgroup must be nested inside a task construct. A cancellation 4416 // point construct for which construct-type-clause is not taskgroup must 4417 // be closely nested inside an OpenMP construct that matches the type 4418 // specified in construct-type-clause. 4419 // A cancel construct for which construct-type-clause is taskgroup must be 4420 // nested inside a task construct. A cancel construct for which 4421 // construct-type-clause is not taskgroup must be closely nested inside an 4422 // OpenMP construct that matches the type specified in 4423 // construct-type-clause. 4424 NestingProhibited = 4425 !((CancelRegion == OMPD_parallel && 4426 (ParentRegion == OMPD_parallel || 4427 ParentRegion == OMPD_target_parallel)) || 4428 (CancelRegion == OMPD_for && 4429 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4430 ParentRegion == OMPD_target_parallel_for || 4431 ParentRegion == OMPD_distribute_parallel_for || 4432 ParentRegion == OMPD_teams_distribute_parallel_for || 4433 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4434 (CancelRegion == OMPD_taskgroup && 4435 (ParentRegion == OMPD_task || 4436 (SemaRef.getLangOpts().OpenMP >= 50 && 4437 (ParentRegion == OMPD_taskloop || 4438 ParentRegion == OMPD_master_taskloop || 4439 ParentRegion == OMPD_parallel_master_taskloop)))) || 4440 (CancelRegion == OMPD_sections && 4441 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4442 ParentRegion == OMPD_parallel_sections))); 4443 OrphanSeen = ParentRegion == OMPD_unknown; 4444 } else if (CurrentRegion == OMPD_master) { 4445 // OpenMP [2.16, Nesting of Regions] 4446 // A master region may not be closely nested inside a worksharing, 4447 // atomic, or explicit task region. 4448 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4449 isOpenMPTaskingDirective(ParentRegion); 4450 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4451 // OpenMP [2.16, Nesting of Regions] 4452 // A critical region may not be nested (closely or otherwise) inside a 4453 // critical region with the same name. Note that this restriction is not 4454 // sufficient to prevent deadlock. 4455 SourceLocation PreviousCriticalLoc; 4456 bool DeadLock = Stack->hasDirective( 4457 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4458 const DeclarationNameInfo &DNI, 4459 SourceLocation Loc) { 4460 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4461 PreviousCriticalLoc = Loc; 4462 return true; 4463 } 4464 return false; 4465 }, 4466 false /* skip top directive */); 4467 if (DeadLock) { 4468 SemaRef.Diag(StartLoc, 4469 diag::err_omp_prohibited_region_critical_same_name) 4470 << CurrentName.getName(); 4471 if (PreviousCriticalLoc.isValid()) 4472 SemaRef.Diag(PreviousCriticalLoc, 4473 diag::note_omp_previous_critical_region); 4474 return true; 4475 } 4476 } else if (CurrentRegion == OMPD_barrier) { 4477 // OpenMP [2.16, Nesting of Regions] 4478 // A barrier region may not be closely nested inside a worksharing, 4479 // explicit task, critical, ordered, atomic, or master region. 4480 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4481 isOpenMPTaskingDirective(ParentRegion) || 4482 ParentRegion == OMPD_master || 4483 ParentRegion == OMPD_parallel_master || 4484 ParentRegion == OMPD_critical || 4485 ParentRegion == OMPD_ordered; 4486 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4487 !isOpenMPParallelDirective(CurrentRegion) && 4488 !isOpenMPTeamsDirective(CurrentRegion)) { 4489 // OpenMP [2.16, Nesting of Regions] 4490 // A worksharing region may not be closely nested inside a worksharing, 4491 // explicit task, critical, ordered, atomic, or master region. 4492 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4493 isOpenMPTaskingDirective(ParentRegion) || 4494 ParentRegion == OMPD_master || 4495 ParentRegion == OMPD_parallel_master || 4496 ParentRegion == OMPD_critical || 4497 ParentRegion == OMPD_ordered; 4498 Recommend = ShouldBeInParallelRegion; 4499 } else if (CurrentRegion == OMPD_ordered) { 4500 // OpenMP [2.16, Nesting of Regions] 4501 // An ordered region may not be closely nested inside a critical, 4502 // atomic, or explicit task region. 4503 // An ordered region must be closely nested inside a loop region (or 4504 // parallel loop region) with an ordered clause. 4505 // OpenMP [2.8.1,simd Construct, Restrictions] 4506 // An ordered construct with the simd clause is the only OpenMP construct 4507 // that can appear in the simd region. 4508 NestingProhibited = ParentRegion == OMPD_critical || 4509 isOpenMPTaskingDirective(ParentRegion) || 4510 !(isOpenMPSimdDirective(ParentRegion) || 4511 Stack->isParentOrderedRegion()); 4512 Recommend = ShouldBeInOrderedRegion; 4513 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4514 // OpenMP [2.16, Nesting of Regions] 4515 // If specified, a teams construct must be contained within a target 4516 // construct. 4517 NestingProhibited = 4518 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4519 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4520 ParentRegion != OMPD_target); 4521 OrphanSeen = ParentRegion == OMPD_unknown; 4522 Recommend = ShouldBeInTargetRegion; 4523 } else if (CurrentRegion == OMPD_scan) { 4524 // OpenMP [2.16, Nesting of Regions] 4525 // If specified, a teams construct must be contained within a target 4526 // construct. 4527 NestingProhibited = 4528 SemaRef.LangOpts.OpenMP < 50 || 4529 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4530 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4531 ParentRegion != OMPD_parallel_for_simd); 4532 OrphanSeen = ParentRegion == OMPD_unknown; 4533 Recommend = ShouldBeInLoopSimdRegion; 4534 } 4535 if (!NestingProhibited && 4536 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4537 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4538 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4539 // OpenMP [2.16, Nesting of Regions] 4540 // distribute, parallel, parallel sections, parallel workshare, and the 4541 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4542 // constructs that can be closely nested in the teams region. 4543 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4544 !isOpenMPDistributeDirective(CurrentRegion); 4545 Recommend = ShouldBeInParallelRegion; 4546 } 4547 if (!NestingProhibited && 4548 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4549 // OpenMP 4.5 [2.17 Nesting of Regions] 4550 // The region associated with the distribute construct must be strictly 4551 // nested inside a teams region 4552 NestingProhibited = 4553 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4554 Recommend = ShouldBeInTeamsRegion; 4555 } 4556 if (!NestingProhibited && 4557 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4558 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4559 // OpenMP 4.5 [2.17 Nesting of Regions] 4560 // If a target, target update, target data, target enter data, or 4561 // target exit data construct is encountered during execution of a 4562 // target region, the behavior is unspecified. 4563 NestingProhibited = Stack->hasDirective( 4564 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4565 SourceLocation) { 4566 if (isOpenMPTargetExecutionDirective(K)) { 4567 OffendingRegion = K; 4568 return true; 4569 } 4570 return false; 4571 }, 4572 false /* don't skip top directive */); 4573 CloseNesting = false; 4574 } 4575 if (NestingProhibited) { 4576 if (OrphanSeen) { 4577 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4578 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4579 } else { 4580 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4581 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4582 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4583 } 4584 return true; 4585 } 4586 } 4587 return false; 4588 } 4589 4590 struct Kind2Unsigned { 4591 using argument_type = OpenMPDirectiveKind; 4592 unsigned operator()(argument_type DK) { return unsigned(DK); } 4593 }; 4594 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4595 ArrayRef<OMPClause *> Clauses, 4596 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4597 bool ErrorFound = false; 4598 unsigned NamedModifiersNumber = 0; 4599 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4600 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); 4601 SmallVector<SourceLocation, 4> NameModifierLoc; 4602 for (const OMPClause *C : Clauses) { 4603 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4604 // At most one if clause without a directive-name-modifier can appear on 4605 // the directive. 4606 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4607 if (FoundNameModifiers[CurNM]) { 4608 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4609 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4610 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4611 ErrorFound = true; 4612 } else if (CurNM != OMPD_unknown) { 4613 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4614 ++NamedModifiersNumber; 4615 } 4616 FoundNameModifiers[CurNM] = IC; 4617 if (CurNM == OMPD_unknown) 4618 continue; 4619 // Check if the specified name modifier is allowed for the current 4620 // directive. 4621 // At most one if clause with the particular directive-name-modifier can 4622 // appear on the directive. 4623 bool MatchFound = false; 4624 for (auto NM : AllowedNameModifiers) { 4625 if (CurNM == NM) { 4626 MatchFound = true; 4627 break; 4628 } 4629 } 4630 if (!MatchFound) { 4631 S.Diag(IC->getNameModifierLoc(), 4632 diag::err_omp_wrong_if_directive_name_modifier) 4633 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4634 ErrorFound = true; 4635 } 4636 } 4637 } 4638 // If any if clause on the directive includes a directive-name-modifier then 4639 // all if clauses on the directive must include a directive-name-modifier. 4640 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4641 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4642 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4643 diag::err_omp_no_more_if_clause); 4644 } else { 4645 std::string Values; 4646 std::string Sep(", "); 4647 unsigned AllowedCnt = 0; 4648 unsigned TotalAllowedNum = 4649 AllowedNameModifiers.size() - NamedModifiersNumber; 4650 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4651 ++Cnt) { 4652 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4653 if (!FoundNameModifiers[NM]) { 4654 Values += "'"; 4655 Values += getOpenMPDirectiveName(NM); 4656 Values += "'"; 4657 if (AllowedCnt + 2 == TotalAllowedNum) 4658 Values += " or "; 4659 else if (AllowedCnt + 1 != TotalAllowedNum) 4660 Values += Sep; 4661 ++AllowedCnt; 4662 } 4663 } 4664 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4665 diag::err_omp_unnamed_if_clause) 4666 << (TotalAllowedNum > 1) << Values; 4667 } 4668 for (SourceLocation Loc : NameModifierLoc) { 4669 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4670 } 4671 ErrorFound = true; 4672 } 4673 return ErrorFound; 4674 } 4675 4676 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4677 SourceLocation &ELoc, 4678 SourceRange &ERange, 4679 bool AllowArraySection) { 4680 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4681 RefExpr->containsUnexpandedParameterPack()) 4682 return std::make_pair(nullptr, true); 4683 4684 // OpenMP [3.1, C/C++] 4685 // A list item is a variable name. 4686 // OpenMP [2.9.3.3, Restrictions, p.1] 4687 // A variable that is part of another variable (as an array or 4688 // structure element) cannot appear in a private clause. 4689 RefExpr = RefExpr->IgnoreParens(); 4690 enum { 4691 NoArrayExpr = -1, 4692 ArraySubscript = 0, 4693 OMPArraySection = 1 4694 } IsArrayExpr = NoArrayExpr; 4695 if (AllowArraySection) { 4696 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4697 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4698 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4699 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4700 RefExpr = Base; 4701 IsArrayExpr = ArraySubscript; 4702 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4703 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4704 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4705 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4706 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4707 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4708 RefExpr = Base; 4709 IsArrayExpr = OMPArraySection; 4710 } 4711 } 4712 ELoc = RefExpr->getExprLoc(); 4713 ERange = RefExpr->getSourceRange(); 4714 RefExpr = RefExpr->IgnoreParenImpCasts(); 4715 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4716 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4717 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4718 (S.getCurrentThisType().isNull() || !ME || 4719 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4720 !isa<FieldDecl>(ME->getMemberDecl()))) { 4721 if (IsArrayExpr != NoArrayExpr) { 4722 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4723 << ERange; 4724 } else { 4725 S.Diag(ELoc, 4726 AllowArraySection 4727 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4728 : diag::err_omp_expected_var_name_member_expr) 4729 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4730 } 4731 return std::make_pair(nullptr, false); 4732 } 4733 return std::make_pair( 4734 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4735 } 4736 4737 namespace { 4738 /// Checks if the allocator is used in uses_allocators clause to be allowed in 4739 /// target regions. 4740 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 4741 DSAStackTy *S = nullptr; 4742 4743 public: 4744 bool VisitDeclRefExpr(const DeclRefExpr *E) { 4745 return !S->isUsesAllocatorsDecl(E->getDecl()); 4746 } 4747 bool VisitStmt(const Stmt *S) { 4748 for (const Stmt *Child : S->children()) { 4749 if (Child && Visit(Child)) 4750 return true; 4751 } 4752 return false; 4753 } 4754 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 4755 }; 4756 } // namespace 4757 4758 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4759 ArrayRef<OMPClause *> Clauses) { 4760 assert(!S.CurContext->isDependentContext() && 4761 "Expected non-dependent context."); 4762 auto AllocateRange = 4763 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4764 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4765 DeclToCopy; 4766 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4767 return isOpenMPPrivate(C->getClauseKind()); 4768 }); 4769 for (OMPClause *Cl : PrivateRange) { 4770 MutableArrayRef<Expr *>::iterator I, It, Et; 4771 if (Cl->getClauseKind() == OMPC_private) { 4772 auto *PC = cast<OMPPrivateClause>(Cl); 4773 I = PC->private_copies().begin(); 4774 It = PC->varlist_begin(); 4775 Et = PC->varlist_end(); 4776 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4777 auto *PC = cast<OMPFirstprivateClause>(Cl); 4778 I = PC->private_copies().begin(); 4779 It = PC->varlist_begin(); 4780 Et = PC->varlist_end(); 4781 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4782 auto *PC = cast<OMPLastprivateClause>(Cl); 4783 I = PC->private_copies().begin(); 4784 It = PC->varlist_begin(); 4785 Et = PC->varlist_end(); 4786 } else if (Cl->getClauseKind() == OMPC_linear) { 4787 auto *PC = cast<OMPLinearClause>(Cl); 4788 I = PC->privates().begin(); 4789 It = PC->varlist_begin(); 4790 Et = PC->varlist_end(); 4791 } else if (Cl->getClauseKind() == OMPC_reduction) { 4792 auto *PC = cast<OMPReductionClause>(Cl); 4793 I = PC->privates().begin(); 4794 It = PC->varlist_begin(); 4795 Et = PC->varlist_end(); 4796 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4797 auto *PC = cast<OMPTaskReductionClause>(Cl); 4798 I = PC->privates().begin(); 4799 It = PC->varlist_begin(); 4800 Et = PC->varlist_end(); 4801 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4802 auto *PC = cast<OMPInReductionClause>(Cl); 4803 I = PC->privates().begin(); 4804 It = PC->varlist_begin(); 4805 Et = PC->varlist_end(); 4806 } else { 4807 llvm_unreachable("Expected private clause."); 4808 } 4809 for (Expr *E : llvm::make_range(It, Et)) { 4810 if (!*I) { 4811 ++I; 4812 continue; 4813 } 4814 SourceLocation ELoc; 4815 SourceRange ERange; 4816 Expr *SimpleRefExpr = E; 4817 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4818 /*AllowArraySection=*/true); 4819 DeclToCopy.try_emplace(Res.first, 4820 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4821 ++I; 4822 } 4823 } 4824 for (OMPClause *C : AllocateRange) { 4825 auto *AC = cast<OMPAllocateClause>(C); 4826 if (S.getLangOpts().OpenMP >= 50 && 4827 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 4828 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 4829 AC->getAllocator()) { 4830 Expr *Allocator = AC->getAllocator(); 4831 // OpenMP, 2.12.5 target Construct 4832 // Memory allocators that do not appear in a uses_allocators clause cannot 4833 // appear as an allocator in an allocate clause or be used in the target 4834 // region unless a requires directive with the dynamic_allocators clause 4835 // is present in the same compilation unit. 4836 AllocatorChecker Checker(Stack); 4837 if (Checker.Visit(Allocator)) 4838 S.Diag(Allocator->getExprLoc(), 4839 diag::err_omp_allocator_not_in_uses_allocators) 4840 << Allocator->getSourceRange(); 4841 } 4842 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4843 getAllocatorKind(S, Stack, AC->getAllocator()); 4844 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4845 // For task, taskloop or target directives, allocation requests to memory 4846 // allocators with the trait access set to thread result in unspecified 4847 // behavior. 4848 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4849 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4850 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4851 S.Diag(AC->getAllocator()->getExprLoc(), 4852 diag::warn_omp_allocate_thread_on_task_target_directive) 4853 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4854 } 4855 for (Expr *E : AC->varlists()) { 4856 SourceLocation ELoc; 4857 SourceRange ERange; 4858 Expr *SimpleRefExpr = E; 4859 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4860 ValueDecl *VD = Res.first; 4861 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4862 if (!isOpenMPPrivate(Data.CKind)) { 4863 S.Diag(E->getExprLoc(), 4864 diag::err_omp_expected_private_copy_for_allocate); 4865 continue; 4866 } 4867 VarDecl *PrivateVD = DeclToCopy[VD]; 4868 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4869 AllocatorKind, AC->getAllocator())) 4870 continue; 4871 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4872 E->getSourceRange()); 4873 } 4874 } 4875 } 4876 4877 StmtResult Sema::ActOnOpenMPExecutableDirective( 4878 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4879 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4880 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4881 StmtResult Res = StmtError(); 4882 // First check CancelRegion which is then used in checkNestingOfRegions. 4883 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4884 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4885 StartLoc)) 4886 return StmtError(); 4887 4888 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4889 VarsWithInheritedDSAType VarsWithInheritedDSA; 4890 bool ErrorFound = false; 4891 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4892 if (AStmt && !CurContext->isDependentContext()) { 4893 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4894 4895 // Check default data sharing attributes for referenced variables. 4896 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4897 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4898 Stmt *S = AStmt; 4899 while (--ThisCaptureLevel >= 0) 4900 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4901 DSAChecker.Visit(S); 4902 if (!isOpenMPTargetDataManagementDirective(Kind) && 4903 !isOpenMPTaskingDirective(Kind)) { 4904 // Visit subcaptures to generate implicit clauses for captured vars. 4905 auto *CS = cast<CapturedStmt>(AStmt); 4906 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4907 getOpenMPCaptureRegions(CaptureRegions, Kind); 4908 // Ignore outer tasking regions for target directives. 4909 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4910 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4911 DSAChecker.visitSubCaptures(CS); 4912 } 4913 if (DSAChecker.isErrorFound()) 4914 return StmtError(); 4915 // Generate list of implicitly defined firstprivate variables. 4916 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4917 4918 SmallVector<Expr *, 4> ImplicitFirstprivates( 4919 DSAChecker.getImplicitFirstprivate().begin(), 4920 DSAChecker.getImplicitFirstprivate().end()); 4921 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4922 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4923 ArrayRef<Expr *> ImplicitMap = 4924 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4925 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4926 } 4927 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4928 for (OMPClause *C : Clauses) { 4929 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4930 for (Expr *E : IRC->taskgroup_descriptors()) 4931 if (E) 4932 ImplicitFirstprivates.emplace_back(E); 4933 } 4934 // OpenMP 5.0, 2.10.1 task Construct 4935 // [detach clause]... The event-handle will be considered as if it was 4936 // specified on a firstprivate clause. 4937 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 4938 ImplicitFirstprivates.push_back(DC->getEventHandler()); 4939 } 4940 if (!ImplicitFirstprivates.empty()) { 4941 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4942 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4943 SourceLocation())) { 4944 ClausesWithImplicit.push_back(Implicit); 4945 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4946 ImplicitFirstprivates.size(); 4947 } else { 4948 ErrorFound = true; 4949 } 4950 } 4951 int ClauseKindCnt = -1; 4952 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4953 ++ClauseKindCnt; 4954 if (ImplicitMap.empty()) 4955 continue; 4956 CXXScopeSpec MapperIdScopeSpec; 4957 DeclarationNameInfo MapperId; 4958 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 4959 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4960 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 4961 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 4962 ImplicitMap, OMPVarListLocTy())) { 4963 ClausesWithImplicit.emplace_back(Implicit); 4964 ErrorFound |= 4965 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 4966 } else { 4967 ErrorFound = true; 4968 } 4969 } 4970 } 4971 4972 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4973 switch (Kind) { 4974 case OMPD_parallel: 4975 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4976 EndLoc); 4977 AllowedNameModifiers.push_back(OMPD_parallel); 4978 break; 4979 case OMPD_simd: 4980 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4981 VarsWithInheritedDSA); 4982 if (LangOpts.OpenMP >= 50) 4983 AllowedNameModifiers.push_back(OMPD_simd); 4984 break; 4985 case OMPD_for: 4986 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4987 VarsWithInheritedDSA); 4988 break; 4989 case OMPD_for_simd: 4990 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4991 EndLoc, VarsWithInheritedDSA); 4992 if (LangOpts.OpenMP >= 50) 4993 AllowedNameModifiers.push_back(OMPD_simd); 4994 break; 4995 case OMPD_sections: 4996 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4997 EndLoc); 4998 break; 4999 case OMPD_section: 5000 assert(ClausesWithImplicit.empty() && 5001 "No clauses are allowed for 'omp section' directive"); 5002 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 5003 break; 5004 case OMPD_single: 5005 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 5006 EndLoc); 5007 break; 5008 case OMPD_master: 5009 assert(ClausesWithImplicit.empty() && 5010 "No clauses are allowed for 'omp master' directive"); 5011 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 5012 break; 5013 case OMPD_critical: 5014 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 5015 StartLoc, EndLoc); 5016 break; 5017 case OMPD_parallel_for: 5018 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 5019 EndLoc, VarsWithInheritedDSA); 5020 AllowedNameModifiers.push_back(OMPD_parallel); 5021 break; 5022 case OMPD_parallel_for_simd: 5023 Res = ActOnOpenMPParallelForSimdDirective( 5024 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5025 AllowedNameModifiers.push_back(OMPD_parallel); 5026 if (LangOpts.OpenMP >= 50) 5027 AllowedNameModifiers.push_back(OMPD_simd); 5028 break; 5029 case OMPD_parallel_master: 5030 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 5031 StartLoc, EndLoc); 5032 AllowedNameModifiers.push_back(OMPD_parallel); 5033 break; 5034 case OMPD_parallel_sections: 5035 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 5036 StartLoc, EndLoc); 5037 AllowedNameModifiers.push_back(OMPD_parallel); 5038 break; 5039 case OMPD_task: 5040 Res = 5041 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5042 AllowedNameModifiers.push_back(OMPD_task); 5043 break; 5044 case OMPD_taskyield: 5045 assert(ClausesWithImplicit.empty() && 5046 "No clauses are allowed for 'omp taskyield' directive"); 5047 assert(AStmt == nullptr && 5048 "No associated statement allowed for 'omp taskyield' directive"); 5049 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 5050 break; 5051 case OMPD_barrier: 5052 assert(ClausesWithImplicit.empty() && 5053 "No clauses are allowed for 'omp barrier' directive"); 5054 assert(AStmt == nullptr && 5055 "No associated statement allowed for 'omp barrier' directive"); 5056 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 5057 break; 5058 case OMPD_taskwait: 5059 assert(ClausesWithImplicit.empty() && 5060 "No clauses are allowed for 'omp taskwait' directive"); 5061 assert(AStmt == nullptr && 5062 "No associated statement allowed for 'omp taskwait' directive"); 5063 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 5064 break; 5065 case OMPD_taskgroup: 5066 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 5067 EndLoc); 5068 break; 5069 case OMPD_flush: 5070 assert(AStmt == nullptr && 5071 "No associated statement allowed for 'omp flush' directive"); 5072 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 5073 break; 5074 case OMPD_depobj: 5075 assert(AStmt == nullptr && 5076 "No associated statement allowed for 'omp depobj' directive"); 5077 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 5078 break; 5079 case OMPD_scan: 5080 assert(AStmt == nullptr && 5081 "No associated statement allowed for 'omp scan' directive"); 5082 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 5083 break; 5084 case OMPD_ordered: 5085 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 5086 EndLoc); 5087 break; 5088 case OMPD_atomic: 5089 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 5090 EndLoc); 5091 break; 5092 case OMPD_teams: 5093 Res = 5094 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5095 break; 5096 case OMPD_target: 5097 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 5098 EndLoc); 5099 AllowedNameModifiers.push_back(OMPD_target); 5100 break; 5101 case OMPD_target_parallel: 5102 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 5103 StartLoc, EndLoc); 5104 AllowedNameModifiers.push_back(OMPD_target); 5105 AllowedNameModifiers.push_back(OMPD_parallel); 5106 break; 5107 case OMPD_target_parallel_for: 5108 Res = ActOnOpenMPTargetParallelForDirective( 5109 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5110 AllowedNameModifiers.push_back(OMPD_target); 5111 AllowedNameModifiers.push_back(OMPD_parallel); 5112 break; 5113 case OMPD_cancellation_point: 5114 assert(ClausesWithImplicit.empty() && 5115 "No clauses are allowed for 'omp cancellation point' directive"); 5116 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 5117 "cancellation point' directive"); 5118 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 5119 break; 5120 case OMPD_cancel: 5121 assert(AStmt == nullptr && 5122 "No associated statement allowed for 'omp cancel' directive"); 5123 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 5124 CancelRegion); 5125 AllowedNameModifiers.push_back(OMPD_cancel); 5126 break; 5127 case OMPD_target_data: 5128 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 5129 EndLoc); 5130 AllowedNameModifiers.push_back(OMPD_target_data); 5131 break; 5132 case OMPD_target_enter_data: 5133 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 5134 EndLoc, AStmt); 5135 AllowedNameModifiers.push_back(OMPD_target_enter_data); 5136 break; 5137 case OMPD_target_exit_data: 5138 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 5139 EndLoc, AStmt); 5140 AllowedNameModifiers.push_back(OMPD_target_exit_data); 5141 break; 5142 case OMPD_taskloop: 5143 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 5144 EndLoc, VarsWithInheritedDSA); 5145 AllowedNameModifiers.push_back(OMPD_taskloop); 5146 break; 5147 case OMPD_taskloop_simd: 5148 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5149 EndLoc, VarsWithInheritedDSA); 5150 AllowedNameModifiers.push_back(OMPD_taskloop); 5151 if (LangOpts.OpenMP >= 50) 5152 AllowedNameModifiers.push_back(OMPD_simd); 5153 break; 5154 case OMPD_master_taskloop: 5155 Res = ActOnOpenMPMasterTaskLoopDirective( 5156 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5157 AllowedNameModifiers.push_back(OMPD_taskloop); 5158 break; 5159 case OMPD_master_taskloop_simd: 5160 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 5161 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5162 AllowedNameModifiers.push_back(OMPD_taskloop); 5163 if (LangOpts.OpenMP >= 50) 5164 AllowedNameModifiers.push_back(OMPD_simd); 5165 break; 5166 case OMPD_parallel_master_taskloop: 5167 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 5168 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5169 AllowedNameModifiers.push_back(OMPD_taskloop); 5170 AllowedNameModifiers.push_back(OMPD_parallel); 5171 break; 5172 case OMPD_parallel_master_taskloop_simd: 5173 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 5174 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5175 AllowedNameModifiers.push_back(OMPD_taskloop); 5176 AllowedNameModifiers.push_back(OMPD_parallel); 5177 if (LangOpts.OpenMP >= 50) 5178 AllowedNameModifiers.push_back(OMPD_simd); 5179 break; 5180 case OMPD_distribute: 5181 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 5182 EndLoc, VarsWithInheritedDSA); 5183 break; 5184 case OMPD_target_update: 5185 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 5186 EndLoc, AStmt); 5187 AllowedNameModifiers.push_back(OMPD_target_update); 5188 break; 5189 case OMPD_distribute_parallel_for: 5190 Res = ActOnOpenMPDistributeParallelForDirective( 5191 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5192 AllowedNameModifiers.push_back(OMPD_parallel); 5193 break; 5194 case OMPD_distribute_parallel_for_simd: 5195 Res = ActOnOpenMPDistributeParallelForSimdDirective( 5196 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5197 AllowedNameModifiers.push_back(OMPD_parallel); 5198 if (LangOpts.OpenMP >= 50) 5199 AllowedNameModifiers.push_back(OMPD_simd); 5200 break; 5201 case OMPD_distribute_simd: 5202 Res = ActOnOpenMPDistributeSimdDirective( 5203 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5204 if (LangOpts.OpenMP >= 50) 5205 AllowedNameModifiers.push_back(OMPD_simd); 5206 break; 5207 case OMPD_target_parallel_for_simd: 5208 Res = ActOnOpenMPTargetParallelForSimdDirective( 5209 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5210 AllowedNameModifiers.push_back(OMPD_target); 5211 AllowedNameModifiers.push_back(OMPD_parallel); 5212 if (LangOpts.OpenMP >= 50) 5213 AllowedNameModifiers.push_back(OMPD_simd); 5214 break; 5215 case OMPD_target_simd: 5216 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5217 EndLoc, VarsWithInheritedDSA); 5218 AllowedNameModifiers.push_back(OMPD_target); 5219 if (LangOpts.OpenMP >= 50) 5220 AllowedNameModifiers.push_back(OMPD_simd); 5221 break; 5222 case OMPD_teams_distribute: 5223 Res = ActOnOpenMPTeamsDistributeDirective( 5224 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5225 break; 5226 case OMPD_teams_distribute_simd: 5227 Res = ActOnOpenMPTeamsDistributeSimdDirective( 5228 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5229 if (LangOpts.OpenMP >= 50) 5230 AllowedNameModifiers.push_back(OMPD_simd); 5231 break; 5232 case OMPD_teams_distribute_parallel_for_simd: 5233 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 5234 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5235 AllowedNameModifiers.push_back(OMPD_parallel); 5236 if (LangOpts.OpenMP >= 50) 5237 AllowedNameModifiers.push_back(OMPD_simd); 5238 break; 5239 case OMPD_teams_distribute_parallel_for: 5240 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 5241 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5242 AllowedNameModifiers.push_back(OMPD_parallel); 5243 break; 5244 case OMPD_target_teams: 5245 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 5246 EndLoc); 5247 AllowedNameModifiers.push_back(OMPD_target); 5248 break; 5249 case OMPD_target_teams_distribute: 5250 Res = ActOnOpenMPTargetTeamsDistributeDirective( 5251 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5252 AllowedNameModifiers.push_back(OMPD_target); 5253 break; 5254 case OMPD_target_teams_distribute_parallel_for: 5255 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 5256 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5257 AllowedNameModifiers.push_back(OMPD_target); 5258 AllowedNameModifiers.push_back(OMPD_parallel); 5259 break; 5260 case OMPD_target_teams_distribute_parallel_for_simd: 5261 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 5262 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5263 AllowedNameModifiers.push_back(OMPD_target); 5264 AllowedNameModifiers.push_back(OMPD_parallel); 5265 if (LangOpts.OpenMP >= 50) 5266 AllowedNameModifiers.push_back(OMPD_simd); 5267 break; 5268 case OMPD_target_teams_distribute_simd: 5269 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 5270 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5271 AllowedNameModifiers.push_back(OMPD_target); 5272 if (LangOpts.OpenMP >= 50) 5273 AllowedNameModifiers.push_back(OMPD_simd); 5274 break; 5275 case OMPD_declare_target: 5276 case OMPD_end_declare_target: 5277 case OMPD_threadprivate: 5278 case OMPD_allocate: 5279 case OMPD_declare_reduction: 5280 case OMPD_declare_mapper: 5281 case OMPD_declare_simd: 5282 case OMPD_requires: 5283 case OMPD_declare_variant: 5284 case OMPD_begin_declare_variant: 5285 case OMPD_end_declare_variant: 5286 llvm_unreachable("OpenMP Directive is not allowed"); 5287 case OMPD_unknown: 5288 llvm_unreachable("Unknown OpenMP directive"); 5289 } 5290 5291 ErrorFound = Res.isInvalid() || ErrorFound; 5292 5293 // Check variables in the clauses if default(none) was specified. 5294 if (DSAStack->getDefaultDSA() == DSA_none) { 5295 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 5296 for (OMPClause *C : Clauses) { 5297 switch (C->getClauseKind()) { 5298 case OMPC_num_threads: 5299 case OMPC_dist_schedule: 5300 // Do not analyse if no parent teams directive. 5301 if (isOpenMPTeamsDirective(Kind)) 5302 break; 5303 continue; 5304 case OMPC_if: 5305 if (isOpenMPTeamsDirective(Kind) && 5306 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 5307 break; 5308 if (isOpenMPParallelDirective(Kind) && 5309 isOpenMPTaskLoopDirective(Kind) && 5310 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 5311 break; 5312 continue; 5313 case OMPC_schedule: 5314 case OMPC_detach: 5315 break; 5316 case OMPC_grainsize: 5317 case OMPC_num_tasks: 5318 case OMPC_final: 5319 case OMPC_priority: 5320 // Do not analyze if no parent parallel directive. 5321 if (isOpenMPParallelDirective(Kind)) 5322 break; 5323 continue; 5324 case OMPC_ordered: 5325 case OMPC_device: 5326 case OMPC_num_teams: 5327 case OMPC_thread_limit: 5328 case OMPC_hint: 5329 case OMPC_collapse: 5330 case OMPC_safelen: 5331 case OMPC_simdlen: 5332 case OMPC_default: 5333 case OMPC_proc_bind: 5334 case OMPC_private: 5335 case OMPC_firstprivate: 5336 case OMPC_lastprivate: 5337 case OMPC_shared: 5338 case OMPC_reduction: 5339 case OMPC_task_reduction: 5340 case OMPC_in_reduction: 5341 case OMPC_linear: 5342 case OMPC_aligned: 5343 case OMPC_copyin: 5344 case OMPC_copyprivate: 5345 case OMPC_nowait: 5346 case OMPC_untied: 5347 case OMPC_mergeable: 5348 case OMPC_allocate: 5349 case OMPC_read: 5350 case OMPC_write: 5351 case OMPC_update: 5352 case OMPC_capture: 5353 case OMPC_seq_cst: 5354 case OMPC_acq_rel: 5355 case OMPC_acquire: 5356 case OMPC_release: 5357 case OMPC_relaxed: 5358 case OMPC_depend: 5359 case OMPC_threads: 5360 case OMPC_simd: 5361 case OMPC_map: 5362 case OMPC_nogroup: 5363 case OMPC_defaultmap: 5364 case OMPC_to: 5365 case OMPC_from: 5366 case OMPC_use_device_ptr: 5367 case OMPC_is_device_ptr: 5368 case OMPC_nontemporal: 5369 case OMPC_order: 5370 case OMPC_destroy: 5371 case OMPC_inclusive: 5372 case OMPC_exclusive: 5373 case OMPC_uses_allocators: 5374 continue; 5375 case OMPC_allocator: 5376 case OMPC_flush: 5377 case OMPC_depobj: 5378 case OMPC_threadprivate: 5379 case OMPC_uniform: 5380 case OMPC_unknown: 5381 case OMPC_unified_address: 5382 case OMPC_unified_shared_memory: 5383 case OMPC_reverse_offload: 5384 case OMPC_dynamic_allocators: 5385 case OMPC_atomic_default_mem_order: 5386 case OMPC_device_type: 5387 case OMPC_match: 5388 llvm_unreachable("Unexpected clause"); 5389 } 5390 for (Stmt *CC : C->children()) { 5391 if (CC) 5392 DSAChecker.Visit(CC); 5393 } 5394 } 5395 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5396 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5397 } 5398 for (const auto &P : VarsWithInheritedDSA) { 5399 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5400 continue; 5401 ErrorFound = true; 5402 if (DSAStack->getDefaultDSA() == DSA_none) { 5403 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5404 << P.first << P.second->getSourceRange(); 5405 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5406 } else if (getLangOpts().OpenMP >= 50) { 5407 Diag(P.second->getExprLoc(), 5408 diag::err_omp_defaultmap_no_attr_for_variable) 5409 << P.first << P.second->getSourceRange(); 5410 Diag(DSAStack->getDefaultDSALocation(), 5411 diag::note_omp_defaultmap_attr_none); 5412 } 5413 } 5414 5415 if (!AllowedNameModifiers.empty()) 5416 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5417 ErrorFound; 5418 5419 if (ErrorFound) 5420 return StmtError(); 5421 5422 if (!CurContext->isDependentContext() && 5423 isOpenMPTargetExecutionDirective(Kind) && 5424 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5425 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5426 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5427 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5428 // Register target to DSA Stack. 5429 DSAStack->addTargetDirLocation(StartLoc); 5430 } 5431 5432 return Res; 5433 } 5434 5435 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5436 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5437 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5438 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5439 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5440 assert(Aligneds.size() == Alignments.size()); 5441 assert(Linears.size() == LinModifiers.size()); 5442 assert(Linears.size() == Steps.size()); 5443 if (!DG || DG.get().isNull()) 5444 return DeclGroupPtrTy(); 5445 5446 const int SimdId = 0; 5447 if (!DG.get().isSingleDecl()) { 5448 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5449 << SimdId; 5450 return DG; 5451 } 5452 Decl *ADecl = DG.get().getSingleDecl(); 5453 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5454 ADecl = FTD->getTemplatedDecl(); 5455 5456 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5457 if (!FD) { 5458 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5459 return DeclGroupPtrTy(); 5460 } 5461 5462 // OpenMP [2.8.2, declare simd construct, Description] 5463 // The parameter of the simdlen clause must be a constant positive integer 5464 // expression. 5465 ExprResult SL; 5466 if (Simdlen) 5467 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5468 // OpenMP [2.8.2, declare simd construct, Description] 5469 // The special this pointer can be used as if was one of the arguments to the 5470 // function in any of the linear, aligned, or uniform clauses. 5471 // The uniform clause declares one or more arguments to have an invariant 5472 // value for all concurrent invocations of the function in the execution of a 5473 // single SIMD loop. 5474 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5475 const Expr *UniformedLinearThis = nullptr; 5476 for (const Expr *E : Uniforms) { 5477 E = E->IgnoreParenImpCasts(); 5478 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5479 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5480 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5481 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5482 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5483 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5484 continue; 5485 } 5486 if (isa<CXXThisExpr>(E)) { 5487 UniformedLinearThis = E; 5488 continue; 5489 } 5490 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5491 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5492 } 5493 // OpenMP [2.8.2, declare simd construct, Description] 5494 // The aligned clause declares that the object to which each list item points 5495 // is aligned to the number of bytes expressed in the optional parameter of 5496 // the aligned clause. 5497 // The special this pointer can be used as if was one of the arguments to the 5498 // function in any of the linear, aligned, or uniform clauses. 5499 // The type of list items appearing in the aligned clause must be array, 5500 // pointer, reference to array, or reference to pointer. 5501 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5502 const Expr *AlignedThis = nullptr; 5503 for (const Expr *E : Aligneds) { 5504 E = E->IgnoreParenImpCasts(); 5505 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5506 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5507 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5508 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5509 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5510 ->getCanonicalDecl() == CanonPVD) { 5511 // OpenMP [2.8.1, simd construct, Restrictions] 5512 // A list-item cannot appear in more than one aligned clause. 5513 if (AlignedArgs.count(CanonPVD) > 0) { 5514 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5515 << 1 << getOpenMPClauseName(OMPC_aligned) 5516 << E->getSourceRange(); 5517 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5518 diag::note_omp_explicit_dsa) 5519 << getOpenMPClauseName(OMPC_aligned); 5520 continue; 5521 } 5522 AlignedArgs[CanonPVD] = E; 5523 QualType QTy = PVD->getType() 5524 .getNonReferenceType() 5525 .getUnqualifiedType() 5526 .getCanonicalType(); 5527 const Type *Ty = QTy.getTypePtrOrNull(); 5528 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5529 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5530 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5531 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5532 } 5533 continue; 5534 } 5535 } 5536 if (isa<CXXThisExpr>(E)) { 5537 if (AlignedThis) { 5538 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5539 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5540 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5541 << getOpenMPClauseName(OMPC_aligned); 5542 } 5543 AlignedThis = E; 5544 continue; 5545 } 5546 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5547 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5548 } 5549 // The optional parameter of the aligned clause, alignment, must be a constant 5550 // positive integer expression. If no optional parameter is specified, 5551 // implementation-defined default alignments for SIMD instructions on the 5552 // target platforms are assumed. 5553 SmallVector<const Expr *, 4> NewAligns; 5554 for (Expr *E : Alignments) { 5555 ExprResult Align; 5556 if (E) 5557 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5558 NewAligns.push_back(Align.get()); 5559 } 5560 // OpenMP [2.8.2, declare simd construct, Description] 5561 // The linear clause declares one or more list items to be private to a SIMD 5562 // lane and to have a linear relationship with respect to the iteration space 5563 // of a loop. 5564 // The special this pointer can be used as if was one of the arguments to the 5565 // function in any of the linear, aligned, or uniform clauses. 5566 // When a linear-step expression is specified in a linear clause it must be 5567 // either a constant integer expression or an integer-typed parameter that is 5568 // specified in a uniform clause on the directive. 5569 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5570 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5571 auto MI = LinModifiers.begin(); 5572 for (const Expr *E : Linears) { 5573 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5574 ++MI; 5575 E = E->IgnoreParenImpCasts(); 5576 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5577 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5578 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5579 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5580 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5581 ->getCanonicalDecl() == CanonPVD) { 5582 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5583 // A list-item cannot appear in more than one linear clause. 5584 if (LinearArgs.count(CanonPVD) > 0) { 5585 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5586 << getOpenMPClauseName(OMPC_linear) 5587 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5588 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5589 diag::note_omp_explicit_dsa) 5590 << getOpenMPClauseName(OMPC_linear); 5591 continue; 5592 } 5593 // Each argument can appear in at most one uniform or linear clause. 5594 if (UniformedArgs.count(CanonPVD) > 0) { 5595 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5596 << getOpenMPClauseName(OMPC_linear) 5597 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5598 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5599 diag::note_omp_explicit_dsa) 5600 << getOpenMPClauseName(OMPC_uniform); 5601 continue; 5602 } 5603 LinearArgs[CanonPVD] = E; 5604 if (E->isValueDependent() || E->isTypeDependent() || 5605 E->isInstantiationDependent() || 5606 E->containsUnexpandedParameterPack()) 5607 continue; 5608 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5609 PVD->getOriginalType(), 5610 /*IsDeclareSimd=*/true); 5611 continue; 5612 } 5613 } 5614 if (isa<CXXThisExpr>(E)) { 5615 if (UniformedLinearThis) { 5616 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5617 << getOpenMPClauseName(OMPC_linear) 5618 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5619 << E->getSourceRange(); 5620 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5621 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5622 : OMPC_linear); 5623 continue; 5624 } 5625 UniformedLinearThis = E; 5626 if (E->isValueDependent() || E->isTypeDependent() || 5627 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5628 continue; 5629 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5630 E->getType(), /*IsDeclareSimd=*/true); 5631 continue; 5632 } 5633 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5634 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5635 } 5636 Expr *Step = nullptr; 5637 Expr *NewStep = nullptr; 5638 SmallVector<Expr *, 4> NewSteps; 5639 for (Expr *E : Steps) { 5640 // Skip the same step expression, it was checked already. 5641 if (Step == E || !E) { 5642 NewSteps.push_back(E ? NewStep : nullptr); 5643 continue; 5644 } 5645 Step = E; 5646 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5647 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5648 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5649 if (UniformedArgs.count(CanonPVD) == 0) { 5650 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5651 << Step->getSourceRange(); 5652 } else if (E->isValueDependent() || E->isTypeDependent() || 5653 E->isInstantiationDependent() || 5654 E->containsUnexpandedParameterPack() || 5655 CanonPVD->getType()->hasIntegerRepresentation()) { 5656 NewSteps.push_back(Step); 5657 } else { 5658 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5659 << Step->getSourceRange(); 5660 } 5661 continue; 5662 } 5663 NewStep = Step; 5664 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5665 !Step->isInstantiationDependent() && 5666 !Step->containsUnexpandedParameterPack()) { 5667 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5668 .get(); 5669 if (NewStep) 5670 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5671 } 5672 NewSteps.push_back(NewStep); 5673 } 5674 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5675 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5676 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5677 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5678 const_cast<Expr **>(Linears.data()), Linears.size(), 5679 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5680 NewSteps.data(), NewSteps.size(), SR); 5681 ADecl->addAttr(NewAttr); 5682 return DG; 5683 } 5684 5685 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5686 QualType NewType) { 5687 assert(NewType->isFunctionProtoType() && 5688 "Expected function type with prototype."); 5689 assert(FD->getType()->isFunctionNoProtoType() && 5690 "Expected function with type with no prototype."); 5691 assert(FDWithProto->getType()->isFunctionProtoType() && 5692 "Expected function with prototype."); 5693 // Synthesize parameters with the same types. 5694 FD->setType(NewType); 5695 SmallVector<ParmVarDecl *, 16> Params; 5696 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5697 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5698 SourceLocation(), nullptr, P->getType(), 5699 /*TInfo=*/nullptr, SC_None, nullptr); 5700 Param->setScopeInfo(0, Params.size()); 5701 Param->setImplicit(); 5702 Params.push_back(Param); 5703 } 5704 5705 FD->setParams(Params); 5706 } 5707 5708 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 5709 : TI(&TI), NameSuffix(TI.getMangledName()) {} 5710 5711 FunctionDecl * 5712 Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, 5713 Declarator &D) { 5714 IdentifierInfo *BaseII = D.getIdentifier(); 5715 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 5716 LookupOrdinaryName); 5717 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 5718 5719 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 5720 QualType FType = TInfo->getType(); 5721 5722 bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr; 5723 bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval; 5724 5725 FunctionDecl *BaseFD = nullptr; 5726 for (auto *Candidate : Lookup) { 5727 auto *UDecl = dyn_cast<FunctionDecl>(Candidate->getUnderlyingDecl()); 5728 if (!UDecl) 5729 continue; 5730 5731 // Don't specialize constexpr/consteval functions with 5732 // non-constexpr/consteval functions. 5733 if (UDecl->isConstexpr() && !IsConstexpr) 5734 continue; 5735 if (UDecl->isConsteval() && !IsConsteval) 5736 continue; 5737 5738 QualType NewType = Context.mergeFunctionTypes( 5739 FType, UDecl->getType(), /* OfBlockPointer */ false, 5740 /* Unqualified */ false, /* AllowCXX */ true); 5741 if (NewType.isNull()) 5742 continue; 5743 5744 // Found a base! 5745 BaseFD = UDecl; 5746 break; 5747 } 5748 if (!BaseFD) { 5749 BaseFD = cast<FunctionDecl>(ActOnDeclarator(S, D)); 5750 BaseFD->setImplicit(true); 5751 } 5752 5753 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5754 std::string MangledName; 5755 MangledName += D.getIdentifier()->getName(); 5756 MangledName += getOpenMPVariantManglingSeparatorStr(); 5757 MangledName += DVScope.NameSuffix; 5758 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 5759 5760 VariantII.setMangledOpenMPVariantName(true); 5761 D.SetIdentifier(&VariantII, D.getBeginLoc()); 5762 return BaseFD; 5763 } 5764 5765 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 5766 FunctionDecl *FD, FunctionDecl *BaseFD) { 5767 // Do not mark function as is used to prevent its emission if this is the 5768 // only place where it is used. 5769 EnterExpressionEvaluationContext Unevaluated( 5770 *this, Sema::ExpressionEvaluationContext::Unevaluated); 5771 5772 Expr *VariantFuncRef = DeclRefExpr::Create( 5773 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 5774 /* RefersToEnclosingVariableOrCapture */ false, 5775 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); 5776 5777 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5778 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 5779 Context, VariantFuncRef, DVScope.TI); 5780 BaseFD->addAttr(OMPDeclareVariantA); 5781 } 5782 5783 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 5784 SourceLocation LParenLoc, 5785 MultiExprArg ArgExprs, 5786 SourceLocation RParenLoc, Expr *ExecConfig) { 5787 // The common case is a regular call we do not want to specialize at all. Try 5788 // to make that case fast by bailing early. 5789 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 5790 if (!CE) 5791 return Call; 5792 5793 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 5794 if (!CalleeFnDecl) 5795 return Call; 5796 5797 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 5798 return Call; 5799 5800 ASTContext &Context = getASTContext(); 5801 OMPContext OMPCtx(getLangOpts().OpenMPIsDevice, 5802 Context.getTargetInfo().getTriple()); 5803 5804 SmallVector<Expr *, 4> Exprs; 5805 SmallVector<VariantMatchInfo, 4> VMIs; 5806 while (CalleeFnDecl) { 5807 for (OMPDeclareVariantAttr *A : 5808 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 5809 Expr *VariantRef = A->getVariantFuncRef(); 5810 5811 VariantMatchInfo VMI; 5812 OMPTraitInfo &TI = A->getTraitInfo(); 5813 TI.getAsVariantMatchInfo(Context, VMI); 5814 if (!isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ false)) 5815 continue; 5816 5817 VMIs.push_back(VMI); 5818 Exprs.push_back(VariantRef); 5819 } 5820 5821 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 5822 } 5823 5824 ExprResult NewCall; 5825 do { 5826 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 5827 if (BestIdx < 0) 5828 return Call; 5829 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 5830 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 5831 5832 { 5833 // Try to build a (member) call expression for the current best applicable 5834 // variant expression. We allow this to fail in which case we continue 5835 // with the next best variant expression. The fail case is part of the 5836 // implementation defined behavior in the OpenMP standard when it talks 5837 // about what differences in the function prototypes: "Any differences 5838 // that the specific OpenMP context requires in the prototype of the 5839 // variant from the base function prototype are implementation defined." 5840 // This wording is there to allow the specialized variant to have a 5841 // different type than the base function. This is intended and OK but if 5842 // we cannot create a call the difference is not in the "implementation 5843 // defined range" we allow. 5844 Sema::TentativeAnalysisScope Trap(*this); 5845 5846 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 5847 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 5848 BestExpr = MemberExpr::CreateImplicit( 5849 Context, MemberCall->getImplicitObjectArgument(), 5850 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 5851 MemberCall->getValueKind(), MemberCall->getObjectKind()); 5852 } 5853 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 5854 ExecConfig); 5855 if (NewCall.isUsable()) 5856 break; 5857 } 5858 5859 VMIs.erase(VMIs.begin() + BestIdx); 5860 Exprs.erase(Exprs.begin() + BestIdx); 5861 } while (!VMIs.empty()); 5862 5863 if (!NewCall.isUsable()) 5864 return Call; 5865 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 5866 } 5867 5868 Optional<std::pair<FunctionDecl *, Expr *>> 5869 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5870 Expr *VariantRef, OMPTraitInfo &TI, 5871 SourceRange SR) { 5872 if (!DG || DG.get().isNull()) 5873 return None; 5874 5875 const int VariantId = 1; 5876 // Must be applied only to single decl. 5877 if (!DG.get().isSingleDecl()) { 5878 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5879 << VariantId << SR; 5880 return None; 5881 } 5882 Decl *ADecl = DG.get().getSingleDecl(); 5883 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5884 ADecl = FTD->getTemplatedDecl(); 5885 5886 // Decl must be a function. 5887 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5888 if (!FD) { 5889 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5890 << VariantId << SR; 5891 return None; 5892 } 5893 5894 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5895 return FD->hasAttrs() && 5896 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5897 FD->hasAttr<TargetAttr>()); 5898 }; 5899 // OpenMP is not compatible with CPU-specific attributes. 5900 if (HasMultiVersionAttributes(FD)) { 5901 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5902 << SR; 5903 return None; 5904 } 5905 5906 // Allow #pragma omp declare variant only if the function is not used. 5907 if (FD->isUsed(false)) 5908 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5909 << FD->getLocation(); 5910 5911 // Check if the function was emitted already. 5912 const FunctionDecl *Definition; 5913 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5914 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5915 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5916 << FD->getLocation(); 5917 5918 // The VariantRef must point to function. 5919 if (!VariantRef) { 5920 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5921 return None; 5922 } 5923 5924 auto ShouldDelayChecks = [](Expr *&E, bool) { 5925 return E && (E->isTypeDependent() || E->isValueDependent() || 5926 E->containsUnexpandedParameterPack() || 5927 E->isInstantiationDependent()); 5928 }; 5929 // Do not check templates, wait until instantiation. 5930 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 5931 TI.anyScoreOrCondition(ShouldDelayChecks)) 5932 return std::make_pair(FD, VariantRef); 5933 5934 // Deal with non-constant score and user condition expressions. 5935 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 5936 bool IsScore) -> bool { 5937 llvm::APSInt Result; 5938 if (!E || E->isIntegerConstantExpr(Result, Context)) 5939 return false; 5940 5941 if (IsScore) { 5942 // We warn on non-constant scores and pretend they were not present. 5943 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 5944 << E; 5945 E = nullptr; 5946 } else { 5947 // We could replace a non-constant user condition with "false" but we 5948 // will soon need to handle these anyway for the dynamic version of 5949 // OpenMP context selectors. 5950 Diag(E->getExprLoc(), 5951 diag::err_omp_declare_variant_user_condition_not_constant) 5952 << E; 5953 } 5954 return true; 5955 }; 5956 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 5957 return None; 5958 5959 // Convert VariantRef expression to the type of the original function to 5960 // resolve possible conflicts. 5961 ExprResult VariantRefCast; 5962 if (LangOpts.CPlusPlus) { 5963 QualType FnPtrType; 5964 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5965 if (Method && !Method->isStatic()) { 5966 const Type *ClassType = 5967 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5968 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5969 ExprResult ER; 5970 { 5971 // Build adrr_of unary op to correctly handle type checks for member 5972 // functions. 5973 Sema::TentativeAnalysisScope Trap(*this); 5974 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5975 VariantRef); 5976 } 5977 if (!ER.isUsable()) { 5978 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5979 << VariantId << VariantRef->getSourceRange(); 5980 return None; 5981 } 5982 VariantRef = ER.get(); 5983 } else { 5984 FnPtrType = Context.getPointerType(FD->getType()); 5985 } 5986 ImplicitConversionSequence ICS = 5987 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5988 /*SuppressUserConversions=*/false, 5989 AllowedExplicit::None, 5990 /*InOverloadResolution=*/false, 5991 /*CStyle=*/false, 5992 /*AllowObjCWritebackConversion=*/false); 5993 if (ICS.isFailure()) { 5994 Diag(VariantRef->getExprLoc(), 5995 diag::err_omp_declare_variant_incompat_types) 5996 << VariantRef->getType() 5997 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 5998 << VariantRef->getSourceRange(); 5999 return None; 6000 } 6001 VariantRefCast = PerformImplicitConversion( 6002 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 6003 if (!VariantRefCast.isUsable()) 6004 return None; 6005 // Drop previously built artificial addr_of unary op for member functions. 6006 if (Method && !Method->isStatic()) { 6007 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 6008 if (auto *UO = dyn_cast<UnaryOperator>( 6009 PossibleAddrOfVariantRef->IgnoreImplicit())) 6010 VariantRefCast = UO->getSubExpr(); 6011 } 6012 } else { 6013 VariantRefCast = VariantRef; 6014 } 6015 6016 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 6017 if (!ER.isUsable() || 6018 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 6019 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6020 << VariantId << VariantRef->getSourceRange(); 6021 return None; 6022 } 6023 6024 // The VariantRef must point to function. 6025 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 6026 if (!DRE) { 6027 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6028 << VariantId << VariantRef->getSourceRange(); 6029 return None; 6030 } 6031 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 6032 if (!NewFD) { 6033 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6034 << VariantId << VariantRef->getSourceRange(); 6035 return None; 6036 } 6037 6038 // Check if function types are compatible in C. 6039 if (!LangOpts.CPlusPlus) { 6040 QualType NewType = 6041 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 6042 if (NewType.isNull()) { 6043 Diag(VariantRef->getExprLoc(), 6044 diag::err_omp_declare_variant_incompat_types) 6045 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 6046 return None; 6047 } 6048 if (NewType->isFunctionProtoType()) { 6049 if (FD->getType()->isFunctionNoProtoType()) 6050 setPrototype(*this, FD, NewFD, NewType); 6051 else if (NewFD->getType()->isFunctionNoProtoType()) 6052 setPrototype(*this, NewFD, FD, NewType); 6053 } 6054 } 6055 6056 // Check if variant function is not marked with declare variant directive. 6057 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 6058 Diag(VariantRef->getExprLoc(), 6059 diag::warn_omp_declare_variant_marked_as_declare_variant) 6060 << VariantRef->getSourceRange(); 6061 SourceRange SR = 6062 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 6063 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 6064 return None; 6065 } 6066 6067 enum DoesntSupport { 6068 VirtFuncs = 1, 6069 Constructors = 3, 6070 Destructors = 4, 6071 DeletedFuncs = 5, 6072 DefaultedFuncs = 6, 6073 ConstexprFuncs = 7, 6074 ConstevalFuncs = 8, 6075 }; 6076 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 6077 if (CXXFD->isVirtual()) { 6078 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6079 << VirtFuncs; 6080 return None; 6081 } 6082 6083 if (isa<CXXConstructorDecl>(FD)) { 6084 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6085 << Constructors; 6086 return None; 6087 } 6088 6089 if (isa<CXXDestructorDecl>(FD)) { 6090 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6091 << Destructors; 6092 return None; 6093 } 6094 } 6095 6096 if (FD->isDeleted()) { 6097 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6098 << DeletedFuncs; 6099 return None; 6100 } 6101 6102 if (FD->isDefaulted()) { 6103 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6104 << DefaultedFuncs; 6105 return None; 6106 } 6107 6108 if (FD->isConstexpr()) { 6109 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6110 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 6111 return None; 6112 } 6113 6114 // Check general compatibility. 6115 if (areMultiversionVariantFunctionsCompatible( 6116 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 6117 PartialDiagnosticAt(SourceLocation(), 6118 PartialDiagnostic::NullDiagnostic()), 6119 PartialDiagnosticAt( 6120 VariantRef->getExprLoc(), 6121 PDiag(diag::err_omp_declare_variant_doesnt_support)), 6122 PartialDiagnosticAt(VariantRef->getExprLoc(), 6123 PDiag(diag::err_omp_declare_variant_diff) 6124 << FD->getLocation()), 6125 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 6126 /*CLinkageMayDiffer=*/true)) 6127 return None; 6128 return std::make_pair(FD, cast<Expr>(DRE)); 6129 } 6130 6131 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 6132 Expr *VariantRef, 6133 OMPTraitInfo &TI, 6134 SourceRange SR) { 6135 auto *NewAttr = 6136 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); 6137 FD->addAttr(NewAttr); 6138 } 6139 6140 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 6141 Stmt *AStmt, 6142 SourceLocation StartLoc, 6143 SourceLocation EndLoc) { 6144 if (!AStmt) 6145 return StmtError(); 6146 6147 auto *CS = cast<CapturedStmt>(AStmt); 6148 // 1.2.2 OpenMP Language Terminology 6149 // Structured block - An executable statement with a single entry at the 6150 // top and a single exit at the bottom. 6151 // The point of exit cannot be a branch out of the structured block. 6152 // longjmp() and throw() must not violate the entry/exit criteria. 6153 CS->getCapturedDecl()->setNothrow(); 6154 6155 setFunctionHasBranchProtectedScope(); 6156 6157 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6158 DSAStack->getTaskgroupReductionRef(), 6159 DSAStack->isCancelRegion()); 6160 } 6161 6162 namespace { 6163 /// Iteration space of a single for loop. 6164 struct LoopIterationSpace final { 6165 /// True if the condition operator is the strict compare operator (<, > or 6166 /// !=). 6167 bool IsStrictCompare = false; 6168 /// Condition of the loop. 6169 Expr *PreCond = nullptr; 6170 /// This expression calculates the number of iterations in the loop. 6171 /// It is always possible to calculate it before starting the loop. 6172 Expr *NumIterations = nullptr; 6173 /// The loop counter variable. 6174 Expr *CounterVar = nullptr; 6175 /// Private loop counter variable. 6176 Expr *PrivateCounterVar = nullptr; 6177 /// This is initializer for the initial value of #CounterVar. 6178 Expr *CounterInit = nullptr; 6179 /// This is step for the #CounterVar used to generate its update: 6180 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 6181 Expr *CounterStep = nullptr; 6182 /// Should step be subtracted? 6183 bool Subtract = false; 6184 /// Source range of the loop init. 6185 SourceRange InitSrcRange; 6186 /// Source range of the loop condition. 6187 SourceRange CondSrcRange; 6188 /// Source range of the loop increment. 6189 SourceRange IncSrcRange; 6190 /// Minimum value that can have the loop control variable. Used to support 6191 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 6192 /// since only such variables can be used in non-loop invariant expressions. 6193 Expr *MinValue = nullptr; 6194 /// Maximum value that can have the loop control variable. Used to support 6195 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 6196 /// since only such variables can be used in non-loop invariant expressions. 6197 Expr *MaxValue = nullptr; 6198 /// true, if the lower bound depends on the outer loop control var. 6199 bool IsNonRectangularLB = false; 6200 /// true, if the upper bound depends on the outer loop control var. 6201 bool IsNonRectangularUB = false; 6202 /// Index of the loop this loop depends on and forms non-rectangular loop 6203 /// nest. 6204 unsigned LoopDependentIdx = 0; 6205 /// Final condition for the non-rectangular loop nest support. It is used to 6206 /// check that the number of iterations for this particular counter must be 6207 /// finished. 6208 Expr *FinalCondition = nullptr; 6209 }; 6210 6211 /// Helper class for checking canonical form of the OpenMP loops and 6212 /// extracting iteration space of each loop in the loop nest, that will be used 6213 /// for IR generation. 6214 class OpenMPIterationSpaceChecker { 6215 /// Reference to Sema. 6216 Sema &SemaRef; 6217 /// Data-sharing stack. 6218 DSAStackTy &Stack; 6219 /// A location for diagnostics (when there is no some better location). 6220 SourceLocation DefaultLoc; 6221 /// A location for diagnostics (when increment is not compatible). 6222 SourceLocation ConditionLoc; 6223 /// A source location for referring to loop init later. 6224 SourceRange InitSrcRange; 6225 /// A source location for referring to condition later. 6226 SourceRange ConditionSrcRange; 6227 /// A source location for referring to increment later. 6228 SourceRange IncrementSrcRange; 6229 /// Loop variable. 6230 ValueDecl *LCDecl = nullptr; 6231 /// Reference to loop variable. 6232 Expr *LCRef = nullptr; 6233 /// Lower bound (initializer for the var). 6234 Expr *LB = nullptr; 6235 /// Upper bound. 6236 Expr *UB = nullptr; 6237 /// Loop step (increment). 6238 Expr *Step = nullptr; 6239 /// This flag is true when condition is one of: 6240 /// Var < UB 6241 /// Var <= UB 6242 /// UB > Var 6243 /// UB >= Var 6244 /// This will have no value when the condition is != 6245 llvm::Optional<bool> TestIsLessOp; 6246 /// This flag is true when condition is strict ( < or > ). 6247 bool TestIsStrictOp = false; 6248 /// This flag is true when step is subtracted on each iteration. 6249 bool SubtractStep = false; 6250 /// The outer loop counter this loop depends on (if any). 6251 const ValueDecl *DepDecl = nullptr; 6252 /// Contains number of loop (starts from 1) on which loop counter init 6253 /// expression of this loop depends on. 6254 Optional<unsigned> InitDependOnLC; 6255 /// Contains number of loop (starts from 1) on which loop counter condition 6256 /// expression of this loop depends on. 6257 Optional<unsigned> CondDependOnLC; 6258 /// Checks if the provide statement depends on the loop counter. 6259 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 6260 /// Original condition required for checking of the exit condition for 6261 /// non-rectangular loop. 6262 Expr *Condition = nullptr; 6263 6264 public: 6265 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 6266 SourceLocation DefaultLoc) 6267 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 6268 ConditionLoc(DefaultLoc) {} 6269 /// Check init-expr for canonical loop form and save loop counter 6270 /// variable - #Var and its initialization value - #LB. 6271 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 6272 /// Check test-expr for canonical form, save upper-bound (#UB), flags 6273 /// for less/greater and for strict/non-strict comparison. 6274 bool checkAndSetCond(Expr *S); 6275 /// Check incr-expr for canonical loop form and return true if it 6276 /// does not conform, otherwise save loop step (#Step). 6277 bool checkAndSetInc(Expr *S); 6278 /// Return the loop counter variable. 6279 ValueDecl *getLoopDecl() const { return LCDecl; } 6280 /// Return the reference expression to loop counter variable. 6281 Expr *getLoopDeclRefExpr() const { return LCRef; } 6282 /// Source range of the loop init. 6283 SourceRange getInitSrcRange() const { return InitSrcRange; } 6284 /// Source range of the loop condition. 6285 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 6286 /// Source range of the loop increment. 6287 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 6288 /// True if the step should be subtracted. 6289 bool shouldSubtractStep() const { return SubtractStep; } 6290 /// True, if the compare operator is strict (<, > or !=). 6291 bool isStrictTestOp() const { return TestIsStrictOp; } 6292 /// Build the expression to calculate the number of iterations. 6293 Expr *buildNumIterations( 6294 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6295 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6296 /// Build the precondition expression for the loops. 6297 Expr * 6298 buildPreCond(Scope *S, Expr *Cond, 6299 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6300 /// Build reference expression to the counter be used for codegen. 6301 DeclRefExpr * 6302 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6303 DSAStackTy &DSA) const; 6304 /// Build reference expression to the private counter be used for 6305 /// codegen. 6306 Expr *buildPrivateCounterVar() const; 6307 /// Build initialization of the counter be used for codegen. 6308 Expr *buildCounterInit() const; 6309 /// Build step of the counter be used for codegen. 6310 Expr *buildCounterStep() const; 6311 /// Build loop data with counter value for depend clauses in ordered 6312 /// directives. 6313 Expr * 6314 buildOrderedLoopData(Scope *S, Expr *Counter, 6315 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6316 SourceLocation Loc, Expr *Inc = nullptr, 6317 OverloadedOperatorKind OOK = OO_Amp); 6318 /// Builds the minimum value for the loop counter. 6319 std::pair<Expr *, Expr *> buildMinMaxValues( 6320 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6321 /// Builds final condition for the non-rectangular loops. 6322 Expr *buildFinalCondition(Scope *S) const; 6323 /// Return true if any expression is dependent. 6324 bool dependent() const; 6325 /// Returns true if the initializer forms non-rectangular loop. 6326 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 6327 /// Returns true if the condition forms non-rectangular loop. 6328 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 6329 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 6330 unsigned getLoopDependentIdx() const { 6331 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 6332 } 6333 6334 private: 6335 /// Check the right-hand side of an assignment in the increment 6336 /// expression. 6337 bool checkAndSetIncRHS(Expr *RHS); 6338 /// Helper to set loop counter variable and its initializer. 6339 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 6340 bool EmitDiags); 6341 /// Helper to set upper bound. 6342 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 6343 SourceRange SR, SourceLocation SL); 6344 /// Helper to set loop increment. 6345 bool setStep(Expr *NewStep, bool Subtract); 6346 }; 6347 6348 bool OpenMPIterationSpaceChecker::dependent() const { 6349 if (!LCDecl) { 6350 assert(!LB && !UB && !Step); 6351 return false; 6352 } 6353 return LCDecl->getType()->isDependentType() || 6354 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 6355 (Step && Step->isValueDependent()); 6356 } 6357 6358 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 6359 Expr *NewLCRefExpr, 6360 Expr *NewLB, bool EmitDiags) { 6361 // State consistency checking to ensure correct usage. 6362 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 6363 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6364 if (!NewLCDecl || !NewLB) 6365 return true; 6366 LCDecl = getCanonicalDecl(NewLCDecl); 6367 LCRef = NewLCRefExpr; 6368 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 6369 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6370 if ((Ctor->isCopyOrMoveConstructor() || 6371 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6372 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6373 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 6374 LB = NewLB; 6375 if (EmitDiags) 6376 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 6377 return false; 6378 } 6379 6380 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 6381 llvm::Optional<bool> LessOp, 6382 bool StrictOp, SourceRange SR, 6383 SourceLocation SL) { 6384 // State consistency checking to ensure correct usage. 6385 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 6386 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6387 if (!NewUB) 6388 return true; 6389 UB = NewUB; 6390 if (LessOp) 6391 TestIsLessOp = LessOp; 6392 TestIsStrictOp = StrictOp; 6393 ConditionSrcRange = SR; 6394 ConditionLoc = SL; 6395 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 6396 return false; 6397 } 6398 6399 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 6400 // State consistency checking to ensure correct usage. 6401 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 6402 if (!NewStep) 6403 return true; 6404 if (!NewStep->isValueDependent()) { 6405 // Check that the step is integer expression. 6406 SourceLocation StepLoc = NewStep->getBeginLoc(); 6407 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 6408 StepLoc, getExprAsWritten(NewStep)); 6409 if (Val.isInvalid()) 6410 return true; 6411 NewStep = Val.get(); 6412 6413 // OpenMP [2.6, Canonical Loop Form, Restrictions] 6414 // If test-expr is of form var relational-op b and relational-op is < or 6415 // <= then incr-expr must cause var to increase on each iteration of the 6416 // loop. If test-expr is of form var relational-op b and relational-op is 6417 // > or >= then incr-expr must cause var to decrease on each iteration of 6418 // the loop. 6419 // If test-expr is of form b relational-op var and relational-op is < or 6420 // <= then incr-expr must cause var to decrease on each iteration of the 6421 // loop. If test-expr is of form b relational-op var and relational-op is 6422 // > or >= then incr-expr must cause var to increase on each iteration of 6423 // the loop. 6424 llvm::APSInt Result; 6425 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 6426 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 6427 bool IsConstNeg = 6428 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 6429 bool IsConstPos = 6430 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 6431 bool IsConstZero = IsConstant && !Result.getBoolValue(); 6432 6433 // != with increment is treated as <; != with decrement is treated as > 6434 if (!TestIsLessOp.hasValue()) 6435 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 6436 if (UB && (IsConstZero || 6437 (TestIsLessOp.getValue() ? 6438 (IsConstNeg || (IsUnsigned && Subtract)) : 6439 (IsConstPos || (IsUnsigned && !Subtract))))) { 6440 SemaRef.Diag(NewStep->getExprLoc(), 6441 diag::err_omp_loop_incr_not_compatible) 6442 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 6443 SemaRef.Diag(ConditionLoc, 6444 diag::note_omp_loop_cond_requres_compatible_incr) 6445 << TestIsLessOp.getValue() << ConditionSrcRange; 6446 return true; 6447 } 6448 if (TestIsLessOp.getValue() == Subtract) { 6449 NewStep = 6450 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 6451 .get(); 6452 Subtract = !Subtract; 6453 } 6454 } 6455 6456 Step = NewStep; 6457 SubtractStep = Subtract; 6458 return false; 6459 } 6460 6461 namespace { 6462 /// Checker for the non-rectangular loops. Checks if the initializer or 6463 /// condition expression references loop counter variable. 6464 class LoopCounterRefChecker final 6465 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 6466 Sema &SemaRef; 6467 DSAStackTy &Stack; 6468 const ValueDecl *CurLCDecl = nullptr; 6469 const ValueDecl *DepDecl = nullptr; 6470 const ValueDecl *PrevDepDecl = nullptr; 6471 bool IsInitializer = true; 6472 unsigned BaseLoopId = 0; 6473 bool checkDecl(const Expr *E, const ValueDecl *VD) { 6474 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 6475 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 6476 << (IsInitializer ? 0 : 1); 6477 return false; 6478 } 6479 const auto &&Data = Stack.isLoopControlVariable(VD); 6480 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6481 // The type of the loop iterator on which we depend may not have a random 6482 // access iterator type. 6483 if (Data.first && VD->getType()->isRecordType()) { 6484 SmallString<128> Name; 6485 llvm::raw_svector_ostream OS(Name); 6486 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6487 /*Qualified=*/true); 6488 SemaRef.Diag(E->getExprLoc(), 6489 diag::err_omp_wrong_dependency_iterator_type) 6490 << OS.str(); 6491 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6492 return false; 6493 } 6494 if (Data.first && 6495 (DepDecl || (PrevDepDecl && 6496 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6497 if (!DepDecl && PrevDepDecl) 6498 DepDecl = PrevDepDecl; 6499 SmallString<128> Name; 6500 llvm::raw_svector_ostream OS(Name); 6501 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6502 /*Qualified=*/true); 6503 SemaRef.Diag(E->getExprLoc(), 6504 diag::err_omp_invariant_or_linear_dependency) 6505 << OS.str(); 6506 return false; 6507 } 6508 if (Data.first) { 6509 DepDecl = VD; 6510 BaseLoopId = Data.first; 6511 } 6512 return Data.first; 6513 } 6514 6515 public: 6516 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6517 const ValueDecl *VD = E->getDecl(); 6518 if (isa<VarDecl>(VD)) 6519 return checkDecl(E, VD); 6520 return false; 6521 } 6522 bool VisitMemberExpr(const MemberExpr *E) { 6523 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6524 const ValueDecl *VD = E->getMemberDecl(); 6525 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6526 return checkDecl(E, VD); 6527 } 6528 return false; 6529 } 6530 bool VisitStmt(const Stmt *S) { 6531 bool Res = false; 6532 for (const Stmt *Child : S->children()) 6533 Res = (Child && Visit(Child)) || Res; 6534 return Res; 6535 } 6536 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6537 const ValueDecl *CurLCDecl, bool IsInitializer, 6538 const ValueDecl *PrevDepDecl = nullptr) 6539 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6540 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6541 unsigned getBaseLoopId() const { 6542 assert(CurLCDecl && "Expected loop dependency."); 6543 return BaseLoopId; 6544 } 6545 const ValueDecl *getDepDecl() const { 6546 assert(CurLCDecl && "Expected loop dependency."); 6547 return DepDecl; 6548 } 6549 }; 6550 } // namespace 6551 6552 Optional<unsigned> 6553 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6554 bool IsInitializer) { 6555 // Check for the non-rectangular loops. 6556 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6557 DepDecl); 6558 if (LoopStmtChecker.Visit(S)) { 6559 DepDecl = LoopStmtChecker.getDepDecl(); 6560 return LoopStmtChecker.getBaseLoopId(); 6561 } 6562 return llvm::None; 6563 } 6564 6565 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6566 // Check init-expr for canonical loop form and save loop counter 6567 // variable - #Var and its initialization value - #LB. 6568 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6569 // var = lb 6570 // integer-type var = lb 6571 // random-access-iterator-type var = lb 6572 // pointer-type var = lb 6573 // 6574 if (!S) { 6575 if (EmitDiags) { 6576 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6577 } 6578 return true; 6579 } 6580 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6581 if (!ExprTemp->cleanupsHaveSideEffects()) 6582 S = ExprTemp->getSubExpr(); 6583 6584 InitSrcRange = S->getSourceRange(); 6585 if (Expr *E = dyn_cast<Expr>(S)) 6586 S = E->IgnoreParens(); 6587 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6588 if (BO->getOpcode() == BO_Assign) { 6589 Expr *LHS = BO->getLHS()->IgnoreParens(); 6590 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6591 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6592 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6593 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6594 EmitDiags); 6595 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6596 } 6597 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6598 if (ME->isArrow() && 6599 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6600 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6601 EmitDiags); 6602 } 6603 } 6604 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6605 if (DS->isSingleDecl()) { 6606 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6607 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6608 // Accept non-canonical init form here but emit ext. warning. 6609 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6610 SemaRef.Diag(S->getBeginLoc(), 6611 diag::ext_omp_loop_not_canonical_init) 6612 << S->getSourceRange(); 6613 return setLCDeclAndLB( 6614 Var, 6615 buildDeclRefExpr(SemaRef, Var, 6616 Var->getType().getNonReferenceType(), 6617 DS->getBeginLoc()), 6618 Var->getInit(), EmitDiags); 6619 } 6620 } 6621 } 6622 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6623 if (CE->getOperator() == OO_Equal) { 6624 Expr *LHS = CE->getArg(0); 6625 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6626 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6627 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6628 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6629 EmitDiags); 6630 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6631 } 6632 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6633 if (ME->isArrow() && 6634 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6635 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6636 EmitDiags); 6637 } 6638 } 6639 } 6640 6641 if (dependent() || SemaRef.CurContext->isDependentContext()) 6642 return false; 6643 if (EmitDiags) { 6644 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6645 << S->getSourceRange(); 6646 } 6647 return true; 6648 } 6649 6650 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6651 /// variable (which may be the loop variable) if possible. 6652 static const ValueDecl *getInitLCDecl(const Expr *E) { 6653 if (!E) 6654 return nullptr; 6655 E = getExprAsWritten(E); 6656 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6657 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6658 if ((Ctor->isCopyOrMoveConstructor() || 6659 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6660 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6661 E = CE->getArg(0)->IgnoreParenImpCasts(); 6662 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6663 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6664 return getCanonicalDecl(VD); 6665 } 6666 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6667 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6668 return getCanonicalDecl(ME->getMemberDecl()); 6669 return nullptr; 6670 } 6671 6672 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6673 // Check test-expr for canonical form, save upper-bound UB, flags for 6674 // less/greater and for strict/non-strict comparison. 6675 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6676 // var relational-op b 6677 // b relational-op var 6678 // 6679 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6680 if (!S) { 6681 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6682 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6683 return true; 6684 } 6685 Condition = S; 6686 S = getExprAsWritten(S); 6687 SourceLocation CondLoc = S->getBeginLoc(); 6688 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6689 if (BO->isRelationalOp()) { 6690 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6691 return setUB(BO->getRHS(), 6692 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6693 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6694 BO->getSourceRange(), BO->getOperatorLoc()); 6695 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6696 return setUB(BO->getLHS(), 6697 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6698 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6699 BO->getSourceRange(), BO->getOperatorLoc()); 6700 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6701 return setUB( 6702 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6703 /*LessOp=*/llvm::None, 6704 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6705 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6706 if (CE->getNumArgs() == 2) { 6707 auto Op = CE->getOperator(); 6708 switch (Op) { 6709 case OO_Greater: 6710 case OO_GreaterEqual: 6711 case OO_Less: 6712 case OO_LessEqual: 6713 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6714 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6715 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6716 CE->getOperatorLoc()); 6717 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6718 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6719 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6720 CE->getOperatorLoc()); 6721 break; 6722 case OO_ExclaimEqual: 6723 if (IneqCondIsCanonical) 6724 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6725 : CE->getArg(0), 6726 /*LessOp=*/llvm::None, 6727 /*StrictOp=*/true, CE->getSourceRange(), 6728 CE->getOperatorLoc()); 6729 break; 6730 default: 6731 break; 6732 } 6733 } 6734 } 6735 if (dependent() || SemaRef.CurContext->isDependentContext()) 6736 return false; 6737 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6738 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6739 return true; 6740 } 6741 6742 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6743 // RHS of canonical loop form increment can be: 6744 // var + incr 6745 // incr + var 6746 // var - incr 6747 // 6748 RHS = RHS->IgnoreParenImpCasts(); 6749 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6750 if (BO->isAdditiveOp()) { 6751 bool IsAdd = BO->getOpcode() == BO_Add; 6752 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6753 return setStep(BO->getRHS(), !IsAdd); 6754 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6755 return setStep(BO->getLHS(), /*Subtract=*/false); 6756 } 6757 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6758 bool IsAdd = CE->getOperator() == OO_Plus; 6759 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6760 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6761 return setStep(CE->getArg(1), !IsAdd); 6762 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6763 return setStep(CE->getArg(0), /*Subtract=*/false); 6764 } 6765 } 6766 if (dependent() || SemaRef.CurContext->isDependentContext()) 6767 return false; 6768 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6769 << RHS->getSourceRange() << LCDecl; 6770 return true; 6771 } 6772 6773 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6774 // Check incr-expr for canonical loop form and return true if it 6775 // does not conform. 6776 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6777 // ++var 6778 // var++ 6779 // --var 6780 // var-- 6781 // var += incr 6782 // var -= incr 6783 // var = var + incr 6784 // var = incr + var 6785 // var = var - incr 6786 // 6787 if (!S) { 6788 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6789 return true; 6790 } 6791 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6792 if (!ExprTemp->cleanupsHaveSideEffects()) 6793 S = ExprTemp->getSubExpr(); 6794 6795 IncrementSrcRange = S->getSourceRange(); 6796 S = S->IgnoreParens(); 6797 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6798 if (UO->isIncrementDecrementOp() && 6799 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6800 return setStep(SemaRef 6801 .ActOnIntegerConstant(UO->getBeginLoc(), 6802 (UO->isDecrementOp() ? -1 : 1)) 6803 .get(), 6804 /*Subtract=*/false); 6805 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6806 switch (BO->getOpcode()) { 6807 case BO_AddAssign: 6808 case BO_SubAssign: 6809 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6810 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6811 break; 6812 case BO_Assign: 6813 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6814 return checkAndSetIncRHS(BO->getRHS()); 6815 break; 6816 default: 6817 break; 6818 } 6819 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6820 switch (CE->getOperator()) { 6821 case OO_PlusPlus: 6822 case OO_MinusMinus: 6823 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6824 return setStep(SemaRef 6825 .ActOnIntegerConstant( 6826 CE->getBeginLoc(), 6827 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6828 .get(), 6829 /*Subtract=*/false); 6830 break; 6831 case OO_PlusEqual: 6832 case OO_MinusEqual: 6833 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6834 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6835 break; 6836 case OO_Equal: 6837 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6838 return checkAndSetIncRHS(CE->getArg(1)); 6839 break; 6840 default: 6841 break; 6842 } 6843 } 6844 if (dependent() || SemaRef.CurContext->isDependentContext()) 6845 return false; 6846 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6847 << S->getSourceRange() << LCDecl; 6848 return true; 6849 } 6850 6851 static ExprResult 6852 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6853 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6854 if (SemaRef.CurContext->isDependentContext()) 6855 return ExprResult(Capture); 6856 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6857 return SemaRef.PerformImplicitConversion( 6858 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6859 /*AllowExplicit=*/true); 6860 auto I = Captures.find(Capture); 6861 if (I != Captures.end()) 6862 return buildCapture(SemaRef, Capture, I->second); 6863 DeclRefExpr *Ref = nullptr; 6864 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6865 Captures[Capture] = Ref; 6866 return Res; 6867 } 6868 6869 /// Build the expression to calculate the number of iterations. 6870 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6871 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6872 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6873 ExprResult Diff; 6874 QualType VarType = LCDecl->getType().getNonReferenceType(); 6875 if (VarType->isIntegerType() || VarType->isPointerType() || 6876 SemaRef.getLangOpts().CPlusPlus) { 6877 Expr *LBVal = LB; 6878 Expr *UBVal = UB; 6879 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6880 // max(LB(MinVal), LB(MaxVal)) 6881 if (InitDependOnLC) { 6882 const LoopIterationSpace &IS = 6883 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6884 InitDependOnLC.getValueOr( 6885 CondDependOnLC.getValueOr(0))]; 6886 if (!IS.MinValue || !IS.MaxValue) 6887 return nullptr; 6888 // OuterVar = Min 6889 ExprResult MinValue = 6890 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6891 if (!MinValue.isUsable()) 6892 return nullptr; 6893 6894 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6895 IS.CounterVar, MinValue.get()); 6896 if (!LBMinVal.isUsable()) 6897 return nullptr; 6898 // OuterVar = Min, LBVal 6899 LBMinVal = 6900 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6901 if (!LBMinVal.isUsable()) 6902 return nullptr; 6903 // (OuterVar = Min, LBVal) 6904 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6905 if (!LBMinVal.isUsable()) 6906 return nullptr; 6907 6908 // OuterVar = Max 6909 ExprResult MaxValue = 6910 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6911 if (!MaxValue.isUsable()) 6912 return nullptr; 6913 6914 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6915 IS.CounterVar, MaxValue.get()); 6916 if (!LBMaxVal.isUsable()) 6917 return nullptr; 6918 // OuterVar = Max, LBVal 6919 LBMaxVal = 6920 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6921 if (!LBMaxVal.isUsable()) 6922 return nullptr; 6923 // (OuterVar = Max, LBVal) 6924 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6925 if (!LBMaxVal.isUsable()) 6926 return nullptr; 6927 6928 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6929 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6930 if (!LBMin || !LBMax) 6931 return nullptr; 6932 // LB(MinVal) < LB(MaxVal) 6933 ExprResult MinLessMaxRes = 6934 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6935 if (!MinLessMaxRes.isUsable()) 6936 return nullptr; 6937 Expr *MinLessMax = 6938 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6939 if (!MinLessMax) 6940 return nullptr; 6941 if (TestIsLessOp.getValue()) { 6942 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6943 // LB(MaxVal)) 6944 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6945 MinLessMax, LBMin, LBMax); 6946 if (!MinLB.isUsable()) 6947 return nullptr; 6948 LBVal = MinLB.get(); 6949 } else { 6950 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6951 // LB(MaxVal)) 6952 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6953 MinLessMax, LBMax, LBMin); 6954 if (!MaxLB.isUsable()) 6955 return nullptr; 6956 LBVal = MaxLB.get(); 6957 } 6958 } 6959 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6960 // min(UB(MinVal), UB(MaxVal)) 6961 if (CondDependOnLC) { 6962 const LoopIterationSpace &IS = 6963 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6964 InitDependOnLC.getValueOr( 6965 CondDependOnLC.getValueOr(0))]; 6966 if (!IS.MinValue || !IS.MaxValue) 6967 return nullptr; 6968 // OuterVar = Min 6969 ExprResult MinValue = 6970 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6971 if (!MinValue.isUsable()) 6972 return nullptr; 6973 6974 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6975 IS.CounterVar, MinValue.get()); 6976 if (!UBMinVal.isUsable()) 6977 return nullptr; 6978 // OuterVar = Min, UBVal 6979 UBMinVal = 6980 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6981 if (!UBMinVal.isUsable()) 6982 return nullptr; 6983 // (OuterVar = Min, UBVal) 6984 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6985 if (!UBMinVal.isUsable()) 6986 return nullptr; 6987 6988 // OuterVar = Max 6989 ExprResult MaxValue = 6990 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6991 if (!MaxValue.isUsable()) 6992 return nullptr; 6993 6994 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6995 IS.CounterVar, MaxValue.get()); 6996 if (!UBMaxVal.isUsable()) 6997 return nullptr; 6998 // OuterVar = Max, UBVal 6999 UBMaxVal = 7000 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 7001 if (!UBMaxVal.isUsable()) 7002 return nullptr; 7003 // (OuterVar = Max, UBVal) 7004 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 7005 if (!UBMaxVal.isUsable()) 7006 return nullptr; 7007 7008 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 7009 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 7010 if (!UBMin || !UBMax) 7011 return nullptr; 7012 // UB(MinVal) > UB(MaxVal) 7013 ExprResult MinGreaterMaxRes = 7014 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 7015 if (!MinGreaterMaxRes.isUsable()) 7016 return nullptr; 7017 Expr *MinGreaterMax = 7018 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 7019 if (!MinGreaterMax) 7020 return nullptr; 7021 if (TestIsLessOp.getValue()) { 7022 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 7023 // UB(MaxVal)) 7024 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 7025 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 7026 if (!MaxUB.isUsable()) 7027 return nullptr; 7028 UBVal = MaxUB.get(); 7029 } else { 7030 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 7031 // UB(MaxVal)) 7032 ExprResult MinUB = SemaRef.ActOnConditionalOp( 7033 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 7034 if (!MinUB.isUsable()) 7035 return nullptr; 7036 UBVal = MinUB.get(); 7037 } 7038 } 7039 // Upper - Lower 7040 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 7041 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 7042 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7043 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7044 if (!Upper || !Lower) 7045 return nullptr; 7046 7047 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7048 7049 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 7050 // BuildBinOp already emitted error, this one is to point user to upper 7051 // and lower bound, and to tell what is passed to 'operator-'. 7052 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7053 << Upper->getSourceRange() << Lower->getSourceRange(); 7054 return nullptr; 7055 } 7056 } 7057 7058 if (!Diff.isUsable()) 7059 return nullptr; 7060 7061 // Upper - Lower [- 1] 7062 if (TestIsStrictOp) 7063 Diff = SemaRef.BuildBinOp( 7064 S, DefaultLoc, BO_Sub, Diff.get(), 7065 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7066 if (!Diff.isUsable()) 7067 return nullptr; 7068 7069 // Upper - Lower [- 1] + Step 7070 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7071 if (!NewStep.isUsable()) 7072 return nullptr; 7073 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 7074 if (!Diff.isUsable()) 7075 return nullptr; 7076 7077 // Parentheses (for dumping/debugging purposes only). 7078 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7079 if (!Diff.isUsable()) 7080 return nullptr; 7081 7082 // (Upper - Lower [- 1] + Step) / Step 7083 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7084 if (!Diff.isUsable()) 7085 return nullptr; 7086 7087 // OpenMP runtime requires 32-bit or 64-bit loop variables. 7088 QualType Type = Diff.get()->getType(); 7089 ASTContext &C = SemaRef.Context; 7090 bool UseVarType = VarType->hasIntegerRepresentation() && 7091 C.getTypeSize(Type) > C.getTypeSize(VarType); 7092 if (!Type->isIntegerType() || UseVarType) { 7093 unsigned NewSize = 7094 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 7095 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 7096 : Type->hasSignedIntegerRepresentation(); 7097 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 7098 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 7099 Diff = SemaRef.PerformImplicitConversion( 7100 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 7101 if (!Diff.isUsable()) 7102 return nullptr; 7103 } 7104 } 7105 if (LimitedType) { 7106 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 7107 if (NewSize != C.getTypeSize(Type)) { 7108 if (NewSize < C.getTypeSize(Type)) { 7109 assert(NewSize == 64 && "incorrect loop var size"); 7110 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 7111 << InitSrcRange << ConditionSrcRange; 7112 } 7113 QualType NewType = C.getIntTypeForBitwidth( 7114 NewSize, Type->hasSignedIntegerRepresentation() || 7115 C.getTypeSize(Type) < NewSize); 7116 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 7117 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 7118 Sema::AA_Converting, true); 7119 if (!Diff.isUsable()) 7120 return nullptr; 7121 } 7122 } 7123 } 7124 7125 return Diff.get(); 7126 } 7127 7128 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 7129 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7130 // Do not build for iterators, they cannot be used in non-rectangular loop 7131 // nests. 7132 if (LCDecl->getType()->isRecordType()) 7133 return std::make_pair(nullptr, nullptr); 7134 // If we subtract, the min is in the condition, otherwise the min is in the 7135 // init value. 7136 Expr *MinExpr = nullptr; 7137 Expr *MaxExpr = nullptr; 7138 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 7139 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 7140 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 7141 : CondDependOnLC.hasValue(); 7142 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 7143 : InitDependOnLC.hasValue(); 7144 Expr *Lower = 7145 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7146 Expr *Upper = 7147 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7148 if (!Upper || !Lower) 7149 return std::make_pair(nullptr, nullptr); 7150 7151 if (TestIsLessOp.getValue()) 7152 MinExpr = Lower; 7153 else 7154 MaxExpr = Upper; 7155 7156 // Build minimum/maximum value based on number of iterations. 7157 ExprResult Diff; 7158 QualType VarType = LCDecl->getType().getNonReferenceType(); 7159 7160 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7161 if (!Diff.isUsable()) 7162 return std::make_pair(nullptr, nullptr); 7163 7164 // Upper - Lower [- 1] 7165 if (TestIsStrictOp) 7166 Diff = SemaRef.BuildBinOp( 7167 S, DefaultLoc, BO_Sub, Diff.get(), 7168 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7169 if (!Diff.isUsable()) 7170 return std::make_pair(nullptr, nullptr); 7171 7172 // Upper - Lower [- 1] + Step 7173 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7174 if (!NewStep.isUsable()) 7175 return std::make_pair(nullptr, nullptr); 7176 7177 // Parentheses (for dumping/debugging purposes only). 7178 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7179 if (!Diff.isUsable()) 7180 return std::make_pair(nullptr, nullptr); 7181 7182 // (Upper - Lower [- 1]) / Step 7183 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7184 if (!Diff.isUsable()) 7185 return std::make_pair(nullptr, nullptr); 7186 7187 // ((Upper - Lower [- 1]) / Step) * Step 7188 // Parentheses (for dumping/debugging purposes only). 7189 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7190 if (!Diff.isUsable()) 7191 return std::make_pair(nullptr, nullptr); 7192 7193 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 7194 if (!Diff.isUsable()) 7195 return std::make_pair(nullptr, nullptr); 7196 7197 // Convert to the original type or ptrdiff_t, if original type is pointer. 7198 if (!VarType->isAnyPointerType() && 7199 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 7200 Diff = SemaRef.PerformImplicitConversion( 7201 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 7202 } else if (VarType->isAnyPointerType() && 7203 !SemaRef.Context.hasSameType( 7204 Diff.get()->getType(), 7205 SemaRef.Context.getUnsignedPointerDiffType())) { 7206 Diff = SemaRef.PerformImplicitConversion( 7207 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 7208 Sema::AA_Converting, /*AllowExplicit=*/true); 7209 } 7210 if (!Diff.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 if (TestIsLessOp.getValue()) { 7219 // MinExpr = Lower; 7220 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 7221 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 7222 if (!Diff.isUsable()) 7223 return std::make_pair(nullptr, nullptr); 7224 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7225 if (!Diff.isUsable()) 7226 return std::make_pair(nullptr, nullptr); 7227 MaxExpr = Diff.get(); 7228 } else { 7229 // MaxExpr = Upper; 7230 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 7231 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 7232 if (!Diff.isUsable()) 7233 return std::make_pair(nullptr, nullptr); 7234 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7235 if (!Diff.isUsable()) 7236 return std::make_pair(nullptr, nullptr); 7237 MinExpr = Diff.get(); 7238 } 7239 7240 return std::make_pair(MinExpr, MaxExpr); 7241 } 7242 7243 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 7244 if (InitDependOnLC || CondDependOnLC) 7245 return Condition; 7246 return nullptr; 7247 } 7248 7249 Expr *OpenMPIterationSpaceChecker::buildPreCond( 7250 Scope *S, Expr *Cond, 7251 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7252 // Do not build a precondition when the condition/initialization is dependent 7253 // to prevent pessimistic early loop exit. 7254 // TODO: this can be improved by calculating min/max values but not sure that 7255 // it will be very effective. 7256 if (CondDependOnLC || InitDependOnLC) 7257 return SemaRef.PerformImplicitConversion( 7258 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 7259 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7260 /*AllowExplicit=*/true).get(); 7261 7262 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 7263 Sema::TentativeAnalysisScope Trap(SemaRef); 7264 7265 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 7266 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 7267 if (!NewLB.isUsable() || !NewUB.isUsable()) 7268 return nullptr; 7269 7270 ExprResult CondExpr = 7271 SemaRef.BuildBinOp(S, DefaultLoc, 7272 TestIsLessOp.getValue() ? 7273 (TestIsStrictOp ? BO_LT : BO_LE) : 7274 (TestIsStrictOp ? BO_GT : BO_GE), 7275 NewLB.get(), NewUB.get()); 7276 if (CondExpr.isUsable()) { 7277 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 7278 SemaRef.Context.BoolTy)) 7279 CondExpr = SemaRef.PerformImplicitConversion( 7280 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7281 /*AllowExplicit=*/true); 7282 } 7283 7284 // Otherwise use original loop condition and evaluate it in runtime. 7285 return CondExpr.isUsable() ? CondExpr.get() : Cond; 7286 } 7287 7288 /// Build reference expression to the counter be used for codegen. 7289 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 7290 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7291 DSAStackTy &DSA) const { 7292 auto *VD = dyn_cast<VarDecl>(LCDecl); 7293 if (!VD) { 7294 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 7295 DeclRefExpr *Ref = buildDeclRefExpr( 7296 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 7297 const DSAStackTy::DSAVarData Data = 7298 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 7299 // If the loop control decl is explicitly marked as private, do not mark it 7300 // as captured again. 7301 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 7302 Captures.insert(std::make_pair(LCRef, Ref)); 7303 return Ref; 7304 } 7305 return cast<DeclRefExpr>(LCRef); 7306 } 7307 7308 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 7309 if (LCDecl && !LCDecl->isInvalidDecl()) { 7310 QualType Type = LCDecl->getType().getNonReferenceType(); 7311 VarDecl *PrivateVar = buildVarDecl( 7312 SemaRef, DefaultLoc, Type, LCDecl->getName(), 7313 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 7314 isa<VarDecl>(LCDecl) 7315 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 7316 : nullptr); 7317 if (PrivateVar->isInvalidDecl()) 7318 return nullptr; 7319 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 7320 } 7321 return nullptr; 7322 } 7323 7324 /// Build initialization of the counter to be used for codegen. 7325 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 7326 7327 /// Build step of the counter be used for codegen. 7328 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 7329 7330 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 7331 Scope *S, Expr *Counter, 7332 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 7333 Expr *Inc, OverloadedOperatorKind OOK) { 7334 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 7335 if (!Cnt) 7336 return nullptr; 7337 if (Inc) { 7338 assert((OOK == OO_Plus || OOK == OO_Minus) && 7339 "Expected only + or - operations for depend clauses."); 7340 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 7341 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 7342 if (!Cnt) 7343 return nullptr; 7344 } 7345 ExprResult Diff; 7346 QualType VarType = LCDecl->getType().getNonReferenceType(); 7347 if (VarType->isIntegerType() || VarType->isPointerType() || 7348 SemaRef.getLangOpts().CPlusPlus) { 7349 // Upper - Lower 7350 Expr *Upper = TestIsLessOp.getValue() 7351 ? Cnt 7352 : tryBuildCapture(SemaRef, LB, Captures).get(); 7353 Expr *Lower = TestIsLessOp.getValue() 7354 ? tryBuildCapture(SemaRef, LB, Captures).get() 7355 : Cnt; 7356 if (!Upper || !Lower) 7357 return nullptr; 7358 7359 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7360 7361 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 7362 // BuildBinOp already emitted error, this one is to point user to upper 7363 // and lower bound, and to tell what is passed to 'operator-'. 7364 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7365 << Upper->getSourceRange() << Lower->getSourceRange(); 7366 return nullptr; 7367 } 7368 } 7369 7370 if (!Diff.isUsable()) 7371 return nullptr; 7372 7373 // Parentheses (for dumping/debugging purposes only). 7374 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7375 if (!Diff.isUsable()) 7376 return nullptr; 7377 7378 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7379 if (!NewStep.isUsable()) 7380 return nullptr; 7381 // (Upper - Lower) / Step 7382 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7383 if (!Diff.isUsable()) 7384 return nullptr; 7385 7386 return Diff.get(); 7387 } 7388 } // namespace 7389 7390 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 7391 assert(getLangOpts().OpenMP && "OpenMP is not active."); 7392 assert(Init && "Expected loop in canonical form."); 7393 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 7394 if (AssociatedLoops > 0 && 7395 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 7396 DSAStack->loopStart(); 7397 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 7398 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 7399 if (ValueDecl *D = ISC.getLoopDecl()) { 7400 auto *VD = dyn_cast<VarDecl>(D); 7401 DeclRefExpr *PrivateRef = nullptr; 7402 if (!VD) { 7403 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 7404 VD = Private; 7405 } else { 7406 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 7407 /*WithInit=*/false); 7408 VD = cast<VarDecl>(PrivateRef->getDecl()); 7409 } 7410 } 7411 DSAStack->addLoopControlVariable(D, VD); 7412 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 7413 if (LD != D->getCanonicalDecl()) { 7414 DSAStack->resetPossibleLoopCounter(); 7415 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 7416 MarkDeclarationsReferencedInExpr( 7417 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 7418 Var->getType().getNonLValueExprType(Context), 7419 ForLoc, /*RefersToCapture=*/true)); 7420 } 7421 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7422 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 7423 // Referenced in a Construct, C/C++]. The loop iteration variable in the 7424 // associated for-loop of a simd construct with just one associated 7425 // for-loop may be listed in a linear clause with a constant-linear-step 7426 // that is the increment of the associated for-loop. The loop iteration 7427 // variable(s) in the associated for-loop(s) of a for or parallel for 7428 // construct may be listed in a private or lastprivate clause. 7429 DSAStackTy::DSAVarData DVar = 7430 DSAStack->getTopDSA(D, /*FromParent=*/false); 7431 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 7432 // is declared in the loop and it is predetermined as a private. 7433 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 7434 OpenMPClauseKind PredeterminedCKind = 7435 isOpenMPSimdDirective(DKind) 7436 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 7437 : OMPC_private; 7438 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7439 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 7440 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 7441 DVar.CKind != OMPC_private))) || 7442 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 7443 DKind == OMPD_master_taskloop || 7444 DKind == OMPD_parallel_master_taskloop || 7445 isOpenMPDistributeDirective(DKind)) && 7446 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7447 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 7448 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 7449 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 7450 << getOpenMPClauseName(DVar.CKind) 7451 << getOpenMPDirectiveName(DKind) 7452 << getOpenMPClauseName(PredeterminedCKind); 7453 if (DVar.RefExpr == nullptr) 7454 DVar.CKind = PredeterminedCKind; 7455 reportOriginalDsa(*this, DSAStack, D, DVar, 7456 /*IsLoopIterVar=*/true); 7457 } else if (LoopDeclRefExpr) { 7458 // Make the loop iteration variable private (for worksharing 7459 // constructs), linear (for simd directives with the only one 7460 // associated loop) or lastprivate (for simd directives with several 7461 // collapsed or ordered loops). 7462 if (DVar.CKind == OMPC_unknown) 7463 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 7464 PrivateRef); 7465 } 7466 } 7467 } 7468 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 7469 } 7470 } 7471 7472 /// Called on a for stmt to check and extract its iteration space 7473 /// for further processing (such as collapsing). 7474 static bool checkOpenMPIterationSpace( 7475 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 7476 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 7477 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7478 Expr *OrderedLoopCountExpr, 7479 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7480 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7481 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7482 // OpenMP [2.9.1, Canonical Loop Form] 7483 // for (init-expr; test-expr; incr-expr) structured-block 7484 // for (range-decl: range-expr) structured-block 7485 auto *For = dyn_cast_or_null<ForStmt>(S); 7486 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7487 // Ranged for is supported only in OpenMP 5.0. 7488 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7489 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7490 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7491 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7492 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7493 if (TotalNestedLoopCount > 1) { 7494 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7495 SemaRef.Diag(DSA.getConstructLoc(), 7496 diag::note_omp_collapse_ordered_expr) 7497 << 2 << CollapseLoopCountExpr->getSourceRange() 7498 << OrderedLoopCountExpr->getSourceRange(); 7499 else if (CollapseLoopCountExpr) 7500 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7501 diag::note_omp_collapse_ordered_expr) 7502 << 0 << CollapseLoopCountExpr->getSourceRange(); 7503 else 7504 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7505 diag::note_omp_collapse_ordered_expr) 7506 << 1 << OrderedLoopCountExpr->getSourceRange(); 7507 } 7508 return true; 7509 } 7510 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7511 "No loop body."); 7512 7513 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7514 For ? For->getForLoc() : CXXFor->getForLoc()); 7515 7516 // Check init. 7517 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7518 if (ISC.checkAndSetInit(Init)) 7519 return true; 7520 7521 bool HasErrors = false; 7522 7523 // Check loop variable's type. 7524 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7525 // OpenMP [2.6, Canonical Loop Form] 7526 // Var is one of the following: 7527 // A variable of signed or unsigned integer type. 7528 // For C++, a variable of a random access iterator type. 7529 // For C, a variable of a pointer type. 7530 QualType VarType = LCDecl->getType().getNonReferenceType(); 7531 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7532 !VarType->isPointerType() && 7533 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7534 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7535 << SemaRef.getLangOpts().CPlusPlus; 7536 HasErrors = true; 7537 } 7538 7539 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7540 // a Construct 7541 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7542 // parallel for construct is (are) private. 7543 // The loop iteration variable in the associated for-loop of a simd 7544 // construct with just one associated for-loop is linear with a 7545 // constant-linear-step that is the increment of the associated for-loop. 7546 // Exclude loop var from the list of variables with implicitly defined data 7547 // sharing attributes. 7548 VarsWithImplicitDSA.erase(LCDecl); 7549 7550 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7551 7552 // Check test-expr. 7553 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7554 7555 // Check incr-expr. 7556 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7557 } 7558 7559 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7560 return HasErrors; 7561 7562 // Build the loop's iteration space representation. 7563 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7564 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7565 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7566 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7567 (isOpenMPWorksharingDirective(DKind) || 7568 isOpenMPTaskLoopDirective(DKind) || 7569 isOpenMPDistributeDirective(DKind)), 7570 Captures); 7571 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7572 ISC.buildCounterVar(Captures, DSA); 7573 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7574 ISC.buildPrivateCounterVar(); 7575 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7576 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7577 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7578 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7579 ISC.getConditionSrcRange(); 7580 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7581 ISC.getIncrementSrcRange(); 7582 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7583 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7584 ISC.isStrictTestOp(); 7585 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7586 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7587 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7588 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7589 ISC.buildFinalCondition(DSA.getCurScope()); 7590 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7591 ISC.doesInitDependOnLC(); 7592 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7593 ISC.doesCondDependOnLC(); 7594 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7595 ISC.getLoopDependentIdx(); 7596 7597 HasErrors |= 7598 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7599 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7600 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7601 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7602 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7603 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7604 if (!HasErrors && DSA.isOrderedRegion()) { 7605 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7606 if (CurrentNestedLoopCount < 7607 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7608 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7609 CurrentNestedLoopCount, 7610 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7611 DSA.getOrderedRegionParam().second->setLoopCounter( 7612 CurrentNestedLoopCount, 7613 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7614 } 7615 } 7616 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7617 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7618 // Erroneous case - clause has some problems. 7619 continue; 7620 } 7621 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7622 Pair.second.size() <= CurrentNestedLoopCount) { 7623 // Erroneous case - clause has some problems. 7624 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7625 continue; 7626 } 7627 Expr *CntValue; 7628 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7629 CntValue = ISC.buildOrderedLoopData( 7630 DSA.getCurScope(), 7631 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7632 Pair.first->getDependencyLoc()); 7633 else 7634 CntValue = ISC.buildOrderedLoopData( 7635 DSA.getCurScope(), 7636 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7637 Pair.first->getDependencyLoc(), 7638 Pair.second[CurrentNestedLoopCount].first, 7639 Pair.second[CurrentNestedLoopCount].second); 7640 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7641 } 7642 } 7643 7644 return HasErrors; 7645 } 7646 7647 /// Build 'VarRef = Start. 7648 static ExprResult 7649 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7650 ExprResult Start, bool IsNonRectangularLB, 7651 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7652 // Build 'VarRef = Start. 7653 ExprResult NewStart = IsNonRectangularLB 7654 ? Start.get() 7655 : tryBuildCapture(SemaRef, Start.get(), Captures); 7656 if (!NewStart.isUsable()) 7657 return ExprError(); 7658 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7659 VarRef.get()->getType())) { 7660 NewStart = SemaRef.PerformImplicitConversion( 7661 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7662 /*AllowExplicit=*/true); 7663 if (!NewStart.isUsable()) 7664 return ExprError(); 7665 } 7666 7667 ExprResult Init = 7668 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7669 return Init; 7670 } 7671 7672 /// Build 'VarRef = Start + Iter * Step'. 7673 static ExprResult buildCounterUpdate( 7674 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7675 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7676 bool IsNonRectangularLB, 7677 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7678 // Add parentheses (for debugging purposes only). 7679 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7680 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7681 !Step.isUsable()) 7682 return ExprError(); 7683 7684 ExprResult NewStep = Step; 7685 if (Captures) 7686 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7687 if (NewStep.isInvalid()) 7688 return ExprError(); 7689 ExprResult Update = 7690 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7691 if (!Update.isUsable()) 7692 return ExprError(); 7693 7694 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7695 // 'VarRef = Start (+|-) Iter * Step'. 7696 if (!Start.isUsable()) 7697 return ExprError(); 7698 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7699 if (!NewStart.isUsable()) 7700 return ExprError(); 7701 if (Captures && !IsNonRectangularLB) 7702 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7703 if (NewStart.isInvalid()) 7704 return ExprError(); 7705 7706 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7707 ExprResult SavedUpdate = Update; 7708 ExprResult UpdateVal; 7709 if (VarRef.get()->getType()->isOverloadableType() || 7710 NewStart.get()->getType()->isOverloadableType() || 7711 Update.get()->getType()->isOverloadableType()) { 7712 Sema::TentativeAnalysisScope Trap(SemaRef); 7713 7714 Update = 7715 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7716 if (Update.isUsable()) { 7717 UpdateVal = 7718 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7719 VarRef.get(), SavedUpdate.get()); 7720 if (UpdateVal.isUsable()) { 7721 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7722 UpdateVal.get()); 7723 } 7724 } 7725 } 7726 7727 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7728 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7729 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7730 NewStart.get(), SavedUpdate.get()); 7731 if (!Update.isUsable()) 7732 return ExprError(); 7733 7734 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7735 VarRef.get()->getType())) { 7736 Update = SemaRef.PerformImplicitConversion( 7737 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7738 if (!Update.isUsable()) 7739 return ExprError(); 7740 } 7741 7742 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7743 } 7744 return Update; 7745 } 7746 7747 /// Convert integer expression \a E to make it have at least \a Bits 7748 /// bits. 7749 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7750 if (E == nullptr) 7751 return ExprError(); 7752 ASTContext &C = SemaRef.Context; 7753 QualType OldType = E->getType(); 7754 unsigned HasBits = C.getTypeSize(OldType); 7755 if (HasBits >= Bits) 7756 return ExprResult(E); 7757 // OK to convert to signed, because new type has more bits than old. 7758 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7759 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7760 true); 7761 } 7762 7763 /// Check if the given expression \a E is a constant integer that fits 7764 /// into \a Bits bits. 7765 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7766 if (E == nullptr) 7767 return false; 7768 llvm::APSInt Result; 7769 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7770 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7771 return false; 7772 } 7773 7774 /// Build preinits statement for the given declarations. 7775 static Stmt *buildPreInits(ASTContext &Context, 7776 MutableArrayRef<Decl *> PreInits) { 7777 if (!PreInits.empty()) { 7778 return new (Context) DeclStmt( 7779 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7780 SourceLocation(), SourceLocation()); 7781 } 7782 return nullptr; 7783 } 7784 7785 /// Build preinits statement for the given declarations. 7786 static Stmt * 7787 buildPreInits(ASTContext &Context, 7788 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7789 if (!Captures.empty()) { 7790 SmallVector<Decl *, 16> PreInits; 7791 for (const auto &Pair : Captures) 7792 PreInits.push_back(Pair.second->getDecl()); 7793 return buildPreInits(Context, PreInits); 7794 } 7795 return nullptr; 7796 } 7797 7798 /// Build postupdate expression for the given list of postupdates expressions. 7799 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7800 Expr *PostUpdate = nullptr; 7801 if (!PostUpdates.empty()) { 7802 for (Expr *E : PostUpdates) { 7803 Expr *ConvE = S.BuildCStyleCastExpr( 7804 E->getExprLoc(), 7805 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7806 E->getExprLoc(), E) 7807 .get(); 7808 PostUpdate = PostUpdate 7809 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7810 PostUpdate, ConvE) 7811 .get() 7812 : ConvE; 7813 } 7814 } 7815 return PostUpdate; 7816 } 7817 7818 /// Called on a for stmt to check itself and nested loops (if any). 7819 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7820 /// number of collapsed loops otherwise. 7821 static unsigned 7822 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7823 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7824 DSAStackTy &DSA, 7825 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7826 OMPLoopDirective::HelperExprs &Built) { 7827 unsigned NestedLoopCount = 1; 7828 if (CollapseLoopCountExpr) { 7829 // Found 'collapse' clause - calculate collapse number. 7830 Expr::EvalResult Result; 7831 if (!CollapseLoopCountExpr->isValueDependent() && 7832 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7833 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7834 } else { 7835 Built.clear(/*Size=*/1); 7836 return 1; 7837 } 7838 } 7839 unsigned OrderedLoopCount = 1; 7840 if (OrderedLoopCountExpr) { 7841 // Found 'ordered' clause - calculate collapse number. 7842 Expr::EvalResult EVResult; 7843 if (!OrderedLoopCountExpr->isValueDependent() && 7844 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7845 SemaRef.getASTContext())) { 7846 llvm::APSInt Result = EVResult.Val.getInt(); 7847 if (Result.getLimitedValue() < NestedLoopCount) { 7848 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7849 diag::err_omp_wrong_ordered_loop_count) 7850 << OrderedLoopCountExpr->getSourceRange(); 7851 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7852 diag::note_collapse_loop_count) 7853 << CollapseLoopCountExpr->getSourceRange(); 7854 } 7855 OrderedLoopCount = Result.getLimitedValue(); 7856 } else { 7857 Built.clear(/*Size=*/1); 7858 return 1; 7859 } 7860 } 7861 // This is helper routine for loop directives (e.g., 'for', 'simd', 7862 // 'for simd', etc.). 7863 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7864 SmallVector<LoopIterationSpace, 4> IterSpaces( 7865 std::max(OrderedLoopCount, NestedLoopCount)); 7866 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7867 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7868 if (checkOpenMPIterationSpace( 7869 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7870 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7871 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7872 return 0; 7873 // Move on to the next nested for loop, or to the loop body. 7874 // OpenMP [2.8.1, simd construct, Restrictions] 7875 // All loops associated with the construct must be perfectly nested; that 7876 // is, there must be no intervening code nor any OpenMP directive between 7877 // any two loops. 7878 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7879 CurStmt = For->getBody(); 7880 } else { 7881 assert(isa<CXXForRangeStmt>(CurStmt) && 7882 "Expected canonical for or range-based for loops."); 7883 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7884 } 7885 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7886 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7887 } 7888 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7889 if (checkOpenMPIterationSpace( 7890 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7891 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7892 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7893 return 0; 7894 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7895 // Handle initialization of captured loop iterator variables. 7896 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7897 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7898 Captures[DRE] = DRE; 7899 } 7900 } 7901 // Move on to the next nested for loop, or to the loop body. 7902 // OpenMP [2.8.1, simd construct, Restrictions] 7903 // All loops associated with the construct must be perfectly nested; that 7904 // is, there must be no intervening code nor any OpenMP directive between 7905 // any two loops. 7906 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7907 CurStmt = For->getBody(); 7908 } else { 7909 assert(isa<CXXForRangeStmt>(CurStmt) && 7910 "Expected canonical for or range-based for loops."); 7911 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7912 } 7913 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7914 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7915 } 7916 7917 Built.clear(/* size */ NestedLoopCount); 7918 7919 if (SemaRef.CurContext->isDependentContext()) 7920 return NestedLoopCount; 7921 7922 // An example of what is generated for the following code: 7923 // 7924 // #pragma omp simd collapse(2) ordered(2) 7925 // for (i = 0; i < NI; ++i) 7926 // for (k = 0; k < NK; ++k) 7927 // for (j = J0; j < NJ; j+=2) { 7928 // <loop body> 7929 // } 7930 // 7931 // We generate the code below. 7932 // Note: the loop body may be outlined in CodeGen. 7933 // Note: some counters may be C++ classes, operator- is used to find number of 7934 // iterations and operator+= to calculate counter value. 7935 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7936 // or i64 is currently supported). 7937 // 7938 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7939 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7940 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7941 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7942 // // similar updates for vars in clauses (e.g. 'linear') 7943 // <loop body (using local i and j)> 7944 // } 7945 // i = NI; // assign final values of counters 7946 // j = NJ; 7947 // 7948 7949 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7950 // the iteration counts of the collapsed for loops. 7951 // Precondition tests if there is at least one iteration (all conditions are 7952 // true). 7953 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7954 Expr *N0 = IterSpaces[0].NumIterations; 7955 ExprResult LastIteration32 = 7956 widenIterationCount(/*Bits=*/32, 7957 SemaRef 7958 .PerformImplicitConversion( 7959 N0->IgnoreImpCasts(), N0->getType(), 7960 Sema::AA_Converting, /*AllowExplicit=*/true) 7961 .get(), 7962 SemaRef); 7963 ExprResult LastIteration64 = widenIterationCount( 7964 /*Bits=*/64, 7965 SemaRef 7966 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7967 Sema::AA_Converting, 7968 /*AllowExplicit=*/true) 7969 .get(), 7970 SemaRef); 7971 7972 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7973 return NestedLoopCount; 7974 7975 ASTContext &C = SemaRef.Context; 7976 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7977 7978 Scope *CurScope = DSA.getCurScope(); 7979 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7980 if (PreCond.isUsable()) { 7981 PreCond = 7982 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7983 PreCond.get(), IterSpaces[Cnt].PreCond); 7984 } 7985 Expr *N = IterSpaces[Cnt].NumIterations; 7986 SourceLocation Loc = N->getExprLoc(); 7987 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7988 if (LastIteration32.isUsable()) 7989 LastIteration32 = SemaRef.BuildBinOp( 7990 CurScope, Loc, BO_Mul, LastIteration32.get(), 7991 SemaRef 7992 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7993 Sema::AA_Converting, 7994 /*AllowExplicit=*/true) 7995 .get()); 7996 if (LastIteration64.isUsable()) 7997 LastIteration64 = SemaRef.BuildBinOp( 7998 CurScope, Loc, BO_Mul, LastIteration64.get(), 7999 SemaRef 8000 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 8001 Sema::AA_Converting, 8002 /*AllowExplicit=*/true) 8003 .get()); 8004 } 8005 8006 // Choose either the 32-bit or 64-bit version. 8007 ExprResult LastIteration = LastIteration64; 8008 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 8009 (LastIteration32.isUsable() && 8010 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 8011 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 8012 fitsInto( 8013 /*Bits=*/32, 8014 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 8015 LastIteration64.get(), SemaRef)))) 8016 LastIteration = LastIteration32; 8017 QualType VType = LastIteration.get()->getType(); 8018 QualType RealVType = VType; 8019 QualType StrideVType = VType; 8020 if (isOpenMPTaskLoopDirective(DKind)) { 8021 VType = 8022 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 8023 StrideVType = 8024 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 8025 } 8026 8027 if (!LastIteration.isUsable()) 8028 return 0; 8029 8030 // Save the number of iterations. 8031 ExprResult NumIterations = LastIteration; 8032 { 8033 LastIteration = SemaRef.BuildBinOp( 8034 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 8035 LastIteration.get(), 8036 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8037 if (!LastIteration.isUsable()) 8038 return 0; 8039 } 8040 8041 // Calculate the last iteration number beforehand instead of doing this on 8042 // each iteration. Do not do this if the number of iterations may be kfold-ed. 8043 llvm::APSInt Result; 8044 bool IsConstant = 8045 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 8046 ExprResult CalcLastIteration; 8047 if (!IsConstant) { 8048 ExprResult SaveRef = 8049 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 8050 LastIteration = SaveRef; 8051 8052 // Prepare SaveRef + 1. 8053 NumIterations = SemaRef.BuildBinOp( 8054 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 8055 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8056 if (!NumIterations.isUsable()) 8057 return 0; 8058 } 8059 8060 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 8061 8062 // Build variables passed into runtime, necessary for worksharing directives. 8063 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 8064 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8065 isOpenMPDistributeDirective(DKind)) { 8066 // Lower bound variable, initialized with zero. 8067 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 8068 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 8069 SemaRef.AddInitializerToDecl(LBDecl, 8070 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8071 /*DirectInit*/ false); 8072 8073 // Upper bound variable, initialized with last iteration number. 8074 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 8075 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 8076 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 8077 /*DirectInit*/ false); 8078 8079 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 8080 // This will be used to implement clause 'lastprivate'. 8081 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 8082 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 8083 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 8084 SemaRef.AddInitializerToDecl(ILDecl, 8085 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8086 /*DirectInit*/ false); 8087 8088 // Stride variable returned by runtime (we initialize it to 1 by default). 8089 VarDecl *STDecl = 8090 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 8091 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 8092 SemaRef.AddInitializerToDecl(STDecl, 8093 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 8094 /*DirectInit*/ false); 8095 8096 // Build expression: UB = min(UB, LastIteration) 8097 // It is necessary for CodeGen of directives with static scheduling. 8098 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 8099 UB.get(), LastIteration.get()); 8100 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8101 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 8102 LastIteration.get(), UB.get()); 8103 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 8104 CondOp.get()); 8105 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 8106 8107 // If we have a combined directive that combines 'distribute', 'for' or 8108 // 'simd' we need to be able to access the bounds of the schedule of the 8109 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 8110 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 8111 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8112 // Lower bound variable, initialized with zero. 8113 VarDecl *CombLBDecl = 8114 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 8115 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 8116 SemaRef.AddInitializerToDecl( 8117 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8118 /*DirectInit*/ false); 8119 8120 // Upper bound variable, initialized with last iteration number. 8121 VarDecl *CombUBDecl = 8122 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 8123 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 8124 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 8125 /*DirectInit*/ false); 8126 8127 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 8128 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 8129 ExprResult CombCondOp = 8130 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 8131 LastIteration.get(), CombUB.get()); 8132 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 8133 CombCondOp.get()); 8134 CombEUB = 8135 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 8136 8137 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 8138 // We expect to have at least 2 more parameters than the 'parallel' 8139 // directive does - the lower and upper bounds of the previous schedule. 8140 assert(CD->getNumParams() >= 4 && 8141 "Unexpected number of parameters in loop combined directive"); 8142 8143 // Set the proper type for the bounds given what we learned from the 8144 // enclosed loops. 8145 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 8146 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 8147 8148 // Previous lower and upper bounds are obtained from the region 8149 // parameters. 8150 PrevLB = 8151 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 8152 PrevUB = 8153 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 8154 } 8155 } 8156 8157 // Build the iteration variable and its initialization before loop. 8158 ExprResult IV; 8159 ExprResult Init, CombInit; 8160 { 8161 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 8162 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 8163 Expr *RHS = 8164 (isOpenMPWorksharingDirective(DKind) || 8165 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8166 ? LB.get() 8167 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8168 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 8169 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 8170 8171 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8172 Expr *CombRHS = 8173 (isOpenMPWorksharingDirective(DKind) || 8174 isOpenMPTaskLoopDirective(DKind) || 8175 isOpenMPDistributeDirective(DKind)) 8176 ? CombLB.get() 8177 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8178 CombInit = 8179 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 8180 CombInit = 8181 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 8182 } 8183 } 8184 8185 bool UseStrictCompare = 8186 RealVType->hasUnsignedIntegerRepresentation() && 8187 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 8188 return LIS.IsStrictCompare; 8189 }); 8190 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 8191 // unsigned IV)) for worksharing loops. 8192 SourceLocation CondLoc = AStmt->getBeginLoc(); 8193 Expr *BoundUB = UB.get(); 8194 if (UseStrictCompare) { 8195 BoundUB = 8196 SemaRef 8197 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 8198 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8199 .get(); 8200 BoundUB = 8201 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 8202 } 8203 ExprResult Cond = 8204 (isOpenMPWorksharingDirective(DKind) || 8205 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8206 ? SemaRef.BuildBinOp(CurScope, CondLoc, 8207 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 8208 BoundUB) 8209 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8210 NumIterations.get()); 8211 ExprResult CombDistCond; 8212 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8213 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8214 NumIterations.get()); 8215 } 8216 8217 ExprResult CombCond; 8218 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8219 Expr *BoundCombUB = CombUB.get(); 8220 if (UseStrictCompare) { 8221 BoundCombUB = 8222 SemaRef 8223 .BuildBinOp( 8224 CurScope, CondLoc, BO_Add, BoundCombUB, 8225 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8226 .get(); 8227 BoundCombUB = 8228 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 8229 .get(); 8230 } 8231 CombCond = 8232 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8233 IV.get(), BoundCombUB); 8234 } 8235 // Loop increment (IV = IV + 1) 8236 SourceLocation IncLoc = AStmt->getBeginLoc(); 8237 ExprResult Inc = 8238 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 8239 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 8240 if (!Inc.isUsable()) 8241 return 0; 8242 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 8243 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 8244 if (!Inc.isUsable()) 8245 return 0; 8246 8247 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 8248 // Used for directives with static scheduling. 8249 // In combined construct, add combined version that use CombLB and CombUB 8250 // base variables for the update 8251 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 8252 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8253 isOpenMPDistributeDirective(DKind)) { 8254 // LB + ST 8255 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 8256 if (!NextLB.isUsable()) 8257 return 0; 8258 // LB = LB + ST 8259 NextLB = 8260 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 8261 NextLB = 8262 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 8263 if (!NextLB.isUsable()) 8264 return 0; 8265 // UB + ST 8266 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 8267 if (!NextUB.isUsable()) 8268 return 0; 8269 // UB = UB + ST 8270 NextUB = 8271 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 8272 NextUB = 8273 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 8274 if (!NextUB.isUsable()) 8275 return 0; 8276 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8277 CombNextLB = 8278 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 8279 if (!NextLB.isUsable()) 8280 return 0; 8281 // LB = LB + ST 8282 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 8283 CombNextLB.get()); 8284 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 8285 /*DiscardedValue*/ false); 8286 if (!CombNextLB.isUsable()) 8287 return 0; 8288 // UB + ST 8289 CombNextUB = 8290 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 8291 if (!CombNextUB.isUsable()) 8292 return 0; 8293 // UB = UB + ST 8294 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 8295 CombNextUB.get()); 8296 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 8297 /*DiscardedValue*/ false); 8298 if (!CombNextUB.isUsable()) 8299 return 0; 8300 } 8301 } 8302 8303 // Create increment expression for distribute loop when combined in a same 8304 // directive with for as IV = IV + ST; ensure upper bound expression based 8305 // on PrevUB instead of NumIterations - used to implement 'for' when found 8306 // in combination with 'distribute', like in 'distribute parallel for' 8307 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 8308 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 8309 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8310 DistCond = SemaRef.BuildBinOp( 8311 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 8312 assert(DistCond.isUsable() && "distribute cond expr was not built"); 8313 8314 DistInc = 8315 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 8316 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8317 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 8318 DistInc.get()); 8319 DistInc = 8320 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 8321 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8322 8323 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 8324 // construct 8325 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 8326 ExprResult IsUBGreater = 8327 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 8328 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8329 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 8330 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 8331 CondOp.get()); 8332 PrevEUB = 8333 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 8334 8335 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 8336 // parallel for is in combination with a distribute directive with 8337 // schedule(static, 1) 8338 Expr *BoundPrevUB = PrevUB.get(); 8339 if (UseStrictCompare) { 8340 BoundPrevUB = 8341 SemaRef 8342 .BuildBinOp( 8343 CurScope, CondLoc, BO_Add, BoundPrevUB, 8344 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8345 .get(); 8346 BoundPrevUB = 8347 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 8348 .get(); 8349 } 8350 ParForInDistCond = 8351 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8352 IV.get(), BoundPrevUB); 8353 } 8354 8355 // Build updates and final values of the loop counters. 8356 bool HasErrors = false; 8357 Built.Counters.resize(NestedLoopCount); 8358 Built.Inits.resize(NestedLoopCount); 8359 Built.Updates.resize(NestedLoopCount); 8360 Built.Finals.resize(NestedLoopCount); 8361 Built.DependentCounters.resize(NestedLoopCount); 8362 Built.DependentInits.resize(NestedLoopCount); 8363 Built.FinalsConditions.resize(NestedLoopCount); 8364 { 8365 // We implement the following algorithm for obtaining the 8366 // original loop iteration variable values based on the 8367 // value of the collapsed loop iteration variable IV. 8368 // 8369 // Let n+1 be the number of collapsed loops in the nest. 8370 // Iteration variables (I0, I1, .... In) 8371 // Iteration counts (N0, N1, ... Nn) 8372 // 8373 // Acc = IV; 8374 // 8375 // To compute Ik for loop k, 0 <= k <= n, generate: 8376 // Prod = N(k+1) * N(k+2) * ... * Nn; 8377 // Ik = Acc / Prod; 8378 // Acc -= Ik * Prod; 8379 // 8380 ExprResult Acc = IV; 8381 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8382 LoopIterationSpace &IS = IterSpaces[Cnt]; 8383 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 8384 ExprResult Iter; 8385 8386 // Compute prod 8387 ExprResult Prod = 8388 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 8389 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 8390 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 8391 IterSpaces[K].NumIterations); 8392 8393 // Iter = Acc / Prod 8394 // If there is at least one more inner loop to avoid 8395 // multiplication by 1. 8396 if (Cnt + 1 < NestedLoopCount) 8397 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 8398 Acc.get(), Prod.get()); 8399 else 8400 Iter = Acc; 8401 if (!Iter.isUsable()) { 8402 HasErrors = true; 8403 break; 8404 } 8405 8406 // Update Acc: 8407 // Acc -= Iter * Prod 8408 // Check if there is at least one more inner loop to avoid 8409 // multiplication by 1. 8410 if (Cnt + 1 < NestedLoopCount) 8411 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 8412 Iter.get(), Prod.get()); 8413 else 8414 Prod = Iter; 8415 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 8416 Acc.get(), Prod.get()); 8417 8418 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 8419 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 8420 DeclRefExpr *CounterVar = buildDeclRefExpr( 8421 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 8422 /*RefersToCapture=*/true); 8423 ExprResult Init = 8424 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 8425 IS.CounterInit, IS.IsNonRectangularLB, Captures); 8426 if (!Init.isUsable()) { 8427 HasErrors = true; 8428 break; 8429 } 8430 ExprResult Update = buildCounterUpdate( 8431 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 8432 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 8433 if (!Update.isUsable()) { 8434 HasErrors = true; 8435 break; 8436 } 8437 8438 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 8439 ExprResult Final = 8440 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 8441 IS.CounterInit, IS.NumIterations, IS.CounterStep, 8442 IS.Subtract, IS.IsNonRectangularLB, &Captures); 8443 if (!Final.isUsable()) { 8444 HasErrors = true; 8445 break; 8446 } 8447 8448 if (!Update.isUsable() || !Final.isUsable()) { 8449 HasErrors = true; 8450 break; 8451 } 8452 // Save results 8453 Built.Counters[Cnt] = IS.CounterVar; 8454 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 8455 Built.Inits[Cnt] = Init.get(); 8456 Built.Updates[Cnt] = Update.get(); 8457 Built.Finals[Cnt] = Final.get(); 8458 Built.DependentCounters[Cnt] = nullptr; 8459 Built.DependentInits[Cnt] = nullptr; 8460 Built.FinalsConditions[Cnt] = nullptr; 8461 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 8462 Built.DependentCounters[Cnt] = 8463 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8464 Built.DependentInits[Cnt] = 8465 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8466 Built.FinalsConditions[Cnt] = IS.FinalCondition; 8467 } 8468 } 8469 } 8470 8471 if (HasErrors) 8472 return 0; 8473 8474 // Save results 8475 Built.IterationVarRef = IV.get(); 8476 Built.LastIteration = LastIteration.get(); 8477 Built.NumIterations = NumIterations.get(); 8478 Built.CalcLastIteration = SemaRef 8479 .ActOnFinishFullExpr(CalcLastIteration.get(), 8480 /*DiscardedValue=*/false) 8481 .get(); 8482 Built.PreCond = PreCond.get(); 8483 Built.PreInits = buildPreInits(C, Captures); 8484 Built.Cond = Cond.get(); 8485 Built.Init = Init.get(); 8486 Built.Inc = Inc.get(); 8487 Built.LB = LB.get(); 8488 Built.UB = UB.get(); 8489 Built.IL = IL.get(); 8490 Built.ST = ST.get(); 8491 Built.EUB = EUB.get(); 8492 Built.NLB = NextLB.get(); 8493 Built.NUB = NextUB.get(); 8494 Built.PrevLB = PrevLB.get(); 8495 Built.PrevUB = PrevUB.get(); 8496 Built.DistInc = DistInc.get(); 8497 Built.PrevEUB = PrevEUB.get(); 8498 Built.DistCombinedFields.LB = CombLB.get(); 8499 Built.DistCombinedFields.UB = CombUB.get(); 8500 Built.DistCombinedFields.EUB = CombEUB.get(); 8501 Built.DistCombinedFields.Init = CombInit.get(); 8502 Built.DistCombinedFields.Cond = CombCond.get(); 8503 Built.DistCombinedFields.NLB = CombNextLB.get(); 8504 Built.DistCombinedFields.NUB = CombNextUB.get(); 8505 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8506 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8507 8508 return NestedLoopCount; 8509 } 8510 8511 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8512 auto CollapseClauses = 8513 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8514 if (CollapseClauses.begin() != CollapseClauses.end()) 8515 return (*CollapseClauses.begin())->getNumForLoops(); 8516 return nullptr; 8517 } 8518 8519 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8520 auto OrderedClauses = 8521 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8522 if (OrderedClauses.begin() != OrderedClauses.end()) 8523 return (*OrderedClauses.begin())->getNumForLoops(); 8524 return nullptr; 8525 } 8526 8527 static bool checkSimdlenSafelenSpecified(Sema &S, 8528 const ArrayRef<OMPClause *> Clauses) { 8529 const OMPSafelenClause *Safelen = nullptr; 8530 const OMPSimdlenClause *Simdlen = nullptr; 8531 8532 for (const OMPClause *Clause : Clauses) { 8533 if (Clause->getClauseKind() == OMPC_safelen) 8534 Safelen = cast<OMPSafelenClause>(Clause); 8535 else if (Clause->getClauseKind() == OMPC_simdlen) 8536 Simdlen = cast<OMPSimdlenClause>(Clause); 8537 if (Safelen && Simdlen) 8538 break; 8539 } 8540 8541 if (Simdlen && Safelen) { 8542 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8543 const Expr *SafelenLength = Safelen->getSafelen(); 8544 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8545 SimdlenLength->isInstantiationDependent() || 8546 SimdlenLength->containsUnexpandedParameterPack()) 8547 return false; 8548 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8549 SafelenLength->isInstantiationDependent() || 8550 SafelenLength->containsUnexpandedParameterPack()) 8551 return false; 8552 Expr::EvalResult SimdlenResult, SafelenResult; 8553 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8554 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8555 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8556 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8557 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8558 // If both simdlen and safelen clauses are specified, the value of the 8559 // simdlen parameter must be less than or equal to the value of the safelen 8560 // parameter. 8561 if (SimdlenRes > SafelenRes) { 8562 S.Diag(SimdlenLength->getExprLoc(), 8563 diag::err_omp_wrong_simdlen_safelen_values) 8564 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8565 return true; 8566 } 8567 } 8568 return false; 8569 } 8570 8571 StmtResult 8572 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8573 SourceLocation StartLoc, SourceLocation EndLoc, 8574 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8575 if (!AStmt) 8576 return StmtError(); 8577 8578 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8579 OMPLoopDirective::HelperExprs B; 8580 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8581 // define the nested loops number. 8582 unsigned NestedLoopCount = checkOpenMPLoop( 8583 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8584 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8585 if (NestedLoopCount == 0) 8586 return StmtError(); 8587 8588 assert((CurContext->isDependentContext() || B.builtAll()) && 8589 "omp simd loop exprs were not built"); 8590 8591 if (!CurContext->isDependentContext()) { 8592 // Finalize the clauses that need pre-built expressions for CodeGen. 8593 for (OMPClause *C : Clauses) { 8594 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8595 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8596 B.NumIterations, *this, CurScope, 8597 DSAStack)) 8598 return StmtError(); 8599 } 8600 } 8601 8602 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8603 return StmtError(); 8604 8605 setFunctionHasBranchProtectedScope(); 8606 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8607 Clauses, AStmt, B); 8608 } 8609 8610 StmtResult 8611 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8612 SourceLocation StartLoc, SourceLocation EndLoc, 8613 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8614 if (!AStmt) 8615 return StmtError(); 8616 8617 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8618 OMPLoopDirective::HelperExprs B; 8619 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8620 // define the nested loops number. 8621 unsigned NestedLoopCount = checkOpenMPLoop( 8622 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8623 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8624 if (NestedLoopCount == 0) 8625 return StmtError(); 8626 8627 assert((CurContext->isDependentContext() || B.builtAll()) && 8628 "omp for loop exprs were not built"); 8629 8630 if (!CurContext->isDependentContext()) { 8631 // Finalize the clauses that need pre-built expressions for CodeGen. 8632 for (OMPClause *C : Clauses) { 8633 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8634 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8635 B.NumIterations, *this, CurScope, 8636 DSAStack)) 8637 return StmtError(); 8638 } 8639 } 8640 8641 setFunctionHasBranchProtectedScope(); 8642 return OMPForDirective::Create( 8643 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8644 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 8645 } 8646 8647 StmtResult Sema::ActOnOpenMPForSimdDirective( 8648 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8649 SourceLocation EndLoc, 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 = 8658 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8659 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8660 VarsWithImplicitDSA, B); 8661 if (NestedLoopCount == 0) 8662 return StmtError(); 8663 8664 assert((CurContext->isDependentContext() || B.builtAll()) && 8665 "omp for simd loop exprs were not built"); 8666 8667 if (!CurContext->isDependentContext()) { 8668 // Finalize the clauses that need pre-built expressions for CodeGen. 8669 for (OMPClause *C : Clauses) { 8670 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8671 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8672 B.NumIterations, *this, CurScope, 8673 DSAStack)) 8674 return StmtError(); 8675 } 8676 } 8677 8678 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8679 return StmtError(); 8680 8681 setFunctionHasBranchProtectedScope(); 8682 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8683 Clauses, AStmt, B); 8684 } 8685 8686 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8687 Stmt *AStmt, 8688 SourceLocation StartLoc, 8689 SourceLocation EndLoc) { 8690 if (!AStmt) 8691 return StmtError(); 8692 8693 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8694 auto BaseStmt = AStmt; 8695 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8696 BaseStmt = CS->getCapturedStmt(); 8697 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8698 auto S = C->children(); 8699 if (S.begin() == S.end()) 8700 return StmtError(); 8701 // All associated statements must be '#pragma omp section' except for 8702 // the first one. 8703 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8704 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8705 if (SectionStmt) 8706 Diag(SectionStmt->getBeginLoc(), 8707 diag::err_omp_sections_substmt_not_section); 8708 return StmtError(); 8709 } 8710 cast<OMPSectionDirective>(SectionStmt) 8711 ->setHasCancel(DSAStack->isCancelRegion()); 8712 } 8713 } else { 8714 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8715 return StmtError(); 8716 } 8717 8718 setFunctionHasBranchProtectedScope(); 8719 8720 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8721 DSAStack->getTaskgroupReductionRef(), 8722 DSAStack->isCancelRegion()); 8723 } 8724 8725 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8726 SourceLocation StartLoc, 8727 SourceLocation EndLoc) { 8728 if (!AStmt) 8729 return StmtError(); 8730 8731 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8732 8733 setFunctionHasBranchProtectedScope(); 8734 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8735 8736 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8737 DSAStack->isCancelRegion()); 8738 } 8739 8740 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8741 Stmt *AStmt, 8742 SourceLocation StartLoc, 8743 SourceLocation EndLoc) { 8744 if (!AStmt) 8745 return StmtError(); 8746 8747 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8748 8749 setFunctionHasBranchProtectedScope(); 8750 8751 // OpenMP [2.7.3, single Construct, Restrictions] 8752 // The copyprivate clause must not be used with the nowait clause. 8753 const OMPClause *Nowait = nullptr; 8754 const OMPClause *Copyprivate = nullptr; 8755 for (const OMPClause *Clause : Clauses) { 8756 if (Clause->getClauseKind() == OMPC_nowait) 8757 Nowait = Clause; 8758 else if (Clause->getClauseKind() == OMPC_copyprivate) 8759 Copyprivate = Clause; 8760 if (Copyprivate && Nowait) { 8761 Diag(Copyprivate->getBeginLoc(), 8762 diag::err_omp_single_copyprivate_with_nowait); 8763 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8764 return StmtError(); 8765 } 8766 } 8767 8768 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8769 } 8770 8771 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8772 SourceLocation StartLoc, 8773 SourceLocation EndLoc) { 8774 if (!AStmt) 8775 return StmtError(); 8776 8777 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8778 8779 setFunctionHasBranchProtectedScope(); 8780 8781 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8782 } 8783 8784 StmtResult Sema::ActOnOpenMPCriticalDirective( 8785 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8786 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8787 if (!AStmt) 8788 return StmtError(); 8789 8790 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8791 8792 bool ErrorFound = false; 8793 llvm::APSInt Hint; 8794 SourceLocation HintLoc; 8795 bool DependentHint = false; 8796 for (const OMPClause *C : Clauses) { 8797 if (C->getClauseKind() == OMPC_hint) { 8798 if (!DirName.getName()) { 8799 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8800 ErrorFound = true; 8801 } 8802 Expr *E = cast<OMPHintClause>(C)->getHint(); 8803 if (E->isTypeDependent() || E->isValueDependent() || 8804 E->isInstantiationDependent()) { 8805 DependentHint = true; 8806 } else { 8807 Hint = E->EvaluateKnownConstInt(Context); 8808 HintLoc = C->getBeginLoc(); 8809 } 8810 } 8811 } 8812 if (ErrorFound) 8813 return StmtError(); 8814 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8815 if (Pair.first && DirName.getName() && !DependentHint) { 8816 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8817 Diag(StartLoc, diag::err_omp_critical_with_hint); 8818 if (HintLoc.isValid()) 8819 Diag(HintLoc, diag::note_omp_critical_hint_here) 8820 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8821 else 8822 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8823 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8824 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8825 << 1 8826 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8827 /*Radix=*/10, /*Signed=*/false); 8828 } else { 8829 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8830 } 8831 } 8832 } 8833 8834 setFunctionHasBranchProtectedScope(); 8835 8836 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8837 Clauses, AStmt); 8838 if (!Pair.first && DirName.getName() && !DependentHint) 8839 DSAStack->addCriticalWithHint(Dir, Hint); 8840 return Dir; 8841 } 8842 8843 StmtResult Sema::ActOnOpenMPParallelForDirective( 8844 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8845 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8846 if (!AStmt) 8847 return StmtError(); 8848 8849 auto *CS = cast<CapturedStmt>(AStmt); 8850 // 1.2.2 OpenMP Language Terminology 8851 // Structured block - An executable statement with a single entry at the 8852 // top and a single exit at the bottom. 8853 // The point of exit cannot be a branch out of the structured block. 8854 // longjmp() and throw() must not violate the entry/exit criteria. 8855 CS->getCapturedDecl()->setNothrow(); 8856 8857 OMPLoopDirective::HelperExprs B; 8858 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8859 // define the nested loops number. 8860 unsigned NestedLoopCount = 8861 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8862 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8863 VarsWithImplicitDSA, B); 8864 if (NestedLoopCount == 0) 8865 return StmtError(); 8866 8867 assert((CurContext->isDependentContext() || B.builtAll()) && 8868 "omp parallel for loop exprs were not built"); 8869 8870 if (!CurContext->isDependentContext()) { 8871 // Finalize the clauses that need pre-built expressions for CodeGen. 8872 for (OMPClause *C : Clauses) { 8873 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8874 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8875 B.NumIterations, *this, CurScope, 8876 DSAStack)) 8877 return StmtError(); 8878 } 8879 } 8880 8881 setFunctionHasBranchProtectedScope(); 8882 return OMPParallelForDirective::Create( 8883 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8884 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 8885 } 8886 8887 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8888 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8889 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8890 if (!AStmt) 8891 return StmtError(); 8892 8893 auto *CS = cast<CapturedStmt>(AStmt); 8894 // 1.2.2 OpenMP Language Terminology 8895 // Structured block - An executable statement with a single entry at the 8896 // top and a single exit at the bottom. 8897 // The point of exit cannot be a branch out of the structured block. 8898 // longjmp() and throw() must not violate the entry/exit criteria. 8899 CS->getCapturedDecl()->setNothrow(); 8900 8901 OMPLoopDirective::HelperExprs B; 8902 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8903 // define the nested loops number. 8904 unsigned NestedLoopCount = 8905 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8906 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8907 VarsWithImplicitDSA, B); 8908 if (NestedLoopCount == 0) 8909 return StmtError(); 8910 8911 if (!CurContext->isDependentContext()) { 8912 // Finalize the clauses that need pre-built expressions for CodeGen. 8913 for (OMPClause *C : Clauses) { 8914 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8915 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8916 B.NumIterations, *this, CurScope, 8917 DSAStack)) 8918 return StmtError(); 8919 } 8920 } 8921 8922 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8923 return StmtError(); 8924 8925 setFunctionHasBranchProtectedScope(); 8926 return OMPParallelForSimdDirective::Create( 8927 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8928 } 8929 8930 StmtResult 8931 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8932 Stmt *AStmt, SourceLocation StartLoc, 8933 SourceLocation EndLoc) { 8934 if (!AStmt) 8935 return StmtError(); 8936 8937 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8938 auto *CS = cast<CapturedStmt>(AStmt); 8939 // 1.2.2 OpenMP Language Terminology 8940 // Structured block - An executable statement with a single entry at the 8941 // top and a single exit at the bottom. 8942 // The point of exit cannot be a branch out of the structured block. 8943 // longjmp() and throw() must not violate the entry/exit criteria. 8944 CS->getCapturedDecl()->setNothrow(); 8945 8946 setFunctionHasBranchProtectedScope(); 8947 8948 return OMPParallelMasterDirective::Create( 8949 Context, StartLoc, EndLoc, Clauses, AStmt, 8950 DSAStack->getTaskgroupReductionRef()); 8951 } 8952 8953 StmtResult 8954 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8955 Stmt *AStmt, SourceLocation StartLoc, 8956 SourceLocation EndLoc) { 8957 if (!AStmt) 8958 return StmtError(); 8959 8960 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8961 auto BaseStmt = AStmt; 8962 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8963 BaseStmt = CS->getCapturedStmt(); 8964 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8965 auto S = C->children(); 8966 if (S.begin() == S.end()) 8967 return StmtError(); 8968 // All associated statements must be '#pragma omp section' except for 8969 // the first one. 8970 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8971 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8972 if (SectionStmt) 8973 Diag(SectionStmt->getBeginLoc(), 8974 diag::err_omp_parallel_sections_substmt_not_section); 8975 return StmtError(); 8976 } 8977 cast<OMPSectionDirective>(SectionStmt) 8978 ->setHasCancel(DSAStack->isCancelRegion()); 8979 } 8980 } else { 8981 Diag(AStmt->getBeginLoc(), 8982 diag::err_omp_parallel_sections_not_compound_stmt); 8983 return StmtError(); 8984 } 8985 8986 setFunctionHasBranchProtectedScope(); 8987 8988 return OMPParallelSectionsDirective::Create( 8989 Context, StartLoc, EndLoc, Clauses, AStmt, 8990 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 8991 } 8992 8993 /// detach and mergeable clauses are mutially exclusive, check for it. 8994 static bool checkDetachMergeableClauses(Sema &S, 8995 ArrayRef<OMPClause *> Clauses) { 8996 const OMPClause *PrevClause = nullptr; 8997 bool ErrorFound = false; 8998 for (const OMPClause *C : Clauses) { 8999 if (C->getClauseKind() == OMPC_detach || 9000 C->getClauseKind() == OMPC_mergeable) { 9001 if (!PrevClause) { 9002 PrevClause = C; 9003 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9004 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 9005 << getOpenMPClauseName(C->getClauseKind()) 9006 << getOpenMPClauseName(PrevClause->getClauseKind()); 9007 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 9008 << getOpenMPClauseName(PrevClause->getClauseKind()); 9009 ErrorFound = true; 9010 } 9011 } 9012 } 9013 return ErrorFound; 9014 } 9015 9016 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 9017 Stmt *AStmt, SourceLocation StartLoc, 9018 SourceLocation EndLoc) { 9019 if (!AStmt) 9020 return StmtError(); 9021 9022 // OpenMP 5.0, 2.10.1 task Construct 9023 // If a detach clause appears on the directive, then a mergeable clause cannot 9024 // appear on the same directive. 9025 if (checkDetachMergeableClauses(*this, Clauses)) 9026 return StmtError(); 9027 9028 auto *CS = cast<CapturedStmt>(AStmt); 9029 // 1.2.2 OpenMP Language Terminology 9030 // Structured block - An executable statement with a single entry at the 9031 // top and a single exit at the bottom. 9032 // The point of exit cannot be a branch out of the structured block. 9033 // longjmp() and throw() must not violate the entry/exit criteria. 9034 CS->getCapturedDecl()->setNothrow(); 9035 9036 setFunctionHasBranchProtectedScope(); 9037 9038 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9039 DSAStack->isCancelRegion()); 9040 } 9041 9042 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 9043 SourceLocation EndLoc) { 9044 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 9045 } 9046 9047 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 9048 SourceLocation EndLoc) { 9049 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 9050 } 9051 9052 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 9053 SourceLocation EndLoc) { 9054 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 9055 } 9056 9057 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 9058 Stmt *AStmt, 9059 SourceLocation StartLoc, 9060 SourceLocation EndLoc) { 9061 if (!AStmt) 9062 return StmtError(); 9063 9064 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9065 9066 setFunctionHasBranchProtectedScope(); 9067 9068 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 9069 AStmt, 9070 DSAStack->getTaskgroupReductionRef()); 9071 } 9072 9073 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 9074 SourceLocation StartLoc, 9075 SourceLocation EndLoc) { 9076 OMPFlushClause *FC = nullptr; 9077 OMPClause *OrderClause = nullptr; 9078 for (OMPClause *C : Clauses) { 9079 if (C->getClauseKind() == OMPC_flush) 9080 FC = cast<OMPFlushClause>(C); 9081 else 9082 OrderClause = C; 9083 } 9084 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9085 SourceLocation MemOrderLoc; 9086 for (const OMPClause *C : Clauses) { 9087 if (C->getClauseKind() == OMPC_acq_rel || 9088 C->getClauseKind() == OMPC_acquire || 9089 C->getClauseKind() == OMPC_release) { 9090 if (MemOrderKind != OMPC_unknown) { 9091 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9092 << getOpenMPDirectiveName(OMPD_flush) << 1 9093 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9094 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9095 << getOpenMPClauseName(MemOrderKind); 9096 } else { 9097 MemOrderKind = C->getClauseKind(); 9098 MemOrderLoc = C->getBeginLoc(); 9099 } 9100 } 9101 } 9102 if (FC && OrderClause) { 9103 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 9104 << getOpenMPClauseName(OrderClause->getClauseKind()); 9105 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 9106 << getOpenMPClauseName(OrderClause->getClauseKind()); 9107 return StmtError(); 9108 } 9109 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 9110 } 9111 9112 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 9113 SourceLocation StartLoc, 9114 SourceLocation EndLoc) { 9115 if (Clauses.empty()) { 9116 Diag(StartLoc, diag::err_omp_depobj_expected); 9117 return StmtError(); 9118 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 9119 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 9120 return StmtError(); 9121 } 9122 // Only depobj expression and another single clause is allowed. 9123 if (Clauses.size() > 2) { 9124 Diag(Clauses[2]->getBeginLoc(), 9125 diag::err_omp_depobj_single_clause_expected); 9126 return StmtError(); 9127 } else if (Clauses.size() < 1) { 9128 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 9129 return StmtError(); 9130 } 9131 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 9132 } 9133 9134 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 9135 SourceLocation StartLoc, 9136 SourceLocation EndLoc) { 9137 // Check that exactly one clause is specified. 9138 if (Clauses.size() != 1) { 9139 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 9140 diag::err_omp_scan_single_clause_expected); 9141 return StmtError(); 9142 } 9143 // Check that only one instance of scan directives is used in the same outer 9144 // region. 9145 if (DSAStack->doesParentHasScanDirective()) { 9146 Diag(StartLoc, diag::err_omp_several_scan_directives_in_region); 9147 Diag(DSAStack->getParentScanDirectiveLoc(), 9148 diag::note_omp_previous_scan_directive); 9149 return StmtError(); 9150 } 9151 DSAStack->setParentHasScanDirective(StartLoc); 9152 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 9153 } 9154 9155 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 9156 Stmt *AStmt, 9157 SourceLocation StartLoc, 9158 SourceLocation EndLoc) { 9159 const OMPClause *DependFound = nullptr; 9160 const OMPClause *DependSourceClause = nullptr; 9161 const OMPClause *DependSinkClause = nullptr; 9162 bool ErrorFound = false; 9163 const OMPThreadsClause *TC = nullptr; 9164 const OMPSIMDClause *SC = nullptr; 9165 for (const OMPClause *C : Clauses) { 9166 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 9167 DependFound = C; 9168 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 9169 if (DependSourceClause) { 9170 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 9171 << getOpenMPDirectiveName(OMPD_ordered) 9172 << getOpenMPClauseName(OMPC_depend) << 2; 9173 ErrorFound = true; 9174 } else { 9175 DependSourceClause = C; 9176 } 9177 if (DependSinkClause) { 9178 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9179 << 0; 9180 ErrorFound = true; 9181 } 9182 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 9183 if (DependSourceClause) { 9184 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9185 << 1; 9186 ErrorFound = true; 9187 } 9188 DependSinkClause = C; 9189 } 9190 } else if (C->getClauseKind() == OMPC_threads) { 9191 TC = cast<OMPThreadsClause>(C); 9192 } else if (C->getClauseKind() == OMPC_simd) { 9193 SC = cast<OMPSIMDClause>(C); 9194 } 9195 } 9196 if (!ErrorFound && !SC && 9197 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 9198 // OpenMP [2.8.1,simd Construct, Restrictions] 9199 // An ordered construct with the simd clause is the only OpenMP construct 9200 // that can appear in the simd region. 9201 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 9202 << (LangOpts.OpenMP >= 50 ? 1 : 0); 9203 ErrorFound = true; 9204 } else if (DependFound && (TC || SC)) { 9205 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 9206 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 9207 ErrorFound = true; 9208 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 9209 Diag(DependFound->getBeginLoc(), 9210 diag::err_omp_ordered_directive_without_param); 9211 ErrorFound = true; 9212 } else if (TC || Clauses.empty()) { 9213 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 9214 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 9215 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 9216 << (TC != nullptr); 9217 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 9218 ErrorFound = true; 9219 } 9220 } 9221 if ((!AStmt && !DependFound) || ErrorFound) 9222 return StmtError(); 9223 9224 if (AStmt) { 9225 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9226 9227 setFunctionHasBranchProtectedScope(); 9228 } 9229 9230 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9231 } 9232 9233 namespace { 9234 /// Helper class for checking expression in 'omp atomic [update]' 9235 /// construct. 9236 class OpenMPAtomicUpdateChecker { 9237 /// Error results for atomic update expressions. 9238 enum ExprAnalysisErrorCode { 9239 /// A statement is not an expression statement. 9240 NotAnExpression, 9241 /// Expression is not builtin binary or unary operation. 9242 NotABinaryOrUnaryExpression, 9243 /// Unary operation is not post-/pre- increment/decrement operation. 9244 NotAnUnaryIncDecExpression, 9245 /// An expression is not of scalar type. 9246 NotAScalarType, 9247 /// A binary operation is not an assignment operation. 9248 NotAnAssignmentOp, 9249 /// RHS part of the binary operation is not a binary expression. 9250 NotABinaryExpression, 9251 /// RHS part is not additive/multiplicative/shift/biwise binary 9252 /// expression. 9253 NotABinaryOperator, 9254 /// RHS binary operation does not have reference to the updated LHS 9255 /// part. 9256 NotAnUpdateExpression, 9257 /// No errors is found. 9258 NoError 9259 }; 9260 /// Reference to Sema. 9261 Sema &SemaRef; 9262 /// A location for note diagnostics (when error is found). 9263 SourceLocation NoteLoc; 9264 /// 'x' lvalue part of the source atomic expression. 9265 Expr *X; 9266 /// 'expr' rvalue part of the source atomic expression. 9267 Expr *E; 9268 /// Helper expression of the form 9269 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9270 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9271 Expr *UpdateExpr; 9272 /// Is 'x' a LHS in a RHS part of full update expression. It is 9273 /// important for non-associative operations. 9274 bool IsXLHSInRHSPart; 9275 BinaryOperatorKind Op; 9276 SourceLocation OpLoc; 9277 /// true if the source expression is a postfix unary operation, false 9278 /// if it is a prefix unary operation. 9279 bool IsPostfixUpdate; 9280 9281 public: 9282 OpenMPAtomicUpdateChecker(Sema &SemaRef) 9283 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 9284 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 9285 /// Check specified statement that it is suitable for 'atomic update' 9286 /// constructs and extract 'x', 'expr' and Operation from the original 9287 /// expression. If DiagId and NoteId == 0, then only check is performed 9288 /// without error notification. 9289 /// \param DiagId Diagnostic which should be emitted if error is found. 9290 /// \param NoteId Diagnostic note for the main error message. 9291 /// \return true if statement is not an update expression, false otherwise. 9292 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 9293 /// Return the 'x' lvalue part of the source atomic expression. 9294 Expr *getX() const { return X; } 9295 /// Return the 'expr' rvalue part of the source atomic expression. 9296 Expr *getExpr() const { return E; } 9297 /// Return the update expression used in calculation of the updated 9298 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9299 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9300 Expr *getUpdateExpr() const { return UpdateExpr; } 9301 /// Return true if 'x' is LHS in RHS part of full update expression, 9302 /// false otherwise. 9303 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 9304 9305 /// true if the source expression is a postfix unary operation, false 9306 /// if it is a prefix unary operation. 9307 bool isPostfixUpdate() const { return IsPostfixUpdate; } 9308 9309 private: 9310 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 9311 unsigned NoteId = 0); 9312 }; 9313 } // namespace 9314 9315 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 9316 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 9317 ExprAnalysisErrorCode ErrorFound = NoError; 9318 SourceLocation ErrorLoc, NoteLoc; 9319 SourceRange ErrorRange, NoteRange; 9320 // Allowed constructs are: 9321 // x = x binop expr; 9322 // x = expr binop x; 9323 if (AtomicBinOp->getOpcode() == BO_Assign) { 9324 X = AtomicBinOp->getLHS(); 9325 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 9326 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 9327 if (AtomicInnerBinOp->isMultiplicativeOp() || 9328 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 9329 AtomicInnerBinOp->isBitwiseOp()) { 9330 Op = AtomicInnerBinOp->getOpcode(); 9331 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 9332 Expr *LHS = AtomicInnerBinOp->getLHS(); 9333 Expr *RHS = AtomicInnerBinOp->getRHS(); 9334 llvm::FoldingSetNodeID XId, LHSId, RHSId; 9335 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 9336 /*Canonical=*/true); 9337 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 9338 /*Canonical=*/true); 9339 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 9340 /*Canonical=*/true); 9341 if (XId == LHSId) { 9342 E = RHS; 9343 IsXLHSInRHSPart = true; 9344 } else if (XId == RHSId) { 9345 E = LHS; 9346 IsXLHSInRHSPart = false; 9347 } else { 9348 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9349 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9350 NoteLoc = X->getExprLoc(); 9351 NoteRange = X->getSourceRange(); 9352 ErrorFound = NotAnUpdateExpression; 9353 } 9354 } else { 9355 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9356 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9357 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 9358 NoteRange = SourceRange(NoteLoc, NoteLoc); 9359 ErrorFound = NotABinaryOperator; 9360 } 9361 } else { 9362 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 9363 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 9364 ErrorFound = NotABinaryExpression; 9365 } 9366 } else { 9367 ErrorLoc = AtomicBinOp->getExprLoc(); 9368 ErrorRange = AtomicBinOp->getSourceRange(); 9369 NoteLoc = AtomicBinOp->getOperatorLoc(); 9370 NoteRange = SourceRange(NoteLoc, NoteLoc); 9371 ErrorFound = NotAnAssignmentOp; 9372 } 9373 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9374 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9375 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9376 return true; 9377 } 9378 if (SemaRef.CurContext->isDependentContext()) 9379 E = X = UpdateExpr = nullptr; 9380 return ErrorFound != NoError; 9381 } 9382 9383 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 9384 unsigned NoteId) { 9385 ExprAnalysisErrorCode ErrorFound = NoError; 9386 SourceLocation ErrorLoc, NoteLoc; 9387 SourceRange ErrorRange, NoteRange; 9388 // Allowed constructs are: 9389 // x++; 9390 // x--; 9391 // ++x; 9392 // --x; 9393 // x binop= expr; 9394 // x = x binop expr; 9395 // x = expr binop x; 9396 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 9397 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 9398 if (AtomicBody->getType()->isScalarType() || 9399 AtomicBody->isInstantiationDependent()) { 9400 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 9401 AtomicBody->IgnoreParenImpCasts())) { 9402 // Check for Compound Assignment Operation 9403 Op = BinaryOperator::getOpForCompoundAssignment( 9404 AtomicCompAssignOp->getOpcode()); 9405 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 9406 E = AtomicCompAssignOp->getRHS(); 9407 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 9408 IsXLHSInRHSPart = true; 9409 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 9410 AtomicBody->IgnoreParenImpCasts())) { 9411 // Check for Binary Operation 9412 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 9413 return true; 9414 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 9415 AtomicBody->IgnoreParenImpCasts())) { 9416 // Check for Unary Operation 9417 if (AtomicUnaryOp->isIncrementDecrementOp()) { 9418 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 9419 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 9420 OpLoc = AtomicUnaryOp->getOperatorLoc(); 9421 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 9422 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 9423 IsXLHSInRHSPart = true; 9424 } else { 9425 ErrorFound = NotAnUnaryIncDecExpression; 9426 ErrorLoc = AtomicUnaryOp->getExprLoc(); 9427 ErrorRange = AtomicUnaryOp->getSourceRange(); 9428 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 9429 NoteRange = SourceRange(NoteLoc, NoteLoc); 9430 } 9431 } else if (!AtomicBody->isInstantiationDependent()) { 9432 ErrorFound = NotABinaryOrUnaryExpression; 9433 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 9434 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 9435 } 9436 } else { 9437 ErrorFound = NotAScalarType; 9438 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 9439 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9440 } 9441 } else { 9442 ErrorFound = NotAnExpression; 9443 NoteLoc = ErrorLoc = S->getBeginLoc(); 9444 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9445 } 9446 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9447 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9448 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9449 return true; 9450 } 9451 if (SemaRef.CurContext->isDependentContext()) 9452 E = X = UpdateExpr = nullptr; 9453 if (ErrorFound == NoError && E && X) { 9454 // Build an update expression of form 'OpaqueValueExpr(x) binop 9455 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 9456 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 9457 auto *OVEX = new (SemaRef.getASTContext()) 9458 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 9459 auto *OVEExpr = new (SemaRef.getASTContext()) 9460 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 9461 ExprResult Update = 9462 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 9463 IsXLHSInRHSPart ? OVEExpr : OVEX); 9464 if (Update.isInvalid()) 9465 return true; 9466 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 9467 Sema::AA_Casting); 9468 if (Update.isInvalid()) 9469 return true; 9470 UpdateExpr = Update.get(); 9471 } 9472 return ErrorFound != NoError; 9473 } 9474 9475 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 9476 Stmt *AStmt, 9477 SourceLocation StartLoc, 9478 SourceLocation EndLoc) { 9479 // Register location of the first atomic directive. 9480 DSAStack->addAtomicDirectiveLoc(StartLoc); 9481 if (!AStmt) 9482 return StmtError(); 9483 9484 auto *CS = cast<CapturedStmt>(AStmt); 9485 // 1.2.2 OpenMP Language Terminology 9486 // Structured block - An executable statement with a single entry at the 9487 // top and a single exit at the bottom. 9488 // The point of exit cannot be a branch out of the structured block. 9489 // longjmp() and throw() must not violate the entry/exit criteria. 9490 OpenMPClauseKind AtomicKind = OMPC_unknown; 9491 SourceLocation AtomicKindLoc; 9492 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9493 SourceLocation MemOrderLoc; 9494 for (const OMPClause *C : Clauses) { 9495 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 9496 C->getClauseKind() == OMPC_update || 9497 C->getClauseKind() == OMPC_capture) { 9498 if (AtomicKind != OMPC_unknown) { 9499 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 9500 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9501 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 9502 << getOpenMPClauseName(AtomicKind); 9503 } else { 9504 AtomicKind = C->getClauseKind(); 9505 AtomicKindLoc = C->getBeginLoc(); 9506 } 9507 } 9508 if (C->getClauseKind() == OMPC_seq_cst || 9509 C->getClauseKind() == OMPC_acq_rel || 9510 C->getClauseKind() == OMPC_acquire || 9511 C->getClauseKind() == OMPC_release || 9512 C->getClauseKind() == OMPC_relaxed) { 9513 if (MemOrderKind != OMPC_unknown) { 9514 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9515 << getOpenMPDirectiveName(OMPD_atomic) << 0 9516 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9517 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9518 << getOpenMPClauseName(MemOrderKind); 9519 } else { 9520 MemOrderKind = C->getClauseKind(); 9521 MemOrderLoc = C->getBeginLoc(); 9522 } 9523 } 9524 } 9525 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 9526 // If atomic-clause is read then memory-order-clause must not be acq_rel or 9527 // release. 9528 // If atomic-clause is write then memory-order-clause must not be acq_rel or 9529 // acquire. 9530 // If atomic-clause is update or not present then memory-order-clause must not 9531 // be acq_rel or acquire. 9532 if ((AtomicKind == OMPC_read && 9533 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 9534 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 9535 AtomicKind == OMPC_unknown) && 9536 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 9537 SourceLocation Loc = AtomicKindLoc; 9538 if (AtomicKind == OMPC_unknown) 9539 Loc = StartLoc; 9540 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 9541 << getOpenMPClauseName(AtomicKind) 9542 << (AtomicKind == OMPC_unknown ? 1 : 0) 9543 << getOpenMPClauseName(MemOrderKind); 9544 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9545 << getOpenMPClauseName(MemOrderKind); 9546 } 9547 9548 Stmt *Body = CS->getCapturedStmt(); 9549 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 9550 Body = EWC->getSubExpr(); 9551 9552 Expr *X = nullptr; 9553 Expr *V = nullptr; 9554 Expr *E = nullptr; 9555 Expr *UE = nullptr; 9556 bool IsXLHSInRHSPart = false; 9557 bool IsPostfixUpdate = false; 9558 // OpenMP [2.12.6, atomic Construct] 9559 // In the next expressions: 9560 // * x and v (as applicable) are both l-value expressions with scalar type. 9561 // * During the execution of an atomic region, multiple syntactic 9562 // occurrences of x must designate the same storage location. 9563 // * Neither of v and expr (as applicable) may access the storage location 9564 // designated by x. 9565 // * Neither of x and expr (as applicable) may access the storage location 9566 // designated by v. 9567 // * expr is an expression with scalar type. 9568 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 9569 // * binop, binop=, ++, and -- are not overloaded operators. 9570 // * The expression x binop expr must be numerically equivalent to x binop 9571 // (expr). This requirement is satisfied if the operators in expr have 9572 // precedence greater than binop, or by using parentheses around expr or 9573 // subexpressions of expr. 9574 // * The expression expr binop x must be numerically equivalent to (expr) 9575 // binop x. This requirement is satisfied if the operators in expr have 9576 // precedence equal to or greater than binop, or by using parentheses around 9577 // expr or subexpressions of expr. 9578 // * For forms that allow multiple occurrences of x, the number of times 9579 // that x is evaluated is unspecified. 9580 if (AtomicKind == OMPC_read) { 9581 enum { 9582 NotAnExpression, 9583 NotAnAssignmentOp, 9584 NotAScalarType, 9585 NotAnLValue, 9586 NoError 9587 } ErrorFound = NoError; 9588 SourceLocation ErrorLoc, NoteLoc; 9589 SourceRange ErrorRange, NoteRange; 9590 // If clause is read: 9591 // v = x; 9592 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9593 const auto *AtomicBinOp = 9594 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9595 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9596 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9597 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 9598 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9599 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9600 if (!X->isLValue() || !V->isLValue()) { 9601 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9602 ErrorFound = NotAnLValue; 9603 ErrorLoc = AtomicBinOp->getExprLoc(); 9604 ErrorRange = AtomicBinOp->getSourceRange(); 9605 NoteLoc = NotLValueExpr->getExprLoc(); 9606 NoteRange = NotLValueExpr->getSourceRange(); 9607 } 9608 } else if (!X->isInstantiationDependent() || 9609 !V->isInstantiationDependent()) { 9610 const Expr *NotScalarExpr = 9611 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9612 ? V 9613 : X; 9614 ErrorFound = NotAScalarType; 9615 ErrorLoc = AtomicBinOp->getExprLoc(); 9616 ErrorRange = AtomicBinOp->getSourceRange(); 9617 NoteLoc = NotScalarExpr->getExprLoc(); 9618 NoteRange = NotScalarExpr->getSourceRange(); 9619 } 9620 } else if (!AtomicBody->isInstantiationDependent()) { 9621 ErrorFound = NotAnAssignmentOp; 9622 ErrorLoc = AtomicBody->getExprLoc(); 9623 ErrorRange = AtomicBody->getSourceRange(); 9624 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9625 : AtomicBody->getExprLoc(); 9626 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9627 : AtomicBody->getSourceRange(); 9628 } 9629 } else { 9630 ErrorFound = NotAnExpression; 9631 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9632 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9633 } 9634 if (ErrorFound != NoError) { 9635 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9636 << ErrorRange; 9637 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9638 << NoteRange; 9639 return StmtError(); 9640 } 9641 if (CurContext->isDependentContext()) 9642 V = X = nullptr; 9643 } else if (AtomicKind == OMPC_write) { 9644 enum { 9645 NotAnExpression, 9646 NotAnAssignmentOp, 9647 NotAScalarType, 9648 NotAnLValue, 9649 NoError 9650 } ErrorFound = NoError; 9651 SourceLocation ErrorLoc, NoteLoc; 9652 SourceRange ErrorRange, NoteRange; 9653 // If clause is write: 9654 // x = expr; 9655 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9656 const auto *AtomicBinOp = 9657 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9658 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9659 X = AtomicBinOp->getLHS(); 9660 E = AtomicBinOp->getRHS(); 9661 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9662 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9663 if (!X->isLValue()) { 9664 ErrorFound = NotAnLValue; 9665 ErrorLoc = AtomicBinOp->getExprLoc(); 9666 ErrorRange = AtomicBinOp->getSourceRange(); 9667 NoteLoc = X->getExprLoc(); 9668 NoteRange = X->getSourceRange(); 9669 } 9670 } else if (!X->isInstantiationDependent() || 9671 !E->isInstantiationDependent()) { 9672 const Expr *NotScalarExpr = 9673 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9674 ? E 9675 : X; 9676 ErrorFound = NotAScalarType; 9677 ErrorLoc = AtomicBinOp->getExprLoc(); 9678 ErrorRange = AtomicBinOp->getSourceRange(); 9679 NoteLoc = NotScalarExpr->getExprLoc(); 9680 NoteRange = NotScalarExpr->getSourceRange(); 9681 } 9682 } else if (!AtomicBody->isInstantiationDependent()) { 9683 ErrorFound = NotAnAssignmentOp; 9684 ErrorLoc = AtomicBody->getExprLoc(); 9685 ErrorRange = AtomicBody->getSourceRange(); 9686 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9687 : AtomicBody->getExprLoc(); 9688 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9689 : AtomicBody->getSourceRange(); 9690 } 9691 } else { 9692 ErrorFound = NotAnExpression; 9693 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9694 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9695 } 9696 if (ErrorFound != NoError) { 9697 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 9698 << ErrorRange; 9699 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9700 << NoteRange; 9701 return StmtError(); 9702 } 9703 if (CurContext->isDependentContext()) 9704 E = X = nullptr; 9705 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9706 // If clause is update: 9707 // x++; 9708 // x--; 9709 // ++x; 9710 // --x; 9711 // x binop= expr; 9712 // x = x binop expr; 9713 // x = expr binop x; 9714 OpenMPAtomicUpdateChecker Checker(*this); 9715 if (Checker.checkStatement( 9716 Body, (AtomicKind == OMPC_update) 9717 ? diag::err_omp_atomic_update_not_expression_statement 9718 : diag::err_omp_atomic_not_expression_statement, 9719 diag::note_omp_atomic_update)) 9720 return StmtError(); 9721 if (!CurContext->isDependentContext()) { 9722 E = Checker.getExpr(); 9723 X = Checker.getX(); 9724 UE = Checker.getUpdateExpr(); 9725 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9726 } 9727 } else if (AtomicKind == OMPC_capture) { 9728 enum { 9729 NotAnAssignmentOp, 9730 NotACompoundStatement, 9731 NotTwoSubstatements, 9732 NotASpecificExpression, 9733 NoError 9734 } ErrorFound = NoError; 9735 SourceLocation ErrorLoc, NoteLoc; 9736 SourceRange ErrorRange, NoteRange; 9737 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9738 // If clause is a capture: 9739 // v = x++; 9740 // v = x--; 9741 // v = ++x; 9742 // v = --x; 9743 // v = x binop= expr; 9744 // v = x = x binop expr; 9745 // v = x = expr binop x; 9746 const auto *AtomicBinOp = 9747 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9748 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9749 V = AtomicBinOp->getLHS(); 9750 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9751 OpenMPAtomicUpdateChecker Checker(*this); 9752 if (Checker.checkStatement( 9753 Body, diag::err_omp_atomic_capture_not_expression_statement, 9754 diag::note_omp_atomic_update)) 9755 return StmtError(); 9756 E = Checker.getExpr(); 9757 X = Checker.getX(); 9758 UE = Checker.getUpdateExpr(); 9759 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9760 IsPostfixUpdate = Checker.isPostfixUpdate(); 9761 } else if (!AtomicBody->isInstantiationDependent()) { 9762 ErrorLoc = AtomicBody->getExprLoc(); 9763 ErrorRange = AtomicBody->getSourceRange(); 9764 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9765 : AtomicBody->getExprLoc(); 9766 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9767 : AtomicBody->getSourceRange(); 9768 ErrorFound = NotAnAssignmentOp; 9769 } 9770 if (ErrorFound != NoError) { 9771 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9772 << ErrorRange; 9773 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9774 return StmtError(); 9775 } 9776 if (CurContext->isDependentContext()) 9777 UE = V = E = X = nullptr; 9778 } else { 9779 // If clause is a capture: 9780 // { v = x; x = expr; } 9781 // { v = x; x++; } 9782 // { v = x; x--; } 9783 // { v = x; ++x; } 9784 // { v = x; --x; } 9785 // { v = x; x binop= expr; } 9786 // { v = x; x = x binop expr; } 9787 // { v = x; x = expr binop x; } 9788 // { x++; v = x; } 9789 // { x--; v = x; } 9790 // { ++x; v = x; } 9791 // { --x; v = x; } 9792 // { x binop= expr; v = x; } 9793 // { x = x binop expr; v = x; } 9794 // { x = expr binop x; v = x; } 9795 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9796 // Check that this is { expr1; expr2; } 9797 if (CS->size() == 2) { 9798 Stmt *First = CS->body_front(); 9799 Stmt *Second = CS->body_back(); 9800 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9801 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9802 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9803 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9804 // Need to find what subexpression is 'v' and what is 'x'. 9805 OpenMPAtomicUpdateChecker Checker(*this); 9806 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9807 BinaryOperator *BinOp = nullptr; 9808 if (IsUpdateExprFound) { 9809 BinOp = dyn_cast<BinaryOperator>(First); 9810 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9811 } 9812 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9813 // { v = x; x++; } 9814 // { v = x; x--; } 9815 // { v = x; ++x; } 9816 // { v = x; --x; } 9817 // { v = x; x binop= expr; } 9818 // { v = x; x = x binop expr; } 9819 // { v = x; x = expr binop x; } 9820 // Check that the first expression has form v = x. 9821 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9822 llvm::FoldingSetNodeID XId, PossibleXId; 9823 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9824 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9825 IsUpdateExprFound = XId == PossibleXId; 9826 if (IsUpdateExprFound) { 9827 V = BinOp->getLHS(); 9828 X = Checker.getX(); 9829 E = Checker.getExpr(); 9830 UE = Checker.getUpdateExpr(); 9831 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9832 IsPostfixUpdate = true; 9833 } 9834 } 9835 if (!IsUpdateExprFound) { 9836 IsUpdateExprFound = !Checker.checkStatement(First); 9837 BinOp = nullptr; 9838 if (IsUpdateExprFound) { 9839 BinOp = dyn_cast<BinaryOperator>(Second); 9840 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9841 } 9842 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9843 // { x++; v = x; } 9844 // { x--; v = x; } 9845 // { ++x; v = x; } 9846 // { --x; v = x; } 9847 // { x binop= expr; v = x; } 9848 // { x = x binop expr; v = x; } 9849 // { x = expr binop x; v = x; } 9850 // Check that the second expression has form v = x. 9851 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9852 llvm::FoldingSetNodeID XId, PossibleXId; 9853 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9854 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9855 IsUpdateExprFound = XId == PossibleXId; 9856 if (IsUpdateExprFound) { 9857 V = BinOp->getLHS(); 9858 X = Checker.getX(); 9859 E = Checker.getExpr(); 9860 UE = Checker.getUpdateExpr(); 9861 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9862 IsPostfixUpdate = false; 9863 } 9864 } 9865 } 9866 if (!IsUpdateExprFound) { 9867 // { v = x; x = expr; } 9868 auto *FirstExpr = dyn_cast<Expr>(First); 9869 auto *SecondExpr = dyn_cast<Expr>(Second); 9870 if (!FirstExpr || !SecondExpr || 9871 !(FirstExpr->isInstantiationDependent() || 9872 SecondExpr->isInstantiationDependent())) { 9873 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9874 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9875 ErrorFound = NotAnAssignmentOp; 9876 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9877 : First->getBeginLoc(); 9878 NoteRange = ErrorRange = FirstBinOp 9879 ? FirstBinOp->getSourceRange() 9880 : SourceRange(ErrorLoc, ErrorLoc); 9881 } else { 9882 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9883 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9884 ErrorFound = NotAnAssignmentOp; 9885 NoteLoc = ErrorLoc = SecondBinOp 9886 ? SecondBinOp->getOperatorLoc() 9887 : Second->getBeginLoc(); 9888 NoteRange = ErrorRange = 9889 SecondBinOp ? SecondBinOp->getSourceRange() 9890 : SourceRange(ErrorLoc, ErrorLoc); 9891 } else { 9892 Expr *PossibleXRHSInFirst = 9893 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9894 Expr *PossibleXLHSInSecond = 9895 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9896 llvm::FoldingSetNodeID X1Id, X2Id; 9897 PossibleXRHSInFirst->Profile(X1Id, Context, 9898 /*Canonical=*/true); 9899 PossibleXLHSInSecond->Profile(X2Id, Context, 9900 /*Canonical=*/true); 9901 IsUpdateExprFound = X1Id == X2Id; 9902 if (IsUpdateExprFound) { 9903 V = FirstBinOp->getLHS(); 9904 X = SecondBinOp->getLHS(); 9905 E = SecondBinOp->getRHS(); 9906 UE = nullptr; 9907 IsXLHSInRHSPart = false; 9908 IsPostfixUpdate = true; 9909 } else { 9910 ErrorFound = NotASpecificExpression; 9911 ErrorLoc = FirstBinOp->getExprLoc(); 9912 ErrorRange = FirstBinOp->getSourceRange(); 9913 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9914 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9915 } 9916 } 9917 } 9918 } 9919 } 9920 } else { 9921 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9922 NoteRange = ErrorRange = 9923 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9924 ErrorFound = NotTwoSubstatements; 9925 } 9926 } else { 9927 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9928 NoteRange = ErrorRange = 9929 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9930 ErrorFound = NotACompoundStatement; 9931 } 9932 if (ErrorFound != NoError) { 9933 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9934 << ErrorRange; 9935 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9936 return StmtError(); 9937 } 9938 if (CurContext->isDependentContext()) 9939 UE = V = E = X = nullptr; 9940 } 9941 } 9942 9943 setFunctionHasBranchProtectedScope(); 9944 9945 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9946 X, V, E, UE, IsXLHSInRHSPart, 9947 IsPostfixUpdate); 9948 } 9949 9950 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9951 Stmt *AStmt, 9952 SourceLocation StartLoc, 9953 SourceLocation EndLoc) { 9954 if (!AStmt) 9955 return StmtError(); 9956 9957 auto *CS = cast<CapturedStmt>(AStmt); 9958 // 1.2.2 OpenMP Language Terminology 9959 // Structured block - An executable statement with a single entry at the 9960 // top and a single exit at the bottom. 9961 // The point of exit cannot be a branch out of the structured block. 9962 // longjmp() and throw() must not violate the entry/exit criteria. 9963 CS->getCapturedDecl()->setNothrow(); 9964 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 9965 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9966 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9967 // 1.2.2 OpenMP Language Terminology 9968 // Structured block - An executable statement with a single entry at the 9969 // top and a single exit at the bottom. 9970 // The point of exit cannot be a branch out of the structured block. 9971 // longjmp() and throw() must not violate the entry/exit criteria. 9972 CS->getCapturedDecl()->setNothrow(); 9973 } 9974 9975 // OpenMP [2.16, Nesting of Regions] 9976 // If specified, a teams construct must be contained within a target 9977 // construct. That target construct must contain no statements or directives 9978 // outside of the teams construct. 9979 if (DSAStack->hasInnerTeamsRegion()) { 9980 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9981 bool OMPTeamsFound = true; 9982 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9983 auto I = CS->body_begin(); 9984 while (I != CS->body_end()) { 9985 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9986 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9987 OMPTeamsFound) { 9988 9989 OMPTeamsFound = false; 9990 break; 9991 } 9992 ++I; 9993 } 9994 assert(I != CS->body_end() && "Not found statement"); 9995 S = *I; 9996 } else { 9997 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9998 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9999 } 10000 if (!OMPTeamsFound) { 10001 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 10002 Diag(DSAStack->getInnerTeamsRegionLoc(), 10003 diag::note_omp_nested_teams_construct_here); 10004 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 10005 << isa<OMPExecutableDirective>(S); 10006 return StmtError(); 10007 } 10008 } 10009 10010 setFunctionHasBranchProtectedScope(); 10011 10012 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10013 } 10014 10015 StmtResult 10016 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 10017 Stmt *AStmt, SourceLocation StartLoc, 10018 SourceLocation EndLoc) { 10019 if (!AStmt) 10020 return StmtError(); 10021 10022 auto *CS = cast<CapturedStmt>(AStmt); 10023 // 1.2.2 OpenMP Language Terminology 10024 // Structured block - An executable statement with a single entry at the 10025 // top and a single exit at the bottom. 10026 // The point of exit cannot be a branch out of the structured block. 10027 // longjmp() and throw() must not violate the entry/exit criteria. 10028 CS->getCapturedDecl()->setNothrow(); 10029 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 10030 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10031 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10032 // 1.2.2 OpenMP Language Terminology 10033 // Structured block - An executable statement with a single entry at the 10034 // top and a single exit at the bottom. 10035 // The point of exit cannot be a branch out of the structured block. 10036 // longjmp() and throw() must not violate the entry/exit criteria. 10037 CS->getCapturedDecl()->setNothrow(); 10038 } 10039 10040 setFunctionHasBranchProtectedScope(); 10041 10042 return OMPTargetParallelDirective::Create( 10043 Context, StartLoc, EndLoc, Clauses, AStmt, 10044 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10045 } 10046 10047 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 10048 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10049 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10050 if (!AStmt) 10051 return StmtError(); 10052 10053 auto *CS = cast<CapturedStmt>(AStmt); 10054 // 1.2.2 OpenMP Language Terminology 10055 // Structured block - An executable statement with a single entry at the 10056 // top and a single exit at the bottom. 10057 // The point of exit cannot be a branch out of the structured block. 10058 // longjmp() and throw() must not violate the entry/exit criteria. 10059 CS->getCapturedDecl()->setNothrow(); 10060 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10061 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10062 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10063 // 1.2.2 OpenMP Language Terminology 10064 // Structured block - An executable statement with a single entry at the 10065 // top and a single exit at the bottom. 10066 // The point of exit cannot be a branch out of the structured block. 10067 // longjmp() and throw() must not violate the entry/exit criteria. 10068 CS->getCapturedDecl()->setNothrow(); 10069 } 10070 10071 OMPLoopDirective::HelperExprs B; 10072 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10073 // define the nested loops number. 10074 unsigned NestedLoopCount = 10075 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 10076 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10077 VarsWithImplicitDSA, B); 10078 if (NestedLoopCount == 0) 10079 return StmtError(); 10080 10081 assert((CurContext->isDependentContext() || B.builtAll()) && 10082 "omp target parallel for loop exprs were not built"); 10083 10084 if (!CurContext->isDependentContext()) { 10085 // Finalize the clauses that need pre-built expressions for CodeGen. 10086 for (OMPClause *C : Clauses) { 10087 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10088 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10089 B.NumIterations, *this, CurScope, 10090 DSAStack)) 10091 return StmtError(); 10092 } 10093 } 10094 10095 setFunctionHasBranchProtectedScope(); 10096 return OMPTargetParallelForDirective::Create( 10097 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10098 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10099 } 10100 10101 /// Check for existence of a map clause in the list of clauses. 10102 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 10103 const OpenMPClauseKind K) { 10104 return llvm::any_of( 10105 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 10106 } 10107 10108 template <typename... Params> 10109 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 10110 const Params... ClauseTypes) { 10111 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 10112 } 10113 10114 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 10115 Stmt *AStmt, 10116 SourceLocation StartLoc, 10117 SourceLocation EndLoc) { 10118 if (!AStmt) 10119 return StmtError(); 10120 10121 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10122 10123 // OpenMP [2.10.1, Restrictions, p. 97] 10124 // At least one map clause must appear on the directive. 10125 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 10126 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10127 << "'map' or 'use_device_ptr'" 10128 << getOpenMPDirectiveName(OMPD_target_data); 10129 return StmtError(); 10130 } 10131 10132 setFunctionHasBranchProtectedScope(); 10133 10134 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10135 AStmt); 10136 } 10137 10138 StmtResult 10139 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 10140 SourceLocation StartLoc, 10141 SourceLocation EndLoc, Stmt *AStmt) { 10142 if (!AStmt) 10143 return StmtError(); 10144 10145 auto *CS = cast<CapturedStmt>(AStmt); 10146 // 1.2.2 OpenMP Language Terminology 10147 // Structured block - An executable statement with a single entry at the 10148 // top and a single exit at the bottom. 10149 // The point of exit cannot be a branch out of the structured block. 10150 // longjmp() and throw() must not violate the entry/exit criteria. 10151 CS->getCapturedDecl()->setNothrow(); 10152 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 10153 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10154 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10155 // 1.2.2 OpenMP Language Terminology 10156 // Structured block - An executable statement with a single entry at the 10157 // top and a single exit at the bottom. 10158 // The point of exit cannot be a branch out of the structured block. 10159 // longjmp() and throw() must not violate the entry/exit criteria. 10160 CS->getCapturedDecl()->setNothrow(); 10161 } 10162 10163 // OpenMP [2.10.2, Restrictions, p. 99] 10164 // At least one map clause must appear on the directive. 10165 if (!hasClauses(Clauses, OMPC_map)) { 10166 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10167 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 10168 return StmtError(); 10169 } 10170 10171 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10172 AStmt); 10173 } 10174 10175 StmtResult 10176 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 10177 SourceLocation StartLoc, 10178 SourceLocation EndLoc, Stmt *AStmt) { 10179 if (!AStmt) 10180 return StmtError(); 10181 10182 auto *CS = cast<CapturedStmt>(AStmt); 10183 // 1.2.2 OpenMP Language Terminology 10184 // Structured block - An executable statement with a single entry at the 10185 // top and a single exit at the bottom. 10186 // The point of exit cannot be a branch out of the structured block. 10187 // longjmp() and throw() must not violate the entry/exit criteria. 10188 CS->getCapturedDecl()->setNothrow(); 10189 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 10190 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10191 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10192 // 1.2.2 OpenMP Language Terminology 10193 // Structured block - An executable statement with a single entry at the 10194 // top and a single exit at the bottom. 10195 // The point of exit cannot be a branch out of the structured block. 10196 // longjmp() and throw() must not violate the entry/exit criteria. 10197 CS->getCapturedDecl()->setNothrow(); 10198 } 10199 10200 // OpenMP [2.10.3, Restrictions, p. 102] 10201 // At least one map clause must appear on the directive. 10202 if (!hasClauses(Clauses, OMPC_map)) { 10203 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10204 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 10205 return StmtError(); 10206 } 10207 10208 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10209 AStmt); 10210 } 10211 10212 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 10213 SourceLocation StartLoc, 10214 SourceLocation EndLoc, 10215 Stmt *AStmt) { 10216 if (!AStmt) 10217 return StmtError(); 10218 10219 auto *CS = cast<CapturedStmt>(AStmt); 10220 // 1.2.2 OpenMP Language Terminology 10221 // Structured block - An executable statement with a single entry at the 10222 // top and a single exit at the bottom. 10223 // The point of exit cannot be a branch out of the structured block. 10224 // longjmp() and throw() must not violate the entry/exit criteria. 10225 CS->getCapturedDecl()->setNothrow(); 10226 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 10227 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10228 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10229 // 1.2.2 OpenMP Language Terminology 10230 // Structured block - An executable statement with a single entry at the 10231 // top and a single exit at the bottom. 10232 // The point of exit cannot be a branch out of the structured block. 10233 // longjmp() and throw() must not violate the entry/exit criteria. 10234 CS->getCapturedDecl()->setNothrow(); 10235 } 10236 10237 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 10238 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 10239 return StmtError(); 10240 } 10241 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 10242 AStmt); 10243 } 10244 10245 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 10246 Stmt *AStmt, SourceLocation StartLoc, 10247 SourceLocation EndLoc) { 10248 if (!AStmt) 10249 return StmtError(); 10250 10251 auto *CS = cast<CapturedStmt>(AStmt); 10252 // 1.2.2 OpenMP Language Terminology 10253 // Structured block - An executable statement with a single entry at the 10254 // top and a single exit at the bottom. 10255 // The point of exit cannot be a branch out of the structured block. 10256 // longjmp() and throw() must not violate the entry/exit criteria. 10257 CS->getCapturedDecl()->setNothrow(); 10258 10259 setFunctionHasBranchProtectedScope(); 10260 10261 DSAStack->setParentTeamsRegionLoc(StartLoc); 10262 10263 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10264 } 10265 10266 StmtResult 10267 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 10268 SourceLocation EndLoc, 10269 OpenMPDirectiveKind CancelRegion) { 10270 if (DSAStack->isParentNowaitRegion()) { 10271 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 10272 return StmtError(); 10273 } 10274 if (DSAStack->isParentOrderedRegion()) { 10275 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 10276 return StmtError(); 10277 } 10278 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 10279 CancelRegion); 10280 } 10281 10282 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 10283 SourceLocation StartLoc, 10284 SourceLocation EndLoc, 10285 OpenMPDirectiveKind CancelRegion) { 10286 if (DSAStack->isParentNowaitRegion()) { 10287 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 10288 return StmtError(); 10289 } 10290 if (DSAStack->isParentOrderedRegion()) { 10291 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 10292 return StmtError(); 10293 } 10294 DSAStack->setParentCancelRegion(/*Cancel=*/true); 10295 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 10296 CancelRegion); 10297 } 10298 10299 static bool checkGrainsizeNumTasksClauses(Sema &S, 10300 ArrayRef<OMPClause *> Clauses) { 10301 const OMPClause *PrevClause = nullptr; 10302 bool ErrorFound = false; 10303 for (const OMPClause *C : Clauses) { 10304 if (C->getClauseKind() == OMPC_grainsize || 10305 C->getClauseKind() == OMPC_num_tasks) { 10306 if (!PrevClause) 10307 PrevClause = C; 10308 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10309 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10310 << getOpenMPClauseName(C->getClauseKind()) 10311 << getOpenMPClauseName(PrevClause->getClauseKind()); 10312 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10313 << getOpenMPClauseName(PrevClause->getClauseKind()); 10314 ErrorFound = true; 10315 } 10316 } 10317 } 10318 return ErrorFound; 10319 } 10320 10321 static bool checkReductionClauseWithNogroup(Sema &S, 10322 ArrayRef<OMPClause *> Clauses) { 10323 const OMPClause *ReductionClause = nullptr; 10324 const OMPClause *NogroupClause = nullptr; 10325 for (const OMPClause *C : Clauses) { 10326 if (C->getClauseKind() == OMPC_reduction) { 10327 ReductionClause = C; 10328 if (NogroupClause) 10329 break; 10330 continue; 10331 } 10332 if (C->getClauseKind() == OMPC_nogroup) { 10333 NogroupClause = C; 10334 if (ReductionClause) 10335 break; 10336 continue; 10337 } 10338 } 10339 if (ReductionClause && NogroupClause) { 10340 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 10341 << SourceRange(NogroupClause->getBeginLoc(), 10342 NogroupClause->getEndLoc()); 10343 return true; 10344 } 10345 return false; 10346 } 10347 10348 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 10349 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10350 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10351 if (!AStmt) 10352 return StmtError(); 10353 10354 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10355 OMPLoopDirective::HelperExprs B; 10356 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10357 // define the nested loops number. 10358 unsigned NestedLoopCount = 10359 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 10360 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10361 VarsWithImplicitDSA, B); 10362 if (NestedLoopCount == 0) 10363 return StmtError(); 10364 10365 assert((CurContext->isDependentContext() || B.builtAll()) && 10366 "omp for loop exprs were not built"); 10367 10368 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10369 // The grainsize clause and num_tasks clause are mutually exclusive and may 10370 // not appear on the same taskloop directive. 10371 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10372 return StmtError(); 10373 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10374 // If a reduction clause is present on the taskloop directive, the nogroup 10375 // clause must not be specified. 10376 if (checkReductionClauseWithNogroup(*this, Clauses)) 10377 return StmtError(); 10378 10379 setFunctionHasBranchProtectedScope(); 10380 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10381 NestedLoopCount, Clauses, AStmt, B, 10382 DSAStack->isCancelRegion()); 10383 } 10384 10385 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 10386 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10387 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10388 if (!AStmt) 10389 return StmtError(); 10390 10391 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10392 OMPLoopDirective::HelperExprs B; 10393 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10394 // define the nested loops number. 10395 unsigned NestedLoopCount = 10396 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 10397 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10398 VarsWithImplicitDSA, B); 10399 if (NestedLoopCount == 0) 10400 return StmtError(); 10401 10402 assert((CurContext->isDependentContext() || B.builtAll()) && 10403 "omp for loop exprs were not built"); 10404 10405 if (!CurContext->isDependentContext()) { 10406 // Finalize the clauses that need pre-built expressions for CodeGen. 10407 for (OMPClause *C : Clauses) { 10408 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10409 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10410 B.NumIterations, *this, CurScope, 10411 DSAStack)) 10412 return StmtError(); 10413 } 10414 } 10415 10416 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10417 // The grainsize clause and num_tasks clause are mutually exclusive and may 10418 // not appear on the same taskloop directive. 10419 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10420 return StmtError(); 10421 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10422 // If a reduction clause is present on the taskloop directive, the nogroup 10423 // clause must not be specified. 10424 if (checkReductionClauseWithNogroup(*this, Clauses)) 10425 return StmtError(); 10426 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10427 return StmtError(); 10428 10429 setFunctionHasBranchProtectedScope(); 10430 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 10431 NestedLoopCount, Clauses, AStmt, B); 10432 } 10433 10434 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 10435 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10436 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10437 if (!AStmt) 10438 return StmtError(); 10439 10440 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10441 OMPLoopDirective::HelperExprs B; 10442 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10443 // define the nested loops number. 10444 unsigned NestedLoopCount = 10445 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 10446 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10447 VarsWithImplicitDSA, B); 10448 if (NestedLoopCount == 0) 10449 return StmtError(); 10450 10451 assert((CurContext->isDependentContext() || B.builtAll()) && 10452 "omp for loop exprs were not built"); 10453 10454 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10455 // The grainsize clause and num_tasks clause are mutually exclusive and may 10456 // not appear on the same taskloop directive. 10457 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10458 return StmtError(); 10459 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10460 // If a reduction clause is present on the taskloop directive, the nogroup 10461 // clause must not be specified. 10462 if (checkReductionClauseWithNogroup(*this, Clauses)) 10463 return StmtError(); 10464 10465 setFunctionHasBranchProtectedScope(); 10466 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10467 NestedLoopCount, Clauses, AStmt, B, 10468 DSAStack->isCancelRegion()); 10469 } 10470 10471 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 10472 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10473 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10474 if (!AStmt) 10475 return StmtError(); 10476 10477 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10478 OMPLoopDirective::HelperExprs B; 10479 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10480 // define the nested loops number. 10481 unsigned NestedLoopCount = 10482 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10483 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10484 VarsWithImplicitDSA, B); 10485 if (NestedLoopCount == 0) 10486 return StmtError(); 10487 10488 assert((CurContext->isDependentContext() || B.builtAll()) && 10489 "omp for loop exprs were not built"); 10490 10491 if (!CurContext->isDependentContext()) { 10492 // Finalize the clauses that need pre-built expressions for CodeGen. 10493 for (OMPClause *C : Clauses) { 10494 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10495 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10496 B.NumIterations, *this, CurScope, 10497 DSAStack)) 10498 return StmtError(); 10499 } 10500 } 10501 10502 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10503 // The grainsize clause and num_tasks clause are mutually exclusive and may 10504 // not appear on the same taskloop directive. 10505 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10506 return StmtError(); 10507 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10508 // If a reduction clause is present on the taskloop directive, the nogroup 10509 // clause must not be specified. 10510 if (checkReductionClauseWithNogroup(*this, Clauses)) 10511 return StmtError(); 10512 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10513 return StmtError(); 10514 10515 setFunctionHasBranchProtectedScope(); 10516 return OMPMasterTaskLoopSimdDirective::Create( 10517 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10518 } 10519 10520 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 10521 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10522 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10523 if (!AStmt) 10524 return StmtError(); 10525 10526 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10527 auto *CS = cast<CapturedStmt>(AStmt); 10528 // 1.2.2 OpenMP Language Terminology 10529 // Structured block - An executable statement with a single entry at the 10530 // top and a single exit at the bottom. 10531 // The point of exit cannot be a branch out of the structured block. 10532 // longjmp() and throw() must not violate the entry/exit criteria. 10533 CS->getCapturedDecl()->setNothrow(); 10534 for (int ThisCaptureLevel = 10535 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 10536 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10537 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10538 // 1.2.2 OpenMP Language Terminology 10539 // Structured block - An executable statement with a single entry at the 10540 // top and a single exit at the bottom. 10541 // The point of exit cannot be a branch out of the structured block. 10542 // longjmp() and throw() must not violate the entry/exit criteria. 10543 CS->getCapturedDecl()->setNothrow(); 10544 } 10545 10546 OMPLoopDirective::HelperExprs B; 10547 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10548 // define the nested loops number. 10549 unsigned NestedLoopCount = checkOpenMPLoop( 10550 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 10551 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10552 VarsWithImplicitDSA, B); 10553 if (NestedLoopCount == 0) 10554 return StmtError(); 10555 10556 assert((CurContext->isDependentContext() || B.builtAll()) && 10557 "omp for loop exprs were not built"); 10558 10559 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10560 // The grainsize clause and num_tasks clause are mutually exclusive and may 10561 // not appear on the same taskloop directive. 10562 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10563 return StmtError(); 10564 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10565 // If a reduction clause is present on the taskloop directive, the nogroup 10566 // clause must not be specified. 10567 if (checkReductionClauseWithNogroup(*this, Clauses)) 10568 return StmtError(); 10569 10570 setFunctionHasBranchProtectedScope(); 10571 return OMPParallelMasterTaskLoopDirective::Create( 10572 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10573 DSAStack->isCancelRegion()); 10574 } 10575 10576 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 10577 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10578 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10579 if (!AStmt) 10580 return StmtError(); 10581 10582 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10583 auto *CS = cast<CapturedStmt>(AStmt); 10584 // 1.2.2 OpenMP Language Terminology 10585 // Structured block - An executable statement with a single entry at the 10586 // top and a single exit at the bottom. 10587 // The point of exit cannot be a branch out of the structured block. 10588 // longjmp() and throw() must not violate the entry/exit criteria. 10589 CS->getCapturedDecl()->setNothrow(); 10590 for (int ThisCaptureLevel = 10591 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 10592 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10593 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10594 // 1.2.2 OpenMP Language Terminology 10595 // Structured block - An executable statement with a single entry at the 10596 // top and a single exit at the bottom. 10597 // The point of exit cannot be a branch out of the structured block. 10598 // longjmp() and throw() must not violate the entry/exit criteria. 10599 CS->getCapturedDecl()->setNothrow(); 10600 } 10601 10602 OMPLoopDirective::HelperExprs B; 10603 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10604 // define the nested loops number. 10605 unsigned NestedLoopCount = checkOpenMPLoop( 10606 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10607 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10608 VarsWithImplicitDSA, B); 10609 if (NestedLoopCount == 0) 10610 return StmtError(); 10611 10612 assert((CurContext->isDependentContext() || B.builtAll()) && 10613 "omp for loop exprs were not built"); 10614 10615 if (!CurContext->isDependentContext()) { 10616 // Finalize the clauses that need pre-built expressions for CodeGen. 10617 for (OMPClause *C : Clauses) { 10618 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10619 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10620 B.NumIterations, *this, CurScope, 10621 DSAStack)) 10622 return StmtError(); 10623 } 10624 } 10625 10626 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10627 // The grainsize clause and num_tasks clause are mutually exclusive and may 10628 // not appear on the same taskloop directive. 10629 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10630 return StmtError(); 10631 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10632 // If a reduction clause is present on the taskloop directive, the nogroup 10633 // clause must not be specified. 10634 if (checkReductionClauseWithNogroup(*this, Clauses)) 10635 return StmtError(); 10636 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10637 return StmtError(); 10638 10639 setFunctionHasBranchProtectedScope(); 10640 return OMPParallelMasterTaskLoopSimdDirective::Create( 10641 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10642 } 10643 10644 StmtResult Sema::ActOnOpenMPDistributeDirective( 10645 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10646 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10647 if (!AStmt) 10648 return StmtError(); 10649 10650 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10651 OMPLoopDirective::HelperExprs B; 10652 // In presence of clause 'collapse' with number of loops, it will 10653 // define the nested loops number. 10654 unsigned NestedLoopCount = 10655 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10656 nullptr /*ordered not a clause on distribute*/, AStmt, 10657 *this, *DSAStack, VarsWithImplicitDSA, B); 10658 if (NestedLoopCount == 0) 10659 return StmtError(); 10660 10661 assert((CurContext->isDependentContext() || B.builtAll()) && 10662 "omp for loop exprs were not built"); 10663 10664 setFunctionHasBranchProtectedScope(); 10665 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 10666 NestedLoopCount, Clauses, AStmt, B); 10667 } 10668 10669 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 10670 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10671 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10672 if (!AStmt) 10673 return StmtError(); 10674 10675 auto *CS = cast<CapturedStmt>(AStmt); 10676 // 1.2.2 OpenMP Language Terminology 10677 // Structured block - An executable statement with a single entry at the 10678 // top and a single exit at the bottom. 10679 // The point of exit cannot be a branch out of the structured block. 10680 // longjmp() and throw() must not violate the entry/exit criteria. 10681 CS->getCapturedDecl()->setNothrow(); 10682 for (int ThisCaptureLevel = 10683 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 10684 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10685 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10686 // 1.2.2 OpenMP Language Terminology 10687 // Structured block - An executable statement with a single entry at the 10688 // top and a single exit at the bottom. 10689 // The point of exit cannot be a branch out of the structured block. 10690 // longjmp() and throw() must not violate the entry/exit criteria. 10691 CS->getCapturedDecl()->setNothrow(); 10692 } 10693 10694 OMPLoopDirective::HelperExprs B; 10695 // In presence of clause 'collapse' with number of loops, it will 10696 // define the nested loops number. 10697 unsigned NestedLoopCount = checkOpenMPLoop( 10698 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10699 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10700 VarsWithImplicitDSA, B); 10701 if (NestedLoopCount == 0) 10702 return StmtError(); 10703 10704 assert((CurContext->isDependentContext() || B.builtAll()) && 10705 "omp for loop exprs were not built"); 10706 10707 setFunctionHasBranchProtectedScope(); 10708 return OMPDistributeParallelForDirective::Create( 10709 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10710 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10711 } 10712 10713 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10714 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10715 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10716 if (!AStmt) 10717 return StmtError(); 10718 10719 auto *CS = cast<CapturedStmt>(AStmt); 10720 // 1.2.2 OpenMP Language Terminology 10721 // Structured block - An executable statement with a single entry at the 10722 // top and a single exit at the bottom. 10723 // The point of exit cannot be a branch out of the structured block. 10724 // longjmp() and throw() must not violate the entry/exit criteria. 10725 CS->getCapturedDecl()->setNothrow(); 10726 for (int ThisCaptureLevel = 10727 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10728 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10729 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10730 // 1.2.2 OpenMP Language Terminology 10731 // Structured block - An executable statement with a single entry at the 10732 // top and a single exit at the bottom. 10733 // The point of exit cannot be a branch out of the structured block. 10734 // longjmp() and throw() must not violate the entry/exit criteria. 10735 CS->getCapturedDecl()->setNothrow(); 10736 } 10737 10738 OMPLoopDirective::HelperExprs B; 10739 // In presence of clause 'collapse' with number of loops, it will 10740 // define the nested loops number. 10741 unsigned NestedLoopCount = checkOpenMPLoop( 10742 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10743 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10744 VarsWithImplicitDSA, B); 10745 if (NestedLoopCount == 0) 10746 return StmtError(); 10747 10748 assert((CurContext->isDependentContext() || B.builtAll()) && 10749 "omp for loop exprs were not built"); 10750 10751 if (!CurContext->isDependentContext()) { 10752 // Finalize the clauses that need pre-built expressions for CodeGen. 10753 for (OMPClause *C : Clauses) { 10754 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10755 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10756 B.NumIterations, *this, CurScope, 10757 DSAStack)) 10758 return StmtError(); 10759 } 10760 } 10761 10762 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10763 return StmtError(); 10764 10765 setFunctionHasBranchProtectedScope(); 10766 return OMPDistributeParallelForSimdDirective::Create( 10767 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10768 } 10769 10770 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10771 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10772 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10773 if (!AStmt) 10774 return StmtError(); 10775 10776 auto *CS = cast<CapturedStmt>(AStmt); 10777 // 1.2.2 OpenMP Language Terminology 10778 // Structured block - An executable statement with a single entry at the 10779 // top and a single exit at the bottom. 10780 // The point of exit cannot be a branch out of the structured block. 10781 // longjmp() and throw() must not violate the entry/exit criteria. 10782 CS->getCapturedDecl()->setNothrow(); 10783 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10784 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10785 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10786 // 1.2.2 OpenMP Language Terminology 10787 // Structured block - An executable statement with a single entry at the 10788 // top and a single exit at the bottom. 10789 // The point of exit cannot be a branch out of the structured block. 10790 // longjmp() and throw() must not violate the entry/exit criteria. 10791 CS->getCapturedDecl()->setNothrow(); 10792 } 10793 10794 OMPLoopDirective::HelperExprs B; 10795 // In presence of clause 'collapse' with number of loops, it will 10796 // define the nested loops number. 10797 unsigned NestedLoopCount = 10798 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10799 nullptr /*ordered not a clause on distribute*/, CS, *this, 10800 *DSAStack, VarsWithImplicitDSA, B); 10801 if (NestedLoopCount == 0) 10802 return StmtError(); 10803 10804 assert((CurContext->isDependentContext() || B.builtAll()) && 10805 "omp for loop exprs were not built"); 10806 10807 if (!CurContext->isDependentContext()) { 10808 // Finalize the clauses that need pre-built expressions for CodeGen. 10809 for (OMPClause *C : Clauses) { 10810 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10811 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10812 B.NumIterations, *this, CurScope, 10813 DSAStack)) 10814 return StmtError(); 10815 } 10816 } 10817 10818 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10819 return StmtError(); 10820 10821 setFunctionHasBranchProtectedScope(); 10822 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10823 NestedLoopCount, Clauses, AStmt, B); 10824 } 10825 10826 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10827 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10828 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10829 if (!AStmt) 10830 return StmtError(); 10831 10832 auto *CS = cast<CapturedStmt>(AStmt); 10833 // 1.2.2 OpenMP Language Terminology 10834 // Structured block - An executable statement with a single entry at the 10835 // top and a single exit at the bottom. 10836 // The point of exit cannot be a branch out of the structured block. 10837 // longjmp() and throw() must not violate the entry/exit criteria. 10838 CS->getCapturedDecl()->setNothrow(); 10839 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10840 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10841 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10842 // 1.2.2 OpenMP Language Terminology 10843 // Structured block - An executable statement with a single entry at the 10844 // top and a single exit at the bottom. 10845 // The point of exit cannot be a branch out of the structured block. 10846 // longjmp() and throw() must not violate the entry/exit criteria. 10847 CS->getCapturedDecl()->setNothrow(); 10848 } 10849 10850 OMPLoopDirective::HelperExprs B; 10851 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10852 // define the nested loops number. 10853 unsigned NestedLoopCount = checkOpenMPLoop( 10854 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10855 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10856 VarsWithImplicitDSA, B); 10857 if (NestedLoopCount == 0) 10858 return StmtError(); 10859 10860 assert((CurContext->isDependentContext() || B.builtAll()) && 10861 "omp target parallel for simd loop exprs were not built"); 10862 10863 if (!CurContext->isDependentContext()) { 10864 // Finalize the clauses that need pre-built expressions for CodeGen. 10865 for (OMPClause *C : Clauses) { 10866 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10867 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10868 B.NumIterations, *this, CurScope, 10869 DSAStack)) 10870 return StmtError(); 10871 } 10872 } 10873 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10874 return StmtError(); 10875 10876 setFunctionHasBranchProtectedScope(); 10877 return OMPTargetParallelForSimdDirective::Create( 10878 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10879 } 10880 10881 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10882 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10883 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10884 if (!AStmt) 10885 return StmtError(); 10886 10887 auto *CS = cast<CapturedStmt>(AStmt); 10888 // 1.2.2 OpenMP Language Terminology 10889 // Structured block - An executable statement with a single entry at the 10890 // top and a single exit at the bottom. 10891 // The point of exit cannot be a branch out of the structured block. 10892 // longjmp() and throw() must not violate the entry/exit criteria. 10893 CS->getCapturedDecl()->setNothrow(); 10894 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10895 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10896 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10897 // 1.2.2 OpenMP Language Terminology 10898 // Structured block - An executable statement with a single entry at the 10899 // top and a single exit at the bottom. 10900 // The point of exit cannot be a branch out of the structured block. 10901 // longjmp() and throw() must not violate the entry/exit criteria. 10902 CS->getCapturedDecl()->setNothrow(); 10903 } 10904 10905 OMPLoopDirective::HelperExprs B; 10906 // In presence of clause 'collapse' with number of loops, it will define the 10907 // nested loops number. 10908 unsigned NestedLoopCount = 10909 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10910 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10911 VarsWithImplicitDSA, B); 10912 if (NestedLoopCount == 0) 10913 return StmtError(); 10914 10915 assert((CurContext->isDependentContext() || B.builtAll()) && 10916 "omp target simd loop exprs were not built"); 10917 10918 if (!CurContext->isDependentContext()) { 10919 // Finalize the clauses that need pre-built expressions for CodeGen. 10920 for (OMPClause *C : Clauses) { 10921 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10922 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10923 B.NumIterations, *this, CurScope, 10924 DSAStack)) 10925 return StmtError(); 10926 } 10927 } 10928 10929 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10930 return StmtError(); 10931 10932 setFunctionHasBranchProtectedScope(); 10933 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10934 NestedLoopCount, Clauses, AStmt, B); 10935 } 10936 10937 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10938 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10939 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10940 if (!AStmt) 10941 return StmtError(); 10942 10943 auto *CS = cast<CapturedStmt>(AStmt); 10944 // 1.2.2 OpenMP Language Terminology 10945 // Structured block - An executable statement with a single entry at the 10946 // top and a single exit at the bottom. 10947 // The point of exit cannot be a branch out of the structured block. 10948 // longjmp() and throw() must not violate the entry/exit criteria. 10949 CS->getCapturedDecl()->setNothrow(); 10950 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10951 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10952 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10953 // 1.2.2 OpenMP Language Terminology 10954 // Structured block - An executable statement with a single entry at the 10955 // top and a single exit at the bottom. 10956 // The point of exit cannot be a branch out of the structured block. 10957 // longjmp() and throw() must not violate the entry/exit criteria. 10958 CS->getCapturedDecl()->setNothrow(); 10959 } 10960 10961 OMPLoopDirective::HelperExprs B; 10962 // In presence of clause 'collapse' with number of loops, it will 10963 // define the nested loops number. 10964 unsigned NestedLoopCount = 10965 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10966 nullptr /*ordered not a clause on distribute*/, CS, *this, 10967 *DSAStack, VarsWithImplicitDSA, B); 10968 if (NestedLoopCount == 0) 10969 return StmtError(); 10970 10971 assert((CurContext->isDependentContext() || B.builtAll()) && 10972 "omp teams distribute loop exprs were not built"); 10973 10974 setFunctionHasBranchProtectedScope(); 10975 10976 DSAStack->setParentTeamsRegionLoc(StartLoc); 10977 10978 return OMPTeamsDistributeDirective::Create( 10979 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10980 } 10981 10982 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10983 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10984 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10985 if (!AStmt) 10986 return StmtError(); 10987 10988 auto *CS = cast<CapturedStmt>(AStmt); 10989 // 1.2.2 OpenMP Language Terminology 10990 // Structured block - An executable statement with a single entry at the 10991 // top and a single exit at the bottom. 10992 // The point of exit cannot be a branch out of the structured block. 10993 // longjmp() and throw() must not violate the entry/exit criteria. 10994 CS->getCapturedDecl()->setNothrow(); 10995 for (int ThisCaptureLevel = 10996 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10997 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10998 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10999 // 1.2.2 OpenMP Language Terminology 11000 // Structured block - An executable statement with a single entry at the 11001 // top and a single exit at the bottom. 11002 // The point of exit cannot be a branch out of the structured block. 11003 // longjmp() and throw() must not violate the entry/exit criteria. 11004 CS->getCapturedDecl()->setNothrow(); 11005 } 11006 11007 OMPLoopDirective::HelperExprs B; 11008 // In presence of clause 'collapse' with number of loops, it will 11009 // define the nested loops number. 11010 unsigned NestedLoopCount = checkOpenMPLoop( 11011 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11012 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11013 VarsWithImplicitDSA, B); 11014 11015 if (NestedLoopCount == 0) 11016 return StmtError(); 11017 11018 assert((CurContext->isDependentContext() || B.builtAll()) && 11019 "omp teams distribute simd loop exprs were not built"); 11020 11021 if (!CurContext->isDependentContext()) { 11022 // Finalize the clauses that need pre-built expressions for CodeGen. 11023 for (OMPClause *C : Clauses) { 11024 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11025 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11026 B.NumIterations, *this, CurScope, 11027 DSAStack)) 11028 return StmtError(); 11029 } 11030 } 11031 11032 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11033 return StmtError(); 11034 11035 setFunctionHasBranchProtectedScope(); 11036 11037 DSAStack->setParentTeamsRegionLoc(StartLoc); 11038 11039 return OMPTeamsDistributeSimdDirective::Create( 11040 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11041 } 11042 11043 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 11044 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11045 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11046 if (!AStmt) 11047 return StmtError(); 11048 11049 auto *CS = cast<CapturedStmt>(AStmt); 11050 // 1.2.2 OpenMP Language Terminology 11051 // Structured block - An executable statement with a single entry at the 11052 // top and a single exit at the bottom. 11053 // The point of exit cannot be a branch out of the structured block. 11054 // longjmp() and throw() must not violate the entry/exit criteria. 11055 CS->getCapturedDecl()->setNothrow(); 11056 11057 for (int ThisCaptureLevel = 11058 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 11059 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11060 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11061 // 1.2.2 OpenMP Language Terminology 11062 // Structured block - An executable statement with a single entry at the 11063 // top and a single exit at the bottom. 11064 // The point of exit cannot be a branch out of the structured block. 11065 // longjmp() and throw() must not violate the entry/exit criteria. 11066 CS->getCapturedDecl()->setNothrow(); 11067 } 11068 11069 OMPLoopDirective::HelperExprs B; 11070 // In presence of clause 'collapse' with number of loops, it will 11071 // define the nested loops number. 11072 unsigned NestedLoopCount = checkOpenMPLoop( 11073 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 11074 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11075 VarsWithImplicitDSA, B); 11076 11077 if (NestedLoopCount == 0) 11078 return StmtError(); 11079 11080 assert((CurContext->isDependentContext() || B.builtAll()) && 11081 "omp for loop exprs were not built"); 11082 11083 if (!CurContext->isDependentContext()) { 11084 // Finalize the clauses that need pre-built expressions for CodeGen. 11085 for (OMPClause *C : Clauses) { 11086 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11087 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11088 B.NumIterations, *this, CurScope, 11089 DSAStack)) 11090 return StmtError(); 11091 } 11092 } 11093 11094 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11095 return StmtError(); 11096 11097 setFunctionHasBranchProtectedScope(); 11098 11099 DSAStack->setParentTeamsRegionLoc(StartLoc); 11100 11101 return OMPTeamsDistributeParallelForSimdDirective::Create( 11102 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11103 } 11104 11105 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 11106 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11107 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11108 if (!AStmt) 11109 return StmtError(); 11110 11111 auto *CS = cast<CapturedStmt>(AStmt); 11112 // 1.2.2 OpenMP Language Terminology 11113 // Structured block - An executable statement with a single entry at the 11114 // top and a single exit at the bottom. 11115 // The point of exit cannot be a branch out of the structured block. 11116 // longjmp() and throw() must not violate the entry/exit criteria. 11117 CS->getCapturedDecl()->setNothrow(); 11118 11119 for (int ThisCaptureLevel = 11120 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 11121 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11122 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11123 // 1.2.2 OpenMP Language Terminology 11124 // Structured block - An executable statement with a single entry at the 11125 // top and a single exit at the bottom. 11126 // The point of exit cannot be a branch out of the structured block. 11127 // longjmp() and throw() must not violate the entry/exit criteria. 11128 CS->getCapturedDecl()->setNothrow(); 11129 } 11130 11131 OMPLoopDirective::HelperExprs B; 11132 // In presence of clause 'collapse' with number of loops, it will 11133 // define the nested loops number. 11134 unsigned NestedLoopCount = checkOpenMPLoop( 11135 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11136 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11137 VarsWithImplicitDSA, B); 11138 11139 if (NestedLoopCount == 0) 11140 return StmtError(); 11141 11142 assert((CurContext->isDependentContext() || B.builtAll()) && 11143 "omp for loop exprs were not built"); 11144 11145 setFunctionHasBranchProtectedScope(); 11146 11147 DSAStack->setParentTeamsRegionLoc(StartLoc); 11148 11149 return OMPTeamsDistributeParallelForDirective::Create( 11150 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11151 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11152 } 11153 11154 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 11155 Stmt *AStmt, 11156 SourceLocation StartLoc, 11157 SourceLocation EndLoc) { 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 = getOpenMPCaptureLevels(OMPD_target_teams); 11170 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11171 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11172 // 1.2.2 OpenMP Language Terminology 11173 // Structured block - An executable statement with a single entry at the 11174 // top and a single exit at the bottom. 11175 // The point of exit cannot be a branch out of the structured block. 11176 // longjmp() and throw() must not violate the entry/exit criteria. 11177 CS->getCapturedDecl()->setNothrow(); 11178 } 11179 setFunctionHasBranchProtectedScope(); 11180 11181 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 11182 AStmt); 11183 } 11184 11185 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 11186 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11187 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11188 if (!AStmt) 11189 return StmtError(); 11190 11191 auto *CS = cast<CapturedStmt>(AStmt); 11192 // 1.2.2 OpenMP Language Terminology 11193 // Structured block - An executable statement with a single entry at the 11194 // top and a single exit at the bottom. 11195 // The point of exit cannot be a branch out of the structured block. 11196 // longjmp() and throw() must not violate the entry/exit criteria. 11197 CS->getCapturedDecl()->setNothrow(); 11198 for (int ThisCaptureLevel = 11199 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 11200 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11201 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11202 // 1.2.2 OpenMP Language Terminology 11203 // Structured block - An executable statement with a single entry at the 11204 // top and a single exit at the bottom. 11205 // The point of exit cannot be a branch out of the structured block. 11206 // longjmp() and throw() must not violate the entry/exit criteria. 11207 CS->getCapturedDecl()->setNothrow(); 11208 } 11209 11210 OMPLoopDirective::HelperExprs B; 11211 // In presence of clause 'collapse' with number of loops, it will 11212 // define the nested loops number. 11213 unsigned NestedLoopCount = checkOpenMPLoop( 11214 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 11215 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11216 VarsWithImplicitDSA, B); 11217 if (NestedLoopCount == 0) 11218 return StmtError(); 11219 11220 assert((CurContext->isDependentContext() || B.builtAll()) && 11221 "omp target teams distribute loop exprs were not built"); 11222 11223 setFunctionHasBranchProtectedScope(); 11224 return OMPTargetTeamsDistributeDirective::Create( 11225 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11226 } 11227 11228 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 11229 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11230 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11231 if (!AStmt) 11232 return StmtError(); 11233 11234 auto *CS = cast<CapturedStmt>(AStmt); 11235 // 1.2.2 OpenMP Language Terminology 11236 // Structured block - An executable statement with a single entry at the 11237 // top and a single exit at the bottom. 11238 // The point of exit cannot be a branch out of the structured block. 11239 // longjmp() and throw() must not violate the entry/exit criteria. 11240 CS->getCapturedDecl()->setNothrow(); 11241 for (int ThisCaptureLevel = 11242 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 11243 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11244 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11245 // 1.2.2 OpenMP Language Terminology 11246 // Structured block - An executable statement with a single entry at the 11247 // top and a single exit at the bottom. 11248 // The point of exit cannot be a branch out of the structured block. 11249 // longjmp() and throw() must not violate the entry/exit criteria. 11250 CS->getCapturedDecl()->setNothrow(); 11251 } 11252 11253 OMPLoopDirective::HelperExprs B; 11254 // In presence of clause 'collapse' with number of loops, it will 11255 // define the nested loops number. 11256 unsigned NestedLoopCount = checkOpenMPLoop( 11257 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11258 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11259 VarsWithImplicitDSA, B); 11260 if (NestedLoopCount == 0) 11261 return StmtError(); 11262 11263 assert((CurContext->isDependentContext() || B.builtAll()) && 11264 "omp target teams distribute parallel for loop exprs were not built"); 11265 11266 if (!CurContext->isDependentContext()) { 11267 // Finalize the clauses that need pre-built expressions for CodeGen. 11268 for (OMPClause *C : Clauses) { 11269 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11270 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11271 B.NumIterations, *this, CurScope, 11272 DSAStack)) 11273 return StmtError(); 11274 } 11275 } 11276 11277 setFunctionHasBranchProtectedScope(); 11278 return OMPTargetTeamsDistributeParallelForDirective::Create( 11279 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11280 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11281 } 11282 11283 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 11284 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11285 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11286 if (!AStmt) 11287 return StmtError(); 11288 11289 auto *CS = cast<CapturedStmt>(AStmt); 11290 // 1.2.2 OpenMP Language Terminology 11291 // Structured block - An executable statement with a single entry at the 11292 // top and a single exit at the bottom. 11293 // The point of exit cannot be a branch out of the structured block. 11294 // longjmp() and throw() must not violate the entry/exit criteria. 11295 CS->getCapturedDecl()->setNothrow(); 11296 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 11297 OMPD_target_teams_distribute_parallel_for_simd); 11298 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11299 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11300 // 1.2.2 OpenMP Language Terminology 11301 // Structured block - An executable statement with a single entry at the 11302 // top and a single exit at the bottom. 11303 // The point of exit cannot be a branch out of the structured block. 11304 // longjmp() and throw() must not violate the entry/exit criteria. 11305 CS->getCapturedDecl()->setNothrow(); 11306 } 11307 11308 OMPLoopDirective::HelperExprs B; 11309 // In presence of clause 'collapse' with number of loops, it will 11310 // define the nested loops number. 11311 unsigned NestedLoopCount = 11312 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 11313 getCollapseNumberExpr(Clauses), 11314 nullptr /*ordered not a clause on distribute*/, CS, *this, 11315 *DSAStack, VarsWithImplicitDSA, B); 11316 if (NestedLoopCount == 0) 11317 return StmtError(); 11318 11319 assert((CurContext->isDependentContext() || B.builtAll()) && 11320 "omp target teams distribute parallel for simd loop exprs were not " 11321 "built"); 11322 11323 if (!CurContext->isDependentContext()) { 11324 // Finalize the clauses that need pre-built expressions for CodeGen. 11325 for (OMPClause *C : Clauses) { 11326 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11327 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11328 B.NumIterations, *this, CurScope, 11329 DSAStack)) 11330 return StmtError(); 11331 } 11332 } 11333 11334 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11335 return StmtError(); 11336 11337 setFunctionHasBranchProtectedScope(); 11338 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 11339 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11340 } 11341 11342 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 11343 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11344 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11345 if (!AStmt) 11346 return StmtError(); 11347 11348 auto *CS = cast<CapturedStmt>(AStmt); 11349 // 1.2.2 OpenMP Language Terminology 11350 // Structured block - An executable statement with a single entry at the 11351 // top and a single exit at the bottom. 11352 // The point of exit cannot be a branch out of the structured block. 11353 // longjmp() and throw() must not violate the entry/exit criteria. 11354 CS->getCapturedDecl()->setNothrow(); 11355 for (int ThisCaptureLevel = 11356 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 11357 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11358 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11359 // 1.2.2 OpenMP Language Terminology 11360 // Structured block - An executable statement with a single entry at the 11361 // top and a single exit at the bottom. 11362 // The point of exit cannot be a branch out of the structured block. 11363 // longjmp() and throw() must not violate the entry/exit criteria. 11364 CS->getCapturedDecl()->setNothrow(); 11365 } 11366 11367 OMPLoopDirective::HelperExprs B; 11368 // In presence of clause 'collapse' with number of loops, it will 11369 // define the nested loops number. 11370 unsigned NestedLoopCount = checkOpenMPLoop( 11371 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11372 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11373 VarsWithImplicitDSA, B); 11374 if (NestedLoopCount == 0) 11375 return StmtError(); 11376 11377 assert((CurContext->isDependentContext() || B.builtAll()) && 11378 "omp target teams distribute simd loop exprs were not built"); 11379 11380 if (!CurContext->isDependentContext()) { 11381 // Finalize the clauses that need pre-built expressions for CodeGen. 11382 for (OMPClause *C : Clauses) { 11383 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11384 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11385 B.NumIterations, *this, CurScope, 11386 DSAStack)) 11387 return StmtError(); 11388 } 11389 } 11390 11391 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11392 return StmtError(); 11393 11394 setFunctionHasBranchProtectedScope(); 11395 return OMPTargetTeamsDistributeSimdDirective::Create( 11396 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11397 } 11398 11399 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 11400 SourceLocation StartLoc, 11401 SourceLocation LParenLoc, 11402 SourceLocation EndLoc) { 11403 OMPClause *Res = nullptr; 11404 switch (Kind) { 11405 case OMPC_final: 11406 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 11407 break; 11408 case OMPC_num_threads: 11409 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 11410 break; 11411 case OMPC_safelen: 11412 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 11413 break; 11414 case OMPC_simdlen: 11415 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 11416 break; 11417 case OMPC_allocator: 11418 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 11419 break; 11420 case OMPC_collapse: 11421 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 11422 break; 11423 case OMPC_ordered: 11424 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 11425 break; 11426 case OMPC_num_teams: 11427 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 11428 break; 11429 case OMPC_thread_limit: 11430 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 11431 break; 11432 case OMPC_priority: 11433 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 11434 break; 11435 case OMPC_grainsize: 11436 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 11437 break; 11438 case OMPC_num_tasks: 11439 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 11440 break; 11441 case OMPC_hint: 11442 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 11443 break; 11444 case OMPC_depobj: 11445 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 11446 break; 11447 case OMPC_detach: 11448 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 11449 break; 11450 case OMPC_device: 11451 case OMPC_if: 11452 case OMPC_default: 11453 case OMPC_proc_bind: 11454 case OMPC_schedule: 11455 case OMPC_private: 11456 case OMPC_firstprivate: 11457 case OMPC_lastprivate: 11458 case OMPC_shared: 11459 case OMPC_reduction: 11460 case OMPC_task_reduction: 11461 case OMPC_in_reduction: 11462 case OMPC_linear: 11463 case OMPC_aligned: 11464 case OMPC_copyin: 11465 case OMPC_copyprivate: 11466 case OMPC_nowait: 11467 case OMPC_untied: 11468 case OMPC_mergeable: 11469 case OMPC_threadprivate: 11470 case OMPC_allocate: 11471 case OMPC_flush: 11472 case OMPC_read: 11473 case OMPC_write: 11474 case OMPC_update: 11475 case OMPC_capture: 11476 case OMPC_seq_cst: 11477 case OMPC_acq_rel: 11478 case OMPC_acquire: 11479 case OMPC_release: 11480 case OMPC_relaxed: 11481 case OMPC_depend: 11482 case OMPC_threads: 11483 case OMPC_simd: 11484 case OMPC_map: 11485 case OMPC_nogroup: 11486 case OMPC_dist_schedule: 11487 case OMPC_defaultmap: 11488 case OMPC_unknown: 11489 case OMPC_uniform: 11490 case OMPC_to: 11491 case OMPC_from: 11492 case OMPC_use_device_ptr: 11493 case OMPC_is_device_ptr: 11494 case OMPC_unified_address: 11495 case OMPC_unified_shared_memory: 11496 case OMPC_reverse_offload: 11497 case OMPC_dynamic_allocators: 11498 case OMPC_atomic_default_mem_order: 11499 case OMPC_device_type: 11500 case OMPC_match: 11501 case OMPC_nontemporal: 11502 case OMPC_order: 11503 case OMPC_destroy: 11504 case OMPC_inclusive: 11505 case OMPC_exclusive: 11506 case OMPC_uses_allocators: 11507 llvm_unreachable("Clause is not allowed."); 11508 } 11509 return Res; 11510 } 11511 11512 // An OpenMP directive such as 'target parallel' has two captured regions: 11513 // for the 'target' and 'parallel' respectively. This function returns 11514 // the region in which to capture expressions associated with a clause. 11515 // A return value of OMPD_unknown signifies that the expression should not 11516 // be captured. 11517 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 11518 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 11519 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 11520 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11521 switch (CKind) { 11522 case OMPC_if: 11523 switch (DKind) { 11524 case OMPD_target_parallel_for_simd: 11525 if (OpenMPVersion >= 50 && 11526 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11527 CaptureRegion = OMPD_parallel; 11528 break; 11529 } 11530 LLVM_FALLTHROUGH; 11531 case OMPD_target_parallel: 11532 case OMPD_target_parallel_for: 11533 // If this clause applies to the nested 'parallel' region, capture within 11534 // the 'target' region, otherwise do not capture. 11535 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11536 CaptureRegion = OMPD_target; 11537 break; 11538 case OMPD_target_teams_distribute_parallel_for_simd: 11539 if (OpenMPVersion >= 50 && 11540 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11541 CaptureRegion = OMPD_parallel; 11542 break; 11543 } 11544 LLVM_FALLTHROUGH; 11545 case OMPD_target_teams_distribute_parallel_for: 11546 // If this clause applies to the nested 'parallel' region, capture within 11547 // the 'teams' region, otherwise do not capture. 11548 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11549 CaptureRegion = OMPD_teams; 11550 break; 11551 case OMPD_teams_distribute_parallel_for_simd: 11552 if (OpenMPVersion >= 50 && 11553 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11554 CaptureRegion = OMPD_parallel; 11555 break; 11556 } 11557 LLVM_FALLTHROUGH; 11558 case OMPD_teams_distribute_parallel_for: 11559 CaptureRegion = OMPD_teams; 11560 break; 11561 case OMPD_target_update: 11562 case OMPD_target_enter_data: 11563 case OMPD_target_exit_data: 11564 CaptureRegion = OMPD_task; 11565 break; 11566 case OMPD_parallel_master_taskloop: 11567 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 11568 CaptureRegion = OMPD_parallel; 11569 break; 11570 case OMPD_parallel_master_taskloop_simd: 11571 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 11572 NameModifier == OMPD_taskloop) { 11573 CaptureRegion = OMPD_parallel; 11574 break; 11575 } 11576 if (OpenMPVersion <= 45) 11577 break; 11578 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11579 CaptureRegion = OMPD_taskloop; 11580 break; 11581 case OMPD_parallel_for_simd: 11582 if (OpenMPVersion <= 45) 11583 break; 11584 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11585 CaptureRegion = OMPD_parallel; 11586 break; 11587 case OMPD_taskloop_simd: 11588 case OMPD_master_taskloop_simd: 11589 if (OpenMPVersion <= 45) 11590 break; 11591 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11592 CaptureRegion = OMPD_taskloop; 11593 break; 11594 case OMPD_distribute_parallel_for_simd: 11595 if (OpenMPVersion <= 45) 11596 break; 11597 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11598 CaptureRegion = OMPD_parallel; 11599 break; 11600 case OMPD_target_simd: 11601 if (OpenMPVersion >= 50 && 11602 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11603 CaptureRegion = OMPD_target; 11604 break; 11605 case OMPD_teams_distribute_simd: 11606 case OMPD_target_teams_distribute_simd: 11607 if (OpenMPVersion >= 50 && 11608 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11609 CaptureRegion = OMPD_teams; 11610 break; 11611 case OMPD_cancel: 11612 case OMPD_parallel: 11613 case OMPD_parallel_master: 11614 case OMPD_parallel_sections: 11615 case OMPD_parallel_for: 11616 case OMPD_target: 11617 case OMPD_target_teams: 11618 case OMPD_target_teams_distribute: 11619 case OMPD_distribute_parallel_for: 11620 case OMPD_task: 11621 case OMPD_taskloop: 11622 case OMPD_master_taskloop: 11623 case OMPD_target_data: 11624 case OMPD_simd: 11625 case OMPD_for_simd: 11626 case OMPD_distribute_simd: 11627 // Do not capture if-clause expressions. 11628 break; 11629 case OMPD_threadprivate: 11630 case OMPD_allocate: 11631 case OMPD_taskyield: 11632 case OMPD_barrier: 11633 case OMPD_taskwait: 11634 case OMPD_cancellation_point: 11635 case OMPD_flush: 11636 case OMPD_depobj: 11637 case OMPD_scan: 11638 case OMPD_declare_reduction: 11639 case OMPD_declare_mapper: 11640 case OMPD_declare_simd: 11641 case OMPD_declare_variant: 11642 case OMPD_begin_declare_variant: 11643 case OMPD_end_declare_variant: 11644 case OMPD_declare_target: 11645 case OMPD_end_declare_target: 11646 case OMPD_teams: 11647 case OMPD_for: 11648 case OMPD_sections: 11649 case OMPD_section: 11650 case OMPD_single: 11651 case OMPD_master: 11652 case OMPD_critical: 11653 case OMPD_taskgroup: 11654 case OMPD_distribute: 11655 case OMPD_ordered: 11656 case OMPD_atomic: 11657 case OMPD_teams_distribute: 11658 case OMPD_requires: 11659 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 11660 case OMPD_unknown: 11661 llvm_unreachable("Unknown OpenMP directive"); 11662 } 11663 break; 11664 case OMPC_num_threads: 11665 switch (DKind) { 11666 case OMPD_target_parallel: 11667 case OMPD_target_parallel_for: 11668 case OMPD_target_parallel_for_simd: 11669 CaptureRegion = OMPD_target; 11670 break; 11671 case OMPD_teams_distribute_parallel_for: 11672 case OMPD_teams_distribute_parallel_for_simd: 11673 case OMPD_target_teams_distribute_parallel_for: 11674 case OMPD_target_teams_distribute_parallel_for_simd: 11675 CaptureRegion = OMPD_teams; 11676 break; 11677 case OMPD_parallel: 11678 case OMPD_parallel_master: 11679 case OMPD_parallel_sections: 11680 case OMPD_parallel_for: 11681 case OMPD_parallel_for_simd: 11682 case OMPD_distribute_parallel_for: 11683 case OMPD_distribute_parallel_for_simd: 11684 case OMPD_parallel_master_taskloop: 11685 case OMPD_parallel_master_taskloop_simd: 11686 // Do not capture num_threads-clause expressions. 11687 break; 11688 case OMPD_target_data: 11689 case OMPD_target_enter_data: 11690 case OMPD_target_exit_data: 11691 case OMPD_target_update: 11692 case OMPD_target: 11693 case OMPD_target_simd: 11694 case OMPD_target_teams: 11695 case OMPD_target_teams_distribute: 11696 case OMPD_target_teams_distribute_simd: 11697 case OMPD_cancel: 11698 case OMPD_task: 11699 case OMPD_taskloop: 11700 case OMPD_taskloop_simd: 11701 case OMPD_master_taskloop: 11702 case OMPD_master_taskloop_simd: 11703 case OMPD_threadprivate: 11704 case OMPD_allocate: 11705 case OMPD_taskyield: 11706 case OMPD_barrier: 11707 case OMPD_taskwait: 11708 case OMPD_cancellation_point: 11709 case OMPD_flush: 11710 case OMPD_depobj: 11711 case OMPD_scan: 11712 case OMPD_declare_reduction: 11713 case OMPD_declare_mapper: 11714 case OMPD_declare_simd: 11715 case OMPD_declare_variant: 11716 case OMPD_begin_declare_variant: 11717 case OMPD_end_declare_variant: 11718 case OMPD_declare_target: 11719 case OMPD_end_declare_target: 11720 case OMPD_teams: 11721 case OMPD_simd: 11722 case OMPD_for: 11723 case OMPD_for_simd: 11724 case OMPD_sections: 11725 case OMPD_section: 11726 case OMPD_single: 11727 case OMPD_master: 11728 case OMPD_critical: 11729 case OMPD_taskgroup: 11730 case OMPD_distribute: 11731 case OMPD_ordered: 11732 case OMPD_atomic: 11733 case OMPD_distribute_simd: 11734 case OMPD_teams_distribute: 11735 case OMPD_teams_distribute_simd: 11736 case OMPD_requires: 11737 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11738 case OMPD_unknown: 11739 llvm_unreachable("Unknown OpenMP directive"); 11740 } 11741 break; 11742 case OMPC_num_teams: 11743 switch (DKind) { 11744 case OMPD_target_teams: 11745 case OMPD_target_teams_distribute: 11746 case OMPD_target_teams_distribute_simd: 11747 case OMPD_target_teams_distribute_parallel_for: 11748 case OMPD_target_teams_distribute_parallel_for_simd: 11749 CaptureRegion = OMPD_target; 11750 break; 11751 case OMPD_teams_distribute_parallel_for: 11752 case OMPD_teams_distribute_parallel_for_simd: 11753 case OMPD_teams: 11754 case OMPD_teams_distribute: 11755 case OMPD_teams_distribute_simd: 11756 // Do not capture num_teams-clause expressions. 11757 break; 11758 case OMPD_distribute_parallel_for: 11759 case OMPD_distribute_parallel_for_simd: 11760 case OMPD_task: 11761 case OMPD_taskloop: 11762 case OMPD_taskloop_simd: 11763 case OMPD_master_taskloop: 11764 case OMPD_master_taskloop_simd: 11765 case OMPD_parallel_master_taskloop: 11766 case OMPD_parallel_master_taskloop_simd: 11767 case OMPD_target_data: 11768 case OMPD_target_enter_data: 11769 case OMPD_target_exit_data: 11770 case OMPD_target_update: 11771 case OMPD_cancel: 11772 case OMPD_parallel: 11773 case OMPD_parallel_master: 11774 case OMPD_parallel_sections: 11775 case OMPD_parallel_for: 11776 case OMPD_parallel_for_simd: 11777 case OMPD_target: 11778 case OMPD_target_simd: 11779 case OMPD_target_parallel: 11780 case OMPD_target_parallel_for: 11781 case OMPD_target_parallel_for_simd: 11782 case OMPD_threadprivate: 11783 case OMPD_allocate: 11784 case OMPD_taskyield: 11785 case OMPD_barrier: 11786 case OMPD_taskwait: 11787 case OMPD_cancellation_point: 11788 case OMPD_flush: 11789 case OMPD_depobj: 11790 case OMPD_scan: 11791 case OMPD_declare_reduction: 11792 case OMPD_declare_mapper: 11793 case OMPD_declare_simd: 11794 case OMPD_declare_variant: 11795 case OMPD_begin_declare_variant: 11796 case OMPD_end_declare_variant: 11797 case OMPD_declare_target: 11798 case OMPD_end_declare_target: 11799 case OMPD_simd: 11800 case OMPD_for: 11801 case OMPD_for_simd: 11802 case OMPD_sections: 11803 case OMPD_section: 11804 case OMPD_single: 11805 case OMPD_master: 11806 case OMPD_critical: 11807 case OMPD_taskgroup: 11808 case OMPD_distribute: 11809 case OMPD_ordered: 11810 case OMPD_atomic: 11811 case OMPD_distribute_simd: 11812 case OMPD_requires: 11813 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11814 case OMPD_unknown: 11815 llvm_unreachable("Unknown OpenMP directive"); 11816 } 11817 break; 11818 case OMPC_thread_limit: 11819 switch (DKind) { 11820 case OMPD_target_teams: 11821 case OMPD_target_teams_distribute: 11822 case OMPD_target_teams_distribute_simd: 11823 case OMPD_target_teams_distribute_parallel_for: 11824 case OMPD_target_teams_distribute_parallel_for_simd: 11825 CaptureRegion = OMPD_target; 11826 break; 11827 case OMPD_teams_distribute_parallel_for: 11828 case OMPD_teams_distribute_parallel_for_simd: 11829 case OMPD_teams: 11830 case OMPD_teams_distribute: 11831 case OMPD_teams_distribute_simd: 11832 // Do not capture thread_limit-clause expressions. 11833 break; 11834 case OMPD_distribute_parallel_for: 11835 case OMPD_distribute_parallel_for_simd: 11836 case OMPD_task: 11837 case OMPD_taskloop: 11838 case OMPD_taskloop_simd: 11839 case OMPD_master_taskloop: 11840 case OMPD_master_taskloop_simd: 11841 case OMPD_parallel_master_taskloop: 11842 case OMPD_parallel_master_taskloop_simd: 11843 case OMPD_target_data: 11844 case OMPD_target_enter_data: 11845 case OMPD_target_exit_data: 11846 case OMPD_target_update: 11847 case OMPD_cancel: 11848 case OMPD_parallel: 11849 case OMPD_parallel_master: 11850 case OMPD_parallel_sections: 11851 case OMPD_parallel_for: 11852 case OMPD_parallel_for_simd: 11853 case OMPD_target: 11854 case OMPD_target_simd: 11855 case OMPD_target_parallel: 11856 case OMPD_target_parallel_for: 11857 case OMPD_target_parallel_for_simd: 11858 case OMPD_threadprivate: 11859 case OMPD_allocate: 11860 case OMPD_taskyield: 11861 case OMPD_barrier: 11862 case OMPD_taskwait: 11863 case OMPD_cancellation_point: 11864 case OMPD_flush: 11865 case OMPD_depobj: 11866 case OMPD_scan: 11867 case OMPD_declare_reduction: 11868 case OMPD_declare_mapper: 11869 case OMPD_declare_simd: 11870 case OMPD_declare_variant: 11871 case OMPD_begin_declare_variant: 11872 case OMPD_end_declare_variant: 11873 case OMPD_declare_target: 11874 case OMPD_end_declare_target: 11875 case OMPD_simd: 11876 case OMPD_for: 11877 case OMPD_for_simd: 11878 case OMPD_sections: 11879 case OMPD_section: 11880 case OMPD_single: 11881 case OMPD_master: 11882 case OMPD_critical: 11883 case OMPD_taskgroup: 11884 case OMPD_distribute: 11885 case OMPD_ordered: 11886 case OMPD_atomic: 11887 case OMPD_distribute_simd: 11888 case OMPD_requires: 11889 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11890 case OMPD_unknown: 11891 llvm_unreachable("Unknown OpenMP directive"); 11892 } 11893 break; 11894 case OMPC_schedule: 11895 switch (DKind) { 11896 case OMPD_parallel_for: 11897 case OMPD_parallel_for_simd: 11898 case OMPD_distribute_parallel_for: 11899 case OMPD_distribute_parallel_for_simd: 11900 case OMPD_teams_distribute_parallel_for: 11901 case OMPD_teams_distribute_parallel_for_simd: 11902 case OMPD_target_parallel_for: 11903 case OMPD_target_parallel_for_simd: 11904 case OMPD_target_teams_distribute_parallel_for: 11905 case OMPD_target_teams_distribute_parallel_for_simd: 11906 CaptureRegion = OMPD_parallel; 11907 break; 11908 case OMPD_for: 11909 case OMPD_for_simd: 11910 // Do not capture schedule-clause expressions. 11911 break; 11912 case OMPD_task: 11913 case OMPD_taskloop: 11914 case OMPD_taskloop_simd: 11915 case OMPD_master_taskloop: 11916 case OMPD_master_taskloop_simd: 11917 case OMPD_parallel_master_taskloop: 11918 case OMPD_parallel_master_taskloop_simd: 11919 case OMPD_target_data: 11920 case OMPD_target_enter_data: 11921 case OMPD_target_exit_data: 11922 case OMPD_target_update: 11923 case OMPD_teams: 11924 case OMPD_teams_distribute: 11925 case OMPD_teams_distribute_simd: 11926 case OMPD_target_teams_distribute: 11927 case OMPD_target_teams_distribute_simd: 11928 case OMPD_target: 11929 case OMPD_target_simd: 11930 case OMPD_target_parallel: 11931 case OMPD_cancel: 11932 case OMPD_parallel: 11933 case OMPD_parallel_master: 11934 case OMPD_parallel_sections: 11935 case OMPD_threadprivate: 11936 case OMPD_allocate: 11937 case OMPD_taskyield: 11938 case OMPD_barrier: 11939 case OMPD_taskwait: 11940 case OMPD_cancellation_point: 11941 case OMPD_flush: 11942 case OMPD_depobj: 11943 case OMPD_scan: 11944 case OMPD_declare_reduction: 11945 case OMPD_declare_mapper: 11946 case OMPD_declare_simd: 11947 case OMPD_declare_variant: 11948 case OMPD_begin_declare_variant: 11949 case OMPD_end_declare_variant: 11950 case OMPD_declare_target: 11951 case OMPD_end_declare_target: 11952 case OMPD_simd: 11953 case OMPD_sections: 11954 case OMPD_section: 11955 case OMPD_single: 11956 case OMPD_master: 11957 case OMPD_critical: 11958 case OMPD_taskgroup: 11959 case OMPD_distribute: 11960 case OMPD_ordered: 11961 case OMPD_atomic: 11962 case OMPD_distribute_simd: 11963 case OMPD_target_teams: 11964 case OMPD_requires: 11965 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11966 case OMPD_unknown: 11967 llvm_unreachable("Unknown OpenMP directive"); 11968 } 11969 break; 11970 case OMPC_dist_schedule: 11971 switch (DKind) { 11972 case OMPD_teams_distribute_parallel_for: 11973 case OMPD_teams_distribute_parallel_for_simd: 11974 case OMPD_teams_distribute: 11975 case OMPD_teams_distribute_simd: 11976 case OMPD_target_teams_distribute_parallel_for: 11977 case OMPD_target_teams_distribute_parallel_for_simd: 11978 case OMPD_target_teams_distribute: 11979 case OMPD_target_teams_distribute_simd: 11980 CaptureRegion = OMPD_teams; 11981 break; 11982 case OMPD_distribute_parallel_for: 11983 case OMPD_distribute_parallel_for_simd: 11984 case OMPD_distribute: 11985 case OMPD_distribute_simd: 11986 // Do not capture thread_limit-clause expressions. 11987 break; 11988 case OMPD_parallel_for: 11989 case OMPD_parallel_for_simd: 11990 case OMPD_target_parallel_for_simd: 11991 case OMPD_target_parallel_for: 11992 case OMPD_task: 11993 case OMPD_taskloop: 11994 case OMPD_taskloop_simd: 11995 case OMPD_master_taskloop: 11996 case OMPD_master_taskloop_simd: 11997 case OMPD_parallel_master_taskloop: 11998 case OMPD_parallel_master_taskloop_simd: 11999 case OMPD_target_data: 12000 case OMPD_target_enter_data: 12001 case OMPD_target_exit_data: 12002 case OMPD_target_update: 12003 case OMPD_teams: 12004 case OMPD_target: 12005 case OMPD_target_simd: 12006 case OMPD_target_parallel: 12007 case OMPD_cancel: 12008 case OMPD_parallel: 12009 case OMPD_parallel_master: 12010 case OMPD_parallel_sections: 12011 case OMPD_threadprivate: 12012 case OMPD_allocate: 12013 case OMPD_taskyield: 12014 case OMPD_barrier: 12015 case OMPD_taskwait: 12016 case OMPD_cancellation_point: 12017 case OMPD_flush: 12018 case OMPD_depobj: 12019 case OMPD_scan: 12020 case OMPD_declare_reduction: 12021 case OMPD_declare_mapper: 12022 case OMPD_declare_simd: 12023 case OMPD_declare_variant: 12024 case OMPD_begin_declare_variant: 12025 case OMPD_end_declare_variant: 12026 case OMPD_declare_target: 12027 case OMPD_end_declare_target: 12028 case OMPD_simd: 12029 case OMPD_for: 12030 case OMPD_for_simd: 12031 case OMPD_sections: 12032 case OMPD_section: 12033 case OMPD_single: 12034 case OMPD_master: 12035 case OMPD_critical: 12036 case OMPD_taskgroup: 12037 case OMPD_ordered: 12038 case OMPD_atomic: 12039 case OMPD_target_teams: 12040 case OMPD_requires: 12041 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 12042 case OMPD_unknown: 12043 llvm_unreachable("Unknown OpenMP directive"); 12044 } 12045 break; 12046 case OMPC_device: 12047 switch (DKind) { 12048 case OMPD_target_update: 12049 case OMPD_target_enter_data: 12050 case OMPD_target_exit_data: 12051 case OMPD_target: 12052 case OMPD_target_simd: 12053 case OMPD_target_teams: 12054 case OMPD_target_parallel: 12055 case OMPD_target_teams_distribute: 12056 case OMPD_target_teams_distribute_simd: 12057 case OMPD_target_parallel_for: 12058 case OMPD_target_parallel_for_simd: 12059 case OMPD_target_teams_distribute_parallel_for: 12060 case OMPD_target_teams_distribute_parallel_for_simd: 12061 CaptureRegion = OMPD_task; 12062 break; 12063 case OMPD_target_data: 12064 // Do not capture device-clause expressions. 12065 break; 12066 case OMPD_teams_distribute_parallel_for: 12067 case OMPD_teams_distribute_parallel_for_simd: 12068 case OMPD_teams: 12069 case OMPD_teams_distribute: 12070 case OMPD_teams_distribute_simd: 12071 case OMPD_distribute_parallel_for: 12072 case OMPD_distribute_parallel_for_simd: 12073 case OMPD_task: 12074 case OMPD_taskloop: 12075 case OMPD_taskloop_simd: 12076 case OMPD_master_taskloop: 12077 case OMPD_master_taskloop_simd: 12078 case OMPD_parallel_master_taskloop: 12079 case OMPD_parallel_master_taskloop_simd: 12080 case OMPD_cancel: 12081 case OMPD_parallel: 12082 case OMPD_parallel_master: 12083 case OMPD_parallel_sections: 12084 case OMPD_parallel_for: 12085 case OMPD_parallel_for_simd: 12086 case OMPD_threadprivate: 12087 case OMPD_allocate: 12088 case OMPD_taskyield: 12089 case OMPD_barrier: 12090 case OMPD_taskwait: 12091 case OMPD_cancellation_point: 12092 case OMPD_flush: 12093 case OMPD_depobj: 12094 case OMPD_scan: 12095 case OMPD_declare_reduction: 12096 case OMPD_declare_mapper: 12097 case OMPD_declare_simd: 12098 case OMPD_declare_variant: 12099 case OMPD_begin_declare_variant: 12100 case OMPD_end_declare_variant: 12101 case OMPD_declare_target: 12102 case OMPD_end_declare_target: 12103 case OMPD_simd: 12104 case OMPD_for: 12105 case OMPD_for_simd: 12106 case OMPD_sections: 12107 case OMPD_section: 12108 case OMPD_single: 12109 case OMPD_master: 12110 case OMPD_critical: 12111 case OMPD_taskgroup: 12112 case OMPD_distribute: 12113 case OMPD_ordered: 12114 case OMPD_atomic: 12115 case OMPD_distribute_simd: 12116 case OMPD_requires: 12117 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 12118 case OMPD_unknown: 12119 llvm_unreachable("Unknown OpenMP directive"); 12120 } 12121 break; 12122 case OMPC_grainsize: 12123 case OMPC_num_tasks: 12124 case OMPC_final: 12125 case OMPC_priority: 12126 switch (DKind) { 12127 case OMPD_task: 12128 case OMPD_taskloop: 12129 case OMPD_taskloop_simd: 12130 case OMPD_master_taskloop: 12131 case OMPD_master_taskloop_simd: 12132 break; 12133 case OMPD_parallel_master_taskloop: 12134 case OMPD_parallel_master_taskloop_simd: 12135 CaptureRegion = OMPD_parallel; 12136 break; 12137 case OMPD_target_update: 12138 case OMPD_target_enter_data: 12139 case OMPD_target_exit_data: 12140 case OMPD_target: 12141 case OMPD_target_simd: 12142 case OMPD_target_teams: 12143 case OMPD_target_parallel: 12144 case OMPD_target_teams_distribute: 12145 case OMPD_target_teams_distribute_simd: 12146 case OMPD_target_parallel_for: 12147 case OMPD_target_parallel_for_simd: 12148 case OMPD_target_teams_distribute_parallel_for: 12149 case OMPD_target_teams_distribute_parallel_for_simd: 12150 case OMPD_target_data: 12151 case OMPD_teams_distribute_parallel_for: 12152 case OMPD_teams_distribute_parallel_for_simd: 12153 case OMPD_teams: 12154 case OMPD_teams_distribute: 12155 case OMPD_teams_distribute_simd: 12156 case OMPD_distribute_parallel_for: 12157 case OMPD_distribute_parallel_for_simd: 12158 case OMPD_cancel: 12159 case OMPD_parallel: 12160 case OMPD_parallel_master: 12161 case OMPD_parallel_sections: 12162 case OMPD_parallel_for: 12163 case OMPD_parallel_for_simd: 12164 case OMPD_threadprivate: 12165 case OMPD_allocate: 12166 case OMPD_taskyield: 12167 case OMPD_barrier: 12168 case OMPD_taskwait: 12169 case OMPD_cancellation_point: 12170 case OMPD_flush: 12171 case OMPD_depobj: 12172 case OMPD_scan: 12173 case OMPD_declare_reduction: 12174 case OMPD_declare_mapper: 12175 case OMPD_declare_simd: 12176 case OMPD_declare_variant: 12177 case OMPD_begin_declare_variant: 12178 case OMPD_end_declare_variant: 12179 case OMPD_declare_target: 12180 case OMPD_end_declare_target: 12181 case OMPD_simd: 12182 case OMPD_for: 12183 case OMPD_for_simd: 12184 case OMPD_sections: 12185 case OMPD_section: 12186 case OMPD_single: 12187 case OMPD_master: 12188 case OMPD_critical: 12189 case OMPD_taskgroup: 12190 case OMPD_distribute: 12191 case OMPD_ordered: 12192 case OMPD_atomic: 12193 case OMPD_distribute_simd: 12194 case OMPD_requires: 12195 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 12196 case OMPD_unknown: 12197 llvm_unreachable("Unknown OpenMP directive"); 12198 } 12199 break; 12200 case OMPC_firstprivate: 12201 case OMPC_lastprivate: 12202 case OMPC_reduction: 12203 case OMPC_task_reduction: 12204 case OMPC_in_reduction: 12205 case OMPC_linear: 12206 case OMPC_default: 12207 case OMPC_proc_bind: 12208 case OMPC_safelen: 12209 case OMPC_simdlen: 12210 case OMPC_allocator: 12211 case OMPC_collapse: 12212 case OMPC_private: 12213 case OMPC_shared: 12214 case OMPC_aligned: 12215 case OMPC_copyin: 12216 case OMPC_copyprivate: 12217 case OMPC_ordered: 12218 case OMPC_nowait: 12219 case OMPC_untied: 12220 case OMPC_mergeable: 12221 case OMPC_threadprivate: 12222 case OMPC_allocate: 12223 case OMPC_flush: 12224 case OMPC_depobj: 12225 case OMPC_read: 12226 case OMPC_write: 12227 case OMPC_update: 12228 case OMPC_capture: 12229 case OMPC_seq_cst: 12230 case OMPC_acq_rel: 12231 case OMPC_acquire: 12232 case OMPC_release: 12233 case OMPC_relaxed: 12234 case OMPC_depend: 12235 case OMPC_threads: 12236 case OMPC_simd: 12237 case OMPC_map: 12238 case OMPC_nogroup: 12239 case OMPC_hint: 12240 case OMPC_defaultmap: 12241 case OMPC_unknown: 12242 case OMPC_uniform: 12243 case OMPC_to: 12244 case OMPC_from: 12245 case OMPC_use_device_ptr: 12246 case OMPC_is_device_ptr: 12247 case OMPC_unified_address: 12248 case OMPC_unified_shared_memory: 12249 case OMPC_reverse_offload: 12250 case OMPC_dynamic_allocators: 12251 case OMPC_atomic_default_mem_order: 12252 case OMPC_device_type: 12253 case OMPC_match: 12254 case OMPC_nontemporal: 12255 case OMPC_order: 12256 case OMPC_destroy: 12257 case OMPC_detach: 12258 case OMPC_inclusive: 12259 case OMPC_exclusive: 12260 case OMPC_uses_allocators: 12261 llvm_unreachable("Unexpected OpenMP clause."); 12262 } 12263 return CaptureRegion; 12264 } 12265 12266 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 12267 Expr *Condition, SourceLocation StartLoc, 12268 SourceLocation LParenLoc, 12269 SourceLocation NameModifierLoc, 12270 SourceLocation ColonLoc, 12271 SourceLocation EndLoc) { 12272 Expr *ValExpr = Condition; 12273 Stmt *HelperValStmt = nullptr; 12274 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12275 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12276 !Condition->isInstantiationDependent() && 12277 !Condition->containsUnexpandedParameterPack()) { 12278 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12279 if (Val.isInvalid()) 12280 return nullptr; 12281 12282 ValExpr = Val.get(); 12283 12284 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12285 CaptureRegion = getOpenMPCaptureRegionForClause( 12286 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 12287 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12288 ValExpr = MakeFullExpr(ValExpr).get(); 12289 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12290 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12291 HelperValStmt = buildPreInits(Context, Captures); 12292 } 12293 } 12294 12295 return new (Context) 12296 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 12297 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 12298 } 12299 12300 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 12301 SourceLocation StartLoc, 12302 SourceLocation LParenLoc, 12303 SourceLocation EndLoc) { 12304 Expr *ValExpr = Condition; 12305 Stmt *HelperValStmt = nullptr; 12306 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12307 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12308 !Condition->isInstantiationDependent() && 12309 !Condition->containsUnexpandedParameterPack()) { 12310 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12311 if (Val.isInvalid()) 12312 return nullptr; 12313 12314 ValExpr = MakeFullExpr(Val.get()).get(); 12315 12316 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12317 CaptureRegion = 12318 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 12319 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12320 ValExpr = MakeFullExpr(ValExpr).get(); 12321 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12322 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12323 HelperValStmt = buildPreInits(Context, Captures); 12324 } 12325 } 12326 12327 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 12328 StartLoc, LParenLoc, EndLoc); 12329 } 12330 12331 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 12332 Expr *Op) { 12333 if (!Op) 12334 return ExprError(); 12335 12336 class IntConvertDiagnoser : public ICEConvertDiagnoser { 12337 public: 12338 IntConvertDiagnoser() 12339 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 12340 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 12341 QualType T) override { 12342 return S.Diag(Loc, diag::err_omp_not_integral) << T; 12343 } 12344 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 12345 QualType T) override { 12346 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 12347 } 12348 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 12349 QualType T, 12350 QualType ConvTy) override { 12351 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 12352 } 12353 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 12354 QualType ConvTy) override { 12355 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12356 << ConvTy->isEnumeralType() << ConvTy; 12357 } 12358 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 12359 QualType T) override { 12360 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 12361 } 12362 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 12363 QualType ConvTy) override { 12364 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12365 << ConvTy->isEnumeralType() << ConvTy; 12366 } 12367 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 12368 QualType) override { 12369 llvm_unreachable("conversion functions are permitted"); 12370 } 12371 } ConvertDiagnoser; 12372 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 12373 } 12374 12375 static bool 12376 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 12377 bool StrictlyPositive, bool BuildCapture = false, 12378 OpenMPDirectiveKind DKind = OMPD_unknown, 12379 OpenMPDirectiveKind *CaptureRegion = nullptr, 12380 Stmt **HelperValStmt = nullptr) { 12381 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 12382 !ValExpr->isInstantiationDependent()) { 12383 SourceLocation Loc = ValExpr->getExprLoc(); 12384 ExprResult Value = 12385 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 12386 if (Value.isInvalid()) 12387 return false; 12388 12389 ValExpr = Value.get(); 12390 // The expression must evaluate to a non-negative integer value. 12391 llvm::APSInt Result; 12392 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 12393 Result.isSigned() && 12394 !((!StrictlyPositive && Result.isNonNegative()) || 12395 (StrictlyPositive && Result.isStrictlyPositive()))) { 12396 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 12397 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12398 << ValExpr->getSourceRange(); 12399 return false; 12400 } 12401 if (!BuildCapture) 12402 return true; 12403 *CaptureRegion = 12404 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 12405 if (*CaptureRegion != OMPD_unknown && 12406 !SemaRef.CurContext->isDependentContext()) { 12407 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 12408 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12409 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 12410 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 12411 } 12412 } 12413 return true; 12414 } 12415 12416 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 12417 SourceLocation StartLoc, 12418 SourceLocation LParenLoc, 12419 SourceLocation EndLoc) { 12420 Expr *ValExpr = NumThreads; 12421 Stmt *HelperValStmt = nullptr; 12422 12423 // OpenMP [2.5, Restrictions] 12424 // The num_threads expression must evaluate to a positive integer value. 12425 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 12426 /*StrictlyPositive=*/true)) 12427 return nullptr; 12428 12429 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12430 OpenMPDirectiveKind CaptureRegion = 12431 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 12432 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12433 ValExpr = MakeFullExpr(ValExpr).get(); 12434 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12435 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12436 HelperValStmt = buildPreInits(Context, Captures); 12437 } 12438 12439 return new (Context) OMPNumThreadsClause( 12440 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 12441 } 12442 12443 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 12444 OpenMPClauseKind CKind, 12445 bool StrictlyPositive) { 12446 if (!E) 12447 return ExprError(); 12448 if (E->isValueDependent() || E->isTypeDependent() || 12449 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 12450 return E; 12451 llvm::APSInt Result; 12452 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 12453 if (ICE.isInvalid()) 12454 return ExprError(); 12455 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 12456 (!StrictlyPositive && !Result.isNonNegative())) { 12457 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 12458 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12459 << E->getSourceRange(); 12460 return ExprError(); 12461 } 12462 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 12463 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 12464 << E->getSourceRange(); 12465 return ExprError(); 12466 } 12467 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 12468 DSAStack->setAssociatedLoops(Result.getExtValue()); 12469 else if (CKind == OMPC_ordered) 12470 DSAStack->setAssociatedLoops(Result.getExtValue()); 12471 return ICE; 12472 } 12473 12474 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 12475 SourceLocation LParenLoc, 12476 SourceLocation EndLoc) { 12477 // OpenMP [2.8.1, simd construct, Description] 12478 // The parameter of the safelen clause must be a constant 12479 // positive integer expression. 12480 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 12481 if (Safelen.isInvalid()) 12482 return nullptr; 12483 return new (Context) 12484 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 12485 } 12486 12487 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 12488 SourceLocation LParenLoc, 12489 SourceLocation EndLoc) { 12490 // OpenMP [2.8.1, simd construct, Description] 12491 // The parameter of the simdlen clause must be a constant 12492 // positive integer expression. 12493 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 12494 if (Simdlen.isInvalid()) 12495 return nullptr; 12496 return new (Context) 12497 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 12498 } 12499 12500 /// Tries to find omp_allocator_handle_t type. 12501 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 12502 DSAStackTy *Stack) { 12503 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 12504 if (!OMPAllocatorHandleT.isNull()) 12505 return true; 12506 // Build the predefined allocator expressions. 12507 bool ErrorFound = false; 12508 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 12509 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 12510 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 12511 StringRef Allocator = 12512 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 12513 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 12514 auto *VD = dyn_cast_or_null<ValueDecl>( 12515 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 12516 if (!VD) { 12517 ErrorFound = true; 12518 break; 12519 } 12520 QualType AllocatorType = 12521 VD->getType().getNonLValueExprType(S.getASTContext()); 12522 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 12523 if (!Res.isUsable()) { 12524 ErrorFound = true; 12525 break; 12526 } 12527 if (OMPAllocatorHandleT.isNull()) 12528 OMPAllocatorHandleT = AllocatorType; 12529 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 12530 ErrorFound = true; 12531 break; 12532 } 12533 Stack->setAllocator(AllocatorKind, Res.get()); 12534 } 12535 if (ErrorFound) { 12536 S.Diag(Loc, diag::err_omp_implied_type_not_found) 12537 << "omp_allocator_handle_t"; 12538 return false; 12539 } 12540 OMPAllocatorHandleT.addConst(); 12541 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 12542 return true; 12543 } 12544 12545 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 12546 SourceLocation LParenLoc, 12547 SourceLocation EndLoc) { 12548 // OpenMP [2.11.3, allocate Directive, Description] 12549 // allocator is an expression of omp_allocator_handle_t type. 12550 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 12551 return nullptr; 12552 12553 ExprResult Allocator = DefaultLvalueConversion(A); 12554 if (Allocator.isInvalid()) 12555 return nullptr; 12556 Allocator = PerformImplicitConversion(Allocator.get(), 12557 DSAStack->getOMPAllocatorHandleT(), 12558 Sema::AA_Initializing, 12559 /*AllowExplicit=*/true); 12560 if (Allocator.isInvalid()) 12561 return nullptr; 12562 return new (Context) 12563 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 12564 } 12565 12566 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 12567 SourceLocation StartLoc, 12568 SourceLocation LParenLoc, 12569 SourceLocation EndLoc) { 12570 // OpenMP [2.7.1, loop construct, Description] 12571 // OpenMP [2.8.1, simd construct, Description] 12572 // OpenMP [2.9.6, distribute construct, Description] 12573 // The parameter of the collapse clause must be a constant 12574 // positive integer expression. 12575 ExprResult NumForLoopsResult = 12576 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 12577 if (NumForLoopsResult.isInvalid()) 12578 return nullptr; 12579 return new (Context) 12580 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 12581 } 12582 12583 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 12584 SourceLocation EndLoc, 12585 SourceLocation LParenLoc, 12586 Expr *NumForLoops) { 12587 // OpenMP [2.7.1, loop construct, Description] 12588 // OpenMP [2.8.1, simd construct, Description] 12589 // OpenMP [2.9.6, distribute construct, Description] 12590 // The parameter of the ordered clause must be a constant 12591 // positive integer expression if any. 12592 if (NumForLoops && LParenLoc.isValid()) { 12593 ExprResult NumForLoopsResult = 12594 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 12595 if (NumForLoopsResult.isInvalid()) 12596 return nullptr; 12597 NumForLoops = NumForLoopsResult.get(); 12598 } else { 12599 NumForLoops = nullptr; 12600 } 12601 auto *Clause = OMPOrderedClause::Create( 12602 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 12603 StartLoc, LParenLoc, EndLoc); 12604 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 12605 return Clause; 12606 } 12607 12608 OMPClause *Sema::ActOnOpenMPSimpleClause( 12609 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 12610 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12611 OMPClause *Res = nullptr; 12612 switch (Kind) { 12613 case OMPC_default: 12614 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 12615 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12616 break; 12617 case OMPC_proc_bind: 12618 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 12619 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12620 break; 12621 case OMPC_atomic_default_mem_order: 12622 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 12623 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 12624 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12625 break; 12626 case OMPC_order: 12627 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 12628 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12629 break; 12630 case OMPC_update: 12631 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 12632 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12633 break; 12634 case OMPC_if: 12635 case OMPC_final: 12636 case OMPC_num_threads: 12637 case OMPC_safelen: 12638 case OMPC_simdlen: 12639 case OMPC_allocator: 12640 case OMPC_collapse: 12641 case OMPC_schedule: 12642 case OMPC_private: 12643 case OMPC_firstprivate: 12644 case OMPC_lastprivate: 12645 case OMPC_shared: 12646 case OMPC_reduction: 12647 case OMPC_task_reduction: 12648 case OMPC_in_reduction: 12649 case OMPC_linear: 12650 case OMPC_aligned: 12651 case OMPC_copyin: 12652 case OMPC_copyprivate: 12653 case OMPC_ordered: 12654 case OMPC_nowait: 12655 case OMPC_untied: 12656 case OMPC_mergeable: 12657 case OMPC_threadprivate: 12658 case OMPC_allocate: 12659 case OMPC_flush: 12660 case OMPC_depobj: 12661 case OMPC_read: 12662 case OMPC_write: 12663 case OMPC_capture: 12664 case OMPC_seq_cst: 12665 case OMPC_acq_rel: 12666 case OMPC_acquire: 12667 case OMPC_release: 12668 case OMPC_relaxed: 12669 case OMPC_depend: 12670 case OMPC_device: 12671 case OMPC_threads: 12672 case OMPC_simd: 12673 case OMPC_map: 12674 case OMPC_num_teams: 12675 case OMPC_thread_limit: 12676 case OMPC_priority: 12677 case OMPC_grainsize: 12678 case OMPC_nogroup: 12679 case OMPC_num_tasks: 12680 case OMPC_hint: 12681 case OMPC_dist_schedule: 12682 case OMPC_defaultmap: 12683 case OMPC_unknown: 12684 case OMPC_uniform: 12685 case OMPC_to: 12686 case OMPC_from: 12687 case OMPC_use_device_ptr: 12688 case OMPC_is_device_ptr: 12689 case OMPC_unified_address: 12690 case OMPC_unified_shared_memory: 12691 case OMPC_reverse_offload: 12692 case OMPC_dynamic_allocators: 12693 case OMPC_device_type: 12694 case OMPC_match: 12695 case OMPC_nontemporal: 12696 case OMPC_destroy: 12697 case OMPC_detach: 12698 case OMPC_inclusive: 12699 case OMPC_exclusive: 12700 case OMPC_uses_allocators: 12701 llvm_unreachable("Clause is not allowed."); 12702 } 12703 return Res; 12704 } 12705 12706 static std::string 12707 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 12708 ArrayRef<unsigned> Exclude = llvm::None) { 12709 SmallString<256> Buffer; 12710 llvm::raw_svector_ostream Out(Buffer); 12711 unsigned Skipped = Exclude.size(); 12712 auto S = Exclude.begin(), E = Exclude.end(); 12713 for (unsigned I = First; I < Last; ++I) { 12714 if (std::find(S, E, I) != E) { 12715 --Skipped; 12716 continue; 12717 } 12718 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 12719 if (I + Skipped + 2 == Last) 12720 Out << " or "; 12721 else if (I + Skipped + 1 != Last) 12722 Out << ", "; 12723 } 12724 return std::string(Out.str()); 12725 } 12726 12727 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 12728 SourceLocation KindKwLoc, 12729 SourceLocation StartLoc, 12730 SourceLocation LParenLoc, 12731 SourceLocation EndLoc) { 12732 if (Kind == OMP_DEFAULT_unknown) { 12733 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12734 << getListOfPossibleValues(OMPC_default, /*First=*/0, 12735 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 12736 << getOpenMPClauseName(OMPC_default); 12737 return nullptr; 12738 } 12739 if (Kind == OMP_DEFAULT_none) 12740 DSAStack->setDefaultDSANone(KindKwLoc); 12741 else if (Kind == OMP_DEFAULT_shared) 12742 DSAStack->setDefaultDSAShared(KindKwLoc); 12743 12744 return new (Context) 12745 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12746 } 12747 12748 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 12749 SourceLocation KindKwLoc, 12750 SourceLocation StartLoc, 12751 SourceLocation LParenLoc, 12752 SourceLocation EndLoc) { 12753 if (Kind == OMP_PROC_BIND_unknown) { 12754 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12755 << getListOfPossibleValues(OMPC_proc_bind, 12756 /*First=*/unsigned(OMP_PROC_BIND_master), 12757 /*Last=*/5) 12758 << getOpenMPClauseName(OMPC_proc_bind); 12759 return nullptr; 12760 } 12761 return new (Context) 12762 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12763 } 12764 12765 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 12766 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 12767 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12768 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 12769 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12770 << getListOfPossibleValues( 12771 OMPC_atomic_default_mem_order, /*First=*/0, 12772 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 12773 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 12774 return nullptr; 12775 } 12776 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 12777 LParenLoc, EndLoc); 12778 } 12779 12780 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 12781 SourceLocation KindKwLoc, 12782 SourceLocation StartLoc, 12783 SourceLocation LParenLoc, 12784 SourceLocation EndLoc) { 12785 if (Kind == OMPC_ORDER_unknown) { 12786 static_assert(OMPC_ORDER_unknown > 0, 12787 "OMPC_ORDER_unknown not greater than 0"); 12788 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12789 << getListOfPossibleValues(OMPC_order, /*First=*/0, 12790 /*Last=*/OMPC_ORDER_unknown) 12791 << getOpenMPClauseName(OMPC_order); 12792 return nullptr; 12793 } 12794 return new (Context) 12795 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12796 } 12797 12798 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 12799 SourceLocation KindKwLoc, 12800 SourceLocation StartLoc, 12801 SourceLocation LParenLoc, 12802 SourceLocation EndLoc) { 12803 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 12804 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 12805 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 12806 OMPC_DEPEND_depobj}; 12807 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12808 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12809 /*Last=*/OMPC_DEPEND_unknown, Except) 12810 << getOpenMPClauseName(OMPC_update); 12811 return nullptr; 12812 } 12813 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 12814 EndLoc); 12815 } 12816 12817 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 12818 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 12819 SourceLocation StartLoc, SourceLocation LParenLoc, 12820 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 12821 SourceLocation EndLoc) { 12822 OMPClause *Res = nullptr; 12823 switch (Kind) { 12824 case OMPC_schedule: 12825 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 12826 assert(Argument.size() == NumberOfElements && 12827 ArgumentLoc.size() == NumberOfElements); 12828 Res = ActOnOpenMPScheduleClause( 12829 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 12830 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 12831 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 12832 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 12833 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12834 break; 12835 case OMPC_if: 12836 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12837 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12838 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12839 DelimLoc, EndLoc); 12840 break; 12841 case OMPC_dist_schedule: 12842 Res = ActOnOpenMPDistScheduleClause( 12843 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12844 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12845 break; 12846 case OMPC_defaultmap: 12847 enum { Modifier, DefaultmapKind }; 12848 Res = ActOnOpenMPDefaultmapClause( 12849 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12850 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12851 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12852 EndLoc); 12853 break; 12854 case OMPC_device: 12855 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12856 Res = ActOnOpenMPDeviceClause( 12857 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 12858 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 12859 break; 12860 case OMPC_final: 12861 case OMPC_num_threads: 12862 case OMPC_safelen: 12863 case OMPC_simdlen: 12864 case OMPC_allocator: 12865 case OMPC_collapse: 12866 case OMPC_default: 12867 case OMPC_proc_bind: 12868 case OMPC_private: 12869 case OMPC_firstprivate: 12870 case OMPC_lastprivate: 12871 case OMPC_shared: 12872 case OMPC_reduction: 12873 case OMPC_task_reduction: 12874 case OMPC_in_reduction: 12875 case OMPC_linear: 12876 case OMPC_aligned: 12877 case OMPC_copyin: 12878 case OMPC_copyprivate: 12879 case OMPC_ordered: 12880 case OMPC_nowait: 12881 case OMPC_untied: 12882 case OMPC_mergeable: 12883 case OMPC_threadprivate: 12884 case OMPC_allocate: 12885 case OMPC_flush: 12886 case OMPC_depobj: 12887 case OMPC_read: 12888 case OMPC_write: 12889 case OMPC_update: 12890 case OMPC_capture: 12891 case OMPC_seq_cst: 12892 case OMPC_acq_rel: 12893 case OMPC_acquire: 12894 case OMPC_release: 12895 case OMPC_relaxed: 12896 case OMPC_depend: 12897 case OMPC_threads: 12898 case OMPC_simd: 12899 case OMPC_map: 12900 case OMPC_num_teams: 12901 case OMPC_thread_limit: 12902 case OMPC_priority: 12903 case OMPC_grainsize: 12904 case OMPC_nogroup: 12905 case OMPC_num_tasks: 12906 case OMPC_hint: 12907 case OMPC_unknown: 12908 case OMPC_uniform: 12909 case OMPC_to: 12910 case OMPC_from: 12911 case OMPC_use_device_ptr: 12912 case OMPC_is_device_ptr: 12913 case OMPC_unified_address: 12914 case OMPC_unified_shared_memory: 12915 case OMPC_reverse_offload: 12916 case OMPC_dynamic_allocators: 12917 case OMPC_atomic_default_mem_order: 12918 case OMPC_device_type: 12919 case OMPC_match: 12920 case OMPC_nontemporal: 12921 case OMPC_order: 12922 case OMPC_destroy: 12923 case OMPC_detach: 12924 case OMPC_inclusive: 12925 case OMPC_exclusive: 12926 case OMPC_uses_allocators: 12927 llvm_unreachable("Clause is not allowed."); 12928 } 12929 return Res; 12930 } 12931 12932 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12933 OpenMPScheduleClauseModifier M2, 12934 SourceLocation M1Loc, SourceLocation M2Loc) { 12935 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12936 SmallVector<unsigned, 2> Excluded; 12937 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12938 Excluded.push_back(M2); 12939 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12940 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12941 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12942 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12943 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12944 << getListOfPossibleValues(OMPC_schedule, 12945 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12946 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12947 Excluded) 12948 << getOpenMPClauseName(OMPC_schedule); 12949 return true; 12950 } 12951 return false; 12952 } 12953 12954 OMPClause *Sema::ActOnOpenMPScheduleClause( 12955 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 12956 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12957 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 12958 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 12959 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 12960 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 12961 return nullptr; 12962 // OpenMP, 2.7.1, Loop Construct, Restrictions 12963 // Either the monotonic modifier or the nonmonotonic modifier can be specified 12964 // but not both. 12965 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 12966 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 12967 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 12968 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 12969 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 12970 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 12971 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 12972 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 12973 return nullptr; 12974 } 12975 if (Kind == OMPC_SCHEDULE_unknown) { 12976 std::string Values; 12977 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 12978 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 12979 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12980 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12981 Exclude); 12982 } else { 12983 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12984 /*Last=*/OMPC_SCHEDULE_unknown); 12985 } 12986 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12987 << Values << getOpenMPClauseName(OMPC_schedule); 12988 return nullptr; 12989 } 12990 // OpenMP, 2.7.1, Loop Construct, Restrictions 12991 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 12992 // schedule(guided). 12993 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 12994 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 12995 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 12996 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 12997 diag::err_omp_schedule_nonmonotonic_static); 12998 return nullptr; 12999 } 13000 Expr *ValExpr = ChunkSize; 13001 Stmt *HelperValStmt = nullptr; 13002 if (ChunkSize) { 13003 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 13004 !ChunkSize->isInstantiationDependent() && 13005 !ChunkSize->containsUnexpandedParameterPack()) { 13006 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 13007 ExprResult Val = 13008 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 13009 if (Val.isInvalid()) 13010 return nullptr; 13011 13012 ValExpr = Val.get(); 13013 13014 // OpenMP [2.7.1, Restrictions] 13015 // chunk_size must be a loop invariant integer expression with a positive 13016 // value. 13017 llvm::APSInt Result; 13018 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 13019 if (Result.isSigned() && !Result.isStrictlyPositive()) { 13020 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 13021 << "schedule" << 1 << ChunkSize->getSourceRange(); 13022 return nullptr; 13023 } 13024 } else if (getOpenMPCaptureRegionForClause( 13025 DSAStack->getCurrentDirective(), OMPC_schedule, 13026 LangOpts.OpenMP) != OMPD_unknown && 13027 !CurContext->isDependentContext()) { 13028 ValExpr = MakeFullExpr(ValExpr).get(); 13029 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13030 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13031 HelperValStmt = buildPreInits(Context, Captures); 13032 } 13033 } 13034 } 13035 13036 return new (Context) 13037 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 13038 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 13039 } 13040 13041 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 13042 SourceLocation StartLoc, 13043 SourceLocation EndLoc) { 13044 OMPClause *Res = nullptr; 13045 switch (Kind) { 13046 case OMPC_ordered: 13047 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 13048 break; 13049 case OMPC_nowait: 13050 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 13051 break; 13052 case OMPC_untied: 13053 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 13054 break; 13055 case OMPC_mergeable: 13056 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 13057 break; 13058 case OMPC_read: 13059 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 13060 break; 13061 case OMPC_write: 13062 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 13063 break; 13064 case OMPC_update: 13065 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 13066 break; 13067 case OMPC_capture: 13068 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 13069 break; 13070 case OMPC_seq_cst: 13071 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 13072 break; 13073 case OMPC_acq_rel: 13074 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 13075 break; 13076 case OMPC_acquire: 13077 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 13078 break; 13079 case OMPC_release: 13080 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 13081 break; 13082 case OMPC_relaxed: 13083 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 13084 break; 13085 case OMPC_threads: 13086 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 13087 break; 13088 case OMPC_simd: 13089 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 13090 break; 13091 case OMPC_nogroup: 13092 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 13093 break; 13094 case OMPC_unified_address: 13095 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 13096 break; 13097 case OMPC_unified_shared_memory: 13098 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13099 break; 13100 case OMPC_reverse_offload: 13101 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 13102 break; 13103 case OMPC_dynamic_allocators: 13104 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 13105 break; 13106 case OMPC_destroy: 13107 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); 13108 break; 13109 case OMPC_if: 13110 case OMPC_final: 13111 case OMPC_num_threads: 13112 case OMPC_safelen: 13113 case OMPC_simdlen: 13114 case OMPC_allocator: 13115 case OMPC_collapse: 13116 case OMPC_schedule: 13117 case OMPC_private: 13118 case OMPC_firstprivate: 13119 case OMPC_lastprivate: 13120 case OMPC_shared: 13121 case OMPC_reduction: 13122 case OMPC_task_reduction: 13123 case OMPC_in_reduction: 13124 case OMPC_linear: 13125 case OMPC_aligned: 13126 case OMPC_copyin: 13127 case OMPC_copyprivate: 13128 case OMPC_default: 13129 case OMPC_proc_bind: 13130 case OMPC_threadprivate: 13131 case OMPC_allocate: 13132 case OMPC_flush: 13133 case OMPC_depobj: 13134 case OMPC_depend: 13135 case OMPC_device: 13136 case OMPC_map: 13137 case OMPC_num_teams: 13138 case OMPC_thread_limit: 13139 case OMPC_priority: 13140 case OMPC_grainsize: 13141 case OMPC_num_tasks: 13142 case OMPC_hint: 13143 case OMPC_dist_schedule: 13144 case OMPC_defaultmap: 13145 case OMPC_unknown: 13146 case OMPC_uniform: 13147 case OMPC_to: 13148 case OMPC_from: 13149 case OMPC_use_device_ptr: 13150 case OMPC_is_device_ptr: 13151 case OMPC_atomic_default_mem_order: 13152 case OMPC_device_type: 13153 case OMPC_match: 13154 case OMPC_nontemporal: 13155 case OMPC_order: 13156 case OMPC_detach: 13157 case OMPC_inclusive: 13158 case OMPC_exclusive: 13159 case OMPC_uses_allocators: 13160 llvm_unreachable("Clause is not allowed."); 13161 } 13162 return Res; 13163 } 13164 13165 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 13166 SourceLocation EndLoc) { 13167 DSAStack->setNowaitRegion(); 13168 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 13169 } 13170 13171 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 13172 SourceLocation EndLoc) { 13173 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 13174 } 13175 13176 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 13177 SourceLocation EndLoc) { 13178 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 13179 } 13180 13181 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 13182 SourceLocation EndLoc) { 13183 return new (Context) OMPReadClause(StartLoc, EndLoc); 13184 } 13185 13186 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 13187 SourceLocation EndLoc) { 13188 return new (Context) OMPWriteClause(StartLoc, EndLoc); 13189 } 13190 13191 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 13192 SourceLocation EndLoc) { 13193 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 13194 } 13195 13196 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 13197 SourceLocation EndLoc) { 13198 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 13199 } 13200 13201 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 13202 SourceLocation EndLoc) { 13203 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 13204 } 13205 13206 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 13207 SourceLocation EndLoc) { 13208 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 13209 } 13210 13211 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 13212 SourceLocation EndLoc) { 13213 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 13214 } 13215 13216 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 13217 SourceLocation EndLoc) { 13218 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 13219 } 13220 13221 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 13222 SourceLocation EndLoc) { 13223 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 13224 } 13225 13226 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 13227 SourceLocation EndLoc) { 13228 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 13229 } 13230 13231 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 13232 SourceLocation EndLoc) { 13233 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 13234 } 13235 13236 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 13237 SourceLocation EndLoc) { 13238 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 13239 } 13240 13241 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 13242 SourceLocation EndLoc) { 13243 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 13244 } 13245 13246 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 13247 SourceLocation EndLoc) { 13248 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13249 } 13250 13251 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 13252 SourceLocation EndLoc) { 13253 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 13254 } 13255 13256 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 13257 SourceLocation EndLoc) { 13258 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 13259 } 13260 13261 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, 13262 SourceLocation EndLoc) { 13263 return new (Context) OMPDestroyClause(StartLoc, EndLoc); 13264 } 13265 13266 OMPClause *Sema::ActOnOpenMPVarListClause( 13267 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr, 13268 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 13269 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 13270 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 13271 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13272 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 13273 SourceLocation ExtraModifierLoc) { 13274 SourceLocation StartLoc = Locs.StartLoc; 13275 SourceLocation LParenLoc = Locs.LParenLoc; 13276 SourceLocation EndLoc = Locs.EndLoc; 13277 OMPClause *Res = nullptr; 13278 switch (Kind) { 13279 case OMPC_private: 13280 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13281 break; 13282 case OMPC_firstprivate: 13283 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13284 break; 13285 case OMPC_lastprivate: 13286 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 13287 "Unexpected lastprivate modifier."); 13288 Res = ActOnOpenMPLastprivateClause( 13289 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 13290 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 13291 break; 13292 case OMPC_shared: 13293 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 13294 break; 13295 case OMPC_reduction: 13296 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 13297 "Unexpected lastprivate modifier."); 13298 Res = ActOnOpenMPReductionClause( 13299 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 13300 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 13301 ReductionOrMapperIdScopeSpec, ReductionOrMapperId); 13302 break; 13303 case OMPC_task_reduction: 13304 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13305 EndLoc, ReductionOrMapperIdScopeSpec, 13306 ReductionOrMapperId); 13307 break; 13308 case OMPC_in_reduction: 13309 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13310 EndLoc, ReductionOrMapperIdScopeSpec, 13311 ReductionOrMapperId); 13312 break; 13313 case OMPC_linear: 13314 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 13315 "Unexpected linear modifier."); 13316 Res = ActOnOpenMPLinearClause( 13317 VarList, DepModOrTailExpr, StartLoc, LParenLoc, 13318 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 13319 ColonLoc, EndLoc); 13320 break; 13321 case OMPC_aligned: 13322 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, 13323 LParenLoc, ColonLoc, EndLoc); 13324 break; 13325 case OMPC_copyin: 13326 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 13327 break; 13328 case OMPC_copyprivate: 13329 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13330 break; 13331 case OMPC_flush: 13332 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 13333 break; 13334 case OMPC_depend: 13335 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 13336 "Unexpected depend modifier."); 13337 Res = ActOnOpenMPDependClause( 13338 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier), 13339 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 13340 break; 13341 case OMPC_map: 13342 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 13343 "Unexpected map modifier."); 13344 Res = ActOnOpenMPMapClause( 13345 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 13346 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 13347 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); 13348 break; 13349 case OMPC_to: 13350 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 13351 ReductionOrMapperId, Locs); 13352 break; 13353 case OMPC_from: 13354 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 13355 ReductionOrMapperId, Locs); 13356 break; 13357 case OMPC_use_device_ptr: 13358 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 13359 break; 13360 case OMPC_is_device_ptr: 13361 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 13362 break; 13363 case OMPC_allocate: 13364 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, 13365 LParenLoc, ColonLoc, EndLoc); 13366 break; 13367 case OMPC_nontemporal: 13368 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 13369 break; 13370 case OMPC_inclusive: 13371 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13372 break; 13373 case OMPC_exclusive: 13374 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13375 break; 13376 case OMPC_if: 13377 case OMPC_depobj: 13378 case OMPC_final: 13379 case OMPC_num_threads: 13380 case OMPC_safelen: 13381 case OMPC_simdlen: 13382 case OMPC_allocator: 13383 case OMPC_collapse: 13384 case OMPC_default: 13385 case OMPC_proc_bind: 13386 case OMPC_schedule: 13387 case OMPC_ordered: 13388 case OMPC_nowait: 13389 case OMPC_untied: 13390 case OMPC_mergeable: 13391 case OMPC_threadprivate: 13392 case OMPC_read: 13393 case OMPC_write: 13394 case OMPC_update: 13395 case OMPC_capture: 13396 case OMPC_seq_cst: 13397 case OMPC_acq_rel: 13398 case OMPC_acquire: 13399 case OMPC_release: 13400 case OMPC_relaxed: 13401 case OMPC_device: 13402 case OMPC_threads: 13403 case OMPC_simd: 13404 case OMPC_num_teams: 13405 case OMPC_thread_limit: 13406 case OMPC_priority: 13407 case OMPC_grainsize: 13408 case OMPC_nogroup: 13409 case OMPC_num_tasks: 13410 case OMPC_hint: 13411 case OMPC_dist_schedule: 13412 case OMPC_defaultmap: 13413 case OMPC_unknown: 13414 case OMPC_uniform: 13415 case OMPC_unified_address: 13416 case OMPC_unified_shared_memory: 13417 case OMPC_reverse_offload: 13418 case OMPC_dynamic_allocators: 13419 case OMPC_atomic_default_mem_order: 13420 case OMPC_device_type: 13421 case OMPC_match: 13422 case OMPC_order: 13423 case OMPC_destroy: 13424 case OMPC_detach: 13425 case OMPC_uses_allocators: 13426 llvm_unreachable("Clause is not allowed."); 13427 } 13428 return Res; 13429 } 13430 13431 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 13432 ExprObjectKind OK, SourceLocation Loc) { 13433 ExprResult Res = BuildDeclRefExpr( 13434 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 13435 if (!Res.isUsable()) 13436 return ExprError(); 13437 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 13438 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 13439 if (!Res.isUsable()) 13440 return ExprError(); 13441 } 13442 if (VK != VK_LValue && Res.get()->isGLValue()) { 13443 Res = DefaultLvalueConversion(Res.get()); 13444 if (!Res.isUsable()) 13445 return ExprError(); 13446 } 13447 return Res; 13448 } 13449 13450 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 13451 SourceLocation StartLoc, 13452 SourceLocation LParenLoc, 13453 SourceLocation EndLoc) { 13454 SmallVector<Expr *, 8> Vars; 13455 SmallVector<Expr *, 8> PrivateCopies; 13456 for (Expr *RefExpr : VarList) { 13457 assert(RefExpr && "NULL expr in OpenMP private clause."); 13458 SourceLocation ELoc; 13459 SourceRange ERange; 13460 Expr *SimpleRefExpr = RefExpr; 13461 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13462 if (Res.second) { 13463 // It will be analyzed later. 13464 Vars.push_back(RefExpr); 13465 PrivateCopies.push_back(nullptr); 13466 } 13467 ValueDecl *D = Res.first; 13468 if (!D) 13469 continue; 13470 13471 QualType Type = D->getType(); 13472 auto *VD = dyn_cast<VarDecl>(D); 13473 13474 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13475 // A variable that appears in a private clause must not have an incomplete 13476 // type or a reference type. 13477 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 13478 continue; 13479 Type = Type.getNonReferenceType(); 13480 13481 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13482 // A variable that is privatized must not have a const-qualified type 13483 // unless it is of class type with a mutable member. This restriction does 13484 // not apply to the firstprivate clause. 13485 // 13486 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 13487 // A variable that appears in a private clause must not have a 13488 // const-qualified type unless it is of class type with a mutable member. 13489 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 13490 continue; 13491 13492 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13493 // in a Construct] 13494 // Variables with the predetermined data-sharing attributes may not be 13495 // listed in data-sharing attributes clauses, except for the cases 13496 // listed below. For these exceptions only, listing a predetermined 13497 // variable in a data-sharing attribute clause is allowed and overrides 13498 // the variable's predetermined data-sharing attributes. 13499 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13500 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 13501 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13502 << getOpenMPClauseName(OMPC_private); 13503 reportOriginalDsa(*this, DSAStack, D, DVar); 13504 continue; 13505 } 13506 13507 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13508 // Variably modified types are not supported for tasks. 13509 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13510 isOpenMPTaskingDirective(CurrDir)) { 13511 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13512 << getOpenMPClauseName(OMPC_private) << Type 13513 << getOpenMPDirectiveName(CurrDir); 13514 bool IsDecl = 13515 !VD || 13516 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13517 Diag(D->getLocation(), 13518 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13519 << D; 13520 continue; 13521 } 13522 13523 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13524 // A list item cannot appear in both a map clause and a data-sharing 13525 // attribute clause on the same construct 13526 // 13527 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13528 // A list item cannot appear in both a map clause and a data-sharing 13529 // attribute clause on the same construct unless the construct is a 13530 // combined construct. 13531 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 13532 CurrDir == OMPD_target) { 13533 OpenMPClauseKind ConflictKind; 13534 if (DSAStack->checkMappableExprComponentListsForDecl( 13535 VD, /*CurrentRegionOnly=*/true, 13536 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 13537 OpenMPClauseKind WhereFoundClauseKind) -> bool { 13538 ConflictKind = WhereFoundClauseKind; 13539 return true; 13540 })) { 13541 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13542 << getOpenMPClauseName(OMPC_private) 13543 << getOpenMPClauseName(ConflictKind) 13544 << getOpenMPDirectiveName(CurrDir); 13545 reportOriginalDsa(*this, DSAStack, D, DVar); 13546 continue; 13547 } 13548 } 13549 13550 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 13551 // A variable of class type (or array thereof) that appears in a private 13552 // clause requires an accessible, unambiguous default constructor for the 13553 // class type. 13554 // Generate helper private variable and initialize it with the default 13555 // value. The address of the original variable is replaced by the address of 13556 // the new private variable in CodeGen. This new variable is not added to 13557 // IdResolver, so the code in the OpenMP region uses original variable for 13558 // proper diagnostics. 13559 Type = Type.getUnqualifiedType(); 13560 VarDecl *VDPrivate = 13561 buildVarDecl(*this, ELoc, Type, D->getName(), 13562 D->hasAttrs() ? &D->getAttrs() : nullptr, 13563 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13564 ActOnUninitializedDecl(VDPrivate); 13565 if (VDPrivate->isInvalidDecl()) 13566 continue; 13567 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13568 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13569 13570 DeclRefExpr *Ref = nullptr; 13571 if (!VD && !CurContext->isDependentContext()) 13572 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13573 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 13574 Vars.push_back((VD || CurContext->isDependentContext()) 13575 ? RefExpr->IgnoreParens() 13576 : Ref); 13577 PrivateCopies.push_back(VDPrivateRefExpr); 13578 } 13579 13580 if (Vars.empty()) 13581 return nullptr; 13582 13583 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13584 PrivateCopies); 13585 } 13586 13587 namespace { 13588 class DiagsUninitializedSeveretyRAII { 13589 private: 13590 DiagnosticsEngine &Diags; 13591 SourceLocation SavedLoc; 13592 bool IsIgnored = false; 13593 13594 public: 13595 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 13596 bool IsIgnored) 13597 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 13598 if (!IsIgnored) { 13599 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 13600 /*Map*/ diag::Severity::Ignored, Loc); 13601 } 13602 } 13603 ~DiagsUninitializedSeveretyRAII() { 13604 if (!IsIgnored) 13605 Diags.popMappings(SavedLoc); 13606 } 13607 }; 13608 } 13609 13610 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 13611 SourceLocation StartLoc, 13612 SourceLocation LParenLoc, 13613 SourceLocation EndLoc) { 13614 SmallVector<Expr *, 8> Vars; 13615 SmallVector<Expr *, 8> PrivateCopies; 13616 SmallVector<Expr *, 8> Inits; 13617 SmallVector<Decl *, 4> ExprCaptures; 13618 bool IsImplicitClause = 13619 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 13620 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 13621 13622 for (Expr *RefExpr : VarList) { 13623 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 13624 SourceLocation ELoc; 13625 SourceRange ERange; 13626 Expr *SimpleRefExpr = RefExpr; 13627 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13628 if (Res.second) { 13629 // It will be analyzed later. 13630 Vars.push_back(RefExpr); 13631 PrivateCopies.push_back(nullptr); 13632 Inits.push_back(nullptr); 13633 } 13634 ValueDecl *D = Res.first; 13635 if (!D) 13636 continue; 13637 13638 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 13639 QualType Type = D->getType(); 13640 auto *VD = dyn_cast<VarDecl>(D); 13641 13642 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13643 // A variable that appears in a private clause must not have an incomplete 13644 // type or a reference type. 13645 if (RequireCompleteType(ELoc, Type, 13646 diag::err_omp_firstprivate_incomplete_type)) 13647 continue; 13648 Type = Type.getNonReferenceType(); 13649 13650 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 13651 // A variable of class type (or array thereof) that appears in a private 13652 // clause requires an accessible, unambiguous copy constructor for the 13653 // class type. 13654 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13655 13656 // If an implicit firstprivate variable found it was checked already. 13657 DSAStackTy::DSAVarData TopDVar; 13658 if (!IsImplicitClause) { 13659 DSAStackTy::DSAVarData DVar = 13660 DSAStack->getTopDSA(D, /*FromParent=*/false); 13661 TopDVar = DVar; 13662 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13663 bool IsConstant = ElemType.isConstant(Context); 13664 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 13665 // A list item that specifies a given variable may not appear in more 13666 // than one clause on the same directive, except that a variable may be 13667 // specified in both firstprivate and lastprivate clauses. 13668 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13669 // A list item may appear in a firstprivate or lastprivate clause but not 13670 // both. 13671 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 13672 (isOpenMPDistributeDirective(CurrDir) || 13673 DVar.CKind != OMPC_lastprivate) && 13674 DVar.RefExpr) { 13675 Diag(ELoc, diag::err_omp_wrong_dsa) 13676 << getOpenMPClauseName(DVar.CKind) 13677 << getOpenMPClauseName(OMPC_firstprivate); 13678 reportOriginalDsa(*this, DSAStack, D, DVar); 13679 continue; 13680 } 13681 13682 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13683 // in a Construct] 13684 // Variables with the predetermined data-sharing attributes may not be 13685 // listed in data-sharing attributes clauses, except for the cases 13686 // listed below. For these exceptions only, listing a predetermined 13687 // variable in a data-sharing attribute clause is allowed and overrides 13688 // the variable's predetermined data-sharing attributes. 13689 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13690 // in a Construct, C/C++, p.2] 13691 // Variables with const-qualified type having no mutable member may be 13692 // listed in a firstprivate clause, even if they are static data members. 13693 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 13694 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 13695 Diag(ELoc, diag::err_omp_wrong_dsa) 13696 << getOpenMPClauseName(DVar.CKind) 13697 << getOpenMPClauseName(OMPC_firstprivate); 13698 reportOriginalDsa(*this, DSAStack, D, DVar); 13699 continue; 13700 } 13701 13702 // OpenMP [2.9.3.4, Restrictions, p.2] 13703 // A list item that is private within a parallel region must not appear 13704 // in a firstprivate clause on a worksharing construct if any of the 13705 // worksharing regions arising from the worksharing construct ever bind 13706 // to any of the parallel regions arising from the parallel construct. 13707 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13708 // A list item that is private within a teams region must not appear in a 13709 // firstprivate clause on a distribute construct if any of the distribute 13710 // regions arising from the distribute construct ever bind to any of the 13711 // teams regions arising from the teams construct. 13712 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13713 // A list item that appears in a reduction clause of a teams construct 13714 // must not appear in a firstprivate clause on a distribute construct if 13715 // any of the distribute regions arising from the distribute construct 13716 // ever bind to any of the teams regions arising from the teams construct. 13717 if ((isOpenMPWorksharingDirective(CurrDir) || 13718 isOpenMPDistributeDirective(CurrDir)) && 13719 !isOpenMPParallelDirective(CurrDir) && 13720 !isOpenMPTeamsDirective(CurrDir)) { 13721 DVar = DSAStack->getImplicitDSA(D, true); 13722 if (DVar.CKind != OMPC_shared && 13723 (isOpenMPParallelDirective(DVar.DKind) || 13724 isOpenMPTeamsDirective(DVar.DKind) || 13725 DVar.DKind == OMPD_unknown)) { 13726 Diag(ELoc, diag::err_omp_required_access) 13727 << getOpenMPClauseName(OMPC_firstprivate) 13728 << getOpenMPClauseName(OMPC_shared); 13729 reportOriginalDsa(*this, DSAStack, D, DVar); 13730 continue; 13731 } 13732 } 13733 // OpenMP [2.9.3.4, Restrictions, p.3] 13734 // A list item that appears in a reduction clause of a parallel construct 13735 // must not appear in a firstprivate clause on a worksharing or task 13736 // construct if any of the worksharing or task regions arising from the 13737 // worksharing or task construct ever bind to any of the parallel regions 13738 // arising from the parallel construct. 13739 // OpenMP [2.9.3.4, Restrictions, p.4] 13740 // A list item that appears in a reduction clause in worksharing 13741 // construct must not appear in a firstprivate clause in a task construct 13742 // encountered during execution of any of the worksharing regions arising 13743 // from the worksharing construct. 13744 if (isOpenMPTaskingDirective(CurrDir)) { 13745 DVar = DSAStack->hasInnermostDSA( 13746 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 13747 [](OpenMPDirectiveKind K) { 13748 return isOpenMPParallelDirective(K) || 13749 isOpenMPWorksharingDirective(K) || 13750 isOpenMPTeamsDirective(K); 13751 }, 13752 /*FromParent=*/true); 13753 if (DVar.CKind == OMPC_reduction && 13754 (isOpenMPParallelDirective(DVar.DKind) || 13755 isOpenMPWorksharingDirective(DVar.DKind) || 13756 isOpenMPTeamsDirective(DVar.DKind))) { 13757 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 13758 << getOpenMPDirectiveName(DVar.DKind); 13759 reportOriginalDsa(*this, DSAStack, D, DVar); 13760 continue; 13761 } 13762 } 13763 13764 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13765 // A list item cannot appear in both a map clause and a data-sharing 13766 // attribute clause on the same construct 13767 // 13768 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13769 // A list item cannot appear in both a map clause and a data-sharing 13770 // attribute clause on the same construct unless the construct is a 13771 // combined construct. 13772 if ((LangOpts.OpenMP <= 45 && 13773 isOpenMPTargetExecutionDirective(CurrDir)) || 13774 CurrDir == OMPD_target) { 13775 OpenMPClauseKind ConflictKind; 13776 if (DSAStack->checkMappableExprComponentListsForDecl( 13777 VD, /*CurrentRegionOnly=*/true, 13778 [&ConflictKind]( 13779 OMPClauseMappableExprCommon::MappableExprComponentListRef, 13780 OpenMPClauseKind WhereFoundClauseKind) { 13781 ConflictKind = WhereFoundClauseKind; 13782 return true; 13783 })) { 13784 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13785 << getOpenMPClauseName(OMPC_firstprivate) 13786 << getOpenMPClauseName(ConflictKind) 13787 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13788 reportOriginalDsa(*this, DSAStack, D, DVar); 13789 continue; 13790 } 13791 } 13792 } 13793 13794 // Variably modified types are not supported for tasks. 13795 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13796 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 13797 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13798 << getOpenMPClauseName(OMPC_firstprivate) << Type 13799 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13800 bool IsDecl = 13801 !VD || 13802 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13803 Diag(D->getLocation(), 13804 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13805 << D; 13806 continue; 13807 } 13808 13809 Type = Type.getUnqualifiedType(); 13810 VarDecl *VDPrivate = 13811 buildVarDecl(*this, ELoc, Type, D->getName(), 13812 D->hasAttrs() ? &D->getAttrs() : nullptr, 13813 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13814 // Generate helper private variable and initialize it with the value of the 13815 // original variable. The address of the original variable is replaced by 13816 // the address of the new private variable in the CodeGen. This new variable 13817 // is not added to IdResolver, so the code in the OpenMP region uses 13818 // original variable for proper diagnostics and variable capturing. 13819 Expr *VDInitRefExpr = nullptr; 13820 // For arrays generate initializer for single element and replace it by the 13821 // original array element in CodeGen. 13822 if (Type->isArrayType()) { 13823 VarDecl *VDInit = 13824 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 13825 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 13826 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 13827 ElemType = ElemType.getUnqualifiedType(); 13828 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 13829 ".firstprivate.temp"); 13830 InitializedEntity Entity = 13831 InitializedEntity::InitializeVariable(VDInitTemp); 13832 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 13833 13834 InitializationSequence InitSeq(*this, Entity, Kind, Init); 13835 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 13836 if (Result.isInvalid()) 13837 VDPrivate->setInvalidDecl(); 13838 else 13839 VDPrivate->setInit(Result.getAs<Expr>()); 13840 // Remove temp variable declaration. 13841 Context.Deallocate(VDInitTemp); 13842 } else { 13843 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 13844 ".firstprivate.temp"); 13845 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 13846 RefExpr->getExprLoc()); 13847 AddInitializerToDecl(VDPrivate, 13848 DefaultLvalueConversion(VDInitRefExpr).get(), 13849 /*DirectInit=*/false); 13850 } 13851 if (VDPrivate->isInvalidDecl()) { 13852 if (IsImplicitClause) { 13853 Diag(RefExpr->getExprLoc(), 13854 diag::note_omp_task_predetermined_firstprivate_here); 13855 } 13856 continue; 13857 } 13858 CurContext->addDecl(VDPrivate); 13859 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13860 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 13861 RefExpr->getExprLoc()); 13862 DeclRefExpr *Ref = nullptr; 13863 if (!VD && !CurContext->isDependentContext()) { 13864 if (TopDVar.CKind == OMPC_lastprivate) { 13865 Ref = TopDVar.PrivateCopy; 13866 } else { 13867 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13868 if (!isOpenMPCapturedDecl(D)) 13869 ExprCaptures.push_back(Ref->getDecl()); 13870 } 13871 } 13872 if (!IsImplicitClause) 13873 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13874 Vars.push_back((VD || CurContext->isDependentContext()) 13875 ? RefExpr->IgnoreParens() 13876 : Ref); 13877 PrivateCopies.push_back(VDPrivateRefExpr); 13878 Inits.push_back(VDInitRefExpr); 13879 } 13880 13881 if (Vars.empty()) 13882 return nullptr; 13883 13884 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13885 Vars, PrivateCopies, Inits, 13886 buildPreInits(Context, ExprCaptures)); 13887 } 13888 13889 OMPClause *Sema::ActOnOpenMPLastprivateClause( 13890 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 13891 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 13892 SourceLocation LParenLoc, SourceLocation EndLoc) { 13893 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 13894 assert(ColonLoc.isValid() && "Colon location must be valid."); 13895 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 13896 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 13897 /*Last=*/OMPC_LASTPRIVATE_unknown) 13898 << getOpenMPClauseName(OMPC_lastprivate); 13899 return nullptr; 13900 } 13901 13902 SmallVector<Expr *, 8> Vars; 13903 SmallVector<Expr *, 8> SrcExprs; 13904 SmallVector<Expr *, 8> DstExprs; 13905 SmallVector<Expr *, 8> AssignmentOps; 13906 SmallVector<Decl *, 4> ExprCaptures; 13907 SmallVector<Expr *, 4> ExprPostUpdates; 13908 for (Expr *RefExpr : VarList) { 13909 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13910 SourceLocation ELoc; 13911 SourceRange ERange; 13912 Expr *SimpleRefExpr = RefExpr; 13913 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13914 if (Res.second) { 13915 // It will be analyzed later. 13916 Vars.push_back(RefExpr); 13917 SrcExprs.push_back(nullptr); 13918 DstExprs.push_back(nullptr); 13919 AssignmentOps.push_back(nullptr); 13920 } 13921 ValueDecl *D = Res.first; 13922 if (!D) 13923 continue; 13924 13925 QualType Type = D->getType(); 13926 auto *VD = dyn_cast<VarDecl>(D); 13927 13928 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 13929 // A variable that appears in a lastprivate clause must not have an 13930 // incomplete type or a reference type. 13931 if (RequireCompleteType(ELoc, Type, 13932 diag::err_omp_lastprivate_incomplete_type)) 13933 continue; 13934 Type = Type.getNonReferenceType(); 13935 13936 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13937 // A variable that is privatized must not have a const-qualified type 13938 // unless it is of class type with a mutable member. This restriction does 13939 // not apply to the firstprivate clause. 13940 // 13941 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 13942 // A variable that appears in a lastprivate clause must not have a 13943 // const-qualified type unless it is of class type with a mutable member. 13944 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 13945 continue; 13946 13947 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 13948 // A list item that appears in a lastprivate clause with the conditional 13949 // modifier must be a scalar variable. 13950 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 13951 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 13952 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13953 VarDecl::DeclarationOnly; 13954 Diag(D->getLocation(), 13955 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13956 << D; 13957 continue; 13958 } 13959 13960 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13961 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13962 // in a Construct] 13963 // Variables with the predetermined data-sharing attributes may not be 13964 // listed in data-sharing attributes clauses, except for the cases 13965 // listed below. 13966 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13967 // A list item may appear in a firstprivate or lastprivate clause but not 13968 // both. 13969 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13970 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 13971 (isOpenMPDistributeDirective(CurrDir) || 13972 DVar.CKind != OMPC_firstprivate) && 13973 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 13974 Diag(ELoc, diag::err_omp_wrong_dsa) 13975 << getOpenMPClauseName(DVar.CKind) 13976 << getOpenMPClauseName(OMPC_lastprivate); 13977 reportOriginalDsa(*this, DSAStack, D, DVar); 13978 continue; 13979 } 13980 13981 // OpenMP [2.14.3.5, Restrictions, p.2] 13982 // A list item that is private within a parallel region, or that appears in 13983 // the reduction clause of a parallel construct, must not appear in a 13984 // lastprivate clause on a worksharing construct if any of the corresponding 13985 // worksharing regions ever binds to any of the corresponding parallel 13986 // regions. 13987 DSAStackTy::DSAVarData TopDVar = DVar; 13988 if (isOpenMPWorksharingDirective(CurrDir) && 13989 !isOpenMPParallelDirective(CurrDir) && 13990 !isOpenMPTeamsDirective(CurrDir)) { 13991 DVar = DSAStack->getImplicitDSA(D, true); 13992 if (DVar.CKind != OMPC_shared) { 13993 Diag(ELoc, diag::err_omp_required_access) 13994 << getOpenMPClauseName(OMPC_lastprivate) 13995 << getOpenMPClauseName(OMPC_shared); 13996 reportOriginalDsa(*this, DSAStack, D, DVar); 13997 continue; 13998 } 13999 } 14000 14001 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 14002 // A variable of class type (or array thereof) that appears in a 14003 // lastprivate clause requires an accessible, unambiguous default 14004 // constructor for the class type, unless the list item is also specified 14005 // in a firstprivate clause. 14006 // A variable of class type (or array thereof) that appears in a 14007 // lastprivate clause requires an accessible, unambiguous copy assignment 14008 // operator for the class type. 14009 Type = Context.getBaseElementType(Type).getNonReferenceType(); 14010 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 14011 Type.getUnqualifiedType(), ".lastprivate.src", 14012 D->hasAttrs() ? &D->getAttrs() : nullptr); 14013 DeclRefExpr *PseudoSrcExpr = 14014 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 14015 VarDecl *DstVD = 14016 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 14017 D->hasAttrs() ? &D->getAttrs() : nullptr); 14018 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14019 // For arrays generate assignment operation for single element and replace 14020 // it by the original array element in CodeGen. 14021 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 14022 PseudoDstExpr, PseudoSrcExpr); 14023 if (AssignmentOp.isInvalid()) 14024 continue; 14025 AssignmentOp = 14026 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14027 if (AssignmentOp.isInvalid()) 14028 continue; 14029 14030 DeclRefExpr *Ref = nullptr; 14031 if (!VD && !CurContext->isDependentContext()) { 14032 if (TopDVar.CKind == OMPC_firstprivate) { 14033 Ref = TopDVar.PrivateCopy; 14034 } else { 14035 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14036 if (!isOpenMPCapturedDecl(D)) 14037 ExprCaptures.push_back(Ref->getDecl()); 14038 } 14039 if (TopDVar.CKind == OMPC_firstprivate || 14040 (!isOpenMPCapturedDecl(D) && 14041 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 14042 ExprResult RefRes = DefaultLvalueConversion(Ref); 14043 if (!RefRes.isUsable()) 14044 continue; 14045 ExprResult PostUpdateRes = 14046 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14047 RefRes.get()); 14048 if (!PostUpdateRes.isUsable()) 14049 continue; 14050 ExprPostUpdates.push_back( 14051 IgnoredValueConversions(PostUpdateRes.get()).get()); 14052 } 14053 } 14054 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 14055 Vars.push_back((VD || CurContext->isDependentContext()) 14056 ? RefExpr->IgnoreParens() 14057 : Ref); 14058 SrcExprs.push_back(PseudoSrcExpr); 14059 DstExprs.push_back(PseudoDstExpr); 14060 AssignmentOps.push_back(AssignmentOp.get()); 14061 } 14062 14063 if (Vars.empty()) 14064 return nullptr; 14065 14066 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14067 Vars, SrcExprs, DstExprs, AssignmentOps, 14068 LPKind, LPKindLoc, ColonLoc, 14069 buildPreInits(Context, ExprCaptures), 14070 buildPostUpdate(*this, ExprPostUpdates)); 14071 } 14072 14073 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 14074 SourceLocation StartLoc, 14075 SourceLocation LParenLoc, 14076 SourceLocation EndLoc) { 14077 SmallVector<Expr *, 8> Vars; 14078 for (Expr *RefExpr : VarList) { 14079 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 14080 SourceLocation ELoc; 14081 SourceRange ERange; 14082 Expr *SimpleRefExpr = RefExpr; 14083 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14084 if (Res.second) { 14085 // It will be analyzed later. 14086 Vars.push_back(RefExpr); 14087 } 14088 ValueDecl *D = Res.first; 14089 if (!D) 14090 continue; 14091 14092 auto *VD = dyn_cast<VarDecl>(D); 14093 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 14094 // in a Construct] 14095 // Variables with the predetermined data-sharing attributes may not be 14096 // listed in data-sharing attributes clauses, except for the cases 14097 // listed below. For these exceptions only, listing a predetermined 14098 // variable in a data-sharing attribute clause is allowed and overrides 14099 // the variable's predetermined data-sharing attributes. 14100 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14101 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 14102 DVar.RefExpr) { 14103 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14104 << getOpenMPClauseName(OMPC_shared); 14105 reportOriginalDsa(*this, DSAStack, D, DVar); 14106 continue; 14107 } 14108 14109 DeclRefExpr *Ref = nullptr; 14110 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 14111 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14112 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 14113 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 14114 ? RefExpr->IgnoreParens() 14115 : Ref); 14116 } 14117 14118 if (Vars.empty()) 14119 return nullptr; 14120 14121 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 14122 } 14123 14124 namespace { 14125 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 14126 DSAStackTy *Stack; 14127 14128 public: 14129 bool VisitDeclRefExpr(DeclRefExpr *E) { 14130 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 14131 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 14132 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 14133 return false; 14134 if (DVar.CKind != OMPC_unknown) 14135 return true; 14136 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 14137 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 14138 /*FromParent=*/true); 14139 return DVarPrivate.CKind != OMPC_unknown; 14140 } 14141 return false; 14142 } 14143 bool VisitStmt(Stmt *S) { 14144 for (Stmt *Child : S->children()) { 14145 if (Child && Visit(Child)) 14146 return true; 14147 } 14148 return false; 14149 } 14150 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 14151 }; 14152 } // namespace 14153 14154 namespace { 14155 // Transform MemberExpression for specified FieldDecl of current class to 14156 // DeclRefExpr to specified OMPCapturedExprDecl. 14157 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 14158 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 14159 ValueDecl *Field = nullptr; 14160 DeclRefExpr *CapturedExpr = nullptr; 14161 14162 public: 14163 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 14164 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 14165 14166 ExprResult TransformMemberExpr(MemberExpr *E) { 14167 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 14168 E->getMemberDecl() == Field) { 14169 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 14170 return CapturedExpr; 14171 } 14172 return BaseTransform::TransformMemberExpr(E); 14173 } 14174 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 14175 }; 14176 } // namespace 14177 14178 template <typename T, typename U> 14179 static T filterLookupForUDReductionAndMapper( 14180 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 14181 for (U &Set : Lookups) { 14182 for (auto *D : Set) { 14183 if (T Res = Gen(cast<ValueDecl>(D))) 14184 return Res; 14185 } 14186 } 14187 return T(); 14188 } 14189 14190 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 14191 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 14192 14193 for (auto RD : D->redecls()) { 14194 // Don't bother with extra checks if we already know this one isn't visible. 14195 if (RD == D) 14196 continue; 14197 14198 auto ND = cast<NamedDecl>(RD); 14199 if (LookupResult::isVisible(SemaRef, ND)) 14200 return ND; 14201 } 14202 14203 return nullptr; 14204 } 14205 14206 static void 14207 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 14208 SourceLocation Loc, QualType Ty, 14209 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 14210 // Find all of the associated namespaces and classes based on the 14211 // arguments we have. 14212 Sema::AssociatedNamespaceSet AssociatedNamespaces; 14213 Sema::AssociatedClassSet AssociatedClasses; 14214 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 14215 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 14216 AssociatedClasses); 14217 14218 // C++ [basic.lookup.argdep]p3: 14219 // Let X be the lookup set produced by unqualified lookup (3.4.1) 14220 // and let Y be the lookup set produced by argument dependent 14221 // lookup (defined as follows). If X contains [...] then Y is 14222 // empty. Otherwise Y is the set of declarations found in the 14223 // namespaces associated with the argument types as described 14224 // below. The set of declarations found by the lookup of the name 14225 // is the union of X and Y. 14226 // 14227 // Here, we compute Y and add its members to the overloaded 14228 // candidate set. 14229 for (auto *NS : AssociatedNamespaces) { 14230 // When considering an associated namespace, the lookup is the 14231 // same as the lookup performed when the associated namespace is 14232 // used as a qualifier (3.4.3.2) except that: 14233 // 14234 // -- Any using-directives in the associated namespace are 14235 // ignored. 14236 // 14237 // -- Any namespace-scope friend functions declared in 14238 // associated classes are visible within their respective 14239 // namespaces even if they are not visible during an ordinary 14240 // lookup (11.4). 14241 DeclContext::lookup_result R = NS->lookup(Id.getName()); 14242 for (auto *D : R) { 14243 auto *Underlying = D; 14244 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14245 Underlying = USD->getTargetDecl(); 14246 14247 if (!isa<OMPDeclareReductionDecl>(Underlying) && 14248 !isa<OMPDeclareMapperDecl>(Underlying)) 14249 continue; 14250 14251 if (!SemaRef.isVisible(D)) { 14252 D = findAcceptableDecl(SemaRef, D); 14253 if (!D) 14254 continue; 14255 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14256 Underlying = USD->getTargetDecl(); 14257 } 14258 Lookups.emplace_back(); 14259 Lookups.back().addDecl(Underlying); 14260 } 14261 } 14262 } 14263 14264 static ExprResult 14265 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 14266 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 14267 const DeclarationNameInfo &ReductionId, QualType Ty, 14268 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 14269 if (ReductionIdScopeSpec.isInvalid()) 14270 return ExprError(); 14271 SmallVector<UnresolvedSet<8>, 4> Lookups; 14272 if (S) { 14273 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14274 Lookup.suppressDiagnostics(); 14275 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 14276 NamedDecl *D = Lookup.getRepresentativeDecl(); 14277 do { 14278 S = S->getParent(); 14279 } while (S && !S->isDeclScope(D)); 14280 if (S) 14281 S = S->getParent(); 14282 Lookups.emplace_back(); 14283 Lookups.back().append(Lookup.begin(), Lookup.end()); 14284 Lookup.clear(); 14285 } 14286 } else if (auto *ULE = 14287 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 14288 Lookups.push_back(UnresolvedSet<8>()); 14289 Decl *PrevD = nullptr; 14290 for (NamedDecl *D : ULE->decls()) { 14291 if (D == PrevD) 14292 Lookups.push_back(UnresolvedSet<8>()); 14293 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 14294 Lookups.back().addDecl(DRD); 14295 PrevD = D; 14296 } 14297 } 14298 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 14299 Ty->isInstantiationDependentType() || 14300 Ty->containsUnexpandedParameterPack() || 14301 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14302 return !D->isInvalidDecl() && 14303 (D->getType()->isDependentType() || 14304 D->getType()->isInstantiationDependentType() || 14305 D->getType()->containsUnexpandedParameterPack()); 14306 })) { 14307 UnresolvedSet<8> ResSet; 14308 for (const UnresolvedSet<8> &Set : Lookups) { 14309 if (Set.empty()) 14310 continue; 14311 ResSet.append(Set.begin(), Set.end()); 14312 // The last item marks the end of all declarations at the specified scope. 14313 ResSet.addDecl(Set[Set.size() - 1]); 14314 } 14315 return UnresolvedLookupExpr::Create( 14316 SemaRef.Context, /*NamingClass=*/nullptr, 14317 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 14318 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 14319 } 14320 // Lookup inside the classes. 14321 // C++ [over.match.oper]p3: 14322 // For a unary operator @ with an operand of a type whose 14323 // cv-unqualified version is T1, and for a binary operator @ with 14324 // a left operand of a type whose cv-unqualified version is T1 and 14325 // a right operand of a type whose cv-unqualified version is T2, 14326 // three sets of candidate functions, designated member 14327 // candidates, non-member candidates and built-in candidates, are 14328 // constructed as follows: 14329 // -- If T1 is a complete class type or a class currently being 14330 // defined, the set of member candidates is the result of the 14331 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 14332 // the set of member candidates is empty. 14333 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14334 Lookup.suppressDiagnostics(); 14335 if (const auto *TyRec = Ty->getAs<RecordType>()) { 14336 // Complete the type if it can be completed. 14337 // If the type is neither complete nor being defined, bail out now. 14338 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 14339 TyRec->getDecl()->getDefinition()) { 14340 Lookup.clear(); 14341 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 14342 if (Lookup.empty()) { 14343 Lookups.emplace_back(); 14344 Lookups.back().append(Lookup.begin(), Lookup.end()); 14345 } 14346 } 14347 } 14348 // Perform ADL. 14349 if (SemaRef.getLangOpts().CPlusPlus) 14350 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 14351 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14352 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 14353 if (!D->isInvalidDecl() && 14354 SemaRef.Context.hasSameType(D->getType(), Ty)) 14355 return D; 14356 return nullptr; 14357 })) 14358 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 14359 VK_LValue, Loc); 14360 if (SemaRef.getLangOpts().CPlusPlus) { 14361 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14362 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 14363 if (!D->isInvalidDecl() && 14364 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 14365 !Ty.isMoreQualifiedThan(D->getType())) 14366 return D; 14367 return nullptr; 14368 })) { 14369 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14370 /*DetectVirtual=*/false); 14371 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 14372 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14373 VD->getType().getUnqualifiedType()))) { 14374 if (SemaRef.CheckBaseClassAccess( 14375 Loc, VD->getType(), Ty, Paths.front(), 14376 /*DiagID=*/0) != Sema::AR_inaccessible) { 14377 SemaRef.BuildBasePathArray(Paths, BasePath); 14378 return SemaRef.BuildDeclRefExpr( 14379 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 14380 } 14381 } 14382 } 14383 } 14384 } 14385 if (ReductionIdScopeSpec.isSet()) { 14386 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 14387 << Ty << Range; 14388 return ExprError(); 14389 } 14390 return ExprEmpty(); 14391 } 14392 14393 namespace { 14394 /// Data for the reduction-based clauses. 14395 struct ReductionData { 14396 /// List of original reduction items. 14397 SmallVector<Expr *, 8> Vars; 14398 /// List of private copies of the reduction items. 14399 SmallVector<Expr *, 8> Privates; 14400 /// LHS expressions for the reduction_op expressions. 14401 SmallVector<Expr *, 8> LHSs; 14402 /// RHS expressions for the reduction_op expressions. 14403 SmallVector<Expr *, 8> RHSs; 14404 /// Reduction operation expression. 14405 SmallVector<Expr *, 8> ReductionOps; 14406 /// Taskgroup descriptors for the corresponding reduction items in 14407 /// in_reduction clauses. 14408 SmallVector<Expr *, 8> TaskgroupDescriptors; 14409 /// List of captures for clause. 14410 SmallVector<Decl *, 4> ExprCaptures; 14411 /// List of postupdate expressions. 14412 SmallVector<Expr *, 4> ExprPostUpdates; 14413 /// Reduction modifier. 14414 unsigned RedModifier = 0; 14415 ReductionData() = delete; 14416 /// Reserves required memory for the reduction data. 14417 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 14418 Vars.reserve(Size); 14419 Privates.reserve(Size); 14420 LHSs.reserve(Size); 14421 RHSs.reserve(Size); 14422 ReductionOps.reserve(Size); 14423 TaskgroupDescriptors.reserve(Size); 14424 ExprCaptures.reserve(Size); 14425 ExprPostUpdates.reserve(Size); 14426 } 14427 /// Stores reduction item and reduction operation only (required for dependent 14428 /// reduction item). 14429 void push(Expr *Item, Expr *ReductionOp) { 14430 Vars.emplace_back(Item); 14431 Privates.emplace_back(nullptr); 14432 LHSs.emplace_back(nullptr); 14433 RHSs.emplace_back(nullptr); 14434 ReductionOps.emplace_back(ReductionOp); 14435 TaskgroupDescriptors.emplace_back(nullptr); 14436 } 14437 /// Stores reduction data. 14438 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 14439 Expr *TaskgroupDescriptor) { 14440 Vars.emplace_back(Item); 14441 Privates.emplace_back(Private); 14442 LHSs.emplace_back(LHS); 14443 RHSs.emplace_back(RHS); 14444 ReductionOps.emplace_back(ReductionOp); 14445 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 14446 } 14447 }; 14448 } // namespace 14449 14450 static bool checkOMPArraySectionConstantForReduction( 14451 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 14452 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 14453 const Expr *Length = OASE->getLength(); 14454 if (Length == nullptr) { 14455 // For array sections of the form [1:] or [:], we would need to analyze 14456 // the lower bound... 14457 if (OASE->getColonLoc().isValid()) 14458 return false; 14459 14460 // This is an array subscript which has implicit length 1! 14461 SingleElement = true; 14462 ArraySizes.push_back(llvm::APSInt::get(1)); 14463 } else { 14464 Expr::EvalResult Result; 14465 if (!Length->EvaluateAsInt(Result, Context)) 14466 return false; 14467 14468 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14469 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 14470 ArraySizes.push_back(ConstantLengthValue); 14471 } 14472 14473 // Get the base of this array section and walk up from there. 14474 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 14475 14476 // We require length = 1 for all array sections except the right-most to 14477 // guarantee that the memory region is contiguous and has no holes in it. 14478 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 14479 Length = TempOASE->getLength(); 14480 if (Length == nullptr) { 14481 // For array sections of the form [1:] or [:], we would need to analyze 14482 // the lower bound... 14483 if (OASE->getColonLoc().isValid()) 14484 return false; 14485 14486 // This is an array subscript which has implicit length 1! 14487 ArraySizes.push_back(llvm::APSInt::get(1)); 14488 } else { 14489 Expr::EvalResult Result; 14490 if (!Length->EvaluateAsInt(Result, Context)) 14491 return false; 14492 14493 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14494 if (ConstantLengthValue.getSExtValue() != 1) 14495 return false; 14496 14497 ArraySizes.push_back(ConstantLengthValue); 14498 } 14499 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 14500 } 14501 14502 // If we have a single element, we don't need to add the implicit lengths. 14503 if (!SingleElement) { 14504 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 14505 // Has implicit length 1! 14506 ArraySizes.push_back(llvm::APSInt::get(1)); 14507 Base = TempASE->getBase()->IgnoreParenImpCasts(); 14508 } 14509 } 14510 14511 // This array section can be privatized as a single value or as a constant 14512 // sized array. 14513 return true; 14514 } 14515 14516 static bool actOnOMPReductionKindClause( 14517 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 14518 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14519 SourceLocation ColonLoc, SourceLocation EndLoc, 14520 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14521 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 14522 DeclarationName DN = ReductionId.getName(); 14523 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 14524 BinaryOperatorKind BOK = BO_Comma; 14525 14526 ASTContext &Context = S.Context; 14527 // OpenMP [2.14.3.6, reduction clause] 14528 // C 14529 // reduction-identifier is either an identifier or one of the following 14530 // operators: +, -, *, &, |, ^, && and || 14531 // C++ 14532 // reduction-identifier is either an id-expression or one of the following 14533 // operators: +, -, *, &, |, ^, && and || 14534 switch (OOK) { 14535 case OO_Plus: 14536 case OO_Minus: 14537 BOK = BO_Add; 14538 break; 14539 case OO_Star: 14540 BOK = BO_Mul; 14541 break; 14542 case OO_Amp: 14543 BOK = BO_And; 14544 break; 14545 case OO_Pipe: 14546 BOK = BO_Or; 14547 break; 14548 case OO_Caret: 14549 BOK = BO_Xor; 14550 break; 14551 case OO_AmpAmp: 14552 BOK = BO_LAnd; 14553 break; 14554 case OO_PipePipe: 14555 BOK = BO_LOr; 14556 break; 14557 case OO_New: 14558 case OO_Delete: 14559 case OO_Array_New: 14560 case OO_Array_Delete: 14561 case OO_Slash: 14562 case OO_Percent: 14563 case OO_Tilde: 14564 case OO_Exclaim: 14565 case OO_Equal: 14566 case OO_Less: 14567 case OO_Greater: 14568 case OO_LessEqual: 14569 case OO_GreaterEqual: 14570 case OO_PlusEqual: 14571 case OO_MinusEqual: 14572 case OO_StarEqual: 14573 case OO_SlashEqual: 14574 case OO_PercentEqual: 14575 case OO_CaretEqual: 14576 case OO_AmpEqual: 14577 case OO_PipeEqual: 14578 case OO_LessLess: 14579 case OO_GreaterGreater: 14580 case OO_LessLessEqual: 14581 case OO_GreaterGreaterEqual: 14582 case OO_EqualEqual: 14583 case OO_ExclaimEqual: 14584 case OO_Spaceship: 14585 case OO_PlusPlus: 14586 case OO_MinusMinus: 14587 case OO_Comma: 14588 case OO_ArrowStar: 14589 case OO_Arrow: 14590 case OO_Call: 14591 case OO_Subscript: 14592 case OO_Conditional: 14593 case OO_Coawait: 14594 case NUM_OVERLOADED_OPERATORS: 14595 llvm_unreachable("Unexpected reduction identifier"); 14596 case OO_None: 14597 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 14598 if (II->isStr("max")) 14599 BOK = BO_GT; 14600 else if (II->isStr("min")) 14601 BOK = BO_LT; 14602 } 14603 break; 14604 } 14605 SourceRange ReductionIdRange; 14606 if (ReductionIdScopeSpec.isValid()) 14607 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 14608 else 14609 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 14610 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 14611 14612 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 14613 bool FirstIter = true; 14614 for (Expr *RefExpr : VarList) { 14615 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 14616 // OpenMP [2.1, C/C++] 14617 // A list item is a variable or array section, subject to the restrictions 14618 // specified in Section 2.4 on page 42 and in each of the sections 14619 // describing clauses and directives for which a list appears. 14620 // OpenMP [2.14.3.3, Restrictions, p.1] 14621 // A variable that is part of another variable (as an array or 14622 // structure element) cannot appear in a private clause. 14623 if (!FirstIter && IR != ER) 14624 ++IR; 14625 FirstIter = false; 14626 SourceLocation ELoc; 14627 SourceRange ERange; 14628 Expr *SimpleRefExpr = RefExpr; 14629 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 14630 /*AllowArraySection=*/true); 14631 if (Res.second) { 14632 // Try to find 'declare reduction' corresponding construct before using 14633 // builtin/overloaded operators. 14634 QualType Type = Context.DependentTy; 14635 CXXCastPath BasePath; 14636 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14637 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14638 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14639 Expr *ReductionOp = nullptr; 14640 if (S.CurContext->isDependentContext() && 14641 (DeclareReductionRef.isUnset() || 14642 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 14643 ReductionOp = DeclareReductionRef.get(); 14644 // It will be analyzed later. 14645 RD.push(RefExpr, ReductionOp); 14646 } 14647 ValueDecl *D = Res.first; 14648 if (!D) 14649 continue; 14650 14651 Expr *TaskgroupDescriptor = nullptr; 14652 QualType Type; 14653 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 14654 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 14655 if (ASE) { 14656 Type = ASE->getType().getNonReferenceType(); 14657 } else if (OASE) { 14658 QualType BaseType = 14659 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 14660 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 14661 Type = ATy->getElementType(); 14662 else 14663 Type = BaseType->getPointeeType(); 14664 Type = Type.getNonReferenceType(); 14665 } else { 14666 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 14667 } 14668 auto *VD = dyn_cast<VarDecl>(D); 14669 14670 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 14671 // A variable that appears in a private clause must not have an incomplete 14672 // type or a reference type. 14673 if (S.RequireCompleteType(ELoc, D->getType(), 14674 diag::err_omp_reduction_incomplete_type)) 14675 continue; 14676 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14677 // A list item that appears in a reduction clause must not be 14678 // const-qualified. 14679 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 14680 /*AcceptIfMutable*/ false, ASE || OASE)) 14681 continue; 14682 14683 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 14684 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 14685 // If a list-item is a reference type then it must bind to the same object 14686 // for all threads of the team. 14687 if (!ASE && !OASE) { 14688 if (VD) { 14689 VarDecl *VDDef = VD->getDefinition(); 14690 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 14691 DSARefChecker Check(Stack); 14692 if (Check.Visit(VDDef->getInit())) { 14693 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 14694 << getOpenMPClauseName(ClauseKind) << ERange; 14695 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 14696 continue; 14697 } 14698 } 14699 } 14700 14701 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14702 // in a Construct] 14703 // Variables with the predetermined data-sharing attributes may not be 14704 // listed in data-sharing attributes clauses, except for the cases 14705 // listed below. For these exceptions only, listing a predetermined 14706 // variable in a data-sharing attribute clause is allowed and overrides 14707 // the variable's predetermined data-sharing attributes. 14708 // OpenMP [2.14.3.6, Restrictions, p.3] 14709 // Any number of reduction clauses can be specified on the directive, 14710 // but a list item can appear only once in the reduction clauses for that 14711 // directive. 14712 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 14713 if (DVar.CKind == OMPC_reduction) { 14714 S.Diag(ELoc, diag::err_omp_once_referenced) 14715 << getOpenMPClauseName(ClauseKind); 14716 if (DVar.RefExpr) 14717 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 14718 continue; 14719 } 14720 if (DVar.CKind != OMPC_unknown) { 14721 S.Diag(ELoc, diag::err_omp_wrong_dsa) 14722 << getOpenMPClauseName(DVar.CKind) 14723 << getOpenMPClauseName(OMPC_reduction); 14724 reportOriginalDsa(S, Stack, D, DVar); 14725 continue; 14726 } 14727 14728 // OpenMP [2.14.3.6, Restrictions, p.1] 14729 // A list item that appears in a reduction clause of a worksharing 14730 // construct must be shared in the parallel regions to which any of the 14731 // worksharing regions arising from the worksharing construct bind. 14732 if (isOpenMPWorksharingDirective(CurrDir) && 14733 !isOpenMPParallelDirective(CurrDir) && 14734 !isOpenMPTeamsDirective(CurrDir)) { 14735 DVar = Stack->getImplicitDSA(D, true); 14736 if (DVar.CKind != OMPC_shared) { 14737 S.Diag(ELoc, diag::err_omp_required_access) 14738 << getOpenMPClauseName(OMPC_reduction) 14739 << getOpenMPClauseName(OMPC_shared); 14740 reportOriginalDsa(S, Stack, D, DVar); 14741 continue; 14742 } 14743 } 14744 } 14745 14746 // Try to find 'declare reduction' corresponding construct before using 14747 // builtin/overloaded operators. 14748 CXXCastPath BasePath; 14749 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14750 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14751 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14752 if (DeclareReductionRef.isInvalid()) 14753 continue; 14754 if (S.CurContext->isDependentContext() && 14755 (DeclareReductionRef.isUnset() || 14756 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 14757 RD.push(RefExpr, DeclareReductionRef.get()); 14758 continue; 14759 } 14760 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 14761 // Not allowed reduction identifier is found. 14762 S.Diag(ReductionId.getBeginLoc(), 14763 diag::err_omp_unknown_reduction_identifier) 14764 << Type << ReductionIdRange; 14765 continue; 14766 } 14767 14768 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14769 // The type of a list item that appears in a reduction clause must be valid 14770 // for the reduction-identifier. For a max or min reduction in C, the type 14771 // of the list item must be an allowed arithmetic data type: char, int, 14772 // float, double, or _Bool, possibly modified with long, short, signed, or 14773 // unsigned. For a max or min reduction in C++, the type of the list item 14774 // must be an allowed arithmetic data type: char, wchar_t, int, float, 14775 // double, or bool, possibly modified with long, short, signed, or unsigned. 14776 if (DeclareReductionRef.isUnset()) { 14777 if ((BOK == BO_GT || BOK == BO_LT) && 14778 !(Type->isScalarType() || 14779 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 14780 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 14781 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 14782 if (!ASE && !OASE) { 14783 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14784 VarDecl::DeclarationOnly; 14785 S.Diag(D->getLocation(), 14786 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14787 << D; 14788 } 14789 continue; 14790 } 14791 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 14792 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 14793 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 14794 << getOpenMPClauseName(ClauseKind); 14795 if (!ASE && !OASE) { 14796 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14797 VarDecl::DeclarationOnly; 14798 S.Diag(D->getLocation(), 14799 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14800 << D; 14801 } 14802 continue; 14803 } 14804 } 14805 14806 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 14807 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 14808 D->hasAttrs() ? &D->getAttrs() : nullptr); 14809 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 14810 D->hasAttrs() ? &D->getAttrs() : nullptr); 14811 QualType PrivateTy = Type; 14812 14813 // Try if we can determine constant lengths for all array sections and avoid 14814 // the VLA. 14815 bool ConstantLengthOASE = false; 14816 if (OASE) { 14817 bool SingleElement; 14818 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 14819 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 14820 Context, OASE, SingleElement, ArraySizes); 14821 14822 // If we don't have a single element, we must emit a constant array type. 14823 if (ConstantLengthOASE && !SingleElement) { 14824 for (llvm::APSInt &Size : ArraySizes) 14825 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 14826 ArrayType::Normal, 14827 /*IndexTypeQuals=*/0); 14828 } 14829 } 14830 14831 if ((OASE && !ConstantLengthOASE) || 14832 (!OASE && !ASE && 14833 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 14834 if (!Context.getTargetInfo().isVLASupported()) { 14835 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 14836 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14837 S.Diag(ELoc, diag::note_vla_unsupported); 14838 } else { 14839 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14840 S.targetDiag(ELoc, diag::note_vla_unsupported); 14841 } 14842 continue; 14843 } 14844 // For arrays/array sections only: 14845 // Create pseudo array type for private copy. The size for this array will 14846 // be generated during codegen. 14847 // For array subscripts or single variables Private Ty is the same as Type 14848 // (type of the variable or single array element). 14849 PrivateTy = Context.getVariableArrayType( 14850 Type, 14851 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 14852 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 14853 } else if (!ASE && !OASE && 14854 Context.getAsArrayType(D->getType().getNonReferenceType())) { 14855 PrivateTy = D->getType().getNonReferenceType(); 14856 } 14857 // Private copy. 14858 VarDecl *PrivateVD = 14859 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 14860 D->hasAttrs() ? &D->getAttrs() : nullptr, 14861 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14862 // Add initializer for private variable. 14863 Expr *Init = nullptr; 14864 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 14865 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 14866 if (DeclareReductionRef.isUsable()) { 14867 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 14868 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 14869 if (DRD->getInitializer()) { 14870 Init = DRDRef; 14871 RHSVD->setInit(DRDRef); 14872 RHSVD->setInitStyle(VarDecl::CallInit); 14873 } 14874 } else { 14875 switch (BOK) { 14876 case BO_Add: 14877 case BO_Xor: 14878 case BO_Or: 14879 case BO_LOr: 14880 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 14881 if (Type->isScalarType() || Type->isAnyComplexType()) 14882 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 14883 break; 14884 case BO_Mul: 14885 case BO_LAnd: 14886 if (Type->isScalarType() || Type->isAnyComplexType()) { 14887 // '*' and '&&' reduction ops - initializer is '1'. 14888 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 14889 } 14890 break; 14891 case BO_And: { 14892 // '&' reduction op - initializer is '~0'. 14893 QualType OrigType = Type; 14894 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 14895 Type = ComplexTy->getElementType(); 14896 if (Type->isRealFloatingType()) { 14897 llvm::APFloat InitValue = 14898 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 14899 /*isIEEE=*/true); 14900 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14901 Type, ELoc); 14902 } else if (Type->isScalarType()) { 14903 uint64_t Size = Context.getTypeSize(Type); 14904 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 14905 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 14906 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14907 } 14908 if (Init && OrigType->isAnyComplexType()) { 14909 // Init = 0xFFFF + 0xFFFFi; 14910 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 14911 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 14912 } 14913 Type = OrigType; 14914 break; 14915 } 14916 case BO_LT: 14917 case BO_GT: { 14918 // 'min' reduction op - initializer is 'Largest representable number in 14919 // the reduction list item type'. 14920 // 'max' reduction op - initializer is 'Least representable number in 14921 // the reduction list item type'. 14922 if (Type->isIntegerType() || Type->isPointerType()) { 14923 bool IsSigned = Type->hasSignedIntegerRepresentation(); 14924 uint64_t Size = Context.getTypeSize(Type); 14925 QualType IntTy = 14926 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 14927 llvm::APInt InitValue = 14928 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 14929 : llvm::APInt::getMinValue(Size) 14930 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 14931 : llvm::APInt::getMaxValue(Size); 14932 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14933 if (Type->isPointerType()) { 14934 // Cast to pointer type. 14935 ExprResult CastExpr = S.BuildCStyleCastExpr( 14936 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 14937 if (CastExpr.isInvalid()) 14938 continue; 14939 Init = CastExpr.get(); 14940 } 14941 } else if (Type->isRealFloatingType()) { 14942 llvm::APFloat InitValue = llvm::APFloat::getLargest( 14943 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 14944 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14945 Type, ELoc); 14946 } 14947 break; 14948 } 14949 case BO_PtrMemD: 14950 case BO_PtrMemI: 14951 case BO_MulAssign: 14952 case BO_Div: 14953 case BO_Rem: 14954 case BO_Sub: 14955 case BO_Shl: 14956 case BO_Shr: 14957 case BO_LE: 14958 case BO_GE: 14959 case BO_EQ: 14960 case BO_NE: 14961 case BO_Cmp: 14962 case BO_AndAssign: 14963 case BO_XorAssign: 14964 case BO_OrAssign: 14965 case BO_Assign: 14966 case BO_AddAssign: 14967 case BO_SubAssign: 14968 case BO_DivAssign: 14969 case BO_RemAssign: 14970 case BO_ShlAssign: 14971 case BO_ShrAssign: 14972 case BO_Comma: 14973 llvm_unreachable("Unexpected reduction operation"); 14974 } 14975 } 14976 if (Init && DeclareReductionRef.isUnset()) 14977 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 14978 else if (!Init) 14979 S.ActOnUninitializedDecl(RHSVD); 14980 if (RHSVD->isInvalidDecl()) 14981 continue; 14982 if (!RHSVD->hasInit() && 14983 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 14984 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 14985 << Type << ReductionIdRange; 14986 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14987 VarDecl::DeclarationOnly; 14988 S.Diag(D->getLocation(), 14989 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14990 << D; 14991 continue; 14992 } 14993 // Store initializer for single element in private copy. Will be used during 14994 // codegen. 14995 PrivateVD->setInit(RHSVD->getInit()); 14996 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 14997 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 14998 ExprResult ReductionOp; 14999 if (DeclareReductionRef.isUsable()) { 15000 QualType RedTy = DeclareReductionRef.get()->getType(); 15001 QualType PtrRedTy = Context.getPointerType(RedTy); 15002 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 15003 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 15004 if (!BasePath.empty()) { 15005 LHS = S.DefaultLvalueConversion(LHS.get()); 15006 RHS = S.DefaultLvalueConversion(RHS.get()); 15007 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 15008 CK_UncheckedDerivedToBase, LHS.get(), 15009 &BasePath, LHS.get()->getValueKind()); 15010 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 15011 CK_UncheckedDerivedToBase, RHS.get(), 15012 &BasePath, RHS.get()->getValueKind()); 15013 } 15014 FunctionProtoType::ExtProtoInfo EPI; 15015 QualType Params[] = {PtrRedTy, PtrRedTy}; 15016 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 15017 auto *OVE = new (Context) OpaqueValueExpr( 15018 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 15019 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 15020 Expr *Args[] = {LHS.get(), RHS.get()}; 15021 ReductionOp = 15022 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 15023 } else { 15024 ReductionOp = S.BuildBinOp( 15025 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 15026 if (ReductionOp.isUsable()) { 15027 if (BOK != BO_LT && BOK != BO_GT) { 15028 ReductionOp = 15029 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15030 BO_Assign, LHSDRE, ReductionOp.get()); 15031 } else { 15032 auto *ConditionalOp = new (Context) 15033 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 15034 Type, VK_LValue, OK_Ordinary); 15035 ReductionOp = 15036 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15037 BO_Assign, LHSDRE, ConditionalOp); 15038 } 15039 if (ReductionOp.isUsable()) 15040 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 15041 /*DiscardedValue*/ false); 15042 } 15043 if (!ReductionOp.isUsable()) 15044 continue; 15045 } 15046 15047 // OpenMP [2.15.4.6, Restrictions, p.2] 15048 // A list item that appears in an in_reduction clause of a task construct 15049 // must appear in a task_reduction clause of a construct associated with a 15050 // taskgroup region that includes the participating task in its taskgroup 15051 // set. The construct associated with the innermost region that meets this 15052 // condition must specify the same reduction-identifier as the in_reduction 15053 // clause. 15054 if (ClauseKind == OMPC_in_reduction) { 15055 SourceRange ParentSR; 15056 BinaryOperatorKind ParentBOK; 15057 const Expr *ParentReductionOp = nullptr; 15058 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 15059 DSAStackTy::DSAVarData ParentBOKDSA = 15060 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 15061 ParentBOKTD); 15062 DSAStackTy::DSAVarData ParentReductionOpDSA = 15063 Stack->getTopMostTaskgroupReductionData( 15064 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 15065 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 15066 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 15067 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 15068 (DeclareReductionRef.isUsable() && IsParentBOK) || 15069 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 15070 bool EmitError = true; 15071 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 15072 llvm::FoldingSetNodeID RedId, ParentRedId; 15073 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 15074 DeclareReductionRef.get()->Profile(RedId, Context, 15075 /*Canonical=*/true); 15076 EmitError = RedId != ParentRedId; 15077 } 15078 if (EmitError) { 15079 S.Diag(ReductionId.getBeginLoc(), 15080 diag::err_omp_reduction_identifier_mismatch) 15081 << ReductionIdRange << RefExpr->getSourceRange(); 15082 S.Diag(ParentSR.getBegin(), 15083 diag::note_omp_previous_reduction_identifier) 15084 << ParentSR 15085 << (IsParentBOK ? ParentBOKDSA.RefExpr 15086 : ParentReductionOpDSA.RefExpr) 15087 ->getSourceRange(); 15088 continue; 15089 } 15090 } 15091 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 15092 } 15093 15094 DeclRefExpr *Ref = nullptr; 15095 Expr *VarsExpr = RefExpr->IgnoreParens(); 15096 if (!VD && !S.CurContext->isDependentContext()) { 15097 if (ASE || OASE) { 15098 TransformExprToCaptures RebuildToCapture(S, D); 15099 VarsExpr = 15100 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 15101 Ref = RebuildToCapture.getCapturedExpr(); 15102 } else { 15103 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 15104 } 15105 if (!S.isOpenMPCapturedDecl(D)) { 15106 RD.ExprCaptures.emplace_back(Ref->getDecl()); 15107 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15108 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 15109 if (!RefRes.isUsable()) 15110 continue; 15111 ExprResult PostUpdateRes = 15112 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 15113 RefRes.get()); 15114 if (!PostUpdateRes.isUsable()) 15115 continue; 15116 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 15117 Stack->getCurrentDirective() == OMPD_taskgroup) { 15118 S.Diag(RefExpr->getExprLoc(), 15119 diag::err_omp_reduction_non_addressable_expression) 15120 << RefExpr->getSourceRange(); 15121 continue; 15122 } 15123 RD.ExprPostUpdates.emplace_back( 15124 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 15125 } 15126 } 15127 } 15128 // All reduction items are still marked as reduction (to do not increase 15129 // code base size). 15130 unsigned Modifier = RD.RedModifier; 15131 // Consider task_reductions as reductions with task modifier. Required for 15132 // correct analysis of in_reduction clauses. 15133 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 15134 Modifier = OMPC_REDUCTION_task; 15135 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier); 15136 if (Modifier == OMPC_REDUCTION_task && 15137 (CurrDir == OMPD_taskgroup || 15138 ((isOpenMPParallelDirective(CurrDir) || 15139 isOpenMPWorksharingDirective(CurrDir)) && 15140 !isOpenMPSimdDirective(CurrDir)))) { 15141 if (DeclareReductionRef.isUsable()) 15142 Stack->addTaskgroupReductionData(D, ReductionIdRange, 15143 DeclareReductionRef.get()); 15144 else 15145 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 15146 } 15147 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 15148 TaskgroupDescriptor); 15149 } 15150 return RD.Vars.empty(); 15151 } 15152 15153 OMPClause *Sema::ActOnOpenMPReductionClause( 15154 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 15155 SourceLocation StartLoc, SourceLocation LParenLoc, 15156 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 15157 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15158 ArrayRef<Expr *> UnresolvedReductions) { 15159 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 15160 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 15161 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 15162 /*Last=*/OMPC_REDUCTION_unknown) 15163 << getOpenMPClauseName(OMPC_reduction); 15164 return nullptr; 15165 } 15166 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 15167 // A reduction clause with the inscan reduction-modifier may only appear on a 15168 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 15169 // construct, a parallel worksharing-loop construct or a parallel 15170 // worksharing-loop SIMD construct. 15171 if (Modifier == OMPC_REDUCTION_inscan && 15172 (DSAStack->getCurrentDirective() != OMPD_for && 15173 DSAStack->getCurrentDirective() != OMPD_for_simd && 15174 DSAStack->getCurrentDirective() != OMPD_simd && 15175 DSAStack->getCurrentDirective() != OMPD_parallel_for && 15176 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 15177 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 15178 return nullptr; 15179 } 15180 15181 ReductionData RD(VarList.size(), Modifier); 15182 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 15183 StartLoc, LParenLoc, ColonLoc, EndLoc, 15184 ReductionIdScopeSpec, ReductionId, 15185 UnresolvedReductions, RD)) 15186 return nullptr; 15187 15188 return OMPReductionClause::Create( 15189 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 15190 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15191 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 15192 buildPreInits(Context, RD.ExprCaptures), 15193 buildPostUpdate(*this, RD.ExprPostUpdates)); 15194 } 15195 15196 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 15197 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15198 SourceLocation ColonLoc, SourceLocation EndLoc, 15199 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15200 ArrayRef<Expr *> UnresolvedReductions) { 15201 ReductionData RD(VarList.size()); 15202 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 15203 StartLoc, LParenLoc, ColonLoc, EndLoc, 15204 ReductionIdScopeSpec, ReductionId, 15205 UnresolvedReductions, RD)) 15206 return nullptr; 15207 15208 return OMPTaskReductionClause::Create( 15209 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15210 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15211 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 15212 buildPreInits(Context, RD.ExprCaptures), 15213 buildPostUpdate(*this, RD.ExprPostUpdates)); 15214 } 15215 15216 OMPClause *Sema::ActOnOpenMPInReductionClause( 15217 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15218 SourceLocation ColonLoc, SourceLocation EndLoc, 15219 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15220 ArrayRef<Expr *> UnresolvedReductions) { 15221 ReductionData RD(VarList.size()); 15222 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 15223 StartLoc, LParenLoc, ColonLoc, EndLoc, 15224 ReductionIdScopeSpec, ReductionId, 15225 UnresolvedReductions, RD)) 15226 return nullptr; 15227 15228 return OMPInReductionClause::Create( 15229 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15230 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15231 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 15232 buildPreInits(Context, RD.ExprCaptures), 15233 buildPostUpdate(*this, RD.ExprPostUpdates)); 15234 } 15235 15236 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 15237 SourceLocation LinLoc) { 15238 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 15239 LinKind == OMPC_LINEAR_unknown) { 15240 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 15241 return true; 15242 } 15243 return false; 15244 } 15245 15246 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 15247 OpenMPLinearClauseKind LinKind, QualType Type, 15248 bool IsDeclareSimd) { 15249 const auto *VD = dyn_cast_or_null<VarDecl>(D); 15250 // A variable must not have an incomplete type or a reference type. 15251 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 15252 return true; 15253 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 15254 !Type->isReferenceType()) { 15255 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 15256 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 15257 return true; 15258 } 15259 Type = Type.getNonReferenceType(); 15260 15261 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 15262 // A variable that is privatized must not have a const-qualified type 15263 // unless it is of class type with a mutable member. This restriction does 15264 // not apply to the firstprivate clause, nor to the linear clause on 15265 // declarative directives (like declare simd). 15266 if (!IsDeclareSimd && 15267 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 15268 return true; 15269 15270 // A list item must be of integral or pointer type. 15271 Type = Type.getUnqualifiedType().getCanonicalType(); 15272 const auto *Ty = Type.getTypePtrOrNull(); 15273 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 15274 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 15275 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 15276 if (D) { 15277 bool IsDecl = 15278 !VD || 15279 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15280 Diag(D->getLocation(), 15281 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15282 << D; 15283 } 15284 return true; 15285 } 15286 return false; 15287 } 15288 15289 OMPClause *Sema::ActOnOpenMPLinearClause( 15290 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 15291 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 15292 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15293 SmallVector<Expr *, 8> Vars; 15294 SmallVector<Expr *, 8> Privates; 15295 SmallVector<Expr *, 8> Inits; 15296 SmallVector<Decl *, 4> ExprCaptures; 15297 SmallVector<Expr *, 4> ExprPostUpdates; 15298 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 15299 LinKind = OMPC_LINEAR_val; 15300 for (Expr *RefExpr : VarList) { 15301 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15302 SourceLocation ELoc; 15303 SourceRange ERange; 15304 Expr *SimpleRefExpr = RefExpr; 15305 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15306 if (Res.second) { 15307 // It will be analyzed later. 15308 Vars.push_back(RefExpr); 15309 Privates.push_back(nullptr); 15310 Inits.push_back(nullptr); 15311 } 15312 ValueDecl *D = Res.first; 15313 if (!D) 15314 continue; 15315 15316 QualType Type = D->getType(); 15317 auto *VD = dyn_cast<VarDecl>(D); 15318 15319 // OpenMP [2.14.3.7, linear clause] 15320 // A list-item cannot appear in more than one linear clause. 15321 // A list-item that appears in a linear clause cannot appear in any 15322 // other data-sharing attribute clause. 15323 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15324 if (DVar.RefExpr) { 15325 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 15326 << getOpenMPClauseName(OMPC_linear); 15327 reportOriginalDsa(*this, DSAStack, D, DVar); 15328 continue; 15329 } 15330 15331 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 15332 continue; 15333 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15334 15335 // Build private copy of original var. 15336 VarDecl *Private = 15337 buildVarDecl(*this, ELoc, Type, D->getName(), 15338 D->hasAttrs() ? &D->getAttrs() : nullptr, 15339 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15340 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 15341 // Build var to save initial value. 15342 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 15343 Expr *InitExpr; 15344 DeclRefExpr *Ref = nullptr; 15345 if (!VD && !CurContext->isDependentContext()) { 15346 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15347 if (!isOpenMPCapturedDecl(D)) { 15348 ExprCaptures.push_back(Ref->getDecl()); 15349 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15350 ExprResult RefRes = DefaultLvalueConversion(Ref); 15351 if (!RefRes.isUsable()) 15352 continue; 15353 ExprResult PostUpdateRes = 15354 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 15355 SimpleRefExpr, RefRes.get()); 15356 if (!PostUpdateRes.isUsable()) 15357 continue; 15358 ExprPostUpdates.push_back( 15359 IgnoredValueConversions(PostUpdateRes.get()).get()); 15360 } 15361 } 15362 } 15363 if (LinKind == OMPC_LINEAR_uval) 15364 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 15365 else 15366 InitExpr = VD ? SimpleRefExpr : Ref; 15367 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 15368 /*DirectInit=*/false); 15369 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 15370 15371 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 15372 Vars.push_back((VD || CurContext->isDependentContext()) 15373 ? RefExpr->IgnoreParens() 15374 : Ref); 15375 Privates.push_back(PrivateRef); 15376 Inits.push_back(InitRef); 15377 } 15378 15379 if (Vars.empty()) 15380 return nullptr; 15381 15382 Expr *StepExpr = Step; 15383 Expr *CalcStepExpr = nullptr; 15384 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 15385 !Step->isInstantiationDependent() && 15386 !Step->containsUnexpandedParameterPack()) { 15387 SourceLocation StepLoc = Step->getBeginLoc(); 15388 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 15389 if (Val.isInvalid()) 15390 return nullptr; 15391 StepExpr = Val.get(); 15392 15393 // Build var to save the step value. 15394 VarDecl *SaveVar = 15395 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 15396 ExprResult SaveRef = 15397 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 15398 ExprResult CalcStep = 15399 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 15400 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 15401 15402 // Warn about zero linear step (it would be probably better specified as 15403 // making corresponding variables 'const'). 15404 llvm::APSInt Result; 15405 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 15406 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 15407 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 15408 << (Vars.size() > 1); 15409 if (!IsConstant && CalcStep.isUsable()) { 15410 // Calculate the step beforehand instead of doing this on each iteration. 15411 // (This is not used if the number of iterations may be kfold-ed). 15412 CalcStepExpr = CalcStep.get(); 15413 } 15414 } 15415 15416 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 15417 ColonLoc, EndLoc, Vars, Privates, Inits, 15418 StepExpr, CalcStepExpr, 15419 buildPreInits(Context, ExprCaptures), 15420 buildPostUpdate(*this, ExprPostUpdates)); 15421 } 15422 15423 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 15424 Expr *NumIterations, Sema &SemaRef, 15425 Scope *S, DSAStackTy *Stack) { 15426 // Walk the vars and build update/final expressions for the CodeGen. 15427 SmallVector<Expr *, 8> Updates; 15428 SmallVector<Expr *, 8> Finals; 15429 SmallVector<Expr *, 8> UsedExprs; 15430 Expr *Step = Clause.getStep(); 15431 Expr *CalcStep = Clause.getCalcStep(); 15432 // OpenMP [2.14.3.7, linear clause] 15433 // If linear-step is not specified it is assumed to be 1. 15434 if (!Step) 15435 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 15436 else if (CalcStep) 15437 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 15438 bool HasErrors = false; 15439 auto CurInit = Clause.inits().begin(); 15440 auto CurPrivate = Clause.privates().begin(); 15441 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 15442 for (Expr *RefExpr : Clause.varlists()) { 15443 SourceLocation ELoc; 15444 SourceRange ERange; 15445 Expr *SimpleRefExpr = RefExpr; 15446 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 15447 ValueDecl *D = Res.first; 15448 if (Res.second || !D) { 15449 Updates.push_back(nullptr); 15450 Finals.push_back(nullptr); 15451 HasErrors = true; 15452 continue; 15453 } 15454 auto &&Info = Stack->isLoopControlVariable(D); 15455 // OpenMP [2.15.11, distribute simd Construct] 15456 // A list item may not appear in a linear clause, unless it is the loop 15457 // iteration variable. 15458 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 15459 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 15460 SemaRef.Diag(ELoc, 15461 diag::err_omp_linear_distribute_var_non_loop_iteration); 15462 Updates.push_back(nullptr); 15463 Finals.push_back(nullptr); 15464 HasErrors = true; 15465 continue; 15466 } 15467 Expr *InitExpr = *CurInit; 15468 15469 // Build privatized reference to the current linear var. 15470 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 15471 Expr *CapturedRef; 15472 if (LinKind == OMPC_LINEAR_uval) 15473 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 15474 else 15475 CapturedRef = 15476 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 15477 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 15478 /*RefersToCapture=*/true); 15479 15480 // Build update: Var = InitExpr + IV * Step 15481 ExprResult Update; 15482 if (!Info.first) 15483 Update = buildCounterUpdate( 15484 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 15485 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 15486 else 15487 Update = *CurPrivate; 15488 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 15489 /*DiscardedValue*/ false); 15490 15491 // Build final: Var = InitExpr + NumIterations * Step 15492 ExprResult Final; 15493 if (!Info.first) 15494 Final = 15495 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 15496 InitExpr, NumIterations, Step, /*Subtract=*/false, 15497 /*IsNonRectangularLB=*/false); 15498 else 15499 Final = *CurPrivate; 15500 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 15501 /*DiscardedValue*/ false); 15502 15503 if (!Update.isUsable() || !Final.isUsable()) { 15504 Updates.push_back(nullptr); 15505 Finals.push_back(nullptr); 15506 UsedExprs.push_back(nullptr); 15507 HasErrors = true; 15508 } else { 15509 Updates.push_back(Update.get()); 15510 Finals.push_back(Final.get()); 15511 if (!Info.first) 15512 UsedExprs.push_back(SimpleRefExpr); 15513 } 15514 ++CurInit; 15515 ++CurPrivate; 15516 } 15517 if (Expr *S = Clause.getStep()) 15518 UsedExprs.push_back(S); 15519 // Fill the remaining part with the nullptr. 15520 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 15521 Clause.setUpdates(Updates); 15522 Clause.setFinals(Finals); 15523 Clause.setUsedExprs(UsedExprs); 15524 return HasErrors; 15525 } 15526 15527 OMPClause *Sema::ActOnOpenMPAlignedClause( 15528 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 15529 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15530 SmallVector<Expr *, 8> Vars; 15531 for (Expr *RefExpr : VarList) { 15532 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15533 SourceLocation ELoc; 15534 SourceRange ERange; 15535 Expr *SimpleRefExpr = RefExpr; 15536 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15537 if (Res.second) { 15538 // It will be analyzed later. 15539 Vars.push_back(RefExpr); 15540 } 15541 ValueDecl *D = Res.first; 15542 if (!D) 15543 continue; 15544 15545 QualType QType = D->getType(); 15546 auto *VD = dyn_cast<VarDecl>(D); 15547 15548 // OpenMP [2.8.1, simd construct, Restrictions] 15549 // The type of list items appearing in the aligned clause must be 15550 // array, pointer, reference to array, or reference to pointer. 15551 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15552 const Type *Ty = QType.getTypePtrOrNull(); 15553 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 15554 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 15555 << QType << getLangOpts().CPlusPlus << ERange; 15556 bool IsDecl = 15557 !VD || 15558 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15559 Diag(D->getLocation(), 15560 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15561 << D; 15562 continue; 15563 } 15564 15565 // OpenMP [2.8.1, simd construct, Restrictions] 15566 // A list-item cannot appear in more than one aligned clause. 15567 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 15568 Diag(ELoc, diag::err_omp_used_in_clause_twice) 15569 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 15570 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 15571 << getOpenMPClauseName(OMPC_aligned); 15572 continue; 15573 } 15574 15575 DeclRefExpr *Ref = nullptr; 15576 if (!VD && isOpenMPCapturedDecl(D)) 15577 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15578 Vars.push_back(DefaultFunctionArrayConversion( 15579 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 15580 .get()); 15581 } 15582 15583 // OpenMP [2.8.1, simd construct, Description] 15584 // The parameter of the aligned clause, alignment, must be a constant 15585 // positive integer expression. 15586 // If no optional parameter is specified, implementation-defined default 15587 // alignments for SIMD instructions on the target platforms are assumed. 15588 if (Alignment != nullptr) { 15589 ExprResult AlignResult = 15590 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 15591 if (AlignResult.isInvalid()) 15592 return nullptr; 15593 Alignment = AlignResult.get(); 15594 } 15595 if (Vars.empty()) 15596 return nullptr; 15597 15598 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 15599 EndLoc, Vars, Alignment); 15600 } 15601 15602 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 15603 SourceLocation StartLoc, 15604 SourceLocation LParenLoc, 15605 SourceLocation EndLoc) { 15606 SmallVector<Expr *, 8> Vars; 15607 SmallVector<Expr *, 8> SrcExprs; 15608 SmallVector<Expr *, 8> DstExprs; 15609 SmallVector<Expr *, 8> AssignmentOps; 15610 for (Expr *RefExpr : VarList) { 15611 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 15612 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15613 // It will be analyzed later. 15614 Vars.push_back(RefExpr); 15615 SrcExprs.push_back(nullptr); 15616 DstExprs.push_back(nullptr); 15617 AssignmentOps.push_back(nullptr); 15618 continue; 15619 } 15620 15621 SourceLocation ELoc = RefExpr->getExprLoc(); 15622 // OpenMP [2.1, C/C++] 15623 // A list item is a variable name. 15624 // OpenMP [2.14.4.1, Restrictions, p.1] 15625 // A list item that appears in a copyin clause must be threadprivate. 15626 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 15627 if (!DE || !isa<VarDecl>(DE->getDecl())) { 15628 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 15629 << 0 << RefExpr->getSourceRange(); 15630 continue; 15631 } 15632 15633 Decl *D = DE->getDecl(); 15634 auto *VD = cast<VarDecl>(D); 15635 15636 QualType Type = VD->getType(); 15637 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 15638 // It will be analyzed later. 15639 Vars.push_back(DE); 15640 SrcExprs.push_back(nullptr); 15641 DstExprs.push_back(nullptr); 15642 AssignmentOps.push_back(nullptr); 15643 continue; 15644 } 15645 15646 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 15647 // A list item that appears in a copyin clause must be threadprivate. 15648 if (!DSAStack->isThreadPrivate(VD)) { 15649 Diag(ELoc, diag::err_omp_required_access) 15650 << getOpenMPClauseName(OMPC_copyin) 15651 << getOpenMPDirectiveName(OMPD_threadprivate); 15652 continue; 15653 } 15654 15655 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15656 // A variable of class type (or array thereof) that appears in a 15657 // copyin clause requires an accessible, unambiguous copy assignment 15658 // operator for the class type. 15659 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 15660 VarDecl *SrcVD = 15661 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 15662 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15663 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 15664 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 15665 VarDecl *DstVD = 15666 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 15667 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15668 DeclRefExpr *PseudoDstExpr = 15669 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 15670 // For arrays generate assignment operation for single element and replace 15671 // it by the original array element in CodeGen. 15672 ExprResult AssignmentOp = 15673 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 15674 PseudoSrcExpr); 15675 if (AssignmentOp.isInvalid()) 15676 continue; 15677 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 15678 /*DiscardedValue*/ false); 15679 if (AssignmentOp.isInvalid()) 15680 continue; 15681 15682 DSAStack->addDSA(VD, DE, OMPC_copyin); 15683 Vars.push_back(DE); 15684 SrcExprs.push_back(PseudoSrcExpr); 15685 DstExprs.push_back(PseudoDstExpr); 15686 AssignmentOps.push_back(AssignmentOp.get()); 15687 } 15688 15689 if (Vars.empty()) 15690 return nullptr; 15691 15692 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 15693 SrcExprs, DstExprs, AssignmentOps); 15694 } 15695 15696 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 15697 SourceLocation StartLoc, 15698 SourceLocation LParenLoc, 15699 SourceLocation EndLoc) { 15700 SmallVector<Expr *, 8> Vars; 15701 SmallVector<Expr *, 8> SrcExprs; 15702 SmallVector<Expr *, 8> DstExprs; 15703 SmallVector<Expr *, 8> AssignmentOps; 15704 for (Expr *RefExpr : VarList) { 15705 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15706 SourceLocation ELoc; 15707 SourceRange ERange; 15708 Expr *SimpleRefExpr = RefExpr; 15709 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15710 if (Res.second) { 15711 // It will be analyzed later. 15712 Vars.push_back(RefExpr); 15713 SrcExprs.push_back(nullptr); 15714 DstExprs.push_back(nullptr); 15715 AssignmentOps.push_back(nullptr); 15716 } 15717 ValueDecl *D = Res.first; 15718 if (!D) 15719 continue; 15720 15721 QualType Type = D->getType(); 15722 auto *VD = dyn_cast<VarDecl>(D); 15723 15724 // OpenMP [2.14.4.2, Restrictions, p.2] 15725 // A list item that appears in a copyprivate clause may not appear in a 15726 // private or firstprivate clause on the single construct. 15727 if (!VD || !DSAStack->isThreadPrivate(VD)) { 15728 DSAStackTy::DSAVarData DVar = 15729 DSAStack->getTopDSA(D, /*FromParent=*/false); 15730 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 15731 DVar.RefExpr) { 15732 Diag(ELoc, diag::err_omp_wrong_dsa) 15733 << getOpenMPClauseName(DVar.CKind) 15734 << getOpenMPClauseName(OMPC_copyprivate); 15735 reportOriginalDsa(*this, DSAStack, D, DVar); 15736 continue; 15737 } 15738 15739 // OpenMP [2.11.4.2, Restrictions, p.1] 15740 // All list items that appear in a copyprivate clause must be either 15741 // threadprivate or private in the enclosing context. 15742 if (DVar.CKind == OMPC_unknown) { 15743 DVar = DSAStack->getImplicitDSA(D, false); 15744 if (DVar.CKind == OMPC_shared) { 15745 Diag(ELoc, diag::err_omp_required_access) 15746 << getOpenMPClauseName(OMPC_copyprivate) 15747 << "threadprivate or private in the enclosing context"; 15748 reportOriginalDsa(*this, DSAStack, D, DVar); 15749 continue; 15750 } 15751 } 15752 } 15753 15754 // Variably modified types are not supported. 15755 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 15756 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 15757 << getOpenMPClauseName(OMPC_copyprivate) << Type 15758 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15759 bool IsDecl = 15760 !VD || 15761 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15762 Diag(D->getLocation(), 15763 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15764 << D; 15765 continue; 15766 } 15767 15768 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15769 // A variable of class type (or array thereof) that appears in a 15770 // copyin clause requires an accessible, unambiguous copy assignment 15771 // operator for the class type. 15772 Type = Context.getBaseElementType(Type.getNonReferenceType()) 15773 .getUnqualifiedType(); 15774 VarDecl *SrcVD = 15775 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 15776 D->hasAttrs() ? &D->getAttrs() : nullptr); 15777 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 15778 VarDecl *DstVD = 15779 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 15780 D->hasAttrs() ? &D->getAttrs() : nullptr); 15781 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 15782 ExprResult AssignmentOp = BuildBinOp( 15783 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 15784 if (AssignmentOp.isInvalid()) 15785 continue; 15786 AssignmentOp = 15787 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 15788 if (AssignmentOp.isInvalid()) 15789 continue; 15790 15791 // No need to mark vars as copyprivate, they are already threadprivate or 15792 // implicitly private. 15793 assert(VD || isOpenMPCapturedDecl(D)); 15794 Vars.push_back( 15795 VD ? RefExpr->IgnoreParens() 15796 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 15797 SrcExprs.push_back(PseudoSrcExpr); 15798 DstExprs.push_back(PseudoDstExpr); 15799 AssignmentOps.push_back(AssignmentOp.get()); 15800 } 15801 15802 if (Vars.empty()) 15803 return nullptr; 15804 15805 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15806 Vars, SrcExprs, DstExprs, AssignmentOps); 15807 } 15808 15809 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 15810 SourceLocation StartLoc, 15811 SourceLocation LParenLoc, 15812 SourceLocation EndLoc) { 15813 if (VarList.empty()) 15814 return nullptr; 15815 15816 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 15817 } 15818 15819 /// Tries to find omp_depend_t. type. 15820 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 15821 bool Diagnose = true) { 15822 QualType OMPDependT = Stack->getOMPDependT(); 15823 if (!OMPDependT.isNull()) 15824 return true; 15825 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 15826 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 15827 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 15828 if (Diagnose) 15829 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 15830 return false; 15831 } 15832 Stack->setOMPDependT(PT.get()); 15833 return true; 15834 } 15835 15836 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 15837 SourceLocation LParenLoc, 15838 SourceLocation EndLoc) { 15839 if (!Depobj) 15840 return nullptr; 15841 15842 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 15843 15844 // OpenMP 5.0, 2.17.10.1 depobj Construct 15845 // depobj is an lvalue expression of type omp_depend_t. 15846 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 15847 !Depobj->isInstantiationDependent() && 15848 !Depobj->containsUnexpandedParameterPack() && 15849 (OMPDependTFound && 15850 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 15851 /*CompareUnqualified=*/true))) { 15852 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15853 << 0 << Depobj->getType() << Depobj->getSourceRange(); 15854 } 15855 15856 if (!Depobj->isLValue()) { 15857 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15858 << 1 << Depobj->getSourceRange(); 15859 } 15860 15861 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 15862 } 15863 15864 OMPClause * 15865 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, 15866 SourceLocation DepLoc, SourceLocation ColonLoc, 15867 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15868 SourceLocation LParenLoc, SourceLocation EndLoc) { 15869 if (DSAStack->getCurrentDirective() == OMPD_ordered && 15870 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 15871 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15872 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 15873 return nullptr; 15874 } 15875 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 15876 DSAStack->getCurrentDirective() == OMPD_depobj) && 15877 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 15878 DepKind == OMPC_DEPEND_sink || 15879 ((LangOpts.OpenMP < 50 || 15880 DSAStack->getCurrentDirective() == OMPD_depobj) && 15881 DepKind == OMPC_DEPEND_depobj))) { 15882 SmallVector<unsigned, 3> Except; 15883 Except.push_back(OMPC_DEPEND_source); 15884 Except.push_back(OMPC_DEPEND_sink); 15885 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 15886 Except.push_back(OMPC_DEPEND_depobj); 15887 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 15888 ? "depend modifier(iterator) or " 15889 : ""; 15890 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15891 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 15892 /*Last=*/OMPC_DEPEND_unknown, 15893 Except) 15894 << getOpenMPClauseName(OMPC_depend); 15895 return nullptr; 15896 } 15897 if (DepModifier && 15898 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 15899 Diag(DepModifier->getExprLoc(), 15900 diag::err_omp_depend_sink_source_with_modifier); 15901 return nullptr; 15902 } 15903 if (DepModifier && 15904 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 15905 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 15906 15907 SmallVector<Expr *, 8> Vars; 15908 DSAStackTy::OperatorOffsetTy OpsOffs; 15909 llvm::APSInt DepCounter(/*BitWidth=*/32); 15910 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 15911 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 15912 if (const Expr *OrderedCountExpr = 15913 DSAStack->getParentOrderedRegionParam().first) { 15914 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 15915 TotalDepCount.setIsUnsigned(/*Val=*/true); 15916 } 15917 } 15918 for (Expr *RefExpr : VarList) { 15919 assert(RefExpr && "NULL expr in OpenMP shared clause."); 15920 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15921 // It will be analyzed later. 15922 Vars.push_back(RefExpr); 15923 continue; 15924 } 15925 15926 SourceLocation ELoc = RefExpr->getExprLoc(); 15927 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 15928 if (DepKind == OMPC_DEPEND_sink) { 15929 if (DSAStack->getParentOrderedRegionParam().first && 15930 DepCounter >= TotalDepCount) { 15931 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 15932 continue; 15933 } 15934 ++DepCounter; 15935 // OpenMP [2.13.9, Summary] 15936 // depend(dependence-type : vec), where dependence-type is: 15937 // 'sink' and where vec is the iteration vector, which has the form: 15938 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 15939 // where n is the value specified by the ordered clause in the loop 15940 // directive, xi denotes the loop iteration variable of the i-th nested 15941 // loop associated with the loop directive, and di is a constant 15942 // non-negative integer. 15943 if (CurContext->isDependentContext()) { 15944 // It will be analyzed later. 15945 Vars.push_back(RefExpr); 15946 continue; 15947 } 15948 SimpleExpr = SimpleExpr->IgnoreImplicit(); 15949 OverloadedOperatorKind OOK = OO_None; 15950 SourceLocation OOLoc; 15951 Expr *LHS = SimpleExpr; 15952 Expr *RHS = nullptr; 15953 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 15954 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 15955 OOLoc = BO->getOperatorLoc(); 15956 LHS = BO->getLHS()->IgnoreParenImpCasts(); 15957 RHS = BO->getRHS()->IgnoreParenImpCasts(); 15958 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 15959 OOK = OCE->getOperator(); 15960 OOLoc = OCE->getOperatorLoc(); 15961 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15962 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 15963 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 15964 OOK = MCE->getMethodDecl() 15965 ->getNameInfo() 15966 .getName() 15967 .getCXXOverloadedOperator(); 15968 OOLoc = MCE->getCallee()->getExprLoc(); 15969 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 15970 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15971 } 15972 SourceLocation ELoc; 15973 SourceRange ERange; 15974 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 15975 if (Res.second) { 15976 // It will be analyzed later. 15977 Vars.push_back(RefExpr); 15978 } 15979 ValueDecl *D = Res.first; 15980 if (!D) 15981 continue; 15982 15983 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 15984 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 15985 continue; 15986 } 15987 if (RHS) { 15988 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 15989 RHS, OMPC_depend, /*StrictlyPositive=*/false); 15990 if (RHSRes.isInvalid()) 15991 continue; 15992 } 15993 if (!CurContext->isDependentContext() && 15994 DSAStack->getParentOrderedRegionParam().first && 15995 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 15996 const ValueDecl *VD = 15997 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 15998 if (VD) 15999 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 16000 << 1 << VD; 16001 else 16002 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 16003 continue; 16004 } 16005 OpsOffs.emplace_back(RHS, OOK); 16006 } else { 16007 bool OMPDependTFound = LangOpts.OpenMP >= 50; 16008 if (OMPDependTFound) 16009 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 16010 DepKind == OMPC_DEPEND_depobj); 16011 if (DepKind == OMPC_DEPEND_depobj) { 16012 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16013 // List items used in depend clauses with the depobj dependence type 16014 // must be expressions of the omp_depend_t type. 16015 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16016 !RefExpr->isInstantiationDependent() && 16017 !RefExpr->containsUnexpandedParameterPack() && 16018 (OMPDependTFound && 16019 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 16020 RefExpr->getType()))) { 16021 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16022 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 16023 continue; 16024 } 16025 if (!RefExpr->isLValue()) { 16026 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16027 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 16028 continue; 16029 } 16030 } else { 16031 // OpenMP 5.0 [2.17.11, Restrictions] 16032 // List items used in depend clauses cannot be zero-length array 16033 // sections. 16034 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 16035 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 16036 if (OASE) { 16037 QualType BaseType = 16038 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16039 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16040 ExprTy = ATy->getElementType(); 16041 else 16042 ExprTy = BaseType->getPointeeType(); 16043 ExprTy = ExprTy.getNonReferenceType(); 16044 const Expr *Length = OASE->getLength(); 16045 Expr::EvalResult Result; 16046 if (Length && !Length->isValueDependent() && 16047 Length->EvaluateAsInt(Result, Context) && 16048 Result.Val.getInt().isNullValue()) { 16049 Diag(ELoc, 16050 diag::err_omp_depend_zero_length_array_section_not_allowed) 16051 << SimpleExpr->getSourceRange(); 16052 continue; 16053 } 16054 } 16055 16056 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16057 // List items used in depend clauses with the in, out, inout or 16058 // mutexinoutset dependence types cannot be expressions of the 16059 // omp_depend_t type. 16060 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16061 !RefExpr->isInstantiationDependent() && 16062 !RefExpr->containsUnexpandedParameterPack() && 16063 (OMPDependTFound && 16064 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { 16065 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16066 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 16067 << RefExpr->getSourceRange(); 16068 continue; 16069 } 16070 16071 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 16072 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 16073 (ASE && 16074 !ASE->getBase() 16075 ->getType() 16076 .getNonReferenceType() 16077 ->isPointerType() && 16078 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 16079 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16080 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16081 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16082 continue; 16083 } 16084 16085 ExprResult Res; 16086 { 16087 Sema::TentativeAnalysisScope Trap(*this); 16088 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 16089 RefExpr->IgnoreParenImpCasts()); 16090 } 16091 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 16092 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 16093 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16094 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16095 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16096 continue; 16097 } 16098 } 16099 } 16100 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 16101 } 16102 16103 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 16104 TotalDepCount > VarList.size() && 16105 DSAStack->getParentOrderedRegionParam().first && 16106 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 16107 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 16108 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 16109 } 16110 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 16111 Vars.empty()) 16112 return nullptr; 16113 16114 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16115 DepModifier, DepKind, DepLoc, ColonLoc, 16116 Vars, TotalDepCount.getZExtValue()); 16117 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 16118 DSAStack->isParentOrderedRegion()) 16119 DSAStack->addDoacrossDependClause(C, OpsOffs); 16120 return C; 16121 } 16122 16123 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 16124 Expr *Device, SourceLocation StartLoc, 16125 SourceLocation LParenLoc, 16126 SourceLocation ModifierLoc, 16127 SourceLocation EndLoc) { 16128 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 16129 "Unexpected device modifier in OpenMP < 50."); 16130 16131 bool ErrorFound = false; 16132 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 16133 std::string Values = 16134 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 16135 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 16136 << Values << getOpenMPClauseName(OMPC_device); 16137 ErrorFound = true; 16138 } 16139 16140 Expr *ValExpr = Device; 16141 Stmt *HelperValStmt = nullptr; 16142 16143 // OpenMP [2.9.1, Restrictions] 16144 // The device expression must evaluate to a non-negative integer value. 16145 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 16146 /*StrictlyPositive=*/false) || 16147 ErrorFound; 16148 if (ErrorFound) 16149 return nullptr; 16150 16151 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16152 OpenMPDirectiveKind CaptureRegion = 16153 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 16154 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16155 ValExpr = MakeFullExpr(ValExpr).get(); 16156 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16157 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16158 HelperValStmt = buildPreInits(Context, Captures); 16159 } 16160 16161 return new (Context) 16162 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 16163 LParenLoc, ModifierLoc, EndLoc); 16164 } 16165 16166 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 16167 DSAStackTy *Stack, QualType QTy, 16168 bool FullCheck = true) { 16169 NamedDecl *ND; 16170 if (QTy->isIncompleteType(&ND)) { 16171 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 16172 return false; 16173 } 16174 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 16175 !QTy.isTriviallyCopyableType(SemaRef.Context)) 16176 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 16177 return true; 16178 } 16179 16180 /// Return true if it can be proven that the provided array expression 16181 /// (array section or array subscript) does NOT specify the whole size of the 16182 /// array whose base type is \a BaseQTy. 16183 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 16184 const Expr *E, 16185 QualType BaseQTy) { 16186 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16187 16188 // If this is an array subscript, it refers to the whole size if the size of 16189 // the dimension is constant and equals 1. Also, an array section assumes the 16190 // format of an array subscript if no colon is used. 16191 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 16192 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16193 return ATy->getSize().getSExtValue() != 1; 16194 // Size can't be evaluated statically. 16195 return false; 16196 } 16197 16198 assert(OASE && "Expecting array section if not an array subscript."); 16199 const Expr *LowerBound = OASE->getLowerBound(); 16200 const Expr *Length = OASE->getLength(); 16201 16202 // If there is a lower bound that does not evaluates to zero, we are not 16203 // covering the whole dimension. 16204 if (LowerBound) { 16205 Expr::EvalResult Result; 16206 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 16207 return false; // Can't get the integer value as a constant. 16208 16209 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 16210 if (ConstLowerBound.getSExtValue()) 16211 return true; 16212 } 16213 16214 // If we don't have a length we covering the whole dimension. 16215 if (!Length) 16216 return false; 16217 16218 // If the base is a pointer, we don't have a way to get the size of the 16219 // pointee. 16220 if (BaseQTy->isPointerType()) 16221 return false; 16222 16223 // We can only check if the length is the same as the size of the dimension 16224 // if we have a constant array. 16225 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 16226 if (!CATy) 16227 return false; 16228 16229 Expr::EvalResult Result; 16230 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16231 return false; // Can't get the integer value as a constant. 16232 16233 llvm::APSInt ConstLength = Result.Val.getInt(); 16234 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 16235 } 16236 16237 // Return true if it can be proven that the provided array expression (array 16238 // section or array subscript) does NOT specify a single element of the array 16239 // whose base type is \a BaseQTy. 16240 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 16241 const Expr *E, 16242 QualType BaseQTy) { 16243 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16244 16245 // An array subscript always refer to a single element. Also, an array section 16246 // assumes the format of an array subscript if no colon is used. 16247 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 16248 return false; 16249 16250 assert(OASE && "Expecting array section if not an array subscript."); 16251 const Expr *Length = OASE->getLength(); 16252 16253 // If we don't have a length we have to check if the array has unitary size 16254 // for this dimension. Also, we should always expect a length if the base type 16255 // is pointer. 16256 if (!Length) { 16257 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16258 return ATy->getSize().getSExtValue() != 1; 16259 // We cannot assume anything. 16260 return false; 16261 } 16262 16263 // Check if the length evaluates to 1. 16264 Expr::EvalResult Result; 16265 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16266 return false; // Can't get the integer value as a constant. 16267 16268 llvm::APSInt ConstLength = Result.Val.getInt(); 16269 return ConstLength.getSExtValue() != 1; 16270 } 16271 16272 // The base of elements of list in a map clause have to be either: 16273 // - a reference to variable or field. 16274 // - a member expression. 16275 // - an array expression. 16276 // 16277 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 16278 // reference to 'r'. 16279 // 16280 // If we have: 16281 // 16282 // struct SS { 16283 // Bla S; 16284 // foo() { 16285 // #pragma omp target map (S.Arr[:12]); 16286 // } 16287 // } 16288 // 16289 // We want to retrieve the member expression 'this->S'; 16290 16291 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 16292 // If a list item is an array section, it must specify contiguous storage. 16293 // 16294 // For this restriction it is sufficient that we make sure only references 16295 // to variables or fields and array expressions, and that no array sections 16296 // exist except in the rightmost expression (unless they cover the whole 16297 // dimension of the array). E.g. these would be invalid: 16298 // 16299 // r.ArrS[3:5].Arr[6:7] 16300 // 16301 // r.ArrS[3:5].x 16302 // 16303 // but these would be valid: 16304 // r.ArrS[3].Arr[6:7] 16305 // 16306 // r.ArrS[3].x 16307 namespace { 16308 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 16309 Sema &SemaRef; 16310 OpenMPClauseKind CKind = OMPC_unknown; 16311 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 16312 bool NoDiagnose = false; 16313 const Expr *RelevantExpr = nullptr; 16314 bool AllowUnitySizeArraySection = true; 16315 bool AllowWholeSizeArraySection = true; 16316 SourceLocation ELoc; 16317 SourceRange ERange; 16318 16319 void emitErrorMsg() { 16320 // If nothing else worked, this is not a valid map clause expression. 16321 if (SemaRef.getLangOpts().OpenMP < 50) { 16322 SemaRef.Diag(ELoc, 16323 diag::err_omp_expected_named_var_member_or_array_expression) 16324 << ERange; 16325 } else { 16326 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16327 << getOpenMPClauseName(CKind) << ERange; 16328 } 16329 } 16330 16331 public: 16332 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 16333 if (!isa<VarDecl>(DRE->getDecl())) { 16334 emitErrorMsg(); 16335 return false; 16336 } 16337 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16338 RelevantExpr = DRE; 16339 // Record the component. 16340 Components.emplace_back(DRE, DRE->getDecl()); 16341 return true; 16342 } 16343 16344 bool VisitMemberExpr(MemberExpr *ME) { 16345 Expr *E = ME; 16346 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 16347 16348 if (isa<CXXThisExpr>(BaseE)) { 16349 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16350 // We found a base expression: this->Val. 16351 RelevantExpr = ME; 16352 } else { 16353 E = BaseE; 16354 } 16355 16356 if (!isa<FieldDecl>(ME->getMemberDecl())) { 16357 if (!NoDiagnose) { 16358 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 16359 << ME->getSourceRange(); 16360 return false; 16361 } 16362 if (RelevantExpr) 16363 return false; 16364 return Visit(E); 16365 } 16366 16367 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 16368 16369 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 16370 // A bit-field cannot appear in a map clause. 16371 // 16372 if (FD->isBitField()) { 16373 if (!NoDiagnose) { 16374 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 16375 << ME->getSourceRange() << getOpenMPClauseName(CKind); 16376 return false; 16377 } 16378 if (RelevantExpr) 16379 return false; 16380 return Visit(E); 16381 } 16382 16383 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16384 // If the type of a list item is a reference to a type T then the type 16385 // will be considered to be T for all purposes of this clause. 16386 QualType CurType = BaseE->getType().getNonReferenceType(); 16387 16388 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 16389 // A list item cannot be a variable that is a member of a structure with 16390 // a union type. 16391 // 16392 if (CurType->isUnionType()) { 16393 if (!NoDiagnose) { 16394 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 16395 << ME->getSourceRange(); 16396 return false; 16397 } 16398 return RelevantExpr || Visit(E); 16399 } 16400 16401 // If we got a member expression, we should not expect any array section 16402 // before that: 16403 // 16404 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 16405 // If a list item is an element of a structure, only the rightmost symbol 16406 // of the variable reference can be an array section. 16407 // 16408 AllowUnitySizeArraySection = false; 16409 AllowWholeSizeArraySection = false; 16410 16411 // Record the component. 16412 Components.emplace_back(ME, FD); 16413 return RelevantExpr || Visit(E); 16414 } 16415 16416 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 16417 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 16418 16419 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 16420 if (!NoDiagnose) { 16421 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16422 << 0 << AE->getSourceRange(); 16423 return false; 16424 } 16425 return RelevantExpr || Visit(E); 16426 } 16427 16428 // If we got an array subscript that express the whole dimension we 16429 // can have any array expressions before. If it only expressing part of 16430 // the dimension, we can only have unitary-size array expressions. 16431 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, 16432 E->getType())) 16433 AllowWholeSizeArraySection = false; 16434 16435 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 16436 Expr::EvalResult Result; 16437 if (!AE->getIdx()->isValueDependent() && 16438 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 16439 !Result.Val.getInt().isNullValue()) { 16440 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16441 diag::err_omp_invalid_map_this_expr); 16442 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16443 diag::note_omp_invalid_subscript_on_this_ptr_map); 16444 } 16445 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16446 RelevantExpr = TE; 16447 } 16448 16449 // Record the component - we don't have any declaration associated. 16450 Components.emplace_back(AE, nullptr); 16451 16452 return RelevantExpr || Visit(E); 16453 } 16454 16455 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 16456 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 16457 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16458 QualType CurType = 16459 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16460 16461 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16462 // If the type of a list item is a reference to a type T then the type 16463 // will be considered to be T for all purposes of this clause. 16464 if (CurType->isReferenceType()) 16465 CurType = CurType->getPointeeType(); 16466 16467 bool IsPointer = CurType->isAnyPointerType(); 16468 16469 if (!IsPointer && !CurType->isArrayType()) { 16470 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16471 << 0 << OASE->getSourceRange(); 16472 return false; 16473 } 16474 16475 bool NotWhole = 16476 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 16477 bool NotUnity = 16478 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 16479 16480 if (AllowWholeSizeArraySection) { 16481 // Any array section is currently allowed. Allowing a whole size array 16482 // section implies allowing a unity array section as well. 16483 // 16484 // If this array section refers to the whole dimension we can still 16485 // accept other array sections before this one, except if the base is a 16486 // pointer. Otherwise, only unitary sections are accepted. 16487 if (NotWhole || IsPointer) 16488 AllowWholeSizeArraySection = false; 16489 } else if (AllowUnitySizeArraySection && NotUnity) { 16490 // A unity or whole array section is not allowed and that is not 16491 // compatible with the properties of the current array section. 16492 SemaRef.Diag( 16493 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 16494 << OASE->getSourceRange(); 16495 return false; 16496 } 16497 16498 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 16499 Expr::EvalResult ResultR; 16500 Expr::EvalResult ResultL; 16501 if (!OASE->getLength()->isValueDependent() && 16502 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 16503 !ResultR.Val.getInt().isOneValue()) { 16504 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16505 diag::err_omp_invalid_map_this_expr); 16506 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16507 diag::note_omp_invalid_length_on_this_ptr_mapping); 16508 } 16509 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 16510 OASE->getLowerBound()->EvaluateAsInt(ResultL, 16511 SemaRef.getASTContext()) && 16512 !ResultL.Val.getInt().isNullValue()) { 16513 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16514 diag::err_omp_invalid_map_this_expr); 16515 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16516 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 16517 } 16518 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16519 RelevantExpr = TE; 16520 } 16521 16522 // Record the component - we don't have any declaration associated. 16523 Components.emplace_back(OASE, nullptr); 16524 return RelevantExpr || Visit(E); 16525 } 16526 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 16527 Expr *Base = E->getBase(); 16528 16529 // Record the component - we don't have any declaration associated. 16530 Components.emplace_back(E, nullptr); 16531 16532 return Visit(Base->IgnoreParenImpCasts()); 16533 } 16534 16535 bool VisitUnaryOperator(UnaryOperator *UO) { 16536 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 16537 UO->getOpcode() != UO_Deref) { 16538 emitErrorMsg(); 16539 return false; 16540 } 16541 if (!RelevantExpr) { 16542 // Record the component if haven't found base decl. 16543 Components.emplace_back(UO, nullptr); 16544 } 16545 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 16546 } 16547 bool VisitBinaryOperator(BinaryOperator *BO) { 16548 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 16549 emitErrorMsg(); 16550 return false; 16551 } 16552 16553 // Pointer arithmetic is the only thing we expect to happen here so after we 16554 // make sure the binary operator is a pointer type, the we only thing need 16555 // to to is to visit the subtree that has the same type as root (so that we 16556 // know the other subtree is just an offset) 16557 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 16558 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 16559 Components.emplace_back(BO, nullptr); 16560 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 16561 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 16562 "Either LHS or RHS have base decl inside"); 16563 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 16564 return RelevantExpr || Visit(LE); 16565 return RelevantExpr || Visit(RE); 16566 } 16567 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 16568 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16569 RelevantExpr = CTE; 16570 Components.emplace_back(CTE, nullptr); 16571 return true; 16572 } 16573 bool VisitStmt(Stmt *) { 16574 emitErrorMsg(); 16575 return false; 16576 } 16577 const Expr *getFoundBase() const { 16578 return RelevantExpr; 16579 } 16580 explicit MapBaseChecker( 16581 Sema &SemaRef, OpenMPClauseKind CKind, 16582 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 16583 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 16584 : SemaRef(SemaRef), CKind(CKind), Components(Components), 16585 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 16586 }; 16587 } // namespace 16588 16589 /// Return the expression of the base of the mappable expression or null if it 16590 /// cannot be determined and do all the necessary checks to see if the expression 16591 /// is valid as a standalone mappable expression. In the process, record all the 16592 /// components of the expression. 16593 static const Expr *checkMapClauseExpressionBase( 16594 Sema &SemaRef, Expr *E, 16595 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 16596 OpenMPClauseKind CKind, bool NoDiagnose) { 16597 SourceLocation ELoc = E->getExprLoc(); 16598 SourceRange ERange = E->getSourceRange(); 16599 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc, 16600 ERange); 16601 if (Checker.Visit(E->IgnoreParens())) 16602 return Checker.getFoundBase(); 16603 return nullptr; 16604 } 16605 16606 // Return true if expression E associated with value VD has conflicts with other 16607 // map information. 16608 static bool checkMapConflicts( 16609 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 16610 bool CurrentRegionOnly, 16611 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 16612 OpenMPClauseKind CKind) { 16613 assert(VD && E); 16614 SourceLocation ELoc = E->getExprLoc(); 16615 SourceRange ERange = E->getSourceRange(); 16616 16617 // In order to easily check the conflicts we need to match each component of 16618 // the expression under test with the components of the expressions that are 16619 // already in the stack. 16620 16621 assert(!CurComponents.empty() && "Map clause expression with no components!"); 16622 assert(CurComponents.back().getAssociatedDeclaration() == VD && 16623 "Map clause expression with unexpected base!"); 16624 16625 // Variables to help detecting enclosing problems in data environment nests. 16626 bool IsEnclosedByDataEnvironmentExpr = false; 16627 const Expr *EnclosingExpr = nullptr; 16628 16629 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 16630 VD, CurrentRegionOnly, 16631 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 16632 ERange, CKind, &EnclosingExpr, 16633 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 16634 StackComponents, 16635 OpenMPClauseKind) { 16636 assert(!StackComponents.empty() && 16637 "Map clause expression with no components!"); 16638 assert(StackComponents.back().getAssociatedDeclaration() == VD && 16639 "Map clause expression with unexpected base!"); 16640 (void)VD; 16641 16642 // The whole expression in the stack. 16643 const Expr *RE = StackComponents.front().getAssociatedExpression(); 16644 16645 // Expressions must start from the same base. Here we detect at which 16646 // point both expressions diverge from each other and see if we can 16647 // detect if the memory referred to both expressions is contiguous and 16648 // do not overlap. 16649 auto CI = CurComponents.rbegin(); 16650 auto CE = CurComponents.rend(); 16651 auto SI = StackComponents.rbegin(); 16652 auto SE = StackComponents.rend(); 16653 for (; CI != CE && SI != SE; ++CI, ++SI) { 16654 16655 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 16656 // At most one list item can be an array item derived from a given 16657 // variable in map clauses of the same construct. 16658 if (CurrentRegionOnly && 16659 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 16660 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 16661 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 16662 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 16663 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 16664 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 16665 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 16666 diag::err_omp_multiple_array_items_in_map_clause) 16667 << CI->getAssociatedExpression()->getSourceRange(); 16668 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 16669 diag::note_used_here) 16670 << SI->getAssociatedExpression()->getSourceRange(); 16671 return true; 16672 } 16673 16674 // Do both expressions have the same kind? 16675 if (CI->getAssociatedExpression()->getStmtClass() != 16676 SI->getAssociatedExpression()->getStmtClass()) 16677 break; 16678 16679 // Are we dealing with different variables/fields? 16680 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 16681 break; 16682 } 16683 // Check if the extra components of the expressions in the enclosing 16684 // data environment are redundant for the current base declaration. 16685 // If they are, the maps completely overlap, which is legal. 16686 for (; SI != SE; ++SI) { 16687 QualType Type; 16688 if (const auto *ASE = 16689 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 16690 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 16691 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 16692 SI->getAssociatedExpression())) { 16693 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16694 Type = 16695 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16696 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 16697 SI->getAssociatedExpression())) { 16698 Type = OASE->getBase()->getType()->getPointeeType(); 16699 } 16700 if (Type.isNull() || Type->isAnyPointerType() || 16701 checkArrayExpressionDoesNotReferToWholeSize( 16702 SemaRef, SI->getAssociatedExpression(), Type)) 16703 break; 16704 } 16705 16706 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16707 // List items of map clauses in the same construct must not share 16708 // original storage. 16709 // 16710 // If the expressions are exactly the same or one is a subset of the 16711 // other, it means they are sharing storage. 16712 if (CI == CE && SI == SE) { 16713 if (CurrentRegionOnly) { 16714 if (CKind == OMPC_map) { 16715 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16716 } else { 16717 assert(CKind == OMPC_to || CKind == OMPC_from); 16718 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16719 << ERange; 16720 } 16721 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16722 << RE->getSourceRange(); 16723 return true; 16724 } 16725 // If we find the same expression in the enclosing data environment, 16726 // that is legal. 16727 IsEnclosedByDataEnvironmentExpr = true; 16728 return false; 16729 } 16730 16731 QualType DerivedType = 16732 std::prev(CI)->getAssociatedDeclaration()->getType(); 16733 SourceLocation DerivedLoc = 16734 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 16735 16736 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16737 // If the type of a list item is a reference to a type T then the type 16738 // will be considered to be T for all purposes of this clause. 16739 DerivedType = DerivedType.getNonReferenceType(); 16740 16741 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 16742 // A variable for which the type is pointer and an array section 16743 // derived from that variable must not appear as list items of map 16744 // clauses of the same construct. 16745 // 16746 // Also, cover one of the cases in: 16747 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16748 // If any part of the original storage of a list item has corresponding 16749 // storage in the device data environment, all of the original storage 16750 // must have corresponding storage in the device data environment. 16751 // 16752 if (DerivedType->isAnyPointerType()) { 16753 if (CI == CE || SI == SE) { 16754 SemaRef.Diag( 16755 DerivedLoc, 16756 diag::err_omp_pointer_mapped_along_with_derived_section) 16757 << DerivedLoc; 16758 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16759 << RE->getSourceRange(); 16760 return true; 16761 } 16762 if (CI->getAssociatedExpression()->getStmtClass() != 16763 SI->getAssociatedExpression()->getStmtClass() || 16764 CI->getAssociatedDeclaration()->getCanonicalDecl() == 16765 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 16766 assert(CI != CE && SI != SE); 16767 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 16768 << DerivedLoc; 16769 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16770 << RE->getSourceRange(); 16771 return true; 16772 } 16773 } 16774 16775 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16776 // List items of map clauses in the same construct must not share 16777 // original storage. 16778 // 16779 // An expression is a subset of the other. 16780 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 16781 if (CKind == OMPC_map) { 16782 if (CI != CE || SI != SE) { 16783 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 16784 // a pointer. 16785 auto Begin = 16786 CI != CE ? CurComponents.begin() : StackComponents.begin(); 16787 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 16788 auto It = Begin; 16789 while (It != End && !It->getAssociatedDeclaration()) 16790 std::advance(It, 1); 16791 assert(It != End && 16792 "Expected at least one component with the declaration."); 16793 if (It != Begin && It->getAssociatedDeclaration() 16794 ->getType() 16795 .getCanonicalType() 16796 ->isAnyPointerType()) { 16797 IsEnclosedByDataEnvironmentExpr = false; 16798 EnclosingExpr = nullptr; 16799 return false; 16800 } 16801 } 16802 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16803 } else { 16804 assert(CKind == OMPC_to || CKind == OMPC_from); 16805 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16806 << ERange; 16807 } 16808 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16809 << RE->getSourceRange(); 16810 return true; 16811 } 16812 16813 // The current expression uses the same base as other expression in the 16814 // data environment but does not contain it completely. 16815 if (!CurrentRegionOnly && SI != SE) 16816 EnclosingExpr = RE; 16817 16818 // The current expression is a subset of the expression in the data 16819 // environment. 16820 IsEnclosedByDataEnvironmentExpr |= 16821 (!CurrentRegionOnly && CI != CE && SI == SE); 16822 16823 return false; 16824 }); 16825 16826 if (CurrentRegionOnly) 16827 return FoundError; 16828 16829 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16830 // If any part of the original storage of a list item has corresponding 16831 // storage in the device data environment, all of the original storage must 16832 // have corresponding storage in the device data environment. 16833 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 16834 // If a list item is an element of a structure, and a different element of 16835 // the structure has a corresponding list item in the device data environment 16836 // prior to a task encountering the construct associated with the map clause, 16837 // then the list item must also have a corresponding list item in the device 16838 // data environment prior to the task encountering the construct. 16839 // 16840 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 16841 SemaRef.Diag(ELoc, 16842 diag::err_omp_original_storage_is_shared_and_does_not_contain) 16843 << ERange; 16844 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 16845 << EnclosingExpr->getSourceRange(); 16846 return true; 16847 } 16848 16849 return FoundError; 16850 } 16851 16852 // Look up the user-defined mapper given the mapper name and mapped type, and 16853 // build a reference to it. 16854 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 16855 CXXScopeSpec &MapperIdScopeSpec, 16856 const DeclarationNameInfo &MapperId, 16857 QualType Type, 16858 Expr *UnresolvedMapper) { 16859 if (MapperIdScopeSpec.isInvalid()) 16860 return ExprError(); 16861 // Get the actual type for the array type. 16862 if (Type->isArrayType()) { 16863 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 16864 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 16865 } 16866 // Find all user-defined mappers with the given MapperId. 16867 SmallVector<UnresolvedSet<8>, 4> Lookups; 16868 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 16869 Lookup.suppressDiagnostics(); 16870 if (S) { 16871 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 16872 NamedDecl *D = Lookup.getRepresentativeDecl(); 16873 while (S && !S->isDeclScope(D)) 16874 S = S->getParent(); 16875 if (S) 16876 S = S->getParent(); 16877 Lookups.emplace_back(); 16878 Lookups.back().append(Lookup.begin(), Lookup.end()); 16879 Lookup.clear(); 16880 } 16881 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 16882 // Extract the user-defined mappers with the given MapperId. 16883 Lookups.push_back(UnresolvedSet<8>()); 16884 for (NamedDecl *D : ULE->decls()) { 16885 auto *DMD = cast<OMPDeclareMapperDecl>(D); 16886 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 16887 Lookups.back().addDecl(DMD); 16888 } 16889 } 16890 // Defer the lookup for dependent types. The results will be passed through 16891 // UnresolvedMapper on instantiation. 16892 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 16893 Type->isInstantiationDependentType() || 16894 Type->containsUnexpandedParameterPack() || 16895 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 16896 return !D->isInvalidDecl() && 16897 (D->getType()->isDependentType() || 16898 D->getType()->isInstantiationDependentType() || 16899 D->getType()->containsUnexpandedParameterPack()); 16900 })) { 16901 UnresolvedSet<8> URS; 16902 for (const UnresolvedSet<8> &Set : Lookups) { 16903 if (Set.empty()) 16904 continue; 16905 URS.append(Set.begin(), Set.end()); 16906 } 16907 return UnresolvedLookupExpr::Create( 16908 SemaRef.Context, /*NamingClass=*/nullptr, 16909 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 16910 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 16911 } 16912 SourceLocation Loc = MapperId.getLoc(); 16913 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16914 // The type must be of struct, union or class type in C and C++ 16915 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 16916 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 16917 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 16918 return ExprError(); 16919 } 16920 // Perform argument dependent lookup. 16921 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 16922 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 16923 // Return the first user-defined mapper with the desired type. 16924 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16925 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 16926 if (!D->isInvalidDecl() && 16927 SemaRef.Context.hasSameType(D->getType(), Type)) 16928 return D; 16929 return nullptr; 16930 })) 16931 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16932 // Find the first user-defined mapper with a type derived from the desired 16933 // type. 16934 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16935 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 16936 if (!D->isInvalidDecl() && 16937 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 16938 !Type.isMoreQualifiedThan(D->getType())) 16939 return D; 16940 return nullptr; 16941 })) { 16942 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 16943 /*DetectVirtual=*/false); 16944 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 16945 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 16946 VD->getType().getUnqualifiedType()))) { 16947 if (SemaRef.CheckBaseClassAccess( 16948 Loc, VD->getType(), Type, Paths.front(), 16949 /*DiagID=*/0) != Sema::AR_inaccessible) { 16950 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16951 } 16952 } 16953 } 16954 } 16955 // Report error if a mapper is specified, but cannot be found. 16956 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 16957 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 16958 << Type << MapperId.getName(); 16959 return ExprError(); 16960 } 16961 return ExprEmpty(); 16962 } 16963 16964 namespace { 16965 // Utility struct that gathers all the related lists associated with a mappable 16966 // expression. 16967 struct MappableVarListInfo { 16968 // The list of expressions. 16969 ArrayRef<Expr *> VarList; 16970 // The list of processed expressions. 16971 SmallVector<Expr *, 16> ProcessedVarList; 16972 // The mappble components for each expression. 16973 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 16974 // The base declaration of the variable. 16975 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 16976 // The reference to the user-defined mapper associated with every expression. 16977 SmallVector<Expr *, 16> UDMapperList; 16978 16979 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 16980 // We have a list of components and base declarations for each entry in the 16981 // variable list. 16982 VarComponents.reserve(VarList.size()); 16983 VarBaseDeclarations.reserve(VarList.size()); 16984 } 16985 }; 16986 } 16987 16988 // Check the validity of the provided variable list for the provided clause kind 16989 // \a CKind. In the check process the valid expressions, mappable expression 16990 // components, variables, and user-defined mappers are extracted and used to 16991 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 16992 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 16993 // and \a MapperId are expected to be valid if the clause kind is 'map'. 16994 static void checkMappableExpressionList( 16995 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 16996 MappableVarListInfo &MVLI, SourceLocation StartLoc, 16997 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 16998 ArrayRef<Expr *> UnresolvedMappers, 16999 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 17000 bool IsMapTypeImplicit = false) { 17001 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 17002 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 17003 "Unexpected clause kind with mappable expressions!"); 17004 17005 // If the identifier of user-defined mapper is not specified, it is "default". 17006 // We do not change the actual name in this clause to distinguish whether a 17007 // mapper is specified explicitly, i.e., it is not explicitly specified when 17008 // MapperId.getName() is empty. 17009 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 17010 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 17011 MapperId.setName(DeclNames.getIdentifier( 17012 &SemaRef.getASTContext().Idents.get("default"))); 17013 } 17014 17015 // Iterators to find the current unresolved mapper expression. 17016 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 17017 bool UpdateUMIt = false; 17018 Expr *UnresolvedMapper = nullptr; 17019 17020 // Keep track of the mappable components and base declarations in this clause. 17021 // Each entry in the list is going to have a list of components associated. We 17022 // record each set of the components so that we can build the clause later on. 17023 // In the end we should have the same amount of declarations and component 17024 // lists. 17025 17026 for (Expr *RE : MVLI.VarList) { 17027 assert(RE && "Null expr in omp to/from/map clause"); 17028 SourceLocation ELoc = RE->getExprLoc(); 17029 17030 // Find the current unresolved mapper expression. 17031 if (UpdateUMIt && UMIt != UMEnd) { 17032 UMIt++; 17033 assert( 17034 UMIt != UMEnd && 17035 "Expect the size of UnresolvedMappers to match with that of VarList"); 17036 } 17037 UpdateUMIt = true; 17038 if (UMIt != UMEnd) 17039 UnresolvedMapper = *UMIt; 17040 17041 const Expr *VE = RE->IgnoreParenLValueCasts(); 17042 17043 if (VE->isValueDependent() || VE->isTypeDependent() || 17044 VE->isInstantiationDependent() || 17045 VE->containsUnexpandedParameterPack()) { 17046 // Try to find the associated user-defined mapper. 17047 ExprResult ER = buildUserDefinedMapperRef( 17048 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17049 VE->getType().getCanonicalType(), UnresolvedMapper); 17050 if (ER.isInvalid()) 17051 continue; 17052 MVLI.UDMapperList.push_back(ER.get()); 17053 // We can only analyze this information once the missing information is 17054 // resolved. 17055 MVLI.ProcessedVarList.push_back(RE); 17056 continue; 17057 } 17058 17059 Expr *SimpleExpr = RE->IgnoreParenCasts(); 17060 17061 if (!RE->isLValue()) { 17062 if (SemaRef.getLangOpts().OpenMP < 50) { 17063 SemaRef.Diag( 17064 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 17065 << RE->getSourceRange(); 17066 } else { 17067 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 17068 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 17069 } 17070 continue; 17071 } 17072 17073 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 17074 ValueDecl *CurDeclaration = nullptr; 17075 17076 // Obtain the array or member expression bases if required. Also, fill the 17077 // components array with all the components identified in the process. 17078 const Expr *BE = checkMapClauseExpressionBase( 17079 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 17080 if (!BE) 17081 continue; 17082 17083 assert(!CurComponents.empty() && 17084 "Invalid mappable expression information."); 17085 17086 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 17087 // Add store "this" pointer to class in DSAStackTy for future checking 17088 DSAS->addMappedClassesQualTypes(TE->getType()); 17089 // Try to find the associated user-defined mapper. 17090 ExprResult ER = buildUserDefinedMapperRef( 17091 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17092 VE->getType().getCanonicalType(), UnresolvedMapper); 17093 if (ER.isInvalid()) 17094 continue; 17095 MVLI.UDMapperList.push_back(ER.get()); 17096 // Skip restriction checking for variable or field declarations 17097 MVLI.ProcessedVarList.push_back(RE); 17098 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17099 MVLI.VarComponents.back().append(CurComponents.begin(), 17100 CurComponents.end()); 17101 MVLI.VarBaseDeclarations.push_back(nullptr); 17102 continue; 17103 } 17104 17105 // For the following checks, we rely on the base declaration which is 17106 // expected to be associated with the last component. The declaration is 17107 // expected to be a variable or a field (if 'this' is being mapped). 17108 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 17109 assert(CurDeclaration && "Null decl on map clause."); 17110 assert( 17111 CurDeclaration->isCanonicalDecl() && 17112 "Expecting components to have associated only canonical declarations."); 17113 17114 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 17115 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 17116 17117 assert((VD || FD) && "Only variables or fields are expected here!"); 17118 (void)FD; 17119 17120 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 17121 // threadprivate variables cannot appear in a map clause. 17122 // OpenMP 4.5 [2.10.5, target update Construct] 17123 // threadprivate variables cannot appear in a from clause. 17124 if (VD && DSAS->isThreadPrivate(VD)) { 17125 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17126 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 17127 << getOpenMPClauseName(CKind); 17128 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 17129 continue; 17130 } 17131 17132 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17133 // A list item cannot appear in both a map clause and a data-sharing 17134 // attribute clause on the same construct. 17135 17136 // Check conflicts with other map clause expressions. We check the conflicts 17137 // with the current construct separately from the enclosing data 17138 // environment, because the restrictions are different. We only have to 17139 // check conflicts across regions for the map clauses. 17140 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17141 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 17142 break; 17143 if (CKind == OMPC_map && 17144 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17145 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 17146 break; 17147 17148 // OpenMP 4.5 [2.10.5, target update Construct] 17149 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 17150 // If the type of a list item is a reference to a type T then the type will 17151 // be considered to be T for all purposes of this clause. 17152 auto I = llvm::find_if( 17153 CurComponents, 17154 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 17155 return MC.getAssociatedDeclaration(); 17156 }); 17157 assert(I != CurComponents.end() && "Null decl on map clause."); 17158 QualType Type; 17159 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 17160 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 17161 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 17162 if (ASE) { 17163 Type = ASE->getType().getNonReferenceType(); 17164 } else if (OASE) { 17165 QualType BaseType = 17166 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 17167 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 17168 Type = ATy->getElementType(); 17169 else 17170 Type = BaseType->getPointeeType(); 17171 Type = Type.getNonReferenceType(); 17172 } else if (OAShE) { 17173 Type = OAShE->getBase()->getType()->getPointeeType(); 17174 } else { 17175 Type = VE->getType(); 17176 } 17177 17178 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 17179 // A list item in a to or from clause must have a mappable type. 17180 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17181 // A list item must have a mappable type. 17182 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 17183 DSAS, Type)) 17184 continue; 17185 17186 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 17187 17188 if (CKind == OMPC_map) { 17189 // target enter data 17190 // OpenMP [2.10.2, Restrictions, p. 99] 17191 // A map-type must be specified in all map clauses and must be either 17192 // to or alloc. 17193 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 17194 if (DKind == OMPD_target_enter_data && 17195 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 17196 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17197 << (IsMapTypeImplicit ? 1 : 0) 17198 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17199 << getOpenMPDirectiveName(DKind); 17200 continue; 17201 } 17202 17203 // target exit_data 17204 // OpenMP [2.10.3, Restrictions, p. 102] 17205 // A map-type must be specified in all map clauses and must be either 17206 // from, release, or delete. 17207 if (DKind == OMPD_target_exit_data && 17208 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 17209 MapType == OMPC_MAP_delete)) { 17210 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17211 << (IsMapTypeImplicit ? 1 : 0) 17212 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17213 << getOpenMPDirectiveName(DKind); 17214 continue; 17215 } 17216 17217 // target, target data 17218 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 17219 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 17220 // A map-type in a map clause must be to, from, tofrom or alloc 17221 if ((DKind == OMPD_target_data || 17222 isOpenMPTargetExecutionDirective(DKind)) && 17223 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 17224 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 17225 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17226 << (IsMapTypeImplicit ? 1 : 0) 17227 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17228 << getOpenMPDirectiveName(DKind); 17229 continue; 17230 } 17231 17232 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17233 // A list item cannot appear in both a map clause and a data-sharing 17234 // attribute clause on the same construct 17235 // 17236 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17237 // A list item cannot appear in both a map clause and a data-sharing 17238 // attribute clause on the same construct unless the construct is a 17239 // combined construct. 17240 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 17241 isOpenMPTargetExecutionDirective(DKind)) || 17242 DKind == OMPD_target)) { 17243 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17244 if (isOpenMPPrivate(DVar.CKind)) { 17245 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17246 << getOpenMPClauseName(DVar.CKind) 17247 << getOpenMPClauseName(OMPC_map) 17248 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 17249 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 17250 continue; 17251 } 17252 } 17253 } 17254 17255 // Try to find the associated user-defined mapper. 17256 ExprResult ER = buildUserDefinedMapperRef( 17257 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17258 Type.getCanonicalType(), UnresolvedMapper); 17259 if (ER.isInvalid()) 17260 continue; 17261 MVLI.UDMapperList.push_back(ER.get()); 17262 17263 // Save the current expression. 17264 MVLI.ProcessedVarList.push_back(RE); 17265 17266 // Store the components in the stack so that they can be used to check 17267 // against other clauses later on. 17268 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 17269 /*WhereFoundClauseKind=*/OMPC_map); 17270 17271 // Save the components and declaration to create the clause. For purposes of 17272 // the clause creation, any component list that has has base 'this' uses 17273 // null as base declaration. 17274 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17275 MVLI.VarComponents.back().append(CurComponents.begin(), 17276 CurComponents.end()); 17277 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 17278 : CurDeclaration); 17279 } 17280 } 17281 17282 OMPClause *Sema::ActOnOpenMPMapClause( 17283 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 17284 ArrayRef<SourceLocation> MapTypeModifiersLoc, 17285 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 17286 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 17287 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 17288 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 17289 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 17290 OMPC_MAP_MODIFIER_unknown, 17291 OMPC_MAP_MODIFIER_unknown}; 17292 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 17293 17294 // Process map-type-modifiers, flag errors for duplicate modifiers. 17295 unsigned Count = 0; 17296 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 17297 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 17298 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 17299 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 17300 continue; 17301 } 17302 assert(Count < NumberOfOMPMapClauseModifiers && 17303 "Modifiers exceed the allowed number of map type modifiers"); 17304 Modifiers[Count] = MapTypeModifiers[I]; 17305 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 17306 ++Count; 17307 } 17308 17309 MappableVarListInfo MVLI(VarList); 17310 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 17311 MapperIdScopeSpec, MapperId, UnresolvedMappers, 17312 MapType, IsMapTypeImplicit); 17313 17314 // We need to produce a map clause even if we don't have variables so that 17315 // other diagnostics related with non-existing map clauses are accurate. 17316 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 17317 MVLI.VarBaseDeclarations, MVLI.VarComponents, 17318 MVLI.UDMapperList, Modifiers, ModifiersLoc, 17319 MapperIdScopeSpec.getWithLocInContext(Context), 17320 MapperId, MapType, IsMapTypeImplicit, MapLoc); 17321 } 17322 17323 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 17324 TypeResult ParsedType) { 17325 assert(ParsedType.isUsable()); 17326 17327 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 17328 if (ReductionType.isNull()) 17329 return QualType(); 17330 17331 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 17332 // A type name in a declare reduction directive cannot be a function type, an 17333 // array type, a reference type, or a type qualified with const, volatile or 17334 // restrict. 17335 if (ReductionType.hasQualifiers()) { 17336 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 17337 return QualType(); 17338 } 17339 17340 if (ReductionType->isFunctionType()) { 17341 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 17342 return QualType(); 17343 } 17344 if (ReductionType->isReferenceType()) { 17345 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 17346 return QualType(); 17347 } 17348 if (ReductionType->isArrayType()) { 17349 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 17350 return QualType(); 17351 } 17352 return ReductionType; 17353 } 17354 17355 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 17356 Scope *S, DeclContext *DC, DeclarationName Name, 17357 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 17358 AccessSpecifier AS, Decl *PrevDeclInScope) { 17359 SmallVector<Decl *, 8> Decls; 17360 Decls.reserve(ReductionTypes.size()); 17361 17362 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 17363 forRedeclarationInCurContext()); 17364 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 17365 // A reduction-identifier may not be re-declared in the current scope for the 17366 // same type or for a type that is compatible according to the base language 17367 // rules. 17368 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17369 OMPDeclareReductionDecl *PrevDRD = nullptr; 17370 bool InCompoundScope = true; 17371 if (S != nullptr) { 17372 // Find previous declaration with the same name not referenced in other 17373 // declarations. 17374 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17375 InCompoundScope = 17376 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17377 LookupName(Lookup, S); 17378 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17379 /*AllowInlineNamespace=*/false); 17380 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 17381 LookupResult::Filter Filter = Lookup.makeFilter(); 17382 while (Filter.hasNext()) { 17383 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 17384 if (InCompoundScope) { 17385 auto I = UsedAsPrevious.find(PrevDecl); 17386 if (I == UsedAsPrevious.end()) 17387 UsedAsPrevious[PrevDecl] = false; 17388 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 17389 UsedAsPrevious[D] = true; 17390 } 17391 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17392 PrevDecl->getLocation(); 17393 } 17394 Filter.done(); 17395 if (InCompoundScope) { 17396 for (const auto &PrevData : UsedAsPrevious) { 17397 if (!PrevData.second) { 17398 PrevDRD = PrevData.first; 17399 break; 17400 } 17401 } 17402 } 17403 } else if (PrevDeclInScope != nullptr) { 17404 auto *PrevDRDInScope = PrevDRD = 17405 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 17406 do { 17407 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 17408 PrevDRDInScope->getLocation(); 17409 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 17410 } while (PrevDRDInScope != nullptr); 17411 } 17412 for (const auto &TyData : ReductionTypes) { 17413 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 17414 bool Invalid = false; 17415 if (I != PreviousRedeclTypes.end()) { 17416 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 17417 << TyData.first; 17418 Diag(I->second, diag::note_previous_definition); 17419 Invalid = true; 17420 } 17421 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 17422 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 17423 Name, TyData.first, PrevDRD); 17424 DC->addDecl(DRD); 17425 DRD->setAccess(AS); 17426 Decls.push_back(DRD); 17427 if (Invalid) 17428 DRD->setInvalidDecl(); 17429 else 17430 PrevDRD = DRD; 17431 } 17432 17433 return DeclGroupPtrTy::make( 17434 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 17435 } 17436 17437 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 17438 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17439 17440 // Enter new function scope. 17441 PushFunctionScope(); 17442 setFunctionHasBranchProtectedScope(); 17443 getCurFunction()->setHasOMPDeclareReductionCombiner(); 17444 17445 if (S != nullptr) 17446 PushDeclContext(S, DRD); 17447 else 17448 CurContext = DRD; 17449 17450 PushExpressionEvaluationContext( 17451 ExpressionEvaluationContext::PotentiallyEvaluated); 17452 17453 QualType ReductionType = DRD->getType(); 17454 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 17455 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 17456 // uses semantics of argument handles by value, but it should be passed by 17457 // reference. C lang does not support references, so pass all parameters as 17458 // pointers. 17459 // Create 'T omp_in;' variable. 17460 VarDecl *OmpInParm = 17461 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 17462 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 17463 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 17464 // uses semantics of argument handles by value, but it should be passed by 17465 // reference. C lang does not support references, so pass all parameters as 17466 // pointers. 17467 // Create 'T omp_out;' variable. 17468 VarDecl *OmpOutParm = 17469 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 17470 if (S != nullptr) { 17471 PushOnScopeChains(OmpInParm, S); 17472 PushOnScopeChains(OmpOutParm, S); 17473 } else { 17474 DRD->addDecl(OmpInParm); 17475 DRD->addDecl(OmpOutParm); 17476 } 17477 Expr *InE = 17478 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 17479 Expr *OutE = 17480 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 17481 DRD->setCombinerData(InE, OutE); 17482 } 17483 17484 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 17485 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17486 DiscardCleanupsInEvaluationContext(); 17487 PopExpressionEvaluationContext(); 17488 17489 PopDeclContext(); 17490 PopFunctionScopeInfo(); 17491 17492 if (Combiner != nullptr) 17493 DRD->setCombiner(Combiner); 17494 else 17495 DRD->setInvalidDecl(); 17496 } 17497 17498 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 17499 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17500 17501 // Enter new function scope. 17502 PushFunctionScope(); 17503 setFunctionHasBranchProtectedScope(); 17504 17505 if (S != nullptr) 17506 PushDeclContext(S, DRD); 17507 else 17508 CurContext = DRD; 17509 17510 PushExpressionEvaluationContext( 17511 ExpressionEvaluationContext::PotentiallyEvaluated); 17512 17513 QualType ReductionType = DRD->getType(); 17514 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 17515 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 17516 // uses semantics of argument handles by value, but it should be passed by 17517 // reference. C lang does not support references, so pass all parameters as 17518 // pointers. 17519 // Create 'T omp_priv;' variable. 17520 VarDecl *OmpPrivParm = 17521 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 17522 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 17523 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 17524 // uses semantics of argument handles by value, but it should be passed by 17525 // reference. C lang does not support references, so pass all parameters as 17526 // pointers. 17527 // Create 'T omp_orig;' variable. 17528 VarDecl *OmpOrigParm = 17529 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 17530 if (S != nullptr) { 17531 PushOnScopeChains(OmpPrivParm, S); 17532 PushOnScopeChains(OmpOrigParm, S); 17533 } else { 17534 DRD->addDecl(OmpPrivParm); 17535 DRD->addDecl(OmpOrigParm); 17536 } 17537 Expr *OrigE = 17538 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 17539 Expr *PrivE = 17540 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 17541 DRD->setInitializerData(OrigE, PrivE); 17542 return OmpPrivParm; 17543 } 17544 17545 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 17546 VarDecl *OmpPrivParm) { 17547 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17548 DiscardCleanupsInEvaluationContext(); 17549 PopExpressionEvaluationContext(); 17550 17551 PopDeclContext(); 17552 PopFunctionScopeInfo(); 17553 17554 if (Initializer != nullptr) { 17555 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 17556 } else if (OmpPrivParm->hasInit()) { 17557 DRD->setInitializer(OmpPrivParm->getInit(), 17558 OmpPrivParm->isDirectInit() 17559 ? OMPDeclareReductionDecl::DirectInit 17560 : OMPDeclareReductionDecl::CopyInit); 17561 } else { 17562 DRD->setInvalidDecl(); 17563 } 17564 } 17565 17566 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 17567 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 17568 for (Decl *D : DeclReductions.get()) { 17569 if (IsValid) { 17570 if (S) 17571 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 17572 /*AddToContext=*/false); 17573 } else { 17574 D->setInvalidDecl(); 17575 } 17576 } 17577 return DeclReductions; 17578 } 17579 17580 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 17581 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 17582 QualType T = TInfo->getType(); 17583 if (D.isInvalidType()) 17584 return true; 17585 17586 if (getLangOpts().CPlusPlus) { 17587 // Check that there are no default arguments (C++ only). 17588 CheckExtraCXXDefaultArguments(D); 17589 } 17590 17591 return CreateParsedType(T, TInfo); 17592 } 17593 17594 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 17595 TypeResult ParsedType) { 17596 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 17597 17598 QualType MapperType = GetTypeFromParser(ParsedType.get()); 17599 assert(!MapperType.isNull() && "Expect valid mapper type"); 17600 17601 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17602 // The type must be of struct, union or class type in C and C++ 17603 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 17604 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 17605 return QualType(); 17606 } 17607 return MapperType; 17608 } 17609 17610 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 17611 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 17612 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 17613 Decl *PrevDeclInScope) { 17614 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 17615 forRedeclarationInCurContext()); 17616 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17617 // A mapper-identifier may not be redeclared in the current scope for the 17618 // same type or for a type that is compatible according to the base language 17619 // rules. 17620 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17621 OMPDeclareMapperDecl *PrevDMD = nullptr; 17622 bool InCompoundScope = true; 17623 if (S != nullptr) { 17624 // Find previous declaration with the same name not referenced in other 17625 // declarations. 17626 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17627 InCompoundScope = 17628 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17629 LookupName(Lookup, S); 17630 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17631 /*AllowInlineNamespace=*/false); 17632 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 17633 LookupResult::Filter Filter = Lookup.makeFilter(); 17634 while (Filter.hasNext()) { 17635 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 17636 if (InCompoundScope) { 17637 auto I = UsedAsPrevious.find(PrevDecl); 17638 if (I == UsedAsPrevious.end()) 17639 UsedAsPrevious[PrevDecl] = false; 17640 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 17641 UsedAsPrevious[D] = true; 17642 } 17643 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17644 PrevDecl->getLocation(); 17645 } 17646 Filter.done(); 17647 if (InCompoundScope) { 17648 for (const auto &PrevData : UsedAsPrevious) { 17649 if (!PrevData.second) { 17650 PrevDMD = PrevData.first; 17651 break; 17652 } 17653 } 17654 } 17655 } else if (PrevDeclInScope) { 17656 auto *PrevDMDInScope = PrevDMD = 17657 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 17658 do { 17659 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 17660 PrevDMDInScope->getLocation(); 17661 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 17662 } while (PrevDMDInScope != nullptr); 17663 } 17664 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 17665 bool Invalid = false; 17666 if (I != PreviousRedeclTypes.end()) { 17667 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 17668 << MapperType << Name; 17669 Diag(I->second, diag::note_previous_definition); 17670 Invalid = true; 17671 } 17672 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 17673 MapperType, VN, PrevDMD); 17674 DC->addDecl(DMD); 17675 DMD->setAccess(AS); 17676 if (Invalid) 17677 DMD->setInvalidDecl(); 17678 17679 // Enter new function scope. 17680 PushFunctionScope(); 17681 setFunctionHasBranchProtectedScope(); 17682 17683 CurContext = DMD; 17684 17685 return DMD; 17686 } 17687 17688 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 17689 Scope *S, 17690 QualType MapperType, 17691 SourceLocation StartLoc, 17692 DeclarationName VN) { 17693 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 17694 if (S) 17695 PushOnScopeChains(VD, S); 17696 else 17697 DMD->addDecl(VD); 17698 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 17699 DMD->setMapperVarRef(MapperVarRefExpr); 17700 } 17701 17702 Sema::DeclGroupPtrTy 17703 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 17704 ArrayRef<OMPClause *> ClauseList) { 17705 PopDeclContext(); 17706 PopFunctionScopeInfo(); 17707 17708 if (D) { 17709 if (S) 17710 PushOnScopeChains(D, S, /*AddToContext=*/false); 17711 D->CreateClauses(Context, ClauseList); 17712 } 17713 17714 return DeclGroupPtrTy::make(DeclGroupRef(D)); 17715 } 17716 17717 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 17718 SourceLocation StartLoc, 17719 SourceLocation LParenLoc, 17720 SourceLocation EndLoc) { 17721 Expr *ValExpr = NumTeams; 17722 Stmt *HelperValStmt = nullptr; 17723 17724 // OpenMP [teams Constrcut, Restrictions] 17725 // The num_teams expression must evaluate to a positive integer value. 17726 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 17727 /*StrictlyPositive=*/true)) 17728 return nullptr; 17729 17730 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17731 OpenMPDirectiveKind CaptureRegion = 17732 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 17733 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17734 ValExpr = MakeFullExpr(ValExpr).get(); 17735 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17736 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17737 HelperValStmt = buildPreInits(Context, Captures); 17738 } 17739 17740 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 17741 StartLoc, LParenLoc, EndLoc); 17742 } 17743 17744 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 17745 SourceLocation StartLoc, 17746 SourceLocation LParenLoc, 17747 SourceLocation EndLoc) { 17748 Expr *ValExpr = ThreadLimit; 17749 Stmt *HelperValStmt = nullptr; 17750 17751 // OpenMP [teams Constrcut, Restrictions] 17752 // The thread_limit expression must evaluate to a positive integer value. 17753 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 17754 /*StrictlyPositive=*/true)) 17755 return nullptr; 17756 17757 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17758 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 17759 DKind, OMPC_thread_limit, LangOpts.OpenMP); 17760 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17761 ValExpr = MakeFullExpr(ValExpr).get(); 17762 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17763 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17764 HelperValStmt = buildPreInits(Context, Captures); 17765 } 17766 17767 return new (Context) OMPThreadLimitClause( 17768 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 17769 } 17770 17771 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 17772 SourceLocation StartLoc, 17773 SourceLocation LParenLoc, 17774 SourceLocation EndLoc) { 17775 Expr *ValExpr = Priority; 17776 Stmt *HelperValStmt = nullptr; 17777 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17778 17779 // OpenMP [2.9.1, task Constrcut] 17780 // The priority-value is a non-negative numerical scalar expression. 17781 if (!isNonNegativeIntegerValue( 17782 ValExpr, *this, OMPC_priority, 17783 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 17784 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17785 return nullptr; 17786 17787 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 17788 StartLoc, LParenLoc, EndLoc); 17789 } 17790 17791 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 17792 SourceLocation StartLoc, 17793 SourceLocation LParenLoc, 17794 SourceLocation EndLoc) { 17795 Expr *ValExpr = Grainsize; 17796 Stmt *HelperValStmt = nullptr; 17797 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17798 17799 // OpenMP [2.9.2, taskloop Constrcut] 17800 // The parameter of the grainsize clause must be a positive integer 17801 // expression. 17802 if (!isNonNegativeIntegerValue( 17803 ValExpr, *this, OMPC_grainsize, 17804 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17805 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17806 return nullptr; 17807 17808 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 17809 StartLoc, LParenLoc, EndLoc); 17810 } 17811 17812 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 17813 SourceLocation StartLoc, 17814 SourceLocation LParenLoc, 17815 SourceLocation EndLoc) { 17816 Expr *ValExpr = NumTasks; 17817 Stmt *HelperValStmt = nullptr; 17818 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17819 17820 // OpenMP [2.9.2, taskloop Constrcut] 17821 // The parameter of the num_tasks clause must be a positive integer 17822 // expression. 17823 if (!isNonNegativeIntegerValue( 17824 ValExpr, *this, OMPC_num_tasks, 17825 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17826 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17827 return nullptr; 17828 17829 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 17830 StartLoc, LParenLoc, EndLoc); 17831 } 17832 17833 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 17834 SourceLocation LParenLoc, 17835 SourceLocation EndLoc) { 17836 // OpenMP [2.13.2, critical construct, Description] 17837 // ... where hint-expression is an integer constant expression that evaluates 17838 // to a valid lock hint. 17839 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 17840 if (HintExpr.isInvalid()) 17841 return nullptr; 17842 return new (Context) 17843 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 17844 } 17845 17846 /// Tries to find omp_event_handle_t type. 17847 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 17848 DSAStackTy *Stack) { 17849 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 17850 if (!OMPEventHandleT.isNull()) 17851 return true; 17852 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 17853 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 17854 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 17855 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 17856 return false; 17857 } 17858 Stack->setOMPEventHandleT(PT.get()); 17859 return true; 17860 } 17861 17862 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 17863 SourceLocation LParenLoc, 17864 SourceLocation EndLoc) { 17865 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 17866 !Evt->isInstantiationDependent() && 17867 !Evt->containsUnexpandedParameterPack()) { 17868 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 17869 return nullptr; 17870 // OpenMP 5.0, 2.10.1 task Construct. 17871 // event-handle is a variable of the omp_event_handle_t type. 17872 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 17873 if (!Ref) { 17874 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 17875 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 17876 return nullptr; 17877 } 17878 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 17879 if (!VD) { 17880 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 17881 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 17882 return nullptr; 17883 } 17884 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 17885 VD->getType()) || 17886 VD->getType().isConstant(Context)) { 17887 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 17888 << "omp_event_handle_t" << 1 << VD->getType() 17889 << Evt->getSourceRange(); 17890 return nullptr; 17891 } 17892 // OpenMP 5.0, 2.10.1 task Construct 17893 // [detach clause]... The event-handle will be considered as if it was 17894 // specified on a firstprivate clause. 17895 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 17896 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 17897 DVar.RefExpr) { 17898 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 17899 << getOpenMPClauseName(DVar.CKind) 17900 << getOpenMPClauseName(OMPC_firstprivate); 17901 reportOriginalDsa(*this, DSAStack, VD, DVar); 17902 return nullptr; 17903 } 17904 } 17905 17906 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 17907 } 17908 17909 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 17910 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 17911 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 17912 SourceLocation EndLoc) { 17913 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 17914 std::string Values; 17915 Values += "'"; 17916 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 17917 Values += "'"; 17918 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17919 << Values << getOpenMPClauseName(OMPC_dist_schedule); 17920 return nullptr; 17921 } 17922 Expr *ValExpr = ChunkSize; 17923 Stmt *HelperValStmt = nullptr; 17924 if (ChunkSize) { 17925 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 17926 !ChunkSize->isInstantiationDependent() && 17927 !ChunkSize->containsUnexpandedParameterPack()) { 17928 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 17929 ExprResult Val = 17930 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 17931 if (Val.isInvalid()) 17932 return nullptr; 17933 17934 ValExpr = Val.get(); 17935 17936 // OpenMP [2.7.1, Restrictions] 17937 // chunk_size must be a loop invariant integer expression with a positive 17938 // value. 17939 llvm::APSInt Result; 17940 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 17941 if (Result.isSigned() && !Result.isStrictlyPositive()) { 17942 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 17943 << "dist_schedule" << ChunkSize->getSourceRange(); 17944 return nullptr; 17945 } 17946 } else if (getOpenMPCaptureRegionForClause( 17947 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 17948 LangOpts.OpenMP) != OMPD_unknown && 17949 !CurContext->isDependentContext()) { 17950 ValExpr = MakeFullExpr(ValExpr).get(); 17951 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17952 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17953 HelperValStmt = buildPreInits(Context, Captures); 17954 } 17955 } 17956 } 17957 17958 return new (Context) 17959 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 17960 Kind, ValExpr, HelperValStmt); 17961 } 17962 17963 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 17964 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 17965 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 17966 SourceLocation KindLoc, SourceLocation EndLoc) { 17967 if (getLangOpts().OpenMP < 50) { 17968 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 17969 Kind != OMPC_DEFAULTMAP_scalar) { 17970 std::string Value; 17971 SourceLocation Loc; 17972 Value += "'"; 17973 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 17974 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 17975 OMPC_DEFAULTMAP_MODIFIER_tofrom); 17976 Loc = MLoc; 17977 } else { 17978 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 17979 OMPC_DEFAULTMAP_scalar); 17980 Loc = KindLoc; 17981 } 17982 Value += "'"; 17983 Diag(Loc, diag::err_omp_unexpected_clause_value) 17984 << Value << getOpenMPClauseName(OMPC_defaultmap); 17985 return nullptr; 17986 } 17987 } else { 17988 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 17989 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 17990 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 17991 if (!isDefaultmapKind || !isDefaultmapModifier) { 17992 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 17993 "'firstprivate', 'none', 'default'"; 17994 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 17995 if (!isDefaultmapKind && isDefaultmapModifier) { 17996 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17997 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17998 } else if (isDefaultmapKind && !isDefaultmapModifier) { 17999 Diag(MLoc, diag::err_omp_unexpected_clause_value) 18000 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 18001 } else { 18002 Diag(MLoc, diag::err_omp_unexpected_clause_value) 18003 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 18004 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18005 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 18006 } 18007 return nullptr; 18008 } 18009 18010 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 18011 // At most one defaultmap clause for each category can appear on the 18012 // directive. 18013 if (DSAStack->checkDefaultmapCategory(Kind)) { 18014 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 18015 return nullptr; 18016 } 18017 } 18018 if (Kind == OMPC_DEFAULTMAP_unknown) { 18019 // Variable category is not specified - mark all categories. 18020 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 18021 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 18022 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 18023 } else { 18024 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 18025 } 18026 18027 return new (Context) 18028 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 18029 } 18030 18031 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 18032 DeclContext *CurLexicalContext = getCurLexicalContext(); 18033 if (!CurLexicalContext->isFileContext() && 18034 !CurLexicalContext->isExternCContext() && 18035 !CurLexicalContext->isExternCXXContext() && 18036 !isa<CXXRecordDecl>(CurLexicalContext) && 18037 !isa<ClassTemplateDecl>(CurLexicalContext) && 18038 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 18039 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 18040 Diag(Loc, diag::err_omp_region_not_file_context); 18041 return false; 18042 } 18043 ++DeclareTargetNestingLevel; 18044 return true; 18045 } 18046 18047 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 18048 assert(DeclareTargetNestingLevel > 0 && 18049 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 18050 --DeclareTargetNestingLevel; 18051 } 18052 18053 NamedDecl * 18054 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 18055 const DeclarationNameInfo &Id, 18056 NamedDeclSetType &SameDirectiveDecls) { 18057 LookupResult Lookup(*this, Id, LookupOrdinaryName); 18058 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 18059 18060 if (Lookup.isAmbiguous()) 18061 return nullptr; 18062 Lookup.suppressDiagnostics(); 18063 18064 if (!Lookup.isSingleResult()) { 18065 VarOrFuncDeclFilterCCC CCC(*this); 18066 if (TypoCorrection Corrected = 18067 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 18068 CTK_ErrorRecovery)) { 18069 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 18070 << Id.getName()); 18071 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 18072 return nullptr; 18073 } 18074 18075 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 18076 return nullptr; 18077 } 18078 18079 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 18080 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 18081 !isa<FunctionTemplateDecl>(ND)) { 18082 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 18083 return nullptr; 18084 } 18085 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 18086 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 18087 return ND; 18088 } 18089 18090 void Sema::ActOnOpenMPDeclareTargetName( 18091 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 18092 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 18093 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 18094 isa<FunctionTemplateDecl>(ND)) && 18095 "Expected variable, function or function template."); 18096 18097 // Diagnose marking after use as it may lead to incorrect diagnosis and 18098 // codegen. 18099 if (LangOpts.OpenMP >= 50 && 18100 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 18101 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 18102 18103 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 18104 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 18105 if (DevTy.hasValue() && *DevTy != DT) { 18106 Diag(Loc, diag::err_omp_device_type_mismatch) 18107 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 18108 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 18109 return; 18110 } 18111 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18112 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 18113 if (!Res) { 18114 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 18115 SourceRange(Loc, Loc)); 18116 ND->addAttr(A); 18117 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18118 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 18119 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 18120 } else if (*Res != MT) { 18121 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 18122 } 18123 } 18124 18125 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 18126 Sema &SemaRef, Decl *D) { 18127 if (!D || !isa<VarDecl>(D)) 18128 return; 18129 auto *VD = cast<VarDecl>(D); 18130 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18131 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18132 if (SemaRef.LangOpts.OpenMP >= 50 && 18133 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 18134 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 18135 VD->hasGlobalStorage()) { 18136 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18137 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18138 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 18139 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 18140 // If a lambda declaration and definition appears between a 18141 // declare target directive and the matching end declare target 18142 // directive, all variables that are captured by the lambda 18143 // expression must also appear in a to clause. 18144 SemaRef.Diag(VD->getLocation(), 18145 diag::err_omp_lambda_capture_in_declare_target_not_to); 18146 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 18147 << VD << 0 << SR; 18148 return; 18149 } 18150 } 18151 if (MapTy.hasValue()) 18152 return; 18153 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 18154 SemaRef.Diag(SL, diag::note_used_here) << SR; 18155 } 18156 18157 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 18158 Sema &SemaRef, DSAStackTy *Stack, 18159 ValueDecl *VD) { 18160 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 18161 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 18162 /*FullCheck=*/false); 18163 } 18164 18165 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 18166 SourceLocation IdLoc) { 18167 if (!D || D->isInvalidDecl()) 18168 return; 18169 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 18170 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 18171 if (auto *VD = dyn_cast<VarDecl>(D)) { 18172 // Only global variables can be marked as declare target. 18173 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 18174 !VD->isStaticDataMember()) 18175 return; 18176 // 2.10.6: threadprivate variable cannot appear in a declare target 18177 // directive. 18178 if (DSAStack->isThreadPrivate(VD)) { 18179 Diag(SL, diag::err_omp_threadprivate_in_target); 18180 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 18181 return; 18182 } 18183 } 18184 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 18185 D = FTD->getTemplatedDecl(); 18186 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 18187 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18188 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 18189 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 18190 Diag(IdLoc, diag::err_omp_function_in_link_clause); 18191 Diag(FD->getLocation(), diag::note_defined_here) << FD; 18192 return; 18193 } 18194 } 18195 if (auto *VD = dyn_cast<ValueDecl>(D)) { 18196 // Problem if any with var declared with incomplete type will be reported 18197 // as normal, so no need to check it here. 18198 if ((E || !VD->getType()->isIncompleteType()) && 18199 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 18200 return; 18201 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 18202 // Checking declaration inside declare target region. 18203 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 18204 isa<FunctionTemplateDecl>(D)) { 18205 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 18206 Context, OMPDeclareTargetDeclAttr::MT_To, 18207 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 18208 D->addAttr(A); 18209 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18210 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 18211 } 18212 return; 18213 } 18214 } 18215 if (!E) 18216 return; 18217 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 18218 } 18219 18220 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 18221 CXXScopeSpec &MapperIdScopeSpec, 18222 DeclarationNameInfo &MapperId, 18223 const OMPVarListLocTy &Locs, 18224 ArrayRef<Expr *> UnresolvedMappers) { 18225 MappableVarListInfo MVLI(VarList); 18226 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 18227 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18228 if (MVLI.ProcessedVarList.empty()) 18229 return nullptr; 18230 18231 return OMPToClause::Create( 18232 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18233 MVLI.VarComponents, MVLI.UDMapperList, 18234 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18235 } 18236 18237 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 18238 CXXScopeSpec &MapperIdScopeSpec, 18239 DeclarationNameInfo &MapperId, 18240 const OMPVarListLocTy &Locs, 18241 ArrayRef<Expr *> UnresolvedMappers) { 18242 MappableVarListInfo MVLI(VarList); 18243 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 18244 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18245 if (MVLI.ProcessedVarList.empty()) 18246 return nullptr; 18247 18248 return OMPFromClause::Create( 18249 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18250 MVLI.VarComponents, MVLI.UDMapperList, 18251 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18252 } 18253 18254 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 18255 const OMPVarListLocTy &Locs) { 18256 MappableVarListInfo MVLI(VarList); 18257 SmallVector<Expr *, 8> PrivateCopies; 18258 SmallVector<Expr *, 8> Inits; 18259 18260 for (Expr *RefExpr : VarList) { 18261 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 18262 SourceLocation ELoc; 18263 SourceRange ERange; 18264 Expr *SimpleRefExpr = RefExpr; 18265 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18266 if (Res.second) { 18267 // It will be analyzed later. 18268 MVLI.ProcessedVarList.push_back(RefExpr); 18269 PrivateCopies.push_back(nullptr); 18270 Inits.push_back(nullptr); 18271 } 18272 ValueDecl *D = Res.first; 18273 if (!D) 18274 continue; 18275 18276 QualType Type = D->getType(); 18277 Type = Type.getNonReferenceType().getUnqualifiedType(); 18278 18279 auto *VD = dyn_cast<VarDecl>(D); 18280 18281 // Item should be a pointer or reference to pointer. 18282 if (!Type->isPointerType()) { 18283 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 18284 << 0 << RefExpr->getSourceRange(); 18285 continue; 18286 } 18287 18288 // Build the private variable and the expression that refers to it. 18289 auto VDPrivate = 18290 buildVarDecl(*this, ELoc, Type, D->getName(), 18291 D->hasAttrs() ? &D->getAttrs() : nullptr, 18292 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18293 if (VDPrivate->isInvalidDecl()) 18294 continue; 18295 18296 CurContext->addDecl(VDPrivate); 18297 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18298 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 18299 18300 // Add temporary variable to initialize the private copy of the pointer. 18301 VarDecl *VDInit = 18302 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 18303 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 18304 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 18305 AddInitializerToDecl(VDPrivate, 18306 DefaultLvalueConversion(VDInitRefExpr).get(), 18307 /*DirectInit=*/false); 18308 18309 // If required, build a capture to implement the privatization initialized 18310 // with the current list item value. 18311 DeclRefExpr *Ref = nullptr; 18312 if (!VD) 18313 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18314 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18315 PrivateCopies.push_back(VDPrivateRefExpr); 18316 Inits.push_back(VDInitRefExpr); 18317 18318 // We need to add a data sharing attribute for this variable to make sure it 18319 // is correctly captured. A variable that shows up in a use_device_ptr has 18320 // similar properties of a first private variable. 18321 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18322 18323 // Create a mappable component for the list item. List items in this clause 18324 // only need a component. 18325 MVLI.VarBaseDeclarations.push_back(D); 18326 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18327 MVLI.VarComponents.back().push_back( 18328 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 18329 } 18330 18331 if (MVLI.ProcessedVarList.empty()) 18332 return nullptr; 18333 18334 return OMPUseDevicePtrClause::Create( 18335 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 18336 MVLI.VarBaseDeclarations, MVLI.VarComponents); 18337 } 18338 18339 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 18340 const OMPVarListLocTy &Locs) { 18341 MappableVarListInfo MVLI(VarList); 18342 for (Expr *RefExpr : VarList) { 18343 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 18344 SourceLocation ELoc; 18345 SourceRange ERange; 18346 Expr *SimpleRefExpr = RefExpr; 18347 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18348 if (Res.second) { 18349 // It will be analyzed later. 18350 MVLI.ProcessedVarList.push_back(RefExpr); 18351 } 18352 ValueDecl *D = Res.first; 18353 if (!D) 18354 continue; 18355 18356 QualType Type = D->getType(); 18357 // item should be a pointer or array or reference to pointer or array 18358 if (!Type.getNonReferenceType()->isPointerType() && 18359 !Type.getNonReferenceType()->isArrayType()) { 18360 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 18361 << 0 << RefExpr->getSourceRange(); 18362 continue; 18363 } 18364 18365 // Check if the declaration in the clause does not show up in any data 18366 // sharing attribute. 18367 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18368 if (isOpenMPPrivate(DVar.CKind)) { 18369 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 18370 << getOpenMPClauseName(DVar.CKind) 18371 << getOpenMPClauseName(OMPC_is_device_ptr) 18372 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18373 reportOriginalDsa(*this, DSAStack, D, DVar); 18374 continue; 18375 } 18376 18377 const Expr *ConflictExpr; 18378 if (DSAStack->checkMappableExprComponentListsForDecl( 18379 D, /*CurrentRegionOnly=*/true, 18380 [&ConflictExpr]( 18381 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 18382 OpenMPClauseKind) -> bool { 18383 ConflictExpr = R.front().getAssociatedExpression(); 18384 return true; 18385 })) { 18386 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 18387 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 18388 << ConflictExpr->getSourceRange(); 18389 continue; 18390 } 18391 18392 // Store the components in the stack so that they can be used to check 18393 // against other clauses later on. 18394 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 18395 DSAStack->addMappableExpressionComponents( 18396 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 18397 18398 // Record the expression we've just processed. 18399 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 18400 18401 // Create a mappable component for the list item. List items in this clause 18402 // only need a component. We use a null declaration to signal fields in 18403 // 'this'. 18404 assert((isa<DeclRefExpr>(SimpleRefExpr) || 18405 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 18406 "Unexpected device pointer expression!"); 18407 MVLI.VarBaseDeclarations.push_back( 18408 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 18409 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18410 MVLI.VarComponents.back().push_back(MC); 18411 } 18412 18413 if (MVLI.ProcessedVarList.empty()) 18414 return nullptr; 18415 18416 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 18417 MVLI.VarBaseDeclarations, 18418 MVLI.VarComponents); 18419 } 18420 18421 OMPClause *Sema::ActOnOpenMPAllocateClause( 18422 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 18423 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 18424 if (Allocator) { 18425 // OpenMP [2.11.4 allocate Clause, Description] 18426 // allocator is an expression of omp_allocator_handle_t type. 18427 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 18428 return nullptr; 18429 18430 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 18431 if (AllocatorRes.isInvalid()) 18432 return nullptr; 18433 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 18434 DSAStack->getOMPAllocatorHandleT(), 18435 Sema::AA_Initializing, 18436 /*AllowExplicit=*/true); 18437 if (AllocatorRes.isInvalid()) 18438 return nullptr; 18439 Allocator = AllocatorRes.get(); 18440 } else { 18441 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 18442 // allocate clauses that appear on a target construct or on constructs in a 18443 // target region must specify an allocator expression unless a requires 18444 // directive with the dynamic_allocators clause is present in the same 18445 // compilation unit. 18446 if (LangOpts.OpenMPIsDevice && 18447 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 18448 targetDiag(StartLoc, diag::err_expected_allocator_expression); 18449 } 18450 // Analyze and build list of variables. 18451 SmallVector<Expr *, 8> Vars; 18452 for (Expr *RefExpr : VarList) { 18453 assert(RefExpr && "NULL expr in OpenMP private clause."); 18454 SourceLocation ELoc; 18455 SourceRange ERange; 18456 Expr *SimpleRefExpr = RefExpr; 18457 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18458 if (Res.second) { 18459 // It will be analyzed later. 18460 Vars.push_back(RefExpr); 18461 } 18462 ValueDecl *D = Res.first; 18463 if (!D) 18464 continue; 18465 18466 auto *VD = dyn_cast<VarDecl>(D); 18467 DeclRefExpr *Ref = nullptr; 18468 if (!VD && !CurContext->isDependentContext()) 18469 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 18470 Vars.push_back((VD || CurContext->isDependentContext()) 18471 ? RefExpr->IgnoreParens() 18472 : Ref); 18473 } 18474 18475 if (Vars.empty()) 18476 return nullptr; 18477 18478 if (Allocator) 18479 DSAStack->addInnerAllocatorExpr(Allocator); 18480 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 18481 ColonLoc, EndLoc, Vars); 18482 } 18483 18484 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 18485 SourceLocation StartLoc, 18486 SourceLocation LParenLoc, 18487 SourceLocation EndLoc) { 18488 SmallVector<Expr *, 8> Vars; 18489 for (Expr *RefExpr : VarList) { 18490 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18491 SourceLocation ELoc; 18492 SourceRange ERange; 18493 Expr *SimpleRefExpr = RefExpr; 18494 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18495 if (Res.second) 18496 // It will be analyzed later. 18497 Vars.push_back(RefExpr); 18498 ValueDecl *D = Res.first; 18499 if (!D) 18500 continue; 18501 18502 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 18503 // A list-item cannot appear in more than one nontemporal clause. 18504 if (const Expr *PrevRef = 18505 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 18506 Diag(ELoc, diag::err_omp_used_in_clause_twice) 18507 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 18508 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 18509 << getOpenMPClauseName(OMPC_nontemporal); 18510 continue; 18511 } 18512 18513 Vars.push_back(RefExpr); 18514 } 18515 18516 if (Vars.empty()) 18517 return nullptr; 18518 18519 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18520 Vars); 18521 } 18522 18523 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 18524 SourceLocation StartLoc, 18525 SourceLocation LParenLoc, 18526 SourceLocation EndLoc) { 18527 SmallVector<Expr *, 8> Vars; 18528 for (Expr *RefExpr : VarList) { 18529 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18530 SourceLocation ELoc; 18531 SourceRange ERange; 18532 Expr *SimpleRefExpr = RefExpr; 18533 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18534 /*AllowArraySection=*/true); 18535 if (Res.second) 18536 // It will be analyzed later. 18537 Vars.push_back(RefExpr); 18538 ValueDecl *D = Res.first; 18539 if (!D) 18540 continue; 18541 18542 const DSAStackTy::DSAVarData DVar = 18543 DSAStack->getTopDSA(D, /*FromParent=*/true); 18544 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18545 // A list item that appears in the inclusive or exclusive clause must appear 18546 // in a reduction clause with the inscan modifier on the enclosing 18547 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18548 if (DVar.CKind != OMPC_reduction || 18549 DVar.Modifier != OMPC_REDUCTION_inscan) 18550 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18551 << RefExpr->getSourceRange(); 18552 18553 if (DSAStack->getParentDirective() != OMPD_unknown) 18554 DSAStack->markDeclAsUsedInScanDirective(D); 18555 Vars.push_back(RefExpr); 18556 } 18557 18558 if (Vars.empty()) 18559 return nullptr; 18560 18561 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18562 } 18563 18564 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 18565 SourceLocation StartLoc, 18566 SourceLocation LParenLoc, 18567 SourceLocation EndLoc) { 18568 SmallVector<Expr *, 8> Vars; 18569 for (Expr *RefExpr : VarList) { 18570 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18571 SourceLocation ELoc; 18572 SourceRange ERange; 18573 Expr *SimpleRefExpr = RefExpr; 18574 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18575 /*AllowArraySection=*/true); 18576 if (Res.second) 18577 // It will be analyzed later. 18578 Vars.push_back(RefExpr); 18579 ValueDecl *D = Res.first; 18580 if (!D) 18581 continue; 18582 18583 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 18584 DSAStackTy::DSAVarData DVar; 18585 if (ParentDirective != OMPD_unknown) 18586 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 18587 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18588 // A list item that appears in the inclusive or exclusive clause must appear 18589 // in a reduction clause with the inscan modifier on the enclosing 18590 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18591 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 18592 DVar.Modifier != OMPC_REDUCTION_inscan) { 18593 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18594 << RefExpr->getSourceRange(); 18595 } else { 18596 DSAStack->markDeclAsUsedInScanDirective(D); 18597 } 18598 Vars.push_back(RefExpr); 18599 } 18600 18601 if (Vars.empty()) 18602 return nullptr; 18603 18604 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18605 } 18606 18607 /// Tries to find omp_alloctrait_t type. 18608 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 18609 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 18610 if (!OMPAlloctraitT.isNull()) 18611 return true; 18612 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 18613 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 18614 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 18615 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 18616 return false; 18617 } 18618 Stack->setOMPAlloctraitT(PT.get()); 18619 return true; 18620 } 18621 18622 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 18623 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 18624 ArrayRef<UsesAllocatorsData> Data) { 18625 // OpenMP [2.12.5, target Construct] 18626 // allocator is an identifier of omp_allocator_handle_t type. 18627 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 18628 return nullptr; 18629 // OpenMP [2.12.5, target Construct] 18630 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 18631 if (llvm::any_of( 18632 Data, 18633 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 18634 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 18635 return nullptr; 18636 llvm::SmallSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 18637 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 18638 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 18639 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 18640 StringRef Allocator = 18641 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 18642 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 18643 PredefinedAllocators.insert(LookupSingleName( 18644 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 18645 } 18646 18647 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 18648 for (const UsesAllocatorsData &D : Data) { 18649 Expr *AllocatorExpr = nullptr; 18650 // Check allocator expression. 18651 if (D.Allocator->isTypeDependent()) { 18652 AllocatorExpr = D.Allocator; 18653 } else { 18654 // Traits were specified - need to assign new allocator to the specified 18655 // allocator, so it must be an lvalue. 18656 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 18657 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 18658 bool IsPredefinedAllocator = false; 18659 if (DRE) 18660 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); 18661 if (!DRE || 18662 !(Context.hasSameUnqualifiedType( 18663 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) || 18664 Context.typesAreCompatible(AllocatorExpr->getType(), 18665 DSAStack->getOMPAllocatorHandleT(), 18666 /*CompareUnqualified=*/true)) || 18667 (!IsPredefinedAllocator && 18668 (AllocatorExpr->getType().isConstant(Context) || 18669 !AllocatorExpr->isLValue()))) { 18670 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 18671 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 18672 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 18673 continue; 18674 } 18675 // OpenMP [2.12.5, target Construct] 18676 // Predefined allocators appearing in a uses_allocators clause cannot have 18677 // traits specified. 18678 if (IsPredefinedAllocator && D.AllocatorTraits) { 18679 Diag(D.AllocatorTraits->getExprLoc(), 18680 diag::err_omp_predefined_allocator_with_traits) 18681 << D.AllocatorTraits->getSourceRange(); 18682 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 18683 << cast<NamedDecl>(DRE->getDecl())->getName() 18684 << D.Allocator->getSourceRange(); 18685 continue; 18686 } 18687 // OpenMP [2.12.5, target Construct] 18688 // Non-predefined allocators appearing in a uses_allocators clause must 18689 // have traits specified. 18690 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 18691 Diag(D.Allocator->getExprLoc(), 18692 diag::err_omp_nonpredefined_allocator_without_traits); 18693 continue; 18694 } 18695 // No allocator traits - just convert it to rvalue. 18696 if (!D.AllocatorTraits) 18697 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 18698 DSAStack->addUsesAllocatorsDecl(DRE->getDecl()); 18699 } 18700 Expr *AllocatorTraitsExpr = nullptr; 18701 if (D.AllocatorTraits) { 18702 if (D.AllocatorTraits->isTypeDependent()) { 18703 AllocatorTraitsExpr = D.AllocatorTraits; 18704 } else { 18705 // OpenMP [2.12.5, target Construct] 18706 // Arrays that contain allocator traits that appear in a uses_allocators 18707 // clause must be constant arrays, have constant values and be defined 18708 // in the same scope as the construct in which the clause appears. 18709 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 18710 // Check that traits expr is a constant array. 18711 QualType TraitTy; 18712 if (const ArrayType *Ty = 18713 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 18714 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 18715 TraitTy = ConstArrayTy->getElementType(); 18716 if (TraitTy.isNull() || 18717 !(Context.hasSameUnqualifiedType(TraitTy, 18718 DSAStack->getOMPAlloctraitT()) || 18719 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 18720 /*CompareUnqualified=*/true))) { 18721 Diag(D.AllocatorTraits->getExprLoc(), 18722 diag::err_omp_expected_array_alloctraits) 18723 << AllocatorTraitsExpr->getType(); 18724 continue; 18725 } 18726 } 18727 } 18728 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 18729 NewD.Allocator = AllocatorExpr; 18730 NewD.AllocatorTraits = AllocatorTraitsExpr; 18731 NewD.LParenLoc = D.LParenLoc; 18732 NewD.RParenLoc = D.RParenLoc; 18733 } 18734 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18735 NewData); 18736 } 18737