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::OMPNullMemAlloc; 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 = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2919 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2920 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2921 llvm::FoldingSetNodeID AEId, DAEId; 2922 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2923 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2924 if (AEId == DAEId) { 2925 AllocatorKindRes = AllocatorKind; 2926 break; 2927 } 2928 } 2929 return AllocatorKindRes; 2930 } 2931 2932 static bool checkPreviousOMPAllocateAttribute( 2933 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 2934 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 2935 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 2936 return false; 2937 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2938 Expr *PrevAllocator = A->getAllocator(); 2939 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2940 getAllocatorKind(S, Stack, PrevAllocator); 2941 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2942 if (AllocatorsMatch && 2943 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 2944 Allocator && PrevAllocator) { 2945 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2946 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2947 llvm::FoldingSetNodeID AEId, PAEId; 2948 AE->Profile(AEId, S.Context, /*Canonical=*/true); 2949 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 2950 AllocatorsMatch = AEId == PAEId; 2951 } 2952 if (!AllocatorsMatch) { 2953 SmallString<256> AllocatorBuffer; 2954 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2955 if (Allocator) 2956 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 2957 SmallString<256> PrevAllocatorBuffer; 2958 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2959 if (PrevAllocator) 2960 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2961 S.getPrintingPolicy()); 2962 2963 SourceLocation AllocatorLoc = 2964 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2965 SourceRange AllocatorRange = 2966 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2967 SourceLocation PrevAllocatorLoc = 2968 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2969 SourceRange PrevAllocatorRange = 2970 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2971 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2972 << (Allocator ? 1 : 0) << AllocatorStream.str() 2973 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2974 << AllocatorRange; 2975 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2976 << PrevAllocatorRange; 2977 return true; 2978 } 2979 return false; 2980 } 2981 2982 static void 2983 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 2984 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 2985 Expr *Allocator, SourceRange SR) { 2986 if (VD->hasAttr<OMPAllocateDeclAttr>()) 2987 return; 2988 if (Allocator && 2989 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2990 Allocator->isInstantiationDependent() || 2991 Allocator->containsUnexpandedParameterPack())) 2992 return; 2993 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 2994 Allocator, SR); 2995 VD->addAttr(A); 2996 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 2997 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2998 } 2999 3000 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 3001 SourceLocation Loc, ArrayRef<Expr *> VarList, 3002 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 3003 assert(Clauses.size() <= 1 && "Expected at most one clause."); 3004 Expr *Allocator = nullptr; 3005 if (Clauses.empty()) { 3006 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 3007 // allocate directives that appear in a target region must specify an 3008 // allocator clause unless a requires directive with the dynamic_allocators 3009 // clause is present in the same compilation unit. 3010 if (LangOpts.OpenMPIsDevice && 3011 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 3012 targetDiag(Loc, diag::err_expected_allocator_clause); 3013 } else { 3014 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 3015 } 3016 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3017 getAllocatorKind(*this, DSAStack, Allocator); 3018 SmallVector<Expr *, 8> Vars; 3019 for (Expr *RefExpr : VarList) { 3020 auto *DE = cast<DeclRefExpr>(RefExpr); 3021 auto *VD = cast<VarDecl>(DE->getDecl()); 3022 3023 // Check if this is a TLS variable or global register. 3024 if (VD->getTLSKind() != VarDecl::TLS_None || 3025 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 3026 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3027 !VD->isLocalVarDecl())) 3028 continue; 3029 3030 // If the used several times in the allocate directive, the same allocator 3031 // must be used. 3032 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 3033 AllocatorKind, Allocator)) 3034 continue; 3035 3036 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 3037 // If a list item has a static storage type, the allocator expression in the 3038 // allocator clause must be a constant expression that evaluates to one of 3039 // the predefined memory allocator values. 3040 if (Allocator && VD->hasGlobalStorage()) { 3041 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 3042 Diag(Allocator->getExprLoc(), 3043 diag::err_omp_expected_predefined_allocator) 3044 << Allocator->getSourceRange(); 3045 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 3046 VarDecl::DeclarationOnly; 3047 Diag(VD->getLocation(), 3048 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3049 << VD; 3050 continue; 3051 } 3052 } 3053 3054 Vars.push_back(RefExpr); 3055 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, 3056 DE->getSourceRange()); 3057 } 3058 if (Vars.empty()) 3059 return nullptr; 3060 if (!Owner) 3061 Owner = getCurLexicalContext(); 3062 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 3063 D->setAccess(AS_public); 3064 Owner->addDecl(D); 3065 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3066 } 3067 3068 Sema::DeclGroupPtrTy 3069 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 3070 ArrayRef<OMPClause *> ClauseList) { 3071 OMPRequiresDecl *D = nullptr; 3072 if (!CurContext->isFileContext()) { 3073 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 3074 } else { 3075 D = CheckOMPRequiresDecl(Loc, ClauseList); 3076 if (D) { 3077 CurContext->addDecl(D); 3078 DSAStack->addRequiresDecl(D); 3079 } 3080 } 3081 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3082 } 3083 3084 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 3085 ArrayRef<OMPClause *> ClauseList) { 3086 /// For target specific clauses, the requires directive cannot be 3087 /// specified after the handling of any of the target regions in the 3088 /// current compilation unit. 3089 ArrayRef<SourceLocation> TargetLocations = 3090 DSAStack->getEncounteredTargetLocs(); 3091 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 3092 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 3093 for (const OMPClause *CNew : ClauseList) { 3094 // Check if any of the requires clauses affect target regions. 3095 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 3096 isa<OMPUnifiedAddressClause>(CNew) || 3097 isa<OMPReverseOffloadClause>(CNew) || 3098 isa<OMPDynamicAllocatorsClause>(CNew)) { 3099 Diag(Loc, diag::err_omp_directive_before_requires) 3100 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 3101 for (SourceLocation TargetLoc : TargetLocations) { 3102 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 3103 << "target"; 3104 } 3105 } else if (!AtomicLoc.isInvalid() && 3106 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 3107 Diag(Loc, diag::err_omp_directive_before_requires) 3108 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 3109 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 3110 << "atomic"; 3111 } 3112 } 3113 } 3114 3115 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 3116 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3117 ClauseList); 3118 return nullptr; 3119 } 3120 3121 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3122 const ValueDecl *D, 3123 const DSAStackTy::DSAVarData &DVar, 3124 bool IsLoopIterVar) { 3125 if (DVar.RefExpr) { 3126 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3127 << getOpenMPClauseName(DVar.CKind); 3128 return; 3129 } 3130 enum { 3131 PDSA_StaticMemberShared, 3132 PDSA_StaticLocalVarShared, 3133 PDSA_LoopIterVarPrivate, 3134 PDSA_LoopIterVarLinear, 3135 PDSA_LoopIterVarLastprivate, 3136 PDSA_ConstVarShared, 3137 PDSA_GlobalVarShared, 3138 PDSA_TaskVarFirstprivate, 3139 PDSA_LocalVarPrivate, 3140 PDSA_Implicit 3141 } Reason = PDSA_Implicit; 3142 bool ReportHint = false; 3143 auto ReportLoc = D->getLocation(); 3144 auto *VD = dyn_cast<VarDecl>(D); 3145 if (IsLoopIterVar) { 3146 if (DVar.CKind == OMPC_private) 3147 Reason = PDSA_LoopIterVarPrivate; 3148 else if (DVar.CKind == OMPC_lastprivate) 3149 Reason = PDSA_LoopIterVarLastprivate; 3150 else 3151 Reason = PDSA_LoopIterVarLinear; 3152 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3153 DVar.CKind == OMPC_firstprivate) { 3154 Reason = PDSA_TaskVarFirstprivate; 3155 ReportLoc = DVar.ImplicitDSALoc; 3156 } else if (VD && VD->isStaticLocal()) 3157 Reason = PDSA_StaticLocalVarShared; 3158 else if (VD && VD->isStaticDataMember()) 3159 Reason = PDSA_StaticMemberShared; 3160 else if (VD && VD->isFileVarDecl()) 3161 Reason = PDSA_GlobalVarShared; 3162 else if (D->getType().isConstant(SemaRef.getASTContext())) 3163 Reason = PDSA_ConstVarShared; 3164 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3165 ReportHint = true; 3166 Reason = PDSA_LocalVarPrivate; 3167 } 3168 if (Reason != PDSA_Implicit) { 3169 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3170 << Reason << ReportHint 3171 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3172 } else if (DVar.ImplicitDSALoc.isValid()) { 3173 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3174 << getOpenMPClauseName(DVar.CKind); 3175 } 3176 } 3177 3178 static OpenMPMapClauseKind 3179 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3180 bool IsAggregateOrDeclareTarget) { 3181 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3182 switch (M) { 3183 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3184 Kind = OMPC_MAP_alloc; 3185 break; 3186 case OMPC_DEFAULTMAP_MODIFIER_to: 3187 Kind = OMPC_MAP_to; 3188 break; 3189 case OMPC_DEFAULTMAP_MODIFIER_from: 3190 Kind = OMPC_MAP_from; 3191 break; 3192 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3193 Kind = OMPC_MAP_tofrom; 3194 break; 3195 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3196 case OMPC_DEFAULTMAP_MODIFIER_last: 3197 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3198 case OMPC_DEFAULTMAP_MODIFIER_none: 3199 case OMPC_DEFAULTMAP_MODIFIER_default: 3200 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3201 // IsAggregateOrDeclareTarget could be true if: 3202 // 1. the implicit behavior for aggregate is tofrom 3203 // 2. it's a declare target link 3204 if (IsAggregateOrDeclareTarget) { 3205 Kind = OMPC_MAP_tofrom; 3206 break; 3207 } 3208 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3209 } 3210 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3211 return Kind; 3212 } 3213 3214 namespace { 3215 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3216 DSAStackTy *Stack; 3217 Sema &SemaRef; 3218 bool ErrorFound = false; 3219 bool TryCaptureCXXThisMembers = false; 3220 CapturedStmt *CS = nullptr; 3221 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3222 llvm::SmallVector<Expr *, 4> ImplicitMap[OMPC_MAP_delete]; 3223 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3224 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3225 3226 void VisitSubCaptures(OMPExecutableDirective *S) { 3227 // Check implicitly captured variables. 3228 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 3229 return; 3230 visitSubCaptures(S->getInnermostCapturedStmt()); 3231 // Try to capture inner this->member references to generate correct mappings 3232 // and diagnostics. 3233 if (TryCaptureCXXThisMembers || 3234 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3235 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3236 [](const CapturedStmt::Capture &C) { 3237 return C.capturesThis(); 3238 }))) { 3239 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3240 TryCaptureCXXThisMembers = true; 3241 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3242 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3243 } 3244 // In tasks firstprivates are not captured anymore, need to analyze them 3245 // explicitly. 3246 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3247 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3248 for (OMPClause *C : S->clauses()) 3249 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3250 for (Expr *Ref : FC->varlists()) 3251 Visit(Ref); 3252 } 3253 } 3254 } 3255 3256 public: 3257 void VisitDeclRefExpr(DeclRefExpr *E) { 3258 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3259 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3260 E->isInstantiationDependent()) 3261 return; 3262 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3263 // Check the datasharing rules for the expressions in the clauses. 3264 if (!CS) { 3265 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3266 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3267 Visit(CED->getInit()); 3268 return; 3269 } 3270 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3271 // Do not analyze internal variables and do not enclose them into 3272 // implicit clauses. 3273 return; 3274 VD = VD->getCanonicalDecl(); 3275 // Skip internally declared variables. 3276 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3277 !Stack->isImplicitTaskFirstprivate(VD)) 3278 return; 3279 // Skip allocators in uses_allocators clauses. 3280 if (Stack->isUsesAllocatorsDecl(VD)) 3281 return; 3282 3283 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3284 // Check if the variable has explicit DSA set and stop analysis if it so. 3285 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3286 return; 3287 3288 // Skip internally declared static variables. 3289 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3290 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3291 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3292 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3293 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3294 !Stack->isImplicitTaskFirstprivate(VD)) 3295 return; 3296 3297 SourceLocation ELoc = E->getExprLoc(); 3298 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3299 // The default(none) clause requires that each variable that is referenced 3300 // in the construct, and does not have a predetermined data-sharing 3301 // attribute, must have its data-sharing attribute explicitly determined 3302 // by being listed in a data-sharing attribute clause. 3303 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 3304 isImplicitOrExplicitTaskingRegion(DKind) && 3305 VarsWithInheritedDSA.count(VD) == 0) { 3306 VarsWithInheritedDSA[VD] = E; 3307 return; 3308 } 3309 3310 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3311 // If implicit-behavior is none, each variable referenced in the 3312 // construct that does not have a predetermined data-sharing attribute 3313 // and does not appear in a to or link clause on a declare target 3314 // directive must be listed in a data-mapping attribute clause, a 3315 // data-haring attribute clause (including a data-sharing attribute 3316 // clause on a combined construct where target. is one of the 3317 // constituent constructs), or an is_device_ptr clause. 3318 OpenMPDefaultmapClauseKind ClauseKind = 3319 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3320 if (SemaRef.getLangOpts().OpenMP >= 50) { 3321 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3322 OMPC_DEFAULTMAP_MODIFIER_none; 3323 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3324 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3325 // Only check for data-mapping attribute and is_device_ptr here 3326 // since we have already make sure that the declaration does not 3327 // have a data-sharing attribute above 3328 if (!Stack->checkMappableExprComponentListsForDecl( 3329 VD, /*CurrentRegionOnly=*/true, 3330 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3331 MapExprComponents, 3332 OpenMPClauseKind) { 3333 auto MI = MapExprComponents.rbegin(); 3334 auto ME = MapExprComponents.rend(); 3335 return MI != ME && MI->getAssociatedDeclaration() == VD; 3336 })) { 3337 VarsWithInheritedDSA[VD] = E; 3338 return; 3339 } 3340 } 3341 } 3342 3343 if (isOpenMPTargetExecutionDirective(DKind) && 3344 !Stack->isLoopControlVariable(VD).first) { 3345 if (!Stack->checkMappableExprComponentListsForDecl( 3346 VD, /*CurrentRegionOnly=*/true, 3347 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3348 StackComponents, 3349 OpenMPClauseKind) { 3350 // Variable is used if it has been marked as an array, array 3351 // section, array shaping or the variable iself. 3352 return StackComponents.size() == 1 || 3353 std::all_of( 3354 std::next(StackComponents.rbegin()), 3355 StackComponents.rend(), 3356 [](const OMPClauseMappableExprCommon:: 3357 MappableComponent &MC) { 3358 return MC.getAssociatedDeclaration() == 3359 nullptr && 3360 (isa<OMPArraySectionExpr>( 3361 MC.getAssociatedExpression()) || 3362 isa<OMPArrayShapingExpr>( 3363 MC.getAssociatedExpression()) || 3364 isa<ArraySubscriptExpr>( 3365 MC.getAssociatedExpression())); 3366 }); 3367 })) { 3368 bool IsFirstprivate = false; 3369 // By default lambdas are captured as firstprivates. 3370 if (const auto *RD = 3371 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3372 IsFirstprivate = RD->isLambda(); 3373 IsFirstprivate = 3374 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3375 if (IsFirstprivate) { 3376 ImplicitFirstprivate.emplace_back(E); 3377 } else { 3378 OpenMPDefaultmapClauseModifier M = 3379 Stack->getDefaultmapModifier(ClauseKind); 3380 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3381 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3382 ImplicitMap[Kind].emplace_back(E); 3383 } 3384 return; 3385 } 3386 } 3387 3388 // OpenMP [2.9.3.6, Restrictions, p.2] 3389 // A list item that appears in a reduction clause of the innermost 3390 // enclosing worksharing or parallel construct may not be accessed in an 3391 // explicit task. 3392 DVar = Stack->hasInnermostDSA( 3393 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3394 [](OpenMPDirectiveKind K) { 3395 return isOpenMPParallelDirective(K) || 3396 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3397 }, 3398 /*FromParent=*/true); 3399 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3400 ErrorFound = true; 3401 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3402 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3403 return; 3404 } 3405 3406 // Define implicit data-sharing attributes for task. 3407 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3408 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3409 !Stack->isLoopControlVariable(VD).first) { 3410 ImplicitFirstprivate.push_back(E); 3411 return; 3412 } 3413 3414 // Store implicitly used globals with declare target link for parent 3415 // target. 3416 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3417 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3418 Stack->addToParentTargetRegionLinkGlobals(E); 3419 return; 3420 } 3421 } 3422 } 3423 void VisitMemberExpr(MemberExpr *E) { 3424 if (E->isTypeDependent() || E->isValueDependent() || 3425 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3426 return; 3427 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3428 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3429 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3430 if (!FD) 3431 return; 3432 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3433 // Check if the variable has explicit DSA set and stop analysis if it 3434 // so. 3435 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3436 return; 3437 3438 if (isOpenMPTargetExecutionDirective(DKind) && 3439 !Stack->isLoopControlVariable(FD).first && 3440 !Stack->checkMappableExprComponentListsForDecl( 3441 FD, /*CurrentRegionOnly=*/true, 3442 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3443 StackComponents, 3444 OpenMPClauseKind) { 3445 return isa<CXXThisExpr>( 3446 cast<MemberExpr>( 3447 StackComponents.back().getAssociatedExpression()) 3448 ->getBase() 3449 ->IgnoreParens()); 3450 })) { 3451 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3452 // A bit-field cannot appear in a map clause. 3453 // 3454 if (FD->isBitField()) 3455 return; 3456 3457 // Check to see if the member expression is referencing a class that 3458 // has already been explicitly mapped 3459 if (Stack->isClassPreviouslyMapped(TE->getType())) 3460 return; 3461 3462 OpenMPDefaultmapClauseModifier Modifier = 3463 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3464 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3465 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3466 ImplicitMap[Kind].emplace_back(E); 3467 return; 3468 } 3469 3470 SourceLocation ELoc = E->getExprLoc(); 3471 // OpenMP [2.9.3.6, Restrictions, p.2] 3472 // A list item that appears in a reduction clause of the innermost 3473 // enclosing worksharing or parallel construct may not be accessed in 3474 // an explicit task. 3475 DVar = Stack->hasInnermostDSA( 3476 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 3477 [](OpenMPDirectiveKind K) { 3478 return isOpenMPParallelDirective(K) || 3479 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3480 }, 3481 /*FromParent=*/true); 3482 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3483 ErrorFound = true; 3484 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3485 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3486 return; 3487 } 3488 3489 // Define implicit data-sharing attributes for task. 3490 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3491 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3492 !Stack->isLoopControlVariable(FD).first) { 3493 // Check if there is a captured expression for the current field in the 3494 // region. Do not mark it as firstprivate unless there is no captured 3495 // expression. 3496 // TODO: try to make it firstprivate. 3497 if (DVar.CKind != OMPC_unknown) 3498 ImplicitFirstprivate.push_back(E); 3499 } 3500 return; 3501 } 3502 if (isOpenMPTargetExecutionDirective(DKind)) { 3503 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3504 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3505 /*NoDiagnose=*/true)) 3506 return; 3507 const auto *VD = cast<ValueDecl>( 3508 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3509 if (!Stack->checkMappableExprComponentListsForDecl( 3510 VD, /*CurrentRegionOnly=*/true, 3511 [&CurComponents]( 3512 OMPClauseMappableExprCommon::MappableExprComponentListRef 3513 StackComponents, 3514 OpenMPClauseKind) { 3515 auto CCI = CurComponents.rbegin(); 3516 auto CCE = CurComponents.rend(); 3517 for (const auto &SC : llvm::reverse(StackComponents)) { 3518 // Do both expressions have the same kind? 3519 if (CCI->getAssociatedExpression()->getStmtClass() != 3520 SC.getAssociatedExpression()->getStmtClass()) 3521 if (!((isa<OMPArraySectionExpr>( 3522 SC.getAssociatedExpression()) || 3523 isa<OMPArrayShapingExpr>( 3524 SC.getAssociatedExpression())) && 3525 isa<ArraySubscriptExpr>( 3526 CCI->getAssociatedExpression()))) 3527 return false; 3528 3529 const Decl *CCD = CCI->getAssociatedDeclaration(); 3530 const Decl *SCD = SC.getAssociatedDeclaration(); 3531 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3532 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3533 if (SCD != CCD) 3534 return false; 3535 std::advance(CCI, 1); 3536 if (CCI == CCE) 3537 break; 3538 } 3539 return true; 3540 })) { 3541 Visit(E->getBase()); 3542 } 3543 } else if (!TryCaptureCXXThisMembers) { 3544 Visit(E->getBase()); 3545 } 3546 } 3547 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3548 for (OMPClause *C : S->clauses()) { 3549 // Skip analysis of arguments of implicitly defined firstprivate clause 3550 // for task|target directives. 3551 // Skip analysis of arguments of implicitly defined map clause for target 3552 // directives. 3553 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3554 C->isImplicit())) { 3555 for (Stmt *CC : C->children()) { 3556 if (CC) 3557 Visit(CC); 3558 } 3559 } 3560 } 3561 // Check implicitly captured variables. 3562 VisitSubCaptures(S); 3563 } 3564 void VisitStmt(Stmt *S) { 3565 for (Stmt *C : S->children()) { 3566 if (C) { 3567 // Check implicitly captured variables in the task-based directives to 3568 // check if they must be firstprivatized. 3569 Visit(C); 3570 } 3571 } 3572 } 3573 3574 void visitSubCaptures(CapturedStmt *S) { 3575 for (const CapturedStmt::Capture &Cap : S->captures()) { 3576 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3577 continue; 3578 VarDecl *VD = Cap.getCapturedVar(); 3579 // Do not try to map the variable if it or its sub-component was mapped 3580 // already. 3581 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3582 Stack->checkMappableExprComponentListsForDecl( 3583 VD, /*CurrentRegionOnly=*/true, 3584 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3585 OpenMPClauseKind) { return true; })) 3586 continue; 3587 DeclRefExpr *DRE = buildDeclRefExpr( 3588 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3589 Cap.getLocation(), /*RefersToCapture=*/true); 3590 Visit(DRE); 3591 } 3592 } 3593 bool isErrorFound() const { return ErrorFound; } 3594 ArrayRef<Expr *> getImplicitFirstprivate() const { 3595 return ImplicitFirstprivate; 3596 } 3597 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind Kind) const { 3598 return ImplicitMap[Kind]; 3599 } 3600 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3601 return VarsWithInheritedDSA; 3602 } 3603 3604 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3605 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3606 // Process declare target link variables for the target directives. 3607 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3608 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3609 Visit(E); 3610 } 3611 } 3612 }; 3613 } // namespace 3614 3615 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3616 switch (DKind) { 3617 case OMPD_parallel: 3618 case OMPD_parallel_for: 3619 case OMPD_parallel_for_simd: 3620 case OMPD_parallel_sections: 3621 case OMPD_parallel_master: 3622 case OMPD_teams: 3623 case OMPD_teams_distribute: 3624 case OMPD_teams_distribute_simd: { 3625 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3626 QualType KmpInt32PtrTy = 3627 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3628 Sema::CapturedParamNameType Params[] = { 3629 std::make_pair(".global_tid.", KmpInt32PtrTy), 3630 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3631 std::make_pair(StringRef(), QualType()) // __context with shared vars 3632 }; 3633 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3634 Params); 3635 break; 3636 } 3637 case OMPD_target_teams: 3638 case OMPD_target_parallel: 3639 case OMPD_target_parallel_for: 3640 case OMPD_target_parallel_for_simd: 3641 case OMPD_target_teams_distribute: 3642 case OMPD_target_teams_distribute_simd: { 3643 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3644 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3645 QualType KmpInt32PtrTy = 3646 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3647 QualType Args[] = {VoidPtrTy}; 3648 FunctionProtoType::ExtProtoInfo EPI; 3649 EPI.Variadic = true; 3650 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3651 Sema::CapturedParamNameType Params[] = { 3652 std::make_pair(".global_tid.", KmpInt32Ty), 3653 std::make_pair(".part_id.", KmpInt32PtrTy), 3654 std::make_pair(".privates.", VoidPtrTy), 3655 std::make_pair( 3656 ".copy_fn.", 3657 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3658 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3659 std::make_pair(StringRef(), QualType()) // __context with shared vars 3660 }; 3661 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3662 Params, /*OpenMPCaptureLevel=*/0); 3663 // Mark this captured region as inlined, because we don't use outlined 3664 // function directly. 3665 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3666 AlwaysInlineAttr::CreateImplicit( 3667 Context, {}, AttributeCommonInfo::AS_Keyword, 3668 AlwaysInlineAttr::Keyword_forceinline)); 3669 Sema::CapturedParamNameType ParamsTarget[] = { 3670 std::make_pair(StringRef(), QualType()) // __context with shared vars 3671 }; 3672 // Start a captured region for 'target' with no implicit parameters. 3673 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3674 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3675 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 3676 std::make_pair(".global_tid.", KmpInt32PtrTy), 3677 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3678 std::make_pair(StringRef(), QualType()) // __context with shared vars 3679 }; 3680 // Start a captured region for 'teams' or 'parallel'. Both regions have 3681 // the same implicit parameters. 3682 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3683 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 3684 break; 3685 } 3686 case OMPD_target: 3687 case OMPD_target_simd: { 3688 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3689 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3690 QualType KmpInt32PtrTy = 3691 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3692 QualType Args[] = {VoidPtrTy}; 3693 FunctionProtoType::ExtProtoInfo EPI; 3694 EPI.Variadic = true; 3695 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3696 Sema::CapturedParamNameType Params[] = { 3697 std::make_pair(".global_tid.", KmpInt32Ty), 3698 std::make_pair(".part_id.", KmpInt32PtrTy), 3699 std::make_pair(".privates.", VoidPtrTy), 3700 std::make_pair( 3701 ".copy_fn.", 3702 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3703 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3704 std::make_pair(StringRef(), QualType()) // __context with shared vars 3705 }; 3706 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3707 Params, /*OpenMPCaptureLevel=*/0); 3708 // Mark this captured region as inlined, because we don't use outlined 3709 // function directly. 3710 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3711 AlwaysInlineAttr::CreateImplicit( 3712 Context, {}, AttributeCommonInfo::AS_Keyword, 3713 AlwaysInlineAttr::Keyword_forceinline)); 3714 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3715 std::make_pair(StringRef(), QualType()), 3716 /*OpenMPCaptureLevel=*/1); 3717 break; 3718 } 3719 case OMPD_simd: 3720 case OMPD_for: 3721 case OMPD_for_simd: 3722 case OMPD_sections: 3723 case OMPD_section: 3724 case OMPD_single: 3725 case OMPD_master: 3726 case OMPD_critical: 3727 case OMPD_taskgroup: 3728 case OMPD_distribute: 3729 case OMPD_distribute_simd: 3730 case OMPD_ordered: 3731 case OMPD_atomic: 3732 case OMPD_target_data: { 3733 Sema::CapturedParamNameType Params[] = { 3734 std::make_pair(StringRef(), QualType()) // __context with shared vars 3735 }; 3736 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3737 Params); 3738 break; 3739 } 3740 case OMPD_task: { 3741 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3742 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3743 QualType KmpInt32PtrTy = 3744 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3745 QualType Args[] = {VoidPtrTy}; 3746 FunctionProtoType::ExtProtoInfo EPI; 3747 EPI.Variadic = true; 3748 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3749 Sema::CapturedParamNameType Params[] = { 3750 std::make_pair(".global_tid.", KmpInt32Ty), 3751 std::make_pair(".part_id.", KmpInt32PtrTy), 3752 std::make_pair(".privates.", VoidPtrTy), 3753 std::make_pair( 3754 ".copy_fn.", 3755 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3756 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3757 std::make_pair(StringRef(), QualType()) // __context with shared vars 3758 }; 3759 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3760 Params); 3761 // Mark this captured region as inlined, because we don't use outlined 3762 // function directly. 3763 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3764 AlwaysInlineAttr::CreateImplicit( 3765 Context, {}, AttributeCommonInfo::AS_Keyword, 3766 AlwaysInlineAttr::Keyword_forceinline)); 3767 break; 3768 } 3769 case OMPD_taskloop: 3770 case OMPD_taskloop_simd: 3771 case OMPD_master_taskloop: 3772 case OMPD_master_taskloop_simd: { 3773 QualType KmpInt32Ty = 3774 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3775 .withConst(); 3776 QualType KmpUInt64Ty = 3777 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3778 .withConst(); 3779 QualType KmpInt64Ty = 3780 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3781 .withConst(); 3782 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3783 QualType KmpInt32PtrTy = 3784 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3785 QualType Args[] = {VoidPtrTy}; 3786 FunctionProtoType::ExtProtoInfo EPI; 3787 EPI.Variadic = true; 3788 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3789 Sema::CapturedParamNameType Params[] = { 3790 std::make_pair(".global_tid.", KmpInt32Ty), 3791 std::make_pair(".part_id.", KmpInt32PtrTy), 3792 std::make_pair(".privates.", VoidPtrTy), 3793 std::make_pair( 3794 ".copy_fn.", 3795 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3796 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3797 std::make_pair(".lb.", KmpUInt64Ty), 3798 std::make_pair(".ub.", KmpUInt64Ty), 3799 std::make_pair(".st.", KmpInt64Ty), 3800 std::make_pair(".liter.", KmpInt32Ty), 3801 std::make_pair(".reductions.", VoidPtrTy), 3802 std::make_pair(StringRef(), QualType()) // __context with shared vars 3803 }; 3804 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3805 Params); 3806 // Mark this captured region as inlined, because we don't use outlined 3807 // function directly. 3808 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3809 AlwaysInlineAttr::CreateImplicit( 3810 Context, {}, AttributeCommonInfo::AS_Keyword, 3811 AlwaysInlineAttr::Keyword_forceinline)); 3812 break; 3813 } 3814 case OMPD_parallel_master_taskloop: 3815 case OMPD_parallel_master_taskloop_simd: { 3816 QualType KmpInt32Ty = 3817 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 3818 .withConst(); 3819 QualType KmpUInt64Ty = 3820 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 3821 .withConst(); 3822 QualType KmpInt64Ty = 3823 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 3824 .withConst(); 3825 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3826 QualType KmpInt32PtrTy = 3827 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3828 Sema::CapturedParamNameType ParamsParallel[] = { 3829 std::make_pair(".global_tid.", KmpInt32PtrTy), 3830 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3831 std::make_pair(StringRef(), QualType()) // __context with shared vars 3832 }; 3833 // Start a captured region for 'parallel'. 3834 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3835 ParamsParallel, /*OpenMPCaptureLevel=*/0); 3836 QualType Args[] = {VoidPtrTy}; 3837 FunctionProtoType::ExtProtoInfo EPI; 3838 EPI.Variadic = true; 3839 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3840 Sema::CapturedParamNameType Params[] = { 3841 std::make_pair(".global_tid.", KmpInt32Ty), 3842 std::make_pair(".part_id.", KmpInt32PtrTy), 3843 std::make_pair(".privates.", VoidPtrTy), 3844 std::make_pair( 3845 ".copy_fn.", 3846 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3847 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3848 std::make_pair(".lb.", KmpUInt64Ty), 3849 std::make_pair(".ub.", KmpUInt64Ty), 3850 std::make_pair(".st.", KmpInt64Ty), 3851 std::make_pair(".liter.", KmpInt32Ty), 3852 std::make_pair(".reductions.", VoidPtrTy), 3853 std::make_pair(StringRef(), QualType()) // __context with shared vars 3854 }; 3855 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3856 Params, /*OpenMPCaptureLevel=*/1); 3857 // Mark this captured region as inlined, because we don't use outlined 3858 // function directly. 3859 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3860 AlwaysInlineAttr::CreateImplicit( 3861 Context, {}, AttributeCommonInfo::AS_Keyword, 3862 AlwaysInlineAttr::Keyword_forceinline)); 3863 break; 3864 } 3865 case OMPD_distribute_parallel_for_simd: 3866 case OMPD_distribute_parallel_for: { 3867 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3868 QualType KmpInt32PtrTy = 3869 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3870 Sema::CapturedParamNameType Params[] = { 3871 std::make_pair(".global_tid.", KmpInt32PtrTy), 3872 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3873 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3874 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3875 std::make_pair(StringRef(), QualType()) // __context with shared vars 3876 }; 3877 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3878 Params); 3879 break; 3880 } 3881 case OMPD_target_teams_distribute_parallel_for: 3882 case OMPD_target_teams_distribute_parallel_for_simd: { 3883 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3884 QualType KmpInt32PtrTy = 3885 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3886 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3887 3888 QualType Args[] = {VoidPtrTy}; 3889 FunctionProtoType::ExtProtoInfo EPI; 3890 EPI.Variadic = true; 3891 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3892 Sema::CapturedParamNameType Params[] = { 3893 std::make_pair(".global_tid.", KmpInt32Ty), 3894 std::make_pair(".part_id.", KmpInt32PtrTy), 3895 std::make_pair(".privates.", VoidPtrTy), 3896 std::make_pair( 3897 ".copy_fn.", 3898 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3899 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3900 std::make_pair(StringRef(), QualType()) // __context with shared vars 3901 }; 3902 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3903 Params, /*OpenMPCaptureLevel=*/0); 3904 // Mark this captured region as inlined, because we don't use outlined 3905 // function directly. 3906 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3907 AlwaysInlineAttr::CreateImplicit( 3908 Context, {}, AttributeCommonInfo::AS_Keyword, 3909 AlwaysInlineAttr::Keyword_forceinline)); 3910 Sema::CapturedParamNameType ParamsTarget[] = { 3911 std::make_pair(StringRef(), QualType()) // __context with shared vars 3912 }; 3913 // Start a captured region for 'target' with no implicit parameters. 3914 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3915 ParamsTarget, /*OpenMPCaptureLevel=*/1); 3916 3917 Sema::CapturedParamNameType ParamsTeams[] = { 3918 std::make_pair(".global_tid.", KmpInt32PtrTy), 3919 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3920 std::make_pair(StringRef(), QualType()) // __context with shared vars 3921 }; 3922 // Start a captured region for 'target' with no implicit parameters. 3923 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3924 ParamsTeams, /*OpenMPCaptureLevel=*/2); 3925 3926 Sema::CapturedParamNameType ParamsParallel[] = { 3927 std::make_pair(".global_tid.", KmpInt32PtrTy), 3928 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3929 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3930 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3931 std::make_pair(StringRef(), QualType()) // __context with shared vars 3932 }; 3933 // Start a captured region for 'teams' or 'parallel'. Both regions have 3934 // the same implicit parameters. 3935 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3936 ParamsParallel, /*OpenMPCaptureLevel=*/3); 3937 break; 3938 } 3939 3940 case OMPD_teams_distribute_parallel_for: 3941 case OMPD_teams_distribute_parallel_for_simd: { 3942 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3943 QualType KmpInt32PtrTy = 3944 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3945 3946 Sema::CapturedParamNameType ParamsTeams[] = { 3947 std::make_pair(".global_tid.", KmpInt32PtrTy), 3948 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3949 std::make_pair(StringRef(), QualType()) // __context with shared vars 3950 }; 3951 // Start a captured region for 'target' with no implicit parameters. 3952 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3953 ParamsTeams, /*OpenMPCaptureLevel=*/0); 3954 3955 Sema::CapturedParamNameType ParamsParallel[] = { 3956 std::make_pair(".global_tid.", KmpInt32PtrTy), 3957 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3958 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3959 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3960 std::make_pair(StringRef(), QualType()) // __context with shared vars 3961 }; 3962 // Start a captured region for 'teams' or 'parallel'. Both regions have 3963 // the same implicit parameters. 3964 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3965 ParamsParallel, /*OpenMPCaptureLevel=*/1); 3966 break; 3967 } 3968 case OMPD_target_update: 3969 case OMPD_target_enter_data: 3970 case OMPD_target_exit_data: { 3971 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3972 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3973 QualType KmpInt32PtrTy = 3974 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3975 QualType Args[] = {VoidPtrTy}; 3976 FunctionProtoType::ExtProtoInfo EPI; 3977 EPI.Variadic = true; 3978 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3979 Sema::CapturedParamNameType Params[] = { 3980 std::make_pair(".global_tid.", KmpInt32Ty), 3981 std::make_pair(".part_id.", KmpInt32PtrTy), 3982 std::make_pair(".privates.", VoidPtrTy), 3983 std::make_pair( 3984 ".copy_fn.", 3985 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3986 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3987 std::make_pair(StringRef(), QualType()) // __context with shared vars 3988 }; 3989 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3990 Params); 3991 // Mark this captured region as inlined, because we don't use outlined 3992 // function directly. 3993 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3994 AlwaysInlineAttr::CreateImplicit( 3995 Context, {}, AttributeCommonInfo::AS_Keyword, 3996 AlwaysInlineAttr::Keyword_forceinline)); 3997 break; 3998 } 3999 case OMPD_threadprivate: 4000 case OMPD_allocate: 4001 case OMPD_taskyield: 4002 case OMPD_barrier: 4003 case OMPD_taskwait: 4004 case OMPD_cancellation_point: 4005 case OMPD_cancel: 4006 case OMPD_flush: 4007 case OMPD_depobj: 4008 case OMPD_scan: 4009 case OMPD_declare_reduction: 4010 case OMPD_declare_mapper: 4011 case OMPD_declare_simd: 4012 case OMPD_declare_target: 4013 case OMPD_end_declare_target: 4014 case OMPD_requires: 4015 case OMPD_declare_variant: 4016 case OMPD_begin_declare_variant: 4017 case OMPD_end_declare_variant: 4018 llvm_unreachable("OpenMP Directive is not allowed"); 4019 case OMPD_unknown: 4020 llvm_unreachable("Unknown OpenMP directive"); 4021 } 4022 } 4023 4024 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4025 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4026 } 4027 4028 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4029 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4030 getOpenMPCaptureRegions(CaptureRegions, DKind); 4031 return CaptureRegions.size(); 4032 } 4033 4034 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4035 Expr *CaptureExpr, bool WithInit, 4036 bool AsExpression) { 4037 assert(CaptureExpr); 4038 ASTContext &C = S.getASTContext(); 4039 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4040 QualType Ty = Init->getType(); 4041 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4042 if (S.getLangOpts().CPlusPlus) { 4043 Ty = C.getLValueReferenceType(Ty); 4044 } else { 4045 Ty = C.getPointerType(Ty); 4046 ExprResult Res = 4047 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4048 if (!Res.isUsable()) 4049 return nullptr; 4050 Init = Res.get(); 4051 } 4052 WithInit = true; 4053 } 4054 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 4055 CaptureExpr->getBeginLoc()); 4056 if (!WithInit) 4057 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4058 S.CurContext->addHiddenDecl(CED); 4059 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4060 return CED; 4061 } 4062 4063 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4064 bool WithInit) { 4065 OMPCapturedExprDecl *CD; 4066 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4067 CD = cast<OMPCapturedExprDecl>(VD); 4068 else 4069 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4070 /*AsExpression=*/false); 4071 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4072 CaptureExpr->getExprLoc()); 4073 } 4074 4075 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 4076 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4077 if (!Ref) { 4078 OMPCapturedExprDecl *CD = buildCaptureDecl( 4079 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 4080 /*WithInit=*/true, /*AsExpression=*/true); 4081 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4082 CaptureExpr->getExprLoc()); 4083 } 4084 ExprResult Res = Ref; 4085 if (!S.getLangOpts().CPlusPlus && 4086 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4087 Ref->getType()->isPointerType()) { 4088 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4089 if (!Res.isUsable()) 4090 return ExprError(); 4091 } 4092 return S.DefaultLvalueConversion(Res.get()); 4093 } 4094 4095 namespace { 4096 // OpenMP directives parsed in this section are represented as a 4097 // CapturedStatement with an associated statement. If a syntax error 4098 // is detected during the parsing of the associated statement, the 4099 // compiler must abort processing and close the CapturedStatement. 4100 // 4101 // Combined directives such as 'target parallel' have more than one 4102 // nested CapturedStatements. This RAII ensures that we unwind out 4103 // of all the nested CapturedStatements when an error is found. 4104 class CaptureRegionUnwinderRAII { 4105 private: 4106 Sema &S; 4107 bool &ErrorFound; 4108 OpenMPDirectiveKind DKind = OMPD_unknown; 4109 4110 public: 4111 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4112 OpenMPDirectiveKind DKind) 4113 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4114 ~CaptureRegionUnwinderRAII() { 4115 if (ErrorFound) { 4116 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4117 while (--ThisCaptureLevel >= 0) 4118 S.ActOnCapturedRegionError(); 4119 } 4120 } 4121 }; 4122 } // namespace 4123 4124 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4125 // Capture variables captured by reference in lambdas for target-based 4126 // directives. 4127 if (!CurContext->isDependentContext() && 4128 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4129 isOpenMPTargetDataManagementDirective( 4130 DSAStack->getCurrentDirective()))) { 4131 QualType Type = V->getType(); 4132 if (const auto *RD = Type.getCanonicalType() 4133 .getNonReferenceType() 4134 ->getAsCXXRecordDecl()) { 4135 bool SavedForceCaptureByReferenceInTargetExecutable = 4136 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4137 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4138 /*V=*/true); 4139 if (RD->isLambda()) { 4140 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4141 FieldDecl *ThisCapture; 4142 RD->getCaptureFields(Captures, ThisCapture); 4143 for (const LambdaCapture &LC : RD->captures()) { 4144 if (LC.getCaptureKind() == LCK_ByRef) { 4145 VarDecl *VD = LC.getCapturedVar(); 4146 DeclContext *VDC = VD->getDeclContext(); 4147 if (!VDC->Encloses(CurContext)) 4148 continue; 4149 MarkVariableReferenced(LC.getLocation(), VD); 4150 } else if (LC.getCaptureKind() == LCK_This) { 4151 QualType ThisTy = getCurrentThisType(); 4152 if (!ThisTy.isNull() && 4153 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4154 CheckCXXThisCapture(LC.getLocation()); 4155 } 4156 } 4157 } 4158 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4159 SavedForceCaptureByReferenceInTargetExecutable); 4160 } 4161 } 4162 } 4163 4164 static bool checkOrderedOrderSpecified(Sema &S, 4165 const ArrayRef<OMPClause *> Clauses) { 4166 const OMPOrderedClause *Ordered = nullptr; 4167 const OMPOrderClause *Order = nullptr; 4168 4169 for (const OMPClause *Clause : Clauses) { 4170 if (Clause->getClauseKind() == OMPC_ordered) 4171 Ordered = cast<OMPOrderedClause>(Clause); 4172 else if (Clause->getClauseKind() == OMPC_order) { 4173 Order = cast<OMPOrderClause>(Clause); 4174 if (Order->getKind() != OMPC_ORDER_concurrent) 4175 Order = nullptr; 4176 } 4177 if (Ordered && Order) 4178 break; 4179 } 4180 4181 if (Ordered && Order) { 4182 S.Diag(Order->getKindKwLoc(), 4183 diag::err_omp_simple_clause_incompatible_with_ordered) 4184 << getOpenMPClauseName(OMPC_order) 4185 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4186 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4187 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4188 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4189 return true; 4190 } 4191 return false; 4192 } 4193 4194 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4195 ArrayRef<OMPClause *> Clauses) { 4196 bool ErrorFound = false; 4197 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4198 *this, ErrorFound, DSAStack->getCurrentDirective()); 4199 if (!S.isUsable()) { 4200 ErrorFound = true; 4201 return StmtError(); 4202 } 4203 4204 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4205 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4206 OMPOrderedClause *OC = nullptr; 4207 OMPScheduleClause *SC = nullptr; 4208 SmallVector<const OMPLinearClause *, 4> LCs; 4209 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4210 // This is required for proper codegen. 4211 for (OMPClause *Clause : Clauses) { 4212 if (!LangOpts.OpenMPSimd && 4213 isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 4214 Clause->getClauseKind() == OMPC_in_reduction) { 4215 // Capture taskgroup task_reduction descriptors inside the tasking regions 4216 // with the corresponding in_reduction items. 4217 auto *IRC = cast<OMPInReductionClause>(Clause); 4218 for (Expr *E : IRC->taskgroup_descriptors()) 4219 if (E) 4220 MarkDeclarationsReferencedInExpr(E); 4221 } 4222 if (isOpenMPPrivate(Clause->getClauseKind()) || 4223 Clause->getClauseKind() == OMPC_copyprivate || 4224 (getLangOpts().OpenMPUseTLS && 4225 getASTContext().getTargetInfo().isTLSSupported() && 4226 Clause->getClauseKind() == OMPC_copyin)) { 4227 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4228 // Mark all variables in private list clauses as used in inner region. 4229 for (Stmt *VarRef : Clause->children()) { 4230 if (auto *E = cast_or_null<Expr>(VarRef)) { 4231 MarkDeclarationsReferencedInExpr(E); 4232 } 4233 } 4234 DSAStack->setForceVarCapturing(/*V=*/false); 4235 } else if (CaptureRegions.size() > 1 || 4236 CaptureRegions.back() != OMPD_unknown) { 4237 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4238 PICs.push_back(C); 4239 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4240 if (Expr *E = C->getPostUpdateExpr()) 4241 MarkDeclarationsReferencedInExpr(E); 4242 } 4243 } 4244 if (Clause->getClauseKind() == OMPC_schedule) 4245 SC = cast<OMPScheduleClause>(Clause); 4246 else if (Clause->getClauseKind() == OMPC_ordered) 4247 OC = cast<OMPOrderedClause>(Clause); 4248 else if (Clause->getClauseKind() == OMPC_linear) 4249 LCs.push_back(cast<OMPLinearClause>(Clause)); 4250 } 4251 // Capture allocator expressions if used. 4252 for (Expr *E : DSAStack->getInnerAllocators()) 4253 MarkDeclarationsReferencedInExpr(E); 4254 // OpenMP, 2.7.1 Loop Construct, Restrictions 4255 // The nonmonotonic modifier cannot be specified if an ordered clause is 4256 // specified. 4257 if (SC && 4258 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4259 SC->getSecondScheduleModifier() == 4260 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4261 OC) { 4262 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4263 ? SC->getFirstScheduleModifierLoc() 4264 : SC->getSecondScheduleModifierLoc(), 4265 diag::err_omp_simple_clause_incompatible_with_ordered) 4266 << getOpenMPClauseName(OMPC_schedule) 4267 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4268 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4269 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4270 ErrorFound = true; 4271 } 4272 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4273 // If an order(concurrent) clause is present, an ordered clause may not appear 4274 // on the same directive. 4275 if (checkOrderedOrderSpecified(*this, Clauses)) 4276 ErrorFound = true; 4277 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4278 for (const OMPLinearClause *C : LCs) { 4279 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4280 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4281 } 4282 ErrorFound = true; 4283 } 4284 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4285 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4286 OC->getNumForLoops()) { 4287 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4288 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4289 ErrorFound = true; 4290 } 4291 if (ErrorFound) { 4292 return StmtError(); 4293 } 4294 StmtResult SR = S; 4295 unsigned CompletedRegions = 0; 4296 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4297 // Mark all variables in private list clauses as used in inner region. 4298 // Required for proper codegen of combined directives. 4299 // TODO: add processing for other clauses. 4300 if (ThisCaptureRegion != OMPD_unknown) { 4301 for (const clang::OMPClauseWithPreInit *C : PICs) { 4302 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4303 // Find the particular capture region for the clause if the 4304 // directive is a combined one with multiple capture regions. 4305 // If the directive is not a combined one, the capture region 4306 // associated with the clause is OMPD_unknown and is generated 4307 // only once. 4308 if (CaptureRegion == ThisCaptureRegion || 4309 CaptureRegion == OMPD_unknown) { 4310 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4311 for (Decl *D : DS->decls()) 4312 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4313 } 4314 } 4315 } 4316 } 4317 if (++CompletedRegions == CaptureRegions.size()) 4318 DSAStack->setBodyComplete(); 4319 SR = ActOnCapturedRegionEnd(SR.get()); 4320 } 4321 return SR; 4322 } 4323 4324 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4325 OpenMPDirectiveKind CancelRegion, 4326 SourceLocation StartLoc) { 4327 // CancelRegion is only needed for cancel and cancellation_point. 4328 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4329 return false; 4330 4331 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4332 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4333 return false; 4334 4335 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4336 << getOpenMPDirectiveName(CancelRegion); 4337 return true; 4338 } 4339 4340 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4341 OpenMPDirectiveKind CurrentRegion, 4342 const DeclarationNameInfo &CurrentName, 4343 OpenMPDirectiveKind CancelRegion, 4344 SourceLocation StartLoc) { 4345 if (Stack->getCurScope()) { 4346 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4347 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4348 bool NestingProhibited = false; 4349 bool CloseNesting = true; 4350 bool OrphanSeen = false; 4351 enum { 4352 NoRecommend, 4353 ShouldBeInParallelRegion, 4354 ShouldBeInOrderedRegion, 4355 ShouldBeInTargetRegion, 4356 ShouldBeInTeamsRegion, 4357 ShouldBeInLoopSimdRegion, 4358 } Recommend = NoRecommend; 4359 if (isOpenMPSimdDirective(ParentRegion) && 4360 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4361 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4362 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4363 CurrentRegion != OMPD_scan))) { 4364 // OpenMP [2.16, Nesting of Regions] 4365 // OpenMP constructs may not be nested inside a simd region. 4366 // OpenMP [2.8.1,simd Construct, Restrictions] 4367 // An ordered construct with the simd clause is the only OpenMP 4368 // construct that can appear in the simd region. 4369 // Allowing a SIMD construct nested in another SIMD construct is an 4370 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4371 // message. 4372 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4373 // The only OpenMP constructs that can be encountered during execution of 4374 // a simd region are the atomic construct, the loop construct, the simd 4375 // construct and the ordered construct with the simd clause. 4376 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4377 ? diag::err_omp_prohibited_region_simd 4378 : diag::warn_omp_nesting_simd) 4379 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4380 return CurrentRegion != OMPD_simd; 4381 } 4382 if (ParentRegion == OMPD_atomic) { 4383 // OpenMP [2.16, Nesting of Regions] 4384 // OpenMP constructs may not be nested inside an atomic region. 4385 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4386 return true; 4387 } 4388 if (CurrentRegion == OMPD_section) { 4389 // OpenMP [2.7.2, sections Construct, Restrictions] 4390 // Orphaned section directives are prohibited. That is, the section 4391 // directives must appear within the sections construct and must not be 4392 // encountered elsewhere in the sections region. 4393 if (ParentRegion != OMPD_sections && 4394 ParentRegion != OMPD_parallel_sections) { 4395 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4396 << (ParentRegion != OMPD_unknown) 4397 << getOpenMPDirectiveName(ParentRegion); 4398 return true; 4399 } 4400 return false; 4401 } 4402 // Allow some constructs (except teams and cancellation constructs) to be 4403 // orphaned (they could be used in functions, called from OpenMP regions 4404 // with the required preconditions). 4405 if (ParentRegion == OMPD_unknown && 4406 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4407 CurrentRegion != OMPD_cancellation_point && 4408 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4409 return false; 4410 if (CurrentRegion == OMPD_cancellation_point || 4411 CurrentRegion == OMPD_cancel) { 4412 // OpenMP [2.16, Nesting of Regions] 4413 // A cancellation point construct for which construct-type-clause is 4414 // taskgroup must be nested inside a task construct. A cancellation 4415 // point construct for which construct-type-clause is not taskgroup must 4416 // be closely nested inside an OpenMP construct that matches the type 4417 // specified in construct-type-clause. 4418 // A cancel construct for which construct-type-clause is taskgroup must be 4419 // nested inside a task construct. A cancel construct for which 4420 // construct-type-clause is not taskgroup must be closely nested inside an 4421 // OpenMP construct that matches the type specified in 4422 // construct-type-clause. 4423 NestingProhibited = 4424 !((CancelRegion == OMPD_parallel && 4425 (ParentRegion == OMPD_parallel || 4426 ParentRegion == OMPD_target_parallel)) || 4427 (CancelRegion == OMPD_for && 4428 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4429 ParentRegion == OMPD_target_parallel_for || 4430 ParentRegion == OMPD_distribute_parallel_for || 4431 ParentRegion == OMPD_teams_distribute_parallel_for || 4432 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4433 (CancelRegion == OMPD_taskgroup && 4434 (ParentRegion == OMPD_task || 4435 (SemaRef.getLangOpts().OpenMP >= 50 && 4436 (ParentRegion == OMPD_taskloop || 4437 ParentRegion == OMPD_master_taskloop || 4438 ParentRegion == OMPD_parallel_master_taskloop)))) || 4439 (CancelRegion == OMPD_sections && 4440 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4441 ParentRegion == OMPD_parallel_sections))); 4442 OrphanSeen = ParentRegion == OMPD_unknown; 4443 } else if (CurrentRegion == OMPD_master) { 4444 // OpenMP [2.16, Nesting of Regions] 4445 // A master region may not be closely nested inside a worksharing, 4446 // atomic, or explicit task region. 4447 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4448 isOpenMPTaskingDirective(ParentRegion); 4449 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4450 // OpenMP [2.16, Nesting of Regions] 4451 // A critical region may not be nested (closely or otherwise) inside a 4452 // critical region with the same name. Note that this restriction is not 4453 // sufficient to prevent deadlock. 4454 SourceLocation PreviousCriticalLoc; 4455 bool DeadLock = Stack->hasDirective( 4456 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4457 const DeclarationNameInfo &DNI, 4458 SourceLocation Loc) { 4459 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4460 PreviousCriticalLoc = Loc; 4461 return true; 4462 } 4463 return false; 4464 }, 4465 false /* skip top directive */); 4466 if (DeadLock) { 4467 SemaRef.Diag(StartLoc, 4468 diag::err_omp_prohibited_region_critical_same_name) 4469 << CurrentName.getName(); 4470 if (PreviousCriticalLoc.isValid()) 4471 SemaRef.Diag(PreviousCriticalLoc, 4472 diag::note_omp_previous_critical_region); 4473 return true; 4474 } 4475 } else if (CurrentRegion == OMPD_barrier) { 4476 // OpenMP [2.16, Nesting of Regions] 4477 // A barrier region may not be closely nested inside a worksharing, 4478 // explicit task, critical, ordered, atomic, or master region. 4479 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4480 isOpenMPTaskingDirective(ParentRegion) || 4481 ParentRegion == OMPD_master || 4482 ParentRegion == OMPD_parallel_master || 4483 ParentRegion == OMPD_critical || 4484 ParentRegion == OMPD_ordered; 4485 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4486 !isOpenMPParallelDirective(CurrentRegion) && 4487 !isOpenMPTeamsDirective(CurrentRegion)) { 4488 // OpenMP [2.16, Nesting of Regions] 4489 // A worksharing region may not be closely nested inside a worksharing, 4490 // explicit task, critical, ordered, atomic, or master region. 4491 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4492 isOpenMPTaskingDirective(ParentRegion) || 4493 ParentRegion == OMPD_master || 4494 ParentRegion == OMPD_parallel_master || 4495 ParentRegion == OMPD_critical || 4496 ParentRegion == OMPD_ordered; 4497 Recommend = ShouldBeInParallelRegion; 4498 } else if (CurrentRegion == OMPD_ordered) { 4499 // OpenMP [2.16, Nesting of Regions] 4500 // An ordered region may not be closely nested inside a critical, 4501 // atomic, or explicit task region. 4502 // An ordered region must be closely nested inside a loop region (or 4503 // parallel loop region) with an ordered clause. 4504 // OpenMP [2.8.1,simd Construct, Restrictions] 4505 // An ordered construct with the simd clause is the only OpenMP construct 4506 // that can appear in the simd region. 4507 NestingProhibited = ParentRegion == OMPD_critical || 4508 isOpenMPTaskingDirective(ParentRegion) || 4509 !(isOpenMPSimdDirective(ParentRegion) || 4510 Stack->isParentOrderedRegion()); 4511 Recommend = ShouldBeInOrderedRegion; 4512 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4513 // OpenMP [2.16, Nesting of Regions] 4514 // If specified, a teams construct must be contained within a target 4515 // construct. 4516 NestingProhibited = 4517 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4518 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4519 ParentRegion != OMPD_target); 4520 OrphanSeen = ParentRegion == OMPD_unknown; 4521 Recommend = ShouldBeInTargetRegion; 4522 } else if (CurrentRegion == OMPD_scan) { 4523 // OpenMP [2.16, Nesting of Regions] 4524 // If specified, a teams construct must be contained within a target 4525 // construct. 4526 NestingProhibited = 4527 SemaRef.LangOpts.OpenMP < 50 || 4528 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4529 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4530 ParentRegion != OMPD_parallel_for_simd); 4531 OrphanSeen = ParentRegion == OMPD_unknown; 4532 Recommend = ShouldBeInLoopSimdRegion; 4533 } 4534 if (!NestingProhibited && 4535 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4536 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4537 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4538 // OpenMP [2.16, Nesting of Regions] 4539 // distribute, parallel, parallel sections, parallel workshare, and the 4540 // parallel loop and parallel loop SIMD constructs are the only OpenMP 4541 // constructs that can be closely nested in the teams region. 4542 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4543 !isOpenMPDistributeDirective(CurrentRegion); 4544 Recommend = ShouldBeInParallelRegion; 4545 } 4546 if (!NestingProhibited && 4547 isOpenMPNestingDistributeDirective(CurrentRegion)) { 4548 // OpenMP 4.5 [2.17 Nesting of Regions] 4549 // The region associated with the distribute construct must be strictly 4550 // nested inside a teams region 4551 NestingProhibited = 4552 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 4553 Recommend = ShouldBeInTeamsRegion; 4554 } 4555 if (!NestingProhibited && 4556 (isOpenMPTargetExecutionDirective(CurrentRegion) || 4557 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 4558 // OpenMP 4.5 [2.17 Nesting of Regions] 4559 // If a target, target update, target data, target enter data, or 4560 // target exit data construct is encountered during execution of a 4561 // target region, the behavior is unspecified. 4562 NestingProhibited = Stack->hasDirective( 4563 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 4564 SourceLocation) { 4565 if (isOpenMPTargetExecutionDirective(K)) { 4566 OffendingRegion = K; 4567 return true; 4568 } 4569 return false; 4570 }, 4571 false /* don't skip top directive */); 4572 CloseNesting = false; 4573 } 4574 if (NestingProhibited) { 4575 if (OrphanSeen) { 4576 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 4577 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 4578 } else { 4579 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 4580 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 4581 << Recommend << getOpenMPDirectiveName(CurrentRegion); 4582 } 4583 return true; 4584 } 4585 } 4586 return false; 4587 } 4588 4589 struct Kind2Unsigned { 4590 using argument_type = OpenMPDirectiveKind; 4591 unsigned operator()(argument_type DK) { return unsigned(DK); } 4592 }; 4593 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 4594 ArrayRef<OMPClause *> Clauses, 4595 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 4596 bool ErrorFound = false; 4597 unsigned NamedModifiersNumber = 0; 4598 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 4599 FoundNameModifiers.resize(unsigned(OMPD_unknown) + 1); 4600 SmallVector<SourceLocation, 4> NameModifierLoc; 4601 for (const OMPClause *C : Clauses) { 4602 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 4603 // At most one if clause without a directive-name-modifier can appear on 4604 // the directive. 4605 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 4606 if (FoundNameModifiers[CurNM]) { 4607 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 4608 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 4609 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 4610 ErrorFound = true; 4611 } else if (CurNM != OMPD_unknown) { 4612 NameModifierLoc.push_back(IC->getNameModifierLoc()); 4613 ++NamedModifiersNumber; 4614 } 4615 FoundNameModifiers[CurNM] = IC; 4616 if (CurNM == OMPD_unknown) 4617 continue; 4618 // Check if the specified name modifier is allowed for the current 4619 // directive. 4620 // At most one if clause with the particular directive-name-modifier can 4621 // appear on the directive. 4622 bool MatchFound = false; 4623 for (auto NM : AllowedNameModifiers) { 4624 if (CurNM == NM) { 4625 MatchFound = true; 4626 break; 4627 } 4628 } 4629 if (!MatchFound) { 4630 S.Diag(IC->getNameModifierLoc(), 4631 diag::err_omp_wrong_if_directive_name_modifier) 4632 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 4633 ErrorFound = true; 4634 } 4635 } 4636 } 4637 // If any if clause on the directive includes a directive-name-modifier then 4638 // all if clauses on the directive must include a directive-name-modifier. 4639 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 4640 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 4641 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 4642 diag::err_omp_no_more_if_clause); 4643 } else { 4644 std::string Values; 4645 std::string Sep(", "); 4646 unsigned AllowedCnt = 0; 4647 unsigned TotalAllowedNum = 4648 AllowedNameModifiers.size() - NamedModifiersNumber; 4649 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 4650 ++Cnt) { 4651 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 4652 if (!FoundNameModifiers[NM]) { 4653 Values += "'"; 4654 Values += getOpenMPDirectiveName(NM); 4655 Values += "'"; 4656 if (AllowedCnt + 2 == TotalAllowedNum) 4657 Values += " or "; 4658 else if (AllowedCnt + 1 != TotalAllowedNum) 4659 Values += Sep; 4660 ++AllowedCnt; 4661 } 4662 } 4663 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 4664 diag::err_omp_unnamed_if_clause) 4665 << (TotalAllowedNum > 1) << Values; 4666 } 4667 for (SourceLocation Loc : NameModifierLoc) { 4668 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 4669 } 4670 ErrorFound = true; 4671 } 4672 return ErrorFound; 4673 } 4674 4675 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 4676 SourceLocation &ELoc, 4677 SourceRange &ERange, 4678 bool AllowArraySection) { 4679 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 4680 RefExpr->containsUnexpandedParameterPack()) 4681 return std::make_pair(nullptr, true); 4682 4683 // OpenMP [3.1, C/C++] 4684 // A list item is a variable name. 4685 // OpenMP [2.9.3.3, Restrictions, p.1] 4686 // A variable that is part of another variable (as an array or 4687 // structure element) cannot appear in a private clause. 4688 RefExpr = RefExpr->IgnoreParens(); 4689 enum { 4690 NoArrayExpr = -1, 4691 ArraySubscript = 0, 4692 OMPArraySection = 1 4693 } IsArrayExpr = NoArrayExpr; 4694 if (AllowArraySection) { 4695 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 4696 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 4697 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4698 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4699 RefExpr = Base; 4700 IsArrayExpr = ArraySubscript; 4701 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 4702 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 4703 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 4704 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 4705 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 4706 Base = TempASE->getBase()->IgnoreParenImpCasts(); 4707 RefExpr = Base; 4708 IsArrayExpr = OMPArraySection; 4709 } 4710 } 4711 ELoc = RefExpr->getExprLoc(); 4712 ERange = RefExpr->getSourceRange(); 4713 RefExpr = RefExpr->IgnoreParenImpCasts(); 4714 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4715 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 4716 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 4717 (S.getCurrentThisType().isNull() || !ME || 4718 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 4719 !isa<FieldDecl>(ME->getMemberDecl()))) { 4720 if (IsArrayExpr != NoArrayExpr) { 4721 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 4722 << ERange; 4723 } else { 4724 S.Diag(ELoc, 4725 AllowArraySection 4726 ? diag::err_omp_expected_var_name_member_expr_or_array_item 4727 : diag::err_omp_expected_var_name_member_expr) 4728 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 4729 } 4730 return std::make_pair(nullptr, false); 4731 } 4732 return std::make_pair( 4733 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 4734 } 4735 4736 namespace { 4737 /// Checks if the allocator is used in uses_allocators clause to be allowed in 4738 /// target regions. 4739 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 4740 DSAStackTy *S = nullptr; 4741 4742 public: 4743 bool VisitDeclRefExpr(const DeclRefExpr *E) { 4744 return !S->isUsesAllocatorsDecl(E->getDecl()); 4745 } 4746 bool VisitStmt(const Stmt *S) { 4747 for (const Stmt *Child : S->children()) { 4748 if (Child && Visit(Child)) 4749 return true; 4750 } 4751 return false; 4752 } 4753 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 4754 }; 4755 } // namespace 4756 4757 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 4758 ArrayRef<OMPClause *> Clauses) { 4759 assert(!S.CurContext->isDependentContext() && 4760 "Expected non-dependent context."); 4761 auto AllocateRange = 4762 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 4763 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> 4764 DeclToCopy; 4765 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 4766 return isOpenMPPrivate(C->getClauseKind()); 4767 }); 4768 for (OMPClause *Cl : PrivateRange) { 4769 MutableArrayRef<Expr *>::iterator I, It, Et; 4770 if (Cl->getClauseKind() == OMPC_private) { 4771 auto *PC = cast<OMPPrivateClause>(Cl); 4772 I = PC->private_copies().begin(); 4773 It = PC->varlist_begin(); 4774 Et = PC->varlist_end(); 4775 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 4776 auto *PC = cast<OMPFirstprivateClause>(Cl); 4777 I = PC->private_copies().begin(); 4778 It = PC->varlist_begin(); 4779 Et = PC->varlist_end(); 4780 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 4781 auto *PC = cast<OMPLastprivateClause>(Cl); 4782 I = PC->private_copies().begin(); 4783 It = PC->varlist_begin(); 4784 Et = PC->varlist_end(); 4785 } else if (Cl->getClauseKind() == OMPC_linear) { 4786 auto *PC = cast<OMPLinearClause>(Cl); 4787 I = PC->privates().begin(); 4788 It = PC->varlist_begin(); 4789 Et = PC->varlist_end(); 4790 } else if (Cl->getClauseKind() == OMPC_reduction) { 4791 auto *PC = cast<OMPReductionClause>(Cl); 4792 I = PC->privates().begin(); 4793 It = PC->varlist_begin(); 4794 Et = PC->varlist_end(); 4795 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 4796 auto *PC = cast<OMPTaskReductionClause>(Cl); 4797 I = PC->privates().begin(); 4798 It = PC->varlist_begin(); 4799 Et = PC->varlist_end(); 4800 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 4801 auto *PC = cast<OMPInReductionClause>(Cl); 4802 I = PC->privates().begin(); 4803 It = PC->varlist_begin(); 4804 Et = PC->varlist_end(); 4805 } else { 4806 llvm_unreachable("Expected private clause."); 4807 } 4808 for (Expr *E : llvm::make_range(It, Et)) { 4809 if (!*I) { 4810 ++I; 4811 continue; 4812 } 4813 SourceLocation ELoc; 4814 SourceRange ERange; 4815 Expr *SimpleRefExpr = E; 4816 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 4817 /*AllowArraySection=*/true); 4818 DeclToCopy.try_emplace(Res.first, 4819 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 4820 ++I; 4821 } 4822 } 4823 for (OMPClause *C : AllocateRange) { 4824 auto *AC = cast<OMPAllocateClause>(C); 4825 if (S.getLangOpts().OpenMP >= 50 && 4826 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 4827 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 4828 AC->getAllocator()) { 4829 Expr *Allocator = AC->getAllocator(); 4830 // OpenMP, 2.12.5 target Construct 4831 // Memory allocators that do not appear in a uses_allocators clause cannot 4832 // appear as an allocator in an allocate clause or be used in the target 4833 // region unless a requires directive with the dynamic_allocators clause 4834 // is present in the same compilation unit. 4835 AllocatorChecker Checker(Stack); 4836 if (Checker.Visit(Allocator)) 4837 S.Diag(Allocator->getExprLoc(), 4838 diag::err_omp_allocator_not_in_uses_allocators) 4839 << Allocator->getSourceRange(); 4840 } 4841 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 4842 getAllocatorKind(S, Stack, AC->getAllocator()); 4843 // OpenMP, 2.11.4 allocate Clause, Restrictions. 4844 // For task, taskloop or target directives, allocation requests to memory 4845 // allocators with the trait access set to thread result in unspecified 4846 // behavior. 4847 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 4848 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 4849 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 4850 S.Diag(AC->getAllocator()->getExprLoc(), 4851 diag::warn_omp_allocate_thread_on_task_target_directive) 4852 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 4853 } 4854 for (Expr *E : AC->varlists()) { 4855 SourceLocation ELoc; 4856 SourceRange ERange; 4857 Expr *SimpleRefExpr = E; 4858 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 4859 ValueDecl *VD = Res.first; 4860 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 4861 if (!isOpenMPPrivate(Data.CKind)) { 4862 S.Diag(E->getExprLoc(), 4863 diag::err_omp_expected_private_copy_for_allocate); 4864 continue; 4865 } 4866 VarDecl *PrivateVD = DeclToCopy[VD]; 4867 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 4868 AllocatorKind, AC->getAllocator())) 4869 continue; 4870 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 4871 E->getSourceRange()); 4872 } 4873 } 4874 } 4875 4876 StmtResult Sema::ActOnOpenMPExecutableDirective( 4877 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 4878 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 4879 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4880 StmtResult Res = StmtError(); 4881 // First check CancelRegion which is then used in checkNestingOfRegions. 4882 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 4883 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 4884 StartLoc)) 4885 return StmtError(); 4886 4887 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 4888 VarsWithInheritedDSAType VarsWithInheritedDSA; 4889 bool ErrorFound = false; 4890 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 4891 if (AStmt && !CurContext->isDependentContext()) { 4892 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4893 4894 // Check default data sharing attributes for referenced variables. 4895 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 4896 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 4897 Stmt *S = AStmt; 4898 while (--ThisCaptureLevel >= 0) 4899 S = cast<CapturedStmt>(S)->getCapturedStmt(); 4900 DSAChecker.Visit(S); 4901 if (!isOpenMPTargetDataManagementDirective(Kind) && 4902 !isOpenMPTaskingDirective(Kind)) { 4903 // Visit subcaptures to generate implicit clauses for captured vars. 4904 auto *CS = cast<CapturedStmt>(AStmt); 4905 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4906 getOpenMPCaptureRegions(CaptureRegions, Kind); 4907 // Ignore outer tasking regions for target directives. 4908 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 4909 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 4910 DSAChecker.visitSubCaptures(CS); 4911 } 4912 if (DSAChecker.isErrorFound()) 4913 return StmtError(); 4914 // Generate list of implicitly defined firstprivate variables. 4915 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 4916 4917 SmallVector<Expr *, 4> ImplicitFirstprivates( 4918 DSAChecker.getImplicitFirstprivate().begin(), 4919 DSAChecker.getImplicitFirstprivate().end()); 4920 SmallVector<Expr *, 4> ImplicitMaps[OMPC_MAP_delete]; 4921 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 4922 ArrayRef<Expr *> ImplicitMap = 4923 DSAChecker.getImplicitMap(static_cast<OpenMPDefaultmapClauseKind>(I)); 4924 ImplicitMaps[I].append(ImplicitMap.begin(), ImplicitMap.end()); 4925 } 4926 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 4927 for (OMPClause *C : Clauses) { 4928 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 4929 for (Expr *E : IRC->taskgroup_descriptors()) 4930 if (E) 4931 ImplicitFirstprivates.emplace_back(E); 4932 } 4933 // OpenMP 5.0, 2.10.1 task Construct 4934 // [detach clause]... The event-handle will be considered as if it was 4935 // specified on a firstprivate clause. 4936 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 4937 ImplicitFirstprivates.push_back(DC->getEventHandler()); 4938 } 4939 if (!ImplicitFirstprivates.empty()) { 4940 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 4941 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 4942 SourceLocation())) { 4943 ClausesWithImplicit.push_back(Implicit); 4944 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 4945 ImplicitFirstprivates.size(); 4946 } else { 4947 ErrorFound = true; 4948 } 4949 } 4950 int ClauseKindCnt = -1; 4951 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps) { 4952 ++ClauseKindCnt; 4953 if (ImplicitMap.empty()) 4954 continue; 4955 CXXScopeSpec MapperIdScopeSpec; 4956 DeclarationNameInfo MapperId; 4957 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 4958 if (OMPClause *Implicit = ActOnOpenMPMapClause( 4959 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, Kind, 4960 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 4961 ImplicitMap, OMPVarListLocTy())) { 4962 ClausesWithImplicit.emplace_back(Implicit); 4963 ErrorFound |= 4964 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMap.size(); 4965 } else { 4966 ErrorFound = true; 4967 } 4968 } 4969 } 4970 4971 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 4972 switch (Kind) { 4973 case OMPD_parallel: 4974 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 4975 EndLoc); 4976 AllowedNameModifiers.push_back(OMPD_parallel); 4977 break; 4978 case OMPD_simd: 4979 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4980 VarsWithInheritedDSA); 4981 if (LangOpts.OpenMP >= 50) 4982 AllowedNameModifiers.push_back(OMPD_simd); 4983 break; 4984 case OMPD_for: 4985 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 4986 VarsWithInheritedDSA); 4987 break; 4988 case OMPD_for_simd: 4989 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 4990 EndLoc, VarsWithInheritedDSA); 4991 if (LangOpts.OpenMP >= 50) 4992 AllowedNameModifiers.push_back(OMPD_simd); 4993 break; 4994 case OMPD_sections: 4995 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 4996 EndLoc); 4997 break; 4998 case OMPD_section: 4999 assert(ClausesWithImplicit.empty() && 5000 "No clauses are allowed for 'omp section' directive"); 5001 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 5002 break; 5003 case OMPD_single: 5004 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 5005 EndLoc); 5006 break; 5007 case OMPD_master: 5008 assert(ClausesWithImplicit.empty() && 5009 "No clauses are allowed for 'omp master' directive"); 5010 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 5011 break; 5012 case OMPD_critical: 5013 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 5014 StartLoc, EndLoc); 5015 break; 5016 case OMPD_parallel_for: 5017 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 5018 EndLoc, VarsWithInheritedDSA); 5019 AllowedNameModifiers.push_back(OMPD_parallel); 5020 break; 5021 case OMPD_parallel_for_simd: 5022 Res = ActOnOpenMPParallelForSimdDirective( 5023 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5024 AllowedNameModifiers.push_back(OMPD_parallel); 5025 if (LangOpts.OpenMP >= 50) 5026 AllowedNameModifiers.push_back(OMPD_simd); 5027 break; 5028 case OMPD_parallel_master: 5029 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 5030 StartLoc, EndLoc); 5031 AllowedNameModifiers.push_back(OMPD_parallel); 5032 break; 5033 case OMPD_parallel_sections: 5034 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 5035 StartLoc, EndLoc); 5036 AllowedNameModifiers.push_back(OMPD_parallel); 5037 break; 5038 case OMPD_task: 5039 Res = 5040 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5041 AllowedNameModifiers.push_back(OMPD_task); 5042 break; 5043 case OMPD_taskyield: 5044 assert(ClausesWithImplicit.empty() && 5045 "No clauses are allowed for 'omp taskyield' directive"); 5046 assert(AStmt == nullptr && 5047 "No associated statement allowed for 'omp taskyield' directive"); 5048 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 5049 break; 5050 case OMPD_barrier: 5051 assert(ClausesWithImplicit.empty() && 5052 "No clauses are allowed for 'omp barrier' directive"); 5053 assert(AStmt == nullptr && 5054 "No associated statement allowed for 'omp barrier' directive"); 5055 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 5056 break; 5057 case OMPD_taskwait: 5058 assert(ClausesWithImplicit.empty() && 5059 "No clauses are allowed for 'omp taskwait' directive"); 5060 assert(AStmt == nullptr && 5061 "No associated statement allowed for 'omp taskwait' directive"); 5062 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 5063 break; 5064 case OMPD_taskgroup: 5065 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 5066 EndLoc); 5067 break; 5068 case OMPD_flush: 5069 assert(AStmt == nullptr && 5070 "No associated statement allowed for 'omp flush' directive"); 5071 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 5072 break; 5073 case OMPD_depobj: 5074 assert(AStmt == nullptr && 5075 "No associated statement allowed for 'omp depobj' directive"); 5076 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 5077 break; 5078 case OMPD_scan: 5079 assert(AStmt == nullptr && 5080 "No associated statement allowed for 'omp scan' directive"); 5081 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 5082 break; 5083 case OMPD_ordered: 5084 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 5085 EndLoc); 5086 break; 5087 case OMPD_atomic: 5088 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 5089 EndLoc); 5090 break; 5091 case OMPD_teams: 5092 Res = 5093 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 5094 break; 5095 case OMPD_target: 5096 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 5097 EndLoc); 5098 AllowedNameModifiers.push_back(OMPD_target); 5099 break; 5100 case OMPD_target_parallel: 5101 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 5102 StartLoc, EndLoc); 5103 AllowedNameModifiers.push_back(OMPD_target); 5104 AllowedNameModifiers.push_back(OMPD_parallel); 5105 break; 5106 case OMPD_target_parallel_for: 5107 Res = ActOnOpenMPTargetParallelForDirective( 5108 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5109 AllowedNameModifiers.push_back(OMPD_target); 5110 AllowedNameModifiers.push_back(OMPD_parallel); 5111 break; 5112 case OMPD_cancellation_point: 5113 assert(ClausesWithImplicit.empty() && 5114 "No clauses are allowed for 'omp cancellation point' directive"); 5115 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 5116 "cancellation point' directive"); 5117 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 5118 break; 5119 case OMPD_cancel: 5120 assert(AStmt == nullptr && 5121 "No associated statement allowed for 'omp cancel' directive"); 5122 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 5123 CancelRegion); 5124 AllowedNameModifiers.push_back(OMPD_cancel); 5125 break; 5126 case OMPD_target_data: 5127 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 5128 EndLoc); 5129 AllowedNameModifiers.push_back(OMPD_target_data); 5130 break; 5131 case OMPD_target_enter_data: 5132 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 5133 EndLoc, AStmt); 5134 AllowedNameModifiers.push_back(OMPD_target_enter_data); 5135 break; 5136 case OMPD_target_exit_data: 5137 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 5138 EndLoc, AStmt); 5139 AllowedNameModifiers.push_back(OMPD_target_exit_data); 5140 break; 5141 case OMPD_taskloop: 5142 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 5143 EndLoc, VarsWithInheritedDSA); 5144 AllowedNameModifiers.push_back(OMPD_taskloop); 5145 break; 5146 case OMPD_taskloop_simd: 5147 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5148 EndLoc, VarsWithInheritedDSA); 5149 AllowedNameModifiers.push_back(OMPD_taskloop); 5150 if (LangOpts.OpenMP >= 50) 5151 AllowedNameModifiers.push_back(OMPD_simd); 5152 break; 5153 case OMPD_master_taskloop: 5154 Res = ActOnOpenMPMasterTaskLoopDirective( 5155 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5156 AllowedNameModifiers.push_back(OMPD_taskloop); 5157 break; 5158 case OMPD_master_taskloop_simd: 5159 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 5160 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5161 AllowedNameModifiers.push_back(OMPD_taskloop); 5162 if (LangOpts.OpenMP >= 50) 5163 AllowedNameModifiers.push_back(OMPD_simd); 5164 break; 5165 case OMPD_parallel_master_taskloop: 5166 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 5167 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5168 AllowedNameModifiers.push_back(OMPD_taskloop); 5169 AllowedNameModifiers.push_back(OMPD_parallel); 5170 break; 5171 case OMPD_parallel_master_taskloop_simd: 5172 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 5173 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5174 AllowedNameModifiers.push_back(OMPD_taskloop); 5175 AllowedNameModifiers.push_back(OMPD_parallel); 5176 if (LangOpts.OpenMP >= 50) 5177 AllowedNameModifiers.push_back(OMPD_simd); 5178 break; 5179 case OMPD_distribute: 5180 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 5181 EndLoc, VarsWithInheritedDSA); 5182 break; 5183 case OMPD_target_update: 5184 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 5185 EndLoc, AStmt); 5186 AllowedNameModifiers.push_back(OMPD_target_update); 5187 break; 5188 case OMPD_distribute_parallel_for: 5189 Res = ActOnOpenMPDistributeParallelForDirective( 5190 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5191 AllowedNameModifiers.push_back(OMPD_parallel); 5192 break; 5193 case OMPD_distribute_parallel_for_simd: 5194 Res = ActOnOpenMPDistributeParallelForSimdDirective( 5195 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5196 AllowedNameModifiers.push_back(OMPD_parallel); 5197 if (LangOpts.OpenMP >= 50) 5198 AllowedNameModifiers.push_back(OMPD_simd); 5199 break; 5200 case OMPD_distribute_simd: 5201 Res = ActOnOpenMPDistributeSimdDirective( 5202 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5203 if (LangOpts.OpenMP >= 50) 5204 AllowedNameModifiers.push_back(OMPD_simd); 5205 break; 5206 case OMPD_target_parallel_for_simd: 5207 Res = ActOnOpenMPTargetParallelForSimdDirective( 5208 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5209 AllowedNameModifiers.push_back(OMPD_target); 5210 AllowedNameModifiers.push_back(OMPD_parallel); 5211 if (LangOpts.OpenMP >= 50) 5212 AllowedNameModifiers.push_back(OMPD_simd); 5213 break; 5214 case OMPD_target_simd: 5215 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 5216 EndLoc, VarsWithInheritedDSA); 5217 AllowedNameModifiers.push_back(OMPD_target); 5218 if (LangOpts.OpenMP >= 50) 5219 AllowedNameModifiers.push_back(OMPD_simd); 5220 break; 5221 case OMPD_teams_distribute: 5222 Res = ActOnOpenMPTeamsDistributeDirective( 5223 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5224 break; 5225 case OMPD_teams_distribute_simd: 5226 Res = ActOnOpenMPTeamsDistributeSimdDirective( 5227 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5228 if (LangOpts.OpenMP >= 50) 5229 AllowedNameModifiers.push_back(OMPD_simd); 5230 break; 5231 case OMPD_teams_distribute_parallel_for_simd: 5232 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 5233 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5234 AllowedNameModifiers.push_back(OMPD_parallel); 5235 if (LangOpts.OpenMP >= 50) 5236 AllowedNameModifiers.push_back(OMPD_simd); 5237 break; 5238 case OMPD_teams_distribute_parallel_for: 5239 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 5240 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5241 AllowedNameModifiers.push_back(OMPD_parallel); 5242 break; 5243 case OMPD_target_teams: 5244 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 5245 EndLoc); 5246 AllowedNameModifiers.push_back(OMPD_target); 5247 break; 5248 case OMPD_target_teams_distribute: 5249 Res = ActOnOpenMPTargetTeamsDistributeDirective( 5250 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5251 AllowedNameModifiers.push_back(OMPD_target); 5252 break; 5253 case OMPD_target_teams_distribute_parallel_for: 5254 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 5255 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5256 AllowedNameModifiers.push_back(OMPD_target); 5257 AllowedNameModifiers.push_back(OMPD_parallel); 5258 break; 5259 case OMPD_target_teams_distribute_parallel_for_simd: 5260 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 5261 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5262 AllowedNameModifiers.push_back(OMPD_target); 5263 AllowedNameModifiers.push_back(OMPD_parallel); 5264 if (LangOpts.OpenMP >= 50) 5265 AllowedNameModifiers.push_back(OMPD_simd); 5266 break; 5267 case OMPD_target_teams_distribute_simd: 5268 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 5269 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 5270 AllowedNameModifiers.push_back(OMPD_target); 5271 if (LangOpts.OpenMP >= 50) 5272 AllowedNameModifiers.push_back(OMPD_simd); 5273 break; 5274 case OMPD_declare_target: 5275 case OMPD_end_declare_target: 5276 case OMPD_threadprivate: 5277 case OMPD_allocate: 5278 case OMPD_declare_reduction: 5279 case OMPD_declare_mapper: 5280 case OMPD_declare_simd: 5281 case OMPD_requires: 5282 case OMPD_declare_variant: 5283 case OMPD_begin_declare_variant: 5284 case OMPD_end_declare_variant: 5285 llvm_unreachable("OpenMP Directive is not allowed"); 5286 case OMPD_unknown: 5287 llvm_unreachable("Unknown OpenMP directive"); 5288 } 5289 5290 ErrorFound = Res.isInvalid() || ErrorFound; 5291 5292 // Check variables in the clauses if default(none) was specified. 5293 if (DSAStack->getDefaultDSA() == DSA_none) { 5294 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 5295 for (OMPClause *C : Clauses) { 5296 switch (C->getClauseKind()) { 5297 case OMPC_num_threads: 5298 case OMPC_dist_schedule: 5299 // Do not analyse if no parent teams directive. 5300 if (isOpenMPTeamsDirective(Kind)) 5301 break; 5302 continue; 5303 case OMPC_if: 5304 if (isOpenMPTeamsDirective(Kind) && 5305 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 5306 break; 5307 if (isOpenMPParallelDirective(Kind) && 5308 isOpenMPTaskLoopDirective(Kind) && 5309 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 5310 break; 5311 continue; 5312 case OMPC_schedule: 5313 case OMPC_detach: 5314 break; 5315 case OMPC_grainsize: 5316 case OMPC_num_tasks: 5317 case OMPC_final: 5318 case OMPC_priority: 5319 // Do not analyze if no parent parallel directive. 5320 if (isOpenMPParallelDirective(Kind)) 5321 break; 5322 continue; 5323 case OMPC_ordered: 5324 case OMPC_device: 5325 case OMPC_num_teams: 5326 case OMPC_thread_limit: 5327 case OMPC_hint: 5328 case OMPC_collapse: 5329 case OMPC_safelen: 5330 case OMPC_simdlen: 5331 case OMPC_default: 5332 case OMPC_proc_bind: 5333 case OMPC_private: 5334 case OMPC_firstprivate: 5335 case OMPC_lastprivate: 5336 case OMPC_shared: 5337 case OMPC_reduction: 5338 case OMPC_task_reduction: 5339 case OMPC_in_reduction: 5340 case OMPC_linear: 5341 case OMPC_aligned: 5342 case OMPC_copyin: 5343 case OMPC_copyprivate: 5344 case OMPC_nowait: 5345 case OMPC_untied: 5346 case OMPC_mergeable: 5347 case OMPC_allocate: 5348 case OMPC_read: 5349 case OMPC_write: 5350 case OMPC_update: 5351 case OMPC_capture: 5352 case OMPC_seq_cst: 5353 case OMPC_acq_rel: 5354 case OMPC_acquire: 5355 case OMPC_release: 5356 case OMPC_relaxed: 5357 case OMPC_depend: 5358 case OMPC_threads: 5359 case OMPC_simd: 5360 case OMPC_map: 5361 case OMPC_nogroup: 5362 case OMPC_defaultmap: 5363 case OMPC_to: 5364 case OMPC_from: 5365 case OMPC_use_device_ptr: 5366 case OMPC_is_device_ptr: 5367 case OMPC_nontemporal: 5368 case OMPC_order: 5369 case OMPC_destroy: 5370 case OMPC_inclusive: 5371 case OMPC_exclusive: 5372 case OMPC_uses_allocators: 5373 continue; 5374 case OMPC_allocator: 5375 case OMPC_flush: 5376 case OMPC_depobj: 5377 case OMPC_threadprivate: 5378 case OMPC_uniform: 5379 case OMPC_unknown: 5380 case OMPC_unified_address: 5381 case OMPC_unified_shared_memory: 5382 case OMPC_reverse_offload: 5383 case OMPC_dynamic_allocators: 5384 case OMPC_atomic_default_mem_order: 5385 case OMPC_device_type: 5386 case OMPC_match: 5387 llvm_unreachable("Unexpected clause"); 5388 } 5389 for (Stmt *CC : C->children()) { 5390 if (CC) 5391 DSAChecker.Visit(CC); 5392 } 5393 } 5394 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 5395 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 5396 } 5397 for (const auto &P : VarsWithInheritedDSA) { 5398 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 5399 continue; 5400 ErrorFound = true; 5401 if (DSAStack->getDefaultDSA() == DSA_none) { 5402 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 5403 << P.first << P.second->getSourceRange(); 5404 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 5405 } else if (getLangOpts().OpenMP >= 50) { 5406 Diag(P.second->getExprLoc(), 5407 diag::err_omp_defaultmap_no_attr_for_variable) 5408 << P.first << P.second->getSourceRange(); 5409 Diag(DSAStack->getDefaultDSALocation(), 5410 diag::note_omp_defaultmap_attr_none); 5411 } 5412 } 5413 5414 if (!AllowedNameModifiers.empty()) 5415 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 5416 ErrorFound; 5417 5418 if (ErrorFound) 5419 return StmtError(); 5420 5421 if (!CurContext->isDependentContext() && 5422 isOpenMPTargetExecutionDirective(Kind) && 5423 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 5424 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 5425 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 5426 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 5427 // Register target to DSA Stack. 5428 DSAStack->addTargetDirLocation(StartLoc); 5429 } 5430 5431 return Res; 5432 } 5433 5434 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 5435 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 5436 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 5437 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 5438 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 5439 assert(Aligneds.size() == Alignments.size()); 5440 assert(Linears.size() == LinModifiers.size()); 5441 assert(Linears.size() == Steps.size()); 5442 if (!DG || DG.get().isNull()) 5443 return DeclGroupPtrTy(); 5444 5445 const int SimdId = 0; 5446 if (!DG.get().isSingleDecl()) { 5447 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5448 << SimdId; 5449 return DG; 5450 } 5451 Decl *ADecl = DG.get().getSingleDecl(); 5452 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5453 ADecl = FTD->getTemplatedDecl(); 5454 5455 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5456 if (!FD) { 5457 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 5458 return DeclGroupPtrTy(); 5459 } 5460 5461 // OpenMP [2.8.2, declare simd construct, Description] 5462 // The parameter of the simdlen clause must be a constant positive integer 5463 // expression. 5464 ExprResult SL; 5465 if (Simdlen) 5466 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 5467 // OpenMP [2.8.2, declare simd construct, Description] 5468 // The special this pointer can be used as if was one of the arguments to the 5469 // function in any of the linear, aligned, or uniform clauses. 5470 // The uniform clause declares one or more arguments to have an invariant 5471 // value for all concurrent invocations of the function in the execution of a 5472 // single SIMD loop. 5473 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 5474 const Expr *UniformedLinearThis = nullptr; 5475 for (const Expr *E : Uniforms) { 5476 E = E->IgnoreParenImpCasts(); 5477 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5478 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 5479 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5480 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5481 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 5482 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 5483 continue; 5484 } 5485 if (isa<CXXThisExpr>(E)) { 5486 UniformedLinearThis = E; 5487 continue; 5488 } 5489 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5490 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5491 } 5492 // OpenMP [2.8.2, declare simd construct, Description] 5493 // The aligned clause declares that the object to which each list item points 5494 // is aligned to the number of bytes expressed in the optional parameter of 5495 // the aligned clause. 5496 // The special this pointer can be used as if was one of the arguments to the 5497 // function in any of the linear, aligned, or uniform clauses. 5498 // The type of list items appearing in the aligned clause must be array, 5499 // pointer, reference to array, or reference to pointer. 5500 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 5501 const Expr *AlignedThis = nullptr; 5502 for (const Expr *E : Aligneds) { 5503 E = E->IgnoreParenImpCasts(); 5504 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5505 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5506 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5507 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5508 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5509 ->getCanonicalDecl() == CanonPVD) { 5510 // OpenMP [2.8.1, simd construct, Restrictions] 5511 // A list-item cannot appear in more than one aligned clause. 5512 if (AlignedArgs.count(CanonPVD) > 0) { 5513 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5514 << 1 << getOpenMPClauseName(OMPC_aligned) 5515 << E->getSourceRange(); 5516 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 5517 diag::note_omp_explicit_dsa) 5518 << getOpenMPClauseName(OMPC_aligned); 5519 continue; 5520 } 5521 AlignedArgs[CanonPVD] = E; 5522 QualType QTy = PVD->getType() 5523 .getNonReferenceType() 5524 .getUnqualifiedType() 5525 .getCanonicalType(); 5526 const Type *Ty = QTy.getTypePtrOrNull(); 5527 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 5528 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 5529 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 5530 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 5531 } 5532 continue; 5533 } 5534 } 5535 if (isa<CXXThisExpr>(E)) { 5536 if (AlignedThis) { 5537 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 5538 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 5539 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 5540 << getOpenMPClauseName(OMPC_aligned); 5541 } 5542 AlignedThis = E; 5543 continue; 5544 } 5545 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5546 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5547 } 5548 // The optional parameter of the aligned clause, alignment, must be a constant 5549 // positive integer expression. If no optional parameter is specified, 5550 // implementation-defined default alignments for SIMD instructions on the 5551 // target platforms are assumed. 5552 SmallVector<const Expr *, 4> NewAligns; 5553 for (Expr *E : Alignments) { 5554 ExprResult Align; 5555 if (E) 5556 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 5557 NewAligns.push_back(Align.get()); 5558 } 5559 // OpenMP [2.8.2, declare simd construct, Description] 5560 // The linear clause declares one or more list items to be private to a SIMD 5561 // lane and to have a linear relationship with respect to the iteration space 5562 // of a loop. 5563 // The special this pointer can be used as if was one of the arguments to the 5564 // function in any of the linear, aligned, or uniform clauses. 5565 // When a linear-step expression is specified in a linear clause it must be 5566 // either a constant integer expression or an integer-typed parameter that is 5567 // specified in a uniform clause on the directive. 5568 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 5569 const bool IsUniformedThis = UniformedLinearThis != nullptr; 5570 auto MI = LinModifiers.begin(); 5571 for (const Expr *E : Linears) { 5572 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 5573 ++MI; 5574 E = E->IgnoreParenImpCasts(); 5575 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 5576 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5577 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5578 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 5579 FD->getParamDecl(PVD->getFunctionScopeIndex()) 5580 ->getCanonicalDecl() == CanonPVD) { 5581 // OpenMP [2.15.3.7, linear Clause, Restrictions] 5582 // A list-item cannot appear in more than one linear clause. 5583 if (LinearArgs.count(CanonPVD) > 0) { 5584 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5585 << getOpenMPClauseName(OMPC_linear) 5586 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 5587 Diag(LinearArgs[CanonPVD]->getExprLoc(), 5588 diag::note_omp_explicit_dsa) 5589 << getOpenMPClauseName(OMPC_linear); 5590 continue; 5591 } 5592 // Each argument can appear in at most one uniform or linear clause. 5593 if (UniformedArgs.count(CanonPVD) > 0) { 5594 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5595 << getOpenMPClauseName(OMPC_linear) 5596 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 5597 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 5598 diag::note_omp_explicit_dsa) 5599 << getOpenMPClauseName(OMPC_uniform); 5600 continue; 5601 } 5602 LinearArgs[CanonPVD] = E; 5603 if (E->isValueDependent() || E->isTypeDependent() || 5604 E->isInstantiationDependent() || 5605 E->containsUnexpandedParameterPack()) 5606 continue; 5607 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 5608 PVD->getOriginalType(), 5609 /*IsDeclareSimd=*/true); 5610 continue; 5611 } 5612 } 5613 if (isa<CXXThisExpr>(E)) { 5614 if (UniformedLinearThis) { 5615 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 5616 << getOpenMPClauseName(OMPC_linear) 5617 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 5618 << E->getSourceRange(); 5619 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 5620 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 5621 : OMPC_linear); 5622 continue; 5623 } 5624 UniformedLinearThis = E; 5625 if (E->isValueDependent() || E->isTypeDependent() || 5626 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 5627 continue; 5628 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 5629 E->getType(), /*IsDeclareSimd=*/true); 5630 continue; 5631 } 5632 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 5633 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 5634 } 5635 Expr *Step = nullptr; 5636 Expr *NewStep = nullptr; 5637 SmallVector<Expr *, 4> NewSteps; 5638 for (Expr *E : Steps) { 5639 // Skip the same step expression, it was checked already. 5640 if (Step == E || !E) { 5641 NewSteps.push_back(E ? NewStep : nullptr); 5642 continue; 5643 } 5644 Step = E; 5645 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 5646 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 5647 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 5648 if (UniformedArgs.count(CanonPVD) == 0) { 5649 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 5650 << Step->getSourceRange(); 5651 } else if (E->isValueDependent() || E->isTypeDependent() || 5652 E->isInstantiationDependent() || 5653 E->containsUnexpandedParameterPack() || 5654 CanonPVD->getType()->hasIntegerRepresentation()) { 5655 NewSteps.push_back(Step); 5656 } else { 5657 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 5658 << Step->getSourceRange(); 5659 } 5660 continue; 5661 } 5662 NewStep = Step; 5663 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5664 !Step->isInstantiationDependent() && 5665 !Step->containsUnexpandedParameterPack()) { 5666 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 5667 .get(); 5668 if (NewStep) 5669 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 5670 } 5671 NewSteps.push_back(NewStep); 5672 } 5673 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 5674 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 5675 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 5676 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 5677 const_cast<Expr **>(Linears.data()), Linears.size(), 5678 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 5679 NewSteps.data(), NewSteps.size(), SR); 5680 ADecl->addAttr(NewAttr); 5681 return DG; 5682 } 5683 5684 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 5685 QualType NewType) { 5686 assert(NewType->isFunctionProtoType() && 5687 "Expected function type with prototype."); 5688 assert(FD->getType()->isFunctionNoProtoType() && 5689 "Expected function with type with no prototype."); 5690 assert(FDWithProto->getType()->isFunctionProtoType() && 5691 "Expected function with prototype."); 5692 // Synthesize parameters with the same types. 5693 FD->setType(NewType); 5694 SmallVector<ParmVarDecl *, 16> Params; 5695 for (const ParmVarDecl *P : FDWithProto->parameters()) { 5696 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 5697 SourceLocation(), nullptr, P->getType(), 5698 /*TInfo=*/nullptr, SC_None, nullptr); 5699 Param->setScopeInfo(0, Params.size()); 5700 Param->setImplicit(); 5701 Params.push_back(Param); 5702 } 5703 5704 FD->setParams(Params); 5705 } 5706 5707 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 5708 : TI(&TI), NameSuffix(TI.getMangledName()) {} 5709 5710 FunctionDecl * 5711 Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope(Scope *S, 5712 Declarator &D) { 5713 IdentifierInfo *BaseII = D.getIdentifier(); 5714 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 5715 LookupOrdinaryName); 5716 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 5717 5718 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 5719 QualType FType = TInfo->getType(); 5720 5721 bool IsConstexpr = D.getDeclSpec().getConstexprSpecifier() == CSK_constexpr; 5722 bool IsConsteval = D.getDeclSpec().getConstexprSpecifier() == CSK_consteval; 5723 5724 FunctionDecl *BaseFD = nullptr; 5725 for (auto *Candidate : Lookup) { 5726 auto *UDecl = dyn_cast<FunctionDecl>(Candidate->getUnderlyingDecl()); 5727 if (!UDecl) 5728 continue; 5729 5730 // Don't specialize constexpr/consteval functions with 5731 // non-constexpr/consteval functions. 5732 if (UDecl->isConstexpr() && !IsConstexpr) 5733 continue; 5734 if (UDecl->isConsteval() && !IsConsteval) 5735 continue; 5736 5737 QualType NewType = Context.mergeFunctionTypes( 5738 FType, UDecl->getType(), /* OfBlockPointer */ false, 5739 /* Unqualified */ false, /* AllowCXX */ true); 5740 if (NewType.isNull()) 5741 continue; 5742 5743 // Found a base! 5744 BaseFD = UDecl; 5745 break; 5746 } 5747 if (!BaseFD) { 5748 BaseFD = cast<FunctionDecl>(ActOnDeclarator(S, D)); 5749 BaseFD->setImplicit(true); 5750 } 5751 5752 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5753 std::string MangledName; 5754 MangledName += D.getIdentifier()->getName(); 5755 MangledName += getOpenMPVariantManglingSeparatorStr(); 5756 MangledName += DVScope.NameSuffix; 5757 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 5758 5759 VariantII.setMangledOpenMPVariantName(true); 5760 D.SetIdentifier(&VariantII, D.getBeginLoc()); 5761 return BaseFD; 5762 } 5763 5764 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 5765 FunctionDecl *FD, FunctionDecl *BaseFD) { 5766 // Do not mark function as is used to prevent its emission if this is the 5767 // only place where it is used. 5768 EnterExpressionEvaluationContext Unevaluated( 5769 *this, Sema::ExpressionEvaluationContext::Unevaluated); 5770 5771 Expr *VariantFuncRef = DeclRefExpr::Create( 5772 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 5773 /* RefersToEnclosingVariableOrCapture */ false, 5774 /* NameLoc */ FD->getLocation(), FD->getType(), ExprValueKind::VK_RValue); 5775 5776 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 5777 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 5778 Context, VariantFuncRef, DVScope.TI); 5779 BaseFD->addAttr(OMPDeclareVariantA); 5780 } 5781 5782 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 5783 SourceLocation LParenLoc, 5784 MultiExprArg ArgExprs, 5785 SourceLocation RParenLoc, Expr *ExecConfig) { 5786 // The common case is a regular call we do not want to specialize at all. Try 5787 // to make that case fast by bailing early. 5788 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 5789 if (!CE) 5790 return Call; 5791 5792 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 5793 if (!CalleeFnDecl) 5794 return Call; 5795 5796 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 5797 return Call; 5798 5799 ASTContext &Context = getASTContext(); 5800 OMPContext OMPCtx(getLangOpts().OpenMPIsDevice, 5801 Context.getTargetInfo().getTriple()); 5802 5803 SmallVector<Expr *, 4> Exprs; 5804 SmallVector<VariantMatchInfo, 4> VMIs; 5805 while (CalleeFnDecl) { 5806 for (OMPDeclareVariantAttr *A : 5807 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 5808 Expr *VariantRef = A->getVariantFuncRef(); 5809 5810 VariantMatchInfo VMI; 5811 OMPTraitInfo &TI = A->getTraitInfo(); 5812 TI.getAsVariantMatchInfo(Context, VMI); 5813 if (!isVariantApplicableInContext(VMI, OMPCtx, /* DeviceSetOnly */ false)) 5814 continue; 5815 5816 VMIs.push_back(VMI); 5817 Exprs.push_back(VariantRef); 5818 } 5819 5820 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 5821 } 5822 5823 ExprResult NewCall; 5824 do { 5825 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 5826 if (BestIdx < 0) 5827 return Call; 5828 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 5829 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 5830 5831 { 5832 // Try to build a (member) call expression for the current best applicable 5833 // variant expression. We allow this to fail in which case we continue 5834 // with the next best variant expression. The fail case is part of the 5835 // implementation defined behavior in the OpenMP standard when it talks 5836 // about what differences in the function prototypes: "Any differences 5837 // that the specific OpenMP context requires in the prototype of the 5838 // variant from the base function prototype are implementation defined." 5839 // This wording is there to allow the specialized variant to have a 5840 // different type than the base function. This is intended and OK but if 5841 // we cannot create a call the difference is not in the "implementation 5842 // defined range" we allow. 5843 Sema::TentativeAnalysisScope Trap(*this); 5844 5845 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 5846 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 5847 BestExpr = MemberExpr::CreateImplicit( 5848 Context, MemberCall->getImplicitObjectArgument(), 5849 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 5850 MemberCall->getValueKind(), MemberCall->getObjectKind()); 5851 } 5852 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 5853 ExecConfig); 5854 if (NewCall.isUsable()) 5855 break; 5856 } 5857 5858 VMIs.erase(VMIs.begin() + BestIdx); 5859 Exprs.erase(Exprs.begin() + BestIdx); 5860 } while (!VMIs.empty()); 5861 5862 if (!NewCall.isUsable()) 5863 return Call; 5864 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 5865 } 5866 5867 Optional<std::pair<FunctionDecl *, Expr *>> 5868 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 5869 Expr *VariantRef, OMPTraitInfo &TI, 5870 SourceRange SR) { 5871 if (!DG || DG.get().isNull()) 5872 return None; 5873 5874 const int VariantId = 1; 5875 // Must be applied only to single decl. 5876 if (!DG.get().isSingleDecl()) { 5877 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 5878 << VariantId << SR; 5879 return None; 5880 } 5881 Decl *ADecl = DG.get().getSingleDecl(); 5882 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 5883 ADecl = FTD->getTemplatedDecl(); 5884 5885 // Decl must be a function. 5886 auto *FD = dyn_cast<FunctionDecl>(ADecl); 5887 if (!FD) { 5888 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 5889 << VariantId << SR; 5890 return None; 5891 } 5892 5893 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 5894 return FD->hasAttrs() && 5895 (FD->hasAttr<CPUDispatchAttr>() || FD->hasAttr<CPUSpecificAttr>() || 5896 FD->hasAttr<TargetAttr>()); 5897 }; 5898 // OpenMP is not compatible with CPU-specific attributes. 5899 if (HasMultiVersionAttributes(FD)) { 5900 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 5901 << SR; 5902 return None; 5903 } 5904 5905 // Allow #pragma omp declare variant only if the function is not used. 5906 if (FD->isUsed(false)) 5907 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 5908 << FD->getLocation(); 5909 5910 // Check if the function was emitted already. 5911 const FunctionDecl *Definition; 5912 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 5913 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 5914 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 5915 << FD->getLocation(); 5916 5917 // The VariantRef must point to function. 5918 if (!VariantRef) { 5919 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 5920 return None; 5921 } 5922 5923 auto ShouldDelayChecks = [](Expr *&E, bool) { 5924 return E && (E->isTypeDependent() || E->isValueDependent() || 5925 E->containsUnexpandedParameterPack() || 5926 E->isInstantiationDependent()); 5927 }; 5928 // Do not check templates, wait until instantiation. 5929 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 5930 TI.anyScoreOrCondition(ShouldDelayChecks)) 5931 return std::make_pair(FD, VariantRef); 5932 5933 // Deal with non-constant score and user condition expressions. 5934 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 5935 bool IsScore) -> bool { 5936 llvm::APSInt Result; 5937 if (!E || E->isIntegerConstantExpr(Result, Context)) 5938 return false; 5939 5940 if (IsScore) { 5941 // We warn on non-constant scores and pretend they were not present. 5942 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 5943 << E; 5944 E = nullptr; 5945 } else { 5946 // We could replace a non-constant user condition with "false" but we 5947 // will soon need to handle these anyway for the dynamic version of 5948 // OpenMP context selectors. 5949 Diag(E->getExprLoc(), 5950 diag::err_omp_declare_variant_user_condition_not_constant) 5951 << E; 5952 } 5953 return true; 5954 }; 5955 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 5956 return None; 5957 5958 // Convert VariantRef expression to the type of the original function to 5959 // resolve possible conflicts. 5960 ExprResult VariantRefCast; 5961 if (LangOpts.CPlusPlus) { 5962 QualType FnPtrType; 5963 auto *Method = dyn_cast<CXXMethodDecl>(FD); 5964 if (Method && !Method->isStatic()) { 5965 const Type *ClassType = 5966 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 5967 FnPtrType = Context.getMemberPointerType(FD->getType(), ClassType); 5968 ExprResult ER; 5969 { 5970 // Build adrr_of unary op to correctly handle type checks for member 5971 // functions. 5972 Sema::TentativeAnalysisScope Trap(*this); 5973 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 5974 VariantRef); 5975 } 5976 if (!ER.isUsable()) { 5977 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 5978 << VariantId << VariantRef->getSourceRange(); 5979 return None; 5980 } 5981 VariantRef = ER.get(); 5982 } else { 5983 FnPtrType = Context.getPointerType(FD->getType()); 5984 } 5985 ImplicitConversionSequence ICS = 5986 TryImplicitConversion(VariantRef, FnPtrType.getUnqualifiedType(), 5987 /*SuppressUserConversions=*/false, 5988 AllowedExplicit::None, 5989 /*InOverloadResolution=*/false, 5990 /*CStyle=*/false, 5991 /*AllowObjCWritebackConversion=*/false); 5992 if (ICS.isFailure()) { 5993 Diag(VariantRef->getExprLoc(), 5994 diag::err_omp_declare_variant_incompat_types) 5995 << VariantRef->getType() 5996 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 5997 << VariantRef->getSourceRange(); 5998 return None; 5999 } 6000 VariantRefCast = PerformImplicitConversion( 6001 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 6002 if (!VariantRefCast.isUsable()) 6003 return None; 6004 // Drop previously built artificial addr_of unary op for member functions. 6005 if (Method && !Method->isStatic()) { 6006 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 6007 if (auto *UO = dyn_cast<UnaryOperator>( 6008 PossibleAddrOfVariantRef->IgnoreImplicit())) 6009 VariantRefCast = UO->getSubExpr(); 6010 } 6011 } else { 6012 VariantRefCast = VariantRef; 6013 } 6014 6015 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 6016 if (!ER.isUsable() || 6017 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 6018 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6019 << VariantId << VariantRef->getSourceRange(); 6020 return None; 6021 } 6022 6023 // The VariantRef must point to function. 6024 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 6025 if (!DRE) { 6026 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6027 << VariantId << VariantRef->getSourceRange(); 6028 return None; 6029 } 6030 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 6031 if (!NewFD) { 6032 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 6033 << VariantId << VariantRef->getSourceRange(); 6034 return None; 6035 } 6036 6037 // Check if function types are compatible in C. 6038 if (!LangOpts.CPlusPlus) { 6039 QualType NewType = 6040 Context.mergeFunctionTypes(FD->getType(), NewFD->getType()); 6041 if (NewType.isNull()) { 6042 Diag(VariantRef->getExprLoc(), 6043 diag::err_omp_declare_variant_incompat_types) 6044 << NewFD->getType() << FD->getType() << VariantRef->getSourceRange(); 6045 return None; 6046 } 6047 if (NewType->isFunctionProtoType()) { 6048 if (FD->getType()->isFunctionNoProtoType()) 6049 setPrototype(*this, FD, NewFD, NewType); 6050 else if (NewFD->getType()->isFunctionNoProtoType()) 6051 setPrototype(*this, NewFD, FD, NewType); 6052 } 6053 } 6054 6055 // Check if variant function is not marked with declare variant directive. 6056 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 6057 Diag(VariantRef->getExprLoc(), 6058 diag::warn_omp_declare_variant_marked_as_declare_variant) 6059 << VariantRef->getSourceRange(); 6060 SourceRange SR = 6061 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 6062 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 6063 return None; 6064 } 6065 6066 enum DoesntSupport { 6067 VirtFuncs = 1, 6068 Constructors = 3, 6069 Destructors = 4, 6070 DeletedFuncs = 5, 6071 DefaultedFuncs = 6, 6072 ConstexprFuncs = 7, 6073 ConstevalFuncs = 8, 6074 }; 6075 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 6076 if (CXXFD->isVirtual()) { 6077 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6078 << VirtFuncs; 6079 return None; 6080 } 6081 6082 if (isa<CXXConstructorDecl>(FD)) { 6083 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6084 << Constructors; 6085 return None; 6086 } 6087 6088 if (isa<CXXDestructorDecl>(FD)) { 6089 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6090 << Destructors; 6091 return None; 6092 } 6093 } 6094 6095 if (FD->isDeleted()) { 6096 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6097 << DeletedFuncs; 6098 return None; 6099 } 6100 6101 if (FD->isDefaulted()) { 6102 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6103 << DefaultedFuncs; 6104 return None; 6105 } 6106 6107 if (FD->isConstexpr()) { 6108 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 6109 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 6110 return None; 6111 } 6112 6113 // Check general compatibility. 6114 if (areMultiversionVariantFunctionsCompatible( 6115 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 6116 PartialDiagnosticAt(SourceLocation(), 6117 PartialDiagnostic::NullDiagnostic()), 6118 PartialDiagnosticAt( 6119 VariantRef->getExprLoc(), 6120 PDiag(diag::err_omp_declare_variant_doesnt_support)), 6121 PartialDiagnosticAt(VariantRef->getExprLoc(), 6122 PDiag(diag::err_omp_declare_variant_diff) 6123 << FD->getLocation()), 6124 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 6125 /*CLinkageMayDiffer=*/true)) 6126 return None; 6127 return std::make_pair(FD, cast<Expr>(DRE)); 6128 } 6129 6130 void Sema::ActOnOpenMPDeclareVariantDirective(FunctionDecl *FD, 6131 Expr *VariantRef, 6132 OMPTraitInfo &TI, 6133 SourceRange SR) { 6134 auto *NewAttr = 6135 OMPDeclareVariantAttr::CreateImplicit(Context, VariantRef, &TI, SR); 6136 FD->addAttr(NewAttr); 6137 } 6138 6139 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 6140 Stmt *AStmt, 6141 SourceLocation StartLoc, 6142 SourceLocation EndLoc) { 6143 if (!AStmt) 6144 return StmtError(); 6145 6146 auto *CS = cast<CapturedStmt>(AStmt); 6147 // 1.2.2 OpenMP Language Terminology 6148 // Structured block - An executable statement with a single entry at the 6149 // top and a single exit at the bottom. 6150 // The point of exit cannot be a branch out of the structured block. 6151 // longjmp() and throw() must not violate the entry/exit criteria. 6152 CS->getCapturedDecl()->setNothrow(); 6153 6154 setFunctionHasBranchProtectedScope(); 6155 6156 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6157 DSAStack->getTaskgroupReductionRef(), 6158 DSAStack->isCancelRegion()); 6159 } 6160 6161 namespace { 6162 /// Iteration space of a single for loop. 6163 struct LoopIterationSpace final { 6164 /// True if the condition operator is the strict compare operator (<, > or 6165 /// !=). 6166 bool IsStrictCompare = false; 6167 /// Condition of the loop. 6168 Expr *PreCond = nullptr; 6169 /// This expression calculates the number of iterations in the loop. 6170 /// It is always possible to calculate it before starting the loop. 6171 Expr *NumIterations = nullptr; 6172 /// The loop counter variable. 6173 Expr *CounterVar = nullptr; 6174 /// Private loop counter variable. 6175 Expr *PrivateCounterVar = nullptr; 6176 /// This is initializer for the initial value of #CounterVar. 6177 Expr *CounterInit = nullptr; 6178 /// This is step for the #CounterVar used to generate its update: 6179 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 6180 Expr *CounterStep = nullptr; 6181 /// Should step be subtracted? 6182 bool Subtract = false; 6183 /// Source range of the loop init. 6184 SourceRange InitSrcRange; 6185 /// Source range of the loop condition. 6186 SourceRange CondSrcRange; 6187 /// Source range of the loop increment. 6188 SourceRange IncSrcRange; 6189 /// Minimum value that can have the loop control variable. Used to support 6190 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 6191 /// since only such variables can be used in non-loop invariant expressions. 6192 Expr *MinValue = nullptr; 6193 /// Maximum value that can have the loop control variable. Used to support 6194 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 6195 /// since only such variables can be used in non-loop invariant expressions. 6196 Expr *MaxValue = nullptr; 6197 /// true, if the lower bound depends on the outer loop control var. 6198 bool IsNonRectangularLB = false; 6199 /// true, if the upper bound depends on the outer loop control var. 6200 bool IsNonRectangularUB = false; 6201 /// Index of the loop this loop depends on and forms non-rectangular loop 6202 /// nest. 6203 unsigned LoopDependentIdx = 0; 6204 /// Final condition for the non-rectangular loop nest support. It is used to 6205 /// check that the number of iterations for this particular counter must be 6206 /// finished. 6207 Expr *FinalCondition = nullptr; 6208 }; 6209 6210 /// Helper class for checking canonical form of the OpenMP loops and 6211 /// extracting iteration space of each loop in the loop nest, that will be used 6212 /// for IR generation. 6213 class OpenMPIterationSpaceChecker { 6214 /// Reference to Sema. 6215 Sema &SemaRef; 6216 /// Data-sharing stack. 6217 DSAStackTy &Stack; 6218 /// A location for diagnostics (when there is no some better location). 6219 SourceLocation DefaultLoc; 6220 /// A location for diagnostics (when increment is not compatible). 6221 SourceLocation ConditionLoc; 6222 /// A source location for referring to loop init later. 6223 SourceRange InitSrcRange; 6224 /// A source location for referring to condition later. 6225 SourceRange ConditionSrcRange; 6226 /// A source location for referring to increment later. 6227 SourceRange IncrementSrcRange; 6228 /// Loop variable. 6229 ValueDecl *LCDecl = nullptr; 6230 /// Reference to loop variable. 6231 Expr *LCRef = nullptr; 6232 /// Lower bound (initializer for the var). 6233 Expr *LB = nullptr; 6234 /// Upper bound. 6235 Expr *UB = nullptr; 6236 /// Loop step (increment). 6237 Expr *Step = nullptr; 6238 /// This flag is true when condition is one of: 6239 /// Var < UB 6240 /// Var <= UB 6241 /// UB > Var 6242 /// UB >= Var 6243 /// This will have no value when the condition is != 6244 llvm::Optional<bool> TestIsLessOp; 6245 /// This flag is true when condition is strict ( < or > ). 6246 bool TestIsStrictOp = false; 6247 /// This flag is true when step is subtracted on each iteration. 6248 bool SubtractStep = false; 6249 /// The outer loop counter this loop depends on (if any). 6250 const ValueDecl *DepDecl = nullptr; 6251 /// Contains number of loop (starts from 1) on which loop counter init 6252 /// expression of this loop depends on. 6253 Optional<unsigned> InitDependOnLC; 6254 /// Contains number of loop (starts from 1) on which loop counter condition 6255 /// expression of this loop depends on. 6256 Optional<unsigned> CondDependOnLC; 6257 /// Checks if the provide statement depends on the loop counter. 6258 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 6259 /// Original condition required for checking of the exit condition for 6260 /// non-rectangular loop. 6261 Expr *Condition = nullptr; 6262 6263 public: 6264 OpenMPIterationSpaceChecker(Sema &SemaRef, DSAStackTy &Stack, 6265 SourceLocation DefaultLoc) 6266 : SemaRef(SemaRef), Stack(Stack), DefaultLoc(DefaultLoc), 6267 ConditionLoc(DefaultLoc) {} 6268 /// Check init-expr for canonical loop form and save loop counter 6269 /// variable - #Var and its initialization value - #LB. 6270 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 6271 /// Check test-expr for canonical form, save upper-bound (#UB), flags 6272 /// for less/greater and for strict/non-strict comparison. 6273 bool checkAndSetCond(Expr *S); 6274 /// Check incr-expr for canonical loop form and return true if it 6275 /// does not conform, otherwise save loop step (#Step). 6276 bool checkAndSetInc(Expr *S); 6277 /// Return the loop counter variable. 6278 ValueDecl *getLoopDecl() const { return LCDecl; } 6279 /// Return the reference expression to loop counter variable. 6280 Expr *getLoopDeclRefExpr() const { return LCRef; } 6281 /// Source range of the loop init. 6282 SourceRange getInitSrcRange() const { return InitSrcRange; } 6283 /// Source range of the loop condition. 6284 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 6285 /// Source range of the loop increment. 6286 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 6287 /// True if the step should be subtracted. 6288 bool shouldSubtractStep() const { return SubtractStep; } 6289 /// True, if the compare operator is strict (<, > or !=). 6290 bool isStrictTestOp() const { return TestIsStrictOp; } 6291 /// Build the expression to calculate the number of iterations. 6292 Expr *buildNumIterations( 6293 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6294 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6295 /// Build the precondition expression for the loops. 6296 Expr * 6297 buildPreCond(Scope *S, Expr *Cond, 6298 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6299 /// Build reference expression to the counter be used for codegen. 6300 DeclRefExpr * 6301 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6302 DSAStackTy &DSA) const; 6303 /// Build reference expression to the private counter be used for 6304 /// codegen. 6305 Expr *buildPrivateCounterVar() const; 6306 /// Build initialization of the counter be used for codegen. 6307 Expr *buildCounterInit() const; 6308 /// Build step of the counter be used for codegen. 6309 Expr *buildCounterStep() const; 6310 /// Build loop data with counter value for depend clauses in ordered 6311 /// directives. 6312 Expr * 6313 buildOrderedLoopData(Scope *S, Expr *Counter, 6314 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 6315 SourceLocation Loc, Expr *Inc = nullptr, 6316 OverloadedOperatorKind OOK = OO_Amp); 6317 /// Builds the minimum value for the loop counter. 6318 std::pair<Expr *, Expr *> buildMinMaxValues( 6319 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 6320 /// Builds final condition for the non-rectangular loops. 6321 Expr *buildFinalCondition(Scope *S) const; 6322 /// Return true if any expression is dependent. 6323 bool dependent() const; 6324 /// Returns true if the initializer forms non-rectangular loop. 6325 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 6326 /// Returns true if the condition forms non-rectangular loop. 6327 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 6328 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 6329 unsigned getLoopDependentIdx() const { 6330 return InitDependOnLC.getValueOr(CondDependOnLC.getValueOr(0)); 6331 } 6332 6333 private: 6334 /// Check the right-hand side of an assignment in the increment 6335 /// expression. 6336 bool checkAndSetIncRHS(Expr *RHS); 6337 /// Helper to set loop counter variable and its initializer. 6338 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 6339 bool EmitDiags); 6340 /// Helper to set upper bound. 6341 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 6342 SourceRange SR, SourceLocation SL); 6343 /// Helper to set loop increment. 6344 bool setStep(Expr *NewStep, bool Subtract); 6345 }; 6346 6347 bool OpenMPIterationSpaceChecker::dependent() const { 6348 if (!LCDecl) { 6349 assert(!LB && !UB && !Step); 6350 return false; 6351 } 6352 return LCDecl->getType()->isDependentType() || 6353 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 6354 (Step && Step->isValueDependent()); 6355 } 6356 6357 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 6358 Expr *NewLCRefExpr, 6359 Expr *NewLB, bool EmitDiags) { 6360 // State consistency checking to ensure correct usage. 6361 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 6362 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6363 if (!NewLCDecl || !NewLB) 6364 return true; 6365 LCDecl = getCanonicalDecl(NewLCDecl); 6366 LCRef = NewLCRefExpr; 6367 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 6368 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6369 if ((Ctor->isCopyOrMoveConstructor() || 6370 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6371 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6372 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 6373 LB = NewLB; 6374 if (EmitDiags) 6375 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 6376 return false; 6377 } 6378 6379 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 6380 llvm::Optional<bool> LessOp, 6381 bool StrictOp, SourceRange SR, 6382 SourceLocation SL) { 6383 // State consistency checking to ensure correct usage. 6384 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 6385 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 6386 if (!NewUB) 6387 return true; 6388 UB = NewUB; 6389 if (LessOp) 6390 TestIsLessOp = LessOp; 6391 TestIsStrictOp = StrictOp; 6392 ConditionSrcRange = SR; 6393 ConditionLoc = SL; 6394 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 6395 return false; 6396 } 6397 6398 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 6399 // State consistency checking to ensure correct usage. 6400 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 6401 if (!NewStep) 6402 return true; 6403 if (!NewStep->isValueDependent()) { 6404 // Check that the step is integer expression. 6405 SourceLocation StepLoc = NewStep->getBeginLoc(); 6406 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 6407 StepLoc, getExprAsWritten(NewStep)); 6408 if (Val.isInvalid()) 6409 return true; 6410 NewStep = Val.get(); 6411 6412 // OpenMP [2.6, Canonical Loop Form, Restrictions] 6413 // If test-expr is of form var relational-op b and relational-op is < or 6414 // <= then incr-expr must cause var to increase on each iteration of the 6415 // loop. If test-expr is of form var relational-op b and relational-op is 6416 // > or >= then incr-expr must cause var to decrease on each iteration of 6417 // the loop. 6418 // If test-expr is of form b relational-op var and relational-op is < or 6419 // <= then incr-expr must cause var to decrease on each iteration of the 6420 // loop. If test-expr is of form b relational-op var and relational-op is 6421 // > or >= then incr-expr must cause var to increase on each iteration of 6422 // the loop. 6423 llvm::APSInt Result; 6424 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 6425 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 6426 bool IsConstNeg = 6427 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 6428 bool IsConstPos = 6429 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 6430 bool IsConstZero = IsConstant && !Result.getBoolValue(); 6431 6432 // != with increment is treated as <; != with decrement is treated as > 6433 if (!TestIsLessOp.hasValue()) 6434 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 6435 if (UB && (IsConstZero || 6436 (TestIsLessOp.getValue() ? 6437 (IsConstNeg || (IsUnsigned && Subtract)) : 6438 (IsConstPos || (IsUnsigned && !Subtract))))) { 6439 SemaRef.Diag(NewStep->getExprLoc(), 6440 diag::err_omp_loop_incr_not_compatible) 6441 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 6442 SemaRef.Diag(ConditionLoc, 6443 diag::note_omp_loop_cond_requres_compatible_incr) 6444 << TestIsLessOp.getValue() << ConditionSrcRange; 6445 return true; 6446 } 6447 if (TestIsLessOp.getValue() == Subtract) { 6448 NewStep = 6449 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 6450 .get(); 6451 Subtract = !Subtract; 6452 } 6453 } 6454 6455 Step = NewStep; 6456 SubtractStep = Subtract; 6457 return false; 6458 } 6459 6460 namespace { 6461 /// Checker for the non-rectangular loops. Checks if the initializer or 6462 /// condition expression references loop counter variable. 6463 class LoopCounterRefChecker final 6464 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 6465 Sema &SemaRef; 6466 DSAStackTy &Stack; 6467 const ValueDecl *CurLCDecl = nullptr; 6468 const ValueDecl *DepDecl = nullptr; 6469 const ValueDecl *PrevDepDecl = nullptr; 6470 bool IsInitializer = true; 6471 unsigned BaseLoopId = 0; 6472 bool checkDecl(const Expr *E, const ValueDecl *VD) { 6473 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 6474 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 6475 << (IsInitializer ? 0 : 1); 6476 return false; 6477 } 6478 const auto &&Data = Stack.isLoopControlVariable(VD); 6479 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 6480 // The type of the loop iterator on which we depend may not have a random 6481 // access iterator type. 6482 if (Data.first && VD->getType()->isRecordType()) { 6483 SmallString<128> Name; 6484 llvm::raw_svector_ostream OS(Name); 6485 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6486 /*Qualified=*/true); 6487 SemaRef.Diag(E->getExprLoc(), 6488 diag::err_omp_wrong_dependency_iterator_type) 6489 << OS.str(); 6490 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 6491 return false; 6492 } 6493 if (Data.first && 6494 (DepDecl || (PrevDepDecl && 6495 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 6496 if (!DepDecl && PrevDepDecl) 6497 DepDecl = PrevDepDecl; 6498 SmallString<128> Name; 6499 llvm::raw_svector_ostream OS(Name); 6500 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 6501 /*Qualified=*/true); 6502 SemaRef.Diag(E->getExprLoc(), 6503 diag::err_omp_invariant_or_linear_dependency) 6504 << OS.str(); 6505 return false; 6506 } 6507 if (Data.first) { 6508 DepDecl = VD; 6509 BaseLoopId = Data.first; 6510 } 6511 return Data.first; 6512 } 6513 6514 public: 6515 bool VisitDeclRefExpr(const DeclRefExpr *E) { 6516 const ValueDecl *VD = E->getDecl(); 6517 if (isa<VarDecl>(VD)) 6518 return checkDecl(E, VD); 6519 return false; 6520 } 6521 bool VisitMemberExpr(const MemberExpr *E) { 6522 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 6523 const ValueDecl *VD = E->getMemberDecl(); 6524 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 6525 return checkDecl(E, VD); 6526 } 6527 return false; 6528 } 6529 bool VisitStmt(const Stmt *S) { 6530 bool Res = false; 6531 for (const Stmt *Child : S->children()) 6532 Res = (Child && Visit(Child)) || Res; 6533 return Res; 6534 } 6535 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 6536 const ValueDecl *CurLCDecl, bool IsInitializer, 6537 const ValueDecl *PrevDepDecl = nullptr) 6538 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 6539 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer) {} 6540 unsigned getBaseLoopId() const { 6541 assert(CurLCDecl && "Expected loop dependency."); 6542 return BaseLoopId; 6543 } 6544 const ValueDecl *getDepDecl() const { 6545 assert(CurLCDecl && "Expected loop dependency."); 6546 return DepDecl; 6547 } 6548 }; 6549 } // namespace 6550 6551 Optional<unsigned> 6552 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 6553 bool IsInitializer) { 6554 // Check for the non-rectangular loops. 6555 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 6556 DepDecl); 6557 if (LoopStmtChecker.Visit(S)) { 6558 DepDecl = LoopStmtChecker.getDepDecl(); 6559 return LoopStmtChecker.getBaseLoopId(); 6560 } 6561 return llvm::None; 6562 } 6563 6564 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 6565 // Check init-expr for canonical loop form and save loop counter 6566 // variable - #Var and its initialization value - #LB. 6567 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 6568 // var = lb 6569 // integer-type var = lb 6570 // random-access-iterator-type var = lb 6571 // pointer-type var = lb 6572 // 6573 if (!S) { 6574 if (EmitDiags) { 6575 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 6576 } 6577 return true; 6578 } 6579 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6580 if (!ExprTemp->cleanupsHaveSideEffects()) 6581 S = ExprTemp->getSubExpr(); 6582 6583 InitSrcRange = S->getSourceRange(); 6584 if (Expr *E = dyn_cast<Expr>(S)) 6585 S = E->IgnoreParens(); 6586 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6587 if (BO->getOpcode() == BO_Assign) { 6588 Expr *LHS = BO->getLHS()->IgnoreParens(); 6589 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6590 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6591 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6592 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6593 EmitDiags); 6594 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 6595 } 6596 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6597 if (ME->isArrow() && 6598 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6599 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6600 EmitDiags); 6601 } 6602 } 6603 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 6604 if (DS->isSingleDecl()) { 6605 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 6606 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 6607 // Accept non-canonical init form here but emit ext. warning. 6608 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 6609 SemaRef.Diag(S->getBeginLoc(), 6610 diag::ext_omp_loop_not_canonical_init) 6611 << S->getSourceRange(); 6612 return setLCDeclAndLB( 6613 Var, 6614 buildDeclRefExpr(SemaRef, Var, 6615 Var->getType().getNonReferenceType(), 6616 DS->getBeginLoc()), 6617 Var->getInit(), EmitDiags); 6618 } 6619 } 6620 } 6621 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6622 if (CE->getOperator() == OO_Equal) { 6623 Expr *LHS = CE->getArg(0); 6624 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 6625 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 6626 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 6627 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6628 EmitDiags); 6629 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 6630 } 6631 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 6632 if (ME->isArrow() && 6633 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6634 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 6635 EmitDiags); 6636 } 6637 } 6638 } 6639 6640 if (dependent() || SemaRef.CurContext->isDependentContext()) 6641 return false; 6642 if (EmitDiags) { 6643 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 6644 << S->getSourceRange(); 6645 } 6646 return true; 6647 } 6648 6649 /// Ignore parenthesizes, implicit casts, copy constructor and return the 6650 /// variable (which may be the loop variable) if possible. 6651 static const ValueDecl *getInitLCDecl(const Expr *E) { 6652 if (!E) 6653 return nullptr; 6654 E = getExprAsWritten(E); 6655 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 6656 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 6657 if ((Ctor->isCopyOrMoveConstructor() || 6658 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 6659 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 6660 E = CE->getArg(0)->IgnoreParenImpCasts(); 6661 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 6662 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 6663 return getCanonicalDecl(VD); 6664 } 6665 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 6666 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 6667 return getCanonicalDecl(ME->getMemberDecl()); 6668 return nullptr; 6669 } 6670 6671 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 6672 // Check test-expr for canonical form, save upper-bound UB, flags for 6673 // less/greater and for strict/non-strict comparison. 6674 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 6675 // var relational-op b 6676 // b relational-op var 6677 // 6678 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 6679 if (!S) { 6680 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 6681 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 6682 return true; 6683 } 6684 Condition = S; 6685 S = getExprAsWritten(S); 6686 SourceLocation CondLoc = S->getBeginLoc(); 6687 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6688 if (BO->isRelationalOp()) { 6689 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6690 return setUB(BO->getRHS(), 6691 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 6692 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6693 BO->getSourceRange(), BO->getOperatorLoc()); 6694 if (getInitLCDecl(BO->getRHS()) == LCDecl) 6695 return setUB(BO->getLHS(), 6696 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 6697 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 6698 BO->getSourceRange(), BO->getOperatorLoc()); 6699 } else if (IneqCondIsCanonical && BO->getOpcode() == BO_NE) 6700 return setUB( 6701 getInitLCDecl(BO->getLHS()) == LCDecl ? BO->getRHS() : BO->getLHS(), 6702 /*LessOp=*/llvm::None, 6703 /*StrictOp=*/true, BO->getSourceRange(), BO->getOperatorLoc()); 6704 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6705 if (CE->getNumArgs() == 2) { 6706 auto Op = CE->getOperator(); 6707 switch (Op) { 6708 case OO_Greater: 6709 case OO_GreaterEqual: 6710 case OO_Less: 6711 case OO_LessEqual: 6712 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6713 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 6714 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6715 CE->getOperatorLoc()); 6716 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 6717 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 6718 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 6719 CE->getOperatorLoc()); 6720 break; 6721 case OO_ExclaimEqual: 6722 if (IneqCondIsCanonical) 6723 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? CE->getArg(1) 6724 : CE->getArg(0), 6725 /*LessOp=*/llvm::None, 6726 /*StrictOp=*/true, CE->getSourceRange(), 6727 CE->getOperatorLoc()); 6728 break; 6729 default: 6730 break; 6731 } 6732 } 6733 } 6734 if (dependent() || SemaRef.CurContext->isDependentContext()) 6735 return false; 6736 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 6737 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 6738 return true; 6739 } 6740 6741 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 6742 // RHS of canonical loop form increment can be: 6743 // var + incr 6744 // incr + var 6745 // var - incr 6746 // 6747 RHS = RHS->IgnoreParenImpCasts(); 6748 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 6749 if (BO->isAdditiveOp()) { 6750 bool IsAdd = BO->getOpcode() == BO_Add; 6751 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6752 return setStep(BO->getRHS(), !IsAdd); 6753 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 6754 return setStep(BO->getLHS(), /*Subtract=*/false); 6755 } 6756 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 6757 bool IsAdd = CE->getOperator() == OO_Plus; 6758 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 6759 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6760 return setStep(CE->getArg(1), !IsAdd); 6761 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 6762 return setStep(CE->getArg(0), /*Subtract=*/false); 6763 } 6764 } 6765 if (dependent() || SemaRef.CurContext->isDependentContext()) 6766 return false; 6767 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6768 << RHS->getSourceRange() << LCDecl; 6769 return true; 6770 } 6771 6772 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 6773 // Check incr-expr for canonical loop form and return true if it 6774 // does not conform. 6775 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 6776 // ++var 6777 // var++ 6778 // --var 6779 // var-- 6780 // var += incr 6781 // var -= incr 6782 // var = var + incr 6783 // var = incr + var 6784 // var = var - incr 6785 // 6786 if (!S) { 6787 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 6788 return true; 6789 } 6790 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 6791 if (!ExprTemp->cleanupsHaveSideEffects()) 6792 S = ExprTemp->getSubExpr(); 6793 6794 IncrementSrcRange = S->getSourceRange(); 6795 S = S->IgnoreParens(); 6796 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 6797 if (UO->isIncrementDecrementOp() && 6798 getInitLCDecl(UO->getSubExpr()) == LCDecl) 6799 return setStep(SemaRef 6800 .ActOnIntegerConstant(UO->getBeginLoc(), 6801 (UO->isDecrementOp() ? -1 : 1)) 6802 .get(), 6803 /*Subtract=*/false); 6804 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 6805 switch (BO->getOpcode()) { 6806 case BO_AddAssign: 6807 case BO_SubAssign: 6808 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6809 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 6810 break; 6811 case BO_Assign: 6812 if (getInitLCDecl(BO->getLHS()) == LCDecl) 6813 return checkAndSetIncRHS(BO->getRHS()); 6814 break; 6815 default: 6816 break; 6817 } 6818 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 6819 switch (CE->getOperator()) { 6820 case OO_PlusPlus: 6821 case OO_MinusMinus: 6822 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6823 return setStep(SemaRef 6824 .ActOnIntegerConstant( 6825 CE->getBeginLoc(), 6826 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 6827 .get(), 6828 /*Subtract=*/false); 6829 break; 6830 case OO_PlusEqual: 6831 case OO_MinusEqual: 6832 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6833 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 6834 break; 6835 case OO_Equal: 6836 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 6837 return checkAndSetIncRHS(CE->getArg(1)); 6838 break; 6839 default: 6840 break; 6841 } 6842 } 6843 if (dependent() || SemaRef.CurContext->isDependentContext()) 6844 return false; 6845 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 6846 << S->getSourceRange() << LCDecl; 6847 return true; 6848 } 6849 6850 static ExprResult 6851 tryBuildCapture(Sema &SemaRef, Expr *Capture, 6852 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 6853 if (SemaRef.CurContext->isDependentContext()) 6854 return ExprResult(Capture); 6855 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 6856 return SemaRef.PerformImplicitConversion( 6857 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 6858 /*AllowExplicit=*/true); 6859 auto I = Captures.find(Capture); 6860 if (I != Captures.end()) 6861 return buildCapture(SemaRef, Capture, I->second); 6862 DeclRefExpr *Ref = nullptr; 6863 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 6864 Captures[Capture] = Ref; 6865 return Res; 6866 } 6867 6868 /// Build the expression to calculate the number of iterations. 6869 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 6870 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 6871 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 6872 ExprResult Diff; 6873 QualType VarType = LCDecl->getType().getNonReferenceType(); 6874 if (VarType->isIntegerType() || VarType->isPointerType() || 6875 SemaRef.getLangOpts().CPlusPlus) { 6876 Expr *LBVal = LB; 6877 Expr *UBVal = UB; 6878 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 6879 // max(LB(MinVal), LB(MaxVal)) 6880 if (InitDependOnLC) { 6881 const LoopIterationSpace &IS = 6882 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6883 InitDependOnLC.getValueOr( 6884 CondDependOnLC.getValueOr(0))]; 6885 if (!IS.MinValue || !IS.MaxValue) 6886 return nullptr; 6887 // OuterVar = Min 6888 ExprResult MinValue = 6889 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6890 if (!MinValue.isUsable()) 6891 return nullptr; 6892 6893 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6894 IS.CounterVar, MinValue.get()); 6895 if (!LBMinVal.isUsable()) 6896 return nullptr; 6897 // OuterVar = Min, LBVal 6898 LBMinVal = 6899 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 6900 if (!LBMinVal.isUsable()) 6901 return nullptr; 6902 // (OuterVar = Min, LBVal) 6903 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 6904 if (!LBMinVal.isUsable()) 6905 return nullptr; 6906 6907 // OuterVar = Max 6908 ExprResult MaxValue = 6909 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6910 if (!MaxValue.isUsable()) 6911 return nullptr; 6912 6913 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6914 IS.CounterVar, MaxValue.get()); 6915 if (!LBMaxVal.isUsable()) 6916 return nullptr; 6917 // OuterVar = Max, LBVal 6918 LBMaxVal = 6919 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 6920 if (!LBMaxVal.isUsable()) 6921 return nullptr; 6922 // (OuterVar = Max, LBVal) 6923 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 6924 if (!LBMaxVal.isUsable()) 6925 return nullptr; 6926 6927 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 6928 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 6929 if (!LBMin || !LBMax) 6930 return nullptr; 6931 // LB(MinVal) < LB(MaxVal) 6932 ExprResult MinLessMaxRes = 6933 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 6934 if (!MinLessMaxRes.isUsable()) 6935 return nullptr; 6936 Expr *MinLessMax = 6937 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 6938 if (!MinLessMax) 6939 return nullptr; 6940 if (TestIsLessOp.getValue()) { 6941 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 6942 // LB(MaxVal)) 6943 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6944 MinLessMax, LBMin, LBMax); 6945 if (!MinLB.isUsable()) 6946 return nullptr; 6947 LBVal = MinLB.get(); 6948 } else { 6949 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 6950 // LB(MaxVal)) 6951 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 6952 MinLessMax, LBMax, LBMin); 6953 if (!MaxLB.isUsable()) 6954 return nullptr; 6955 LBVal = MaxLB.get(); 6956 } 6957 } 6958 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 6959 // min(UB(MinVal), UB(MaxVal)) 6960 if (CondDependOnLC) { 6961 const LoopIterationSpace &IS = 6962 ResultIterSpaces[ResultIterSpaces.size() - 1 - 6963 InitDependOnLC.getValueOr( 6964 CondDependOnLC.getValueOr(0))]; 6965 if (!IS.MinValue || !IS.MaxValue) 6966 return nullptr; 6967 // OuterVar = Min 6968 ExprResult MinValue = 6969 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 6970 if (!MinValue.isUsable()) 6971 return nullptr; 6972 6973 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6974 IS.CounterVar, MinValue.get()); 6975 if (!UBMinVal.isUsable()) 6976 return nullptr; 6977 // OuterVar = Min, UBVal 6978 UBMinVal = 6979 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 6980 if (!UBMinVal.isUsable()) 6981 return nullptr; 6982 // (OuterVar = Min, UBVal) 6983 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 6984 if (!UBMinVal.isUsable()) 6985 return nullptr; 6986 6987 // OuterVar = Max 6988 ExprResult MaxValue = 6989 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 6990 if (!MaxValue.isUsable()) 6991 return nullptr; 6992 6993 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 6994 IS.CounterVar, MaxValue.get()); 6995 if (!UBMaxVal.isUsable()) 6996 return nullptr; 6997 // OuterVar = Max, UBVal 6998 UBMaxVal = 6999 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 7000 if (!UBMaxVal.isUsable()) 7001 return nullptr; 7002 // (OuterVar = Max, UBVal) 7003 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 7004 if (!UBMaxVal.isUsable()) 7005 return nullptr; 7006 7007 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 7008 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 7009 if (!UBMin || !UBMax) 7010 return nullptr; 7011 // UB(MinVal) > UB(MaxVal) 7012 ExprResult MinGreaterMaxRes = 7013 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 7014 if (!MinGreaterMaxRes.isUsable()) 7015 return nullptr; 7016 Expr *MinGreaterMax = 7017 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 7018 if (!MinGreaterMax) 7019 return nullptr; 7020 if (TestIsLessOp.getValue()) { 7021 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 7022 // UB(MaxVal)) 7023 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 7024 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 7025 if (!MaxUB.isUsable()) 7026 return nullptr; 7027 UBVal = MaxUB.get(); 7028 } else { 7029 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 7030 // UB(MaxVal)) 7031 ExprResult MinUB = SemaRef.ActOnConditionalOp( 7032 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 7033 if (!MinUB.isUsable()) 7034 return nullptr; 7035 UBVal = MinUB.get(); 7036 } 7037 } 7038 // Upper - Lower 7039 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 7040 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 7041 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7042 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7043 if (!Upper || !Lower) 7044 return nullptr; 7045 7046 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7047 7048 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 7049 // BuildBinOp already emitted error, this one is to point user to upper 7050 // and lower bound, and to tell what is passed to 'operator-'. 7051 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7052 << Upper->getSourceRange() << Lower->getSourceRange(); 7053 return nullptr; 7054 } 7055 } 7056 7057 if (!Diff.isUsable()) 7058 return nullptr; 7059 7060 // Upper - Lower [- 1] 7061 if (TestIsStrictOp) 7062 Diff = SemaRef.BuildBinOp( 7063 S, DefaultLoc, BO_Sub, Diff.get(), 7064 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7065 if (!Diff.isUsable()) 7066 return nullptr; 7067 7068 // Upper - Lower [- 1] + Step 7069 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7070 if (!NewStep.isUsable()) 7071 return nullptr; 7072 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 7073 if (!Diff.isUsable()) 7074 return nullptr; 7075 7076 // Parentheses (for dumping/debugging purposes only). 7077 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7078 if (!Diff.isUsable()) 7079 return nullptr; 7080 7081 // (Upper - Lower [- 1] + Step) / Step 7082 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7083 if (!Diff.isUsable()) 7084 return nullptr; 7085 7086 // OpenMP runtime requires 32-bit or 64-bit loop variables. 7087 QualType Type = Diff.get()->getType(); 7088 ASTContext &C = SemaRef.Context; 7089 bool UseVarType = VarType->hasIntegerRepresentation() && 7090 C.getTypeSize(Type) > C.getTypeSize(VarType); 7091 if (!Type->isIntegerType() || UseVarType) { 7092 unsigned NewSize = 7093 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 7094 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 7095 : Type->hasSignedIntegerRepresentation(); 7096 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 7097 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 7098 Diff = SemaRef.PerformImplicitConversion( 7099 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 7100 if (!Diff.isUsable()) 7101 return nullptr; 7102 } 7103 } 7104 if (LimitedType) { 7105 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 7106 if (NewSize != C.getTypeSize(Type)) { 7107 if (NewSize < C.getTypeSize(Type)) { 7108 assert(NewSize == 64 && "incorrect loop var size"); 7109 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 7110 << InitSrcRange << ConditionSrcRange; 7111 } 7112 QualType NewType = C.getIntTypeForBitwidth( 7113 NewSize, Type->hasSignedIntegerRepresentation() || 7114 C.getTypeSize(Type) < NewSize); 7115 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 7116 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 7117 Sema::AA_Converting, true); 7118 if (!Diff.isUsable()) 7119 return nullptr; 7120 } 7121 } 7122 } 7123 7124 return Diff.get(); 7125 } 7126 7127 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 7128 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7129 // Do not build for iterators, they cannot be used in non-rectangular loop 7130 // nests. 7131 if (LCDecl->getType()->isRecordType()) 7132 return std::make_pair(nullptr, nullptr); 7133 // If we subtract, the min is in the condition, otherwise the min is in the 7134 // init value. 7135 Expr *MinExpr = nullptr; 7136 Expr *MaxExpr = nullptr; 7137 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 7138 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 7139 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 7140 : CondDependOnLC.hasValue(); 7141 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 7142 : InitDependOnLC.hasValue(); 7143 Expr *Lower = 7144 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 7145 Expr *Upper = 7146 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 7147 if (!Upper || !Lower) 7148 return std::make_pair(nullptr, nullptr); 7149 7150 if (TestIsLessOp.getValue()) 7151 MinExpr = Lower; 7152 else 7153 MaxExpr = Upper; 7154 7155 // Build minimum/maximum value based on number of iterations. 7156 ExprResult Diff; 7157 QualType VarType = LCDecl->getType().getNonReferenceType(); 7158 7159 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7160 if (!Diff.isUsable()) 7161 return std::make_pair(nullptr, nullptr); 7162 7163 // Upper - Lower [- 1] 7164 if (TestIsStrictOp) 7165 Diff = SemaRef.BuildBinOp( 7166 S, DefaultLoc, BO_Sub, Diff.get(), 7167 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 7168 if (!Diff.isUsable()) 7169 return std::make_pair(nullptr, nullptr); 7170 7171 // Upper - Lower [- 1] + Step 7172 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7173 if (!NewStep.isUsable()) 7174 return std::make_pair(nullptr, nullptr); 7175 7176 // Parentheses (for dumping/debugging purposes only). 7177 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7178 if (!Diff.isUsable()) 7179 return std::make_pair(nullptr, nullptr); 7180 7181 // (Upper - Lower [- 1]) / Step 7182 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7183 if (!Diff.isUsable()) 7184 return std::make_pair(nullptr, nullptr); 7185 7186 // ((Upper - Lower [- 1]) / Step) * Step 7187 // Parentheses (for dumping/debugging purposes only). 7188 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7189 if (!Diff.isUsable()) 7190 return std::make_pair(nullptr, nullptr); 7191 7192 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 7193 if (!Diff.isUsable()) 7194 return std::make_pair(nullptr, nullptr); 7195 7196 // Convert to the original type or ptrdiff_t, if original type is pointer. 7197 if (!VarType->isAnyPointerType() && 7198 !SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) { 7199 Diff = SemaRef.PerformImplicitConversion( 7200 Diff.get(), VarType, Sema::AA_Converting, /*AllowExplicit=*/true); 7201 } else if (VarType->isAnyPointerType() && 7202 !SemaRef.Context.hasSameType( 7203 Diff.get()->getType(), 7204 SemaRef.Context.getUnsignedPointerDiffType())) { 7205 Diff = SemaRef.PerformImplicitConversion( 7206 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 7207 Sema::AA_Converting, /*AllowExplicit=*/true); 7208 } 7209 if (!Diff.isUsable()) 7210 return std::make_pair(nullptr, nullptr); 7211 7212 // Parentheses (for dumping/debugging purposes only). 7213 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7214 if (!Diff.isUsable()) 7215 return std::make_pair(nullptr, nullptr); 7216 7217 if (TestIsLessOp.getValue()) { 7218 // MinExpr = Lower; 7219 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 7220 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Lower, Diff.get()); 7221 if (!Diff.isUsable()) 7222 return std::make_pair(nullptr, nullptr); 7223 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7224 if (!Diff.isUsable()) 7225 return std::make_pair(nullptr, nullptr); 7226 MaxExpr = Diff.get(); 7227 } else { 7228 // MaxExpr = Upper; 7229 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 7230 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 7231 if (!Diff.isUsable()) 7232 return std::make_pair(nullptr, nullptr); 7233 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue*/ false); 7234 if (!Diff.isUsable()) 7235 return std::make_pair(nullptr, nullptr); 7236 MinExpr = Diff.get(); 7237 } 7238 7239 return std::make_pair(MinExpr, MaxExpr); 7240 } 7241 7242 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 7243 if (InitDependOnLC || CondDependOnLC) 7244 return Condition; 7245 return nullptr; 7246 } 7247 7248 Expr *OpenMPIterationSpaceChecker::buildPreCond( 7249 Scope *S, Expr *Cond, 7250 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 7251 // Do not build a precondition when the condition/initialization is dependent 7252 // to prevent pessimistic early loop exit. 7253 // TODO: this can be improved by calculating min/max values but not sure that 7254 // it will be very effective. 7255 if (CondDependOnLC || InitDependOnLC) 7256 return SemaRef.PerformImplicitConversion( 7257 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 7258 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7259 /*AllowExplicit=*/true).get(); 7260 7261 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 7262 Sema::TentativeAnalysisScope Trap(SemaRef); 7263 7264 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 7265 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 7266 if (!NewLB.isUsable() || !NewUB.isUsable()) 7267 return nullptr; 7268 7269 ExprResult CondExpr = 7270 SemaRef.BuildBinOp(S, DefaultLoc, 7271 TestIsLessOp.getValue() ? 7272 (TestIsStrictOp ? BO_LT : BO_LE) : 7273 (TestIsStrictOp ? BO_GT : BO_GE), 7274 NewLB.get(), NewUB.get()); 7275 if (CondExpr.isUsable()) { 7276 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 7277 SemaRef.Context.BoolTy)) 7278 CondExpr = SemaRef.PerformImplicitConversion( 7279 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 7280 /*AllowExplicit=*/true); 7281 } 7282 7283 // Otherwise use original loop condition and evaluate it in runtime. 7284 return CondExpr.isUsable() ? CondExpr.get() : Cond; 7285 } 7286 7287 /// Build reference expression to the counter be used for codegen. 7288 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 7289 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7290 DSAStackTy &DSA) const { 7291 auto *VD = dyn_cast<VarDecl>(LCDecl); 7292 if (!VD) { 7293 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 7294 DeclRefExpr *Ref = buildDeclRefExpr( 7295 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 7296 const DSAStackTy::DSAVarData Data = 7297 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 7298 // If the loop control decl is explicitly marked as private, do not mark it 7299 // as captured again. 7300 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 7301 Captures.insert(std::make_pair(LCRef, Ref)); 7302 return Ref; 7303 } 7304 return cast<DeclRefExpr>(LCRef); 7305 } 7306 7307 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 7308 if (LCDecl && !LCDecl->isInvalidDecl()) { 7309 QualType Type = LCDecl->getType().getNonReferenceType(); 7310 VarDecl *PrivateVar = buildVarDecl( 7311 SemaRef, DefaultLoc, Type, LCDecl->getName(), 7312 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 7313 isa<VarDecl>(LCDecl) 7314 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 7315 : nullptr); 7316 if (PrivateVar->isInvalidDecl()) 7317 return nullptr; 7318 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 7319 } 7320 return nullptr; 7321 } 7322 7323 /// Build initialization of the counter to be used for codegen. 7324 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 7325 7326 /// Build step of the counter be used for codegen. 7327 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 7328 7329 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 7330 Scope *S, Expr *Counter, 7331 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 7332 Expr *Inc, OverloadedOperatorKind OOK) { 7333 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 7334 if (!Cnt) 7335 return nullptr; 7336 if (Inc) { 7337 assert((OOK == OO_Plus || OOK == OO_Minus) && 7338 "Expected only + or - operations for depend clauses."); 7339 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 7340 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 7341 if (!Cnt) 7342 return nullptr; 7343 } 7344 ExprResult Diff; 7345 QualType VarType = LCDecl->getType().getNonReferenceType(); 7346 if (VarType->isIntegerType() || VarType->isPointerType() || 7347 SemaRef.getLangOpts().CPlusPlus) { 7348 // Upper - Lower 7349 Expr *Upper = TestIsLessOp.getValue() 7350 ? Cnt 7351 : tryBuildCapture(SemaRef, LB, Captures).get(); 7352 Expr *Lower = TestIsLessOp.getValue() 7353 ? tryBuildCapture(SemaRef, LB, Captures).get() 7354 : Cnt; 7355 if (!Upper || !Lower) 7356 return nullptr; 7357 7358 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 7359 7360 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 7361 // BuildBinOp already emitted error, this one is to point user to upper 7362 // and lower bound, and to tell what is passed to 'operator-'. 7363 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 7364 << Upper->getSourceRange() << Lower->getSourceRange(); 7365 return nullptr; 7366 } 7367 } 7368 7369 if (!Diff.isUsable()) 7370 return nullptr; 7371 7372 // Parentheses (for dumping/debugging purposes only). 7373 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 7374 if (!Diff.isUsable()) 7375 return nullptr; 7376 7377 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 7378 if (!NewStep.isUsable()) 7379 return nullptr; 7380 // (Upper - Lower) / Step 7381 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 7382 if (!Diff.isUsable()) 7383 return nullptr; 7384 7385 return Diff.get(); 7386 } 7387 } // namespace 7388 7389 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 7390 assert(getLangOpts().OpenMP && "OpenMP is not active."); 7391 assert(Init && "Expected loop in canonical form."); 7392 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 7393 if (AssociatedLoops > 0 && 7394 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 7395 DSAStack->loopStart(); 7396 OpenMPIterationSpaceChecker ISC(*this, *DSAStack, ForLoc); 7397 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 7398 if (ValueDecl *D = ISC.getLoopDecl()) { 7399 auto *VD = dyn_cast<VarDecl>(D); 7400 DeclRefExpr *PrivateRef = nullptr; 7401 if (!VD) { 7402 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 7403 VD = Private; 7404 } else { 7405 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 7406 /*WithInit=*/false); 7407 VD = cast<VarDecl>(PrivateRef->getDecl()); 7408 } 7409 } 7410 DSAStack->addLoopControlVariable(D, VD); 7411 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 7412 if (LD != D->getCanonicalDecl()) { 7413 DSAStack->resetPossibleLoopCounter(); 7414 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 7415 MarkDeclarationsReferencedInExpr( 7416 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 7417 Var->getType().getNonLValueExprType(Context), 7418 ForLoc, /*RefersToCapture=*/true)); 7419 } 7420 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7421 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 7422 // Referenced in a Construct, C/C++]. The loop iteration variable in the 7423 // associated for-loop of a simd construct with just one associated 7424 // for-loop may be listed in a linear clause with a constant-linear-step 7425 // that is the increment of the associated for-loop. The loop iteration 7426 // variable(s) in the associated for-loop(s) of a for or parallel for 7427 // construct may be listed in a private or lastprivate clause. 7428 DSAStackTy::DSAVarData DVar = 7429 DSAStack->getTopDSA(D, /*FromParent=*/false); 7430 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 7431 // is declared in the loop and it is predetermined as a private. 7432 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 7433 OpenMPClauseKind PredeterminedCKind = 7434 isOpenMPSimdDirective(DKind) 7435 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 7436 : OMPC_private; 7437 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7438 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 7439 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 7440 DVar.CKind != OMPC_private))) || 7441 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 7442 DKind == OMPD_master_taskloop || 7443 DKind == OMPD_parallel_master_taskloop || 7444 isOpenMPDistributeDirective(DKind)) && 7445 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 7446 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 7447 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 7448 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 7449 << getOpenMPClauseName(DVar.CKind) 7450 << getOpenMPDirectiveName(DKind) 7451 << getOpenMPClauseName(PredeterminedCKind); 7452 if (DVar.RefExpr == nullptr) 7453 DVar.CKind = PredeterminedCKind; 7454 reportOriginalDsa(*this, DSAStack, D, DVar, 7455 /*IsLoopIterVar=*/true); 7456 } else if (LoopDeclRefExpr) { 7457 // Make the loop iteration variable private (for worksharing 7458 // constructs), linear (for simd directives with the only one 7459 // associated loop) or lastprivate (for simd directives with several 7460 // collapsed or ordered loops). 7461 if (DVar.CKind == OMPC_unknown) 7462 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 7463 PrivateRef); 7464 } 7465 } 7466 } 7467 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 7468 } 7469 } 7470 7471 /// Called on a for stmt to check and extract its iteration space 7472 /// for further processing (such as collapsing). 7473 static bool checkOpenMPIterationSpace( 7474 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 7475 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 7476 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 7477 Expr *OrderedLoopCountExpr, 7478 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7479 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 7480 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7481 // OpenMP [2.9.1, Canonical Loop Form] 7482 // for (init-expr; test-expr; incr-expr) structured-block 7483 // for (range-decl: range-expr) structured-block 7484 auto *For = dyn_cast_or_null<ForStmt>(S); 7485 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 7486 // Ranged for is supported only in OpenMP 5.0. 7487 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 7488 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 7489 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 7490 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 7491 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 7492 if (TotalNestedLoopCount > 1) { 7493 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 7494 SemaRef.Diag(DSA.getConstructLoc(), 7495 diag::note_omp_collapse_ordered_expr) 7496 << 2 << CollapseLoopCountExpr->getSourceRange() 7497 << OrderedLoopCountExpr->getSourceRange(); 7498 else if (CollapseLoopCountExpr) 7499 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7500 diag::note_omp_collapse_ordered_expr) 7501 << 0 << CollapseLoopCountExpr->getSourceRange(); 7502 else 7503 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7504 diag::note_omp_collapse_ordered_expr) 7505 << 1 << OrderedLoopCountExpr->getSourceRange(); 7506 } 7507 return true; 7508 } 7509 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 7510 "No loop body."); 7511 7512 OpenMPIterationSpaceChecker ISC(SemaRef, DSA, 7513 For ? For->getForLoc() : CXXFor->getForLoc()); 7514 7515 // Check init. 7516 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 7517 if (ISC.checkAndSetInit(Init)) 7518 return true; 7519 7520 bool HasErrors = false; 7521 7522 // Check loop variable's type. 7523 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 7524 // OpenMP [2.6, Canonical Loop Form] 7525 // Var is one of the following: 7526 // A variable of signed or unsigned integer type. 7527 // For C++, a variable of a random access iterator type. 7528 // For C, a variable of a pointer type. 7529 QualType VarType = LCDecl->getType().getNonReferenceType(); 7530 if (!VarType->isDependentType() && !VarType->isIntegerType() && 7531 !VarType->isPointerType() && 7532 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 7533 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 7534 << SemaRef.getLangOpts().CPlusPlus; 7535 HasErrors = true; 7536 } 7537 7538 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 7539 // a Construct 7540 // The loop iteration variable(s) in the associated for-loop(s) of a for or 7541 // parallel for construct is (are) private. 7542 // The loop iteration variable in the associated for-loop of a simd 7543 // construct with just one associated for-loop is linear with a 7544 // constant-linear-step that is the increment of the associated for-loop. 7545 // Exclude loop var from the list of variables with implicitly defined data 7546 // sharing attributes. 7547 VarsWithImplicitDSA.erase(LCDecl); 7548 7549 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 7550 7551 // Check test-expr. 7552 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 7553 7554 // Check incr-expr. 7555 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 7556 } 7557 7558 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 7559 return HasErrors; 7560 7561 // Build the loop's iteration space representation. 7562 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 7563 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 7564 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 7565 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 7566 (isOpenMPWorksharingDirective(DKind) || 7567 isOpenMPTaskLoopDirective(DKind) || 7568 isOpenMPDistributeDirective(DKind)), 7569 Captures); 7570 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 7571 ISC.buildCounterVar(Captures, DSA); 7572 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 7573 ISC.buildPrivateCounterVar(); 7574 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 7575 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 7576 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 7577 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 7578 ISC.getConditionSrcRange(); 7579 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 7580 ISC.getIncrementSrcRange(); 7581 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 7582 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 7583 ISC.isStrictTestOp(); 7584 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 7585 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 7586 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 7587 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 7588 ISC.buildFinalCondition(DSA.getCurScope()); 7589 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 7590 ISC.doesInitDependOnLC(); 7591 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 7592 ISC.doesCondDependOnLC(); 7593 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 7594 ISC.getLoopDependentIdx(); 7595 7596 HasErrors |= 7597 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 7598 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 7599 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 7600 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 7601 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 7602 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 7603 if (!HasErrors && DSA.isOrderedRegion()) { 7604 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 7605 if (CurrentNestedLoopCount < 7606 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 7607 DSA.getOrderedRegionParam().second->setLoopNumIterations( 7608 CurrentNestedLoopCount, 7609 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 7610 DSA.getOrderedRegionParam().second->setLoopCounter( 7611 CurrentNestedLoopCount, 7612 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 7613 } 7614 } 7615 for (auto &Pair : DSA.getDoacrossDependClauses()) { 7616 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 7617 // Erroneous case - clause has some problems. 7618 continue; 7619 } 7620 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 7621 Pair.second.size() <= CurrentNestedLoopCount) { 7622 // Erroneous case - clause has some problems. 7623 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 7624 continue; 7625 } 7626 Expr *CntValue; 7627 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 7628 CntValue = ISC.buildOrderedLoopData( 7629 DSA.getCurScope(), 7630 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7631 Pair.first->getDependencyLoc()); 7632 else 7633 CntValue = ISC.buildOrderedLoopData( 7634 DSA.getCurScope(), 7635 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 7636 Pair.first->getDependencyLoc(), 7637 Pair.second[CurrentNestedLoopCount].first, 7638 Pair.second[CurrentNestedLoopCount].second); 7639 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 7640 } 7641 } 7642 7643 return HasErrors; 7644 } 7645 7646 /// Build 'VarRef = Start. 7647 static ExprResult 7648 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7649 ExprResult Start, bool IsNonRectangularLB, 7650 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7651 // Build 'VarRef = Start. 7652 ExprResult NewStart = IsNonRectangularLB 7653 ? Start.get() 7654 : tryBuildCapture(SemaRef, Start.get(), Captures); 7655 if (!NewStart.isUsable()) 7656 return ExprError(); 7657 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 7658 VarRef.get()->getType())) { 7659 NewStart = SemaRef.PerformImplicitConversion( 7660 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 7661 /*AllowExplicit=*/true); 7662 if (!NewStart.isUsable()) 7663 return ExprError(); 7664 } 7665 7666 ExprResult Init = 7667 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7668 return Init; 7669 } 7670 7671 /// Build 'VarRef = Start + Iter * Step'. 7672 static ExprResult buildCounterUpdate( 7673 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 7674 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 7675 bool IsNonRectangularLB, 7676 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 7677 // Add parentheses (for debugging purposes only). 7678 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 7679 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 7680 !Step.isUsable()) 7681 return ExprError(); 7682 7683 ExprResult NewStep = Step; 7684 if (Captures) 7685 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 7686 if (NewStep.isInvalid()) 7687 return ExprError(); 7688 ExprResult Update = 7689 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 7690 if (!Update.isUsable()) 7691 return ExprError(); 7692 7693 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 7694 // 'VarRef = Start (+|-) Iter * Step'. 7695 if (!Start.isUsable()) 7696 return ExprError(); 7697 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 7698 if (!NewStart.isUsable()) 7699 return ExprError(); 7700 if (Captures && !IsNonRectangularLB) 7701 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 7702 if (NewStart.isInvalid()) 7703 return ExprError(); 7704 7705 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 7706 ExprResult SavedUpdate = Update; 7707 ExprResult UpdateVal; 7708 if (VarRef.get()->getType()->isOverloadableType() || 7709 NewStart.get()->getType()->isOverloadableType() || 7710 Update.get()->getType()->isOverloadableType()) { 7711 Sema::TentativeAnalysisScope Trap(SemaRef); 7712 7713 Update = 7714 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 7715 if (Update.isUsable()) { 7716 UpdateVal = 7717 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 7718 VarRef.get(), SavedUpdate.get()); 7719 if (UpdateVal.isUsable()) { 7720 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 7721 UpdateVal.get()); 7722 } 7723 } 7724 } 7725 7726 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 7727 if (!Update.isUsable() || !UpdateVal.isUsable()) { 7728 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 7729 NewStart.get(), SavedUpdate.get()); 7730 if (!Update.isUsable()) 7731 return ExprError(); 7732 7733 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 7734 VarRef.get()->getType())) { 7735 Update = SemaRef.PerformImplicitConversion( 7736 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 7737 if (!Update.isUsable()) 7738 return ExprError(); 7739 } 7740 7741 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 7742 } 7743 return Update; 7744 } 7745 7746 /// Convert integer expression \a E to make it have at least \a Bits 7747 /// bits. 7748 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 7749 if (E == nullptr) 7750 return ExprError(); 7751 ASTContext &C = SemaRef.Context; 7752 QualType OldType = E->getType(); 7753 unsigned HasBits = C.getTypeSize(OldType); 7754 if (HasBits >= Bits) 7755 return ExprResult(E); 7756 // OK to convert to signed, because new type has more bits than old. 7757 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 7758 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 7759 true); 7760 } 7761 7762 /// Check if the given expression \a E is a constant integer that fits 7763 /// into \a Bits bits. 7764 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 7765 if (E == nullptr) 7766 return false; 7767 llvm::APSInt Result; 7768 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 7769 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 7770 return false; 7771 } 7772 7773 /// Build preinits statement for the given declarations. 7774 static Stmt *buildPreInits(ASTContext &Context, 7775 MutableArrayRef<Decl *> PreInits) { 7776 if (!PreInits.empty()) { 7777 return new (Context) DeclStmt( 7778 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 7779 SourceLocation(), SourceLocation()); 7780 } 7781 return nullptr; 7782 } 7783 7784 /// Build preinits statement for the given declarations. 7785 static Stmt * 7786 buildPreInits(ASTContext &Context, 7787 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 7788 if (!Captures.empty()) { 7789 SmallVector<Decl *, 16> PreInits; 7790 for (const auto &Pair : Captures) 7791 PreInits.push_back(Pair.second->getDecl()); 7792 return buildPreInits(Context, PreInits); 7793 } 7794 return nullptr; 7795 } 7796 7797 /// Build postupdate expression for the given list of postupdates expressions. 7798 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 7799 Expr *PostUpdate = nullptr; 7800 if (!PostUpdates.empty()) { 7801 for (Expr *E : PostUpdates) { 7802 Expr *ConvE = S.BuildCStyleCastExpr( 7803 E->getExprLoc(), 7804 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 7805 E->getExprLoc(), E) 7806 .get(); 7807 PostUpdate = PostUpdate 7808 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 7809 PostUpdate, ConvE) 7810 .get() 7811 : ConvE; 7812 } 7813 } 7814 return PostUpdate; 7815 } 7816 7817 /// Called on a for stmt to check itself and nested loops (if any). 7818 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 7819 /// number of collapsed loops otherwise. 7820 static unsigned 7821 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 7822 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 7823 DSAStackTy &DSA, 7824 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 7825 OMPLoopDirective::HelperExprs &Built) { 7826 unsigned NestedLoopCount = 1; 7827 if (CollapseLoopCountExpr) { 7828 // Found 'collapse' clause - calculate collapse number. 7829 Expr::EvalResult Result; 7830 if (!CollapseLoopCountExpr->isValueDependent() && 7831 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 7832 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 7833 } else { 7834 Built.clear(/*Size=*/1); 7835 return 1; 7836 } 7837 } 7838 unsigned OrderedLoopCount = 1; 7839 if (OrderedLoopCountExpr) { 7840 // Found 'ordered' clause - calculate collapse number. 7841 Expr::EvalResult EVResult; 7842 if (!OrderedLoopCountExpr->isValueDependent() && 7843 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 7844 SemaRef.getASTContext())) { 7845 llvm::APSInt Result = EVResult.Val.getInt(); 7846 if (Result.getLimitedValue() < NestedLoopCount) { 7847 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 7848 diag::err_omp_wrong_ordered_loop_count) 7849 << OrderedLoopCountExpr->getSourceRange(); 7850 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 7851 diag::note_collapse_loop_count) 7852 << CollapseLoopCountExpr->getSourceRange(); 7853 } 7854 OrderedLoopCount = Result.getLimitedValue(); 7855 } else { 7856 Built.clear(/*Size=*/1); 7857 return 1; 7858 } 7859 } 7860 // This is helper routine for loop directives (e.g., 'for', 'simd', 7861 // 'for simd', etc.). 7862 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 7863 SmallVector<LoopIterationSpace, 4> IterSpaces( 7864 std::max(OrderedLoopCount, NestedLoopCount)); 7865 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 7866 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 7867 if (checkOpenMPIterationSpace( 7868 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7869 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7870 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7871 return 0; 7872 // Move on to the next nested for loop, or to the loop body. 7873 // OpenMP [2.8.1, simd construct, Restrictions] 7874 // All loops associated with the construct must be perfectly nested; that 7875 // is, there must be no intervening code nor any OpenMP directive between 7876 // any two loops. 7877 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7878 CurStmt = For->getBody(); 7879 } else { 7880 assert(isa<CXXForRangeStmt>(CurStmt) && 7881 "Expected canonical for or range-based for loops."); 7882 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7883 } 7884 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7885 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7886 } 7887 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 7888 if (checkOpenMPIterationSpace( 7889 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 7890 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 7891 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces, Captures)) 7892 return 0; 7893 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 7894 // Handle initialization of captured loop iterator variables. 7895 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 7896 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 7897 Captures[DRE] = DRE; 7898 } 7899 } 7900 // Move on to the next nested for loop, or to the loop body. 7901 // OpenMP [2.8.1, simd construct, Restrictions] 7902 // All loops associated with the construct must be perfectly nested; that 7903 // is, there must be no intervening code nor any OpenMP directive between 7904 // any two loops. 7905 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 7906 CurStmt = For->getBody(); 7907 } else { 7908 assert(isa<CXXForRangeStmt>(CurStmt) && 7909 "Expected canonical for or range-based for loops."); 7910 CurStmt = cast<CXXForRangeStmt>(CurStmt)->getBody(); 7911 } 7912 CurStmt = OMPLoopDirective::tryToFindNextInnerLoop( 7913 CurStmt, SemaRef.LangOpts.OpenMP >= 50); 7914 } 7915 7916 Built.clear(/* size */ NestedLoopCount); 7917 7918 if (SemaRef.CurContext->isDependentContext()) 7919 return NestedLoopCount; 7920 7921 // An example of what is generated for the following code: 7922 // 7923 // #pragma omp simd collapse(2) ordered(2) 7924 // for (i = 0; i < NI; ++i) 7925 // for (k = 0; k < NK; ++k) 7926 // for (j = J0; j < NJ; j+=2) { 7927 // <loop body> 7928 // } 7929 // 7930 // We generate the code below. 7931 // Note: the loop body may be outlined in CodeGen. 7932 // Note: some counters may be C++ classes, operator- is used to find number of 7933 // iterations and operator+= to calculate counter value. 7934 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 7935 // or i64 is currently supported). 7936 // 7937 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 7938 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 7939 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 7940 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 7941 // // similar updates for vars in clauses (e.g. 'linear') 7942 // <loop body (using local i and j)> 7943 // } 7944 // i = NI; // assign final values of counters 7945 // j = NJ; 7946 // 7947 7948 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 7949 // the iteration counts of the collapsed for loops. 7950 // Precondition tests if there is at least one iteration (all conditions are 7951 // true). 7952 auto PreCond = ExprResult(IterSpaces[0].PreCond); 7953 Expr *N0 = IterSpaces[0].NumIterations; 7954 ExprResult LastIteration32 = 7955 widenIterationCount(/*Bits=*/32, 7956 SemaRef 7957 .PerformImplicitConversion( 7958 N0->IgnoreImpCasts(), N0->getType(), 7959 Sema::AA_Converting, /*AllowExplicit=*/true) 7960 .get(), 7961 SemaRef); 7962 ExprResult LastIteration64 = widenIterationCount( 7963 /*Bits=*/64, 7964 SemaRef 7965 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 7966 Sema::AA_Converting, 7967 /*AllowExplicit=*/true) 7968 .get(), 7969 SemaRef); 7970 7971 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 7972 return NestedLoopCount; 7973 7974 ASTContext &C = SemaRef.Context; 7975 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 7976 7977 Scope *CurScope = DSA.getCurScope(); 7978 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 7979 if (PreCond.isUsable()) { 7980 PreCond = 7981 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 7982 PreCond.get(), IterSpaces[Cnt].PreCond); 7983 } 7984 Expr *N = IterSpaces[Cnt].NumIterations; 7985 SourceLocation Loc = N->getExprLoc(); 7986 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 7987 if (LastIteration32.isUsable()) 7988 LastIteration32 = SemaRef.BuildBinOp( 7989 CurScope, Loc, BO_Mul, LastIteration32.get(), 7990 SemaRef 7991 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 7992 Sema::AA_Converting, 7993 /*AllowExplicit=*/true) 7994 .get()); 7995 if (LastIteration64.isUsable()) 7996 LastIteration64 = SemaRef.BuildBinOp( 7997 CurScope, Loc, BO_Mul, LastIteration64.get(), 7998 SemaRef 7999 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 8000 Sema::AA_Converting, 8001 /*AllowExplicit=*/true) 8002 .get()); 8003 } 8004 8005 // Choose either the 32-bit or 64-bit version. 8006 ExprResult LastIteration = LastIteration64; 8007 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 8008 (LastIteration32.isUsable() && 8009 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 8010 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 8011 fitsInto( 8012 /*Bits=*/32, 8013 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 8014 LastIteration64.get(), SemaRef)))) 8015 LastIteration = LastIteration32; 8016 QualType VType = LastIteration.get()->getType(); 8017 QualType RealVType = VType; 8018 QualType StrideVType = VType; 8019 if (isOpenMPTaskLoopDirective(DKind)) { 8020 VType = 8021 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 8022 StrideVType = 8023 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 8024 } 8025 8026 if (!LastIteration.isUsable()) 8027 return 0; 8028 8029 // Save the number of iterations. 8030 ExprResult NumIterations = LastIteration; 8031 { 8032 LastIteration = SemaRef.BuildBinOp( 8033 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 8034 LastIteration.get(), 8035 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8036 if (!LastIteration.isUsable()) 8037 return 0; 8038 } 8039 8040 // Calculate the last iteration number beforehand instead of doing this on 8041 // each iteration. Do not do this if the number of iterations may be kfold-ed. 8042 llvm::APSInt Result; 8043 bool IsConstant = 8044 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 8045 ExprResult CalcLastIteration; 8046 if (!IsConstant) { 8047 ExprResult SaveRef = 8048 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 8049 LastIteration = SaveRef; 8050 8051 // Prepare SaveRef + 1. 8052 NumIterations = SemaRef.BuildBinOp( 8053 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 8054 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8055 if (!NumIterations.isUsable()) 8056 return 0; 8057 } 8058 8059 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 8060 8061 // Build variables passed into runtime, necessary for worksharing directives. 8062 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 8063 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8064 isOpenMPDistributeDirective(DKind)) { 8065 // Lower bound variable, initialized with zero. 8066 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 8067 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 8068 SemaRef.AddInitializerToDecl(LBDecl, 8069 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8070 /*DirectInit*/ false); 8071 8072 // Upper bound variable, initialized with last iteration number. 8073 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 8074 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 8075 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 8076 /*DirectInit*/ false); 8077 8078 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 8079 // This will be used to implement clause 'lastprivate'. 8080 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 8081 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 8082 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 8083 SemaRef.AddInitializerToDecl(ILDecl, 8084 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8085 /*DirectInit*/ false); 8086 8087 // Stride variable returned by runtime (we initialize it to 1 by default). 8088 VarDecl *STDecl = 8089 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 8090 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 8091 SemaRef.AddInitializerToDecl(STDecl, 8092 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 8093 /*DirectInit*/ false); 8094 8095 // Build expression: UB = min(UB, LastIteration) 8096 // It is necessary for CodeGen of directives with static scheduling. 8097 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 8098 UB.get(), LastIteration.get()); 8099 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8100 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 8101 LastIteration.get(), UB.get()); 8102 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 8103 CondOp.get()); 8104 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 8105 8106 // If we have a combined directive that combines 'distribute', 'for' or 8107 // 'simd' we need to be able to access the bounds of the schedule of the 8108 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 8109 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 8110 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8111 // Lower bound variable, initialized with zero. 8112 VarDecl *CombLBDecl = 8113 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 8114 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 8115 SemaRef.AddInitializerToDecl( 8116 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 8117 /*DirectInit*/ false); 8118 8119 // Upper bound variable, initialized with last iteration number. 8120 VarDecl *CombUBDecl = 8121 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 8122 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 8123 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 8124 /*DirectInit*/ false); 8125 8126 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 8127 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 8128 ExprResult CombCondOp = 8129 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 8130 LastIteration.get(), CombUB.get()); 8131 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 8132 CombCondOp.get()); 8133 CombEUB = 8134 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 8135 8136 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 8137 // We expect to have at least 2 more parameters than the 'parallel' 8138 // directive does - the lower and upper bounds of the previous schedule. 8139 assert(CD->getNumParams() >= 4 && 8140 "Unexpected number of parameters in loop combined directive"); 8141 8142 // Set the proper type for the bounds given what we learned from the 8143 // enclosed loops. 8144 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 8145 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 8146 8147 // Previous lower and upper bounds are obtained from the region 8148 // parameters. 8149 PrevLB = 8150 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 8151 PrevUB = 8152 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 8153 } 8154 } 8155 8156 // Build the iteration variable and its initialization before loop. 8157 ExprResult IV; 8158 ExprResult Init, CombInit; 8159 { 8160 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 8161 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 8162 Expr *RHS = 8163 (isOpenMPWorksharingDirective(DKind) || 8164 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8165 ? LB.get() 8166 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8167 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 8168 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 8169 8170 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8171 Expr *CombRHS = 8172 (isOpenMPWorksharingDirective(DKind) || 8173 isOpenMPTaskLoopDirective(DKind) || 8174 isOpenMPDistributeDirective(DKind)) 8175 ? CombLB.get() 8176 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 8177 CombInit = 8178 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 8179 CombInit = 8180 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 8181 } 8182 } 8183 8184 bool UseStrictCompare = 8185 RealVType->hasUnsignedIntegerRepresentation() && 8186 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 8187 return LIS.IsStrictCompare; 8188 }); 8189 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 8190 // unsigned IV)) for worksharing loops. 8191 SourceLocation CondLoc = AStmt->getBeginLoc(); 8192 Expr *BoundUB = UB.get(); 8193 if (UseStrictCompare) { 8194 BoundUB = 8195 SemaRef 8196 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 8197 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8198 .get(); 8199 BoundUB = 8200 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 8201 } 8202 ExprResult Cond = 8203 (isOpenMPWorksharingDirective(DKind) || 8204 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 8205 ? SemaRef.BuildBinOp(CurScope, CondLoc, 8206 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 8207 BoundUB) 8208 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8209 NumIterations.get()); 8210 ExprResult CombDistCond; 8211 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8212 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 8213 NumIterations.get()); 8214 } 8215 8216 ExprResult CombCond; 8217 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8218 Expr *BoundCombUB = CombUB.get(); 8219 if (UseStrictCompare) { 8220 BoundCombUB = 8221 SemaRef 8222 .BuildBinOp( 8223 CurScope, CondLoc, BO_Add, BoundCombUB, 8224 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8225 .get(); 8226 BoundCombUB = 8227 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 8228 .get(); 8229 } 8230 CombCond = 8231 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8232 IV.get(), BoundCombUB); 8233 } 8234 // Loop increment (IV = IV + 1) 8235 SourceLocation IncLoc = AStmt->getBeginLoc(); 8236 ExprResult Inc = 8237 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 8238 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 8239 if (!Inc.isUsable()) 8240 return 0; 8241 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 8242 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 8243 if (!Inc.isUsable()) 8244 return 0; 8245 8246 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 8247 // Used for directives with static scheduling. 8248 // In combined construct, add combined version that use CombLB and CombUB 8249 // base variables for the update 8250 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 8251 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 8252 isOpenMPDistributeDirective(DKind)) { 8253 // LB + ST 8254 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 8255 if (!NextLB.isUsable()) 8256 return 0; 8257 // LB = LB + ST 8258 NextLB = 8259 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 8260 NextLB = 8261 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 8262 if (!NextLB.isUsable()) 8263 return 0; 8264 // UB + ST 8265 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 8266 if (!NextUB.isUsable()) 8267 return 0; 8268 // UB = UB + ST 8269 NextUB = 8270 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 8271 NextUB = 8272 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 8273 if (!NextUB.isUsable()) 8274 return 0; 8275 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8276 CombNextLB = 8277 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 8278 if (!NextLB.isUsable()) 8279 return 0; 8280 // LB = LB + ST 8281 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 8282 CombNextLB.get()); 8283 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 8284 /*DiscardedValue*/ false); 8285 if (!CombNextLB.isUsable()) 8286 return 0; 8287 // UB + ST 8288 CombNextUB = 8289 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 8290 if (!CombNextUB.isUsable()) 8291 return 0; 8292 // UB = UB + ST 8293 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 8294 CombNextUB.get()); 8295 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 8296 /*DiscardedValue*/ false); 8297 if (!CombNextUB.isUsable()) 8298 return 0; 8299 } 8300 } 8301 8302 // Create increment expression for distribute loop when combined in a same 8303 // directive with for as IV = IV + ST; ensure upper bound expression based 8304 // on PrevUB instead of NumIterations - used to implement 'for' when found 8305 // in combination with 'distribute', like in 'distribute parallel for' 8306 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 8307 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 8308 if (isOpenMPLoopBoundSharingDirective(DKind)) { 8309 DistCond = SemaRef.BuildBinOp( 8310 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 8311 assert(DistCond.isUsable() && "distribute cond expr was not built"); 8312 8313 DistInc = 8314 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 8315 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8316 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 8317 DistInc.get()); 8318 DistInc = 8319 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 8320 assert(DistInc.isUsable() && "distribute inc expr was not built"); 8321 8322 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 8323 // construct 8324 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 8325 ExprResult IsUBGreater = 8326 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 8327 ExprResult CondOp = SemaRef.ActOnConditionalOp( 8328 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 8329 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 8330 CondOp.get()); 8331 PrevEUB = 8332 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 8333 8334 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 8335 // parallel for is in combination with a distribute directive with 8336 // schedule(static, 1) 8337 Expr *BoundPrevUB = PrevUB.get(); 8338 if (UseStrictCompare) { 8339 BoundPrevUB = 8340 SemaRef 8341 .BuildBinOp( 8342 CurScope, CondLoc, BO_Add, BoundPrevUB, 8343 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 8344 .get(); 8345 BoundPrevUB = 8346 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 8347 .get(); 8348 } 8349 ParForInDistCond = 8350 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 8351 IV.get(), BoundPrevUB); 8352 } 8353 8354 // Build updates and final values of the loop counters. 8355 bool HasErrors = false; 8356 Built.Counters.resize(NestedLoopCount); 8357 Built.Inits.resize(NestedLoopCount); 8358 Built.Updates.resize(NestedLoopCount); 8359 Built.Finals.resize(NestedLoopCount); 8360 Built.DependentCounters.resize(NestedLoopCount); 8361 Built.DependentInits.resize(NestedLoopCount); 8362 Built.FinalsConditions.resize(NestedLoopCount); 8363 { 8364 // We implement the following algorithm for obtaining the 8365 // original loop iteration variable values based on the 8366 // value of the collapsed loop iteration variable IV. 8367 // 8368 // Let n+1 be the number of collapsed loops in the nest. 8369 // Iteration variables (I0, I1, .... In) 8370 // Iteration counts (N0, N1, ... Nn) 8371 // 8372 // Acc = IV; 8373 // 8374 // To compute Ik for loop k, 0 <= k <= n, generate: 8375 // Prod = N(k+1) * N(k+2) * ... * Nn; 8376 // Ik = Acc / Prod; 8377 // Acc -= Ik * Prod; 8378 // 8379 ExprResult Acc = IV; 8380 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 8381 LoopIterationSpace &IS = IterSpaces[Cnt]; 8382 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 8383 ExprResult Iter; 8384 8385 // Compute prod 8386 ExprResult Prod = 8387 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 8388 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 8389 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 8390 IterSpaces[K].NumIterations); 8391 8392 // Iter = Acc / Prod 8393 // If there is at least one more inner loop to avoid 8394 // multiplication by 1. 8395 if (Cnt + 1 < NestedLoopCount) 8396 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 8397 Acc.get(), Prod.get()); 8398 else 8399 Iter = Acc; 8400 if (!Iter.isUsable()) { 8401 HasErrors = true; 8402 break; 8403 } 8404 8405 // Update Acc: 8406 // Acc -= Iter * Prod 8407 // Check if there is at least one more inner loop to avoid 8408 // multiplication by 1. 8409 if (Cnt + 1 < NestedLoopCount) 8410 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 8411 Iter.get(), Prod.get()); 8412 else 8413 Prod = Iter; 8414 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 8415 Acc.get(), Prod.get()); 8416 8417 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 8418 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 8419 DeclRefExpr *CounterVar = buildDeclRefExpr( 8420 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 8421 /*RefersToCapture=*/true); 8422 ExprResult Init = 8423 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 8424 IS.CounterInit, IS.IsNonRectangularLB, Captures); 8425 if (!Init.isUsable()) { 8426 HasErrors = true; 8427 break; 8428 } 8429 ExprResult Update = buildCounterUpdate( 8430 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 8431 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 8432 if (!Update.isUsable()) { 8433 HasErrors = true; 8434 break; 8435 } 8436 8437 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 8438 ExprResult Final = 8439 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 8440 IS.CounterInit, IS.NumIterations, IS.CounterStep, 8441 IS.Subtract, IS.IsNonRectangularLB, &Captures); 8442 if (!Final.isUsable()) { 8443 HasErrors = true; 8444 break; 8445 } 8446 8447 if (!Update.isUsable() || !Final.isUsable()) { 8448 HasErrors = true; 8449 break; 8450 } 8451 // Save results 8452 Built.Counters[Cnt] = IS.CounterVar; 8453 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 8454 Built.Inits[Cnt] = Init.get(); 8455 Built.Updates[Cnt] = Update.get(); 8456 Built.Finals[Cnt] = Final.get(); 8457 Built.DependentCounters[Cnt] = nullptr; 8458 Built.DependentInits[Cnt] = nullptr; 8459 Built.FinalsConditions[Cnt] = nullptr; 8460 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 8461 Built.DependentCounters[Cnt] = 8462 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8463 Built.DependentInits[Cnt] = 8464 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 8465 Built.FinalsConditions[Cnt] = IS.FinalCondition; 8466 } 8467 } 8468 } 8469 8470 if (HasErrors) 8471 return 0; 8472 8473 // Save results 8474 Built.IterationVarRef = IV.get(); 8475 Built.LastIteration = LastIteration.get(); 8476 Built.NumIterations = NumIterations.get(); 8477 Built.CalcLastIteration = SemaRef 8478 .ActOnFinishFullExpr(CalcLastIteration.get(), 8479 /*DiscardedValue=*/false) 8480 .get(); 8481 Built.PreCond = PreCond.get(); 8482 Built.PreInits = buildPreInits(C, Captures); 8483 Built.Cond = Cond.get(); 8484 Built.Init = Init.get(); 8485 Built.Inc = Inc.get(); 8486 Built.LB = LB.get(); 8487 Built.UB = UB.get(); 8488 Built.IL = IL.get(); 8489 Built.ST = ST.get(); 8490 Built.EUB = EUB.get(); 8491 Built.NLB = NextLB.get(); 8492 Built.NUB = NextUB.get(); 8493 Built.PrevLB = PrevLB.get(); 8494 Built.PrevUB = PrevUB.get(); 8495 Built.DistInc = DistInc.get(); 8496 Built.PrevEUB = PrevEUB.get(); 8497 Built.DistCombinedFields.LB = CombLB.get(); 8498 Built.DistCombinedFields.UB = CombUB.get(); 8499 Built.DistCombinedFields.EUB = CombEUB.get(); 8500 Built.DistCombinedFields.Init = CombInit.get(); 8501 Built.DistCombinedFields.Cond = CombCond.get(); 8502 Built.DistCombinedFields.NLB = CombNextLB.get(); 8503 Built.DistCombinedFields.NUB = CombNextUB.get(); 8504 Built.DistCombinedFields.DistCond = CombDistCond.get(); 8505 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 8506 8507 return NestedLoopCount; 8508 } 8509 8510 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 8511 auto CollapseClauses = 8512 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 8513 if (CollapseClauses.begin() != CollapseClauses.end()) 8514 return (*CollapseClauses.begin())->getNumForLoops(); 8515 return nullptr; 8516 } 8517 8518 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 8519 auto OrderedClauses = 8520 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 8521 if (OrderedClauses.begin() != OrderedClauses.end()) 8522 return (*OrderedClauses.begin())->getNumForLoops(); 8523 return nullptr; 8524 } 8525 8526 static bool checkSimdlenSafelenSpecified(Sema &S, 8527 const ArrayRef<OMPClause *> Clauses) { 8528 const OMPSafelenClause *Safelen = nullptr; 8529 const OMPSimdlenClause *Simdlen = nullptr; 8530 8531 for (const OMPClause *Clause : Clauses) { 8532 if (Clause->getClauseKind() == OMPC_safelen) 8533 Safelen = cast<OMPSafelenClause>(Clause); 8534 else if (Clause->getClauseKind() == OMPC_simdlen) 8535 Simdlen = cast<OMPSimdlenClause>(Clause); 8536 if (Safelen && Simdlen) 8537 break; 8538 } 8539 8540 if (Simdlen && Safelen) { 8541 const Expr *SimdlenLength = Simdlen->getSimdlen(); 8542 const Expr *SafelenLength = Safelen->getSafelen(); 8543 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 8544 SimdlenLength->isInstantiationDependent() || 8545 SimdlenLength->containsUnexpandedParameterPack()) 8546 return false; 8547 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 8548 SafelenLength->isInstantiationDependent() || 8549 SafelenLength->containsUnexpandedParameterPack()) 8550 return false; 8551 Expr::EvalResult SimdlenResult, SafelenResult; 8552 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 8553 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 8554 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 8555 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 8556 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 8557 // If both simdlen and safelen clauses are specified, the value of the 8558 // simdlen parameter must be less than or equal to the value of the safelen 8559 // parameter. 8560 if (SimdlenRes > SafelenRes) { 8561 S.Diag(SimdlenLength->getExprLoc(), 8562 diag::err_omp_wrong_simdlen_safelen_values) 8563 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 8564 return true; 8565 } 8566 } 8567 return false; 8568 } 8569 8570 StmtResult 8571 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8572 SourceLocation StartLoc, SourceLocation EndLoc, 8573 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8574 if (!AStmt) 8575 return StmtError(); 8576 8577 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8578 OMPLoopDirective::HelperExprs B; 8579 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8580 // define the nested loops number. 8581 unsigned NestedLoopCount = checkOpenMPLoop( 8582 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8583 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8584 if (NestedLoopCount == 0) 8585 return StmtError(); 8586 8587 assert((CurContext->isDependentContext() || B.builtAll()) && 8588 "omp simd loop exprs were not built"); 8589 8590 if (!CurContext->isDependentContext()) { 8591 // Finalize the clauses that need pre-built expressions for CodeGen. 8592 for (OMPClause *C : Clauses) { 8593 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8594 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8595 B.NumIterations, *this, CurScope, 8596 DSAStack)) 8597 return StmtError(); 8598 } 8599 } 8600 8601 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8602 return StmtError(); 8603 8604 setFunctionHasBranchProtectedScope(); 8605 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8606 Clauses, AStmt, B); 8607 } 8608 8609 StmtResult 8610 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 8611 SourceLocation StartLoc, SourceLocation EndLoc, 8612 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8613 if (!AStmt) 8614 return StmtError(); 8615 8616 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8617 OMPLoopDirective::HelperExprs B; 8618 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8619 // define the nested loops number. 8620 unsigned NestedLoopCount = checkOpenMPLoop( 8621 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 8622 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 8623 if (NestedLoopCount == 0) 8624 return StmtError(); 8625 8626 assert((CurContext->isDependentContext() || B.builtAll()) && 8627 "omp for loop exprs were not built"); 8628 8629 if (!CurContext->isDependentContext()) { 8630 // Finalize the clauses that need pre-built expressions for CodeGen. 8631 for (OMPClause *C : Clauses) { 8632 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8633 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8634 B.NumIterations, *this, CurScope, 8635 DSAStack)) 8636 return StmtError(); 8637 } 8638 } 8639 8640 setFunctionHasBranchProtectedScope(); 8641 return OMPForDirective::Create( 8642 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8643 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 8644 } 8645 8646 StmtResult Sema::ActOnOpenMPForSimdDirective( 8647 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8648 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8649 if (!AStmt) 8650 return StmtError(); 8651 8652 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8653 OMPLoopDirective::HelperExprs B; 8654 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8655 // define the nested loops number. 8656 unsigned NestedLoopCount = 8657 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 8658 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8659 VarsWithImplicitDSA, B); 8660 if (NestedLoopCount == 0) 8661 return StmtError(); 8662 8663 assert((CurContext->isDependentContext() || B.builtAll()) && 8664 "omp for simd loop exprs were not built"); 8665 8666 if (!CurContext->isDependentContext()) { 8667 // Finalize the clauses that need pre-built expressions for CodeGen. 8668 for (OMPClause *C : Clauses) { 8669 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8670 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8671 B.NumIterations, *this, CurScope, 8672 DSAStack)) 8673 return StmtError(); 8674 } 8675 } 8676 8677 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8678 return StmtError(); 8679 8680 setFunctionHasBranchProtectedScope(); 8681 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 8682 Clauses, AStmt, B); 8683 } 8684 8685 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 8686 Stmt *AStmt, 8687 SourceLocation StartLoc, 8688 SourceLocation EndLoc) { 8689 if (!AStmt) 8690 return StmtError(); 8691 8692 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8693 auto BaseStmt = AStmt; 8694 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8695 BaseStmt = CS->getCapturedStmt(); 8696 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8697 auto S = C->children(); 8698 if (S.begin() == S.end()) 8699 return StmtError(); 8700 // All associated statements must be '#pragma omp section' except for 8701 // the first one. 8702 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8703 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8704 if (SectionStmt) 8705 Diag(SectionStmt->getBeginLoc(), 8706 diag::err_omp_sections_substmt_not_section); 8707 return StmtError(); 8708 } 8709 cast<OMPSectionDirective>(SectionStmt) 8710 ->setHasCancel(DSAStack->isCancelRegion()); 8711 } 8712 } else { 8713 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 8714 return StmtError(); 8715 } 8716 8717 setFunctionHasBranchProtectedScope(); 8718 8719 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 8720 DSAStack->getTaskgroupReductionRef(), 8721 DSAStack->isCancelRegion()); 8722 } 8723 8724 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 8725 SourceLocation StartLoc, 8726 SourceLocation EndLoc) { 8727 if (!AStmt) 8728 return StmtError(); 8729 8730 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8731 8732 setFunctionHasBranchProtectedScope(); 8733 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 8734 8735 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 8736 DSAStack->isCancelRegion()); 8737 } 8738 8739 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 8740 Stmt *AStmt, 8741 SourceLocation StartLoc, 8742 SourceLocation EndLoc) { 8743 if (!AStmt) 8744 return StmtError(); 8745 8746 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8747 8748 setFunctionHasBranchProtectedScope(); 8749 8750 // OpenMP [2.7.3, single Construct, Restrictions] 8751 // The copyprivate clause must not be used with the nowait clause. 8752 const OMPClause *Nowait = nullptr; 8753 const OMPClause *Copyprivate = nullptr; 8754 for (const OMPClause *Clause : Clauses) { 8755 if (Clause->getClauseKind() == OMPC_nowait) 8756 Nowait = Clause; 8757 else if (Clause->getClauseKind() == OMPC_copyprivate) 8758 Copyprivate = Clause; 8759 if (Copyprivate && Nowait) { 8760 Diag(Copyprivate->getBeginLoc(), 8761 diag::err_omp_single_copyprivate_with_nowait); 8762 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 8763 return StmtError(); 8764 } 8765 } 8766 8767 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 8768 } 8769 8770 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 8771 SourceLocation StartLoc, 8772 SourceLocation EndLoc) { 8773 if (!AStmt) 8774 return StmtError(); 8775 8776 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8777 8778 setFunctionHasBranchProtectedScope(); 8779 8780 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 8781 } 8782 8783 StmtResult Sema::ActOnOpenMPCriticalDirective( 8784 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 8785 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 8786 if (!AStmt) 8787 return StmtError(); 8788 8789 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8790 8791 bool ErrorFound = false; 8792 llvm::APSInt Hint; 8793 SourceLocation HintLoc; 8794 bool DependentHint = false; 8795 for (const OMPClause *C : Clauses) { 8796 if (C->getClauseKind() == OMPC_hint) { 8797 if (!DirName.getName()) { 8798 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 8799 ErrorFound = true; 8800 } 8801 Expr *E = cast<OMPHintClause>(C)->getHint(); 8802 if (E->isTypeDependent() || E->isValueDependent() || 8803 E->isInstantiationDependent()) { 8804 DependentHint = true; 8805 } else { 8806 Hint = E->EvaluateKnownConstInt(Context); 8807 HintLoc = C->getBeginLoc(); 8808 } 8809 } 8810 } 8811 if (ErrorFound) 8812 return StmtError(); 8813 const auto Pair = DSAStack->getCriticalWithHint(DirName); 8814 if (Pair.first && DirName.getName() && !DependentHint) { 8815 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 8816 Diag(StartLoc, diag::err_omp_critical_with_hint); 8817 if (HintLoc.isValid()) 8818 Diag(HintLoc, diag::note_omp_critical_hint_here) 8819 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 8820 else 8821 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 8822 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 8823 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 8824 << 1 8825 << C->getHint()->EvaluateKnownConstInt(Context).toString( 8826 /*Radix=*/10, /*Signed=*/false); 8827 } else { 8828 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 8829 } 8830 } 8831 } 8832 8833 setFunctionHasBranchProtectedScope(); 8834 8835 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 8836 Clauses, AStmt); 8837 if (!Pair.first && DirName.getName() && !DependentHint) 8838 DSAStack->addCriticalWithHint(Dir, Hint); 8839 return Dir; 8840 } 8841 8842 StmtResult Sema::ActOnOpenMPParallelForDirective( 8843 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8844 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8845 if (!AStmt) 8846 return StmtError(); 8847 8848 auto *CS = cast<CapturedStmt>(AStmt); 8849 // 1.2.2 OpenMP Language Terminology 8850 // Structured block - An executable statement with a single entry at the 8851 // top and a single exit at the bottom. 8852 // The point of exit cannot be a branch out of the structured block. 8853 // longjmp() and throw() must not violate the entry/exit criteria. 8854 CS->getCapturedDecl()->setNothrow(); 8855 8856 OMPLoopDirective::HelperExprs B; 8857 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8858 // define the nested loops number. 8859 unsigned NestedLoopCount = 8860 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 8861 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8862 VarsWithImplicitDSA, B); 8863 if (NestedLoopCount == 0) 8864 return StmtError(); 8865 8866 assert((CurContext->isDependentContext() || B.builtAll()) && 8867 "omp parallel for loop exprs were not built"); 8868 8869 if (!CurContext->isDependentContext()) { 8870 // Finalize the clauses that need pre-built expressions for CodeGen. 8871 for (OMPClause *C : Clauses) { 8872 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8873 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8874 B.NumIterations, *this, CurScope, 8875 DSAStack)) 8876 return StmtError(); 8877 } 8878 } 8879 8880 setFunctionHasBranchProtectedScope(); 8881 return OMPParallelForDirective::Create( 8882 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8883 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 8884 } 8885 8886 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 8887 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8888 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8889 if (!AStmt) 8890 return StmtError(); 8891 8892 auto *CS = cast<CapturedStmt>(AStmt); 8893 // 1.2.2 OpenMP Language Terminology 8894 // Structured block - An executable statement with a single entry at the 8895 // top and a single exit at the bottom. 8896 // The point of exit cannot be a branch out of the structured block. 8897 // longjmp() and throw() must not violate the entry/exit criteria. 8898 CS->getCapturedDecl()->setNothrow(); 8899 8900 OMPLoopDirective::HelperExprs B; 8901 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8902 // define the nested loops number. 8903 unsigned NestedLoopCount = 8904 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 8905 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 8906 VarsWithImplicitDSA, B); 8907 if (NestedLoopCount == 0) 8908 return StmtError(); 8909 8910 if (!CurContext->isDependentContext()) { 8911 // Finalize the clauses that need pre-built expressions for CodeGen. 8912 for (OMPClause *C : Clauses) { 8913 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8914 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8915 B.NumIterations, *this, CurScope, 8916 DSAStack)) 8917 return StmtError(); 8918 } 8919 } 8920 8921 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8922 return StmtError(); 8923 8924 setFunctionHasBranchProtectedScope(); 8925 return OMPParallelForSimdDirective::Create( 8926 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8927 } 8928 8929 StmtResult 8930 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 8931 Stmt *AStmt, SourceLocation StartLoc, 8932 SourceLocation EndLoc) { 8933 if (!AStmt) 8934 return StmtError(); 8935 8936 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8937 auto *CS = cast<CapturedStmt>(AStmt); 8938 // 1.2.2 OpenMP Language Terminology 8939 // Structured block - An executable statement with a single entry at the 8940 // top and a single exit at the bottom. 8941 // The point of exit cannot be a branch out of the structured block. 8942 // longjmp() and throw() must not violate the entry/exit criteria. 8943 CS->getCapturedDecl()->setNothrow(); 8944 8945 setFunctionHasBranchProtectedScope(); 8946 8947 return OMPParallelMasterDirective::Create( 8948 Context, StartLoc, EndLoc, Clauses, AStmt, 8949 DSAStack->getTaskgroupReductionRef()); 8950 } 8951 8952 StmtResult 8953 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 8954 Stmt *AStmt, SourceLocation StartLoc, 8955 SourceLocation EndLoc) { 8956 if (!AStmt) 8957 return StmtError(); 8958 8959 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 8960 auto BaseStmt = AStmt; 8961 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 8962 BaseStmt = CS->getCapturedStmt(); 8963 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 8964 auto S = C->children(); 8965 if (S.begin() == S.end()) 8966 return StmtError(); 8967 // All associated statements must be '#pragma omp section' except for 8968 // the first one. 8969 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 8970 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 8971 if (SectionStmt) 8972 Diag(SectionStmt->getBeginLoc(), 8973 diag::err_omp_parallel_sections_substmt_not_section); 8974 return StmtError(); 8975 } 8976 cast<OMPSectionDirective>(SectionStmt) 8977 ->setHasCancel(DSAStack->isCancelRegion()); 8978 } 8979 } else { 8980 Diag(AStmt->getBeginLoc(), 8981 diag::err_omp_parallel_sections_not_compound_stmt); 8982 return StmtError(); 8983 } 8984 8985 setFunctionHasBranchProtectedScope(); 8986 8987 return OMPParallelSectionsDirective::Create( 8988 Context, StartLoc, EndLoc, Clauses, AStmt, 8989 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 8990 } 8991 8992 /// detach and mergeable clauses are mutially exclusive, check for it. 8993 static bool checkDetachMergeableClauses(Sema &S, 8994 ArrayRef<OMPClause *> Clauses) { 8995 const OMPClause *PrevClause = nullptr; 8996 bool ErrorFound = false; 8997 for (const OMPClause *C : Clauses) { 8998 if (C->getClauseKind() == OMPC_detach || 8999 C->getClauseKind() == OMPC_mergeable) { 9000 if (!PrevClause) { 9001 PrevClause = C; 9002 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 9003 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 9004 << getOpenMPClauseName(C->getClauseKind()) 9005 << getOpenMPClauseName(PrevClause->getClauseKind()); 9006 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 9007 << getOpenMPClauseName(PrevClause->getClauseKind()); 9008 ErrorFound = true; 9009 } 9010 } 9011 } 9012 return ErrorFound; 9013 } 9014 9015 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 9016 Stmt *AStmt, SourceLocation StartLoc, 9017 SourceLocation EndLoc) { 9018 if (!AStmt) 9019 return StmtError(); 9020 9021 // OpenMP 5.0, 2.10.1 task Construct 9022 // If a detach clause appears on the directive, then a mergeable clause cannot 9023 // appear on the same directive. 9024 if (checkDetachMergeableClauses(*this, Clauses)) 9025 return StmtError(); 9026 9027 auto *CS = cast<CapturedStmt>(AStmt); 9028 // 1.2.2 OpenMP Language Terminology 9029 // Structured block - An executable statement with a single entry at the 9030 // top and a single exit at the bottom. 9031 // The point of exit cannot be a branch out of the structured block. 9032 // longjmp() and throw() must not violate the entry/exit criteria. 9033 CS->getCapturedDecl()->setNothrow(); 9034 9035 setFunctionHasBranchProtectedScope(); 9036 9037 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9038 DSAStack->isCancelRegion()); 9039 } 9040 9041 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 9042 SourceLocation EndLoc) { 9043 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 9044 } 9045 9046 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 9047 SourceLocation EndLoc) { 9048 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 9049 } 9050 9051 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 9052 SourceLocation EndLoc) { 9053 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 9054 } 9055 9056 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 9057 Stmt *AStmt, 9058 SourceLocation StartLoc, 9059 SourceLocation EndLoc) { 9060 if (!AStmt) 9061 return StmtError(); 9062 9063 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9064 9065 setFunctionHasBranchProtectedScope(); 9066 9067 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 9068 AStmt, 9069 DSAStack->getTaskgroupReductionRef()); 9070 } 9071 9072 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 9073 SourceLocation StartLoc, 9074 SourceLocation EndLoc) { 9075 OMPFlushClause *FC = nullptr; 9076 OMPClause *OrderClause = nullptr; 9077 for (OMPClause *C : Clauses) { 9078 if (C->getClauseKind() == OMPC_flush) 9079 FC = cast<OMPFlushClause>(C); 9080 else 9081 OrderClause = C; 9082 } 9083 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9084 SourceLocation MemOrderLoc; 9085 for (const OMPClause *C : Clauses) { 9086 if (C->getClauseKind() == OMPC_acq_rel || 9087 C->getClauseKind() == OMPC_acquire || 9088 C->getClauseKind() == OMPC_release) { 9089 if (MemOrderKind != OMPC_unknown) { 9090 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9091 << getOpenMPDirectiveName(OMPD_flush) << 1 9092 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9093 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9094 << getOpenMPClauseName(MemOrderKind); 9095 } else { 9096 MemOrderKind = C->getClauseKind(); 9097 MemOrderLoc = C->getBeginLoc(); 9098 } 9099 } 9100 } 9101 if (FC && OrderClause) { 9102 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 9103 << getOpenMPClauseName(OrderClause->getClauseKind()); 9104 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 9105 << getOpenMPClauseName(OrderClause->getClauseKind()); 9106 return StmtError(); 9107 } 9108 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 9109 } 9110 9111 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 9112 SourceLocation StartLoc, 9113 SourceLocation EndLoc) { 9114 if (Clauses.empty()) { 9115 Diag(StartLoc, diag::err_omp_depobj_expected); 9116 return StmtError(); 9117 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 9118 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 9119 return StmtError(); 9120 } 9121 // Only depobj expression and another single clause is allowed. 9122 if (Clauses.size() > 2) { 9123 Diag(Clauses[2]->getBeginLoc(), 9124 diag::err_omp_depobj_single_clause_expected); 9125 return StmtError(); 9126 } else if (Clauses.size() < 1) { 9127 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 9128 return StmtError(); 9129 } 9130 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 9131 } 9132 9133 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 9134 SourceLocation StartLoc, 9135 SourceLocation EndLoc) { 9136 // Check that exactly one clause is specified. 9137 if (Clauses.size() != 1) { 9138 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 9139 diag::err_omp_scan_single_clause_expected); 9140 return StmtError(); 9141 } 9142 // Check that only one instance of scan directives is used in the same outer 9143 // region. 9144 if (DSAStack->doesParentHasScanDirective()) { 9145 Diag(StartLoc, diag::err_omp_several_scan_directives_in_region); 9146 Diag(DSAStack->getParentScanDirectiveLoc(), 9147 diag::note_omp_previous_scan_directive); 9148 return StmtError(); 9149 } 9150 DSAStack->setParentHasScanDirective(StartLoc); 9151 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 9152 } 9153 9154 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 9155 Stmt *AStmt, 9156 SourceLocation StartLoc, 9157 SourceLocation EndLoc) { 9158 const OMPClause *DependFound = nullptr; 9159 const OMPClause *DependSourceClause = nullptr; 9160 const OMPClause *DependSinkClause = nullptr; 9161 bool ErrorFound = false; 9162 const OMPThreadsClause *TC = nullptr; 9163 const OMPSIMDClause *SC = nullptr; 9164 for (const OMPClause *C : Clauses) { 9165 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 9166 DependFound = C; 9167 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 9168 if (DependSourceClause) { 9169 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 9170 << getOpenMPDirectiveName(OMPD_ordered) 9171 << getOpenMPClauseName(OMPC_depend) << 2; 9172 ErrorFound = true; 9173 } else { 9174 DependSourceClause = C; 9175 } 9176 if (DependSinkClause) { 9177 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9178 << 0; 9179 ErrorFound = true; 9180 } 9181 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 9182 if (DependSourceClause) { 9183 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 9184 << 1; 9185 ErrorFound = true; 9186 } 9187 DependSinkClause = C; 9188 } 9189 } else if (C->getClauseKind() == OMPC_threads) { 9190 TC = cast<OMPThreadsClause>(C); 9191 } else if (C->getClauseKind() == OMPC_simd) { 9192 SC = cast<OMPSIMDClause>(C); 9193 } 9194 } 9195 if (!ErrorFound && !SC && 9196 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 9197 // OpenMP [2.8.1,simd Construct, Restrictions] 9198 // An ordered construct with the simd clause is the only OpenMP construct 9199 // that can appear in the simd region. 9200 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 9201 << (LangOpts.OpenMP >= 50 ? 1 : 0); 9202 ErrorFound = true; 9203 } else if (DependFound && (TC || SC)) { 9204 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 9205 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 9206 ErrorFound = true; 9207 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 9208 Diag(DependFound->getBeginLoc(), 9209 diag::err_omp_ordered_directive_without_param); 9210 ErrorFound = true; 9211 } else if (TC || Clauses.empty()) { 9212 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 9213 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 9214 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 9215 << (TC != nullptr); 9216 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 9217 ErrorFound = true; 9218 } 9219 } 9220 if ((!AStmt && !DependFound) || ErrorFound) 9221 return StmtError(); 9222 9223 if (AStmt) { 9224 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 9225 9226 setFunctionHasBranchProtectedScope(); 9227 } 9228 9229 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 9230 } 9231 9232 namespace { 9233 /// Helper class for checking expression in 'omp atomic [update]' 9234 /// construct. 9235 class OpenMPAtomicUpdateChecker { 9236 /// Error results for atomic update expressions. 9237 enum ExprAnalysisErrorCode { 9238 /// A statement is not an expression statement. 9239 NotAnExpression, 9240 /// Expression is not builtin binary or unary operation. 9241 NotABinaryOrUnaryExpression, 9242 /// Unary operation is not post-/pre- increment/decrement operation. 9243 NotAnUnaryIncDecExpression, 9244 /// An expression is not of scalar type. 9245 NotAScalarType, 9246 /// A binary operation is not an assignment operation. 9247 NotAnAssignmentOp, 9248 /// RHS part of the binary operation is not a binary expression. 9249 NotABinaryExpression, 9250 /// RHS part is not additive/multiplicative/shift/biwise binary 9251 /// expression. 9252 NotABinaryOperator, 9253 /// RHS binary operation does not have reference to the updated LHS 9254 /// part. 9255 NotAnUpdateExpression, 9256 /// No errors is found. 9257 NoError 9258 }; 9259 /// Reference to Sema. 9260 Sema &SemaRef; 9261 /// A location for note diagnostics (when error is found). 9262 SourceLocation NoteLoc; 9263 /// 'x' lvalue part of the source atomic expression. 9264 Expr *X; 9265 /// 'expr' rvalue part of the source atomic expression. 9266 Expr *E; 9267 /// Helper expression of the form 9268 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9269 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9270 Expr *UpdateExpr; 9271 /// Is 'x' a LHS in a RHS part of full update expression. It is 9272 /// important for non-associative operations. 9273 bool IsXLHSInRHSPart; 9274 BinaryOperatorKind Op; 9275 SourceLocation OpLoc; 9276 /// true if the source expression is a postfix unary operation, false 9277 /// if it is a prefix unary operation. 9278 bool IsPostfixUpdate; 9279 9280 public: 9281 OpenMPAtomicUpdateChecker(Sema &SemaRef) 9282 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 9283 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 9284 /// Check specified statement that it is suitable for 'atomic update' 9285 /// constructs and extract 'x', 'expr' and Operation from the original 9286 /// expression. If DiagId and NoteId == 0, then only check is performed 9287 /// without error notification. 9288 /// \param DiagId Diagnostic which should be emitted if error is found. 9289 /// \param NoteId Diagnostic note for the main error message. 9290 /// \return true if statement is not an update expression, false otherwise. 9291 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 9292 /// Return the 'x' lvalue part of the source atomic expression. 9293 Expr *getX() const { return X; } 9294 /// Return the 'expr' rvalue part of the source atomic expression. 9295 Expr *getExpr() const { return E; } 9296 /// Return the update expression used in calculation of the updated 9297 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 9298 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 9299 Expr *getUpdateExpr() const { return UpdateExpr; } 9300 /// Return true if 'x' is LHS in RHS part of full update expression, 9301 /// false otherwise. 9302 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 9303 9304 /// true if the source expression is a postfix unary operation, false 9305 /// if it is a prefix unary operation. 9306 bool isPostfixUpdate() const { return IsPostfixUpdate; } 9307 9308 private: 9309 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 9310 unsigned NoteId = 0); 9311 }; 9312 } // namespace 9313 9314 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 9315 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 9316 ExprAnalysisErrorCode ErrorFound = NoError; 9317 SourceLocation ErrorLoc, NoteLoc; 9318 SourceRange ErrorRange, NoteRange; 9319 // Allowed constructs are: 9320 // x = x binop expr; 9321 // x = expr binop x; 9322 if (AtomicBinOp->getOpcode() == BO_Assign) { 9323 X = AtomicBinOp->getLHS(); 9324 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 9325 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 9326 if (AtomicInnerBinOp->isMultiplicativeOp() || 9327 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 9328 AtomicInnerBinOp->isBitwiseOp()) { 9329 Op = AtomicInnerBinOp->getOpcode(); 9330 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 9331 Expr *LHS = AtomicInnerBinOp->getLHS(); 9332 Expr *RHS = AtomicInnerBinOp->getRHS(); 9333 llvm::FoldingSetNodeID XId, LHSId, RHSId; 9334 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 9335 /*Canonical=*/true); 9336 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 9337 /*Canonical=*/true); 9338 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 9339 /*Canonical=*/true); 9340 if (XId == LHSId) { 9341 E = RHS; 9342 IsXLHSInRHSPart = true; 9343 } else if (XId == RHSId) { 9344 E = LHS; 9345 IsXLHSInRHSPart = false; 9346 } else { 9347 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9348 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9349 NoteLoc = X->getExprLoc(); 9350 NoteRange = X->getSourceRange(); 9351 ErrorFound = NotAnUpdateExpression; 9352 } 9353 } else { 9354 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 9355 ErrorRange = AtomicInnerBinOp->getSourceRange(); 9356 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 9357 NoteRange = SourceRange(NoteLoc, NoteLoc); 9358 ErrorFound = NotABinaryOperator; 9359 } 9360 } else { 9361 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 9362 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 9363 ErrorFound = NotABinaryExpression; 9364 } 9365 } else { 9366 ErrorLoc = AtomicBinOp->getExprLoc(); 9367 ErrorRange = AtomicBinOp->getSourceRange(); 9368 NoteLoc = AtomicBinOp->getOperatorLoc(); 9369 NoteRange = SourceRange(NoteLoc, NoteLoc); 9370 ErrorFound = NotAnAssignmentOp; 9371 } 9372 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9373 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9374 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9375 return true; 9376 } 9377 if (SemaRef.CurContext->isDependentContext()) 9378 E = X = UpdateExpr = nullptr; 9379 return ErrorFound != NoError; 9380 } 9381 9382 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 9383 unsigned NoteId) { 9384 ExprAnalysisErrorCode ErrorFound = NoError; 9385 SourceLocation ErrorLoc, NoteLoc; 9386 SourceRange ErrorRange, NoteRange; 9387 // Allowed constructs are: 9388 // x++; 9389 // x--; 9390 // ++x; 9391 // --x; 9392 // x binop= expr; 9393 // x = x binop expr; 9394 // x = expr binop x; 9395 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 9396 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 9397 if (AtomicBody->getType()->isScalarType() || 9398 AtomicBody->isInstantiationDependent()) { 9399 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 9400 AtomicBody->IgnoreParenImpCasts())) { 9401 // Check for Compound Assignment Operation 9402 Op = BinaryOperator::getOpForCompoundAssignment( 9403 AtomicCompAssignOp->getOpcode()); 9404 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 9405 E = AtomicCompAssignOp->getRHS(); 9406 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 9407 IsXLHSInRHSPart = true; 9408 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 9409 AtomicBody->IgnoreParenImpCasts())) { 9410 // Check for Binary Operation 9411 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 9412 return true; 9413 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 9414 AtomicBody->IgnoreParenImpCasts())) { 9415 // Check for Unary Operation 9416 if (AtomicUnaryOp->isIncrementDecrementOp()) { 9417 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 9418 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 9419 OpLoc = AtomicUnaryOp->getOperatorLoc(); 9420 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 9421 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 9422 IsXLHSInRHSPart = true; 9423 } else { 9424 ErrorFound = NotAnUnaryIncDecExpression; 9425 ErrorLoc = AtomicUnaryOp->getExprLoc(); 9426 ErrorRange = AtomicUnaryOp->getSourceRange(); 9427 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 9428 NoteRange = SourceRange(NoteLoc, NoteLoc); 9429 } 9430 } else if (!AtomicBody->isInstantiationDependent()) { 9431 ErrorFound = NotABinaryOrUnaryExpression; 9432 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 9433 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 9434 } 9435 } else { 9436 ErrorFound = NotAScalarType; 9437 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 9438 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9439 } 9440 } else { 9441 ErrorFound = NotAnExpression; 9442 NoteLoc = ErrorLoc = S->getBeginLoc(); 9443 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9444 } 9445 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 9446 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 9447 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 9448 return true; 9449 } 9450 if (SemaRef.CurContext->isDependentContext()) 9451 E = X = UpdateExpr = nullptr; 9452 if (ErrorFound == NoError && E && X) { 9453 // Build an update expression of form 'OpaqueValueExpr(x) binop 9454 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 9455 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 9456 auto *OVEX = new (SemaRef.getASTContext()) 9457 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 9458 auto *OVEExpr = new (SemaRef.getASTContext()) 9459 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 9460 ExprResult Update = 9461 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 9462 IsXLHSInRHSPart ? OVEExpr : OVEX); 9463 if (Update.isInvalid()) 9464 return true; 9465 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 9466 Sema::AA_Casting); 9467 if (Update.isInvalid()) 9468 return true; 9469 UpdateExpr = Update.get(); 9470 } 9471 return ErrorFound != NoError; 9472 } 9473 9474 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 9475 Stmt *AStmt, 9476 SourceLocation StartLoc, 9477 SourceLocation EndLoc) { 9478 // Register location of the first atomic directive. 9479 DSAStack->addAtomicDirectiveLoc(StartLoc); 9480 if (!AStmt) 9481 return StmtError(); 9482 9483 auto *CS = cast<CapturedStmt>(AStmt); 9484 // 1.2.2 OpenMP Language Terminology 9485 // Structured block - An executable statement with a single entry at the 9486 // top and a single exit at the bottom. 9487 // The point of exit cannot be a branch out of the structured block. 9488 // longjmp() and throw() must not violate the entry/exit criteria. 9489 OpenMPClauseKind AtomicKind = OMPC_unknown; 9490 SourceLocation AtomicKindLoc; 9491 OpenMPClauseKind MemOrderKind = OMPC_unknown; 9492 SourceLocation MemOrderLoc; 9493 for (const OMPClause *C : Clauses) { 9494 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 9495 C->getClauseKind() == OMPC_update || 9496 C->getClauseKind() == OMPC_capture) { 9497 if (AtomicKind != OMPC_unknown) { 9498 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 9499 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9500 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 9501 << getOpenMPClauseName(AtomicKind); 9502 } else { 9503 AtomicKind = C->getClauseKind(); 9504 AtomicKindLoc = C->getBeginLoc(); 9505 } 9506 } 9507 if (C->getClauseKind() == OMPC_seq_cst || 9508 C->getClauseKind() == OMPC_acq_rel || 9509 C->getClauseKind() == OMPC_acquire || 9510 C->getClauseKind() == OMPC_release || 9511 C->getClauseKind() == OMPC_relaxed) { 9512 if (MemOrderKind != OMPC_unknown) { 9513 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 9514 << getOpenMPDirectiveName(OMPD_atomic) << 0 9515 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 9516 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9517 << getOpenMPClauseName(MemOrderKind); 9518 } else { 9519 MemOrderKind = C->getClauseKind(); 9520 MemOrderLoc = C->getBeginLoc(); 9521 } 9522 } 9523 } 9524 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 9525 // If atomic-clause is read then memory-order-clause must not be acq_rel or 9526 // release. 9527 // If atomic-clause is write then memory-order-clause must not be acq_rel or 9528 // acquire. 9529 // If atomic-clause is update or not present then memory-order-clause must not 9530 // be acq_rel or acquire. 9531 if ((AtomicKind == OMPC_read && 9532 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 9533 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 9534 AtomicKind == OMPC_unknown) && 9535 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 9536 SourceLocation Loc = AtomicKindLoc; 9537 if (AtomicKind == OMPC_unknown) 9538 Loc = StartLoc; 9539 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 9540 << getOpenMPClauseName(AtomicKind) 9541 << (AtomicKind == OMPC_unknown ? 1 : 0) 9542 << getOpenMPClauseName(MemOrderKind); 9543 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 9544 << getOpenMPClauseName(MemOrderKind); 9545 } 9546 9547 Stmt *Body = CS->getCapturedStmt(); 9548 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 9549 Body = EWC->getSubExpr(); 9550 9551 Expr *X = nullptr; 9552 Expr *V = nullptr; 9553 Expr *E = nullptr; 9554 Expr *UE = nullptr; 9555 bool IsXLHSInRHSPart = false; 9556 bool IsPostfixUpdate = false; 9557 // OpenMP [2.12.6, atomic Construct] 9558 // In the next expressions: 9559 // * x and v (as applicable) are both l-value expressions with scalar type. 9560 // * During the execution of an atomic region, multiple syntactic 9561 // occurrences of x must designate the same storage location. 9562 // * Neither of v and expr (as applicable) may access the storage location 9563 // designated by x. 9564 // * Neither of x and expr (as applicable) may access the storage location 9565 // designated by v. 9566 // * expr is an expression with scalar type. 9567 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 9568 // * binop, binop=, ++, and -- are not overloaded operators. 9569 // * The expression x binop expr must be numerically equivalent to x binop 9570 // (expr). This requirement is satisfied if the operators in expr have 9571 // precedence greater than binop, or by using parentheses around expr or 9572 // subexpressions of expr. 9573 // * The expression expr binop x must be numerically equivalent to (expr) 9574 // binop x. This requirement is satisfied if the operators in expr have 9575 // precedence equal to or greater than binop, or by using parentheses around 9576 // expr or subexpressions of expr. 9577 // * For forms that allow multiple occurrences of x, the number of times 9578 // that x is evaluated is unspecified. 9579 if (AtomicKind == OMPC_read) { 9580 enum { 9581 NotAnExpression, 9582 NotAnAssignmentOp, 9583 NotAScalarType, 9584 NotAnLValue, 9585 NoError 9586 } ErrorFound = NoError; 9587 SourceLocation ErrorLoc, NoteLoc; 9588 SourceRange ErrorRange, NoteRange; 9589 // If clause is read: 9590 // v = x; 9591 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9592 const auto *AtomicBinOp = 9593 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9594 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9595 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9596 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 9597 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9598 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 9599 if (!X->isLValue() || !V->isLValue()) { 9600 const Expr *NotLValueExpr = X->isLValue() ? V : X; 9601 ErrorFound = NotAnLValue; 9602 ErrorLoc = AtomicBinOp->getExprLoc(); 9603 ErrorRange = AtomicBinOp->getSourceRange(); 9604 NoteLoc = NotLValueExpr->getExprLoc(); 9605 NoteRange = NotLValueExpr->getSourceRange(); 9606 } 9607 } else if (!X->isInstantiationDependent() || 9608 !V->isInstantiationDependent()) { 9609 const Expr *NotScalarExpr = 9610 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9611 ? V 9612 : X; 9613 ErrorFound = NotAScalarType; 9614 ErrorLoc = AtomicBinOp->getExprLoc(); 9615 ErrorRange = AtomicBinOp->getSourceRange(); 9616 NoteLoc = NotScalarExpr->getExprLoc(); 9617 NoteRange = NotScalarExpr->getSourceRange(); 9618 } 9619 } else if (!AtomicBody->isInstantiationDependent()) { 9620 ErrorFound = NotAnAssignmentOp; 9621 ErrorLoc = AtomicBody->getExprLoc(); 9622 ErrorRange = AtomicBody->getSourceRange(); 9623 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9624 : AtomicBody->getExprLoc(); 9625 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9626 : AtomicBody->getSourceRange(); 9627 } 9628 } else { 9629 ErrorFound = NotAnExpression; 9630 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9631 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9632 } 9633 if (ErrorFound != NoError) { 9634 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 9635 << ErrorRange; 9636 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9637 << NoteRange; 9638 return StmtError(); 9639 } 9640 if (CurContext->isDependentContext()) 9641 V = X = nullptr; 9642 } else if (AtomicKind == OMPC_write) { 9643 enum { 9644 NotAnExpression, 9645 NotAnAssignmentOp, 9646 NotAScalarType, 9647 NotAnLValue, 9648 NoError 9649 } ErrorFound = NoError; 9650 SourceLocation ErrorLoc, NoteLoc; 9651 SourceRange ErrorRange, NoteRange; 9652 // If clause is write: 9653 // x = expr; 9654 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9655 const auto *AtomicBinOp = 9656 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9657 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9658 X = AtomicBinOp->getLHS(); 9659 E = AtomicBinOp->getRHS(); 9660 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 9661 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 9662 if (!X->isLValue()) { 9663 ErrorFound = NotAnLValue; 9664 ErrorLoc = AtomicBinOp->getExprLoc(); 9665 ErrorRange = AtomicBinOp->getSourceRange(); 9666 NoteLoc = X->getExprLoc(); 9667 NoteRange = X->getSourceRange(); 9668 } 9669 } else if (!X->isInstantiationDependent() || 9670 !E->isInstantiationDependent()) { 9671 const Expr *NotScalarExpr = 9672 (X->isInstantiationDependent() || X->getType()->isScalarType()) 9673 ? E 9674 : X; 9675 ErrorFound = NotAScalarType; 9676 ErrorLoc = AtomicBinOp->getExprLoc(); 9677 ErrorRange = AtomicBinOp->getSourceRange(); 9678 NoteLoc = NotScalarExpr->getExprLoc(); 9679 NoteRange = NotScalarExpr->getSourceRange(); 9680 } 9681 } else if (!AtomicBody->isInstantiationDependent()) { 9682 ErrorFound = NotAnAssignmentOp; 9683 ErrorLoc = AtomicBody->getExprLoc(); 9684 ErrorRange = AtomicBody->getSourceRange(); 9685 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9686 : AtomicBody->getExprLoc(); 9687 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9688 : AtomicBody->getSourceRange(); 9689 } 9690 } else { 9691 ErrorFound = NotAnExpression; 9692 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9693 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 9694 } 9695 if (ErrorFound != NoError) { 9696 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 9697 << ErrorRange; 9698 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 9699 << NoteRange; 9700 return StmtError(); 9701 } 9702 if (CurContext->isDependentContext()) 9703 E = X = nullptr; 9704 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 9705 // If clause is update: 9706 // x++; 9707 // x--; 9708 // ++x; 9709 // --x; 9710 // x binop= expr; 9711 // x = x binop expr; 9712 // x = expr binop x; 9713 OpenMPAtomicUpdateChecker Checker(*this); 9714 if (Checker.checkStatement( 9715 Body, (AtomicKind == OMPC_update) 9716 ? diag::err_omp_atomic_update_not_expression_statement 9717 : diag::err_omp_atomic_not_expression_statement, 9718 diag::note_omp_atomic_update)) 9719 return StmtError(); 9720 if (!CurContext->isDependentContext()) { 9721 E = Checker.getExpr(); 9722 X = Checker.getX(); 9723 UE = Checker.getUpdateExpr(); 9724 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9725 } 9726 } else if (AtomicKind == OMPC_capture) { 9727 enum { 9728 NotAnAssignmentOp, 9729 NotACompoundStatement, 9730 NotTwoSubstatements, 9731 NotASpecificExpression, 9732 NoError 9733 } ErrorFound = NoError; 9734 SourceLocation ErrorLoc, NoteLoc; 9735 SourceRange ErrorRange, NoteRange; 9736 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 9737 // If clause is a capture: 9738 // v = x++; 9739 // v = x--; 9740 // v = ++x; 9741 // v = --x; 9742 // v = x binop= expr; 9743 // v = x = x binop expr; 9744 // v = x = expr binop x; 9745 const auto *AtomicBinOp = 9746 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 9747 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 9748 V = AtomicBinOp->getLHS(); 9749 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 9750 OpenMPAtomicUpdateChecker Checker(*this); 9751 if (Checker.checkStatement( 9752 Body, diag::err_omp_atomic_capture_not_expression_statement, 9753 diag::note_omp_atomic_update)) 9754 return StmtError(); 9755 E = Checker.getExpr(); 9756 X = Checker.getX(); 9757 UE = Checker.getUpdateExpr(); 9758 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9759 IsPostfixUpdate = Checker.isPostfixUpdate(); 9760 } else if (!AtomicBody->isInstantiationDependent()) { 9761 ErrorLoc = AtomicBody->getExprLoc(); 9762 ErrorRange = AtomicBody->getSourceRange(); 9763 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 9764 : AtomicBody->getExprLoc(); 9765 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 9766 : AtomicBody->getSourceRange(); 9767 ErrorFound = NotAnAssignmentOp; 9768 } 9769 if (ErrorFound != NoError) { 9770 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 9771 << ErrorRange; 9772 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9773 return StmtError(); 9774 } 9775 if (CurContext->isDependentContext()) 9776 UE = V = E = X = nullptr; 9777 } else { 9778 // If clause is a capture: 9779 // { v = x; x = expr; } 9780 // { v = x; x++; } 9781 // { v = x; x--; } 9782 // { v = x; ++x; } 9783 // { v = x; --x; } 9784 // { v = x; x binop= expr; } 9785 // { v = x; x = x binop expr; } 9786 // { v = x; x = expr binop x; } 9787 // { x++; v = x; } 9788 // { x--; v = x; } 9789 // { ++x; v = x; } 9790 // { --x; v = x; } 9791 // { x binop= expr; v = x; } 9792 // { x = x binop expr; v = x; } 9793 // { x = expr binop x; v = x; } 9794 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 9795 // Check that this is { expr1; expr2; } 9796 if (CS->size() == 2) { 9797 Stmt *First = CS->body_front(); 9798 Stmt *Second = CS->body_back(); 9799 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 9800 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 9801 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 9802 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 9803 // Need to find what subexpression is 'v' and what is 'x'. 9804 OpenMPAtomicUpdateChecker Checker(*this); 9805 bool IsUpdateExprFound = !Checker.checkStatement(Second); 9806 BinaryOperator *BinOp = nullptr; 9807 if (IsUpdateExprFound) { 9808 BinOp = dyn_cast<BinaryOperator>(First); 9809 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9810 } 9811 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9812 // { v = x; x++; } 9813 // { v = x; x--; } 9814 // { v = x; ++x; } 9815 // { v = x; --x; } 9816 // { v = x; x binop= expr; } 9817 // { v = x; x = x binop expr; } 9818 // { v = x; x = expr binop x; } 9819 // Check that the first expression has form v = x. 9820 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9821 llvm::FoldingSetNodeID XId, PossibleXId; 9822 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9823 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9824 IsUpdateExprFound = XId == PossibleXId; 9825 if (IsUpdateExprFound) { 9826 V = BinOp->getLHS(); 9827 X = Checker.getX(); 9828 E = Checker.getExpr(); 9829 UE = Checker.getUpdateExpr(); 9830 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9831 IsPostfixUpdate = true; 9832 } 9833 } 9834 if (!IsUpdateExprFound) { 9835 IsUpdateExprFound = !Checker.checkStatement(First); 9836 BinOp = nullptr; 9837 if (IsUpdateExprFound) { 9838 BinOp = dyn_cast<BinaryOperator>(Second); 9839 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 9840 } 9841 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 9842 // { x++; v = x; } 9843 // { x--; v = x; } 9844 // { ++x; v = x; } 9845 // { --x; v = x; } 9846 // { x binop= expr; v = x; } 9847 // { x = x binop expr; v = x; } 9848 // { x = expr binop x; v = x; } 9849 // Check that the second expression has form v = x. 9850 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 9851 llvm::FoldingSetNodeID XId, PossibleXId; 9852 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 9853 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 9854 IsUpdateExprFound = XId == PossibleXId; 9855 if (IsUpdateExprFound) { 9856 V = BinOp->getLHS(); 9857 X = Checker.getX(); 9858 E = Checker.getExpr(); 9859 UE = Checker.getUpdateExpr(); 9860 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 9861 IsPostfixUpdate = false; 9862 } 9863 } 9864 } 9865 if (!IsUpdateExprFound) { 9866 // { v = x; x = expr; } 9867 auto *FirstExpr = dyn_cast<Expr>(First); 9868 auto *SecondExpr = dyn_cast<Expr>(Second); 9869 if (!FirstExpr || !SecondExpr || 9870 !(FirstExpr->isInstantiationDependent() || 9871 SecondExpr->isInstantiationDependent())) { 9872 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 9873 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 9874 ErrorFound = NotAnAssignmentOp; 9875 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 9876 : First->getBeginLoc(); 9877 NoteRange = ErrorRange = FirstBinOp 9878 ? FirstBinOp->getSourceRange() 9879 : SourceRange(ErrorLoc, ErrorLoc); 9880 } else { 9881 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 9882 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 9883 ErrorFound = NotAnAssignmentOp; 9884 NoteLoc = ErrorLoc = SecondBinOp 9885 ? SecondBinOp->getOperatorLoc() 9886 : Second->getBeginLoc(); 9887 NoteRange = ErrorRange = 9888 SecondBinOp ? SecondBinOp->getSourceRange() 9889 : SourceRange(ErrorLoc, ErrorLoc); 9890 } else { 9891 Expr *PossibleXRHSInFirst = 9892 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 9893 Expr *PossibleXLHSInSecond = 9894 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 9895 llvm::FoldingSetNodeID X1Id, X2Id; 9896 PossibleXRHSInFirst->Profile(X1Id, Context, 9897 /*Canonical=*/true); 9898 PossibleXLHSInSecond->Profile(X2Id, Context, 9899 /*Canonical=*/true); 9900 IsUpdateExprFound = X1Id == X2Id; 9901 if (IsUpdateExprFound) { 9902 V = FirstBinOp->getLHS(); 9903 X = SecondBinOp->getLHS(); 9904 E = SecondBinOp->getRHS(); 9905 UE = nullptr; 9906 IsXLHSInRHSPart = false; 9907 IsPostfixUpdate = true; 9908 } else { 9909 ErrorFound = NotASpecificExpression; 9910 ErrorLoc = FirstBinOp->getExprLoc(); 9911 ErrorRange = FirstBinOp->getSourceRange(); 9912 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 9913 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 9914 } 9915 } 9916 } 9917 } 9918 } 9919 } else { 9920 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9921 NoteRange = ErrorRange = 9922 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9923 ErrorFound = NotTwoSubstatements; 9924 } 9925 } else { 9926 NoteLoc = ErrorLoc = Body->getBeginLoc(); 9927 NoteRange = ErrorRange = 9928 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 9929 ErrorFound = NotACompoundStatement; 9930 } 9931 if (ErrorFound != NoError) { 9932 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 9933 << ErrorRange; 9934 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 9935 return StmtError(); 9936 } 9937 if (CurContext->isDependentContext()) 9938 UE = V = E = X = nullptr; 9939 } 9940 } 9941 9942 setFunctionHasBranchProtectedScope(); 9943 9944 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 9945 X, V, E, UE, IsXLHSInRHSPart, 9946 IsPostfixUpdate); 9947 } 9948 9949 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 9950 Stmt *AStmt, 9951 SourceLocation StartLoc, 9952 SourceLocation EndLoc) { 9953 if (!AStmt) 9954 return StmtError(); 9955 9956 auto *CS = cast<CapturedStmt>(AStmt); 9957 // 1.2.2 OpenMP Language Terminology 9958 // Structured block - An executable statement with a single entry at the 9959 // top and a single exit at the bottom. 9960 // The point of exit cannot be a branch out of the structured block. 9961 // longjmp() and throw() must not violate the entry/exit criteria. 9962 CS->getCapturedDecl()->setNothrow(); 9963 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 9964 ThisCaptureLevel > 1; --ThisCaptureLevel) { 9965 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 9966 // 1.2.2 OpenMP Language Terminology 9967 // Structured block - An executable statement with a single entry at the 9968 // top and a single exit at the bottom. 9969 // The point of exit cannot be a branch out of the structured block. 9970 // longjmp() and throw() must not violate the entry/exit criteria. 9971 CS->getCapturedDecl()->setNothrow(); 9972 } 9973 9974 // OpenMP [2.16, Nesting of Regions] 9975 // If specified, a teams construct must be contained within a target 9976 // construct. That target construct must contain no statements or directives 9977 // outside of the teams construct. 9978 if (DSAStack->hasInnerTeamsRegion()) { 9979 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 9980 bool OMPTeamsFound = true; 9981 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 9982 auto I = CS->body_begin(); 9983 while (I != CS->body_end()) { 9984 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 9985 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 9986 OMPTeamsFound) { 9987 9988 OMPTeamsFound = false; 9989 break; 9990 } 9991 ++I; 9992 } 9993 assert(I != CS->body_end() && "Not found statement"); 9994 S = *I; 9995 } else { 9996 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 9997 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 9998 } 9999 if (!OMPTeamsFound) { 10000 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 10001 Diag(DSAStack->getInnerTeamsRegionLoc(), 10002 diag::note_omp_nested_teams_construct_here); 10003 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 10004 << isa<OMPExecutableDirective>(S); 10005 return StmtError(); 10006 } 10007 } 10008 10009 setFunctionHasBranchProtectedScope(); 10010 10011 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10012 } 10013 10014 StmtResult 10015 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 10016 Stmt *AStmt, SourceLocation StartLoc, 10017 SourceLocation EndLoc) { 10018 if (!AStmt) 10019 return StmtError(); 10020 10021 auto *CS = cast<CapturedStmt>(AStmt); 10022 // 1.2.2 OpenMP Language Terminology 10023 // Structured block - An executable statement with a single entry at the 10024 // top and a single exit at the bottom. 10025 // The point of exit cannot be a branch out of the structured block. 10026 // longjmp() and throw() must not violate the entry/exit criteria. 10027 CS->getCapturedDecl()->setNothrow(); 10028 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 10029 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10030 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10031 // 1.2.2 OpenMP Language Terminology 10032 // Structured block - An executable statement with a single entry at the 10033 // top and a single exit at the bottom. 10034 // The point of exit cannot be a branch out of the structured block. 10035 // longjmp() and throw() must not violate the entry/exit criteria. 10036 CS->getCapturedDecl()->setNothrow(); 10037 } 10038 10039 setFunctionHasBranchProtectedScope(); 10040 10041 return OMPTargetParallelDirective::Create( 10042 Context, StartLoc, EndLoc, Clauses, AStmt, 10043 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10044 } 10045 10046 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 10047 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10048 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10049 if (!AStmt) 10050 return StmtError(); 10051 10052 auto *CS = cast<CapturedStmt>(AStmt); 10053 // 1.2.2 OpenMP Language Terminology 10054 // Structured block - An executable statement with a single entry at the 10055 // top and a single exit at the bottom. 10056 // The point of exit cannot be a branch out of the structured block. 10057 // longjmp() and throw() must not violate the entry/exit criteria. 10058 CS->getCapturedDecl()->setNothrow(); 10059 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10060 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10061 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10062 // 1.2.2 OpenMP Language Terminology 10063 // Structured block - An executable statement with a single entry at the 10064 // top and a single exit at the bottom. 10065 // The point of exit cannot be a branch out of the structured block. 10066 // longjmp() and throw() must not violate the entry/exit criteria. 10067 CS->getCapturedDecl()->setNothrow(); 10068 } 10069 10070 OMPLoopDirective::HelperExprs B; 10071 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10072 // define the nested loops number. 10073 unsigned NestedLoopCount = 10074 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 10075 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10076 VarsWithImplicitDSA, B); 10077 if (NestedLoopCount == 0) 10078 return StmtError(); 10079 10080 assert((CurContext->isDependentContext() || B.builtAll()) && 10081 "omp target parallel for loop exprs were not built"); 10082 10083 if (!CurContext->isDependentContext()) { 10084 // Finalize the clauses that need pre-built expressions for CodeGen. 10085 for (OMPClause *C : Clauses) { 10086 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10087 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10088 B.NumIterations, *this, CurScope, 10089 DSAStack)) 10090 return StmtError(); 10091 } 10092 } 10093 10094 setFunctionHasBranchProtectedScope(); 10095 return OMPTargetParallelForDirective::Create( 10096 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10097 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10098 } 10099 10100 /// Check for existence of a map clause in the list of clauses. 10101 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 10102 const OpenMPClauseKind K) { 10103 return llvm::any_of( 10104 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 10105 } 10106 10107 template <typename... Params> 10108 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 10109 const Params... ClauseTypes) { 10110 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 10111 } 10112 10113 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 10114 Stmt *AStmt, 10115 SourceLocation StartLoc, 10116 SourceLocation EndLoc) { 10117 if (!AStmt) 10118 return StmtError(); 10119 10120 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10121 10122 // OpenMP [2.10.1, Restrictions, p. 97] 10123 // At least one map clause must appear on the directive. 10124 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 10125 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10126 << "'map' or 'use_device_ptr'" 10127 << getOpenMPDirectiveName(OMPD_target_data); 10128 return StmtError(); 10129 } 10130 10131 setFunctionHasBranchProtectedScope(); 10132 10133 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10134 AStmt); 10135 } 10136 10137 StmtResult 10138 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 10139 SourceLocation StartLoc, 10140 SourceLocation EndLoc, Stmt *AStmt) { 10141 if (!AStmt) 10142 return StmtError(); 10143 10144 auto *CS = cast<CapturedStmt>(AStmt); 10145 // 1.2.2 OpenMP Language Terminology 10146 // Structured block - An executable statement with a single entry at the 10147 // top and a single exit at the bottom. 10148 // The point of exit cannot be a branch out of the structured block. 10149 // longjmp() and throw() must not violate the entry/exit criteria. 10150 CS->getCapturedDecl()->setNothrow(); 10151 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 10152 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10153 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10154 // 1.2.2 OpenMP Language Terminology 10155 // Structured block - An executable statement with a single entry at the 10156 // top and a single exit at the bottom. 10157 // The point of exit cannot be a branch out of the structured block. 10158 // longjmp() and throw() must not violate the entry/exit criteria. 10159 CS->getCapturedDecl()->setNothrow(); 10160 } 10161 10162 // OpenMP [2.10.2, Restrictions, p. 99] 10163 // At least one map clause must appear on the directive. 10164 if (!hasClauses(Clauses, OMPC_map)) { 10165 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10166 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 10167 return StmtError(); 10168 } 10169 10170 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10171 AStmt); 10172 } 10173 10174 StmtResult 10175 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 10176 SourceLocation StartLoc, 10177 SourceLocation EndLoc, Stmt *AStmt) { 10178 if (!AStmt) 10179 return StmtError(); 10180 10181 auto *CS = cast<CapturedStmt>(AStmt); 10182 // 1.2.2 OpenMP Language Terminology 10183 // Structured block - An executable statement with a single entry at the 10184 // top and a single exit at the bottom. 10185 // The point of exit cannot be a branch out of the structured block. 10186 // longjmp() and throw() must not violate the entry/exit criteria. 10187 CS->getCapturedDecl()->setNothrow(); 10188 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 10189 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10190 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10191 // 1.2.2 OpenMP Language Terminology 10192 // Structured block - An executable statement with a single entry at the 10193 // top and a single exit at the bottom. 10194 // The point of exit cannot be a branch out of the structured block. 10195 // longjmp() and throw() must not violate the entry/exit criteria. 10196 CS->getCapturedDecl()->setNothrow(); 10197 } 10198 10199 // OpenMP [2.10.3, Restrictions, p. 102] 10200 // At least one map clause must appear on the directive. 10201 if (!hasClauses(Clauses, OMPC_map)) { 10202 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 10203 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 10204 return StmtError(); 10205 } 10206 10207 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 10208 AStmt); 10209 } 10210 10211 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 10212 SourceLocation StartLoc, 10213 SourceLocation EndLoc, 10214 Stmt *AStmt) { 10215 if (!AStmt) 10216 return StmtError(); 10217 10218 auto *CS = cast<CapturedStmt>(AStmt); 10219 // 1.2.2 OpenMP Language Terminology 10220 // Structured block - An executable statement with a single entry at the 10221 // top and a single exit at the bottom. 10222 // The point of exit cannot be a branch out of the structured block. 10223 // longjmp() and throw() must not violate the entry/exit criteria. 10224 CS->getCapturedDecl()->setNothrow(); 10225 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 10226 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10227 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10228 // 1.2.2 OpenMP Language Terminology 10229 // Structured block - An executable statement with a single entry at the 10230 // top and a single exit at the bottom. 10231 // The point of exit cannot be a branch out of the structured block. 10232 // longjmp() and throw() must not violate the entry/exit criteria. 10233 CS->getCapturedDecl()->setNothrow(); 10234 } 10235 10236 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 10237 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 10238 return StmtError(); 10239 } 10240 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 10241 AStmt); 10242 } 10243 10244 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 10245 Stmt *AStmt, SourceLocation StartLoc, 10246 SourceLocation EndLoc) { 10247 if (!AStmt) 10248 return StmtError(); 10249 10250 auto *CS = cast<CapturedStmt>(AStmt); 10251 // 1.2.2 OpenMP Language Terminology 10252 // Structured block - An executable statement with a single entry at the 10253 // top and a single exit at the bottom. 10254 // The point of exit cannot be a branch out of the structured block. 10255 // longjmp() and throw() must not violate the entry/exit criteria. 10256 CS->getCapturedDecl()->setNothrow(); 10257 10258 setFunctionHasBranchProtectedScope(); 10259 10260 DSAStack->setParentTeamsRegionLoc(StartLoc); 10261 10262 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10263 } 10264 10265 StmtResult 10266 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 10267 SourceLocation EndLoc, 10268 OpenMPDirectiveKind CancelRegion) { 10269 if (DSAStack->isParentNowaitRegion()) { 10270 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 10271 return StmtError(); 10272 } 10273 if (DSAStack->isParentOrderedRegion()) { 10274 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 10275 return StmtError(); 10276 } 10277 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 10278 CancelRegion); 10279 } 10280 10281 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 10282 SourceLocation StartLoc, 10283 SourceLocation EndLoc, 10284 OpenMPDirectiveKind CancelRegion) { 10285 if (DSAStack->isParentNowaitRegion()) { 10286 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 10287 return StmtError(); 10288 } 10289 if (DSAStack->isParentOrderedRegion()) { 10290 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 10291 return StmtError(); 10292 } 10293 DSAStack->setParentCancelRegion(/*Cancel=*/true); 10294 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 10295 CancelRegion); 10296 } 10297 10298 static bool checkGrainsizeNumTasksClauses(Sema &S, 10299 ArrayRef<OMPClause *> Clauses) { 10300 const OMPClause *PrevClause = nullptr; 10301 bool ErrorFound = false; 10302 for (const OMPClause *C : Clauses) { 10303 if (C->getClauseKind() == OMPC_grainsize || 10304 C->getClauseKind() == OMPC_num_tasks) { 10305 if (!PrevClause) 10306 PrevClause = C; 10307 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10308 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10309 << getOpenMPClauseName(C->getClauseKind()) 10310 << getOpenMPClauseName(PrevClause->getClauseKind()); 10311 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10312 << getOpenMPClauseName(PrevClause->getClauseKind()); 10313 ErrorFound = true; 10314 } 10315 } 10316 } 10317 return ErrorFound; 10318 } 10319 10320 static bool checkReductionClauseWithNogroup(Sema &S, 10321 ArrayRef<OMPClause *> Clauses) { 10322 const OMPClause *ReductionClause = nullptr; 10323 const OMPClause *NogroupClause = nullptr; 10324 for (const OMPClause *C : Clauses) { 10325 if (C->getClauseKind() == OMPC_reduction) { 10326 ReductionClause = C; 10327 if (NogroupClause) 10328 break; 10329 continue; 10330 } 10331 if (C->getClauseKind() == OMPC_nogroup) { 10332 NogroupClause = C; 10333 if (ReductionClause) 10334 break; 10335 continue; 10336 } 10337 } 10338 if (ReductionClause && NogroupClause) { 10339 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 10340 << SourceRange(NogroupClause->getBeginLoc(), 10341 NogroupClause->getEndLoc()); 10342 return true; 10343 } 10344 return false; 10345 } 10346 10347 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 10348 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10349 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10350 if (!AStmt) 10351 return StmtError(); 10352 10353 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10354 OMPLoopDirective::HelperExprs B; 10355 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10356 // define the nested loops number. 10357 unsigned NestedLoopCount = 10358 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 10359 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10360 VarsWithImplicitDSA, B); 10361 if (NestedLoopCount == 0) 10362 return StmtError(); 10363 10364 assert((CurContext->isDependentContext() || B.builtAll()) && 10365 "omp for loop exprs were not built"); 10366 10367 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10368 // The grainsize clause and num_tasks clause are mutually exclusive and may 10369 // not appear on the same taskloop directive. 10370 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10371 return StmtError(); 10372 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10373 // If a reduction clause is present on the taskloop directive, the nogroup 10374 // clause must not be specified. 10375 if (checkReductionClauseWithNogroup(*this, Clauses)) 10376 return StmtError(); 10377 10378 setFunctionHasBranchProtectedScope(); 10379 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10380 NestedLoopCount, Clauses, AStmt, B, 10381 DSAStack->isCancelRegion()); 10382 } 10383 10384 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 10385 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10386 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10387 if (!AStmt) 10388 return StmtError(); 10389 10390 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10391 OMPLoopDirective::HelperExprs B; 10392 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10393 // define the nested loops number. 10394 unsigned NestedLoopCount = 10395 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 10396 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10397 VarsWithImplicitDSA, B); 10398 if (NestedLoopCount == 0) 10399 return StmtError(); 10400 10401 assert((CurContext->isDependentContext() || B.builtAll()) && 10402 "omp for loop exprs were not built"); 10403 10404 if (!CurContext->isDependentContext()) { 10405 // Finalize the clauses that need pre-built expressions for CodeGen. 10406 for (OMPClause *C : Clauses) { 10407 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10408 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10409 B.NumIterations, *this, CurScope, 10410 DSAStack)) 10411 return StmtError(); 10412 } 10413 } 10414 10415 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10416 // The grainsize clause and num_tasks clause are mutually exclusive and may 10417 // not appear on the same taskloop directive. 10418 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10419 return StmtError(); 10420 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10421 // If a reduction clause is present on the taskloop directive, the nogroup 10422 // clause must not be specified. 10423 if (checkReductionClauseWithNogroup(*this, Clauses)) 10424 return StmtError(); 10425 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10426 return StmtError(); 10427 10428 setFunctionHasBranchProtectedScope(); 10429 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 10430 NestedLoopCount, Clauses, AStmt, B); 10431 } 10432 10433 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 10434 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10435 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10436 if (!AStmt) 10437 return StmtError(); 10438 10439 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10440 OMPLoopDirective::HelperExprs B; 10441 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10442 // define the nested loops number. 10443 unsigned NestedLoopCount = 10444 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 10445 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10446 VarsWithImplicitDSA, B); 10447 if (NestedLoopCount == 0) 10448 return StmtError(); 10449 10450 assert((CurContext->isDependentContext() || B.builtAll()) && 10451 "omp for loop exprs were not built"); 10452 10453 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10454 // The grainsize clause and num_tasks clause are mutually exclusive and may 10455 // not appear on the same taskloop directive. 10456 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10457 return StmtError(); 10458 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10459 // If a reduction clause is present on the taskloop directive, the nogroup 10460 // clause must not be specified. 10461 if (checkReductionClauseWithNogroup(*this, Clauses)) 10462 return StmtError(); 10463 10464 setFunctionHasBranchProtectedScope(); 10465 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 10466 NestedLoopCount, Clauses, AStmt, B, 10467 DSAStack->isCancelRegion()); 10468 } 10469 10470 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 10471 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10472 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10473 if (!AStmt) 10474 return StmtError(); 10475 10476 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10477 OMPLoopDirective::HelperExprs B; 10478 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10479 // define the nested loops number. 10480 unsigned NestedLoopCount = 10481 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10482 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 10483 VarsWithImplicitDSA, B); 10484 if (NestedLoopCount == 0) 10485 return StmtError(); 10486 10487 assert((CurContext->isDependentContext() || B.builtAll()) && 10488 "omp for loop exprs were not built"); 10489 10490 if (!CurContext->isDependentContext()) { 10491 // Finalize the clauses that need pre-built expressions for CodeGen. 10492 for (OMPClause *C : Clauses) { 10493 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10494 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10495 B.NumIterations, *this, CurScope, 10496 DSAStack)) 10497 return StmtError(); 10498 } 10499 } 10500 10501 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10502 // The grainsize clause and num_tasks clause are mutually exclusive and may 10503 // not appear on the same taskloop directive. 10504 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10505 return StmtError(); 10506 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10507 // If a reduction clause is present on the taskloop directive, the nogroup 10508 // clause must not be specified. 10509 if (checkReductionClauseWithNogroup(*this, Clauses)) 10510 return StmtError(); 10511 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10512 return StmtError(); 10513 10514 setFunctionHasBranchProtectedScope(); 10515 return OMPMasterTaskLoopSimdDirective::Create( 10516 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10517 } 10518 10519 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 10520 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10521 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10522 if (!AStmt) 10523 return StmtError(); 10524 10525 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10526 auto *CS = cast<CapturedStmt>(AStmt); 10527 // 1.2.2 OpenMP Language Terminology 10528 // Structured block - An executable statement with a single entry at the 10529 // top and a single exit at the bottom. 10530 // The point of exit cannot be a branch out of the structured block. 10531 // longjmp() and throw() must not violate the entry/exit criteria. 10532 CS->getCapturedDecl()->setNothrow(); 10533 for (int ThisCaptureLevel = 10534 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 10535 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10536 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10537 // 1.2.2 OpenMP Language Terminology 10538 // Structured block - An executable statement with a single entry at the 10539 // top and a single exit at the bottom. 10540 // The point of exit cannot be a branch out of the structured block. 10541 // longjmp() and throw() must not violate the entry/exit criteria. 10542 CS->getCapturedDecl()->setNothrow(); 10543 } 10544 10545 OMPLoopDirective::HelperExprs B; 10546 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10547 // define the nested loops number. 10548 unsigned NestedLoopCount = checkOpenMPLoop( 10549 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 10550 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10551 VarsWithImplicitDSA, B); 10552 if (NestedLoopCount == 0) 10553 return StmtError(); 10554 10555 assert((CurContext->isDependentContext() || B.builtAll()) && 10556 "omp for loop exprs were not built"); 10557 10558 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10559 // The grainsize clause and num_tasks clause are mutually exclusive and may 10560 // not appear on the same taskloop directive. 10561 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10562 return StmtError(); 10563 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10564 // If a reduction clause is present on the taskloop directive, the nogroup 10565 // clause must not be specified. 10566 if (checkReductionClauseWithNogroup(*this, Clauses)) 10567 return StmtError(); 10568 10569 setFunctionHasBranchProtectedScope(); 10570 return OMPParallelMasterTaskLoopDirective::Create( 10571 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10572 DSAStack->isCancelRegion()); 10573 } 10574 10575 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 10576 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10577 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10578 if (!AStmt) 10579 return StmtError(); 10580 10581 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10582 auto *CS = cast<CapturedStmt>(AStmt); 10583 // 1.2.2 OpenMP Language Terminology 10584 // Structured block - An executable statement with a single entry at the 10585 // top and a single exit at the bottom. 10586 // The point of exit cannot be a branch out of the structured block. 10587 // longjmp() and throw() must not violate the entry/exit criteria. 10588 CS->getCapturedDecl()->setNothrow(); 10589 for (int ThisCaptureLevel = 10590 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 10591 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10592 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10593 // 1.2.2 OpenMP Language Terminology 10594 // Structured block - An executable statement with a single entry at the 10595 // top and a single exit at the bottom. 10596 // The point of exit cannot be a branch out of the structured block. 10597 // longjmp() and throw() must not violate the entry/exit criteria. 10598 CS->getCapturedDecl()->setNothrow(); 10599 } 10600 10601 OMPLoopDirective::HelperExprs B; 10602 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10603 // define the nested loops number. 10604 unsigned NestedLoopCount = checkOpenMPLoop( 10605 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 10606 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10607 VarsWithImplicitDSA, B); 10608 if (NestedLoopCount == 0) 10609 return StmtError(); 10610 10611 assert((CurContext->isDependentContext() || B.builtAll()) && 10612 "omp for loop exprs were not built"); 10613 10614 if (!CurContext->isDependentContext()) { 10615 // Finalize the clauses that need pre-built expressions for CodeGen. 10616 for (OMPClause *C : Clauses) { 10617 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10618 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10619 B.NumIterations, *this, CurScope, 10620 DSAStack)) 10621 return StmtError(); 10622 } 10623 } 10624 10625 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10626 // The grainsize clause and num_tasks clause are mutually exclusive and may 10627 // not appear on the same taskloop directive. 10628 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 10629 return StmtError(); 10630 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 10631 // If a reduction clause is present on the taskloop directive, the nogroup 10632 // clause must not be specified. 10633 if (checkReductionClauseWithNogroup(*this, Clauses)) 10634 return StmtError(); 10635 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10636 return StmtError(); 10637 10638 setFunctionHasBranchProtectedScope(); 10639 return OMPParallelMasterTaskLoopSimdDirective::Create( 10640 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10641 } 10642 10643 StmtResult Sema::ActOnOpenMPDistributeDirective( 10644 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10645 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10646 if (!AStmt) 10647 return StmtError(); 10648 10649 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10650 OMPLoopDirective::HelperExprs B; 10651 // In presence of clause 'collapse' with number of loops, it will 10652 // define the nested loops number. 10653 unsigned NestedLoopCount = 10654 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 10655 nullptr /*ordered not a clause on distribute*/, AStmt, 10656 *this, *DSAStack, VarsWithImplicitDSA, B); 10657 if (NestedLoopCount == 0) 10658 return StmtError(); 10659 10660 assert((CurContext->isDependentContext() || B.builtAll()) && 10661 "omp for loop exprs were not built"); 10662 10663 setFunctionHasBranchProtectedScope(); 10664 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 10665 NestedLoopCount, Clauses, AStmt, B); 10666 } 10667 10668 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 10669 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10670 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10671 if (!AStmt) 10672 return StmtError(); 10673 10674 auto *CS = cast<CapturedStmt>(AStmt); 10675 // 1.2.2 OpenMP Language Terminology 10676 // Structured block - An executable statement with a single entry at the 10677 // top and a single exit at the bottom. 10678 // The point of exit cannot be a branch out of the structured block. 10679 // longjmp() and throw() must not violate the entry/exit criteria. 10680 CS->getCapturedDecl()->setNothrow(); 10681 for (int ThisCaptureLevel = 10682 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 10683 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10684 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10685 // 1.2.2 OpenMP Language Terminology 10686 // Structured block - An executable statement with a single entry at the 10687 // top and a single exit at the bottom. 10688 // The point of exit cannot be a branch out of the structured block. 10689 // longjmp() and throw() must not violate the entry/exit criteria. 10690 CS->getCapturedDecl()->setNothrow(); 10691 } 10692 10693 OMPLoopDirective::HelperExprs B; 10694 // In presence of clause 'collapse' with number of loops, it will 10695 // define the nested loops number. 10696 unsigned NestedLoopCount = checkOpenMPLoop( 10697 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 10698 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10699 VarsWithImplicitDSA, B); 10700 if (NestedLoopCount == 0) 10701 return StmtError(); 10702 10703 assert((CurContext->isDependentContext() || B.builtAll()) && 10704 "omp for loop exprs were not built"); 10705 10706 setFunctionHasBranchProtectedScope(); 10707 return OMPDistributeParallelForDirective::Create( 10708 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10709 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10710 } 10711 10712 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 10713 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10714 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10715 if (!AStmt) 10716 return StmtError(); 10717 10718 auto *CS = cast<CapturedStmt>(AStmt); 10719 // 1.2.2 OpenMP Language Terminology 10720 // Structured block - An executable statement with a single entry at the 10721 // top and a single exit at the bottom. 10722 // The point of exit cannot be a branch out of the structured block. 10723 // longjmp() and throw() must not violate the entry/exit criteria. 10724 CS->getCapturedDecl()->setNothrow(); 10725 for (int ThisCaptureLevel = 10726 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 10727 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10728 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10729 // 1.2.2 OpenMP Language Terminology 10730 // Structured block - An executable statement with a single entry at the 10731 // top and a single exit at the bottom. 10732 // The point of exit cannot be a branch out of the structured block. 10733 // longjmp() and throw() must not violate the entry/exit criteria. 10734 CS->getCapturedDecl()->setNothrow(); 10735 } 10736 10737 OMPLoopDirective::HelperExprs B; 10738 // In presence of clause 'collapse' with number of loops, it will 10739 // define the nested loops number. 10740 unsigned NestedLoopCount = checkOpenMPLoop( 10741 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 10742 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 10743 VarsWithImplicitDSA, B); 10744 if (NestedLoopCount == 0) 10745 return StmtError(); 10746 10747 assert((CurContext->isDependentContext() || B.builtAll()) && 10748 "omp for loop exprs were not built"); 10749 10750 if (!CurContext->isDependentContext()) { 10751 // Finalize the clauses that need pre-built expressions for CodeGen. 10752 for (OMPClause *C : Clauses) { 10753 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10754 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10755 B.NumIterations, *this, CurScope, 10756 DSAStack)) 10757 return StmtError(); 10758 } 10759 } 10760 10761 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10762 return StmtError(); 10763 10764 setFunctionHasBranchProtectedScope(); 10765 return OMPDistributeParallelForSimdDirective::Create( 10766 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10767 } 10768 10769 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 10770 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10771 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10772 if (!AStmt) 10773 return StmtError(); 10774 10775 auto *CS = cast<CapturedStmt>(AStmt); 10776 // 1.2.2 OpenMP Language Terminology 10777 // Structured block - An executable statement with a single entry at the 10778 // top and a single exit at the bottom. 10779 // The point of exit cannot be a branch out of the structured block. 10780 // longjmp() and throw() must not violate the entry/exit criteria. 10781 CS->getCapturedDecl()->setNothrow(); 10782 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 10783 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10784 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10785 // 1.2.2 OpenMP Language Terminology 10786 // Structured block - An executable statement with a single entry at the 10787 // top and a single exit at the bottom. 10788 // The point of exit cannot be a branch out of the structured block. 10789 // longjmp() and throw() must not violate the entry/exit criteria. 10790 CS->getCapturedDecl()->setNothrow(); 10791 } 10792 10793 OMPLoopDirective::HelperExprs B; 10794 // In presence of clause 'collapse' with number of loops, it will 10795 // define the nested loops number. 10796 unsigned NestedLoopCount = 10797 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 10798 nullptr /*ordered not a clause on distribute*/, CS, *this, 10799 *DSAStack, VarsWithImplicitDSA, B); 10800 if (NestedLoopCount == 0) 10801 return StmtError(); 10802 10803 assert((CurContext->isDependentContext() || B.builtAll()) && 10804 "omp for loop exprs were not built"); 10805 10806 if (!CurContext->isDependentContext()) { 10807 // Finalize the clauses that need pre-built expressions for CodeGen. 10808 for (OMPClause *C : Clauses) { 10809 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10810 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10811 B.NumIterations, *this, CurScope, 10812 DSAStack)) 10813 return StmtError(); 10814 } 10815 } 10816 10817 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10818 return StmtError(); 10819 10820 setFunctionHasBranchProtectedScope(); 10821 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 10822 NestedLoopCount, Clauses, AStmt, B); 10823 } 10824 10825 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 10826 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10827 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10828 if (!AStmt) 10829 return StmtError(); 10830 10831 auto *CS = cast<CapturedStmt>(AStmt); 10832 // 1.2.2 OpenMP Language Terminology 10833 // Structured block - An executable statement with a single entry at the 10834 // top and a single exit at the bottom. 10835 // The point of exit cannot be a branch out of the structured block. 10836 // longjmp() and throw() must not violate the entry/exit criteria. 10837 CS->getCapturedDecl()->setNothrow(); 10838 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 10839 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10840 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10841 // 1.2.2 OpenMP Language Terminology 10842 // Structured block - An executable statement with a single entry at the 10843 // top and a single exit at the bottom. 10844 // The point of exit cannot be a branch out of the structured block. 10845 // longjmp() and throw() must not violate the entry/exit criteria. 10846 CS->getCapturedDecl()->setNothrow(); 10847 } 10848 10849 OMPLoopDirective::HelperExprs B; 10850 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10851 // define the nested loops number. 10852 unsigned NestedLoopCount = checkOpenMPLoop( 10853 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 10854 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10855 VarsWithImplicitDSA, B); 10856 if (NestedLoopCount == 0) 10857 return StmtError(); 10858 10859 assert((CurContext->isDependentContext() || B.builtAll()) && 10860 "omp target parallel for simd loop exprs were not built"); 10861 10862 if (!CurContext->isDependentContext()) { 10863 // Finalize the clauses that need pre-built expressions for CodeGen. 10864 for (OMPClause *C : Clauses) { 10865 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10866 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10867 B.NumIterations, *this, CurScope, 10868 DSAStack)) 10869 return StmtError(); 10870 } 10871 } 10872 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10873 return StmtError(); 10874 10875 setFunctionHasBranchProtectedScope(); 10876 return OMPTargetParallelForSimdDirective::Create( 10877 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10878 } 10879 10880 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 10881 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10882 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10883 if (!AStmt) 10884 return StmtError(); 10885 10886 auto *CS = cast<CapturedStmt>(AStmt); 10887 // 1.2.2 OpenMP Language Terminology 10888 // Structured block - An executable statement with a single entry at the 10889 // top and a single exit at the bottom. 10890 // The point of exit cannot be a branch out of the structured block. 10891 // longjmp() and throw() must not violate the entry/exit criteria. 10892 CS->getCapturedDecl()->setNothrow(); 10893 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 10894 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10895 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10896 // 1.2.2 OpenMP Language Terminology 10897 // Structured block - An executable statement with a single entry at the 10898 // top and a single exit at the bottom. 10899 // The point of exit cannot be a branch out of the structured block. 10900 // longjmp() and throw() must not violate the entry/exit criteria. 10901 CS->getCapturedDecl()->setNothrow(); 10902 } 10903 10904 OMPLoopDirective::HelperExprs B; 10905 // In presence of clause 'collapse' with number of loops, it will define the 10906 // nested loops number. 10907 unsigned NestedLoopCount = 10908 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 10909 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 10910 VarsWithImplicitDSA, B); 10911 if (NestedLoopCount == 0) 10912 return StmtError(); 10913 10914 assert((CurContext->isDependentContext() || B.builtAll()) && 10915 "omp target simd loop exprs were not built"); 10916 10917 if (!CurContext->isDependentContext()) { 10918 // Finalize the clauses that need pre-built expressions for CodeGen. 10919 for (OMPClause *C : Clauses) { 10920 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10921 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10922 B.NumIterations, *this, CurScope, 10923 DSAStack)) 10924 return StmtError(); 10925 } 10926 } 10927 10928 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10929 return StmtError(); 10930 10931 setFunctionHasBranchProtectedScope(); 10932 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 10933 NestedLoopCount, Clauses, AStmt, B); 10934 } 10935 10936 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 10937 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10938 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10939 if (!AStmt) 10940 return StmtError(); 10941 10942 auto *CS = cast<CapturedStmt>(AStmt); 10943 // 1.2.2 OpenMP Language Terminology 10944 // Structured block - An executable statement with a single entry at the 10945 // top and a single exit at the bottom. 10946 // The point of exit cannot be a branch out of the structured block. 10947 // longjmp() and throw() must not violate the entry/exit criteria. 10948 CS->getCapturedDecl()->setNothrow(); 10949 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 10950 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10951 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10952 // 1.2.2 OpenMP Language Terminology 10953 // Structured block - An executable statement with a single entry at the 10954 // top and a single exit at the bottom. 10955 // The point of exit cannot be a branch out of the structured block. 10956 // longjmp() and throw() must not violate the entry/exit criteria. 10957 CS->getCapturedDecl()->setNothrow(); 10958 } 10959 10960 OMPLoopDirective::HelperExprs B; 10961 // In presence of clause 'collapse' with number of loops, it will 10962 // define the nested loops number. 10963 unsigned NestedLoopCount = 10964 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 10965 nullptr /*ordered not a clause on distribute*/, CS, *this, 10966 *DSAStack, VarsWithImplicitDSA, B); 10967 if (NestedLoopCount == 0) 10968 return StmtError(); 10969 10970 assert((CurContext->isDependentContext() || B.builtAll()) && 10971 "omp teams distribute loop exprs were not built"); 10972 10973 setFunctionHasBranchProtectedScope(); 10974 10975 DSAStack->setParentTeamsRegionLoc(StartLoc); 10976 10977 return OMPTeamsDistributeDirective::Create( 10978 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10979 } 10980 10981 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 10982 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10983 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10984 if (!AStmt) 10985 return StmtError(); 10986 10987 auto *CS = cast<CapturedStmt>(AStmt); 10988 // 1.2.2 OpenMP Language Terminology 10989 // Structured block - An executable statement with a single entry at the 10990 // top and a single exit at the bottom. 10991 // The point of exit cannot be a branch out of the structured block. 10992 // longjmp() and throw() must not violate the entry/exit criteria. 10993 CS->getCapturedDecl()->setNothrow(); 10994 for (int ThisCaptureLevel = 10995 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 10996 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10997 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10998 // 1.2.2 OpenMP Language Terminology 10999 // Structured block - An executable statement with a single entry at the 11000 // top and a single exit at the bottom. 11001 // The point of exit cannot be a branch out of the structured block. 11002 // longjmp() and throw() must not violate the entry/exit criteria. 11003 CS->getCapturedDecl()->setNothrow(); 11004 } 11005 11006 OMPLoopDirective::HelperExprs B; 11007 // In presence of clause 'collapse' with number of loops, it will 11008 // define the nested loops number. 11009 unsigned NestedLoopCount = checkOpenMPLoop( 11010 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11011 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11012 VarsWithImplicitDSA, B); 11013 11014 if (NestedLoopCount == 0) 11015 return StmtError(); 11016 11017 assert((CurContext->isDependentContext() || B.builtAll()) && 11018 "omp teams distribute simd loop exprs were not built"); 11019 11020 if (!CurContext->isDependentContext()) { 11021 // Finalize the clauses that need pre-built expressions for CodeGen. 11022 for (OMPClause *C : Clauses) { 11023 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11024 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11025 B.NumIterations, *this, CurScope, 11026 DSAStack)) 11027 return StmtError(); 11028 } 11029 } 11030 11031 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11032 return StmtError(); 11033 11034 setFunctionHasBranchProtectedScope(); 11035 11036 DSAStack->setParentTeamsRegionLoc(StartLoc); 11037 11038 return OMPTeamsDistributeSimdDirective::Create( 11039 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11040 } 11041 11042 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 11043 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11044 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11045 if (!AStmt) 11046 return StmtError(); 11047 11048 auto *CS = cast<CapturedStmt>(AStmt); 11049 // 1.2.2 OpenMP Language Terminology 11050 // Structured block - An executable statement with a single entry at the 11051 // top and a single exit at the bottom. 11052 // The point of exit cannot be a branch out of the structured block. 11053 // longjmp() and throw() must not violate the entry/exit criteria. 11054 CS->getCapturedDecl()->setNothrow(); 11055 11056 for (int ThisCaptureLevel = 11057 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 11058 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11059 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11060 // 1.2.2 OpenMP Language Terminology 11061 // Structured block - An executable statement with a single entry at the 11062 // top and a single exit at the bottom. 11063 // The point of exit cannot be a branch out of the structured block. 11064 // longjmp() and throw() must not violate the entry/exit criteria. 11065 CS->getCapturedDecl()->setNothrow(); 11066 } 11067 11068 OMPLoopDirective::HelperExprs B; 11069 // In presence of clause 'collapse' with number of loops, it will 11070 // define the nested loops number. 11071 unsigned NestedLoopCount = checkOpenMPLoop( 11072 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 11073 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11074 VarsWithImplicitDSA, B); 11075 11076 if (NestedLoopCount == 0) 11077 return StmtError(); 11078 11079 assert((CurContext->isDependentContext() || B.builtAll()) && 11080 "omp for loop exprs were not built"); 11081 11082 if (!CurContext->isDependentContext()) { 11083 // Finalize the clauses that need pre-built expressions for CodeGen. 11084 for (OMPClause *C : Clauses) { 11085 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11086 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11087 B.NumIterations, *this, CurScope, 11088 DSAStack)) 11089 return StmtError(); 11090 } 11091 } 11092 11093 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11094 return StmtError(); 11095 11096 setFunctionHasBranchProtectedScope(); 11097 11098 DSAStack->setParentTeamsRegionLoc(StartLoc); 11099 11100 return OMPTeamsDistributeParallelForSimdDirective::Create( 11101 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11102 } 11103 11104 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 11105 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11106 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11107 if (!AStmt) 11108 return StmtError(); 11109 11110 auto *CS = cast<CapturedStmt>(AStmt); 11111 // 1.2.2 OpenMP Language Terminology 11112 // Structured block - An executable statement with a single entry at the 11113 // top and a single exit at the bottom. 11114 // The point of exit cannot be a branch out of the structured block. 11115 // longjmp() and throw() must not violate the entry/exit criteria. 11116 CS->getCapturedDecl()->setNothrow(); 11117 11118 for (int ThisCaptureLevel = 11119 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 11120 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11121 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11122 // 1.2.2 OpenMP Language Terminology 11123 // Structured block - An executable statement with a single entry at the 11124 // top and a single exit at the bottom. 11125 // The point of exit cannot be a branch out of the structured block. 11126 // longjmp() and throw() must not violate the entry/exit criteria. 11127 CS->getCapturedDecl()->setNothrow(); 11128 } 11129 11130 OMPLoopDirective::HelperExprs B; 11131 // In presence of clause 'collapse' with number of loops, it will 11132 // define the nested loops number. 11133 unsigned NestedLoopCount = checkOpenMPLoop( 11134 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11135 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11136 VarsWithImplicitDSA, B); 11137 11138 if (NestedLoopCount == 0) 11139 return StmtError(); 11140 11141 assert((CurContext->isDependentContext() || B.builtAll()) && 11142 "omp for loop exprs were not built"); 11143 11144 setFunctionHasBranchProtectedScope(); 11145 11146 DSAStack->setParentTeamsRegionLoc(StartLoc); 11147 11148 return OMPTeamsDistributeParallelForDirective::Create( 11149 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11150 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11151 } 11152 11153 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 11154 Stmt *AStmt, 11155 SourceLocation StartLoc, 11156 SourceLocation EndLoc) { 11157 if (!AStmt) 11158 return StmtError(); 11159 11160 auto *CS = cast<CapturedStmt>(AStmt); 11161 // 1.2.2 OpenMP Language Terminology 11162 // Structured block - An executable statement with a single entry at the 11163 // top and a single exit at the bottom. 11164 // The point of exit cannot be a branch out of the structured block. 11165 // longjmp() and throw() must not violate the entry/exit criteria. 11166 CS->getCapturedDecl()->setNothrow(); 11167 11168 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 11169 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11170 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11171 // 1.2.2 OpenMP Language Terminology 11172 // Structured block - An executable statement with a single entry at the 11173 // top and a single exit at the bottom. 11174 // The point of exit cannot be a branch out of the structured block. 11175 // longjmp() and throw() must not violate the entry/exit criteria. 11176 CS->getCapturedDecl()->setNothrow(); 11177 } 11178 setFunctionHasBranchProtectedScope(); 11179 11180 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 11181 AStmt); 11182 } 11183 11184 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 11185 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11186 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11187 if (!AStmt) 11188 return StmtError(); 11189 11190 auto *CS = cast<CapturedStmt>(AStmt); 11191 // 1.2.2 OpenMP Language Terminology 11192 // Structured block - An executable statement with a single entry at the 11193 // top and a single exit at the bottom. 11194 // The point of exit cannot be a branch out of the structured block. 11195 // longjmp() and throw() must not violate the entry/exit criteria. 11196 CS->getCapturedDecl()->setNothrow(); 11197 for (int ThisCaptureLevel = 11198 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 11199 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11200 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11201 // 1.2.2 OpenMP Language Terminology 11202 // Structured block - An executable statement with a single entry at the 11203 // top and a single exit at the bottom. 11204 // The point of exit cannot be a branch out of the structured block. 11205 // longjmp() and throw() must not violate the entry/exit criteria. 11206 CS->getCapturedDecl()->setNothrow(); 11207 } 11208 11209 OMPLoopDirective::HelperExprs B; 11210 // In presence of clause 'collapse' with number of loops, it will 11211 // define the nested loops number. 11212 unsigned NestedLoopCount = checkOpenMPLoop( 11213 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 11214 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11215 VarsWithImplicitDSA, B); 11216 if (NestedLoopCount == 0) 11217 return StmtError(); 11218 11219 assert((CurContext->isDependentContext() || B.builtAll()) && 11220 "omp target teams distribute loop exprs were not built"); 11221 11222 setFunctionHasBranchProtectedScope(); 11223 return OMPTargetTeamsDistributeDirective::Create( 11224 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11225 } 11226 11227 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 11228 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11229 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11230 if (!AStmt) 11231 return StmtError(); 11232 11233 auto *CS = cast<CapturedStmt>(AStmt); 11234 // 1.2.2 OpenMP Language Terminology 11235 // Structured block - An executable statement with a single entry at the 11236 // top and a single exit at the bottom. 11237 // The point of exit cannot be a branch out of the structured block. 11238 // longjmp() and throw() must not violate the entry/exit criteria. 11239 CS->getCapturedDecl()->setNothrow(); 11240 for (int ThisCaptureLevel = 11241 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 11242 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11243 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11244 // 1.2.2 OpenMP Language Terminology 11245 // Structured block - An executable statement with a single entry at the 11246 // top and a single exit at the bottom. 11247 // The point of exit cannot be a branch out of the structured block. 11248 // longjmp() and throw() must not violate the entry/exit criteria. 11249 CS->getCapturedDecl()->setNothrow(); 11250 } 11251 11252 OMPLoopDirective::HelperExprs B; 11253 // In presence of clause 'collapse' with number of loops, it will 11254 // define the nested loops number. 11255 unsigned NestedLoopCount = checkOpenMPLoop( 11256 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 11257 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11258 VarsWithImplicitDSA, B); 11259 if (NestedLoopCount == 0) 11260 return StmtError(); 11261 11262 assert((CurContext->isDependentContext() || B.builtAll()) && 11263 "omp target teams distribute parallel for loop exprs were not built"); 11264 11265 if (!CurContext->isDependentContext()) { 11266 // Finalize the clauses that need pre-built expressions for CodeGen. 11267 for (OMPClause *C : Clauses) { 11268 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11269 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11270 B.NumIterations, *this, CurScope, 11271 DSAStack)) 11272 return StmtError(); 11273 } 11274 } 11275 11276 setFunctionHasBranchProtectedScope(); 11277 return OMPTargetTeamsDistributeParallelForDirective::Create( 11278 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 11279 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 11280 } 11281 11282 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 11283 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11284 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11285 if (!AStmt) 11286 return StmtError(); 11287 11288 auto *CS = cast<CapturedStmt>(AStmt); 11289 // 1.2.2 OpenMP Language Terminology 11290 // Structured block - An executable statement with a single entry at the 11291 // top and a single exit at the bottom. 11292 // The point of exit cannot be a branch out of the structured block. 11293 // longjmp() and throw() must not violate the entry/exit criteria. 11294 CS->getCapturedDecl()->setNothrow(); 11295 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 11296 OMPD_target_teams_distribute_parallel_for_simd); 11297 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11298 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11299 // 1.2.2 OpenMP Language Terminology 11300 // Structured block - An executable statement with a single entry at the 11301 // top and a single exit at the bottom. 11302 // The point of exit cannot be a branch out of the structured block. 11303 // longjmp() and throw() must not violate the entry/exit criteria. 11304 CS->getCapturedDecl()->setNothrow(); 11305 } 11306 11307 OMPLoopDirective::HelperExprs B; 11308 // In presence of clause 'collapse' with number of loops, it will 11309 // define the nested loops number. 11310 unsigned NestedLoopCount = 11311 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 11312 getCollapseNumberExpr(Clauses), 11313 nullptr /*ordered not a clause on distribute*/, CS, *this, 11314 *DSAStack, VarsWithImplicitDSA, B); 11315 if (NestedLoopCount == 0) 11316 return StmtError(); 11317 11318 assert((CurContext->isDependentContext() || B.builtAll()) && 11319 "omp target teams distribute parallel for simd loop exprs were not " 11320 "built"); 11321 11322 if (!CurContext->isDependentContext()) { 11323 // Finalize the clauses that need pre-built expressions for CodeGen. 11324 for (OMPClause *C : Clauses) { 11325 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11326 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11327 B.NumIterations, *this, CurScope, 11328 DSAStack)) 11329 return StmtError(); 11330 } 11331 } 11332 11333 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11334 return StmtError(); 11335 11336 setFunctionHasBranchProtectedScope(); 11337 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 11338 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11339 } 11340 11341 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 11342 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 11343 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 11344 if (!AStmt) 11345 return StmtError(); 11346 11347 auto *CS = cast<CapturedStmt>(AStmt); 11348 // 1.2.2 OpenMP Language Terminology 11349 // Structured block - An executable statement with a single entry at the 11350 // top and a single exit at the bottom. 11351 // The point of exit cannot be a branch out of the structured block. 11352 // longjmp() and throw() must not violate the entry/exit criteria. 11353 CS->getCapturedDecl()->setNothrow(); 11354 for (int ThisCaptureLevel = 11355 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 11356 ThisCaptureLevel > 1; --ThisCaptureLevel) { 11357 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 11358 // 1.2.2 OpenMP Language Terminology 11359 // Structured block - An executable statement with a single entry at the 11360 // top and a single exit at the bottom. 11361 // The point of exit cannot be a branch out of the structured block. 11362 // longjmp() and throw() must not violate the entry/exit criteria. 11363 CS->getCapturedDecl()->setNothrow(); 11364 } 11365 11366 OMPLoopDirective::HelperExprs B; 11367 // In presence of clause 'collapse' with number of loops, it will 11368 // define the nested loops number. 11369 unsigned NestedLoopCount = checkOpenMPLoop( 11370 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 11371 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 11372 VarsWithImplicitDSA, B); 11373 if (NestedLoopCount == 0) 11374 return StmtError(); 11375 11376 assert((CurContext->isDependentContext() || B.builtAll()) && 11377 "omp target teams distribute simd loop exprs were not built"); 11378 11379 if (!CurContext->isDependentContext()) { 11380 // Finalize the clauses that need pre-built expressions for CodeGen. 11381 for (OMPClause *C : Clauses) { 11382 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 11383 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 11384 B.NumIterations, *this, CurScope, 11385 DSAStack)) 11386 return StmtError(); 11387 } 11388 } 11389 11390 if (checkSimdlenSafelenSpecified(*this, Clauses)) 11391 return StmtError(); 11392 11393 setFunctionHasBranchProtectedScope(); 11394 return OMPTargetTeamsDistributeSimdDirective::Create( 11395 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 11396 } 11397 11398 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 11399 SourceLocation StartLoc, 11400 SourceLocation LParenLoc, 11401 SourceLocation EndLoc) { 11402 OMPClause *Res = nullptr; 11403 switch (Kind) { 11404 case OMPC_final: 11405 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 11406 break; 11407 case OMPC_num_threads: 11408 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 11409 break; 11410 case OMPC_safelen: 11411 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 11412 break; 11413 case OMPC_simdlen: 11414 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 11415 break; 11416 case OMPC_allocator: 11417 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 11418 break; 11419 case OMPC_collapse: 11420 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 11421 break; 11422 case OMPC_ordered: 11423 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 11424 break; 11425 case OMPC_num_teams: 11426 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 11427 break; 11428 case OMPC_thread_limit: 11429 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 11430 break; 11431 case OMPC_priority: 11432 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 11433 break; 11434 case OMPC_grainsize: 11435 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 11436 break; 11437 case OMPC_num_tasks: 11438 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 11439 break; 11440 case OMPC_hint: 11441 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 11442 break; 11443 case OMPC_depobj: 11444 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 11445 break; 11446 case OMPC_detach: 11447 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 11448 break; 11449 case OMPC_device: 11450 case OMPC_if: 11451 case OMPC_default: 11452 case OMPC_proc_bind: 11453 case OMPC_schedule: 11454 case OMPC_private: 11455 case OMPC_firstprivate: 11456 case OMPC_lastprivate: 11457 case OMPC_shared: 11458 case OMPC_reduction: 11459 case OMPC_task_reduction: 11460 case OMPC_in_reduction: 11461 case OMPC_linear: 11462 case OMPC_aligned: 11463 case OMPC_copyin: 11464 case OMPC_copyprivate: 11465 case OMPC_nowait: 11466 case OMPC_untied: 11467 case OMPC_mergeable: 11468 case OMPC_threadprivate: 11469 case OMPC_allocate: 11470 case OMPC_flush: 11471 case OMPC_read: 11472 case OMPC_write: 11473 case OMPC_update: 11474 case OMPC_capture: 11475 case OMPC_seq_cst: 11476 case OMPC_acq_rel: 11477 case OMPC_acquire: 11478 case OMPC_release: 11479 case OMPC_relaxed: 11480 case OMPC_depend: 11481 case OMPC_threads: 11482 case OMPC_simd: 11483 case OMPC_map: 11484 case OMPC_nogroup: 11485 case OMPC_dist_schedule: 11486 case OMPC_defaultmap: 11487 case OMPC_unknown: 11488 case OMPC_uniform: 11489 case OMPC_to: 11490 case OMPC_from: 11491 case OMPC_use_device_ptr: 11492 case OMPC_is_device_ptr: 11493 case OMPC_unified_address: 11494 case OMPC_unified_shared_memory: 11495 case OMPC_reverse_offload: 11496 case OMPC_dynamic_allocators: 11497 case OMPC_atomic_default_mem_order: 11498 case OMPC_device_type: 11499 case OMPC_match: 11500 case OMPC_nontemporal: 11501 case OMPC_order: 11502 case OMPC_destroy: 11503 case OMPC_inclusive: 11504 case OMPC_exclusive: 11505 case OMPC_uses_allocators: 11506 llvm_unreachable("Clause is not allowed."); 11507 } 11508 return Res; 11509 } 11510 11511 // An OpenMP directive such as 'target parallel' has two captured regions: 11512 // for the 'target' and 'parallel' respectively. This function returns 11513 // the region in which to capture expressions associated with a clause. 11514 // A return value of OMPD_unknown signifies that the expression should not 11515 // be captured. 11516 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 11517 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 11518 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 11519 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11520 switch (CKind) { 11521 case OMPC_if: 11522 switch (DKind) { 11523 case OMPD_target_parallel_for_simd: 11524 if (OpenMPVersion >= 50 && 11525 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11526 CaptureRegion = OMPD_parallel; 11527 break; 11528 } 11529 LLVM_FALLTHROUGH; 11530 case OMPD_target_parallel: 11531 case OMPD_target_parallel_for: 11532 // If this clause applies to the nested 'parallel' region, capture within 11533 // the 'target' region, otherwise do not capture. 11534 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11535 CaptureRegion = OMPD_target; 11536 break; 11537 case OMPD_target_teams_distribute_parallel_for_simd: 11538 if (OpenMPVersion >= 50 && 11539 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11540 CaptureRegion = OMPD_parallel; 11541 break; 11542 } 11543 LLVM_FALLTHROUGH; 11544 case OMPD_target_teams_distribute_parallel_for: 11545 // If this clause applies to the nested 'parallel' region, capture within 11546 // the 'teams' region, otherwise do not capture. 11547 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 11548 CaptureRegion = OMPD_teams; 11549 break; 11550 case OMPD_teams_distribute_parallel_for_simd: 11551 if (OpenMPVersion >= 50 && 11552 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 11553 CaptureRegion = OMPD_parallel; 11554 break; 11555 } 11556 LLVM_FALLTHROUGH; 11557 case OMPD_teams_distribute_parallel_for: 11558 CaptureRegion = OMPD_teams; 11559 break; 11560 case OMPD_target_update: 11561 case OMPD_target_enter_data: 11562 case OMPD_target_exit_data: 11563 CaptureRegion = OMPD_task; 11564 break; 11565 case OMPD_parallel_master_taskloop: 11566 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 11567 CaptureRegion = OMPD_parallel; 11568 break; 11569 case OMPD_parallel_master_taskloop_simd: 11570 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 11571 NameModifier == OMPD_taskloop) { 11572 CaptureRegion = OMPD_parallel; 11573 break; 11574 } 11575 if (OpenMPVersion <= 45) 11576 break; 11577 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11578 CaptureRegion = OMPD_taskloop; 11579 break; 11580 case OMPD_parallel_for_simd: 11581 if (OpenMPVersion <= 45) 11582 break; 11583 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11584 CaptureRegion = OMPD_parallel; 11585 break; 11586 case OMPD_taskloop_simd: 11587 case OMPD_master_taskloop_simd: 11588 if (OpenMPVersion <= 45) 11589 break; 11590 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11591 CaptureRegion = OMPD_taskloop; 11592 break; 11593 case OMPD_distribute_parallel_for_simd: 11594 if (OpenMPVersion <= 45) 11595 break; 11596 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 11597 CaptureRegion = OMPD_parallel; 11598 break; 11599 case OMPD_target_simd: 11600 if (OpenMPVersion >= 50 && 11601 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11602 CaptureRegion = OMPD_target; 11603 break; 11604 case OMPD_teams_distribute_simd: 11605 case OMPD_target_teams_distribute_simd: 11606 if (OpenMPVersion >= 50 && 11607 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 11608 CaptureRegion = OMPD_teams; 11609 break; 11610 case OMPD_cancel: 11611 case OMPD_parallel: 11612 case OMPD_parallel_master: 11613 case OMPD_parallel_sections: 11614 case OMPD_parallel_for: 11615 case OMPD_target: 11616 case OMPD_target_teams: 11617 case OMPD_target_teams_distribute: 11618 case OMPD_distribute_parallel_for: 11619 case OMPD_task: 11620 case OMPD_taskloop: 11621 case OMPD_master_taskloop: 11622 case OMPD_target_data: 11623 case OMPD_simd: 11624 case OMPD_for_simd: 11625 case OMPD_distribute_simd: 11626 // Do not capture if-clause expressions. 11627 break; 11628 case OMPD_threadprivate: 11629 case OMPD_allocate: 11630 case OMPD_taskyield: 11631 case OMPD_barrier: 11632 case OMPD_taskwait: 11633 case OMPD_cancellation_point: 11634 case OMPD_flush: 11635 case OMPD_depobj: 11636 case OMPD_scan: 11637 case OMPD_declare_reduction: 11638 case OMPD_declare_mapper: 11639 case OMPD_declare_simd: 11640 case OMPD_declare_variant: 11641 case OMPD_begin_declare_variant: 11642 case OMPD_end_declare_variant: 11643 case OMPD_declare_target: 11644 case OMPD_end_declare_target: 11645 case OMPD_teams: 11646 case OMPD_for: 11647 case OMPD_sections: 11648 case OMPD_section: 11649 case OMPD_single: 11650 case OMPD_master: 11651 case OMPD_critical: 11652 case OMPD_taskgroup: 11653 case OMPD_distribute: 11654 case OMPD_ordered: 11655 case OMPD_atomic: 11656 case OMPD_teams_distribute: 11657 case OMPD_requires: 11658 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 11659 case OMPD_unknown: 11660 llvm_unreachable("Unknown OpenMP directive"); 11661 } 11662 break; 11663 case OMPC_num_threads: 11664 switch (DKind) { 11665 case OMPD_target_parallel: 11666 case OMPD_target_parallel_for: 11667 case OMPD_target_parallel_for_simd: 11668 CaptureRegion = OMPD_target; 11669 break; 11670 case OMPD_teams_distribute_parallel_for: 11671 case OMPD_teams_distribute_parallel_for_simd: 11672 case OMPD_target_teams_distribute_parallel_for: 11673 case OMPD_target_teams_distribute_parallel_for_simd: 11674 CaptureRegion = OMPD_teams; 11675 break; 11676 case OMPD_parallel: 11677 case OMPD_parallel_master: 11678 case OMPD_parallel_sections: 11679 case OMPD_parallel_for: 11680 case OMPD_parallel_for_simd: 11681 case OMPD_distribute_parallel_for: 11682 case OMPD_distribute_parallel_for_simd: 11683 case OMPD_parallel_master_taskloop: 11684 case OMPD_parallel_master_taskloop_simd: 11685 // Do not capture num_threads-clause expressions. 11686 break; 11687 case OMPD_target_data: 11688 case OMPD_target_enter_data: 11689 case OMPD_target_exit_data: 11690 case OMPD_target_update: 11691 case OMPD_target: 11692 case OMPD_target_simd: 11693 case OMPD_target_teams: 11694 case OMPD_target_teams_distribute: 11695 case OMPD_target_teams_distribute_simd: 11696 case OMPD_cancel: 11697 case OMPD_task: 11698 case OMPD_taskloop: 11699 case OMPD_taskloop_simd: 11700 case OMPD_master_taskloop: 11701 case OMPD_master_taskloop_simd: 11702 case OMPD_threadprivate: 11703 case OMPD_allocate: 11704 case OMPD_taskyield: 11705 case OMPD_barrier: 11706 case OMPD_taskwait: 11707 case OMPD_cancellation_point: 11708 case OMPD_flush: 11709 case OMPD_depobj: 11710 case OMPD_scan: 11711 case OMPD_declare_reduction: 11712 case OMPD_declare_mapper: 11713 case OMPD_declare_simd: 11714 case OMPD_declare_variant: 11715 case OMPD_begin_declare_variant: 11716 case OMPD_end_declare_variant: 11717 case OMPD_declare_target: 11718 case OMPD_end_declare_target: 11719 case OMPD_teams: 11720 case OMPD_simd: 11721 case OMPD_for: 11722 case OMPD_for_simd: 11723 case OMPD_sections: 11724 case OMPD_section: 11725 case OMPD_single: 11726 case OMPD_master: 11727 case OMPD_critical: 11728 case OMPD_taskgroup: 11729 case OMPD_distribute: 11730 case OMPD_ordered: 11731 case OMPD_atomic: 11732 case OMPD_distribute_simd: 11733 case OMPD_teams_distribute: 11734 case OMPD_teams_distribute_simd: 11735 case OMPD_requires: 11736 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 11737 case OMPD_unknown: 11738 llvm_unreachable("Unknown OpenMP directive"); 11739 } 11740 break; 11741 case OMPC_num_teams: 11742 switch (DKind) { 11743 case OMPD_target_teams: 11744 case OMPD_target_teams_distribute: 11745 case OMPD_target_teams_distribute_simd: 11746 case OMPD_target_teams_distribute_parallel_for: 11747 case OMPD_target_teams_distribute_parallel_for_simd: 11748 CaptureRegion = OMPD_target; 11749 break; 11750 case OMPD_teams_distribute_parallel_for: 11751 case OMPD_teams_distribute_parallel_for_simd: 11752 case OMPD_teams: 11753 case OMPD_teams_distribute: 11754 case OMPD_teams_distribute_simd: 11755 // Do not capture num_teams-clause expressions. 11756 break; 11757 case OMPD_distribute_parallel_for: 11758 case OMPD_distribute_parallel_for_simd: 11759 case OMPD_task: 11760 case OMPD_taskloop: 11761 case OMPD_taskloop_simd: 11762 case OMPD_master_taskloop: 11763 case OMPD_master_taskloop_simd: 11764 case OMPD_parallel_master_taskloop: 11765 case OMPD_parallel_master_taskloop_simd: 11766 case OMPD_target_data: 11767 case OMPD_target_enter_data: 11768 case OMPD_target_exit_data: 11769 case OMPD_target_update: 11770 case OMPD_cancel: 11771 case OMPD_parallel: 11772 case OMPD_parallel_master: 11773 case OMPD_parallel_sections: 11774 case OMPD_parallel_for: 11775 case OMPD_parallel_for_simd: 11776 case OMPD_target: 11777 case OMPD_target_simd: 11778 case OMPD_target_parallel: 11779 case OMPD_target_parallel_for: 11780 case OMPD_target_parallel_for_simd: 11781 case OMPD_threadprivate: 11782 case OMPD_allocate: 11783 case OMPD_taskyield: 11784 case OMPD_barrier: 11785 case OMPD_taskwait: 11786 case OMPD_cancellation_point: 11787 case OMPD_flush: 11788 case OMPD_depobj: 11789 case OMPD_scan: 11790 case OMPD_declare_reduction: 11791 case OMPD_declare_mapper: 11792 case OMPD_declare_simd: 11793 case OMPD_declare_variant: 11794 case OMPD_begin_declare_variant: 11795 case OMPD_end_declare_variant: 11796 case OMPD_declare_target: 11797 case OMPD_end_declare_target: 11798 case OMPD_simd: 11799 case OMPD_for: 11800 case OMPD_for_simd: 11801 case OMPD_sections: 11802 case OMPD_section: 11803 case OMPD_single: 11804 case OMPD_master: 11805 case OMPD_critical: 11806 case OMPD_taskgroup: 11807 case OMPD_distribute: 11808 case OMPD_ordered: 11809 case OMPD_atomic: 11810 case OMPD_distribute_simd: 11811 case OMPD_requires: 11812 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 11813 case OMPD_unknown: 11814 llvm_unreachable("Unknown OpenMP directive"); 11815 } 11816 break; 11817 case OMPC_thread_limit: 11818 switch (DKind) { 11819 case OMPD_target_teams: 11820 case OMPD_target_teams_distribute: 11821 case OMPD_target_teams_distribute_simd: 11822 case OMPD_target_teams_distribute_parallel_for: 11823 case OMPD_target_teams_distribute_parallel_for_simd: 11824 CaptureRegion = OMPD_target; 11825 break; 11826 case OMPD_teams_distribute_parallel_for: 11827 case OMPD_teams_distribute_parallel_for_simd: 11828 case OMPD_teams: 11829 case OMPD_teams_distribute: 11830 case OMPD_teams_distribute_simd: 11831 // Do not capture thread_limit-clause expressions. 11832 break; 11833 case OMPD_distribute_parallel_for: 11834 case OMPD_distribute_parallel_for_simd: 11835 case OMPD_task: 11836 case OMPD_taskloop: 11837 case OMPD_taskloop_simd: 11838 case OMPD_master_taskloop: 11839 case OMPD_master_taskloop_simd: 11840 case OMPD_parallel_master_taskloop: 11841 case OMPD_parallel_master_taskloop_simd: 11842 case OMPD_target_data: 11843 case OMPD_target_enter_data: 11844 case OMPD_target_exit_data: 11845 case OMPD_target_update: 11846 case OMPD_cancel: 11847 case OMPD_parallel: 11848 case OMPD_parallel_master: 11849 case OMPD_parallel_sections: 11850 case OMPD_parallel_for: 11851 case OMPD_parallel_for_simd: 11852 case OMPD_target: 11853 case OMPD_target_simd: 11854 case OMPD_target_parallel: 11855 case OMPD_target_parallel_for: 11856 case OMPD_target_parallel_for_simd: 11857 case OMPD_threadprivate: 11858 case OMPD_allocate: 11859 case OMPD_taskyield: 11860 case OMPD_barrier: 11861 case OMPD_taskwait: 11862 case OMPD_cancellation_point: 11863 case OMPD_flush: 11864 case OMPD_depobj: 11865 case OMPD_scan: 11866 case OMPD_declare_reduction: 11867 case OMPD_declare_mapper: 11868 case OMPD_declare_simd: 11869 case OMPD_declare_variant: 11870 case OMPD_begin_declare_variant: 11871 case OMPD_end_declare_variant: 11872 case OMPD_declare_target: 11873 case OMPD_end_declare_target: 11874 case OMPD_simd: 11875 case OMPD_for: 11876 case OMPD_for_simd: 11877 case OMPD_sections: 11878 case OMPD_section: 11879 case OMPD_single: 11880 case OMPD_master: 11881 case OMPD_critical: 11882 case OMPD_taskgroup: 11883 case OMPD_distribute: 11884 case OMPD_ordered: 11885 case OMPD_atomic: 11886 case OMPD_distribute_simd: 11887 case OMPD_requires: 11888 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 11889 case OMPD_unknown: 11890 llvm_unreachable("Unknown OpenMP directive"); 11891 } 11892 break; 11893 case OMPC_schedule: 11894 switch (DKind) { 11895 case OMPD_parallel_for: 11896 case OMPD_parallel_for_simd: 11897 case OMPD_distribute_parallel_for: 11898 case OMPD_distribute_parallel_for_simd: 11899 case OMPD_teams_distribute_parallel_for: 11900 case OMPD_teams_distribute_parallel_for_simd: 11901 case OMPD_target_parallel_for: 11902 case OMPD_target_parallel_for_simd: 11903 case OMPD_target_teams_distribute_parallel_for: 11904 case OMPD_target_teams_distribute_parallel_for_simd: 11905 CaptureRegion = OMPD_parallel; 11906 break; 11907 case OMPD_for: 11908 case OMPD_for_simd: 11909 // Do not capture schedule-clause expressions. 11910 break; 11911 case OMPD_task: 11912 case OMPD_taskloop: 11913 case OMPD_taskloop_simd: 11914 case OMPD_master_taskloop: 11915 case OMPD_master_taskloop_simd: 11916 case OMPD_parallel_master_taskloop: 11917 case OMPD_parallel_master_taskloop_simd: 11918 case OMPD_target_data: 11919 case OMPD_target_enter_data: 11920 case OMPD_target_exit_data: 11921 case OMPD_target_update: 11922 case OMPD_teams: 11923 case OMPD_teams_distribute: 11924 case OMPD_teams_distribute_simd: 11925 case OMPD_target_teams_distribute: 11926 case OMPD_target_teams_distribute_simd: 11927 case OMPD_target: 11928 case OMPD_target_simd: 11929 case OMPD_target_parallel: 11930 case OMPD_cancel: 11931 case OMPD_parallel: 11932 case OMPD_parallel_master: 11933 case OMPD_parallel_sections: 11934 case OMPD_threadprivate: 11935 case OMPD_allocate: 11936 case OMPD_taskyield: 11937 case OMPD_barrier: 11938 case OMPD_taskwait: 11939 case OMPD_cancellation_point: 11940 case OMPD_flush: 11941 case OMPD_depobj: 11942 case OMPD_scan: 11943 case OMPD_declare_reduction: 11944 case OMPD_declare_mapper: 11945 case OMPD_declare_simd: 11946 case OMPD_declare_variant: 11947 case OMPD_begin_declare_variant: 11948 case OMPD_end_declare_variant: 11949 case OMPD_declare_target: 11950 case OMPD_end_declare_target: 11951 case OMPD_simd: 11952 case OMPD_sections: 11953 case OMPD_section: 11954 case OMPD_single: 11955 case OMPD_master: 11956 case OMPD_critical: 11957 case OMPD_taskgroup: 11958 case OMPD_distribute: 11959 case OMPD_ordered: 11960 case OMPD_atomic: 11961 case OMPD_distribute_simd: 11962 case OMPD_target_teams: 11963 case OMPD_requires: 11964 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 11965 case OMPD_unknown: 11966 llvm_unreachable("Unknown OpenMP directive"); 11967 } 11968 break; 11969 case OMPC_dist_schedule: 11970 switch (DKind) { 11971 case OMPD_teams_distribute_parallel_for: 11972 case OMPD_teams_distribute_parallel_for_simd: 11973 case OMPD_teams_distribute: 11974 case OMPD_teams_distribute_simd: 11975 case OMPD_target_teams_distribute_parallel_for: 11976 case OMPD_target_teams_distribute_parallel_for_simd: 11977 case OMPD_target_teams_distribute: 11978 case OMPD_target_teams_distribute_simd: 11979 CaptureRegion = OMPD_teams; 11980 break; 11981 case OMPD_distribute_parallel_for: 11982 case OMPD_distribute_parallel_for_simd: 11983 case OMPD_distribute: 11984 case OMPD_distribute_simd: 11985 // Do not capture thread_limit-clause expressions. 11986 break; 11987 case OMPD_parallel_for: 11988 case OMPD_parallel_for_simd: 11989 case OMPD_target_parallel_for_simd: 11990 case OMPD_target_parallel_for: 11991 case OMPD_task: 11992 case OMPD_taskloop: 11993 case OMPD_taskloop_simd: 11994 case OMPD_master_taskloop: 11995 case OMPD_master_taskloop_simd: 11996 case OMPD_parallel_master_taskloop: 11997 case OMPD_parallel_master_taskloop_simd: 11998 case OMPD_target_data: 11999 case OMPD_target_enter_data: 12000 case OMPD_target_exit_data: 12001 case OMPD_target_update: 12002 case OMPD_teams: 12003 case OMPD_target: 12004 case OMPD_target_simd: 12005 case OMPD_target_parallel: 12006 case OMPD_cancel: 12007 case OMPD_parallel: 12008 case OMPD_parallel_master: 12009 case OMPD_parallel_sections: 12010 case OMPD_threadprivate: 12011 case OMPD_allocate: 12012 case OMPD_taskyield: 12013 case OMPD_barrier: 12014 case OMPD_taskwait: 12015 case OMPD_cancellation_point: 12016 case OMPD_flush: 12017 case OMPD_depobj: 12018 case OMPD_scan: 12019 case OMPD_declare_reduction: 12020 case OMPD_declare_mapper: 12021 case OMPD_declare_simd: 12022 case OMPD_declare_variant: 12023 case OMPD_begin_declare_variant: 12024 case OMPD_end_declare_variant: 12025 case OMPD_declare_target: 12026 case OMPD_end_declare_target: 12027 case OMPD_simd: 12028 case OMPD_for: 12029 case OMPD_for_simd: 12030 case OMPD_sections: 12031 case OMPD_section: 12032 case OMPD_single: 12033 case OMPD_master: 12034 case OMPD_critical: 12035 case OMPD_taskgroup: 12036 case OMPD_ordered: 12037 case OMPD_atomic: 12038 case OMPD_target_teams: 12039 case OMPD_requires: 12040 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 12041 case OMPD_unknown: 12042 llvm_unreachable("Unknown OpenMP directive"); 12043 } 12044 break; 12045 case OMPC_device: 12046 switch (DKind) { 12047 case OMPD_target_update: 12048 case OMPD_target_enter_data: 12049 case OMPD_target_exit_data: 12050 case OMPD_target: 12051 case OMPD_target_simd: 12052 case OMPD_target_teams: 12053 case OMPD_target_parallel: 12054 case OMPD_target_teams_distribute: 12055 case OMPD_target_teams_distribute_simd: 12056 case OMPD_target_parallel_for: 12057 case OMPD_target_parallel_for_simd: 12058 case OMPD_target_teams_distribute_parallel_for: 12059 case OMPD_target_teams_distribute_parallel_for_simd: 12060 CaptureRegion = OMPD_task; 12061 break; 12062 case OMPD_target_data: 12063 // Do not capture device-clause expressions. 12064 break; 12065 case OMPD_teams_distribute_parallel_for: 12066 case OMPD_teams_distribute_parallel_for_simd: 12067 case OMPD_teams: 12068 case OMPD_teams_distribute: 12069 case OMPD_teams_distribute_simd: 12070 case OMPD_distribute_parallel_for: 12071 case OMPD_distribute_parallel_for_simd: 12072 case OMPD_task: 12073 case OMPD_taskloop: 12074 case OMPD_taskloop_simd: 12075 case OMPD_master_taskloop: 12076 case OMPD_master_taskloop_simd: 12077 case OMPD_parallel_master_taskloop: 12078 case OMPD_parallel_master_taskloop_simd: 12079 case OMPD_cancel: 12080 case OMPD_parallel: 12081 case OMPD_parallel_master: 12082 case OMPD_parallel_sections: 12083 case OMPD_parallel_for: 12084 case OMPD_parallel_for_simd: 12085 case OMPD_threadprivate: 12086 case OMPD_allocate: 12087 case OMPD_taskyield: 12088 case OMPD_barrier: 12089 case OMPD_taskwait: 12090 case OMPD_cancellation_point: 12091 case OMPD_flush: 12092 case OMPD_depobj: 12093 case OMPD_scan: 12094 case OMPD_declare_reduction: 12095 case OMPD_declare_mapper: 12096 case OMPD_declare_simd: 12097 case OMPD_declare_variant: 12098 case OMPD_begin_declare_variant: 12099 case OMPD_end_declare_variant: 12100 case OMPD_declare_target: 12101 case OMPD_end_declare_target: 12102 case OMPD_simd: 12103 case OMPD_for: 12104 case OMPD_for_simd: 12105 case OMPD_sections: 12106 case OMPD_section: 12107 case OMPD_single: 12108 case OMPD_master: 12109 case OMPD_critical: 12110 case OMPD_taskgroup: 12111 case OMPD_distribute: 12112 case OMPD_ordered: 12113 case OMPD_atomic: 12114 case OMPD_distribute_simd: 12115 case OMPD_requires: 12116 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 12117 case OMPD_unknown: 12118 llvm_unreachable("Unknown OpenMP directive"); 12119 } 12120 break; 12121 case OMPC_grainsize: 12122 case OMPC_num_tasks: 12123 case OMPC_final: 12124 case OMPC_priority: 12125 switch (DKind) { 12126 case OMPD_task: 12127 case OMPD_taskloop: 12128 case OMPD_taskloop_simd: 12129 case OMPD_master_taskloop: 12130 case OMPD_master_taskloop_simd: 12131 break; 12132 case OMPD_parallel_master_taskloop: 12133 case OMPD_parallel_master_taskloop_simd: 12134 CaptureRegion = OMPD_parallel; 12135 break; 12136 case OMPD_target_update: 12137 case OMPD_target_enter_data: 12138 case OMPD_target_exit_data: 12139 case OMPD_target: 12140 case OMPD_target_simd: 12141 case OMPD_target_teams: 12142 case OMPD_target_parallel: 12143 case OMPD_target_teams_distribute: 12144 case OMPD_target_teams_distribute_simd: 12145 case OMPD_target_parallel_for: 12146 case OMPD_target_parallel_for_simd: 12147 case OMPD_target_teams_distribute_parallel_for: 12148 case OMPD_target_teams_distribute_parallel_for_simd: 12149 case OMPD_target_data: 12150 case OMPD_teams_distribute_parallel_for: 12151 case OMPD_teams_distribute_parallel_for_simd: 12152 case OMPD_teams: 12153 case OMPD_teams_distribute: 12154 case OMPD_teams_distribute_simd: 12155 case OMPD_distribute_parallel_for: 12156 case OMPD_distribute_parallel_for_simd: 12157 case OMPD_cancel: 12158 case OMPD_parallel: 12159 case OMPD_parallel_master: 12160 case OMPD_parallel_sections: 12161 case OMPD_parallel_for: 12162 case OMPD_parallel_for_simd: 12163 case OMPD_threadprivate: 12164 case OMPD_allocate: 12165 case OMPD_taskyield: 12166 case OMPD_barrier: 12167 case OMPD_taskwait: 12168 case OMPD_cancellation_point: 12169 case OMPD_flush: 12170 case OMPD_depobj: 12171 case OMPD_scan: 12172 case OMPD_declare_reduction: 12173 case OMPD_declare_mapper: 12174 case OMPD_declare_simd: 12175 case OMPD_declare_variant: 12176 case OMPD_begin_declare_variant: 12177 case OMPD_end_declare_variant: 12178 case OMPD_declare_target: 12179 case OMPD_end_declare_target: 12180 case OMPD_simd: 12181 case OMPD_for: 12182 case OMPD_for_simd: 12183 case OMPD_sections: 12184 case OMPD_section: 12185 case OMPD_single: 12186 case OMPD_master: 12187 case OMPD_critical: 12188 case OMPD_taskgroup: 12189 case OMPD_distribute: 12190 case OMPD_ordered: 12191 case OMPD_atomic: 12192 case OMPD_distribute_simd: 12193 case OMPD_requires: 12194 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 12195 case OMPD_unknown: 12196 llvm_unreachable("Unknown OpenMP directive"); 12197 } 12198 break; 12199 case OMPC_firstprivate: 12200 case OMPC_lastprivate: 12201 case OMPC_reduction: 12202 case OMPC_task_reduction: 12203 case OMPC_in_reduction: 12204 case OMPC_linear: 12205 case OMPC_default: 12206 case OMPC_proc_bind: 12207 case OMPC_safelen: 12208 case OMPC_simdlen: 12209 case OMPC_allocator: 12210 case OMPC_collapse: 12211 case OMPC_private: 12212 case OMPC_shared: 12213 case OMPC_aligned: 12214 case OMPC_copyin: 12215 case OMPC_copyprivate: 12216 case OMPC_ordered: 12217 case OMPC_nowait: 12218 case OMPC_untied: 12219 case OMPC_mergeable: 12220 case OMPC_threadprivate: 12221 case OMPC_allocate: 12222 case OMPC_flush: 12223 case OMPC_depobj: 12224 case OMPC_read: 12225 case OMPC_write: 12226 case OMPC_update: 12227 case OMPC_capture: 12228 case OMPC_seq_cst: 12229 case OMPC_acq_rel: 12230 case OMPC_acquire: 12231 case OMPC_release: 12232 case OMPC_relaxed: 12233 case OMPC_depend: 12234 case OMPC_threads: 12235 case OMPC_simd: 12236 case OMPC_map: 12237 case OMPC_nogroup: 12238 case OMPC_hint: 12239 case OMPC_defaultmap: 12240 case OMPC_unknown: 12241 case OMPC_uniform: 12242 case OMPC_to: 12243 case OMPC_from: 12244 case OMPC_use_device_ptr: 12245 case OMPC_is_device_ptr: 12246 case OMPC_unified_address: 12247 case OMPC_unified_shared_memory: 12248 case OMPC_reverse_offload: 12249 case OMPC_dynamic_allocators: 12250 case OMPC_atomic_default_mem_order: 12251 case OMPC_device_type: 12252 case OMPC_match: 12253 case OMPC_nontemporal: 12254 case OMPC_order: 12255 case OMPC_destroy: 12256 case OMPC_detach: 12257 case OMPC_inclusive: 12258 case OMPC_exclusive: 12259 case OMPC_uses_allocators: 12260 llvm_unreachable("Unexpected OpenMP clause."); 12261 } 12262 return CaptureRegion; 12263 } 12264 12265 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 12266 Expr *Condition, SourceLocation StartLoc, 12267 SourceLocation LParenLoc, 12268 SourceLocation NameModifierLoc, 12269 SourceLocation ColonLoc, 12270 SourceLocation EndLoc) { 12271 Expr *ValExpr = Condition; 12272 Stmt *HelperValStmt = nullptr; 12273 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12274 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12275 !Condition->isInstantiationDependent() && 12276 !Condition->containsUnexpandedParameterPack()) { 12277 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12278 if (Val.isInvalid()) 12279 return nullptr; 12280 12281 ValExpr = Val.get(); 12282 12283 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12284 CaptureRegion = getOpenMPCaptureRegionForClause( 12285 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 12286 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12287 ValExpr = MakeFullExpr(ValExpr).get(); 12288 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12289 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12290 HelperValStmt = buildPreInits(Context, Captures); 12291 } 12292 } 12293 12294 return new (Context) 12295 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 12296 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 12297 } 12298 12299 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 12300 SourceLocation StartLoc, 12301 SourceLocation LParenLoc, 12302 SourceLocation EndLoc) { 12303 Expr *ValExpr = Condition; 12304 Stmt *HelperValStmt = nullptr; 12305 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 12306 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 12307 !Condition->isInstantiationDependent() && 12308 !Condition->containsUnexpandedParameterPack()) { 12309 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 12310 if (Val.isInvalid()) 12311 return nullptr; 12312 12313 ValExpr = MakeFullExpr(Val.get()).get(); 12314 12315 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12316 CaptureRegion = 12317 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 12318 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12319 ValExpr = MakeFullExpr(ValExpr).get(); 12320 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12321 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12322 HelperValStmt = buildPreInits(Context, Captures); 12323 } 12324 } 12325 12326 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 12327 StartLoc, LParenLoc, EndLoc); 12328 } 12329 12330 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 12331 Expr *Op) { 12332 if (!Op) 12333 return ExprError(); 12334 12335 class IntConvertDiagnoser : public ICEConvertDiagnoser { 12336 public: 12337 IntConvertDiagnoser() 12338 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 12339 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 12340 QualType T) override { 12341 return S.Diag(Loc, diag::err_omp_not_integral) << T; 12342 } 12343 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 12344 QualType T) override { 12345 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 12346 } 12347 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 12348 QualType T, 12349 QualType ConvTy) override { 12350 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 12351 } 12352 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 12353 QualType ConvTy) override { 12354 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12355 << ConvTy->isEnumeralType() << ConvTy; 12356 } 12357 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 12358 QualType T) override { 12359 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 12360 } 12361 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 12362 QualType ConvTy) override { 12363 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 12364 << ConvTy->isEnumeralType() << ConvTy; 12365 } 12366 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 12367 QualType) override { 12368 llvm_unreachable("conversion functions are permitted"); 12369 } 12370 } ConvertDiagnoser; 12371 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 12372 } 12373 12374 static bool 12375 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 12376 bool StrictlyPositive, bool BuildCapture = false, 12377 OpenMPDirectiveKind DKind = OMPD_unknown, 12378 OpenMPDirectiveKind *CaptureRegion = nullptr, 12379 Stmt **HelperValStmt = nullptr) { 12380 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 12381 !ValExpr->isInstantiationDependent()) { 12382 SourceLocation Loc = ValExpr->getExprLoc(); 12383 ExprResult Value = 12384 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 12385 if (Value.isInvalid()) 12386 return false; 12387 12388 ValExpr = Value.get(); 12389 // The expression must evaluate to a non-negative integer value. 12390 llvm::APSInt Result; 12391 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 12392 Result.isSigned() && 12393 !((!StrictlyPositive && Result.isNonNegative()) || 12394 (StrictlyPositive && Result.isStrictlyPositive()))) { 12395 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 12396 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12397 << ValExpr->getSourceRange(); 12398 return false; 12399 } 12400 if (!BuildCapture) 12401 return true; 12402 *CaptureRegion = 12403 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 12404 if (*CaptureRegion != OMPD_unknown && 12405 !SemaRef.CurContext->isDependentContext()) { 12406 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 12407 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12408 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 12409 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 12410 } 12411 } 12412 return true; 12413 } 12414 12415 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 12416 SourceLocation StartLoc, 12417 SourceLocation LParenLoc, 12418 SourceLocation EndLoc) { 12419 Expr *ValExpr = NumThreads; 12420 Stmt *HelperValStmt = nullptr; 12421 12422 // OpenMP [2.5, Restrictions] 12423 // The num_threads expression must evaluate to a positive integer value. 12424 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 12425 /*StrictlyPositive=*/true)) 12426 return nullptr; 12427 12428 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12429 OpenMPDirectiveKind CaptureRegion = 12430 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 12431 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12432 ValExpr = MakeFullExpr(ValExpr).get(); 12433 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12434 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12435 HelperValStmt = buildPreInits(Context, Captures); 12436 } 12437 12438 return new (Context) OMPNumThreadsClause( 12439 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 12440 } 12441 12442 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 12443 OpenMPClauseKind CKind, 12444 bool StrictlyPositive) { 12445 if (!E) 12446 return ExprError(); 12447 if (E->isValueDependent() || E->isTypeDependent() || 12448 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 12449 return E; 12450 llvm::APSInt Result; 12451 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 12452 if (ICE.isInvalid()) 12453 return ExprError(); 12454 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 12455 (!StrictlyPositive && !Result.isNonNegative())) { 12456 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 12457 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 12458 << E->getSourceRange(); 12459 return ExprError(); 12460 } 12461 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 12462 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 12463 << E->getSourceRange(); 12464 return ExprError(); 12465 } 12466 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 12467 DSAStack->setAssociatedLoops(Result.getExtValue()); 12468 else if (CKind == OMPC_ordered) 12469 DSAStack->setAssociatedLoops(Result.getExtValue()); 12470 return ICE; 12471 } 12472 12473 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 12474 SourceLocation LParenLoc, 12475 SourceLocation EndLoc) { 12476 // OpenMP [2.8.1, simd construct, Description] 12477 // The parameter of the safelen clause must be a constant 12478 // positive integer expression. 12479 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 12480 if (Safelen.isInvalid()) 12481 return nullptr; 12482 return new (Context) 12483 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 12484 } 12485 12486 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 12487 SourceLocation LParenLoc, 12488 SourceLocation EndLoc) { 12489 // OpenMP [2.8.1, simd construct, Description] 12490 // The parameter of the simdlen clause must be a constant 12491 // positive integer expression. 12492 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 12493 if (Simdlen.isInvalid()) 12494 return nullptr; 12495 return new (Context) 12496 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 12497 } 12498 12499 /// Tries to find omp_allocator_handle_t type. 12500 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 12501 DSAStackTy *Stack) { 12502 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 12503 if (!OMPAllocatorHandleT.isNull()) 12504 return true; 12505 // Build the predefined allocator expressions. 12506 bool ErrorFound = false; 12507 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 12508 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 12509 StringRef Allocator = 12510 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 12511 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 12512 auto *VD = dyn_cast_or_null<ValueDecl>( 12513 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 12514 if (!VD) { 12515 ErrorFound = true; 12516 break; 12517 } 12518 QualType AllocatorType = 12519 VD->getType().getNonLValueExprType(S.getASTContext()); 12520 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 12521 if (!Res.isUsable()) { 12522 ErrorFound = true; 12523 break; 12524 } 12525 if (OMPAllocatorHandleT.isNull()) 12526 OMPAllocatorHandleT = AllocatorType; 12527 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 12528 ErrorFound = true; 12529 break; 12530 } 12531 Stack->setAllocator(AllocatorKind, Res.get()); 12532 } 12533 if (ErrorFound) { 12534 S.Diag(Loc, diag::err_omp_implied_type_not_found) 12535 << "omp_allocator_handle_t"; 12536 return false; 12537 } 12538 OMPAllocatorHandleT.addConst(); 12539 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 12540 return true; 12541 } 12542 12543 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 12544 SourceLocation LParenLoc, 12545 SourceLocation EndLoc) { 12546 // OpenMP [2.11.3, allocate Directive, Description] 12547 // allocator is an expression of omp_allocator_handle_t type. 12548 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 12549 return nullptr; 12550 12551 ExprResult Allocator = DefaultLvalueConversion(A); 12552 if (Allocator.isInvalid()) 12553 return nullptr; 12554 Allocator = PerformImplicitConversion(Allocator.get(), 12555 DSAStack->getOMPAllocatorHandleT(), 12556 Sema::AA_Initializing, 12557 /*AllowExplicit=*/true); 12558 if (Allocator.isInvalid()) 12559 return nullptr; 12560 return new (Context) 12561 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 12562 } 12563 12564 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 12565 SourceLocation StartLoc, 12566 SourceLocation LParenLoc, 12567 SourceLocation EndLoc) { 12568 // OpenMP [2.7.1, loop construct, Description] 12569 // OpenMP [2.8.1, simd construct, Description] 12570 // OpenMP [2.9.6, distribute construct, Description] 12571 // The parameter of the collapse clause must be a constant 12572 // positive integer expression. 12573 ExprResult NumForLoopsResult = 12574 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 12575 if (NumForLoopsResult.isInvalid()) 12576 return nullptr; 12577 return new (Context) 12578 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 12579 } 12580 12581 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 12582 SourceLocation EndLoc, 12583 SourceLocation LParenLoc, 12584 Expr *NumForLoops) { 12585 // OpenMP [2.7.1, loop construct, Description] 12586 // OpenMP [2.8.1, simd construct, Description] 12587 // OpenMP [2.9.6, distribute construct, Description] 12588 // The parameter of the ordered clause must be a constant 12589 // positive integer expression if any. 12590 if (NumForLoops && LParenLoc.isValid()) { 12591 ExprResult NumForLoopsResult = 12592 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 12593 if (NumForLoopsResult.isInvalid()) 12594 return nullptr; 12595 NumForLoops = NumForLoopsResult.get(); 12596 } else { 12597 NumForLoops = nullptr; 12598 } 12599 auto *Clause = OMPOrderedClause::Create( 12600 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 12601 StartLoc, LParenLoc, EndLoc); 12602 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 12603 return Clause; 12604 } 12605 12606 OMPClause *Sema::ActOnOpenMPSimpleClause( 12607 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 12608 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12609 OMPClause *Res = nullptr; 12610 switch (Kind) { 12611 case OMPC_default: 12612 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 12613 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12614 break; 12615 case OMPC_proc_bind: 12616 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 12617 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12618 break; 12619 case OMPC_atomic_default_mem_order: 12620 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 12621 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 12622 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12623 break; 12624 case OMPC_order: 12625 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 12626 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12627 break; 12628 case OMPC_update: 12629 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 12630 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 12631 break; 12632 case OMPC_if: 12633 case OMPC_final: 12634 case OMPC_num_threads: 12635 case OMPC_safelen: 12636 case OMPC_simdlen: 12637 case OMPC_allocator: 12638 case OMPC_collapse: 12639 case OMPC_schedule: 12640 case OMPC_private: 12641 case OMPC_firstprivate: 12642 case OMPC_lastprivate: 12643 case OMPC_shared: 12644 case OMPC_reduction: 12645 case OMPC_task_reduction: 12646 case OMPC_in_reduction: 12647 case OMPC_linear: 12648 case OMPC_aligned: 12649 case OMPC_copyin: 12650 case OMPC_copyprivate: 12651 case OMPC_ordered: 12652 case OMPC_nowait: 12653 case OMPC_untied: 12654 case OMPC_mergeable: 12655 case OMPC_threadprivate: 12656 case OMPC_allocate: 12657 case OMPC_flush: 12658 case OMPC_depobj: 12659 case OMPC_read: 12660 case OMPC_write: 12661 case OMPC_capture: 12662 case OMPC_seq_cst: 12663 case OMPC_acq_rel: 12664 case OMPC_acquire: 12665 case OMPC_release: 12666 case OMPC_relaxed: 12667 case OMPC_depend: 12668 case OMPC_device: 12669 case OMPC_threads: 12670 case OMPC_simd: 12671 case OMPC_map: 12672 case OMPC_num_teams: 12673 case OMPC_thread_limit: 12674 case OMPC_priority: 12675 case OMPC_grainsize: 12676 case OMPC_nogroup: 12677 case OMPC_num_tasks: 12678 case OMPC_hint: 12679 case OMPC_dist_schedule: 12680 case OMPC_defaultmap: 12681 case OMPC_unknown: 12682 case OMPC_uniform: 12683 case OMPC_to: 12684 case OMPC_from: 12685 case OMPC_use_device_ptr: 12686 case OMPC_is_device_ptr: 12687 case OMPC_unified_address: 12688 case OMPC_unified_shared_memory: 12689 case OMPC_reverse_offload: 12690 case OMPC_dynamic_allocators: 12691 case OMPC_device_type: 12692 case OMPC_match: 12693 case OMPC_nontemporal: 12694 case OMPC_destroy: 12695 case OMPC_detach: 12696 case OMPC_inclusive: 12697 case OMPC_exclusive: 12698 case OMPC_uses_allocators: 12699 llvm_unreachable("Clause is not allowed."); 12700 } 12701 return Res; 12702 } 12703 12704 static std::string 12705 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 12706 ArrayRef<unsigned> Exclude = llvm::None) { 12707 SmallString<256> Buffer; 12708 llvm::raw_svector_ostream Out(Buffer); 12709 unsigned Skipped = Exclude.size(); 12710 auto S = Exclude.begin(), E = Exclude.end(); 12711 for (unsigned I = First; I < Last; ++I) { 12712 if (std::find(S, E, I) != E) { 12713 --Skipped; 12714 continue; 12715 } 12716 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 12717 if (I + Skipped + 2 == Last) 12718 Out << " or "; 12719 else if (I + Skipped + 1 != Last) 12720 Out << ", "; 12721 } 12722 return std::string(Out.str()); 12723 } 12724 12725 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 12726 SourceLocation KindKwLoc, 12727 SourceLocation StartLoc, 12728 SourceLocation LParenLoc, 12729 SourceLocation EndLoc) { 12730 if (Kind == OMP_DEFAULT_unknown) { 12731 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12732 << getListOfPossibleValues(OMPC_default, /*First=*/0, 12733 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 12734 << getOpenMPClauseName(OMPC_default); 12735 return nullptr; 12736 } 12737 if (Kind == OMP_DEFAULT_none) 12738 DSAStack->setDefaultDSANone(KindKwLoc); 12739 else if (Kind == OMP_DEFAULT_shared) 12740 DSAStack->setDefaultDSAShared(KindKwLoc); 12741 12742 return new (Context) 12743 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12744 } 12745 12746 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 12747 SourceLocation KindKwLoc, 12748 SourceLocation StartLoc, 12749 SourceLocation LParenLoc, 12750 SourceLocation EndLoc) { 12751 if (Kind == OMP_PROC_BIND_unknown) { 12752 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12753 << getListOfPossibleValues(OMPC_proc_bind, 12754 /*First=*/unsigned(OMP_PROC_BIND_master), 12755 /*Last=*/5) 12756 << getOpenMPClauseName(OMPC_proc_bind); 12757 return nullptr; 12758 } 12759 return new (Context) 12760 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12761 } 12762 12763 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 12764 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 12765 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 12766 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 12767 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12768 << getListOfPossibleValues( 12769 OMPC_atomic_default_mem_order, /*First=*/0, 12770 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 12771 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 12772 return nullptr; 12773 } 12774 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 12775 LParenLoc, EndLoc); 12776 } 12777 12778 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 12779 SourceLocation KindKwLoc, 12780 SourceLocation StartLoc, 12781 SourceLocation LParenLoc, 12782 SourceLocation EndLoc) { 12783 if (Kind == OMPC_ORDER_unknown) { 12784 static_assert(OMPC_ORDER_unknown > 0, 12785 "OMPC_ORDER_unknown not greater than 0"); 12786 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12787 << getListOfPossibleValues(OMPC_order, /*First=*/0, 12788 /*Last=*/OMPC_ORDER_unknown) 12789 << getOpenMPClauseName(OMPC_order); 12790 return nullptr; 12791 } 12792 return new (Context) 12793 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 12794 } 12795 12796 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 12797 SourceLocation KindKwLoc, 12798 SourceLocation StartLoc, 12799 SourceLocation LParenLoc, 12800 SourceLocation EndLoc) { 12801 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 12802 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 12803 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 12804 OMPC_DEPEND_depobj}; 12805 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 12806 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12807 /*Last=*/OMPC_DEPEND_unknown, Except) 12808 << getOpenMPClauseName(OMPC_update); 12809 return nullptr; 12810 } 12811 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 12812 EndLoc); 12813 } 12814 12815 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 12816 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 12817 SourceLocation StartLoc, SourceLocation LParenLoc, 12818 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 12819 SourceLocation EndLoc) { 12820 OMPClause *Res = nullptr; 12821 switch (Kind) { 12822 case OMPC_schedule: 12823 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 12824 assert(Argument.size() == NumberOfElements && 12825 ArgumentLoc.size() == NumberOfElements); 12826 Res = ActOnOpenMPScheduleClause( 12827 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 12828 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 12829 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 12830 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 12831 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 12832 break; 12833 case OMPC_if: 12834 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12835 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 12836 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 12837 DelimLoc, EndLoc); 12838 break; 12839 case OMPC_dist_schedule: 12840 Res = ActOnOpenMPDistScheduleClause( 12841 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 12842 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 12843 break; 12844 case OMPC_defaultmap: 12845 enum { Modifier, DefaultmapKind }; 12846 Res = ActOnOpenMPDefaultmapClause( 12847 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 12848 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 12849 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 12850 EndLoc); 12851 break; 12852 case OMPC_device: 12853 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 12854 Res = ActOnOpenMPDeviceClause( 12855 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 12856 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 12857 break; 12858 case OMPC_final: 12859 case OMPC_num_threads: 12860 case OMPC_safelen: 12861 case OMPC_simdlen: 12862 case OMPC_allocator: 12863 case OMPC_collapse: 12864 case OMPC_default: 12865 case OMPC_proc_bind: 12866 case OMPC_private: 12867 case OMPC_firstprivate: 12868 case OMPC_lastprivate: 12869 case OMPC_shared: 12870 case OMPC_reduction: 12871 case OMPC_task_reduction: 12872 case OMPC_in_reduction: 12873 case OMPC_linear: 12874 case OMPC_aligned: 12875 case OMPC_copyin: 12876 case OMPC_copyprivate: 12877 case OMPC_ordered: 12878 case OMPC_nowait: 12879 case OMPC_untied: 12880 case OMPC_mergeable: 12881 case OMPC_threadprivate: 12882 case OMPC_allocate: 12883 case OMPC_flush: 12884 case OMPC_depobj: 12885 case OMPC_read: 12886 case OMPC_write: 12887 case OMPC_update: 12888 case OMPC_capture: 12889 case OMPC_seq_cst: 12890 case OMPC_acq_rel: 12891 case OMPC_acquire: 12892 case OMPC_release: 12893 case OMPC_relaxed: 12894 case OMPC_depend: 12895 case OMPC_threads: 12896 case OMPC_simd: 12897 case OMPC_map: 12898 case OMPC_num_teams: 12899 case OMPC_thread_limit: 12900 case OMPC_priority: 12901 case OMPC_grainsize: 12902 case OMPC_nogroup: 12903 case OMPC_num_tasks: 12904 case OMPC_hint: 12905 case OMPC_unknown: 12906 case OMPC_uniform: 12907 case OMPC_to: 12908 case OMPC_from: 12909 case OMPC_use_device_ptr: 12910 case OMPC_is_device_ptr: 12911 case OMPC_unified_address: 12912 case OMPC_unified_shared_memory: 12913 case OMPC_reverse_offload: 12914 case OMPC_dynamic_allocators: 12915 case OMPC_atomic_default_mem_order: 12916 case OMPC_device_type: 12917 case OMPC_match: 12918 case OMPC_nontemporal: 12919 case OMPC_order: 12920 case OMPC_destroy: 12921 case OMPC_detach: 12922 case OMPC_inclusive: 12923 case OMPC_exclusive: 12924 case OMPC_uses_allocators: 12925 llvm_unreachable("Clause is not allowed."); 12926 } 12927 return Res; 12928 } 12929 12930 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 12931 OpenMPScheduleClauseModifier M2, 12932 SourceLocation M1Loc, SourceLocation M2Loc) { 12933 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 12934 SmallVector<unsigned, 2> Excluded; 12935 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 12936 Excluded.push_back(M2); 12937 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 12938 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 12939 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 12940 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 12941 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 12942 << getListOfPossibleValues(OMPC_schedule, 12943 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 12944 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12945 Excluded) 12946 << getOpenMPClauseName(OMPC_schedule); 12947 return true; 12948 } 12949 return false; 12950 } 12951 12952 OMPClause *Sema::ActOnOpenMPScheduleClause( 12953 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 12954 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12955 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 12956 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 12957 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 12958 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 12959 return nullptr; 12960 // OpenMP, 2.7.1, Loop Construct, Restrictions 12961 // Either the monotonic modifier or the nonmonotonic modifier can be specified 12962 // but not both. 12963 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 12964 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 12965 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 12966 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 12967 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 12968 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 12969 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 12970 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 12971 return nullptr; 12972 } 12973 if (Kind == OMPC_SCHEDULE_unknown) { 12974 std::string Values; 12975 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 12976 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 12977 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12978 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 12979 Exclude); 12980 } else { 12981 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 12982 /*Last=*/OMPC_SCHEDULE_unknown); 12983 } 12984 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12985 << Values << getOpenMPClauseName(OMPC_schedule); 12986 return nullptr; 12987 } 12988 // OpenMP, 2.7.1, Loop Construct, Restrictions 12989 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 12990 // schedule(guided). 12991 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 12992 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 12993 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 12994 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 12995 diag::err_omp_schedule_nonmonotonic_static); 12996 return nullptr; 12997 } 12998 Expr *ValExpr = ChunkSize; 12999 Stmt *HelperValStmt = nullptr; 13000 if (ChunkSize) { 13001 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 13002 !ChunkSize->isInstantiationDependent() && 13003 !ChunkSize->containsUnexpandedParameterPack()) { 13004 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 13005 ExprResult Val = 13006 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 13007 if (Val.isInvalid()) 13008 return nullptr; 13009 13010 ValExpr = Val.get(); 13011 13012 // OpenMP [2.7.1, Restrictions] 13013 // chunk_size must be a loop invariant integer expression with a positive 13014 // value. 13015 llvm::APSInt Result; 13016 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 13017 if (Result.isSigned() && !Result.isStrictlyPositive()) { 13018 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 13019 << "schedule" << 1 << ChunkSize->getSourceRange(); 13020 return nullptr; 13021 } 13022 } else if (getOpenMPCaptureRegionForClause( 13023 DSAStack->getCurrentDirective(), OMPC_schedule, 13024 LangOpts.OpenMP) != OMPD_unknown && 13025 !CurContext->isDependentContext()) { 13026 ValExpr = MakeFullExpr(ValExpr).get(); 13027 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 13028 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 13029 HelperValStmt = buildPreInits(Context, Captures); 13030 } 13031 } 13032 } 13033 13034 return new (Context) 13035 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 13036 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 13037 } 13038 13039 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 13040 SourceLocation StartLoc, 13041 SourceLocation EndLoc) { 13042 OMPClause *Res = nullptr; 13043 switch (Kind) { 13044 case OMPC_ordered: 13045 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 13046 break; 13047 case OMPC_nowait: 13048 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 13049 break; 13050 case OMPC_untied: 13051 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 13052 break; 13053 case OMPC_mergeable: 13054 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 13055 break; 13056 case OMPC_read: 13057 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 13058 break; 13059 case OMPC_write: 13060 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 13061 break; 13062 case OMPC_update: 13063 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 13064 break; 13065 case OMPC_capture: 13066 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 13067 break; 13068 case OMPC_seq_cst: 13069 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 13070 break; 13071 case OMPC_acq_rel: 13072 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 13073 break; 13074 case OMPC_acquire: 13075 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 13076 break; 13077 case OMPC_release: 13078 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 13079 break; 13080 case OMPC_relaxed: 13081 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 13082 break; 13083 case OMPC_threads: 13084 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 13085 break; 13086 case OMPC_simd: 13087 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 13088 break; 13089 case OMPC_nogroup: 13090 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 13091 break; 13092 case OMPC_unified_address: 13093 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 13094 break; 13095 case OMPC_unified_shared_memory: 13096 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13097 break; 13098 case OMPC_reverse_offload: 13099 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 13100 break; 13101 case OMPC_dynamic_allocators: 13102 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 13103 break; 13104 case OMPC_destroy: 13105 Res = ActOnOpenMPDestroyClause(StartLoc, EndLoc); 13106 break; 13107 case OMPC_if: 13108 case OMPC_final: 13109 case OMPC_num_threads: 13110 case OMPC_safelen: 13111 case OMPC_simdlen: 13112 case OMPC_allocator: 13113 case OMPC_collapse: 13114 case OMPC_schedule: 13115 case OMPC_private: 13116 case OMPC_firstprivate: 13117 case OMPC_lastprivate: 13118 case OMPC_shared: 13119 case OMPC_reduction: 13120 case OMPC_task_reduction: 13121 case OMPC_in_reduction: 13122 case OMPC_linear: 13123 case OMPC_aligned: 13124 case OMPC_copyin: 13125 case OMPC_copyprivate: 13126 case OMPC_default: 13127 case OMPC_proc_bind: 13128 case OMPC_threadprivate: 13129 case OMPC_allocate: 13130 case OMPC_flush: 13131 case OMPC_depobj: 13132 case OMPC_depend: 13133 case OMPC_device: 13134 case OMPC_map: 13135 case OMPC_num_teams: 13136 case OMPC_thread_limit: 13137 case OMPC_priority: 13138 case OMPC_grainsize: 13139 case OMPC_num_tasks: 13140 case OMPC_hint: 13141 case OMPC_dist_schedule: 13142 case OMPC_defaultmap: 13143 case OMPC_unknown: 13144 case OMPC_uniform: 13145 case OMPC_to: 13146 case OMPC_from: 13147 case OMPC_use_device_ptr: 13148 case OMPC_is_device_ptr: 13149 case OMPC_atomic_default_mem_order: 13150 case OMPC_device_type: 13151 case OMPC_match: 13152 case OMPC_nontemporal: 13153 case OMPC_order: 13154 case OMPC_detach: 13155 case OMPC_inclusive: 13156 case OMPC_exclusive: 13157 case OMPC_uses_allocators: 13158 llvm_unreachable("Clause is not allowed."); 13159 } 13160 return Res; 13161 } 13162 13163 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 13164 SourceLocation EndLoc) { 13165 DSAStack->setNowaitRegion(); 13166 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 13167 } 13168 13169 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 13170 SourceLocation EndLoc) { 13171 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 13172 } 13173 13174 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 13175 SourceLocation EndLoc) { 13176 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 13177 } 13178 13179 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 13180 SourceLocation EndLoc) { 13181 return new (Context) OMPReadClause(StartLoc, EndLoc); 13182 } 13183 13184 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 13185 SourceLocation EndLoc) { 13186 return new (Context) OMPWriteClause(StartLoc, EndLoc); 13187 } 13188 13189 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 13190 SourceLocation EndLoc) { 13191 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 13192 } 13193 13194 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 13195 SourceLocation EndLoc) { 13196 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 13197 } 13198 13199 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 13200 SourceLocation EndLoc) { 13201 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 13202 } 13203 13204 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 13205 SourceLocation EndLoc) { 13206 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 13207 } 13208 13209 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 13210 SourceLocation EndLoc) { 13211 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 13212 } 13213 13214 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 13215 SourceLocation EndLoc) { 13216 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 13217 } 13218 13219 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 13220 SourceLocation EndLoc) { 13221 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 13222 } 13223 13224 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 13225 SourceLocation EndLoc) { 13226 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 13227 } 13228 13229 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 13230 SourceLocation EndLoc) { 13231 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 13232 } 13233 13234 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 13235 SourceLocation EndLoc) { 13236 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 13237 } 13238 13239 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 13240 SourceLocation EndLoc) { 13241 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 13242 } 13243 13244 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 13245 SourceLocation EndLoc) { 13246 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 13247 } 13248 13249 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 13250 SourceLocation EndLoc) { 13251 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 13252 } 13253 13254 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 13255 SourceLocation EndLoc) { 13256 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 13257 } 13258 13259 OMPClause *Sema::ActOnOpenMPDestroyClause(SourceLocation StartLoc, 13260 SourceLocation EndLoc) { 13261 return new (Context) OMPDestroyClause(StartLoc, EndLoc); 13262 } 13263 13264 OMPClause *Sema::ActOnOpenMPVarListClause( 13265 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *DepModOrTailExpr, 13266 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 13267 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 13268 DeclarationNameInfo &ReductionOrMapperId, int ExtraModifier, 13269 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13270 ArrayRef<SourceLocation> MapTypeModifiersLoc, bool IsMapTypeImplicit, 13271 SourceLocation ExtraModifierLoc) { 13272 SourceLocation StartLoc = Locs.StartLoc; 13273 SourceLocation LParenLoc = Locs.LParenLoc; 13274 SourceLocation EndLoc = Locs.EndLoc; 13275 OMPClause *Res = nullptr; 13276 switch (Kind) { 13277 case OMPC_private: 13278 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13279 break; 13280 case OMPC_firstprivate: 13281 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13282 break; 13283 case OMPC_lastprivate: 13284 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 13285 "Unexpected lastprivate modifier."); 13286 Res = ActOnOpenMPLastprivateClause( 13287 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 13288 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 13289 break; 13290 case OMPC_shared: 13291 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 13292 break; 13293 case OMPC_reduction: 13294 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 13295 "Unexpected lastprivate modifier."); 13296 Res = ActOnOpenMPReductionClause( 13297 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 13298 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 13299 ReductionOrMapperIdScopeSpec, ReductionOrMapperId); 13300 break; 13301 case OMPC_task_reduction: 13302 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13303 EndLoc, ReductionOrMapperIdScopeSpec, 13304 ReductionOrMapperId); 13305 break; 13306 case OMPC_in_reduction: 13307 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 13308 EndLoc, ReductionOrMapperIdScopeSpec, 13309 ReductionOrMapperId); 13310 break; 13311 case OMPC_linear: 13312 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 13313 "Unexpected linear modifier."); 13314 Res = ActOnOpenMPLinearClause( 13315 VarList, DepModOrTailExpr, StartLoc, LParenLoc, 13316 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 13317 ColonLoc, EndLoc); 13318 break; 13319 case OMPC_aligned: 13320 Res = ActOnOpenMPAlignedClause(VarList, DepModOrTailExpr, StartLoc, 13321 LParenLoc, ColonLoc, EndLoc); 13322 break; 13323 case OMPC_copyin: 13324 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 13325 break; 13326 case OMPC_copyprivate: 13327 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 13328 break; 13329 case OMPC_flush: 13330 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 13331 break; 13332 case OMPC_depend: 13333 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 13334 "Unexpected depend modifier."); 13335 Res = ActOnOpenMPDependClause( 13336 DepModOrTailExpr, static_cast<OpenMPDependClauseKind>(ExtraModifier), 13337 ExtraModifierLoc, ColonLoc, VarList, StartLoc, LParenLoc, EndLoc); 13338 break; 13339 case OMPC_map: 13340 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 13341 "Unexpected map modifier."); 13342 Res = ActOnOpenMPMapClause( 13343 MapTypeModifiers, MapTypeModifiersLoc, ReductionOrMapperIdScopeSpec, 13344 ReductionOrMapperId, static_cast<OpenMPMapClauseKind>(ExtraModifier), 13345 IsMapTypeImplicit, ExtraModifierLoc, ColonLoc, VarList, Locs); 13346 break; 13347 case OMPC_to: 13348 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 13349 ReductionOrMapperId, Locs); 13350 break; 13351 case OMPC_from: 13352 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 13353 ReductionOrMapperId, Locs); 13354 break; 13355 case OMPC_use_device_ptr: 13356 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 13357 break; 13358 case OMPC_is_device_ptr: 13359 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 13360 break; 13361 case OMPC_allocate: 13362 Res = ActOnOpenMPAllocateClause(DepModOrTailExpr, VarList, StartLoc, 13363 LParenLoc, ColonLoc, EndLoc); 13364 break; 13365 case OMPC_nontemporal: 13366 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 13367 break; 13368 case OMPC_inclusive: 13369 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13370 break; 13371 case OMPC_exclusive: 13372 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 13373 break; 13374 case OMPC_if: 13375 case OMPC_depobj: 13376 case OMPC_final: 13377 case OMPC_num_threads: 13378 case OMPC_safelen: 13379 case OMPC_simdlen: 13380 case OMPC_allocator: 13381 case OMPC_collapse: 13382 case OMPC_default: 13383 case OMPC_proc_bind: 13384 case OMPC_schedule: 13385 case OMPC_ordered: 13386 case OMPC_nowait: 13387 case OMPC_untied: 13388 case OMPC_mergeable: 13389 case OMPC_threadprivate: 13390 case OMPC_read: 13391 case OMPC_write: 13392 case OMPC_update: 13393 case OMPC_capture: 13394 case OMPC_seq_cst: 13395 case OMPC_acq_rel: 13396 case OMPC_acquire: 13397 case OMPC_release: 13398 case OMPC_relaxed: 13399 case OMPC_device: 13400 case OMPC_threads: 13401 case OMPC_simd: 13402 case OMPC_num_teams: 13403 case OMPC_thread_limit: 13404 case OMPC_priority: 13405 case OMPC_grainsize: 13406 case OMPC_nogroup: 13407 case OMPC_num_tasks: 13408 case OMPC_hint: 13409 case OMPC_dist_schedule: 13410 case OMPC_defaultmap: 13411 case OMPC_unknown: 13412 case OMPC_uniform: 13413 case OMPC_unified_address: 13414 case OMPC_unified_shared_memory: 13415 case OMPC_reverse_offload: 13416 case OMPC_dynamic_allocators: 13417 case OMPC_atomic_default_mem_order: 13418 case OMPC_device_type: 13419 case OMPC_match: 13420 case OMPC_order: 13421 case OMPC_destroy: 13422 case OMPC_detach: 13423 case OMPC_uses_allocators: 13424 llvm_unreachable("Clause is not allowed."); 13425 } 13426 return Res; 13427 } 13428 13429 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 13430 ExprObjectKind OK, SourceLocation Loc) { 13431 ExprResult Res = BuildDeclRefExpr( 13432 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 13433 if (!Res.isUsable()) 13434 return ExprError(); 13435 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 13436 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 13437 if (!Res.isUsable()) 13438 return ExprError(); 13439 } 13440 if (VK != VK_LValue && Res.get()->isGLValue()) { 13441 Res = DefaultLvalueConversion(Res.get()); 13442 if (!Res.isUsable()) 13443 return ExprError(); 13444 } 13445 return Res; 13446 } 13447 13448 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 13449 SourceLocation StartLoc, 13450 SourceLocation LParenLoc, 13451 SourceLocation EndLoc) { 13452 SmallVector<Expr *, 8> Vars; 13453 SmallVector<Expr *, 8> PrivateCopies; 13454 for (Expr *RefExpr : VarList) { 13455 assert(RefExpr && "NULL expr in OpenMP private clause."); 13456 SourceLocation ELoc; 13457 SourceRange ERange; 13458 Expr *SimpleRefExpr = RefExpr; 13459 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13460 if (Res.second) { 13461 // It will be analyzed later. 13462 Vars.push_back(RefExpr); 13463 PrivateCopies.push_back(nullptr); 13464 } 13465 ValueDecl *D = Res.first; 13466 if (!D) 13467 continue; 13468 13469 QualType Type = D->getType(); 13470 auto *VD = dyn_cast<VarDecl>(D); 13471 13472 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13473 // A variable that appears in a private clause must not have an incomplete 13474 // type or a reference type. 13475 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 13476 continue; 13477 Type = Type.getNonReferenceType(); 13478 13479 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13480 // A variable that is privatized must not have a const-qualified type 13481 // unless it is of class type with a mutable member. This restriction does 13482 // not apply to the firstprivate clause. 13483 // 13484 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 13485 // A variable that appears in a private clause must not have a 13486 // const-qualified type unless it is of class type with a mutable member. 13487 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 13488 continue; 13489 13490 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13491 // in a Construct] 13492 // Variables with the predetermined data-sharing attributes may not be 13493 // listed in data-sharing attributes clauses, except for the cases 13494 // listed below. For these exceptions only, listing a predetermined 13495 // variable in a data-sharing attribute clause is allowed and overrides 13496 // the variable's predetermined data-sharing attributes. 13497 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13498 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 13499 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 13500 << getOpenMPClauseName(OMPC_private); 13501 reportOriginalDsa(*this, DSAStack, D, DVar); 13502 continue; 13503 } 13504 13505 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13506 // Variably modified types are not supported for tasks. 13507 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13508 isOpenMPTaskingDirective(CurrDir)) { 13509 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13510 << getOpenMPClauseName(OMPC_private) << Type 13511 << getOpenMPDirectiveName(CurrDir); 13512 bool IsDecl = 13513 !VD || 13514 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13515 Diag(D->getLocation(), 13516 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13517 << D; 13518 continue; 13519 } 13520 13521 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13522 // A list item cannot appear in both a map clause and a data-sharing 13523 // attribute clause on the same construct 13524 // 13525 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13526 // A list item cannot appear in both a map clause and a data-sharing 13527 // attribute clause on the same construct unless the construct is a 13528 // combined construct. 13529 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 13530 CurrDir == OMPD_target) { 13531 OpenMPClauseKind ConflictKind; 13532 if (DSAStack->checkMappableExprComponentListsForDecl( 13533 VD, /*CurrentRegionOnly=*/true, 13534 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 13535 OpenMPClauseKind WhereFoundClauseKind) -> bool { 13536 ConflictKind = WhereFoundClauseKind; 13537 return true; 13538 })) { 13539 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13540 << getOpenMPClauseName(OMPC_private) 13541 << getOpenMPClauseName(ConflictKind) 13542 << getOpenMPDirectiveName(CurrDir); 13543 reportOriginalDsa(*this, DSAStack, D, DVar); 13544 continue; 13545 } 13546 } 13547 13548 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 13549 // A variable of class type (or array thereof) that appears in a private 13550 // clause requires an accessible, unambiguous default constructor for the 13551 // class type. 13552 // Generate helper private variable and initialize it with the default 13553 // value. The address of the original variable is replaced by the address of 13554 // the new private variable in CodeGen. This new variable is not added to 13555 // IdResolver, so the code in the OpenMP region uses original variable for 13556 // proper diagnostics. 13557 Type = Type.getUnqualifiedType(); 13558 VarDecl *VDPrivate = 13559 buildVarDecl(*this, ELoc, Type, D->getName(), 13560 D->hasAttrs() ? &D->getAttrs() : nullptr, 13561 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13562 ActOnUninitializedDecl(VDPrivate); 13563 if (VDPrivate->isInvalidDecl()) 13564 continue; 13565 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13566 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 13567 13568 DeclRefExpr *Ref = nullptr; 13569 if (!VD && !CurContext->isDependentContext()) 13570 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 13571 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 13572 Vars.push_back((VD || CurContext->isDependentContext()) 13573 ? RefExpr->IgnoreParens() 13574 : Ref); 13575 PrivateCopies.push_back(VDPrivateRefExpr); 13576 } 13577 13578 if (Vars.empty()) 13579 return nullptr; 13580 13581 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 13582 PrivateCopies); 13583 } 13584 13585 namespace { 13586 class DiagsUninitializedSeveretyRAII { 13587 private: 13588 DiagnosticsEngine &Diags; 13589 SourceLocation SavedLoc; 13590 bool IsIgnored = false; 13591 13592 public: 13593 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 13594 bool IsIgnored) 13595 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 13596 if (!IsIgnored) { 13597 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 13598 /*Map*/ diag::Severity::Ignored, Loc); 13599 } 13600 } 13601 ~DiagsUninitializedSeveretyRAII() { 13602 if (!IsIgnored) 13603 Diags.popMappings(SavedLoc); 13604 } 13605 }; 13606 } 13607 13608 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 13609 SourceLocation StartLoc, 13610 SourceLocation LParenLoc, 13611 SourceLocation EndLoc) { 13612 SmallVector<Expr *, 8> Vars; 13613 SmallVector<Expr *, 8> PrivateCopies; 13614 SmallVector<Expr *, 8> Inits; 13615 SmallVector<Decl *, 4> ExprCaptures; 13616 bool IsImplicitClause = 13617 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 13618 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 13619 13620 for (Expr *RefExpr : VarList) { 13621 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 13622 SourceLocation ELoc; 13623 SourceRange ERange; 13624 Expr *SimpleRefExpr = RefExpr; 13625 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13626 if (Res.second) { 13627 // It will be analyzed later. 13628 Vars.push_back(RefExpr); 13629 PrivateCopies.push_back(nullptr); 13630 Inits.push_back(nullptr); 13631 } 13632 ValueDecl *D = Res.first; 13633 if (!D) 13634 continue; 13635 13636 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 13637 QualType Type = D->getType(); 13638 auto *VD = dyn_cast<VarDecl>(D); 13639 13640 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 13641 // A variable that appears in a private clause must not have an incomplete 13642 // type or a reference type. 13643 if (RequireCompleteType(ELoc, Type, 13644 diag::err_omp_firstprivate_incomplete_type)) 13645 continue; 13646 Type = Type.getNonReferenceType(); 13647 13648 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 13649 // A variable of class type (or array thereof) that appears in a private 13650 // clause requires an accessible, unambiguous copy constructor for the 13651 // class type. 13652 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 13653 13654 // If an implicit firstprivate variable found it was checked already. 13655 DSAStackTy::DSAVarData TopDVar; 13656 if (!IsImplicitClause) { 13657 DSAStackTy::DSAVarData DVar = 13658 DSAStack->getTopDSA(D, /*FromParent=*/false); 13659 TopDVar = DVar; 13660 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13661 bool IsConstant = ElemType.isConstant(Context); 13662 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 13663 // A list item that specifies a given variable may not appear in more 13664 // than one clause on the same directive, except that a variable may be 13665 // specified in both firstprivate and lastprivate clauses. 13666 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13667 // A list item may appear in a firstprivate or lastprivate clause but not 13668 // both. 13669 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 13670 (isOpenMPDistributeDirective(CurrDir) || 13671 DVar.CKind != OMPC_lastprivate) && 13672 DVar.RefExpr) { 13673 Diag(ELoc, diag::err_omp_wrong_dsa) 13674 << getOpenMPClauseName(DVar.CKind) 13675 << getOpenMPClauseName(OMPC_firstprivate); 13676 reportOriginalDsa(*this, DSAStack, D, DVar); 13677 continue; 13678 } 13679 13680 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13681 // in a Construct] 13682 // Variables with the predetermined data-sharing attributes may not be 13683 // listed in data-sharing attributes clauses, except for the cases 13684 // listed below. For these exceptions only, listing a predetermined 13685 // variable in a data-sharing attribute clause is allowed and overrides 13686 // the variable's predetermined data-sharing attributes. 13687 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 13688 // in a Construct, C/C++, p.2] 13689 // Variables with const-qualified type having no mutable member may be 13690 // listed in a firstprivate clause, even if they are static data members. 13691 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 13692 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 13693 Diag(ELoc, diag::err_omp_wrong_dsa) 13694 << getOpenMPClauseName(DVar.CKind) 13695 << getOpenMPClauseName(OMPC_firstprivate); 13696 reportOriginalDsa(*this, DSAStack, D, DVar); 13697 continue; 13698 } 13699 13700 // OpenMP [2.9.3.4, Restrictions, p.2] 13701 // A list item that is private within a parallel region must not appear 13702 // in a firstprivate clause on a worksharing construct if any of the 13703 // worksharing regions arising from the worksharing construct ever bind 13704 // to any of the parallel regions arising from the parallel construct. 13705 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13706 // A list item that is private within a teams region must not appear in a 13707 // firstprivate clause on a distribute construct if any of the distribute 13708 // regions arising from the distribute construct ever bind to any of the 13709 // teams regions arising from the teams construct. 13710 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 13711 // A list item that appears in a reduction clause of a teams construct 13712 // must not appear in a firstprivate clause on a distribute construct if 13713 // any of the distribute regions arising from the distribute construct 13714 // ever bind to any of the teams regions arising from the teams construct. 13715 if ((isOpenMPWorksharingDirective(CurrDir) || 13716 isOpenMPDistributeDirective(CurrDir)) && 13717 !isOpenMPParallelDirective(CurrDir) && 13718 !isOpenMPTeamsDirective(CurrDir)) { 13719 DVar = DSAStack->getImplicitDSA(D, true); 13720 if (DVar.CKind != OMPC_shared && 13721 (isOpenMPParallelDirective(DVar.DKind) || 13722 isOpenMPTeamsDirective(DVar.DKind) || 13723 DVar.DKind == OMPD_unknown)) { 13724 Diag(ELoc, diag::err_omp_required_access) 13725 << getOpenMPClauseName(OMPC_firstprivate) 13726 << getOpenMPClauseName(OMPC_shared); 13727 reportOriginalDsa(*this, DSAStack, D, DVar); 13728 continue; 13729 } 13730 } 13731 // OpenMP [2.9.3.4, Restrictions, p.3] 13732 // A list item that appears in a reduction clause of a parallel construct 13733 // must not appear in a firstprivate clause on a worksharing or task 13734 // construct if any of the worksharing or task regions arising from the 13735 // worksharing or task construct ever bind to any of the parallel regions 13736 // arising from the parallel construct. 13737 // OpenMP [2.9.3.4, Restrictions, p.4] 13738 // A list item that appears in a reduction clause in worksharing 13739 // construct must not appear in a firstprivate clause in a task construct 13740 // encountered during execution of any of the worksharing regions arising 13741 // from the worksharing construct. 13742 if (isOpenMPTaskingDirective(CurrDir)) { 13743 DVar = DSAStack->hasInnermostDSA( 13744 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 13745 [](OpenMPDirectiveKind K) { 13746 return isOpenMPParallelDirective(K) || 13747 isOpenMPWorksharingDirective(K) || 13748 isOpenMPTeamsDirective(K); 13749 }, 13750 /*FromParent=*/true); 13751 if (DVar.CKind == OMPC_reduction && 13752 (isOpenMPParallelDirective(DVar.DKind) || 13753 isOpenMPWorksharingDirective(DVar.DKind) || 13754 isOpenMPTeamsDirective(DVar.DKind))) { 13755 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 13756 << getOpenMPDirectiveName(DVar.DKind); 13757 reportOriginalDsa(*this, DSAStack, D, DVar); 13758 continue; 13759 } 13760 } 13761 13762 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13763 // A list item cannot appear in both a map clause and a data-sharing 13764 // attribute clause on the same construct 13765 // 13766 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 13767 // A list item cannot appear in both a map clause and a data-sharing 13768 // attribute clause on the same construct unless the construct is a 13769 // combined construct. 13770 if ((LangOpts.OpenMP <= 45 && 13771 isOpenMPTargetExecutionDirective(CurrDir)) || 13772 CurrDir == OMPD_target) { 13773 OpenMPClauseKind ConflictKind; 13774 if (DSAStack->checkMappableExprComponentListsForDecl( 13775 VD, /*CurrentRegionOnly=*/true, 13776 [&ConflictKind]( 13777 OMPClauseMappableExprCommon::MappableExprComponentListRef, 13778 OpenMPClauseKind WhereFoundClauseKind) { 13779 ConflictKind = WhereFoundClauseKind; 13780 return true; 13781 })) { 13782 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13783 << getOpenMPClauseName(OMPC_firstprivate) 13784 << getOpenMPClauseName(ConflictKind) 13785 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13786 reportOriginalDsa(*this, DSAStack, D, DVar); 13787 continue; 13788 } 13789 } 13790 } 13791 13792 // Variably modified types are not supported for tasks. 13793 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 13794 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 13795 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 13796 << getOpenMPClauseName(OMPC_firstprivate) << Type 13797 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 13798 bool IsDecl = 13799 !VD || 13800 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 13801 Diag(D->getLocation(), 13802 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13803 << D; 13804 continue; 13805 } 13806 13807 Type = Type.getUnqualifiedType(); 13808 VarDecl *VDPrivate = 13809 buildVarDecl(*this, ELoc, Type, D->getName(), 13810 D->hasAttrs() ? &D->getAttrs() : nullptr, 13811 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 13812 // Generate helper private variable and initialize it with the value of the 13813 // original variable. The address of the original variable is replaced by 13814 // the address of the new private variable in the CodeGen. This new variable 13815 // is not added to IdResolver, so the code in the OpenMP region uses 13816 // original variable for proper diagnostics and variable capturing. 13817 Expr *VDInitRefExpr = nullptr; 13818 // For arrays generate initializer for single element and replace it by the 13819 // original array element in CodeGen. 13820 if (Type->isArrayType()) { 13821 VarDecl *VDInit = 13822 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 13823 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 13824 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 13825 ElemType = ElemType.getUnqualifiedType(); 13826 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 13827 ".firstprivate.temp"); 13828 InitializedEntity Entity = 13829 InitializedEntity::InitializeVariable(VDInitTemp); 13830 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 13831 13832 InitializationSequence InitSeq(*this, Entity, Kind, Init); 13833 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 13834 if (Result.isInvalid()) 13835 VDPrivate->setInvalidDecl(); 13836 else 13837 VDPrivate->setInit(Result.getAs<Expr>()); 13838 // Remove temp variable declaration. 13839 Context.Deallocate(VDInitTemp); 13840 } else { 13841 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 13842 ".firstprivate.temp"); 13843 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 13844 RefExpr->getExprLoc()); 13845 AddInitializerToDecl(VDPrivate, 13846 DefaultLvalueConversion(VDInitRefExpr).get(), 13847 /*DirectInit=*/false); 13848 } 13849 if (VDPrivate->isInvalidDecl()) { 13850 if (IsImplicitClause) { 13851 Diag(RefExpr->getExprLoc(), 13852 diag::note_omp_task_predetermined_firstprivate_here); 13853 } 13854 continue; 13855 } 13856 CurContext->addDecl(VDPrivate); 13857 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 13858 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 13859 RefExpr->getExprLoc()); 13860 DeclRefExpr *Ref = nullptr; 13861 if (!VD && !CurContext->isDependentContext()) { 13862 if (TopDVar.CKind == OMPC_lastprivate) { 13863 Ref = TopDVar.PrivateCopy; 13864 } else { 13865 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 13866 if (!isOpenMPCapturedDecl(D)) 13867 ExprCaptures.push_back(Ref->getDecl()); 13868 } 13869 } 13870 if (!IsImplicitClause) 13871 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 13872 Vars.push_back((VD || CurContext->isDependentContext()) 13873 ? RefExpr->IgnoreParens() 13874 : Ref); 13875 PrivateCopies.push_back(VDPrivateRefExpr); 13876 Inits.push_back(VDInitRefExpr); 13877 } 13878 13879 if (Vars.empty()) 13880 return nullptr; 13881 13882 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 13883 Vars, PrivateCopies, Inits, 13884 buildPreInits(Context, ExprCaptures)); 13885 } 13886 13887 OMPClause *Sema::ActOnOpenMPLastprivateClause( 13888 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 13889 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 13890 SourceLocation LParenLoc, SourceLocation EndLoc) { 13891 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 13892 assert(ColonLoc.isValid() && "Colon location must be valid."); 13893 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 13894 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 13895 /*Last=*/OMPC_LASTPRIVATE_unknown) 13896 << getOpenMPClauseName(OMPC_lastprivate); 13897 return nullptr; 13898 } 13899 13900 SmallVector<Expr *, 8> Vars; 13901 SmallVector<Expr *, 8> SrcExprs; 13902 SmallVector<Expr *, 8> DstExprs; 13903 SmallVector<Expr *, 8> AssignmentOps; 13904 SmallVector<Decl *, 4> ExprCaptures; 13905 SmallVector<Expr *, 4> ExprPostUpdates; 13906 for (Expr *RefExpr : VarList) { 13907 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 13908 SourceLocation ELoc; 13909 SourceRange ERange; 13910 Expr *SimpleRefExpr = RefExpr; 13911 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 13912 if (Res.second) { 13913 // It will be analyzed later. 13914 Vars.push_back(RefExpr); 13915 SrcExprs.push_back(nullptr); 13916 DstExprs.push_back(nullptr); 13917 AssignmentOps.push_back(nullptr); 13918 } 13919 ValueDecl *D = Res.first; 13920 if (!D) 13921 continue; 13922 13923 QualType Type = D->getType(); 13924 auto *VD = dyn_cast<VarDecl>(D); 13925 13926 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 13927 // A variable that appears in a lastprivate clause must not have an 13928 // incomplete type or a reference type. 13929 if (RequireCompleteType(ELoc, Type, 13930 diag::err_omp_lastprivate_incomplete_type)) 13931 continue; 13932 Type = Type.getNonReferenceType(); 13933 13934 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 13935 // A variable that is privatized must not have a const-qualified type 13936 // unless it is of class type with a mutable member. This restriction does 13937 // not apply to the firstprivate clause. 13938 // 13939 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 13940 // A variable that appears in a lastprivate clause must not have a 13941 // const-qualified type unless it is of class type with a mutable member. 13942 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 13943 continue; 13944 13945 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 13946 // A list item that appears in a lastprivate clause with the conditional 13947 // modifier must be a scalar variable. 13948 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 13949 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 13950 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 13951 VarDecl::DeclarationOnly; 13952 Diag(D->getLocation(), 13953 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 13954 << D; 13955 continue; 13956 } 13957 13958 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 13959 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 13960 // in a Construct] 13961 // Variables with the predetermined data-sharing attributes may not be 13962 // listed in data-sharing attributes clauses, except for the cases 13963 // listed below. 13964 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 13965 // A list item may appear in a firstprivate or lastprivate clause but not 13966 // both. 13967 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 13968 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 13969 (isOpenMPDistributeDirective(CurrDir) || 13970 DVar.CKind != OMPC_firstprivate) && 13971 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 13972 Diag(ELoc, diag::err_omp_wrong_dsa) 13973 << getOpenMPClauseName(DVar.CKind) 13974 << getOpenMPClauseName(OMPC_lastprivate); 13975 reportOriginalDsa(*this, DSAStack, D, DVar); 13976 continue; 13977 } 13978 13979 // OpenMP [2.14.3.5, Restrictions, p.2] 13980 // A list item that is private within a parallel region, or that appears in 13981 // the reduction clause of a parallel construct, must not appear in a 13982 // lastprivate clause on a worksharing construct if any of the corresponding 13983 // worksharing regions ever binds to any of the corresponding parallel 13984 // regions. 13985 DSAStackTy::DSAVarData TopDVar = DVar; 13986 if (isOpenMPWorksharingDirective(CurrDir) && 13987 !isOpenMPParallelDirective(CurrDir) && 13988 !isOpenMPTeamsDirective(CurrDir)) { 13989 DVar = DSAStack->getImplicitDSA(D, true); 13990 if (DVar.CKind != OMPC_shared) { 13991 Diag(ELoc, diag::err_omp_required_access) 13992 << getOpenMPClauseName(OMPC_lastprivate) 13993 << getOpenMPClauseName(OMPC_shared); 13994 reportOriginalDsa(*this, DSAStack, D, DVar); 13995 continue; 13996 } 13997 } 13998 13999 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 14000 // A variable of class type (or array thereof) that appears in a 14001 // lastprivate clause requires an accessible, unambiguous default 14002 // constructor for the class type, unless the list item is also specified 14003 // in a firstprivate clause. 14004 // A variable of class type (or array thereof) that appears in a 14005 // lastprivate clause requires an accessible, unambiguous copy assignment 14006 // operator for the class type. 14007 Type = Context.getBaseElementType(Type).getNonReferenceType(); 14008 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 14009 Type.getUnqualifiedType(), ".lastprivate.src", 14010 D->hasAttrs() ? &D->getAttrs() : nullptr); 14011 DeclRefExpr *PseudoSrcExpr = 14012 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 14013 VarDecl *DstVD = 14014 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 14015 D->hasAttrs() ? &D->getAttrs() : nullptr); 14016 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 14017 // For arrays generate assignment operation for single element and replace 14018 // it by the original array element in CodeGen. 14019 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 14020 PseudoDstExpr, PseudoSrcExpr); 14021 if (AssignmentOp.isInvalid()) 14022 continue; 14023 AssignmentOp = 14024 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 14025 if (AssignmentOp.isInvalid()) 14026 continue; 14027 14028 DeclRefExpr *Ref = nullptr; 14029 if (!VD && !CurContext->isDependentContext()) { 14030 if (TopDVar.CKind == OMPC_firstprivate) { 14031 Ref = TopDVar.PrivateCopy; 14032 } else { 14033 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 14034 if (!isOpenMPCapturedDecl(D)) 14035 ExprCaptures.push_back(Ref->getDecl()); 14036 } 14037 if (TopDVar.CKind == OMPC_firstprivate || 14038 (!isOpenMPCapturedDecl(D) && 14039 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 14040 ExprResult RefRes = DefaultLvalueConversion(Ref); 14041 if (!RefRes.isUsable()) 14042 continue; 14043 ExprResult PostUpdateRes = 14044 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 14045 RefRes.get()); 14046 if (!PostUpdateRes.isUsable()) 14047 continue; 14048 ExprPostUpdates.push_back( 14049 IgnoredValueConversions(PostUpdateRes.get()).get()); 14050 } 14051 } 14052 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 14053 Vars.push_back((VD || CurContext->isDependentContext()) 14054 ? RefExpr->IgnoreParens() 14055 : Ref); 14056 SrcExprs.push_back(PseudoSrcExpr); 14057 DstExprs.push_back(PseudoDstExpr); 14058 AssignmentOps.push_back(AssignmentOp.get()); 14059 } 14060 14061 if (Vars.empty()) 14062 return nullptr; 14063 14064 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 14065 Vars, SrcExprs, DstExprs, AssignmentOps, 14066 LPKind, LPKindLoc, ColonLoc, 14067 buildPreInits(Context, ExprCaptures), 14068 buildPostUpdate(*this, ExprPostUpdates)); 14069 } 14070 14071 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 14072 SourceLocation StartLoc, 14073 SourceLocation LParenLoc, 14074 SourceLocation EndLoc) { 14075 SmallVector<Expr *, 8> Vars; 14076 for (Expr *RefExpr : VarList) { 14077 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 14078 SourceLocation ELoc; 14079 SourceRange ERange; 14080 Expr *SimpleRefExpr = RefExpr; 14081 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14082 if (Res.second) { 14083 // It will be analyzed later. 14084 Vars.push_back(RefExpr); 14085 } 14086 ValueDecl *D = Res.first; 14087 if (!D) 14088 continue; 14089 14090 auto *VD = dyn_cast<VarDecl>(D); 14091 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 14092 // in a Construct] 14093 // Variables with the predetermined data-sharing attributes may not be 14094 // listed in data-sharing attributes clauses, except for the cases 14095 // listed below. For these exceptions only, listing a predetermined 14096 // variable in a data-sharing attribute clause is allowed and overrides 14097 // the variable's predetermined data-sharing attributes. 14098 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14099 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 14100 DVar.RefExpr) { 14101 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 14102 << getOpenMPClauseName(OMPC_shared); 14103 reportOriginalDsa(*this, DSAStack, D, DVar); 14104 continue; 14105 } 14106 14107 DeclRefExpr *Ref = nullptr; 14108 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 14109 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14110 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 14111 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 14112 ? RefExpr->IgnoreParens() 14113 : Ref); 14114 } 14115 14116 if (Vars.empty()) 14117 return nullptr; 14118 14119 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 14120 } 14121 14122 namespace { 14123 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 14124 DSAStackTy *Stack; 14125 14126 public: 14127 bool VisitDeclRefExpr(DeclRefExpr *E) { 14128 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 14129 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 14130 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 14131 return false; 14132 if (DVar.CKind != OMPC_unknown) 14133 return true; 14134 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 14135 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 14136 /*FromParent=*/true); 14137 return DVarPrivate.CKind != OMPC_unknown; 14138 } 14139 return false; 14140 } 14141 bool VisitStmt(Stmt *S) { 14142 for (Stmt *Child : S->children()) { 14143 if (Child && Visit(Child)) 14144 return true; 14145 } 14146 return false; 14147 } 14148 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 14149 }; 14150 } // namespace 14151 14152 namespace { 14153 // Transform MemberExpression for specified FieldDecl of current class to 14154 // DeclRefExpr to specified OMPCapturedExprDecl. 14155 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 14156 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 14157 ValueDecl *Field = nullptr; 14158 DeclRefExpr *CapturedExpr = nullptr; 14159 14160 public: 14161 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 14162 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 14163 14164 ExprResult TransformMemberExpr(MemberExpr *E) { 14165 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 14166 E->getMemberDecl() == Field) { 14167 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 14168 return CapturedExpr; 14169 } 14170 return BaseTransform::TransformMemberExpr(E); 14171 } 14172 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 14173 }; 14174 } // namespace 14175 14176 template <typename T, typename U> 14177 static T filterLookupForUDReductionAndMapper( 14178 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 14179 for (U &Set : Lookups) { 14180 for (auto *D : Set) { 14181 if (T Res = Gen(cast<ValueDecl>(D))) 14182 return Res; 14183 } 14184 } 14185 return T(); 14186 } 14187 14188 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 14189 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 14190 14191 for (auto RD : D->redecls()) { 14192 // Don't bother with extra checks if we already know this one isn't visible. 14193 if (RD == D) 14194 continue; 14195 14196 auto ND = cast<NamedDecl>(RD); 14197 if (LookupResult::isVisible(SemaRef, ND)) 14198 return ND; 14199 } 14200 14201 return nullptr; 14202 } 14203 14204 static void 14205 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 14206 SourceLocation Loc, QualType Ty, 14207 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 14208 // Find all of the associated namespaces and classes based on the 14209 // arguments we have. 14210 Sema::AssociatedNamespaceSet AssociatedNamespaces; 14211 Sema::AssociatedClassSet AssociatedClasses; 14212 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 14213 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 14214 AssociatedClasses); 14215 14216 // C++ [basic.lookup.argdep]p3: 14217 // Let X be the lookup set produced by unqualified lookup (3.4.1) 14218 // and let Y be the lookup set produced by argument dependent 14219 // lookup (defined as follows). If X contains [...] then Y is 14220 // empty. Otherwise Y is the set of declarations found in the 14221 // namespaces associated with the argument types as described 14222 // below. The set of declarations found by the lookup of the name 14223 // is the union of X and Y. 14224 // 14225 // Here, we compute Y and add its members to the overloaded 14226 // candidate set. 14227 for (auto *NS : AssociatedNamespaces) { 14228 // When considering an associated namespace, the lookup is the 14229 // same as the lookup performed when the associated namespace is 14230 // used as a qualifier (3.4.3.2) except that: 14231 // 14232 // -- Any using-directives in the associated namespace are 14233 // ignored. 14234 // 14235 // -- Any namespace-scope friend functions declared in 14236 // associated classes are visible within their respective 14237 // namespaces even if they are not visible during an ordinary 14238 // lookup (11.4). 14239 DeclContext::lookup_result R = NS->lookup(Id.getName()); 14240 for (auto *D : R) { 14241 auto *Underlying = D; 14242 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14243 Underlying = USD->getTargetDecl(); 14244 14245 if (!isa<OMPDeclareReductionDecl>(Underlying) && 14246 !isa<OMPDeclareMapperDecl>(Underlying)) 14247 continue; 14248 14249 if (!SemaRef.isVisible(D)) { 14250 D = findAcceptableDecl(SemaRef, D); 14251 if (!D) 14252 continue; 14253 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 14254 Underlying = USD->getTargetDecl(); 14255 } 14256 Lookups.emplace_back(); 14257 Lookups.back().addDecl(Underlying); 14258 } 14259 } 14260 } 14261 14262 static ExprResult 14263 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 14264 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 14265 const DeclarationNameInfo &ReductionId, QualType Ty, 14266 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 14267 if (ReductionIdScopeSpec.isInvalid()) 14268 return ExprError(); 14269 SmallVector<UnresolvedSet<8>, 4> Lookups; 14270 if (S) { 14271 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14272 Lookup.suppressDiagnostics(); 14273 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 14274 NamedDecl *D = Lookup.getRepresentativeDecl(); 14275 do { 14276 S = S->getParent(); 14277 } while (S && !S->isDeclScope(D)); 14278 if (S) 14279 S = S->getParent(); 14280 Lookups.emplace_back(); 14281 Lookups.back().append(Lookup.begin(), Lookup.end()); 14282 Lookup.clear(); 14283 } 14284 } else if (auto *ULE = 14285 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 14286 Lookups.push_back(UnresolvedSet<8>()); 14287 Decl *PrevD = nullptr; 14288 for (NamedDecl *D : ULE->decls()) { 14289 if (D == PrevD) 14290 Lookups.push_back(UnresolvedSet<8>()); 14291 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 14292 Lookups.back().addDecl(DRD); 14293 PrevD = D; 14294 } 14295 } 14296 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 14297 Ty->isInstantiationDependentType() || 14298 Ty->containsUnexpandedParameterPack() || 14299 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 14300 return !D->isInvalidDecl() && 14301 (D->getType()->isDependentType() || 14302 D->getType()->isInstantiationDependentType() || 14303 D->getType()->containsUnexpandedParameterPack()); 14304 })) { 14305 UnresolvedSet<8> ResSet; 14306 for (const UnresolvedSet<8> &Set : Lookups) { 14307 if (Set.empty()) 14308 continue; 14309 ResSet.append(Set.begin(), Set.end()); 14310 // The last item marks the end of all declarations at the specified scope. 14311 ResSet.addDecl(Set[Set.size() - 1]); 14312 } 14313 return UnresolvedLookupExpr::Create( 14314 SemaRef.Context, /*NamingClass=*/nullptr, 14315 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 14316 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 14317 } 14318 // Lookup inside the classes. 14319 // C++ [over.match.oper]p3: 14320 // For a unary operator @ with an operand of a type whose 14321 // cv-unqualified version is T1, and for a binary operator @ with 14322 // a left operand of a type whose cv-unqualified version is T1 and 14323 // a right operand of a type whose cv-unqualified version is T2, 14324 // three sets of candidate functions, designated member 14325 // candidates, non-member candidates and built-in candidates, are 14326 // constructed as follows: 14327 // -- If T1 is a complete class type or a class currently being 14328 // defined, the set of member candidates is the result of the 14329 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 14330 // the set of member candidates is empty. 14331 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 14332 Lookup.suppressDiagnostics(); 14333 if (const auto *TyRec = Ty->getAs<RecordType>()) { 14334 // Complete the type if it can be completed. 14335 // If the type is neither complete nor being defined, bail out now. 14336 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 14337 TyRec->getDecl()->getDefinition()) { 14338 Lookup.clear(); 14339 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 14340 if (Lookup.empty()) { 14341 Lookups.emplace_back(); 14342 Lookups.back().append(Lookup.begin(), Lookup.end()); 14343 } 14344 } 14345 } 14346 // Perform ADL. 14347 if (SemaRef.getLangOpts().CPlusPlus) 14348 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 14349 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14350 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 14351 if (!D->isInvalidDecl() && 14352 SemaRef.Context.hasSameType(D->getType(), Ty)) 14353 return D; 14354 return nullptr; 14355 })) 14356 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 14357 VK_LValue, Loc); 14358 if (SemaRef.getLangOpts().CPlusPlus) { 14359 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 14360 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 14361 if (!D->isInvalidDecl() && 14362 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 14363 !Ty.isMoreQualifiedThan(D->getType())) 14364 return D; 14365 return nullptr; 14366 })) { 14367 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 14368 /*DetectVirtual=*/false); 14369 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 14370 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 14371 VD->getType().getUnqualifiedType()))) { 14372 if (SemaRef.CheckBaseClassAccess( 14373 Loc, VD->getType(), Ty, Paths.front(), 14374 /*DiagID=*/0) != Sema::AR_inaccessible) { 14375 SemaRef.BuildBasePathArray(Paths, BasePath); 14376 return SemaRef.BuildDeclRefExpr( 14377 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 14378 } 14379 } 14380 } 14381 } 14382 } 14383 if (ReductionIdScopeSpec.isSet()) { 14384 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 14385 << Ty << Range; 14386 return ExprError(); 14387 } 14388 return ExprEmpty(); 14389 } 14390 14391 namespace { 14392 /// Data for the reduction-based clauses. 14393 struct ReductionData { 14394 /// List of original reduction items. 14395 SmallVector<Expr *, 8> Vars; 14396 /// List of private copies of the reduction items. 14397 SmallVector<Expr *, 8> Privates; 14398 /// LHS expressions for the reduction_op expressions. 14399 SmallVector<Expr *, 8> LHSs; 14400 /// RHS expressions for the reduction_op expressions. 14401 SmallVector<Expr *, 8> RHSs; 14402 /// Reduction operation expression. 14403 SmallVector<Expr *, 8> ReductionOps; 14404 /// Taskgroup descriptors for the corresponding reduction items in 14405 /// in_reduction clauses. 14406 SmallVector<Expr *, 8> TaskgroupDescriptors; 14407 /// List of captures for clause. 14408 SmallVector<Decl *, 4> ExprCaptures; 14409 /// List of postupdate expressions. 14410 SmallVector<Expr *, 4> ExprPostUpdates; 14411 /// Reduction modifier. 14412 unsigned RedModifier = 0; 14413 ReductionData() = delete; 14414 /// Reserves required memory for the reduction data. 14415 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 14416 Vars.reserve(Size); 14417 Privates.reserve(Size); 14418 LHSs.reserve(Size); 14419 RHSs.reserve(Size); 14420 ReductionOps.reserve(Size); 14421 TaskgroupDescriptors.reserve(Size); 14422 ExprCaptures.reserve(Size); 14423 ExprPostUpdates.reserve(Size); 14424 } 14425 /// Stores reduction item and reduction operation only (required for dependent 14426 /// reduction item). 14427 void push(Expr *Item, Expr *ReductionOp) { 14428 Vars.emplace_back(Item); 14429 Privates.emplace_back(nullptr); 14430 LHSs.emplace_back(nullptr); 14431 RHSs.emplace_back(nullptr); 14432 ReductionOps.emplace_back(ReductionOp); 14433 TaskgroupDescriptors.emplace_back(nullptr); 14434 } 14435 /// Stores reduction data. 14436 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 14437 Expr *TaskgroupDescriptor) { 14438 Vars.emplace_back(Item); 14439 Privates.emplace_back(Private); 14440 LHSs.emplace_back(LHS); 14441 RHSs.emplace_back(RHS); 14442 ReductionOps.emplace_back(ReductionOp); 14443 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 14444 } 14445 }; 14446 } // namespace 14447 14448 static bool checkOMPArraySectionConstantForReduction( 14449 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 14450 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 14451 const Expr *Length = OASE->getLength(); 14452 if (Length == nullptr) { 14453 // For array sections of the form [1:] or [:], we would need to analyze 14454 // the lower bound... 14455 if (OASE->getColonLoc().isValid()) 14456 return false; 14457 14458 // This is an array subscript which has implicit length 1! 14459 SingleElement = true; 14460 ArraySizes.push_back(llvm::APSInt::get(1)); 14461 } else { 14462 Expr::EvalResult Result; 14463 if (!Length->EvaluateAsInt(Result, Context)) 14464 return false; 14465 14466 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14467 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 14468 ArraySizes.push_back(ConstantLengthValue); 14469 } 14470 14471 // Get the base of this array section and walk up from there. 14472 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 14473 14474 // We require length = 1 for all array sections except the right-most to 14475 // guarantee that the memory region is contiguous and has no holes in it. 14476 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 14477 Length = TempOASE->getLength(); 14478 if (Length == nullptr) { 14479 // For array sections of the form [1:] or [:], we would need to analyze 14480 // the lower bound... 14481 if (OASE->getColonLoc().isValid()) 14482 return false; 14483 14484 // This is an array subscript which has implicit length 1! 14485 ArraySizes.push_back(llvm::APSInt::get(1)); 14486 } else { 14487 Expr::EvalResult Result; 14488 if (!Length->EvaluateAsInt(Result, Context)) 14489 return false; 14490 14491 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 14492 if (ConstantLengthValue.getSExtValue() != 1) 14493 return false; 14494 14495 ArraySizes.push_back(ConstantLengthValue); 14496 } 14497 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 14498 } 14499 14500 // If we have a single element, we don't need to add the implicit lengths. 14501 if (!SingleElement) { 14502 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 14503 // Has implicit length 1! 14504 ArraySizes.push_back(llvm::APSInt::get(1)); 14505 Base = TempASE->getBase()->IgnoreParenImpCasts(); 14506 } 14507 } 14508 14509 // This array section can be privatized as a single value or as a constant 14510 // sized array. 14511 return true; 14512 } 14513 14514 static bool actOnOMPReductionKindClause( 14515 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 14516 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 14517 SourceLocation ColonLoc, SourceLocation EndLoc, 14518 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 14519 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 14520 DeclarationName DN = ReductionId.getName(); 14521 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 14522 BinaryOperatorKind BOK = BO_Comma; 14523 14524 ASTContext &Context = S.Context; 14525 // OpenMP [2.14.3.6, reduction clause] 14526 // C 14527 // reduction-identifier is either an identifier or one of the following 14528 // operators: +, -, *, &, |, ^, && and || 14529 // C++ 14530 // reduction-identifier is either an id-expression or one of the following 14531 // operators: +, -, *, &, |, ^, && and || 14532 switch (OOK) { 14533 case OO_Plus: 14534 case OO_Minus: 14535 BOK = BO_Add; 14536 break; 14537 case OO_Star: 14538 BOK = BO_Mul; 14539 break; 14540 case OO_Amp: 14541 BOK = BO_And; 14542 break; 14543 case OO_Pipe: 14544 BOK = BO_Or; 14545 break; 14546 case OO_Caret: 14547 BOK = BO_Xor; 14548 break; 14549 case OO_AmpAmp: 14550 BOK = BO_LAnd; 14551 break; 14552 case OO_PipePipe: 14553 BOK = BO_LOr; 14554 break; 14555 case OO_New: 14556 case OO_Delete: 14557 case OO_Array_New: 14558 case OO_Array_Delete: 14559 case OO_Slash: 14560 case OO_Percent: 14561 case OO_Tilde: 14562 case OO_Exclaim: 14563 case OO_Equal: 14564 case OO_Less: 14565 case OO_Greater: 14566 case OO_LessEqual: 14567 case OO_GreaterEqual: 14568 case OO_PlusEqual: 14569 case OO_MinusEqual: 14570 case OO_StarEqual: 14571 case OO_SlashEqual: 14572 case OO_PercentEqual: 14573 case OO_CaretEqual: 14574 case OO_AmpEqual: 14575 case OO_PipeEqual: 14576 case OO_LessLess: 14577 case OO_GreaterGreater: 14578 case OO_LessLessEqual: 14579 case OO_GreaterGreaterEqual: 14580 case OO_EqualEqual: 14581 case OO_ExclaimEqual: 14582 case OO_Spaceship: 14583 case OO_PlusPlus: 14584 case OO_MinusMinus: 14585 case OO_Comma: 14586 case OO_ArrowStar: 14587 case OO_Arrow: 14588 case OO_Call: 14589 case OO_Subscript: 14590 case OO_Conditional: 14591 case OO_Coawait: 14592 case NUM_OVERLOADED_OPERATORS: 14593 llvm_unreachable("Unexpected reduction identifier"); 14594 case OO_None: 14595 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 14596 if (II->isStr("max")) 14597 BOK = BO_GT; 14598 else if (II->isStr("min")) 14599 BOK = BO_LT; 14600 } 14601 break; 14602 } 14603 SourceRange ReductionIdRange; 14604 if (ReductionIdScopeSpec.isValid()) 14605 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 14606 else 14607 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 14608 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 14609 14610 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 14611 bool FirstIter = true; 14612 for (Expr *RefExpr : VarList) { 14613 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 14614 // OpenMP [2.1, C/C++] 14615 // A list item is a variable or array section, subject to the restrictions 14616 // specified in Section 2.4 on page 42 and in each of the sections 14617 // describing clauses and directives for which a list appears. 14618 // OpenMP [2.14.3.3, Restrictions, p.1] 14619 // A variable that is part of another variable (as an array or 14620 // structure element) cannot appear in a private clause. 14621 if (!FirstIter && IR != ER) 14622 ++IR; 14623 FirstIter = false; 14624 SourceLocation ELoc; 14625 SourceRange ERange; 14626 Expr *SimpleRefExpr = RefExpr; 14627 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 14628 /*AllowArraySection=*/true); 14629 if (Res.second) { 14630 // Try to find 'declare reduction' corresponding construct before using 14631 // builtin/overloaded operators. 14632 QualType Type = Context.DependentTy; 14633 CXXCastPath BasePath; 14634 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14635 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14636 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14637 Expr *ReductionOp = nullptr; 14638 if (S.CurContext->isDependentContext() && 14639 (DeclareReductionRef.isUnset() || 14640 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 14641 ReductionOp = DeclareReductionRef.get(); 14642 // It will be analyzed later. 14643 RD.push(RefExpr, ReductionOp); 14644 } 14645 ValueDecl *D = Res.first; 14646 if (!D) 14647 continue; 14648 14649 Expr *TaskgroupDescriptor = nullptr; 14650 QualType Type; 14651 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 14652 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 14653 if (ASE) { 14654 Type = ASE->getType().getNonReferenceType(); 14655 } else if (OASE) { 14656 QualType BaseType = 14657 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 14658 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 14659 Type = ATy->getElementType(); 14660 else 14661 Type = BaseType->getPointeeType(); 14662 Type = Type.getNonReferenceType(); 14663 } else { 14664 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 14665 } 14666 auto *VD = dyn_cast<VarDecl>(D); 14667 14668 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 14669 // A variable that appears in a private clause must not have an incomplete 14670 // type or a reference type. 14671 if (S.RequireCompleteType(ELoc, D->getType(), 14672 diag::err_omp_reduction_incomplete_type)) 14673 continue; 14674 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14675 // A list item that appears in a reduction clause must not be 14676 // const-qualified. 14677 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 14678 /*AcceptIfMutable*/ false, ASE || OASE)) 14679 continue; 14680 14681 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 14682 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 14683 // If a list-item is a reference type then it must bind to the same object 14684 // for all threads of the team. 14685 if (!ASE && !OASE) { 14686 if (VD) { 14687 VarDecl *VDDef = VD->getDefinition(); 14688 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 14689 DSARefChecker Check(Stack); 14690 if (Check.Visit(VDDef->getInit())) { 14691 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 14692 << getOpenMPClauseName(ClauseKind) << ERange; 14693 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 14694 continue; 14695 } 14696 } 14697 } 14698 14699 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 14700 // in a Construct] 14701 // Variables with the predetermined data-sharing attributes may not be 14702 // listed in data-sharing attributes clauses, except for the cases 14703 // listed below. For these exceptions only, listing a predetermined 14704 // variable in a data-sharing attribute clause is allowed and overrides 14705 // the variable's predetermined data-sharing attributes. 14706 // OpenMP [2.14.3.6, Restrictions, p.3] 14707 // Any number of reduction clauses can be specified on the directive, 14708 // but a list item can appear only once in the reduction clauses for that 14709 // directive. 14710 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 14711 if (DVar.CKind == OMPC_reduction) { 14712 S.Diag(ELoc, diag::err_omp_once_referenced) 14713 << getOpenMPClauseName(ClauseKind); 14714 if (DVar.RefExpr) 14715 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 14716 continue; 14717 } 14718 if (DVar.CKind != OMPC_unknown) { 14719 S.Diag(ELoc, diag::err_omp_wrong_dsa) 14720 << getOpenMPClauseName(DVar.CKind) 14721 << getOpenMPClauseName(OMPC_reduction); 14722 reportOriginalDsa(S, Stack, D, DVar); 14723 continue; 14724 } 14725 14726 // OpenMP [2.14.3.6, Restrictions, p.1] 14727 // A list item that appears in a reduction clause of a worksharing 14728 // construct must be shared in the parallel regions to which any of the 14729 // worksharing regions arising from the worksharing construct bind. 14730 if (isOpenMPWorksharingDirective(CurrDir) && 14731 !isOpenMPParallelDirective(CurrDir) && 14732 !isOpenMPTeamsDirective(CurrDir)) { 14733 DVar = Stack->getImplicitDSA(D, true); 14734 if (DVar.CKind != OMPC_shared) { 14735 S.Diag(ELoc, diag::err_omp_required_access) 14736 << getOpenMPClauseName(OMPC_reduction) 14737 << getOpenMPClauseName(OMPC_shared); 14738 reportOriginalDsa(S, Stack, D, DVar); 14739 continue; 14740 } 14741 } 14742 } 14743 14744 // Try to find 'declare reduction' corresponding construct before using 14745 // builtin/overloaded operators. 14746 CXXCastPath BasePath; 14747 ExprResult DeclareReductionRef = buildDeclareReductionRef( 14748 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 14749 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 14750 if (DeclareReductionRef.isInvalid()) 14751 continue; 14752 if (S.CurContext->isDependentContext() && 14753 (DeclareReductionRef.isUnset() || 14754 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 14755 RD.push(RefExpr, DeclareReductionRef.get()); 14756 continue; 14757 } 14758 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 14759 // Not allowed reduction identifier is found. 14760 S.Diag(ReductionId.getBeginLoc(), 14761 diag::err_omp_unknown_reduction_identifier) 14762 << Type << ReductionIdRange; 14763 continue; 14764 } 14765 14766 // OpenMP [2.14.3.6, reduction clause, Restrictions] 14767 // The type of a list item that appears in a reduction clause must be valid 14768 // for the reduction-identifier. For a max or min reduction in C, the type 14769 // of the list item must be an allowed arithmetic data type: char, int, 14770 // float, double, or _Bool, possibly modified with long, short, signed, or 14771 // unsigned. For a max or min reduction in C++, the type of the list item 14772 // must be an allowed arithmetic data type: char, wchar_t, int, float, 14773 // double, or bool, possibly modified with long, short, signed, or unsigned. 14774 if (DeclareReductionRef.isUnset()) { 14775 if ((BOK == BO_GT || BOK == BO_LT) && 14776 !(Type->isScalarType() || 14777 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 14778 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 14779 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 14780 if (!ASE && !OASE) { 14781 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14782 VarDecl::DeclarationOnly; 14783 S.Diag(D->getLocation(), 14784 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14785 << D; 14786 } 14787 continue; 14788 } 14789 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 14790 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 14791 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 14792 << getOpenMPClauseName(ClauseKind); 14793 if (!ASE && !OASE) { 14794 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14795 VarDecl::DeclarationOnly; 14796 S.Diag(D->getLocation(), 14797 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14798 << D; 14799 } 14800 continue; 14801 } 14802 } 14803 14804 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 14805 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 14806 D->hasAttrs() ? &D->getAttrs() : nullptr); 14807 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 14808 D->hasAttrs() ? &D->getAttrs() : nullptr); 14809 QualType PrivateTy = Type; 14810 14811 // Try if we can determine constant lengths for all array sections and avoid 14812 // the VLA. 14813 bool ConstantLengthOASE = false; 14814 if (OASE) { 14815 bool SingleElement; 14816 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 14817 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 14818 Context, OASE, SingleElement, ArraySizes); 14819 14820 // If we don't have a single element, we must emit a constant array type. 14821 if (ConstantLengthOASE && !SingleElement) { 14822 for (llvm::APSInt &Size : ArraySizes) 14823 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 14824 ArrayType::Normal, 14825 /*IndexTypeQuals=*/0); 14826 } 14827 } 14828 14829 if ((OASE && !ConstantLengthOASE) || 14830 (!OASE && !ASE && 14831 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 14832 if (!Context.getTargetInfo().isVLASupported()) { 14833 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 14834 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14835 S.Diag(ELoc, diag::note_vla_unsupported); 14836 } else { 14837 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 14838 S.targetDiag(ELoc, diag::note_vla_unsupported); 14839 } 14840 continue; 14841 } 14842 // For arrays/array sections only: 14843 // Create pseudo array type for private copy. The size for this array will 14844 // be generated during codegen. 14845 // For array subscripts or single variables Private Ty is the same as Type 14846 // (type of the variable or single array element). 14847 PrivateTy = Context.getVariableArrayType( 14848 Type, 14849 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 14850 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 14851 } else if (!ASE && !OASE && 14852 Context.getAsArrayType(D->getType().getNonReferenceType())) { 14853 PrivateTy = D->getType().getNonReferenceType(); 14854 } 14855 // Private copy. 14856 VarDecl *PrivateVD = 14857 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 14858 D->hasAttrs() ? &D->getAttrs() : nullptr, 14859 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14860 // Add initializer for private variable. 14861 Expr *Init = nullptr; 14862 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 14863 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 14864 if (DeclareReductionRef.isUsable()) { 14865 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 14866 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 14867 if (DRD->getInitializer()) { 14868 Init = DRDRef; 14869 RHSVD->setInit(DRDRef); 14870 RHSVD->setInitStyle(VarDecl::CallInit); 14871 } 14872 } else { 14873 switch (BOK) { 14874 case BO_Add: 14875 case BO_Xor: 14876 case BO_Or: 14877 case BO_LOr: 14878 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 14879 if (Type->isScalarType() || Type->isAnyComplexType()) 14880 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 14881 break; 14882 case BO_Mul: 14883 case BO_LAnd: 14884 if (Type->isScalarType() || Type->isAnyComplexType()) { 14885 // '*' and '&&' reduction ops - initializer is '1'. 14886 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 14887 } 14888 break; 14889 case BO_And: { 14890 // '&' reduction op - initializer is '~0'. 14891 QualType OrigType = Type; 14892 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 14893 Type = ComplexTy->getElementType(); 14894 if (Type->isRealFloatingType()) { 14895 llvm::APFloat InitValue = 14896 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 14897 /*isIEEE=*/true); 14898 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14899 Type, ELoc); 14900 } else if (Type->isScalarType()) { 14901 uint64_t Size = Context.getTypeSize(Type); 14902 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 14903 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 14904 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14905 } 14906 if (Init && OrigType->isAnyComplexType()) { 14907 // Init = 0xFFFF + 0xFFFFi; 14908 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 14909 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 14910 } 14911 Type = OrigType; 14912 break; 14913 } 14914 case BO_LT: 14915 case BO_GT: { 14916 // 'min' reduction op - initializer is 'Largest representable number in 14917 // the reduction list item type'. 14918 // 'max' reduction op - initializer is 'Least representable number in 14919 // the reduction list item type'. 14920 if (Type->isIntegerType() || Type->isPointerType()) { 14921 bool IsSigned = Type->hasSignedIntegerRepresentation(); 14922 uint64_t Size = Context.getTypeSize(Type); 14923 QualType IntTy = 14924 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 14925 llvm::APInt InitValue = 14926 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 14927 : llvm::APInt::getMinValue(Size) 14928 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 14929 : llvm::APInt::getMaxValue(Size); 14930 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 14931 if (Type->isPointerType()) { 14932 // Cast to pointer type. 14933 ExprResult CastExpr = S.BuildCStyleCastExpr( 14934 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 14935 if (CastExpr.isInvalid()) 14936 continue; 14937 Init = CastExpr.get(); 14938 } 14939 } else if (Type->isRealFloatingType()) { 14940 llvm::APFloat InitValue = llvm::APFloat::getLargest( 14941 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 14942 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 14943 Type, ELoc); 14944 } 14945 break; 14946 } 14947 case BO_PtrMemD: 14948 case BO_PtrMemI: 14949 case BO_MulAssign: 14950 case BO_Div: 14951 case BO_Rem: 14952 case BO_Sub: 14953 case BO_Shl: 14954 case BO_Shr: 14955 case BO_LE: 14956 case BO_GE: 14957 case BO_EQ: 14958 case BO_NE: 14959 case BO_Cmp: 14960 case BO_AndAssign: 14961 case BO_XorAssign: 14962 case BO_OrAssign: 14963 case BO_Assign: 14964 case BO_AddAssign: 14965 case BO_SubAssign: 14966 case BO_DivAssign: 14967 case BO_RemAssign: 14968 case BO_ShlAssign: 14969 case BO_ShrAssign: 14970 case BO_Comma: 14971 llvm_unreachable("Unexpected reduction operation"); 14972 } 14973 } 14974 if (Init && DeclareReductionRef.isUnset()) 14975 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 14976 else if (!Init) 14977 S.ActOnUninitializedDecl(RHSVD); 14978 if (RHSVD->isInvalidDecl()) 14979 continue; 14980 if (!RHSVD->hasInit() && 14981 (DeclareReductionRef.isUnset() || !S.LangOpts.CPlusPlus)) { 14982 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 14983 << Type << ReductionIdRange; 14984 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 14985 VarDecl::DeclarationOnly; 14986 S.Diag(D->getLocation(), 14987 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 14988 << D; 14989 continue; 14990 } 14991 // Store initializer for single element in private copy. Will be used during 14992 // codegen. 14993 PrivateVD->setInit(RHSVD->getInit()); 14994 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 14995 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 14996 ExprResult ReductionOp; 14997 if (DeclareReductionRef.isUsable()) { 14998 QualType RedTy = DeclareReductionRef.get()->getType(); 14999 QualType PtrRedTy = Context.getPointerType(RedTy); 15000 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 15001 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 15002 if (!BasePath.empty()) { 15003 LHS = S.DefaultLvalueConversion(LHS.get()); 15004 RHS = S.DefaultLvalueConversion(RHS.get()); 15005 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 15006 CK_UncheckedDerivedToBase, LHS.get(), 15007 &BasePath, LHS.get()->getValueKind()); 15008 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 15009 CK_UncheckedDerivedToBase, RHS.get(), 15010 &BasePath, RHS.get()->getValueKind()); 15011 } 15012 FunctionProtoType::ExtProtoInfo EPI; 15013 QualType Params[] = {PtrRedTy, PtrRedTy}; 15014 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 15015 auto *OVE = new (Context) OpaqueValueExpr( 15016 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 15017 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 15018 Expr *Args[] = {LHS.get(), RHS.get()}; 15019 ReductionOp = 15020 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 15021 } else { 15022 ReductionOp = S.BuildBinOp( 15023 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 15024 if (ReductionOp.isUsable()) { 15025 if (BOK != BO_LT && BOK != BO_GT) { 15026 ReductionOp = 15027 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15028 BO_Assign, LHSDRE, ReductionOp.get()); 15029 } else { 15030 auto *ConditionalOp = new (Context) 15031 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 15032 Type, VK_LValue, OK_Ordinary); 15033 ReductionOp = 15034 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 15035 BO_Assign, LHSDRE, ConditionalOp); 15036 } 15037 if (ReductionOp.isUsable()) 15038 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 15039 /*DiscardedValue*/ false); 15040 } 15041 if (!ReductionOp.isUsable()) 15042 continue; 15043 } 15044 15045 // OpenMP [2.15.4.6, Restrictions, p.2] 15046 // A list item that appears in an in_reduction clause of a task construct 15047 // must appear in a task_reduction clause of a construct associated with a 15048 // taskgroup region that includes the participating task in its taskgroup 15049 // set. The construct associated with the innermost region that meets this 15050 // condition must specify the same reduction-identifier as the in_reduction 15051 // clause. 15052 if (ClauseKind == OMPC_in_reduction) { 15053 SourceRange ParentSR; 15054 BinaryOperatorKind ParentBOK; 15055 const Expr *ParentReductionOp = nullptr; 15056 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 15057 DSAStackTy::DSAVarData ParentBOKDSA = 15058 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 15059 ParentBOKTD); 15060 DSAStackTy::DSAVarData ParentReductionOpDSA = 15061 Stack->getTopMostTaskgroupReductionData( 15062 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 15063 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 15064 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 15065 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 15066 (DeclareReductionRef.isUsable() && IsParentBOK) || 15067 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 15068 bool EmitError = true; 15069 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 15070 llvm::FoldingSetNodeID RedId, ParentRedId; 15071 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 15072 DeclareReductionRef.get()->Profile(RedId, Context, 15073 /*Canonical=*/true); 15074 EmitError = RedId != ParentRedId; 15075 } 15076 if (EmitError) { 15077 S.Diag(ReductionId.getBeginLoc(), 15078 diag::err_omp_reduction_identifier_mismatch) 15079 << ReductionIdRange << RefExpr->getSourceRange(); 15080 S.Diag(ParentSR.getBegin(), 15081 diag::note_omp_previous_reduction_identifier) 15082 << ParentSR 15083 << (IsParentBOK ? ParentBOKDSA.RefExpr 15084 : ParentReductionOpDSA.RefExpr) 15085 ->getSourceRange(); 15086 continue; 15087 } 15088 } 15089 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 15090 } 15091 15092 DeclRefExpr *Ref = nullptr; 15093 Expr *VarsExpr = RefExpr->IgnoreParens(); 15094 if (!VD && !S.CurContext->isDependentContext()) { 15095 if (ASE || OASE) { 15096 TransformExprToCaptures RebuildToCapture(S, D); 15097 VarsExpr = 15098 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 15099 Ref = RebuildToCapture.getCapturedExpr(); 15100 } else { 15101 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 15102 } 15103 if (!S.isOpenMPCapturedDecl(D)) { 15104 RD.ExprCaptures.emplace_back(Ref->getDecl()); 15105 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15106 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 15107 if (!RefRes.isUsable()) 15108 continue; 15109 ExprResult PostUpdateRes = 15110 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 15111 RefRes.get()); 15112 if (!PostUpdateRes.isUsable()) 15113 continue; 15114 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 15115 Stack->getCurrentDirective() == OMPD_taskgroup) { 15116 S.Diag(RefExpr->getExprLoc(), 15117 diag::err_omp_reduction_non_addressable_expression) 15118 << RefExpr->getSourceRange(); 15119 continue; 15120 } 15121 RD.ExprPostUpdates.emplace_back( 15122 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 15123 } 15124 } 15125 } 15126 // All reduction items are still marked as reduction (to do not increase 15127 // code base size). 15128 unsigned Modifier = RD.RedModifier; 15129 // Consider task_reductions as reductions with task modifier. Required for 15130 // correct analysis of in_reduction clauses. 15131 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 15132 Modifier = OMPC_REDUCTION_task; 15133 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier); 15134 if (Modifier == OMPC_REDUCTION_task && 15135 (CurrDir == OMPD_taskgroup || 15136 ((isOpenMPParallelDirective(CurrDir) || 15137 isOpenMPWorksharingDirective(CurrDir)) && 15138 !isOpenMPSimdDirective(CurrDir)))) { 15139 if (DeclareReductionRef.isUsable()) 15140 Stack->addTaskgroupReductionData(D, ReductionIdRange, 15141 DeclareReductionRef.get()); 15142 else 15143 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 15144 } 15145 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 15146 TaskgroupDescriptor); 15147 } 15148 return RD.Vars.empty(); 15149 } 15150 15151 OMPClause *Sema::ActOnOpenMPReductionClause( 15152 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 15153 SourceLocation StartLoc, SourceLocation LParenLoc, 15154 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 15155 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15156 ArrayRef<Expr *> UnresolvedReductions) { 15157 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 15158 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 15159 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 15160 /*Last=*/OMPC_REDUCTION_unknown) 15161 << getOpenMPClauseName(OMPC_reduction); 15162 return nullptr; 15163 } 15164 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 15165 // A reduction clause with the inscan reduction-modifier may only appear on a 15166 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 15167 // construct, a parallel worksharing-loop construct or a parallel 15168 // worksharing-loop SIMD construct. 15169 if (Modifier == OMPC_REDUCTION_inscan && 15170 (DSAStack->getCurrentDirective() != OMPD_for && 15171 DSAStack->getCurrentDirective() != OMPD_for_simd && 15172 DSAStack->getCurrentDirective() != OMPD_simd && 15173 DSAStack->getCurrentDirective() != OMPD_parallel_for && 15174 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 15175 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 15176 return nullptr; 15177 } 15178 15179 ReductionData RD(VarList.size(), Modifier); 15180 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 15181 StartLoc, LParenLoc, ColonLoc, EndLoc, 15182 ReductionIdScopeSpec, ReductionId, 15183 UnresolvedReductions, RD)) 15184 return nullptr; 15185 15186 return OMPReductionClause::Create( 15187 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 15188 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15189 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 15190 buildPreInits(Context, RD.ExprCaptures), 15191 buildPostUpdate(*this, RD.ExprPostUpdates)); 15192 } 15193 15194 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 15195 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15196 SourceLocation ColonLoc, SourceLocation EndLoc, 15197 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15198 ArrayRef<Expr *> UnresolvedReductions) { 15199 ReductionData RD(VarList.size()); 15200 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 15201 StartLoc, LParenLoc, ColonLoc, EndLoc, 15202 ReductionIdScopeSpec, ReductionId, 15203 UnresolvedReductions, RD)) 15204 return nullptr; 15205 15206 return OMPTaskReductionClause::Create( 15207 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15208 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15209 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 15210 buildPreInits(Context, RD.ExprCaptures), 15211 buildPostUpdate(*this, RD.ExprPostUpdates)); 15212 } 15213 15214 OMPClause *Sema::ActOnOpenMPInReductionClause( 15215 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 15216 SourceLocation ColonLoc, SourceLocation EndLoc, 15217 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 15218 ArrayRef<Expr *> UnresolvedReductions) { 15219 ReductionData RD(VarList.size()); 15220 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 15221 StartLoc, LParenLoc, ColonLoc, EndLoc, 15222 ReductionIdScopeSpec, ReductionId, 15223 UnresolvedReductions, RD)) 15224 return nullptr; 15225 15226 return OMPInReductionClause::Create( 15227 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 15228 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 15229 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 15230 buildPreInits(Context, RD.ExprCaptures), 15231 buildPostUpdate(*this, RD.ExprPostUpdates)); 15232 } 15233 15234 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 15235 SourceLocation LinLoc) { 15236 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 15237 LinKind == OMPC_LINEAR_unknown) { 15238 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 15239 return true; 15240 } 15241 return false; 15242 } 15243 15244 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 15245 OpenMPLinearClauseKind LinKind, QualType Type, 15246 bool IsDeclareSimd) { 15247 const auto *VD = dyn_cast_or_null<VarDecl>(D); 15248 // A variable must not have an incomplete type or a reference type. 15249 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 15250 return true; 15251 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 15252 !Type->isReferenceType()) { 15253 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 15254 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 15255 return true; 15256 } 15257 Type = Type.getNonReferenceType(); 15258 15259 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 15260 // A variable that is privatized must not have a const-qualified type 15261 // unless it is of class type with a mutable member. This restriction does 15262 // not apply to the firstprivate clause, nor to the linear clause on 15263 // declarative directives (like declare simd). 15264 if (!IsDeclareSimd && 15265 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 15266 return true; 15267 15268 // A list item must be of integral or pointer type. 15269 Type = Type.getUnqualifiedType().getCanonicalType(); 15270 const auto *Ty = Type.getTypePtrOrNull(); 15271 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 15272 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 15273 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 15274 if (D) { 15275 bool IsDecl = 15276 !VD || 15277 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15278 Diag(D->getLocation(), 15279 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15280 << D; 15281 } 15282 return true; 15283 } 15284 return false; 15285 } 15286 15287 OMPClause *Sema::ActOnOpenMPLinearClause( 15288 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 15289 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 15290 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15291 SmallVector<Expr *, 8> Vars; 15292 SmallVector<Expr *, 8> Privates; 15293 SmallVector<Expr *, 8> Inits; 15294 SmallVector<Decl *, 4> ExprCaptures; 15295 SmallVector<Expr *, 4> ExprPostUpdates; 15296 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 15297 LinKind = OMPC_LINEAR_val; 15298 for (Expr *RefExpr : VarList) { 15299 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15300 SourceLocation ELoc; 15301 SourceRange ERange; 15302 Expr *SimpleRefExpr = RefExpr; 15303 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15304 if (Res.second) { 15305 // It will be analyzed later. 15306 Vars.push_back(RefExpr); 15307 Privates.push_back(nullptr); 15308 Inits.push_back(nullptr); 15309 } 15310 ValueDecl *D = Res.first; 15311 if (!D) 15312 continue; 15313 15314 QualType Type = D->getType(); 15315 auto *VD = dyn_cast<VarDecl>(D); 15316 15317 // OpenMP [2.14.3.7, linear clause] 15318 // A list-item cannot appear in more than one linear clause. 15319 // A list-item that appears in a linear clause cannot appear in any 15320 // other data-sharing attribute clause. 15321 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 15322 if (DVar.RefExpr) { 15323 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 15324 << getOpenMPClauseName(OMPC_linear); 15325 reportOriginalDsa(*this, DSAStack, D, DVar); 15326 continue; 15327 } 15328 15329 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 15330 continue; 15331 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15332 15333 // Build private copy of original var. 15334 VarDecl *Private = 15335 buildVarDecl(*this, ELoc, Type, D->getName(), 15336 D->hasAttrs() ? &D->getAttrs() : nullptr, 15337 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 15338 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 15339 // Build var to save initial value. 15340 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 15341 Expr *InitExpr; 15342 DeclRefExpr *Ref = nullptr; 15343 if (!VD && !CurContext->isDependentContext()) { 15344 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 15345 if (!isOpenMPCapturedDecl(D)) { 15346 ExprCaptures.push_back(Ref->getDecl()); 15347 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 15348 ExprResult RefRes = DefaultLvalueConversion(Ref); 15349 if (!RefRes.isUsable()) 15350 continue; 15351 ExprResult PostUpdateRes = 15352 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 15353 SimpleRefExpr, RefRes.get()); 15354 if (!PostUpdateRes.isUsable()) 15355 continue; 15356 ExprPostUpdates.push_back( 15357 IgnoredValueConversions(PostUpdateRes.get()).get()); 15358 } 15359 } 15360 } 15361 if (LinKind == OMPC_LINEAR_uval) 15362 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 15363 else 15364 InitExpr = VD ? SimpleRefExpr : Ref; 15365 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 15366 /*DirectInit=*/false); 15367 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 15368 15369 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 15370 Vars.push_back((VD || CurContext->isDependentContext()) 15371 ? RefExpr->IgnoreParens() 15372 : Ref); 15373 Privates.push_back(PrivateRef); 15374 Inits.push_back(InitRef); 15375 } 15376 15377 if (Vars.empty()) 15378 return nullptr; 15379 15380 Expr *StepExpr = Step; 15381 Expr *CalcStepExpr = nullptr; 15382 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 15383 !Step->isInstantiationDependent() && 15384 !Step->containsUnexpandedParameterPack()) { 15385 SourceLocation StepLoc = Step->getBeginLoc(); 15386 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 15387 if (Val.isInvalid()) 15388 return nullptr; 15389 StepExpr = Val.get(); 15390 15391 // Build var to save the step value. 15392 VarDecl *SaveVar = 15393 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 15394 ExprResult SaveRef = 15395 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 15396 ExprResult CalcStep = 15397 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 15398 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 15399 15400 // Warn about zero linear step (it would be probably better specified as 15401 // making corresponding variables 'const'). 15402 llvm::APSInt Result; 15403 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 15404 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 15405 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 15406 << (Vars.size() > 1); 15407 if (!IsConstant && CalcStep.isUsable()) { 15408 // Calculate the step beforehand instead of doing this on each iteration. 15409 // (This is not used if the number of iterations may be kfold-ed). 15410 CalcStepExpr = CalcStep.get(); 15411 } 15412 } 15413 15414 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 15415 ColonLoc, EndLoc, Vars, Privates, Inits, 15416 StepExpr, CalcStepExpr, 15417 buildPreInits(Context, ExprCaptures), 15418 buildPostUpdate(*this, ExprPostUpdates)); 15419 } 15420 15421 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 15422 Expr *NumIterations, Sema &SemaRef, 15423 Scope *S, DSAStackTy *Stack) { 15424 // Walk the vars and build update/final expressions for the CodeGen. 15425 SmallVector<Expr *, 8> Updates; 15426 SmallVector<Expr *, 8> Finals; 15427 SmallVector<Expr *, 8> UsedExprs; 15428 Expr *Step = Clause.getStep(); 15429 Expr *CalcStep = Clause.getCalcStep(); 15430 // OpenMP [2.14.3.7, linear clause] 15431 // If linear-step is not specified it is assumed to be 1. 15432 if (!Step) 15433 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 15434 else if (CalcStep) 15435 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 15436 bool HasErrors = false; 15437 auto CurInit = Clause.inits().begin(); 15438 auto CurPrivate = Clause.privates().begin(); 15439 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 15440 for (Expr *RefExpr : Clause.varlists()) { 15441 SourceLocation ELoc; 15442 SourceRange ERange; 15443 Expr *SimpleRefExpr = RefExpr; 15444 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 15445 ValueDecl *D = Res.first; 15446 if (Res.second || !D) { 15447 Updates.push_back(nullptr); 15448 Finals.push_back(nullptr); 15449 HasErrors = true; 15450 continue; 15451 } 15452 auto &&Info = Stack->isLoopControlVariable(D); 15453 // OpenMP [2.15.11, distribute simd Construct] 15454 // A list item may not appear in a linear clause, unless it is the loop 15455 // iteration variable. 15456 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 15457 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 15458 SemaRef.Diag(ELoc, 15459 diag::err_omp_linear_distribute_var_non_loop_iteration); 15460 Updates.push_back(nullptr); 15461 Finals.push_back(nullptr); 15462 HasErrors = true; 15463 continue; 15464 } 15465 Expr *InitExpr = *CurInit; 15466 15467 // Build privatized reference to the current linear var. 15468 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 15469 Expr *CapturedRef; 15470 if (LinKind == OMPC_LINEAR_uval) 15471 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 15472 else 15473 CapturedRef = 15474 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 15475 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 15476 /*RefersToCapture=*/true); 15477 15478 // Build update: Var = InitExpr + IV * Step 15479 ExprResult Update; 15480 if (!Info.first) 15481 Update = buildCounterUpdate( 15482 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 15483 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 15484 else 15485 Update = *CurPrivate; 15486 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 15487 /*DiscardedValue*/ false); 15488 15489 // Build final: Var = InitExpr + NumIterations * Step 15490 ExprResult Final; 15491 if (!Info.first) 15492 Final = 15493 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 15494 InitExpr, NumIterations, Step, /*Subtract=*/false, 15495 /*IsNonRectangularLB=*/false); 15496 else 15497 Final = *CurPrivate; 15498 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 15499 /*DiscardedValue*/ false); 15500 15501 if (!Update.isUsable() || !Final.isUsable()) { 15502 Updates.push_back(nullptr); 15503 Finals.push_back(nullptr); 15504 UsedExprs.push_back(nullptr); 15505 HasErrors = true; 15506 } else { 15507 Updates.push_back(Update.get()); 15508 Finals.push_back(Final.get()); 15509 if (!Info.first) 15510 UsedExprs.push_back(SimpleRefExpr); 15511 } 15512 ++CurInit; 15513 ++CurPrivate; 15514 } 15515 if (Expr *S = Clause.getStep()) 15516 UsedExprs.push_back(S); 15517 // Fill the remaining part with the nullptr. 15518 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 15519 Clause.setUpdates(Updates); 15520 Clause.setFinals(Finals); 15521 Clause.setUsedExprs(UsedExprs); 15522 return HasErrors; 15523 } 15524 15525 OMPClause *Sema::ActOnOpenMPAlignedClause( 15526 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 15527 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 15528 SmallVector<Expr *, 8> Vars; 15529 for (Expr *RefExpr : VarList) { 15530 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15531 SourceLocation ELoc; 15532 SourceRange ERange; 15533 Expr *SimpleRefExpr = RefExpr; 15534 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15535 if (Res.second) { 15536 // It will be analyzed later. 15537 Vars.push_back(RefExpr); 15538 } 15539 ValueDecl *D = Res.first; 15540 if (!D) 15541 continue; 15542 15543 QualType QType = D->getType(); 15544 auto *VD = dyn_cast<VarDecl>(D); 15545 15546 // OpenMP [2.8.1, simd construct, Restrictions] 15547 // The type of list items appearing in the aligned clause must be 15548 // array, pointer, reference to array, or reference to pointer. 15549 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 15550 const Type *Ty = QType.getTypePtrOrNull(); 15551 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 15552 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 15553 << QType << getLangOpts().CPlusPlus << ERange; 15554 bool IsDecl = 15555 !VD || 15556 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15557 Diag(D->getLocation(), 15558 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15559 << D; 15560 continue; 15561 } 15562 15563 // OpenMP [2.8.1, simd construct, Restrictions] 15564 // A list-item cannot appear in more than one aligned clause. 15565 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 15566 Diag(ELoc, diag::err_omp_used_in_clause_twice) 15567 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 15568 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 15569 << getOpenMPClauseName(OMPC_aligned); 15570 continue; 15571 } 15572 15573 DeclRefExpr *Ref = nullptr; 15574 if (!VD && isOpenMPCapturedDecl(D)) 15575 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 15576 Vars.push_back(DefaultFunctionArrayConversion( 15577 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 15578 .get()); 15579 } 15580 15581 // OpenMP [2.8.1, simd construct, Description] 15582 // The parameter of the aligned clause, alignment, must be a constant 15583 // positive integer expression. 15584 // If no optional parameter is specified, implementation-defined default 15585 // alignments for SIMD instructions on the target platforms are assumed. 15586 if (Alignment != nullptr) { 15587 ExprResult AlignResult = 15588 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 15589 if (AlignResult.isInvalid()) 15590 return nullptr; 15591 Alignment = AlignResult.get(); 15592 } 15593 if (Vars.empty()) 15594 return nullptr; 15595 15596 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 15597 EndLoc, Vars, Alignment); 15598 } 15599 15600 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 15601 SourceLocation StartLoc, 15602 SourceLocation LParenLoc, 15603 SourceLocation EndLoc) { 15604 SmallVector<Expr *, 8> Vars; 15605 SmallVector<Expr *, 8> SrcExprs; 15606 SmallVector<Expr *, 8> DstExprs; 15607 SmallVector<Expr *, 8> AssignmentOps; 15608 for (Expr *RefExpr : VarList) { 15609 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 15610 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15611 // It will be analyzed later. 15612 Vars.push_back(RefExpr); 15613 SrcExprs.push_back(nullptr); 15614 DstExprs.push_back(nullptr); 15615 AssignmentOps.push_back(nullptr); 15616 continue; 15617 } 15618 15619 SourceLocation ELoc = RefExpr->getExprLoc(); 15620 // OpenMP [2.1, C/C++] 15621 // A list item is a variable name. 15622 // OpenMP [2.14.4.1, Restrictions, p.1] 15623 // A list item that appears in a copyin clause must be threadprivate. 15624 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 15625 if (!DE || !isa<VarDecl>(DE->getDecl())) { 15626 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 15627 << 0 << RefExpr->getSourceRange(); 15628 continue; 15629 } 15630 15631 Decl *D = DE->getDecl(); 15632 auto *VD = cast<VarDecl>(D); 15633 15634 QualType Type = VD->getType(); 15635 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 15636 // It will be analyzed later. 15637 Vars.push_back(DE); 15638 SrcExprs.push_back(nullptr); 15639 DstExprs.push_back(nullptr); 15640 AssignmentOps.push_back(nullptr); 15641 continue; 15642 } 15643 15644 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 15645 // A list item that appears in a copyin clause must be threadprivate. 15646 if (!DSAStack->isThreadPrivate(VD)) { 15647 Diag(ELoc, diag::err_omp_required_access) 15648 << getOpenMPClauseName(OMPC_copyin) 15649 << getOpenMPDirectiveName(OMPD_threadprivate); 15650 continue; 15651 } 15652 15653 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15654 // A variable of class type (or array thereof) that appears in a 15655 // copyin clause requires an accessible, unambiguous copy assignment 15656 // operator for the class type. 15657 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 15658 VarDecl *SrcVD = 15659 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 15660 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15661 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 15662 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 15663 VarDecl *DstVD = 15664 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 15665 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 15666 DeclRefExpr *PseudoDstExpr = 15667 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 15668 // For arrays generate assignment operation for single element and replace 15669 // it by the original array element in CodeGen. 15670 ExprResult AssignmentOp = 15671 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 15672 PseudoSrcExpr); 15673 if (AssignmentOp.isInvalid()) 15674 continue; 15675 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 15676 /*DiscardedValue*/ false); 15677 if (AssignmentOp.isInvalid()) 15678 continue; 15679 15680 DSAStack->addDSA(VD, DE, OMPC_copyin); 15681 Vars.push_back(DE); 15682 SrcExprs.push_back(PseudoSrcExpr); 15683 DstExprs.push_back(PseudoDstExpr); 15684 AssignmentOps.push_back(AssignmentOp.get()); 15685 } 15686 15687 if (Vars.empty()) 15688 return nullptr; 15689 15690 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 15691 SrcExprs, DstExprs, AssignmentOps); 15692 } 15693 15694 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 15695 SourceLocation StartLoc, 15696 SourceLocation LParenLoc, 15697 SourceLocation EndLoc) { 15698 SmallVector<Expr *, 8> Vars; 15699 SmallVector<Expr *, 8> SrcExprs; 15700 SmallVector<Expr *, 8> DstExprs; 15701 SmallVector<Expr *, 8> AssignmentOps; 15702 for (Expr *RefExpr : VarList) { 15703 assert(RefExpr && "NULL expr in OpenMP linear clause."); 15704 SourceLocation ELoc; 15705 SourceRange ERange; 15706 Expr *SimpleRefExpr = RefExpr; 15707 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 15708 if (Res.second) { 15709 // It will be analyzed later. 15710 Vars.push_back(RefExpr); 15711 SrcExprs.push_back(nullptr); 15712 DstExprs.push_back(nullptr); 15713 AssignmentOps.push_back(nullptr); 15714 } 15715 ValueDecl *D = Res.first; 15716 if (!D) 15717 continue; 15718 15719 QualType Type = D->getType(); 15720 auto *VD = dyn_cast<VarDecl>(D); 15721 15722 // OpenMP [2.14.4.2, Restrictions, p.2] 15723 // A list item that appears in a copyprivate clause may not appear in a 15724 // private or firstprivate clause on the single construct. 15725 if (!VD || !DSAStack->isThreadPrivate(VD)) { 15726 DSAStackTy::DSAVarData DVar = 15727 DSAStack->getTopDSA(D, /*FromParent=*/false); 15728 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 15729 DVar.RefExpr) { 15730 Diag(ELoc, diag::err_omp_wrong_dsa) 15731 << getOpenMPClauseName(DVar.CKind) 15732 << getOpenMPClauseName(OMPC_copyprivate); 15733 reportOriginalDsa(*this, DSAStack, D, DVar); 15734 continue; 15735 } 15736 15737 // OpenMP [2.11.4.2, Restrictions, p.1] 15738 // All list items that appear in a copyprivate clause must be either 15739 // threadprivate or private in the enclosing context. 15740 if (DVar.CKind == OMPC_unknown) { 15741 DVar = DSAStack->getImplicitDSA(D, false); 15742 if (DVar.CKind == OMPC_shared) { 15743 Diag(ELoc, diag::err_omp_required_access) 15744 << getOpenMPClauseName(OMPC_copyprivate) 15745 << "threadprivate or private in the enclosing context"; 15746 reportOriginalDsa(*this, DSAStack, D, DVar); 15747 continue; 15748 } 15749 } 15750 } 15751 15752 // Variably modified types are not supported. 15753 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 15754 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 15755 << getOpenMPClauseName(OMPC_copyprivate) << Type 15756 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 15757 bool IsDecl = 15758 !VD || 15759 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 15760 Diag(D->getLocation(), 15761 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 15762 << D; 15763 continue; 15764 } 15765 15766 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 15767 // A variable of class type (or array thereof) that appears in a 15768 // copyin clause requires an accessible, unambiguous copy assignment 15769 // operator for the class type. 15770 Type = Context.getBaseElementType(Type.getNonReferenceType()) 15771 .getUnqualifiedType(); 15772 VarDecl *SrcVD = 15773 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 15774 D->hasAttrs() ? &D->getAttrs() : nullptr); 15775 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 15776 VarDecl *DstVD = 15777 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 15778 D->hasAttrs() ? &D->getAttrs() : nullptr); 15779 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 15780 ExprResult AssignmentOp = BuildBinOp( 15781 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 15782 if (AssignmentOp.isInvalid()) 15783 continue; 15784 AssignmentOp = 15785 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 15786 if (AssignmentOp.isInvalid()) 15787 continue; 15788 15789 // No need to mark vars as copyprivate, they are already threadprivate or 15790 // implicitly private. 15791 assert(VD || isOpenMPCapturedDecl(D)); 15792 Vars.push_back( 15793 VD ? RefExpr->IgnoreParens() 15794 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 15795 SrcExprs.push_back(PseudoSrcExpr); 15796 DstExprs.push_back(PseudoDstExpr); 15797 AssignmentOps.push_back(AssignmentOp.get()); 15798 } 15799 15800 if (Vars.empty()) 15801 return nullptr; 15802 15803 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 15804 Vars, SrcExprs, DstExprs, AssignmentOps); 15805 } 15806 15807 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 15808 SourceLocation StartLoc, 15809 SourceLocation LParenLoc, 15810 SourceLocation EndLoc) { 15811 if (VarList.empty()) 15812 return nullptr; 15813 15814 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 15815 } 15816 15817 /// Tries to find omp_depend_t. type. 15818 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 15819 bool Diagnose = true) { 15820 QualType OMPDependT = Stack->getOMPDependT(); 15821 if (!OMPDependT.isNull()) 15822 return true; 15823 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 15824 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 15825 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 15826 if (Diagnose) 15827 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 15828 return false; 15829 } 15830 Stack->setOMPDependT(PT.get()); 15831 return true; 15832 } 15833 15834 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 15835 SourceLocation LParenLoc, 15836 SourceLocation EndLoc) { 15837 if (!Depobj) 15838 return nullptr; 15839 15840 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 15841 15842 // OpenMP 5.0, 2.17.10.1 depobj Construct 15843 // depobj is an lvalue expression of type omp_depend_t. 15844 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 15845 !Depobj->isInstantiationDependent() && 15846 !Depobj->containsUnexpandedParameterPack() && 15847 (OMPDependTFound && 15848 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 15849 /*CompareUnqualified=*/true))) { 15850 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15851 << 0 << Depobj->getType() << Depobj->getSourceRange(); 15852 } 15853 15854 if (!Depobj->isLValue()) { 15855 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 15856 << 1 << Depobj->getSourceRange(); 15857 } 15858 15859 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 15860 } 15861 15862 OMPClause * 15863 Sema::ActOnOpenMPDependClause(Expr *DepModifier, OpenMPDependClauseKind DepKind, 15864 SourceLocation DepLoc, SourceLocation ColonLoc, 15865 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 15866 SourceLocation LParenLoc, SourceLocation EndLoc) { 15867 if (DSAStack->getCurrentDirective() == OMPD_ordered && 15868 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 15869 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15870 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 15871 return nullptr; 15872 } 15873 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 15874 DSAStack->getCurrentDirective() == OMPD_depobj) && 15875 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 15876 DepKind == OMPC_DEPEND_sink || 15877 ((LangOpts.OpenMP < 50 || 15878 DSAStack->getCurrentDirective() == OMPD_depobj) && 15879 DepKind == OMPC_DEPEND_depobj))) { 15880 SmallVector<unsigned, 3> Except; 15881 Except.push_back(OMPC_DEPEND_source); 15882 Except.push_back(OMPC_DEPEND_sink); 15883 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 15884 Except.push_back(OMPC_DEPEND_depobj); 15885 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 15886 ? "depend modifier(iterator) or " 15887 : ""; 15888 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 15889 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 15890 /*Last=*/OMPC_DEPEND_unknown, 15891 Except) 15892 << getOpenMPClauseName(OMPC_depend); 15893 return nullptr; 15894 } 15895 if (DepModifier && 15896 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 15897 Diag(DepModifier->getExprLoc(), 15898 diag::err_omp_depend_sink_source_with_modifier); 15899 return nullptr; 15900 } 15901 if (DepModifier && 15902 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 15903 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 15904 15905 SmallVector<Expr *, 8> Vars; 15906 DSAStackTy::OperatorOffsetTy OpsOffs; 15907 llvm::APSInt DepCounter(/*BitWidth=*/32); 15908 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 15909 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 15910 if (const Expr *OrderedCountExpr = 15911 DSAStack->getParentOrderedRegionParam().first) { 15912 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 15913 TotalDepCount.setIsUnsigned(/*Val=*/true); 15914 } 15915 } 15916 for (Expr *RefExpr : VarList) { 15917 assert(RefExpr && "NULL expr in OpenMP shared clause."); 15918 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 15919 // It will be analyzed later. 15920 Vars.push_back(RefExpr); 15921 continue; 15922 } 15923 15924 SourceLocation ELoc = RefExpr->getExprLoc(); 15925 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 15926 if (DepKind == OMPC_DEPEND_sink) { 15927 if (DSAStack->getParentOrderedRegionParam().first && 15928 DepCounter >= TotalDepCount) { 15929 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 15930 continue; 15931 } 15932 ++DepCounter; 15933 // OpenMP [2.13.9, Summary] 15934 // depend(dependence-type : vec), where dependence-type is: 15935 // 'sink' and where vec is the iteration vector, which has the form: 15936 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 15937 // where n is the value specified by the ordered clause in the loop 15938 // directive, xi denotes the loop iteration variable of the i-th nested 15939 // loop associated with the loop directive, and di is a constant 15940 // non-negative integer. 15941 if (CurContext->isDependentContext()) { 15942 // It will be analyzed later. 15943 Vars.push_back(RefExpr); 15944 continue; 15945 } 15946 SimpleExpr = SimpleExpr->IgnoreImplicit(); 15947 OverloadedOperatorKind OOK = OO_None; 15948 SourceLocation OOLoc; 15949 Expr *LHS = SimpleExpr; 15950 Expr *RHS = nullptr; 15951 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 15952 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 15953 OOLoc = BO->getOperatorLoc(); 15954 LHS = BO->getLHS()->IgnoreParenImpCasts(); 15955 RHS = BO->getRHS()->IgnoreParenImpCasts(); 15956 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 15957 OOK = OCE->getOperator(); 15958 OOLoc = OCE->getOperatorLoc(); 15959 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15960 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 15961 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 15962 OOK = MCE->getMethodDecl() 15963 ->getNameInfo() 15964 .getName() 15965 .getCXXOverloadedOperator(); 15966 OOLoc = MCE->getCallee()->getExprLoc(); 15967 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 15968 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 15969 } 15970 SourceLocation ELoc; 15971 SourceRange ERange; 15972 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 15973 if (Res.second) { 15974 // It will be analyzed later. 15975 Vars.push_back(RefExpr); 15976 } 15977 ValueDecl *D = Res.first; 15978 if (!D) 15979 continue; 15980 15981 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 15982 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 15983 continue; 15984 } 15985 if (RHS) { 15986 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 15987 RHS, OMPC_depend, /*StrictlyPositive=*/false); 15988 if (RHSRes.isInvalid()) 15989 continue; 15990 } 15991 if (!CurContext->isDependentContext() && 15992 DSAStack->getParentOrderedRegionParam().first && 15993 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 15994 const ValueDecl *VD = 15995 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 15996 if (VD) 15997 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 15998 << 1 << VD; 15999 else 16000 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 16001 continue; 16002 } 16003 OpsOffs.emplace_back(RHS, OOK); 16004 } else { 16005 bool OMPDependTFound = LangOpts.OpenMP >= 50; 16006 if (OMPDependTFound) 16007 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 16008 DepKind == OMPC_DEPEND_depobj); 16009 if (DepKind == OMPC_DEPEND_depobj) { 16010 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16011 // List items used in depend clauses with the depobj dependence type 16012 // must be expressions of the omp_depend_t type. 16013 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16014 !RefExpr->isInstantiationDependent() && 16015 !RefExpr->containsUnexpandedParameterPack() && 16016 (OMPDependTFound && 16017 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 16018 RefExpr->getType()))) { 16019 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16020 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 16021 continue; 16022 } 16023 if (!RefExpr->isLValue()) { 16024 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 16025 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 16026 continue; 16027 } 16028 } else { 16029 // OpenMP 5.0 [2.17.11, Restrictions] 16030 // List items used in depend clauses cannot be zero-length array 16031 // sections. 16032 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 16033 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 16034 if (OASE) { 16035 QualType BaseType = 16036 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 16037 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 16038 ExprTy = ATy->getElementType(); 16039 else 16040 ExprTy = BaseType->getPointeeType(); 16041 ExprTy = ExprTy.getNonReferenceType(); 16042 const Expr *Length = OASE->getLength(); 16043 Expr::EvalResult Result; 16044 if (Length && !Length->isValueDependent() && 16045 Length->EvaluateAsInt(Result, Context) && 16046 Result.Val.getInt().isNullValue()) { 16047 Diag(ELoc, 16048 diag::err_omp_depend_zero_length_array_section_not_allowed) 16049 << SimpleExpr->getSourceRange(); 16050 continue; 16051 } 16052 } 16053 16054 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 16055 // List items used in depend clauses with the in, out, inout or 16056 // mutexinoutset dependence types cannot be expressions of the 16057 // omp_depend_t type. 16058 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 16059 !RefExpr->isInstantiationDependent() && 16060 !RefExpr->containsUnexpandedParameterPack() && 16061 (OMPDependTFound && 16062 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr())) { 16063 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16064 << (LangOpts.OpenMP >= 50 ? 1 : 0) << 1 16065 << RefExpr->getSourceRange(); 16066 continue; 16067 } 16068 16069 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 16070 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 16071 (ASE && 16072 !ASE->getBase() 16073 ->getType() 16074 .getNonReferenceType() 16075 ->isPointerType() && 16076 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 16077 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16078 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16079 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16080 continue; 16081 } 16082 16083 ExprResult Res; 16084 { 16085 Sema::TentativeAnalysisScope Trap(*this); 16086 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 16087 RefExpr->IgnoreParenImpCasts()); 16088 } 16089 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 16090 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 16091 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 16092 << (LangOpts.OpenMP >= 50 ? 1 : 0) 16093 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 16094 continue; 16095 } 16096 } 16097 } 16098 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 16099 } 16100 16101 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 16102 TotalDepCount > VarList.size() && 16103 DSAStack->getParentOrderedRegionParam().first && 16104 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 16105 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 16106 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 16107 } 16108 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 16109 Vars.empty()) 16110 return nullptr; 16111 16112 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16113 DepModifier, DepKind, DepLoc, ColonLoc, 16114 Vars, TotalDepCount.getZExtValue()); 16115 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 16116 DSAStack->isParentOrderedRegion()) 16117 DSAStack->addDoacrossDependClause(C, OpsOffs); 16118 return C; 16119 } 16120 16121 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 16122 Expr *Device, SourceLocation StartLoc, 16123 SourceLocation LParenLoc, 16124 SourceLocation ModifierLoc, 16125 SourceLocation EndLoc) { 16126 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 16127 "Unexpected device modifier in OpenMP < 50."); 16128 16129 bool ErrorFound = false; 16130 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 16131 std::string Values = 16132 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 16133 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 16134 << Values << getOpenMPClauseName(OMPC_device); 16135 ErrorFound = true; 16136 } 16137 16138 Expr *ValExpr = Device; 16139 Stmt *HelperValStmt = nullptr; 16140 16141 // OpenMP [2.9.1, Restrictions] 16142 // The device expression must evaluate to a non-negative integer value. 16143 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 16144 /*StrictlyPositive=*/false) || 16145 ErrorFound; 16146 if (ErrorFound) 16147 return nullptr; 16148 16149 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 16150 OpenMPDirectiveKind CaptureRegion = 16151 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 16152 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 16153 ValExpr = MakeFullExpr(ValExpr).get(); 16154 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16155 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16156 HelperValStmt = buildPreInits(Context, Captures); 16157 } 16158 16159 return new (Context) 16160 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 16161 LParenLoc, ModifierLoc, EndLoc); 16162 } 16163 16164 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 16165 DSAStackTy *Stack, QualType QTy, 16166 bool FullCheck = true) { 16167 NamedDecl *ND; 16168 if (QTy->isIncompleteType(&ND)) { 16169 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 16170 return false; 16171 } 16172 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 16173 !QTy.isTriviallyCopyableType(SemaRef.Context)) 16174 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 16175 return true; 16176 } 16177 16178 /// Return true if it can be proven that the provided array expression 16179 /// (array section or array subscript) does NOT specify the whole size of the 16180 /// array whose base type is \a BaseQTy. 16181 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 16182 const Expr *E, 16183 QualType BaseQTy) { 16184 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16185 16186 // If this is an array subscript, it refers to the whole size if the size of 16187 // the dimension is constant and equals 1. Also, an array section assumes the 16188 // format of an array subscript if no colon is used. 16189 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 16190 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16191 return ATy->getSize().getSExtValue() != 1; 16192 // Size can't be evaluated statically. 16193 return false; 16194 } 16195 16196 assert(OASE && "Expecting array section if not an array subscript."); 16197 const Expr *LowerBound = OASE->getLowerBound(); 16198 const Expr *Length = OASE->getLength(); 16199 16200 // If there is a lower bound that does not evaluates to zero, we are not 16201 // covering the whole dimension. 16202 if (LowerBound) { 16203 Expr::EvalResult Result; 16204 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 16205 return false; // Can't get the integer value as a constant. 16206 16207 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 16208 if (ConstLowerBound.getSExtValue()) 16209 return true; 16210 } 16211 16212 // If we don't have a length we covering the whole dimension. 16213 if (!Length) 16214 return false; 16215 16216 // If the base is a pointer, we don't have a way to get the size of the 16217 // pointee. 16218 if (BaseQTy->isPointerType()) 16219 return false; 16220 16221 // We can only check if the length is the same as the size of the dimension 16222 // if we have a constant array. 16223 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 16224 if (!CATy) 16225 return false; 16226 16227 Expr::EvalResult Result; 16228 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16229 return false; // Can't get the integer value as a constant. 16230 16231 llvm::APSInt ConstLength = Result.Val.getInt(); 16232 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 16233 } 16234 16235 // Return true if it can be proven that the provided array expression (array 16236 // section or array subscript) does NOT specify a single element of the array 16237 // whose base type is \a BaseQTy. 16238 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 16239 const Expr *E, 16240 QualType BaseQTy) { 16241 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 16242 16243 // An array subscript always refer to a single element. Also, an array section 16244 // assumes the format of an array subscript if no colon is used. 16245 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 16246 return false; 16247 16248 assert(OASE && "Expecting array section if not an array subscript."); 16249 const Expr *Length = OASE->getLength(); 16250 16251 // If we don't have a length we have to check if the array has unitary size 16252 // for this dimension. Also, we should always expect a length if the base type 16253 // is pointer. 16254 if (!Length) { 16255 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 16256 return ATy->getSize().getSExtValue() != 1; 16257 // We cannot assume anything. 16258 return false; 16259 } 16260 16261 // Check if the length evaluates to 1. 16262 Expr::EvalResult Result; 16263 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 16264 return false; // Can't get the integer value as a constant. 16265 16266 llvm::APSInt ConstLength = Result.Val.getInt(); 16267 return ConstLength.getSExtValue() != 1; 16268 } 16269 16270 // The base of elements of list in a map clause have to be either: 16271 // - a reference to variable or field. 16272 // - a member expression. 16273 // - an array expression. 16274 // 16275 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 16276 // reference to 'r'. 16277 // 16278 // If we have: 16279 // 16280 // struct SS { 16281 // Bla S; 16282 // foo() { 16283 // #pragma omp target map (S.Arr[:12]); 16284 // } 16285 // } 16286 // 16287 // We want to retrieve the member expression 'this->S'; 16288 16289 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 16290 // If a list item is an array section, it must specify contiguous storage. 16291 // 16292 // For this restriction it is sufficient that we make sure only references 16293 // to variables or fields and array expressions, and that no array sections 16294 // exist except in the rightmost expression (unless they cover the whole 16295 // dimension of the array). E.g. these would be invalid: 16296 // 16297 // r.ArrS[3:5].Arr[6:7] 16298 // 16299 // r.ArrS[3:5].x 16300 // 16301 // but these would be valid: 16302 // r.ArrS[3].Arr[6:7] 16303 // 16304 // r.ArrS[3].x 16305 namespace { 16306 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 16307 Sema &SemaRef; 16308 OpenMPClauseKind CKind = OMPC_unknown; 16309 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 16310 bool NoDiagnose = false; 16311 const Expr *RelevantExpr = nullptr; 16312 bool AllowUnitySizeArraySection = true; 16313 bool AllowWholeSizeArraySection = true; 16314 SourceLocation ELoc; 16315 SourceRange ERange; 16316 16317 void emitErrorMsg() { 16318 // If nothing else worked, this is not a valid map clause expression. 16319 if (SemaRef.getLangOpts().OpenMP < 50) { 16320 SemaRef.Diag(ELoc, 16321 diag::err_omp_expected_named_var_member_or_array_expression) 16322 << ERange; 16323 } else { 16324 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 16325 << getOpenMPClauseName(CKind) << ERange; 16326 } 16327 } 16328 16329 public: 16330 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 16331 if (!isa<VarDecl>(DRE->getDecl())) { 16332 emitErrorMsg(); 16333 return false; 16334 } 16335 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16336 RelevantExpr = DRE; 16337 // Record the component. 16338 Components.emplace_back(DRE, DRE->getDecl()); 16339 return true; 16340 } 16341 16342 bool VisitMemberExpr(MemberExpr *ME) { 16343 Expr *E = ME; 16344 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 16345 16346 if (isa<CXXThisExpr>(BaseE)) { 16347 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16348 // We found a base expression: this->Val. 16349 RelevantExpr = ME; 16350 } else { 16351 E = BaseE; 16352 } 16353 16354 if (!isa<FieldDecl>(ME->getMemberDecl())) { 16355 if (!NoDiagnose) { 16356 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 16357 << ME->getSourceRange(); 16358 return false; 16359 } 16360 if (RelevantExpr) 16361 return false; 16362 return Visit(E); 16363 } 16364 16365 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 16366 16367 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 16368 // A bit-field cannot appear in a map clause. 16369 // 16370 if (FD->isBitField()) { 16371 if (!NoDiagnose) { 16372 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 16373 << ME->getSourceRange() << getOpenMPClauseName(CKind); 16374 return false; 16375 } 16376 if (RelevantExpr) 16377 return false; 16378 return Visit(E); 16379 } 16380 16381 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16382 // If the type of a list item is a reference to a type T then the type 16383 // will be considered to be T for all purposes of this clause. 16384 QualType CurType = BaseE->getType().getNonReferenceType(); 16385 16386 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 16387 // A list item cannot be a variable that is a member of a structure with 16388 // a union type. 16389 // 16390 if (CurType->isUnionType()) { 16391 if (!NoDiagnose) { 16392 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 16393 << ME->getSourceRange(); 16394 return false; 16395 } 16396 return RelevantExpr || Visit(E); 16397 } 16398 16399 // If we got a member expression, we should not expect any array section 16400 // before that: 16401 // 16402 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 16403 // If a list item is an element of a structure, only the rightmost symbol 16404 // of the variable reference can be an array section. 16405 // 16406 AllowUnitySizeArraySection = false; 16407 AllowWholeSizeArraySection = false; 16408 16409 // Record the component. 16410 Components.emplace_back(ME, FD); 16411 return RelevantExpr || Visit(E); 16412 } 16413 16414 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 16415 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 16416 16417 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 16418 if (!NoDiagnose) { 16419 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16420 << 0 << AE->getSourceRange(); 16421 return false; 16422 } 16423 return RelevantExpr || Visit(E); 16424 } 16425 16426 // If we got an array subscript that express the whole dimension we 16427 // can have any array expressions before. If it only expressing part of 16428 // the dimension, we can only have unitary-size array expressions. 16429 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, 16430 E->getType())) 16431 AllowWholeSizeArraySection = false; 16432 16433 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 16434 Expr::EvalResult Result; 16435 if (!AE->getIdx()->isValueDependent() && 16436 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 16437 !Result.Val.getInt().isNullValue()) { 16438 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16439 diag::err_omp_invalid_map_this_expr); 16440 SemaRef.Diag(AE->getIdx()->getExprLoc(), 16441 diag::note_omp_invalid_subscript_on_this_ptr_map); 16442 } 16443 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16444 RelevantExpr = TE; 16445 } 16446 16447 // Record the component - we don't have any declaration associated. 16448 Components.emplace_back(AE, nullptr); 16449 16450 return RelevantExpr || Visit(E); 16451 } 16452 16453 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 16454 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 16455 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16456 QualType CurType = 16457 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16458 16459 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16460 // If the type of a list item is a reference to a type T then the type 16461 // will be considered to be T for all purposes of this clause. 16462 if (CurType->isReferenceType()) 16463 CurType = CurType->getPointeeType(); 16464 16465 bool IsPointer = CurType->isAnyPointerType(); 16466 16467 if (!IsPointer && !CurType->isArrayType()) { 16468 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 16469 << 0 << OASE->getSourceRange(); 16470 return false; 16471 } 16472 16473 bool NotWhole = 16474 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 16475 bool NotUnity = 16476 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 16477 16478 if (AllowWholeSizeArraySection) { 16479 // Any array section is currently allowed. Allowing a whole size array 16480 // section implies allowing a unity array section as well. 16481 // 16482 // If this array section refers to the whole dimension we can still 16483 // accept other array sections before this one, except if the base is a 16484 // pointer. Otherwise, only unitary sections are accepted. 16485 if (NotWhole || IsPointer) 16486 AllowWholeSizeArraySection = false; 16487 } else if (AllowUnitySizeArraySection && NotUnity) { 16488 // A unity or whole array section is not allowed and that is not 16489 // compatible with the properties of the current array section. 16490 SemaRef.Diag( 16491 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 16492 << OASE->getSourceRange(); 16493 return false; 16494 } 16495 16496 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 16497 Expr::EvalResult ResultR; 16498 Expr::EvalResult ResultL; 16499 if (!OASE->getLength()->isValueDependent() && 16500 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 16501 !ResultR.Val.getInt().isOneValue()) { 16502 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16503 diag::err_omp_invalid_map_this_expr); 16504 SemaRef.Diag(OASE->getLength()->getExprLoc(), 16505 diag::note_omp_invalid_length_on_this_ptr_mapping); 16506 } 16507 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 16508 OASE->getLowerBound()->EvaluateAsInt(ResultL, 16509 SemaRef.getASTContext()) && 16510 !ResultL.Val.getInt().isNullValue()) { 16511 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16512 diag::err_omp_invalid_map_this_expr); 16513 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 16514 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 16515 } 16516 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16517 RelevantExpr = TE; 16518 } 16519 16520 // Record the component - we don't have any declaration associated. 16521 Components.emplace_back(OASE, nullptr); 16522 return RelevantExpr || Visit(E); 16523 } 16524 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 16525 Expr *Base = E->getBase(); 16526 16527 // Record the component - we don't have any declaration associated. 16528 Components.emplace_back(E, nullptr); 16529 16530 return Visit(Base->IgnoreParenImpCasts()); 16531 } 16532 16533 bool VisitUnaryOperator(UnaryOperator *UO) { 16534 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 16535 UO->getOpcode() != UO_Deref) { 16536 emitErrorMsg(); 16537 return false; 16538 } 16539 if (!RelevantExpr) { 16540 // Record the component if haven't found base decl. 16541 Components.emplace_back(UO, nullptr); 16542 } 16543 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 16544 } 16545 bool VisitBinaryOperator(BinaryOperator *BO) { 16546 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 16547 emitErrorMsg(); 16548 return false; 16549 } 16550 16551 // Pointer arithmetic is the only thing we expect to happen here so after we 16552 // make sure the binary operator is a pointer type, the we only thing need 16553 // to to is to visit the subtree that has the same type as root (so that we 16554 // know the other subtree is just an offset) 16555 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 16556 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 16557 Components.emplace_back(BO, nullptr); 16558 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 16559 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 16560 "Either LHS or RHS have base decl inside"); 16561 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 16562 return RelevantExpr || Visit(LE); 16563 return RelevantExpr || Visit(RE); 16564 } 16565 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 16566 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 16567 RelevantExpr = CTE; 16568 Components.emplace_back(CTE, nullptr); 16569 return true; 16570 } 16571 bool VisitStmt(Stmt *) { 16572 emitErrorMsg(); 16573 return false; 16574 } 16575 const Expr *getFoundBase() const { 16576 return RelevantExpr; 16577 } 16578 explicit MapBaseChecker( 16579 Sema &SemaRef, OpenMPClauseKind CKind, 16580 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 16581 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 16582 : SemaRef(SemaRef), CKind(CKind), Components(Components), 16583 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 16584 }; 16585 } // namespace 16586 16587 /// Return the expression of the base of the mappable expression or null if it 16588 /// cannot be determined and do all the necessary checks to see if the expression 16589 /// is valid as a standalone mappable expression. In the process, record all the 16590 /// components of the expression. 16591 static const Expr *checkMapClauseExpressionBase( 16592 Sema &SemaRef, Expr *E, 16593 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 16594 OpenMPClauseKind CKind, bool NoDiagnose) { 16595 SourceLocation ELoc = E->getExprLoc(); 16596 SourceRange ERange = E->getSourceRange(); 16597 MapBaseChecker Checker(SemaRef, CKind, CurComponents, NoDiagnose, ELoc, 16598 ERange); 16599 if (Checker.Visit(E->IgnoreParens())) 16600 return Checker.getFoundBase(); 16601 return nullptr; 16602 } 16603 16604 // Return true if expression E associated with value VD has conflicts with other 16605 // map information. 16606 static bool checkMapConflicts( 16607 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 16608 bool CurrentRegionOnly, 16609 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 16610 OpenMPClauseKind CKind) { 16611 assert(VD && E); 16612 SourceLocation ELoc = E->getExprLoc(); 16613 SourceRange ERange = E->getSourceRange(); 16614 16615 // In order to easily check the conflicts we need to match each component of 16616 // the expression under test with the components of the expressions that are 16617 // already in the stack. 16618 16619 assert(!CurComponents.empty() && "Map clause expression with no components!"); 16620 assert(CurComponents.back().getAssociatedDeclaration() == VD && 16621 "Map clause expression with unexpected base!"); 16622 16623 // Variables to help detecting enclosing problems in data environment nests. 16624 bool IsEnclosedByDataEnvironmentExpr = false; 16625 const Expr *EnclosingExpr = nullptr; 16626 16627 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 16628 VD, CurrentRegionOnly, 16629 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 16630 ERange, CKind, &EnclosingExpr, 16631 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 16632 StackComponents, 16633 OpenMPClauseKind) { 16634 assert(!StackComponents.empty() && 16635 "Map clause expression with no components!"); 16636 assert(StackComponents.back().getAssociatedDeclaration() == VD && 16637 "Map clause expression with unexpected base!"); 16638 (void)VD; 16639 16640 // The whole expression in the stack. 16641 const Expr *RE = StackComponents.front().getAssociatedExpression(); 16642 16643 // Expressions must start from the same base. Here we detect at which 16644 // point both expressions diverge from each other and see if we can 16645 // detect if the memory referred to both expressions is contiguous and 16646 // do not overlap. 16647 auto CI = CurComponents.rbegin(); 16648 auto CE = CurComponents.rend(); 16649 auto SI = StackComponents.rbegin(); 16650 auto SE = StackComponents.rend(); 16651 for (; CI != CE && SI != SE; ++CI, ++SI) { 16652 16653 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 16654 // At most one list item can be an array item derived from a given 16655 // variable in map clauses of the same construct. 16656 if (CurrentRegionOnly && 16657 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 16658 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 16659 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 16660 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 16661 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 16662 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 16663 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 16664 diag::err_omp_multiple_array_items_in_map_clause) 16665 << CI->getAssociatedExpression()->getSourceRange(); 16666 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 16667 diag::note_used_here) 16668 << SI->getAssociatedExpression()->getSourceRange(); 16669 return true; 16670 } 16671 16672 // Do both expressions have the same kind? 16673 if (CI->getAssociatedExpression()->getStmtClass() != 16674 SI->getAssociatedExpression()->getStmtClass()) 16675 break; 16676 16677 // Are we dealing with different variables/fields? 16678 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 16679 break; 16680 } 16681 // Check if the extra components of the expressions in the enclosing 16682 // data environment are redundant for the current base declaration. 16683 // If they are, the maps completely overlap, which is legal. 16684 for (; SI != SE; ++SI) { 16685 QualType Type; 16686 if (const auto *ASE = 16687 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 16688 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 16689 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 16690 SI->getAssociatedExpression())) { 16691 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 16692 Type = 16693 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 16694 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 16695 SI->getAssociatedExpression())) { 16696 Type = OASE->getBase()->getType()->getPointeeType(); 16697 } 16698 if (Type.isNull() || Type->isAnyPointerType() || 16699 checkArrayExpressionDoesNotReferToWholeSize( 16700 SemaRef, SI->getAssociatedExpression(), Type)) 16701 break; 16702 } 16703 16704 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16705 // List items of map clauses in the same construct must not share 16706 // original storage. 16707 // 16708 // If the expressions are exactly the same or one is a subset of the 16709 // other, it means they are sharing storage. 16710 if (CI == CE && SI == SE) { 16711 if (CurrentRegionOnly) { 16712 if (CKind == OMPC_map) { 16713 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16714 } else { 16715 assert(CKind == OMPC_to || CKind == OMPC_from); 16716 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16717 << ERange; 16718 } 16719 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16720 << RE->getSourceRange(); 16721 return true; 16722 } 16723 // If we find the same expression in the enclosing data environment, 16724 // that is legal. 16725 IsEnclosedByDataEnvironmentExpr = true; 16726 return false; 16727 } 16728 16729 QualType DerivedType = 16730 std::prev(CI)->getAssociatedDeclaration()->getType(); 16731 SourceLocation DerivedLoc = 16732 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 16733 16734 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 16735 // If the type of a list item is a reference to a type T then the type 16736 // will be considered to be T for all purposes of this clause. 16737 DerivedType = DerivedType.getNonReferenceType(); 16738 16739 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 16740 // A variable for which the type is pointer and an array section 16741 // derived from that variable must not appear as list items of map 16742 // clauses of the same construct. 16743 // 16744 // Also, cover one of the cases in: 16745 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16746 // If any part of the original storage of a list item has corresponding 16747 // storage in the device data environment, all of the original storage 16748 // must have corresponding storage in the device data environment. 16749 // 16750 if (DerivedType->isAnyPointerType()) { 16751 if (CI == CE || SI == SE) { 16752 SemaRef.Diag( 16753 DerivedLoc, 16754 diag::err_omp_pointer_mapped_along_with_derived_section) 16755 << DerivedLoc; 16756 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16757 << RE->getSourceRange(); 16758 return true; 16759 } 16760 if (CI->getAssociatedExpression()->getStmtClass() != 16761 SI->getAssociatedExpression()->getStmtClass() || 16762 CI->getAssociatedDeclaration()->getCanonicalDecl() == 16763 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 16764 assert(CI != CE && SI != SE); 16765 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 16766 << DerivedLoc; 16767 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16768 << RE->getSourceRange(); 16769 return true; 16770 } 16771 } 16772 16773 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 16774 // List items of map clauses in the same construct must not share 16775 // original storage. 16776 // 16777 // An expression is a subset of the other. 16778 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 16779 if (CKind == OMPC_map) { 16780 if (CI != CE || SI != SE) { 16781 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 16782 // a pointer. 16783 auto Begin = 16784 CI != CE ? CurComponents.begin() : StackComponents.begin(); 16785 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 16786 auto It = Begin; 16787 while (It != End && !It->getAssociatedDeclaration()) 16788 std::advance(It, 1); 16789 assert(It != End && 16790 "Expected at least one component with the declaration."); 16791 if (It != Begin && It->getAssociatedDeclaration() 16792 ->getType() 16793 .getCanonicalType() 16794 ->isAnyPointerType()) { 16795 IsEnclosedByDataEnvironmentExpr = false; 16796 EnclosingExpr = nullptr; 16797 return false; 16798 } 16799 } 16800 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 16801 } else { 16802 assert(CKind == OMPC_to || CKind == OMPC_from); 16803 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 16804 << ERange; 16805 } 16806 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 16807 << RE->getSourceRange(); 16808 return true; 16809 } 16810 16811 // The current expression uses the same base as other expression in the 16812 // data environment but does not contain it completely. 16813 if (!CurrentRegionOnly && SI != SE) 16814 EnclosingExpr = RE; 16815 16816 // The current expression is a subset of the expression in the data 16817 // environment. 16818 IsEnclosedByDataEnvironmentExpr |= 16819 (!CurrentRegionOnly && CI != CE && SI == SE); 16820 16821 return false; 16822 }); 16823 16824 if (CurrentRegionOnly) 16825 return FoundError; 16826 16827 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 16828 // If any part of the original storage of a list item has corresponding 16829 // storage in the device data environment, all of the original storage must 16830 // have corresponding storage in the device data environment. 16831 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 16832 // If a list item is an element of a structure, and a different element of 16833 // the structure has a corresponding list item in the device data environment 16834 // prior to a task encountering the construct associated with the map clause, 16835 // then the list item must also have a corresponding list item in the device 16836 // data environment prior to the task encountering the construct. 16837 // 16838 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 16839 SemaRef.Diag(ELoc, 16840 diag::err_omp_original_storage_is_shared_and_does_not_contain) 16841 << ERange; 16842 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 16843 << EnclosingExpr->getSourceRange(); 16844 return true; 16845 } 16846 16847 return FoundError; 16848 } 16849 16850 // Look up the user-defined mapper given the mapper name and mapped type, and 16851 // build a reference to it. 16852 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 16853 CXXScopeSpec &MapperIdScopeSpec, 16854 const DeclarationNameInfo &MapperId, 16855 QualType Type, 16856 Expr *UnresolvedMapper) { 16857 if (MapperIdScopeSpec.isInvalid()) 16858 return ExprError(); 16859 // Get the actual type for the array type. 16860 if (Type->isArrayType()) { 16861 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 16862 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 16863 } 16864 // Find all user-defined mappers with the given MapperId. 16865 SmallVector<UnresolvedSet<8>, 4> Lookups; 16866 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 16867 Lookup.suppressDiagnostics(); 16868 if (S) { 16869 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 16870 NamedDecl *D = Lookup.getRepresentativeDecl(); 16871 while (S && !S->isDeclScope(D)) 16872 S = S->getParent(); 16873 if (S) 16874 S = S->getParent(); 16875 Lookups.emplace_back(); 16876 Lookups.back().append(Lookup.begin(), Lookup.end()); 16877 Lookup.clear(); 16878 } 16879 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 16880 // Extract the user-defined mappers with the given MapperId. 16881 Lookups.push_back(UnresolvedSet<8>()); 16882 for (NamedDecl *D : ULE->decls()) { 16883 auto *DMD = cast<OMPDeclareMapperDecl>(D); 16884 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 16885 Lookups.back().addDecl(DMD); 16886 } 16887 } 16888 // Defer the lookup for dependent types. The results will be passed through 16889 // UnresolvedMapper on instantiation. 16890 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 16891 Type->isInstantiationDependentType() || 16892 Type->containsUnexpandedParameterPack() || 16893 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 16894 return !D->isInvalidDecl() && 16895 (D->getType()->isDependentType() || 16896 D->getType()->isInstantiationDependentType() || 16897 D->getType()->containsUnexpandedParameterPack()); 16898 })) { 16899 UnresolvedSet<8> URS; 16900 for (const UnresolvedSet<8> &Set : Lookups) { 16901 if (Set.empty()) 16902 continue; 16903 URS.append(Set.begin(), Set.end()); 16904 } 16905 return UnresolvedLookupExpr::Create( 16906 SemaRef.Context, /*NamingClass=*/nullptr, 16907 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 16908 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 16909 } 16910 SourceLocation Loc = MapperId.getLoc(); 16911 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 16912 // The type must be of struct, union or class type in C and C++ 16913 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 16914 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 16915 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 16916 return ExprError(); 16917 } 16918 // Perform argument dependent lookup. 16919 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 16920 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 16921 // Return the first user-defined mapper with the desired type. 16922 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16923 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 16924 if (!D->isInvalidDecl() && 16925 SemaRef.Context.hasSameType(D->getType(), Type)) 16926 return D; 16927 return nullptr; 16928 })) 16929 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16930 // Find the first user-defined mapper with a type derived from the desired 16931 // type. 16932 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 16933 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 16934 if (!D->isInvalidDecl() && 16935 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 16936 !Type.isMoreQualifiedThan(D->getType())) 16937 return D; 16938 return nullptr; 16939 })) { 16940 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 16941 /*DetectVirtual=*/false); 16942 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 16943 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 16944 VD->getType().getUnqualifiedType()))) { 16945 if (SemaRef.CheckBaseClassAccess( 16946 Loc, VD->getType(), Type, Paths.front(), 16947 /*DiagID=*/0) != Sema::AR_inaccessible) { 16948 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 16949 } 16950 } 16951 } 16952 } 16953 // Report error if a mapper is specified, but cannot be found. 16954 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 16955 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 16956 << Type << MapperId.getName(); 16957 return ExprError(); 16958 } 16959 return ExprEmpty(); 16960 } 16961 16962 namespace { 16963 // Utility struct that gathers all the related lists associated with a mappable 16964 // expression. 16965 struct MappableVarListInfo { 16966 // The list of expressions. 16967 ArrayRef<Expr *> VarList; 16968 // The list of processed expressions. 16969 SmallVector<Expr *, 16> ProcessedVarList; 16970 // The mappble components for each expression. 16971 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 16972 // The base declaration of the variable. 16973 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 16974 // The reference to the user-defined mapper associated with every expression. 16975 SmallVector<Expr *, 16> UDMapperList; 16976 16977 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 16978 // We have a list of components and base declarations for each entry in the 16979 // variable list. 16980 VarComponents.reserve(VarList.size()); 16981 VarBaseDeclarations.reserve(VarList.size()); 16982 } 16983 }; 16984 } 16985 16986 // Check the validity of the provided variable list for the provided clause kind 16987 // \a CKind. In the check process the valid expressions, mappable expression 16988 // components, variables, and user-defined mappers are extracted and used to 16989 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 16990 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 16991 // and \a MapperId are expected to be valid if the clause kind is 'map'. 16992 static void checkMappableExpressionList( 16993 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 16994 MappableVarListInfo &MVLI, SourceLocation StartLoc, 16995 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 16996 ArrayRef<Expr *> UnresolvedMappers, 16997 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 16998 bool IsMapTypeImplicit = false) { 16999 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 17000 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 17001 "Unexpected clause kind with mappable expressions!"); 17002 17003 // If the identifier of user-defined mapper is not specified, it is "default". 17004 // We do not change the actual name in this clause to distinguish whether a 17005 // mapper is specified explicitly, i.e., it is not explicitly specified when 17006 // MapperId.getName() is empty. 17007 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 17008 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 17009 MapperId.setName(DeclNames.getIdentifier( 17010 &SemaRef.getASTContext().Idents.get("default"))); 17011 } 17012 17013 // Iterators to find the current unresolved mapper expression. 17014 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 17015 bool UpdateUMIt = false; 17016 Expr *UnresolvedMapper = nullptr; 17017 17018 // Keep track of the mappable components and base declarations in this clause. 17019 // Each entry in the list is going to have a list of components associated. We 17020 // record each set of the components so that we can build the clause later on. 17021 // In the end we should have the same amount of declarations and component 17022 // lists. 17023 17024 for (Expr *RE : MVLI.VarList) { 17025 assert(RE && "Null expr in omp to/from/map clause"); 17026 SourceLocation ELoc = RE->getExprLoc(); 17027 17028 // Find the current unresolved mapper expression. 17029 if (UpdateUMIt && UMIt != UMEnd) { 17030 UMIt++; 17031 assert( 17032 UMIt != UMEnd && 17033 "Expect the size of UnresolvedMappers to match with that of VarList"); 17034 } 17035 UpdateUMIt = true; 17036 if (UMIt != UMEnd) 17037 UnresolvedMapper = *UMIt; 17038 17039 const Expr *VE = RE->IgnoreParenLValueCasts(); 17040 17041 if (VE->isValueDependent() || VE->isTypeDependent() || 17042 VE->isInstantiationDependent() || 17043 VE->containsUnexpandedParameterPack()) { 17044 // Try to find the associated user-defined mapper. 17045 ExprResult ER = buildUserDefinedMapperRef( 17046 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17047 VE->getType().getCanonicalType(), UnresolvedMapper); 17048 if (ER.isInvalid()) 17049 continue; 17050 MVLI.UDMapperList.push_back(ER.get()); 17051 // We can only analyze this information once the missing information is 17052 // resolved. 17053 MVLI.ProcessedVarList.push_back(RE); 17054 continue; 17055 } 17056 17057 Expr *SimpleExpr = RE->IgnoreParenCasts(); 17058 17059 if (!RE->isLValue()) { 17060 if (SemaRef.getLangOpts().OpenMP < 50) { 17061 SemaRef.Diag( 17062 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 17063 << RE->getSourceRange(); 17064 } else { 17065 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 17066 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 17067 } 17068 continue; 17069 } 17070 17071 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 17072 ValueDecl *CurDeclaration = nullptr; 17073 17074 // Obtain the array or member expression bases if required. Also, fill the 17075 // components array with all the components identified in the process. 17076 const Expr *BE = checkMapClauseExpressionBase( 17077 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 17078 if (!BE) 17079 continue; 17080 17081 assert(!CurComponents.empty() && 17082 "Invalid mappable expression information."); 17083 17084 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 17085 // Add store "this" pointer to class in DSAStackTy for future checking 17086 DSAS->addMappedClassesQualTypes(TE->getType()); 17087 // Try to find the associated user-defined mapper. 17088 ExprResult ER = buildUserDefinedMapperRef( 17089 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17090 VE->getType().getCanonicalType(), UnresolvedMapper); 17091 if (ER.isInvalid()) 17092 continue; 17093 MVLI.UDMapperList.push_back(ER.get()); 17094 // Skip restriction checking for variable or field declarations 17095 MVLI.ProcessedVarList.push_back(RE); 17096 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17097 MVLI.VarComponents.back().append(CurComponents.begin(), 17098 CurComponents.end()); 17099 MVLI.VarBaseDeclarations.push_back(nullptr); 17100 continue; 17101 } 17102 17103 // For the following checks, we rely on the base declaration which is 17104 // expected to be associated with the last component. The declaration is 17105 // expected to be a variable or a field (if 'this' is being mapped). 17106 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 17107 assert(CurDeclaration && "Null decl on map clause."); 17108 assert( 17109 CurDeclaration->isCanonicalDecl() && 17110 "Expecting components to have associated only canonical declarations."); 17111 17112 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 17113 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 17114 17115 assert((VD || FD) && "Only variables or fields are expected here!"); 17116 (void)FD; 17117 17118 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 17119 // threadprivate variables cannot appear in a map clause. 17120 // OpenMP 4.5 [2.10.5, target update Construct] 17121 // threadprivate variables cannot appear in a from clause. 17122 if (VD && DSAS->isThreadPrivate(VD)) { 17123 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17124 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 17125 << getOpenMPClauseName(CKind); 17126 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 17127 continue; 17128 } 17129 17130 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17131 // A list item cannot appear in both a map clause and a data-sharing 17132 // attribute clause on the same construct. 17133 17134 // Check conflicts with other map clause expressions. We check the conflicts 17135 // with the current construct separately from the enclosing data 17136 // environment, because the restrictions are different. We only have to 17137 // check conflicts across regions for the map clauses. 17138 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17139 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 17140 break; 17141 if (CKind == OMPC_map && 17142 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 17143 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 17144 break; 17145 17146 // OpenMP 4.5 [2.10.5, target update Construct] 17147 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 17148 // If the type of a list item is a reference to a type T then the type will 17149 // be considered to be T for all purposes of this clause. 17150 auto I = llvm::find_if( 17151 CurComponents, 17152 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 17153 return MC.getAssociatedDeclaration(); 17154 }); 17155 assert(I != CurComponents.end() && "Null decl on map clause."); 17156 QualType Type; 17157 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 17158 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 17159 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 17160 if (ASE) { 17161 Type = ASE->getType().getNonReferenceType(); 17162 } else if (OASE) { 17163 QualType BaseType = 17164 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 17165 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 17166 Type = ATy->getElementType(); 17167 else 17168 Type = BaseType->getPointeeType(); 17169 Type = Type.getNonReferenceType(); 17170 } else if (OAShE) { 17171 Type = OAShE->getBase()->getType()->getPointeeType(); 17172 } else { 17173 Type = VE->getType(); 17174 } 17175 17176 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 17177 // A list item in a to or from clause must have a mappable type. 17178 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 17179 // A list item must have a mappable type. 17180 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 17181 DSAS, Type)) 17182 continue; 17183 17184 Type = I->getAssociatedDeclaration()->getType().getNonReferenceType(); 17185 17186 if (CKind == OMPC_map) { 17187 // target enter data 17188 // OpenMP [2.10.2, Restrictions, p. 99] 17189 // A map-type must be specified in all map clauses and must be either 17190 // to or alloc. 17191 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 17192 if (DKind == OMPD_target_enter_data && 17193 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 17194 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17195 << (IsMapTypeImplicit ? 1 : 0) 17196 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17197 << getOpenMPDirectiveName(DKind); 17198 continue; 17199 } 17200 17201 // target exit_data 17202 // OpenMP [2.10.3, Restrictions, p. 102] 17203 // A map-type must be specified in all map clauses and must be either 17204 // from, release, or delete. 17205 if (DKind == OMPD_target_exit_data && 17206 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 17207 MapType == OMPC_MAP_delete)) { 17208 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17209 << (IsMapTypeImplicit ? 1 : 0) 17210 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17211 << getOpenMPDirectiveName(DKind); 17212 continue; 17213 } 17214 17215 // target, target data 17216 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 17217 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 17218 // A map-type in a map clause must be to, from, tofrom or alloc 17219 if ((DKind == OMPD_target_data || 17220 isOpenMPTargetExecutionDirective(DKind)) && 17221 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 17222 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 17223 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 17224 << (IsMapTypeImplicit ? 1 : 0) 17225 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 17226 << getOpenMPDirectiveName(DKind); 17227 continue; 17228 } 17229 17230 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17231 // A list item cannot appear in both a map clause and a data-sharing 17232 // attribute clause on the same construct 17233 // 17234 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17235 // A list item cannot appear in both a map clause and a data-sharing 17236 // attribute clause on the same construct unless the construct is a 17237 // combined construct. 17238 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 17239 isOpenMPTargetExecutionDirective(DKind)) || 17240 DKind == OMPD_target)) { 17241 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 17242 if (isOpenMPPrivate(DVar.CKind)) { 17243 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17244 << getOpenMPClauseName(DVar.CKind) 17245 << getOpenMPClauseName(OMPC_map) 17246 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 17247 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 17248 continue; 17249 } 17250 } 17251 } 17252 17253 // Try to find the associated user-defined mapper. 17254 ExprResult ER = buildUserDefinedMapperRef( 17255 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 17256 Type.getCanonicalType(), UnresolvedMapper); 17257 if (ER.isInvalid()) 17258 continue; 17259 MVLI.UDMapperList.push_back(ER.get()); 17260 17261 // Save the current expression. 17262 MVLI.ProcessedVarList.push_back(RE); 17263 17264 // Store the components in the stack so that they can be used to check 17265 // against other clauses later on. 17266 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 17267 /*WhereFoundClauseKind=*/OMPC_map); 17268 17269 // Save the components and declaration to create the clause. For purposes of 17270 // the clause creation, any component list that has has base 'this' uses 17271 // null as base declaration. 17272 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 17273 MVLI.VarComponents.back().append(CurComponents.begin(), 17274 CurComponents.end()); 17275 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 17276 : CurDeclaration); 17277 } 17278 } 17279 17280 OMPClause *Sema::ActOnOpenMPMapClause( 17281 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 17282 ArrayRef<SourceLocation> MapTypeModifiersLoc, 17283 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 17284 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 17285 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 17286 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 17287 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 17288 OMPC_MAP_MODIFIER_unknown, 17289 OMPC_MAP_MODIFIER_unknown}; 17290 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 17291 17292 // Process map-type-modifiers, flag errors for duplicate modifiers. 17293 unsigned Count = 0; 17294 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 17295 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 17296 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 17297 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 17298 continue; 17299 } 17300 assert(Count < NumberOfOMPMapClauseModifiers && 17301 "Modifiers exceed the allowed number of map type modifiers"); 17302 Modifiers[Count] = MapTypeModifiers[I]; 17303 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 17304 ++Count; 17305 } 17306 17307 MappableVarListInfo MVLI(VarList); 17308 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 17309 MapperIdScopeSpec, MapperId, UnresolvedMappers, 17310 MapType, IsMapTypeImplicit); 17311 17312 // We need to produce a map clause even if we don't have variables so that 17313 // other diagnostics related with non-existing map clauses are accurate. 17314 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 17315 MVLI.VarBaseDeclarations, MVLI.VarComponents, 17316 MVLI.UDMapperList, Modifiers, ModifiersLoc, 17317 MapperIdScopeSpec.getWithLocInContext(Context), 17318 MapperId, MapType, IsMapTypeImplicit, MapLoc); 17319 } 17320 17321 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 17322 TypeResult ParsedType) { 17323 assert(ParsedType.isUsable()); 17324 17325 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 17326 if (ReductionType.isNull()) 17327 return QualType(); 17328 17329 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 17330 // A type name in a declare reduction directive cannot be a function type, an 17331 // array type, a reference type, or a type qualified with const, volatile or 17332 // restrict. 17333 if (ReductionType.hasQualifiers()) { 17334 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 17335 return QualType(); 17336 } 17337 17338 if (ReductionType->isFunctionType()) { 17339 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 17340 return QualType(); 17341 } 17342 if (ReductionType->isReferenceType()) { 17343 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 17344 return QualType(); 17345 } 17346 if (ReductionType->isArrayType()) { 17347 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 17348 return QualType(); 17349 } 17350 return ReductionType; 17351 } 17352 17353 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 17354 Scope *S, DeclContext *DC, DeclarationName Name, 17355 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 17356 AccessSpecifier AS, Decl *PrevDeclInScope) { 17357 SmallVector<Decl *, 8> Decls; 17358 Decls.reserve(ReductionTypes.size()); 17359 17360 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 17361 forRedeclarationInCurContext()); 17362 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 17363 // A reduction-identifier may not be re-declared in the current scope for the 17364 // same type or for a type that is compatible according to the base language 17365 // rules. 17366 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17367 OMPDeclareReductionDecl *PrevDRD = nullptr; 17368 bool InCompoundScope = true; 17369 if (S != nullptr) { 17370 // Find previous declaration with the same name not referenced in other 17371 // declarations. 17372 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17373 InCompoundScope = 17374 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17375 LookupName(Lookup, S); 17376 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17377 /*AllowInlineNamespace=*/false); 17378 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 17379 LookupResult::Filter Filter = Lookup.makeFilter(); 17380 while (Filter.hasNext()) { 17381 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 17382 if (InCompoundScope) { 17383 auto I = UsedAsPrevious.find(PrevDecl); 17384 if (I == UsedAsPrevious.end()) 17385 UsedAsPrevious[PrevDecl] = false; 17386 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 17387 UsedAsPrevious[D] = true; 17388 } 17389 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17390 PrevDecl->getLocation(); 17391 } 17392 Filter.done(); 17393 if (InCompoundScope) { 17394 for (const auto &PrevData : UsedAsPrevious) { 17395 if (!PrevData.second) { 17396 PrevDRD = PrevData.first; 17397 break; 17398 } 17399 } 17400 } 17401 } else if (PrevDeclInScope != nullptr) { 17402 auto *PrevDRDInScope = PrevDRD = 17403 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 17404 do { 17405 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 17406 PrevDRDInScope->getLocation(); 17407 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 17408 } while (PrevDRDInScope != nullptr); 17409 } 17410 for (const auto &TyData : ReductionTypes) { 17411 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 17412 bool Invalid = false; 17413 if (I != PreviousRedeclTypes.end()) { 17414 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 17415 << TyData.first; 17416 Diag(I->second, diag::note_previous_definition); 17417 Invalid = true; 17418 } 17419 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 17420 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 17421 Name, TyData.first, PrevDRD); 17422 DC->addDecl(DRD); 17423 DRD->setAccess(AS); 17424 Decls.push_back(DRD); 17425 if (Invalid) 17426 DRD->setInvalidDecl(); 17427 else 17428 PrevDRD = DRD; 17429 } 17430 17431 return DeclGroupPtrTy::make( 17432 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 17433 } 17434 17435 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 17436 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17437 17438 // Enter new function scope. 17439 PushFunctionScope(); 17440 setFunctionHasBranchProtectedScope(); 17441 getCurFunction()->setHasOMPDeclareReductionCombiner(); 17442 17443 if (S != nullptr) 17444 PushDeclContext(S, DRD); 17445 else 17446 CurContext = DRD; 17447 17448 PushExpressionEvaluationContext( 17449 ExpressionEvaluationContext::PotentiallyEvaluated); 17450 17451 QualType ReductionType = DRD->getType(); 17452 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 17453 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 17454 // uses semantics of argument handles by value, but it should be passed by 17455 // reference. C lang does not support references, so pass all parameters as 17456 // pointers. 17457 // Create 'T omp_in;' variable. 17458 VarDecl *OmpInParm = 17459 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 17460 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 17461 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 17462 // uses semantics of argument handles by value, but it should be passed by 17463 // reference. C lang does not support references, so pass all parameters as 17464 // pointers. 17465 // Create 'T omp_out;' variable. 17466 VarDecl *OmpOutParm = 17467 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 17468 if (S != nullptr) { 17469 PushOnScopeChains(OmpInParm, S); 17470 PushOnScopeChains(OmpOutParm, S); 17471 } else { 17472 DRD->addDecl(OmpInParm); 17473 DRD->addDecl(OmpOutParm); 17474 } 17475 Expr *InE = 17476 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 17477 Expr *OutE = 17478 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 17479 DRD->setCombinerData(InE, OutE); 17480 } 17481 17482 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 17483 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17484 DiscardCleanupsInEvaluationContext(); 17485 PopExpressionEvaluationContext(); 17486 17487 PopDeclContext(); 17488 PopFunctionScopeInfo(); 17489 17490 if (Combiner != nullptr) 17491 DRD->setCombiner(Combiner); 17492 else 17493 DRD->setInvalidDecl(); 17494 } 17495 17496 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 17497 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17498 17499 // Enter new function scope. 17500 PushFunctionScope(); 17501 setFunctionHasBranchProtectedScope(); 17502 17503 if (S != nullptr) 17504 PushDeclContext(S, DRD); 17505 else 17506 CurContext = DRD; 17507 17508 PushExpressionEvaluationContext( 17509 ExpressionEvaluationContext::PotentiallyEvaluated); 17510 17511 QualType ReductionType = DRD->getType(); 17512 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 17513 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 17514 // uses semantics of argument handles by value, but it should be passed by 17515 // reference. C lang does not support references, so pass all parameters as 17516 // pointers. 17517 // Create 'T omp_priv;' variable. 17518 VarDecl *OmpPrivParm = 17519 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 17520 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 17521 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 17522 // uses semantics of argument handles by value, but it should be passed by 17523 // reference. C lang does not support references, so pass all parameters as 17524 // pointers. 17525 // Create 'T omp_orig;' variable. 17526 VarDecl *OmpOrigParm = 17527 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 17528 if (S != nullptr) { 17529 PushOnScopeChains(OmpPrivParm, S); 17530 PushOnScopeChains(OmpOrigParm, S); 17531 } else { 17532 DRD->addDecl(OmpPrivParm); 17533 DRD->addDecl(OmpOrigParm); 17534 } 17535 Expr *OrigE = 17536 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 17537 Expr *PrivE = 17538 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 17539 DRD->setInitializerData(OrigE, PrivE); 17540 return OmpPrivParm; 17541 } 17542 17543 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 17544 VarDecl *OmpPrivParm) { 17545 auto *DRD = cast<OMPDeclareReductionDecl>(D); 17546 DiscardCleanupsInEvaluationContext(); 17547 PopExpressionEvaluationContext(); 17548 17549 PopDeclContext(); 17550 PopFunctionScopeInfo(); 17551 17552 if (Initializer != nullptr) { 17553 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 17554 } else if (OmpPrivParm->hasInit()) { 17555 DRD->setInitializer(OmpPrivParm->getInit(), 17556 OmpPrivParm->isDirectInit() 17557 ? OMPDeclareReductionDecl::DirectInit 17558 : OMPDeclareReductionDecl::CopyInit); 17559 } else { 17560 DRD->setInvalidDecl(); 17561 } 17562 } 17563 17564 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 17565 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 17566 for (Decl *D : DeclReductions.get()) { 17567 if (IsValid) { 17568 if (S) 17569 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 17570 /*AddToContext=*/false); 17571 } else { 17572 D->setInvalidDecl(); 17573 } 17574 } 17575 return DeclReductions; 17576 } 17577 17578 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 17579 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 17580 QualType T = TInfo->getType(); 17581 if (D.isInvalidType()) 17582 return true; 17583 17584 if (getLangOpts().CPlusPlus) { 17585 // Check that there are no default arguments (C++ only). 17586 CheckExtraCXXDefaultArguments(D); 17587 } 17588 17589 return CreateParsedType(T, TInfo); 17590 } 17591 17592 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 17593 TypeResult ParsedType) { 17594 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 17595 17596 QualType MapperType = GetTypeFromParser(ParsedType.get()); 17597 assert(!MapperType.isNull() && "Expect valid mapper type"); 17598 17599 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17600 // The type must be of struct, union or class type in C and C++ 17601 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 17602 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 17603 return QualType(); 17604 } 17605 return MapperType; 17606 } 17607 17608 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 17609 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 17610 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 17611 Decl *PrevDeclInScope) { 17612 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 17613 forRedeclarationInCurContext()); 17614 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 17615 // A mapper-identifier may not be redeclared in the current scope for the 17616 // same type or for a type that is compatible according to the base language 17617 // rules. 17618 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 17619 OMPDeclareMapperDecl *PrevDMD = nullptr; 17620 bool InCompoundScope = true; 17621 if (S != nullptr) { 17622 // Find previous declaration with the same name not referenced in other 17623 // declarations. 17624 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 17625 InCompoundScope = 17626 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 17627 LookupName(Lookup, S); 17628 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 17629 /*AllowInlineNamespace=*/false); 17630 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 17631 LookupResult::Filter Filter = Lookup.makeFilter(); 17632 while (Filter.hasNext()) { 17633 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 17634 if (InCompoundScope) { 17635 auto I = UsedAsPrevious.find(PrevDecl); 17636 if (I == UsedAsPrevious.end()) 17637 UsedAsPrevious[PrevDecl] = false; 17638 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 17639 UsedAsPrevious[D] = true; 17640 } 17641 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 17642 PrevDecl->getLocation(); 17643 } 17644 Filter.done(); 17645 if (InCompoundScope) { 17646 for (const auto &PrevData : UsedAsPrevious) { 17647 if (!PrevData.second) { 17648 PrevDMD = PrevData.first; 17649 break; 17650 } 17651 } 17652 } 17653 } else if (PrevDeclInScope) { 17654 auto *PrevDMDInScope = PrevDMD = 17655 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 17656 do { 17657 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 17658 PrevDMDInScope->getLocation(); 17659 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 17660 } while (PrevDMDInScope != nullptr); 17661 } 17662 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 17663 bool Invalid = false; 17664 if (I != PreviousRedeclTypes.end()) { 17665 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 17666 << MapperType << Name; 17667 Diag(I->second, diag::note_previous_definition); 17668 Invalid = true; 17669 } 17670 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 17671 MapperType, VN, PrevDMD); 17672 DC->addDecl(DMD); 17673 DMD->setAccess(AS); 17674 if (Invalid) 17675 DMD->setInvalidDecl(); 17676 17677 // Enter new function scope. 17678 PushFunctionScope(); 17679 setFunctionHasBranchProtectedScope(); 17680 17681 CurContext = DMD; 17682 17683 return DMD; 17684 } 17685 17686 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 17687 Scope *S, 17688 QualType MapperType, 17689 SourceLocation StartLoc, 17690 DeclarationName VN) { 17691 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 17692 if (S) 17693 PushOnScopeChains(VD, S); 17694 else 17695 DMD->addDecl(VD); 17696 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 17697 DMD->setMapperVarRef(MapperVarRefExpr); 17698 } 17699 17700 Sema::DeclGroupPtrTy 17701 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 17702 ArrayRef<OMPClause *> ClauseList) { 17703 PopDeclContext(); 17704 PopFunctionScopeInfo(); 17705 17706 if (D) { 17707 if (S) 17708 PushOnScopeChains(D, S, /*AddToContext=*/false); 17709 D->CreateClauses(Context, ClauseList); 17710 } 17711 17712 return DeclGroupPtrTy::make(DeclGroupRef(D)); 17713 } 17714 17715 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 17716 SourceLocation StartLoc, 17717 SourceLocation LParenLoc, 17718 SourceLocation EndLoc) { 17719 Expr *ValExpr = NumTeams; 17720 Stmt *HelperValStmt = nullptr; 17721 17722 // OpenMP [teams Constrcut, Restrictions] 17723 // The num_teams expression must evaluate to a positive integer value. 17724 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 17725 /*StrictlyPositive=*/true)) 17726 return nullptr; 17727 17728 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17729 OpenMPDirectiveKind CaptureRegion = 17730 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 17731 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17732 ValExpr = MakeFullExpr(ValExpr).get(); 17733 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17734 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17735 HelperValStmt = buildPreInits(Context, Captures); 17736 } 17737 17738 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 17739 StartLoc, LParenLoc, EndLoc); 17740 } 17741 17742 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 17743 SourceLocation StartLoc, 17744 SourceLocation LParenLoc, 17745 SourceLocation EndLoc) { 17746 Expr *ValExpr = ThreadLimit; 17747 Stmt *HelperValStmt = nullptr; 17748 17749 // OpenMP [teams Constrcut, Restrictions] 17750 // The thread_limit expression must evaluate to a positive integer value. 17751 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 17752 /*StrictlyPositive=*/true)) 17753 return nullptr; 17754 17755 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17756 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 17757 DKind, OMPC_thread_limit, LangOpts.OpenMP); 17758 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17759 ValExpr = MakeFullExpr(ValExpr).get(); 17760 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17761 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17762 HelperValStmt = buildPreInits(Context, Captures); 17763 } 17764 17765 return new (Context) OMPThreadLimitClause( 17766 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 17767 } 17768 17769 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 17770 SourceLocation StartLoc, 17771 SourceLocation LParenLoc, 17772 SourceLocation EndLoc) { 17773 Expr *ValExpr = Priority; 17774 Stmt *HelperValStmt = nullptr; 17775 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17776 17777 // OpenMP [2.9.1, task Constrcut] 17778 // The priority-value is a non-negative numerical scalar expression. 17779 if (!isNonNegativeIntegerValue( 17780 ValExpr, *this, OMPC_priority, 17781 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 17782 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17783 return nullptr; 17784 17785 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 17786 StartLoc, LParenLoc, EndLoc); 17787 } 17788 17789 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 17790 SourceLocation StartLoc, 17791 SourceLocation LParenLoc, 17792 SourceLocation EndLoc) { 17793 Expr *ValExpr = Grainsize; 17794 Stmt *HelperValStmt = nullptr; 17795 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17796 17797 // OpenMP [2.9.2, taskloop Constrcut] 17798 // The parameter of the grainsize clause must be a positive integer 17799 // expression. 17800 if (!isNonNegativeIntegerValue( 17801 ValExpr, *this, OMPC_grainsize, 17802 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17803 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17804 return nullptr; 17805 17806 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 17807 StartLoc, LParenLoc, EndLoc); 17808 } 17809 17810 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 17811 SourceLocation StartLoc, 17812 SourceLocation LParenLoc, 17813 SourceLocation EndLoc) { 17814 Expr *ValExpr = NumTasks; 17815 Stmt *HelperValStmt = nullptr; 17816 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17817 17818 // OpenMP [2.9.2, taskloop Constrcut] 17819 // The parameter of the num_tasks clause must be a positive integer 17820 // expression. 17821 if (!isNonNegativeIntegerValue( 17822 ValExpr, *this, OMPC_num_tasks, 17823 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 17824 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 17825 return nullptr; 17826 17827 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 17828 StartLoc, LParenLoc, EndLoc); 17829 } 17830 17831 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 17832 SourceLocation LParenLoc, 17833 SourceLocation EndLoc) { 17834 // OpenMP [2.13.2, critical construct, Description] 17835 // ... where hint-expression is an integer constant expression that evaluates 17836 // to a valid lock hint. 17837 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 17838 if (HintExpr.isInvalid()) 17839 return nullptr; 17840 return new (Context) 17841 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 17842 } 17843 17844 /// Tries to find omp_event_handle_t type. 17845 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 17846 DSAStackTy *Stack) { 17847 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 17848 if (!OMPEventHandleT.isNull()) 17849 return true; 17850 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 17851 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 17852 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 17853 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 17854 return false; 17855 } 17856 Stack->setOMPEventHandleT(PT.get()); 17857 return true; 17858 } 17859 17860 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 17861 SourceLocation LParenLoc, 17862 SourceLocation EndLoc) { 17863 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 17864 !Evt->isInstantiationDependent() && 17865 !Evt->containsUnexpandedParameterPack()) { 17866 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 17867 return nullptr; 17868 // OpenMP 5.0, 2.10.1 task Construct. 17869 // event-handle is a variable of the omp_event_handle_t type. 17870 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 17871 if (!Ref) { 17872 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 17873 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 17874 return nullptr; 17875 } 17876 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 17877 if (!VD) { 17878 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 17879 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 17880 return nullptr; 17881 } 17882 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 17883 VD->getType()) || 17884 VD->getType().isConstant(Context)) { 17885 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 17886 << "omp_event_handle_t" << 1 << VD->getType() 17887 << Evt->getSourceRange(); 17888 return nullptr; 17889 } 17890 // OpenMP 5.0, 2.10.1 task Construct 17891 // [detach clause]... The event-handle will be considered as if it was 17892 // specified on a firstprivate clause. 17893 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 17894 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 17895 DVar.RefExpr) { 17896 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 17897 << getOpenMPClauseName(DVar.CKind) 17898 << getOpenMPClauseName(OMPC_firstprivate); 17899 reportOriginalDsa(*this, DSAStack, VD, DVar); 17900 return nullptr; 17901 } 17902 } 17903 17904 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 17905 } 17906 17907 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 17908 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 17909 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 17910 SourceLocation EndLoc) { 17911 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 17912 std::string Values; 17913 Values += "'"; 17914 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 17915 Values += "'"; 17916 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17917 << Values << getOpenMPClauseName(OMPC_dist_schedule); 17918 return nullptr; 17919 } 17920 Expr *ValExpr = ChunkSize; 17921 Stmt *HelperValStmt = nullptr; 17922 if (ChunkSize) { 17923 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 17924 !ChunkSize->isInstantiationDependent() && 17925 !ChunkSize->containsUnexpandedParameterPack()) { 17926 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 17927 ExprResult Val = 17928 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 17929 if (Val.isInvalid()) 17930 return nullptr; 17931 17932 ValExpr = Val.get(); 17933 17934 // OpenMP [2.7.1, Restrictions] 17935 // chunk_size must be a loop invariant integer expression with a positive 17936 // value. 17937 llvm::APSInt Result; 17938 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 17939 if (Result.isSigned() && !Result.isStrictlyPositive()) { 17940 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 17941 << "dist_schedule" << ChunkSize->getSourceRange(); 17942 return nullptr; 17943 } 17944 } else if (getOpenMPCaptureRegionForClause( 17945 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 17946 LangOpts.OpenMP) != OMPD_unknown && 17947 !CurContext->isDependentContext()) { 17948 ValExpr = MakeFullExpr(ValExpr).get(); 17949 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17950 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17951 HelperValStmt = buildPreInits(Context, Captures); 17952 } 17953 } 17954 } 17955 17956 return new (Context) 17957 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 17958 Kind, ValExpr, HelperValStmt); 17959 } 17960 17961 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 17962 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 17963 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 17964 SourceLocation KindLoc, SourceLocation EndLoc) { 17965 if (getLangOpts().OpenMP < 50) { 17966 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 17967 Kind != OMPC_DEFAULTMAP_scalar) { 17968 std::string Value; 17969 SourceLocation Loc; 17970 Value += "'"; 17971 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 17972 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 17973 OMPC_DEFAULTMAP_MODIFIER_tofrom); 17974 Loc = MLoc; 17975 } else { 17976 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 17977 OMPC_DEFAULTMAP_scalar); 17978 Loc = KindLoc; 17979 } 17980 Value += "'"; 17981 Diag(Loc, diag::err_omp_unexpected_clause_value) 17982 << Value << getOpenMPClauseName(OMPC_defaultmap); 17983 return nullptr; 17984 } 17985 } else { 17986 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 17987 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 17988 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 17989 if (!isDefaultmapKind || !isDefaultmapModifier) { 17990 std::string ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 17991 "'firstprivate', 'none', 'default'"; 17992 std::string KindValue = "'scalar', 'aggregate', 'pointer'"; 17993 if (!isDefaultmapKind && isDefaultmapModifier) { 17994 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 17995 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 17996 } else if (isDefaultmapKind && !isDefaultmapModifier) { 17997 Diag(MLoc, diag::err_omp_unexpected_clause_value) 17998 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 17999 } else { 18000 Diag(MLoc, diag::err_omp_unexpected_clause_value) 18001 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 18002 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 18003 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 18004 } 18005 return nullptr; 18006 } 18007 18008 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 18009 // At most one defaultmap clause for each category can appear on the 18010 // directive. 18011 if (DSAStack->checkDefaultmapCategory(Kind)) { 18012 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 18013 return nullptr; 18014 } 18015 } 18016 if (Kind == OMPC_DEFAULTMAP_unknown) { 18017 // Variable category is not specified - mark all categories. 18018 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 18019 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 18020 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 18021 } else { 18022 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 18023 } 18024 18025 return new (Context) 18026 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 18027 } 18028 18029 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 18030 DeclContext *CurLexicalContext = getCurLexicalContext(); 18031 if (!CurLexicalContext->isFileContext() && 18032 !CurLexicalContext->isExternCContext() && 18033 !CurLexicalContext->isExternCXXContext() && 18034 !isa<CXXRecordDecl>(CurLexicalContext) && 18035 !isa<ClassTemplateDecl>(CurLexicalContext) && 18036 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 18037 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 18038 Diag(Loc, diag::err_omp_region_not_file_context); 18039 return false; 18040 } 18041 ++DeclareTargetNestingLevel; 18042 return true; 18043 } 18044 18045 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 18046 assert(DeclareTargetNestingLevel > 0 && 18047 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 18048 --DeclareTargetNestingLevel; 18049 } 18050 18051 NamedDecl * 18052 Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 18053 const DeclarationNameInfo &Id, 18054 NamedDeclSetType &SameDirectiveDecls) { 18055 LookupResult Lookup(*this, Id, LookupOrdinaryName); 18056 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 18057 18058 if (Lookup.isAmbiguous()) 18059 return nullptr; 18060 Lookup.suppressDiagnostics(); 18061 18062 if (!Lookup.isSingleResult()) { 18063 VarOrFuncDeclFilterCCC CCC(*this); 18064 if (TypoCorrection Corrected = 18065 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 18066 CTK_ErrorRecovery)) { 18067 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 18068 << Id.getName()); 18069 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 18070 return nullptr; 18071 } 18072 18073 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 18074 return nullptr; 18075 } 18076 18077 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 18078 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 18079 !isa<FunctionTemplateDecl>(ND)) { 18080 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 18081 return nullptr; 18082 } 18083 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 18084 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 18085 return ND; 18086 } 18087 18088 void Sema::ActOnOpenMPDeclareTargetName( 18089 NamedDecl *ND, SourceLocation Loc, OMPDeclareTargetDeclAttr::MapTypeTy MT, 18090 OMPDeclareTargetDeclAttr::DevTypeTy DT) { 18091 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 18092 isa<FunctionTemplateDecl>(ND)) && 18093 "Expected variable, function or function template."); 18094 18095 // Diagnose marking after use as it may lead to incorrect diagnosis and 18096 // codegen. 18097 if (LangOpts.OpenMP >= 50 && 18098 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 18099 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 18100 18101 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 18102 OMPDeclareTargetDeclAttr::getDeviceType(cast<ValueDecl>(ND)); 18103 if (DevTy.hasValue() && *DevTy != DT) { 18104 Diag(Loc, diag::err_omp_device_type_mismatch) 18105 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DT) 18106 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(*DevTy); 18107 return; 18108 } 18109 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18110 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(cast<ValueDecl>(ND)); 18111 if (!Res) { 18112 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT, DT, 18113 SourceRange(Loc, Loc)); 18114 ND->addAttr(A); 18115 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18116 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 18117 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 18118 } else if (*Res != MT) { 18119 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 18120 } 18121 } 18122 18123 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 18124 Sema &SemaRef, Decl *D) { 18125 if (!D || !isa<VarDecl>(D)) 18126 return; 18127 auto *VD = cast<VarDecl>(D); 18128 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18129 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18130 if (SemaRef.LangOpts.OpenMP >= 50 && 18131 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 18132 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 18133 VD->hasGlobalStorage()) { 18134 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 18135 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 18136 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 18137 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 18138 // If a lambda declaration and definition appears between a 18139 // declare target directive and the matching end declare target 18140 // directive, all variables that are captured by the lambda 18141 // expression must also appear in a to clause. 18142 SemaRef.Diag(VD->getLocation(), 18143 diag::err_omp_lambda_capture_in_declare_target_not_to); 18144 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 18145 << VD << 0 << SR; 18146 return; 18147 } 18148 } 18149 if (MapTy.hasValue()) 18150 return; 18151 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 18152 SemaRef.Diag(SL, diag::note_used_here) << SR; 18153 } 18154 18155 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 18156 Sema &SemaRef, DSAStackTy *Stack, 18157 ValueDecl *VD) { 18158 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 18159 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 18160 /*FullCheck=*/false); 18161 } 18162 18163 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 18164 SourceLocation IdLoc) { 18165 if (!D || D->isInvalidDecl()) 18166 return; 18167 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 18168 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 18169 if (auto *VD = dyn_cast<VarDecl>(D)) { 18170 // Only global variables can be marked as declare target. 18171 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 18172 !VD->isStaticDataMember()) 18173 return; 18174 // 2.10.6: threadprivate variable cannot appear in a declare target 18175 // directive. 18176 if (DSAStack->isThreadPrivate(VD)) { 18177 Diag(SL, diag::err_omp_threadprivate_in_target); 18178 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 18179 return; 18180 } 18181 } 18182 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 18183 D = FTD->getTemplatedDecl(); 18184 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 18185 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 18186 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 18187 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 18188 Diag(IdLoc, diag::err_omp_function_in_link_clause); 18189 Diag(FD->getLocation(), diag::note_defined_here) << FD; 18190 return; 18191 } 18192 } 18193 if (auto *VD = dyn_cast<ValueDecl>(D)) { 18194 // Problem if any with var declared with incomplete type will be reported 18195 // as normal, so no need to check it here. 18196 if ((E || !VD->getType()->isIncompleteType()) && 18197 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 18198 return; 18199 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 18200 // Checking declaration inside declare target region. 18201 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 18202 isa<FunctionTemplateDecl>(D)) { 18203 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 18204 Context, OMPDeclareTargetDeclAttr::MT_To, 18205 OMPDeclareTargetDeclAttr::DT_Any, SourceRange(IdLoc, IdLoc)); 18206 D->addAttr(A); 18207 if (ASTMutationListener *ML = Context.getASTMutationListener()) 18208 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 18209 } 18210 return; 18211 } 18212 } 18213 if (!E) 18214 return; 18215 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 18216 } 18217 18218 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 18219 CXXScopeSpec &MapperIdScopeSpec, 18220 DeclarationNameInfo &MapperId, 18221 const OMPVarListLocTy &Locs, 18222 ArrayRef<Expr *> UnresolvedMappers) { 18223 MappableVarListInfo MVLI(VarList); 18224 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 18225 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18226 if (MVLI.ProcessedVarList.empty()) 18227 return nullptr; 18228 18229 return OMPToClause::Create( 18230 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18231 MVLI.VarComponents, MVLI.UDMapperList, 18232 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18233 } 18234 18235 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 18236 CXXScopeSpec &MapperIdScopeSpec, 18237 DeclarationNameInfo &MapperId, 18238 const OMPVarListLocTy &Locs, 18239 ArrayRef<Expr *> UnresolvedMappers) { 18240 MappableVarListInfo MVLI(VarList); 18241 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 18242 MapperIdScopeSpec, MapperId, UnresolvedMappers); 18243 if (MVLI.ProcessedVarList.empty()) 18244 return nullptr; 18245 18246 return OMPFromClause::Create( 18247 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 18248 MVLI.VarComponents, MVLI.UDMapperList, 18249 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 18250 } 18251 18252 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 18253 const OMPVarListLocTy &Locs) { 18254 MappableVarListInfo MVLI(VarList); 18255 SmallVector<Expr *, 8> PrivateCopies; 18256 SmallVector<Expr *, 8> Inits; 18257 18258 for (Expr *RefExpr : VarList) { 18259 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 18260 SourceLocation ELoc; 18261 SourceRange ERange; 18262 Expr *SimpleRefExpr = RefExpr; 18263 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18264 if (Res.second) { 18265 // It will be analyzed later. 18266 MVLI.ProcessedVarList.push_back(RefExpr); 18267 PrivateCopies.push_back(nullptr); 18268 Inits.push_back(nullptr); 18269 } 18270 ValueDecl *D = Res.first; 18271 if (!D) 18272 continue; 18273 18274 QualType Type = D->getType(); 18275 Type = Type.getNonReferenceType().getUnqualifiedType(); 18276 18277 auto *VD = dyn_cast<VarDecl>(D); 18278 18279 // Item should be a pointer or reference to pointer. 18280 if (!Type->isPointerType()) { 18281 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 18282 << 0 << RefExpr->getSourceRange(); 18283 continue; 18284 } 18285 18286 // Build the private variable and the expression that refers to it. 18287 auto VDPrivate = 18288 buildVarDecl(*this, ELoc, Type, D->getName(), 18289 D->hasAttrs() ? &D->getAttrs() : nullptr, 18290 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18291 if (VDPrivate->isInvalidDecl()) 18292 continue; 18293 18294 CurContext->addDecl(VDPrivate); 18295 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 18296 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 18297 18298 // Add temporary variable to initialize the private copy of the pointer. 18299 VarDecl *VDInit = 18300 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 18301 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 18302 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 18303 AddInitializerToDecl(VDPrivate, 18304 DefaultLvalueConversion(VDInitRefExpr).get(), 18305 /*DirectInit=*/false); 18306 18307 // If required, build a capture to implement the privatization initialized 18308 // with the current list item value. 18309 DeclRefExpr *Ref = nullptr; 18310 if (!VD) 18311 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 18312 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 18313 PrivateCopies.push_back(VDPrivateRefExpr); 18314 Inits.push_back(VDInitRefExpr); 18315 18316 // We need to add a data sharing attribute for this variable to make sure it 18317 // is correctly captured. A variable that shows up in a use_device_ptr has 18318 // similar properties of a first private variable. 18319 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 18320 18321 // Create a mappable component for the list item. List items in this clause 18322 // only need a component. 18323 MVLI.VarBaseDeclarations.push_back(D); 18324 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18325 MVLI.VarComponents.back().push_back( 18326 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 18327 } 18328 18329 if (MVLI.ProcessedVarList.empty()) 18330 return nullptr; 18331 18332 return OMPUseDevicePtrClause::Create( 18333 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 18334 MVLI.VarBaseDeclarations, MVLI.VarComponents); 18335 } 18336 18337 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 18338 const OMPVarListLocTy &Locs) { 18339 MappableVarListInfo MVLI(VarList); 18340 for (Expr *RefExpr : VarList) { 18341 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 18342 SourceLocation ELoc; 18343 SourceRange ERange; 18344 Expr *SimpleRefExpr = RefExpr; 18345 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18346 if (Res.second) { 18347 // It will be analyzed later. 18348 MVLI.ProcessedVarList.push_back(RefExpr); 18349 } 18350 ValueDecl *D = Res.first; 18351 if (!D) 18352 continue; 18353 18354 QualType Type = D->getType(); 18355 // item should be a pointer or array or reference to pointer or array 18356 if (!Type.getNonReferenceType()->isPointerType() && 18357 !Type.getNonReferenceType()->isArrayType()) { 18358 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 18359 << 0 << RefExpr->getSourceRange(); 18360 continue; 18361 } 18362 18363 // Check if the declaration in the clause does not show up in any data 18364 // sharing attribute. 18365 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 18366 if (isOpenMPPrivate(DVar.CKind)) { 18367 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 18368 << getOpenMPClauseName(DVar.CKind) 18369 << getOpenMPClauseName(OMPC_is_device_ptr) 18370 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 18371 reportOriginalDsa(*this, DSAStack, D, DVar); 18372 continue; 18373 } 18374 18375 const Expr *ConflictExpr; 18376 if (DSAStack->checkMappableExprComponentListsForDecl( 18377 D, /*CurrentRegionOnly=*/true, 18378 [&ConflictExpr]( 18379 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 18380 OpenMPClauseKind) -> bool { 18381 ConflictExpr = R.front().getAssociatedExpression(); 18382 return true; 18383 })) { 18384 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 18385 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 18386 << ConflictExpr->getSourceRange(); 18387 continue; 18388 } 18389 18390 // Store the components in the stack so that they can be used to check 18391 // against other clauses later on. 18392 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 18393 DSAStack->addMappableExpressionComponents( 18394 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 18395 18396 // Record the expression we've just processed. 18397 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 18398 18399 // Create a mappable component for the list item. List items in this clause 18400 // only need a component. We use a null declaration to signal fields in 18401 // 'this'. 18402 assert((isa<DeclRefExpr>(SimpleRefExpr) || 18403 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 18404 "Unexpected device pointer expression!"); 18405 MVLI.VarBaseDeclarations.push_back( 18406 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 18407 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 18408 MVLI.VarComponents.back().push_back(MC); 18409 } 18410 18411 if (MVLI.ProcessedVarList.empty()) 18412 return nullptr; 18413 18414 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 18415 MVLI.VarBaseDeclarations, 18416 MVLI.VarComponents); 18417 } 18418 18419 OMPClause *Sema::ActOnOpenMPAllocateClause( 18420 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 18421 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 18422 if (Allocator) { 18423 // OpenMP [2.11.4 allocate Clause, Description] 18424 // allocator is an expression of omp_allocator_handle_t type. 18425 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 18426 return nullptr; 18427 18428 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 18429 if (AllocatorRes.isInvalid()) 18430 return nullptr; 18431 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 18432 DSAStack->getOMPAllocatorHandleT(), 18433 Sema::AA_Initializing, 18434 /*AllowExplicit=*/true); 18435 if (AllocatorRes.isInvalid()) 18436 return nullptr; 18437 Allocator = AllocatorRes.get(); 18438 } else { 18439 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 18440 // allocate clauses that appear on a target construct or on constructs in a 18441 // target region must specify an allocator expression unless a requires 18442 // directive with the dynamic_allocators clause is present in the same 18443 // compilation unit. 18444 if (LangOpts.OpenMPIsDevice && 18445 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 18446 targetDiag(StartLoc, diag::err_expected_allocator_expression); 18447 } 18448 // Analyze and build list of variables. 18449 SmallVector<Expr *, 8> Vars; 18450 for (Expr *RefExpr : VarList) { 18451 assert(RefExpr && "NULL expr in OpenMP private clause."); 18452 SourceLocation ELoc; 18453 SourceRange ERange; 18454 Expr *SimpleRefExpr = RefExpr; 18455 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18456 if (Res.second) { 18457 // It will be analyzed later. 18458 Vars.push_back(RefExpr); 18459 } 18460 ValueDecl *D = Res.first; 18461 if (!D) 18462 continue; 18463 18464 auto *VD = dyn_cast<VarDecl>(D); 18465 DeclRefExpr *Ref = nullptr; 18466 if (!VD && !CurContext->isDependentContext()) 18467 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 18468 Vars.push_back((VD || CurContext->isDependentContext()) 18469 ? RefExpr->IgnoreParens() 18470 : Ref); 18471 } 18472 18473 if (Vars.empty()) 18474 return nullptr; 18475 18476 if (Allocator) 18477 DSAStack->addInnerAllocatorExpr(Allocator); 18478 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 18479 ColonLoc, EndLoc, Vars); 18480 } 18481 18482 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 18483 SourceLocation StartLoc, 18484 SourceLocation LParenLoc, 18485 SourceLocation EndLoc) { 18486 SmallVector<Expr *, 8> Vars; 18487 for (Expr *RefExpr : VarList) { 18488 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18489 SourceLocation ELoc; 18490 SourceRange ERange; 18491 Expr *SimpleRefExpr = RefExpr; 18492 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 18493 if (Res.second) 18494 // It will be analyzed later. 18495 Vars.push_back(RefExpr); 18496 ValueDecl *D = Res.first; 18497 if (!D) 18498 continue; 18499 18500 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 18501 // A list-item cannot appear in more than one nontemporal clause. 18502 if (const Expr *PrevRef = 18503 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 18504 Diag(ELoc, diag::err_omp_used_in_clause_twice) 18505 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 18506 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 18507 << getOpenMPClauseName(OMPC_nontemporal); 18508 continue; 18509 } 18510 18511 Vars.push_back(RefExpr); 18512 } 18513 18514 if (Vars.empty()) 18515 return nullptr; 18516 18517 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18518 Vars); 18519 } 18520 18521 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 18522 SourceLocation StartLoc, 18523 SourceLocation LParenLoc, 18524 SourceLocation EndLoc) { 18525 SmallVector<Expr *, 8> Vars; 18526 for (Expr *RefExpr : VarList) { 18527 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18528 SourceLocation ELoc; 18529 SourceRange ERange; 18530 Expr *SimpleRefExpr = RefExpr; 18531 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18532 /*AllowArraySection=*/true); 18533 if (Res.second) 18534 // It will be analyzed later. 18535 Vars.push_back(RefExpr); 18536 ValueDecl *D = Res.first; 18537 if (!D) 18538 continue; 18539 18540 const DSAStackTy::DSAVarData DVar = 18541 DSAStack->getTopDSA(D, /*FromParent=*/true); 18542 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18543 // A list item that appears in the inclusive or exclusive clause must appear 18544 // in a reduction clause with the inscan modifier on the enclosing 18545 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18546 if (DVar.CKind != OMPC_reduction || 18547 DVar.Modifier != OMPC_REDUCTION_inscan) 18548 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18549 << RefExpr->getSourceRange(); 18550 18551 if (DSAStack->getParentDirective() != OMPD_unknown) 18552 DSAStack->markDeclAsUsedInScanDirective(D); 18553 Vars.push_back(RefExpr); 18554 } 18555 18556 if (Vars.empty()) 18557 return nullptr; 18558 18559 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18560 } 18561 18562 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 18563 SourceLocation StartLoc, 18564 SourceLocation LParenLoc, 18565 SourceLocation EndLoc) { 18566 SmallVector<Expr *, 8> Vars; 18567 for (Expr *RefExpr : VarList) { 18568 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 18569 SourceLocation ELoc; 18570 SourceRange ERange; 18571 Expr *SimpleRefExpr = RefExpr; 18572 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 18573 /*AllowArraySection=*/true); 18574 if (Res.second) 18575 // It will be analyzed later. 18576 Vars.push_back(RefExpr); 18577 ValueDecl *D = Res.first; 18578 if (!D) 18579 continue; 18580 18581 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 18582 DSAStackTy::DSAVarData DVar; 18583 if (ParentDirective != OMPD_unknown) 18584 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 18585 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 18586 // A list item that appears in the inclusive or exclusive clause must appear 18587 // in a reduction clause with the inscan modifier on the enclosing 18588 // worksharing-loop, worksharing-loop SIMD, or simd construct. 18589 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 18590 DVar.Modifier != OMPC_REDUCTION_inscan) { 18591 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 18592 << RefExpr->getSourceRange(); 18593 } else { 18594 DSAStack->markDeclAsUsedInScanDirective(D); 18595 } 18596 Vars.push_back(RefExpr); 18597 } 18598 18599 if (Vars.empty()) 18600 return nullptr; 18601 18602 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 18603 } 18604 18605 /// Tries to find omp_alloctrait_t type. 18606 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 18607 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 18608 if (!OMPAlloctraitT.isNull()) 18609 return true; 18610 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 18611 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 18612 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 18613 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 18614 return false; 18615 } 18616 Stack->setOMPAlloctraitT(PT.get()); 18617 return true; 18618 } 18619 18620 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 18621 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 18622 ArrayRef<UsesAllocatorsData> Data) { 18623 // OpenMP [2.12.5, target Construct] 18624 // allocator is an identifier of omp_allocator_handle_t type. 18625 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 18626 return nullptr; 18627 // OpenMP [2.12.5, target Construct] 18628 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 18629 if (llvm::any_of( 18630 Data, 18631 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 18632 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 18633 return nullptr; 18634 llvm::SmallSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 18635 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 18636 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 18637 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 18638 StringRef Allocator = 18639 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 18640 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 18641 PredefinedAllocators.insert(LookupSingleName( 18642 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 18643 } 18644 18645 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 18646 for (const UsesAllocatorsData &D : Data) { 18647 Expr *AllocatorExpr = nullptr; 18648 // Check allocator expression. 18649 if (D.Allocator->isTypeDependent()) { 18650 AllocatorExpr = D.Allocator; 18651 } else { 18652 // Traits were specified - need to assign new allocator to the specified 18653 // allocator, so it must be an lvalue. 18654 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 18655 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 18656 bool IsPredefinedAllocator = false; 18657 if (DRE) 18658 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); 18659 if (!DRE || 18660 !(Context.hasSameUnqualifiedType( 18661 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) || 18662 Context.typesAreCompatible(AllocatorExpr->getType(), 18663 DSAStack->getOMPAllocatorHandleT(), 18664 /*CompareUnqualified=*/true)) || 18665 (!IsPredefinedAllocator && 18666 (AllocatorExpr->getType().isConstant(Context) || 18667 !AllocatorExpr->isLValue()))) { 18668 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 18669 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 18670 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 18671 continue; 18672 } 18673 // OpenMP [2.12.5, target Construct] 18674 // Predefined allocators appearing in a uses_allocators clause cannot have 18675 // traits specified. 18676 if (IsPredefinedAllocator && D.AllocatorTraits) { 18677 Diag(D.AllocatorTraits->getExprLoc(), 18678 diag::err_omp_predefined_allocator_with_traits) 18679 << D.AllocatorTraits->getSourceRange(); 18680 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 18681 << cast<NamedDecl>(DRE->getDecl())->getName() 18682 << D.Allocator->getSourceRange(); 18683 continue; 18684 } 18685 // OpenMP [2.12.5, target Construct] 18686 // Non-predefined allocators appearing in a uses_allocators clause must 18687 // have traits specified. 18688 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 18689 Diag(D.Allocator->getExprLoc(), 18690 diag::err_omp_nonpredefined_allocator_without_traits); 18691 continue; 18692 } 18693 // No allocator traits - just convert it to rvalue. 18694 if (!D.AllocatorTraits) 18695 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 18696 DSAStack->addUsesAllocatorsDecl(DRE->getDecl()); 18697 } 18698 Expr *AllocatorTraitsExpr = nullptr; 18699 if (D.AllocatorTraits) { 18700 if (D.AllocatorTraits->isTypeDependent()) { 18701 AllocatorTraitsExpr = D.AllocatorTraits; 18702 } else { 18703 // OpenMP [2.12.5, target Construct] 18704 // Arrays that contain allocator traits that appear in a uses_allocators 18705 // clause must be constant arrays, have constant values and be defined 18706 // in the same scope as the construct in which the clause appears. 18707 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 18708 // Check that traits expr is a constant array. 18709 QualType TraitTy; 18710 if (const ArrayType *Ty = 18711 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 18712 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 18713 TraitTy = ConstArrayTy->getElementType(); 18714 if (TraitTy.isNull() || 18715 !(Context.hasSameUnqualifiedType(TraitTy, 18716 DSAStack->getOMPAlloctraitT()) || 18717 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 18718 /*CompareUnqualified=*/true))) { 18719 Diag(D.AllocatorTraits->getExprLoc(), 18720 diag::err_omp_expected_array_alloctraits) 18721 << AllocatorTraitsExpr->getType(); 18722 continue; 18723 } 18724 } 18725 } 18726 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 18727 NewD.Allocator = AllocatorExpr; 18728 NewD.AllocatorTraits = AllocatorTraitsExpr; 18729 NewD.LParenLoc = D.LParenLoc; 18730 NewD.RParenLoc = D.RParenLoc; 18731 } 18732 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 18733 NewData); 18734 } 18735