1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/OpenMPClause.h" 22 #include "clang/AST/StmtCXX.h" 23 #include "clang/AST/StmtOpenMP.h" 24 #include "clang/AST/StmtVisitor.h" 25 #include "clang/AST/TypeOrdering.h" 26 #include "clang/Basic/DiagnosticSema.h" 27 #include "clang/Basic/OpenMPKinds.h" 28 #include "clang/Basic/PartialDiagnostic.h" 29 #include "clang/Basic/TargetInfo.h" 30 #include "clang/Sema/Initialization.h" 31 #include "clang/Sema/Lookup.h" 32 #include "clang/Sema/Scope.h" 33 #include "clang/Sema/ScopeInfo.h" 34 #include "clang/Sema/SemaInternal.h" 35 #include "llvm/ADT/IndexedMap.h" 36 #include "llvm/ADT/PointerEmbeddedInt.h" 37 #include "llvm/ADT/STLExtras.h" 38 #include "llvm/ADT/SmallSet.h" 39 #include "llvm/ADT/StringExtras.h" 40 #include "llvm/Frontend/OpenMP/OMPAssume.h" 41 #include "llvm/Frontend/OpenMP/OMPConstants.h" 42 #include <set> 43 44 using namespace clang; 45 using namespace llvm::omp; 46 47 //===----------------------------------------------------------------------===// 48 // Stack of data-sharing attributes for variables 49 //===----------------------------------------------------------------------===// 50 51 static const Expr *checkMapClauseExpressionBase( 52 Sema &SemaRef, Expr *E, 53 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 54 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose); 55 56 namespace { 57 /// Default data sharing attributes, which can be applied to directive. 58 enum DefaultDataSharingAttributes { 59 DSA_unspecified = 0, /// Data sharing attribute not specified. 60 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 61 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 62 DSA_private = 1 << 2, /// Default data sharing attribute 'private'. 63 DSA_firstprivate = 1 << 3, /// Default data sharing attribute 'firstprivate'. 64 }; 65 66 /// Stack for tracking declarations used in OpenMP directives and 67 /// clauses and their data-sharing attributes. 68 class DSAStackTy { 69 public: 70 struct DSAVarData { 71 OpenMPDirectiveKind DKind = OMPD_unknown; 72 OpenMPClauseKind CKind = OMPC_unknown; 73 unsigned Modifier = 0; 74 const Expr *RefExpr = nullptr; 75 DeclRefExpr *PrivateCopy = nullptr; 76 SourceLocation ImplicitDSALoc; 77 bool AppliedToPointee = false; 78 DSAVarData() = default; 79 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 80 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 81 SourceLocation ImplicitDSALoc, unsigned Modifier, 82 bool AppliedToPointee) 83 : DKind(DKind), CKind(CKind), Modifier(Modifier), RefExpr(RefExpr), 84 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc), 85 AppliedToPointee(AppliedToPointee) {} 86 }; 87 using OperatorOffsetTy = 88 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 89 using DoacrossDependMapTy = 90 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 91 /// Kind of the declaration used in the uses_allocators clauses. 92 enum class UsesAllocatorsDeclKind { 93 /// Predefined allocator 94 PredefinedAllocator, 95 /// User-defined allocator 96 UserDefinedAllocator, 97 /// The declaration that represent allocator trait 98 AllocatorTrait, 99 }; 100 101 private: 102 struct DSAInfo { 103 OpenMPClauseKind Attributes = OMPC_unknown; 104 unsigned Modifier = 0; 105 /// Pointer to a reference expression and a flag which shows that the 106 /// variable is marked as lastprivate(true) or not (false). 107 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 108 DeclRefExpr *PrivateCopy = nullptr; 109 /// true if the attribute is applied to the pointee, not the variable 110 /// itself. 111 bool AppliedToPointee = false; 112 }; 113 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 114 using UsedRefMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 115 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 116 using LoopControlVariablesMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 118 /// Struct that associates a component with the clause kind where they are 119 /// found. 120 struct MappedExprComponentTy { 121 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 122 OpenMPClauseKind Kind = OMPC_unknown; 123 }; 124 using MappedExprComponentsTy = 125 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 126 using CriticalsWithHintsTy = 127 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 128 struct ReductionData { 129 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 130 SourceRange ReductionRange; 131 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 132 ReductionData() = default; 133 void set(BinaryOperatorKind BO, SourceRange RR) { 134 ReductionRange = RR; 135 ReductionOp = BO; 136 } 137 void set(const Expr *RefExpr, SourceRange RR) { 138 ReductionRange = RR; 139 ReductionOp = RefExpr; 140 } 141 }; 142 using DeclReductionMapTy = 143 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 144 struct DefaultmapInfo { 145 OpenMPDefaultmapClauseModifier ImplicitBehavior = 146 OMPC_DEFAULTMAP_MODIFIER_unknown; 147 SourceLocation SLoc; 148 DefaultmapInfo() = default; 149 DefaultmapInfo(OpenMPDefaultmapClauseModifier M, SourceLocation Loc) 150 : ImplicitBehavior(M), SLoc(Loc) {} 151 }; 152 153 struct SharingMapTy { 154 DeclSAMapTy SharingMap; 155 DeclReductionMapTy ReductionMap; 156 UsedRefMapTy AlignedMap; 157 UsedRefMapTy NontemporalMap; 158 MappedExprComponentsTy MappedExprComponents; 159 LoopControlVariablesMapTy LCVMap; 160 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 161 SourceLocation DefaultAttrLoc; 162 DefaultmapInfo DefaultmapMap[OMPC_DEFAULTMAP_unknown]; 163 OpenMPDirectiveKind Directive = OMPD_unknown; 164 DeclarationNameInfo DirectiveName; 165 Scope *CurScope = nullptr; 166 DeclContext *Context = nullptr; 167 SourceLocation ConstructLoc; 168 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 169 /// get the data (loop counters etc.) about enclosing loop-based construct. 170 /// This data is required during codegen. 171 DoacrossDependMapTy DoacrossDepends; 172 /// First argument (Expr *) contains optional argument of the 173 /// 'ordered' clause, the second one is true if the regions has 'ordered' 174 /// clause, false otherwise. 175 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 176 unsigned AssociatedLoops = 1; 177 bool HasMutipleLoops = false; 178 const Decl *PossiblyLoopCounter = nullptr; 179 bool NowaitRegion = false; 180 bool UntiedRegion = false; 181 bool CancelRegion = false; 182 bool LoopStart = false; 183 bool BodyComplete = false; 184 SourceLocation PrevScanLocation; 185 SourceLocation PrevOrderedLocation; 186 SourceLocation InnerTeamsRegionLoc; 187 /// Reference to the taskgroup task_reduction reference expression. 188 Expr *TaskgroupReductionRef = nullptr; 189 llvm::DenseSet<QualType> MappedClassesQualTypes; 190 SmallVector<Expr *, 4> InnerUsedAllocators; 191 llvm::DenseSet<CanonicalDeclPtr<Decl>> ImplicitTaskFirstprivates; 192 /// List of globals marked as declare target link in this target region 193 /// (isOpenMPTargetExecutionDirective(Directive) == true). 194 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 195 /// List of decls used in inclusive/exclusive clauses of the scan directive. 196 llvm::DenseSet<CanonicalDeclPtr<Decl>> UsedInScanDirective; 197 llvm::DenseMap<CanonicalDeclPtr<const Decl>, UsesAllocatorsDeclKind> 198 UsesAllocatorsDecls; 199 Expr *DeclareMapperVar = nullptr; 200 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 201 Scope *CurScope, SourceLocation Loc) 202 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 203 ConstructLoc(Loc) {} 204 SharingMapTy() = default; 205 }; 206 207 using StackTy = SmallVector<SharingMapTy, 4>; 208 209 /// Stack of used declaration and their data-sharing attributes. 210 DeclSAMapTy Threadprivates; 211 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 212 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 213 /// true, if check for DSA must be from parent directive, false, if 214 /// from current directive. 215 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 216 Sema &SemaRef; 217 bool ForceCapturing = false; 218 /// true if all the variables in the target executable directives must be 219 /// captured by reference. 220 bool ForceCaptureByReferenceInTargetExecutable = false; 221 CriticalsWithHintsTy Criticals; 222 unsigned IgnoredStackElements = 0; 223 224 /// Iterators over the stack iterate in order from innermost to outermost 225 /// directive. 226 using const_iterator = StackTy::const_reverse_iterator; 227 const_iterator begin() const { 228 return Stack.empty() ? const_iterator() 229 : Stack.back().first.rbegin() + IgnoredStackElements; 230 } 231 const_iterator end() const { 232 return Stack.empty() ? const_iterator() : Stack.back().first.rend(); 233 } 234 using iterator = StackTy::reverse_iterator; 235 iterator begin() { 236 return Stack.empty() ? iterator() 237 : Stack.back().first.rbegin() + IgnoredStackElements; 238 } 239 iterator end() { 240 return Stack.empty() ? iterator() : Stack.back().first.rend(); 241 } 242 243 // Convenience operations to get at the elements of the stack. 244 245 bool isStackEmpty() const { 246 return Stack.empty() || 247 Stack.back().second != CurrentNonCapturingFunctionScope || 248 Stack.back().first.size() <= IgnoredStackElements; 249 } 250 size_t getStackSize() const { 251 return isStackEmpty() ? 0 252 : Stack.back().first.size() - IgnoredStackElements; 253 } 254 255 SharingMapTy *getTopOfStackOrNull() { 256 size_t Size = getStackSize(); 257 if (Size == 0) 258 return nullptr; 259 return &Stack.back().first[Size - 1]; 260 } 261 const SharingMapTy *getTopOfStackOrNull() const { 262 return const_cast<DSAStackTy &>(*this).getTopOfStackOrNull(); 263 } 264 SharingMapTy &getTopOfStack() { 265 assert(!isStackEmpty() && "no current directive"); 266 return *getTopOfStackOrNull(); 267 } 268 const SharingMapTy &getTopOfStack() const { 269 return const_cast<DSAStackTy &>(*this).getTopOfStack(); 270 } 271 272 SharingMapTy *getSecondOnStackOrNull() { 273 size_t Size = getStackSize(); 274 if (Size <= 1) 275 return nullptr; 276 return &Stack.back().first[Size - 2]; 277 } 278 const SharingMapTy *getSecondOnStackOrNull() const { 279 return const_cast<DSAStackTy &>(*this).getSecondOnStackOrNull(); 280 } 281 282 /// Get the stack element at a certain level (previously returned by 283 /// \c getNestingLevel). 284 /// 285 /// Note that nesting levels count from outermost to innermost, and this is 286 /// the reverse of our iteration order where new inner levels are pushed at 287 /// the front of the stack. 288 SharingMapTy &getStackElemAtLevel(unsigned Level) { 289 assert(Level < getStackSize() && "no such stack element"); 290 return Stack.back().first[Level]; 291 } 292 const SharingMapTy &getStackElemAtLevel(unsigned Level) const { 293 return const_cast<DSAStackTy &>(*this).getStackElemAtLevel(Level); 294 } 295 296 DSAVarData getDSA(const_iterator &Iter, ValueDecl *D) const; 297 298 /// Checks if the variable is a local for OpenMP region. 299 bool isOpenMPLocal(VarDecl *D, const_iterator Iter) const; 300 301 /// Vector of previously declared requires directives 302 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 303 /// omp_allocator_handle_t type. 304 QualType OMPAllocatorHandleT; 305 /// omp_depend_t type. 306 QualType OMPDependT; 307 /// omp_event_handle_t type. 308 QualType OMPEventHandleT; 309 /// omp_alloctrait_t type. 310 QualType OMPAlloctraitT; 311 /// Expression for the predefined allocators. 312 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 313 nullptr}; 314 /// Vector of previously encountered target directives 315 SmallVector<SourceLocation, 2> TargetLocations; 316 SourceLocation AtomicLocation; 317 /// Vector of declare variant construct traits. 318 SmallVector<llvm::omp::TraitProperty, 8> ConstructTraits; 319 320 public: 321 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 322 323 /// Sets omp_allocator_handle_t type. 324 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 325 /// Gets omp_allocator_handle_t type. 326 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 327 /// Sets omp_alloctrait_t type. 328 void setOMPAlloctraitT(QualType Ty) { OMPAlloctraitT = Ty; } 329 /// Gets omp_alloctrait_t type. 330 QualType getOMPAlloctraitT() const { return OMPAlloctraitT; } 331 /// Sets the given default allocator. 332 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 333 Expr *Allocator) { 334 OMPPredefinedAllocators[AllocatorKind] = Allocator; 335 } 336 /// Returns the specified default allocator. 337 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 338 return OMPPredefinedAllocators[AllocatorKind]; 339 } 340 /// Sets omp_depend_t type. 341 void setOMPDependT(QualType Ty) { OMPDependT = Ty; } 342 /// Gets omp_depend_t type. 343 QualType getOMPDependT() const { return OMPDependT; } 344 345 /// Sets omp_event_handle_t type. 346 void setOMPEventHandleT(QualType Ty) { OMPEventHandleT = Ty; } 347 /// Gets omp_event_handle_t type. 348 QualType getOMPEventHandleT() const { return OMPEventHandleT; } 349 350 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 351 OpenMPClauseKind getClauseParsingMode() const { 352 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 353 return ClauseKindMode; 354 } 355 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 356 357 bool isBodyComplete() const { 358 const SharingMapTy *Top = getTopOfStackOrNull(); 359 return Top && Top->BodyComplete; 360 } 361 void setBodyComplete() { getTopOfStack().BodyComplete = true; } 362 363 bool isForceVarCapturing() const { return ForceCapturing; } 364 void setForceVarCapturing(bool V) { ForceCapturing = V; } 365 366 void setForceCaptureByReferenceInTargetExecutable(bool V) { 367 ForceCaptureByReferenceInTargetExecutable = V; 368 } 369 bool isForceCaptureByReferenceInTargetExecutable() const { 370 return ForceCaptureByReferenceInTargetExecutable; 371 } 372 373 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 374 Scope *CurScope, SourceLocation Loc) { 375 assert(!IgnoredStackElements && 376 "cannot change stack while ignoring elements"); 377 if (Stack.empty() || 378 Stack.back().second != CurrentNonCapturingFunctionScope) 379 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 380 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 381 Stack.back().first.back().DefaultAttrLoc = Loc; 382 } 383 384 void pop() { 385 assert(!IgnoredStackElements && 386 "cannot change stack while ignoring elements"); 387 assert(!Stack.back().first.empty() && 388 "Data-sharing attributes stack is empty!"); 389 Stack.back().first.pop_back(); 390 } 391 392 /// RAII object to temporarily leave the scope of a directive when we want to 393 /// logically operate in its parent. 394 class ParentDirectiveScope { 395 DSAStackTy &Self; 396 bool Active; 397 398 public: 399 ParentDirectiveScope(DSAStackTy &Self, bool Activate) 400 : Self(Self), Active(false) { 401 if (Activate) 402 enable(); 403 } 404 ~ParentDirectiveScope() { disable(); } 405 void disable() { 406 if (Active) { 407 --Self.IgnoredStackElements; 408 Active = false; 409 } 410 } 411 void enable() { 412 if (!Active) { 413 ++Self.IgnoredStackElements; 414 Active = true; 415 } 416 } 417 }; 418 419 /// Marks that we're started loop parsing. 420 void loopInit() { 421 assert(isOpenMPLoopDirective(getCurrentDirective()) && 422 "Expected loop-based directive."); 423 getTopOfStack().LoopStart = true; 424 } 425 /// Start capturing of the variables in the loop context. 426 void loopStart() { 427 assert(isOpenMPLoopDirective(getCurrentDirective()) && 428 "Expected loop-based directive."); 429 getTopOfStack().LoopStart = false; 430 } 431 /// true, if variables are captured, false otherwise. 432 bool isLoopStarted() const { 433 assert(isOpenMPLoopDirective(getCurrentDirective()) && 434 "Expected loop-based directive."); 435 return !getTopOfStack().LoopStart; 436 } 437 /// Marks (or clears) declaration as possibly loop counter. 438 void resetPossibleLoopCounter(const Decl *D = nullptr) { 439 getTopOfStack().PossiblyLoopCounter = D ? D->getCanonicalDecl() : D; 440 } 441 /// Gets the possible loop counter decl. 442 const Decl *getPossiblyLoopCunter() const { 443 return getTopOfStack().PossiblyLoopCounter; 444 } 445 /// Start new OpenMP region stack in new non-capturing function. 446 void pushFunction() { 447 assert(!IgnoredStackElements && 448 "cannot change stack while ignoring elements"); 449 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 450 assert(!isa<CapturingScopeInfo>(CurFnScope)); 451 CurrentNonCapturingFunctionScope = CurFnScope; 452 } 453 /// Pop region stack for non-capturing function. 454 void popFunction(const FunctionScopeInfo *OldFSI) { 455 assert(!IgnoredStackElements && 456 "cannot change stack while ignoring elements"); 457 if (!Stack.empty() && Stack.back().second == OldFSI) { 458 assert(Stack.back().first.empty()); 459 Stack.pop_back(); 460 } 461 CurrentNonCapturingFunctionScope = nullptr; 462 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 463 if (!isa<CapturingScopeInfo>(FSI)) { 464 CurrentNonCapturingFunctionScope = FSI; 465 break; 466 } 467 } 468 } 469 470 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 471 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 472 } 473 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 474 getCriticalWithHint(const DeclarationNameInfo &Name) const { 475 auto I = Criticals.find(Name.getAsString()); 476 if (I != Criticals.end()) 477 return I->second; 478 return std::make_pair(nullptr, llvm::APSInt()); 479 } 480 /// If 'aligned' declaration for given variable \a D was not seen yet, 481 /// add it and return NULL; otherwise return previous occurrence's expression 482 /// for diagnostics. 483 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 484 /// If 'nontemporal' declaration for given variable \a D was not seen yet, 485 /// add it and return NULL; otherwise return previous occurrence's expression 486 /// for diagnostics. 487 const Expr *addUniqueNontemporal(const ValueDecl *D, const Expr *NewDE); 488 489 /// Register specified variable as loop control variable. 490 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 491 /// Check if the specified variable is a loop control variable for 492 /// current region. 493 /// \return The index of the loop control variable in the list of associated 494 /// for-loops (from outer to inner). 495 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 496 /// Check if the specified variable is a loop control variable for 497 /// parent region. 498 /// \return The index of the loop control variable in the list of associated 499 /// for-loops (from outer to inner). 500 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 501 /// Check if the specified variable is a loop control variable for 502 /// current region. 503 /// \return The index of the loop control variable in the list of associated 504 /// for-loops (from outer to inner). 505 const LCDeclInfo isLoopControlVariable(const ValueDecl *D, 506 unsigned Level) const; 507 /// Get the loop control variable for the I-th loop (or nullptr) in 508 /// parent directive. 509 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 510 511 /// Marks the specified decl \p D as used in scan directive. 512 void markDeclAsUsedInScanDirective(ValueDecl *D) { 513 if (SharingMapTy *Stack = getSecondOnStackOrNull()) 514 Stack->UsedInScanDirective.insert(D); 515 } 516 517 /// Checks if the specified declaration was used in the inner scan directive. 518 bool isUsedInScanDirective(ValueDecl *D) const { 519 if (const SharingMapTy *Stack = getTopOfStackOrNull()) 520 return Stack->UsedInScanDirective.contains(D); 521 return false; 522 } 523 524 /// Adds explicit data sharing attribute to the specified declaration. 525 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 526 DeclRefExpr *PrivateCopy = nullptr, unsigned Modifier = 0, 527 bool AppliedToPointee = false); 528 529 /// Adds additional information for the reduction items with the reduction id 530 /// represented as an operator. 531 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 532 BinaryOperatorKind BOK); 533 /// Adds additional information for the reduction items with the reduction id 534 /// represented as reduction identifier. 535 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 536 const Expr *ReductionRef); 537 /// Returns the location and reduction operation from the innermost parent 538 /// region for the given \p D. 539 const DSAVarData 540 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 541 BinaryOperatorKind &BOK, 542 Expr *&TaskgroupDescriptor) const; 543 /// Returns the location and reduction operation from the innermost parent 544 /// region for the given \p D. 545 const DSAVarData 546 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 547 const Expr *&ReductionRef, 548 Expr *&TaskgroupDescriptor) const; 549 /// Return reduction reference expression for the current taskgroup or 550 /// parallel/worksharing directives with task reductions. 551 Expr *getTaskgroupReductionRef() const { 552 assert((getTopOfStack().Directive == OMPD_taskgroup || 553 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 554 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 555 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 556 "taskgroup reference expression requested for non taskgroup or " 557 "parallel/worksharing directive."); 558 return getTopOfStack().TaskgroupReductionRef; 559 } 560 /// Checks if the given \p VD declaration is actually a taskgroup reduction 561 /// descriptor variable at the \p Level of OpenMP regions. 562 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 563 return getStackElemAtLevel(Level).TaskgroupReductionRef && 564 cast<DeclRefExpr>(getStackElemAtLevel(Level).TaskgroupReductionRef) 565 ->getDecl() == VD; 566 } 567 568 /// Returns data sharing attributes from top of the stack for the 569 /// specified declaration. 570 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 571 /// Returns data-sharing attributes for the specified declaration. 572 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 573 /// Returns data-sharing attributes for the specified declaration. 574 const DSAVarData getImplicitDSA(ValueDecl *D, unsigned Level) const; 575 /// Checks if the specified variables has data-sharing attributes which 576 /// match specified \a CPred predicate in any directive which matches \a DPred 577 /// predicate. 578 const DSAVarData 579 hasDSA(ValueDecl *D, 580 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 581 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 582 bool FromParent) const; 583 /// Checks if the specified variables has data-sharing attributes which 584 /// match specified \a CPred predicate in any innermost directive which 585 /// matches \a DPred predicate. 586 const DSAVarData 587 hasInnermostDSA(ValueDecl *D, 588 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 589 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 590 bool FromParent) const; 591 /// Checks if the specified variables has explicit data-sharing 592 /// attributes which match specified \a CPred predicate at the specified 593 /// OpenMP region. 594 bool 595 hasExplicitDSA(const ValueDecl *D, 596 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 597 unsigned Level, bool NotLastprivate = false) const; 598 599 /// Returns true if the directive at level \Level matches in the 600 /// specified \a DPred predicate. 601 bool hasExplicitDirective( 602 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 603 unsigned Level) const; 604 605 /// Finds a directive which matches specified \a DPred predicate. 606 bool hasDirective( 607 const llvm::function_ref<bool( 608 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 609 DPred, 610 bool FromParent) const; 611 612 /// Returns currently analyzed directive. 613 OpenMPDirectiveKind getCurrentDirective() const { 614 const SharingMapTy *Top = getTopOfStackOrNull(); 615 return Top ? Top->Directive : OMPD_unknown; 616 } 617 /// Returns directive kind at specified level. 618 OpenMPDirectiveKind getDirective(unsigned Level) const { 619 assert(!isStackEmpty() && "No directive at specified level."); 620 return getStackElemAtLevel(Level).Directive; 621 } 622 /// Returns the capture region at the specified level. 623 OpenMPDirectiveKind getCaptureRegion(unsigned Level, 624 unsigned OpenMPCaptureLevel) const { 625 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 626 getOpenMPCaptureRegions(CaptureRegions, getDirective(Level)); 627 return CaptureRegions[OpenMPCaptureLevel]; 628 } 629 /// Returns parent directive. 630 OpenMPDirectiveKind getParentDirective() const { 631 const SharingMapTy *Parent = getSecondOnStackOrNull(); 632 return Parent ? Parent->Directive : OMPD_unknown; 633 } 634 635 /// Add requires decl to internal vector 636 void addRequiresDecl(OMPRequiresDecl *RD) { RequiresDecls.push_back(RD); } 637 638 /// Checks if the defined 'requires' directive has specified type of clause. 639 template <typename ClauseType> bool hasRequiresDeclWithClause() const { 640 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 641 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 642 return isa<ClauseType>(C); 643 }); 644 }); 645 } 646 647 /// Checks for a duplicate clause amongst previously declared requires 648 /// directives 649 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 650 bool IsDuplicate = false; 651 for (OMPClause *CNew : ClauseList) { 652 for (const OMPRequiresDecl *D : RequiresDecls) { 653 for (const OMPClause *CPrev : D->clauselists()) { 654 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 655 SemaRef.Diag(CNew->getBeginLoc(), 656 diag::err_omp_requires_clause_redeclaration) 657 << getOpenMPClauseName(CNew->getClauseKind()); 658 SemaRef.Diag(CPrev->getBeginLoc(), 659 diag::note_omp_requires_previous_clause) 660 << getOpenMPClauseName(CPrev->getClauseKind()); 661 IsDuplicate = true; 662 } 663 } 664 } 665 } 666 return IsDuplicate; 667 } 668 669 /// Add location of previously encountered target to internal vector 670 void addTargetDirLocation(SourceLocation LocStart) { 671 TargetLocations.push_back(LocStart); 672 } 673 674 /// Add location for the first encountered atomicc directive. 675 void addAtomicDirectiveLoc(SourceLocation Loc) { 676 if (AtomicLocation.isInvalid()) 677 AtomicLocation = Loc; 678 } 679 680 /// Returns the location of the first encountered atomic directive in the 681 /// module. 682 SourceLocation getAtomicDirectiveLoc() const { return AtomicLocation; } 683 684 // Return previously encountered target region locations. 685 ArrayRef<SourceLocation> getEncounteredTargetLocs() const { 686 return TargetLocations; 687 } 688 689 /// Set default data sharing attribute to none. 690 void setDefaultDSANone(SourceLocation Loc) { 691 getTopOfStack().DefaultAttr = DSA_none; 692 getTopOfStack().DefaultAttrLoc = Loc; 693 } 694 /// Set default data sharing attribute to shared. 695 void setDefaultDSAShared(SourceLocation Loc) { 696 getTopOfStack().DefaultAttr = DSA_shared; 697 getTopOfStack().DefaultAttrLoc = Loc; 698 } 699 /// Set default data sharing attribute to private. 700 void setDefaultDSAPrivate(SourceLocation Loc) { 701 getTopOfStack().DefaultAttr = DSA_private; 702 getTopOfStack().DefaultAttrLoc = Loc; 703 } 704 /// Set default data sharing attribute to firstprivate. 705 void setDefaultDSAFirstPrivate(SourceLocation Loc) { 706 getTopOfStack().DefaultAttr = DSA_firstprivate; 707 getTopOfStack().DefaultAttrLoc = Loc; 708 } 709 /// Set default data mapping attribute to Modifier:Kind 710 void setDefaultDMAAttr(OpenMPDefaultmapClauseModifier M, 711 OpenMPDefaultmapClauseKind Kind, SourceLocation Loc) { 712 DefaultmapInfo &DMI = getTopOfStack().DefaultmapMap[Kind]; 713 DMI.ImplicitBehavior = M; 714 DMI.SLoc = Loc; 715 } 716 /// Check whether the implicit-behavior has been set in defaultmap 717 bool checkDefaultmapCategory(OpenMPDefaultmapClauseKind VariableCategory) { 718 if (VariableCategory == OMPC_DEFAULTMAP_unknown) 719 return getTopOfStack() 720 .DefaultmapMap[OMPC_DEFAULTMAP_aggregate] 721 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 722 getTopOfStack() 723 .DefaultmapMap[OMPC_DEFAULTMAP_scalar] 724 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown || 725 getTopOfStack() 726 .DefaultmapMap[OMPC_DEFAULTMAP_pointer] 727 .ImplicitBehavior != OMPC_DEFAULTMAP_MODIFIER_unknown; 728 return getTopOfStack().DefaultmapMap[VariableCategory].ImplicitBehavior != 729 OMPC_DEFAULTMAP_MODIFIER_unknown; 730 } 731 732 ArrayRef<llvm::omp::TraitProperty> getConstructTraits() { 733 return ConstructTraits; 734 } 735 void handleConstructTrait(ArrayRef<llvm::omp::TraitProperty> Traits, 736 bool ScopeEntry) { 737 if (ScopeEntry) 738 ConstructTraits.append(Traits.begin(), Traits.end()); 739 else 740 for (llvm::omp::TraitProperty Trait : llvm::reverse(Traits)) { 741 llvm::omp::TraitProperty Top = ConstructTraits.pop_back_val(); 742 assert(Top == Trait && "Something left a trait on the stack!"); 743 (void)Trait; 744 (void)Top; 745 } 746 } 747 748 DefaultDataSharingAttributes getDefaultDSA(unsigned Level) const { 749 return getStackSize() <= Level ? DSA_unspecified 750 : getStackElemAtLevel(Level).DefaultAttr; 751 } 752 DefaultDataSharingAttributes getDefaultDSA() const { 753 return isStackEmpty() ? DSA_unspecified : getTopOfStack().DefaultAttr; 754 } 755 SourceLocation getDefaultDSALocation() const { 756 return isStackEmpty() ? SourceLocation() : getTopOfStack().DefaultAttrLoc; 757 } 758 OpenMPDefaultmapClauseModifier 759 getDefaultmapModifier(OpenMPDefaultmapClauseKind Kind) const { 760 return isStackEmpty() 761 ? OMPC_DEFAULTMAP_MODIFIER_unknown 762 : getTopOfStack().DefaultmapMap[Kind].ImplicitBehavior; 763 } 764 OpenMPDefaultmapClauseModifier 765 getDefaultmapModifierAtLevel(unsigned Level, 766 OpenMPDefaultmapClauseKind Kind) const { 767 return getStackElemAtLevel(Level).DefaultmapMap[Kind].ImplicitBehavior; 768 } 769 bool isDefaultmapCapturedByRef(unsigned Level, 770 OpenMPDefaultmapClauseKind Kind) const { 771 OpenMPDefaultmapClauseModifier M = 772 getDefaultmapModifierAtLevel(Level, Kind); 773 if (Kind == OMPC_DEFAULTMAP_scalar || Kind == OMPC_DEFAULTMAP_pointer) { 774 return (M == OMPC_DEFAULTMAP_MODIFIER_alloc) || 775 (M == OMPC_DEFAULTMAP_MODIFIER_to) || 776 (M == OMPC_DEFAULTMAP_MODIFIER_from) || 777 (M == OMPC_DEFAULTMAP_MODIFIER_tofrom); 778 } 779 return true; 780 } 781 static bool mustBeFirstprivateBase(OpenMPDefaultmapClauseModifier M, 782 OpenMPDefaultmapClauseKind Kind) { 783 switch (Kind) { 784 case OMPC_DEFAULTMAP_scalar: 785 case OMPC_DEFAULTMAP_pointer: 786 return (M == OMPC_DEFAULTMAP_MODIFIER_unknown) || 787 (M == OMPC_DEFAULTMAP_MODIFIER_firstprivate) || 788 (M == OMPC_DEFAULTMAP_MODIFIER_default); 789 case OMPC_DEFAULTMAP_aggregate: 790 return M == OMPC_DEFAULTMAP_MODIFIER_firstprivate; 791 default: 792 break; 793 } 794 llvm_unreachable("Unexpected OpenMPDefaultmapClauseKind enum"); 795 } 796 bool mustBeFirstprivateAtLevel(unsigned Level, 797 OpenMPDefaultmapClauseKind Kind) const { 798 OpenMPDefaultmapClauseModifier M = 799 getDefaultmapModifierAtLevel(Level, Kind); 800 return mustBeFirstprivateBase(M, Kind); 801 } 802 bool mustBeFirstprivate(OpenMPDefaultmapClauseKind Kind) const { 803 OpenMPDefaultmapClauseModifier M = getDefaultmapModifier(Kind); 804 return mustBeFirstprivateBase(M, Kind); 805 } 806 807 /// Checks if the specified variable is a threadprivate. 808 bool isThreadPrivate(VarDecl *D) { 809 const DSAVarData DVar = getTopDSA(D, false); 810 return isOpenMPThreadPrivate(DVar.CKind); 811 } 812 813 /// Marks current region as ordered (it has an 'ordered' clause). 814 void setOrderedRegion(bool IsOrdered, const Expr *Param, 815 OMPOrderedClause *Clause) { 816 if (IsOrdered) 817 getTopOfStack().OrderedRegion.emplace(Param, Clause); 818 else 819 getTopOfStack().OrderedRegion.reset(); 820 } 821 /// Returns true, if region is ordered (has associated 'ordered' clause), 822 /// false - otherwise. 823 bool isOrderedRegion() const { 824 if (const SharingMapTy *Top = getTopOfStackOrNull()) 825 return Top->OrderedRegion.hasValue(); 826 return false; 827 } 828 /// Returns optional parameter for the ordered region. 829 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 830 if (const SharingMapTy *Top = getTopOfStackOrNull()) 831 if (Top->OrderedRegion) 832 return Top->OrderedRegion.getValue(); 833 return std::make_pair(nullptr, nullptr); 834 } 835 /// Returns true, if parent region is ordered (has associated 836 /// 'ordered' clause), false - otherwise. 837 bool isParentOrderedRegion() const { 838 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 839 return Parent->OrderedRegion.hasValue(); 840 return false; 841 } 842 /// Returns optional parameter for the ordered region. 843 std::pair<const Expr *, OMPOrderedClause *> 844 getParentOrderedRegionParam() const { 845 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 846 if (Parent->OrderedRegion) 847 return Parent->OrderedRegion.getValue(); 848 return std::make_pair(nullptr, nullptr); 849 } 850 /// Marks current region as nowait (it has a 'nowait' clause). 851 void setNowaitRegion(bool IsNowait = true) { 852 getTopOfStack().NowaitRegion = IsNowait; 853 } 854 /// Returns true, if parent region is nowait (has associated 855 /// 'nowait' clause), false - otherwise. 856 bool isParentNowaitRegion() const { 857 if (const SharingMapTy *Parent = getSecondOnStackOrNull()) 858 return Parent->NowaitRegion; 859 return false; 860 } 861 /// Marks current region as untied (it has a 'untied' clause). 862 void setUntiedRegion(bool IsUntied = true) { 863 getTopOfStack().UntiedRegion = IsUntied; 864 } 865 /// Return true if current region is untied. 866 bool isUntiedRegion() const { 867 const SharingMapTy *Top = getTopOfStackOrNull(); 868 return Top ? Top->UntiedRegion : false; 869 } 870 /// Marks parent region as cancel region. 871 void setParentCancelRegion(bool Cancel = true) { 872 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 873 Parent->CancelRegion |= Cancel; 874 } 875 /// Return true if current region has inner cancel construct. 876 bool isCancelRegion() const { 877 const SharingMapTy *Top = getTopOfStackOrNull(); 878 return Top ? Top->CancelRegion : false; 879 } 880 881 /// Mark that parent region already has scan directive. 882 void setParentHasScanDirective(SourceLocation Loc) { 883 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 884 Parent->PrevScanLocation = Loc; 885 } 886 /// Return true if current region has inner cancel construct. 887 bool doesParentHasScanDirective() const { 888 const SharingMapTy *Top = getSecondOnStackOrNull(); 889 return Top ? Top->PrevScanLocation.isValid() : false; 890 } 891 /// Return true if current region has inner cancel construct. 892 SourceLocation getParentScanDirectiveLoc() const { 893 const SharingMapTy *Top = getSecondOnStackOrNull(); 894 return Top ? Top->PrevScanLocation : SourceLocation(); 895 } 896 /// Mark that parent region already has ordered directive. 897 void setParentHasOrderedDirective(SourceLocation Loc) { 898 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 899 Parent->PrevOrderedLocation = Loc; 900 } 901 /// Return true if current region has inner ordered construct. 902 bool doesParentHasOrderedDirective() const { 903 const SharingMapTy *Top = getSecondOnStackOrNull(); 904 return Top ? Top->PrevOrderedLocation.isValid() : false; 905 } 906 /// Returns the location of the previously specified ordered directive. 907 SourceLocation getParentOrderedDirectiveLoc() const { 908 const SharingMapTy *Top = getSecondOnStackOrNull(); 909 return Top ? Top->PrevOrderedLocation : SourceLocation(); 910 } 911 912 /// Set collapse value for the region. 913 void setAssociatedLoops(unsigned Val) { 914 getTopOfStack().AssociatedLoops = Val; 915 if (Val > 1) 916 getTopOfStack().HasMutipleLoops = true; 917 } 918 /// Return collapse value for region. 919 unsigned getAssociatedLoops() const { 920 const SharingMapTy *Top = getTopOfStackOrNull(); 921 return Top ? Top->AssociatedLoops : 0; 922 } 923 /// Returns true if the construct is associated with multiple loops. 924 bool hasMutipleLoops() const { 925 const SharingMapTy *Top = getTopOfStackOrNull(); 926 return Top ? Top->HasMutipleLoops : false; 927 } 928 929 /// Marks current target region as one with closely nested teams 930 /// region. 931 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 932 if (SharingMapTy *Parent = getSecondOnStackOrNull()) 933 Parent->InnerTeamsRegionLoc = TeamsRegionLoc; 934 } 935 /// Returns true, if current region has closely nested teams region. 936 bool hasInnerTeamsRegion() const { 937 return getInnerTeamsRegionLoc().isValid(); 938 } 939 /// Returns location of the nested teams region (if any). 940 SourceLocation getInnerTeamsRegionLoc() const { 941 const SharingMapTy *Top = getTopOfStackOrNull(); 942 return Top ? Top->InnerTeamsRegionLoc : SourceLocation(); 943 } 944 945 Scope *getCurScope() const { 946 const SharingMapTy *Top = getTopOfStackOrNull(); 947 return Top ? Top->CurScope : nullptr; 948 } 949 void setContext(DeclContext *DC) { getTopOfStack().Context = DC; } 950 SourceLocation getConstructLoc() const { 951 const SharingMapTy *Top = getTopOfStackOrNull(); 952 return Top ? Top->ConstructLoc : SourceLocation(); 953 } 954 955 /// Do the check specified in \a Check to all component lists and return true 956 /// if any issue is found. 957 bool checkMappableExprComponentListsForDecl( 958 const ValueDecl *VD, bool CurrentRegionOnly, 959 const llvm::function_ref< 960 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 961 OpenMPClauseKind)> 962 Check) const { 963 if (isStackEmpty()) 964 return false; 965 auto SI = begin(); 966 auto SE = end(); 967 968 if (SI == SE) 969 return false; 970 971 if (CurrentRegionOnly) 972 SE = std::next(SI); 973 else 974 std::advance(SI, 1); 975 976 for (; SI != SE; ++SI) { 977 auto MI = SI->MappedExprComponents.find(VD); 978 if (MI != SI->MappedExprComponents.end()) 979 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 980 MI->second.Components) 981 if (Check(L, MI->second.Kind)) 982 return true; 983 } 984 return false; 985 } 986 987 /// Do the check specified in \a Check to all component lists at a given level 988 /// and return true if any issue is found. 989 bool checkMappableExprComponentListsForDeclAtLevel( 990 const ValueDecl *VD, unsigned Level, 991 const llvm::function_ref< 992 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 993 OpenMPClauseKind)> 994 Check) const { 995 if (getStackSize() <= Level) 996 return false; 997 998 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 999 auto MI = StackElem.MappedExprComponents.find(VD); 1000 if (MI != StackElem.MappedExprComponents.end()) 1001 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 1002 MI->second.Components) 1003 if (Check(L, MI->second.Kind)) 1004 return true; 1005 return false; 1006 } 1007 1008 /// Create a new mappable expression component list associated with a given 1009 /// declaration and initialize it with the provided list of components. 1010 void addMappableExpressionComponents( 1011 const ValueDecl *VD, 1012 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 1013 OpenMPClauseKind WhereFoundClauseKind) { 1014 MappedExprComponentTy &MEC = getTopOfStack().MappedExprComponents[VD]; 1015 // Create new entry and append the new components there. 1016 MEC.Components.resize(MEC.Components.size() + 1); 1017 MEC.Components.back().append(Components.begin(), Components.end()); 1018 MEC.Kind = WhereFoundClauseKind; 1019 } 1020 1021 unsigned getNestingLevel() const { 1022 assert(!isStackEmpty()); 1023 return getStackSize() - 1; 1024 } 1025 void addDoacrossDependClause(OMPDependClause *C, 1026 const OperatorOffsetTy &OpsOffs) { 1027 SharingMapTy *Parent = getSecondOnStackOrNull(); 1028 assert(Parent && isOpenMPWorksharingDirective(Parent->Directive)); 1029 Parent->DoacrossDepends.try_emplace(C, OpsOffs); 1030 } 1031 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 1032 getDoacrossDependClauses() const { 1033 const SharingMapTy &StackElem = getTopOfStack(); 1034 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 1035 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 1036 return llvm::make_range(Ref.begin(), Ref.end()); 1037 } 1038 return llvm::make_range(StackElem.DoacrossDepends.end(), 1039 StackElem.DoacrossDepends.end()); 1040 } 1041 1042 // Store types of classes which have been explicitly mapped 1043 void addMappedClassesQualTypes(QualType QT) { 1044 SharingMapTy &StackElem = getTopOfStack(); 1045 StackElem.MappedClassesQualTypes.insert(QT); 1046 } 1047 1048 // Return set of mapped classes types 1049 bool isClassPreviouslyMapped(QualType QT) const { 1050 const SharingMapTy &StackElem = getTopOfStack(); 1051 return StackElem.MappedClassesQualTypes.contains(QT); 1052 } 1053 1054 /// Adds global declare target to the parent target region. 1055 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 1056 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1057 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 1058 "Expected declare target link global."); 1059 for (auto &Elem : *this) { 1060 if (isOpenMPTargetExecutionDirective(Elem.Directive)) { 1061 Elem.DeclareTargetLinkVarDecls.push_back(E); 1062 return; 1063 } 1064 } 1065 } 1066 1067 /// Returns the list of globals with declare target link if current directive 1068 /// is target. 1069 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 1070 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 1071 "Expected target executable directive."); 1072 return getTopOfStack().DeclareTargetLinkVarDecls; 1073 } 1074 1075 /// Adds list of allocators expressions. 1076 void addInnerAllocatorExpr(Expr *E) { 1077 getTopOfStack().InnerUsedAllocators.push_back(E); 1078 } 1079 /// Return list of used allocators. 1080 ArrayRef<Expr *> getInnerAllocators() const { 1081 return getTopOfStack().InnerUsedAllocators; 1082 } 1083 /// Marks the declaration as implicitly firstprivate nin the task-based 1084 /// regions. 1085 void addImplicitTaskFirstprivate(unsigned Level, Decl *D) { 1086 getStackElemAtLevel(Level).ImplicitTaskFirstprivates.insert(D); 1087 } 1088 /// Checks if the decl is implicitly firstprivate in the task-based region. 1089 bool isImplicitTaskFirstprivate(Decl *D) const { 1090 return getTopOfStack().ImplicitTaskFirstprivates.contains(D); 1091 } 1092 1093 /// Marks decl as used in uses_allocators clause as the allocator. 1094 void addUsesAllocatorsDecl(const Decl *D, UsesAllocatorsDeclKind Kind) { 1095 getTopOfStack().UsesAllocatorsDecls.try_emplace(D, Kind); 1096 } 1097 /// Checks if specified decl is used in uses allocator clause as the 1098 /// allocator. 1099 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(unsigned Level, 1100 const Decl *D) const { 1101 const SharingMapTy &StackElem = getTopOfStack(); 1102 auto I = StackElem.UsesAllocatorsDecls.find(D); 1103 if (I == StackElem.UsesAllocatorsDecls.end()) 1104 return None; 1105 return I->getSecond(); 1106 } 1107 Optional<UsesAllocatorsDeclKind> isUsesAllocatorsDecl(const Decl *D) const { 1108 const SharingMapTy &StackElem = getTopOfStack(); 1109 auto I = StackElem.UsesAllocatorsDecls.find(D); 1110 if (I == StackElem.UsesAllocatorsDecls.end()) 1111 return None; 1112 return I->getSecond(); 1113 } 1114 1115 void addDeclareMapperVarRef(Expr *Ref) { 1116 SharingMapTy &StackElem = getTopOfStack(); 1117 StackElem.DeclareMapperVar = Ref; 1118 } 1119 const Expr *getDeclareMapperVarRef() const { 1120 const SharingMapTy *Top = getTopOfStackOrNull(); 1121 return Top ? Top->DeclareMapperVar : nullptr; 1122 } 1123 }; 1124 1125 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1126 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 1127 } 1128 1129 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 1130 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || 1131 DKind == OMPD_unknown; 1132 } 1133 1134 } // namespace 1135 1136 static const Expr *getExprAsWritten(const Expr *E) { 1137 if (const auto *FE = dyn_cast<FullExpr>(E)) 1138 E = FE->getSubExpr(); 1139 1140 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 1141 E = MTE->getSubExpr(); 1142 1143 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 1144 E = Binder->getSubExpr(); 1145 1146 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 1147 E = ICE->getSubExprAsWritten(); 1148 return E->IgnoreParens(); 1149 } 1150 1151 static Expr *getExprAsWritten(Expr *E) { 1152 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 1153 } 1154 1155 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 1156 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 1157 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 1158 D = ME->getMemberDecl(); 1159 const auto *VD = dyn_cast<VarDecl>(D); 1160 const auto *FD = dyn_cast<FieldDecl>(D); 1161 if (VD != nullptr) { 1162 VD = VD->getCanonicalDecl(); 1163 D = VD; 1164 } else { 1165 assert(FD); 1166 FD = FD->getCanonicalDecl(); 1167 D = FD; 1168 } 1169 return D; 1170 } 1171 1172 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 1173 return const_cast<ValueDecl *>( 1174 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 1175 } 1176 1177 DSAStackTy::DSAVarData DSAStackTy::getDSA(const_iterator &Iter, 1178 ValueDecl *D) const { 1179 D = getCanonicalDecl(D); 1180 auto *VD = dyn_cast<VarDecl>(D); 1181 const auto *FD = dyn_cast<FieldDecl>(D); 1182 DSAVarData DVar; 1183 if (Iter == end()) { 1184 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1185 // in a region but not in construct] 1186 // File-scope or namespace-scope variables referenced in called routines 1187 // in the region are shared unless they appear in a threadprivate 1188 // directive. 1189 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 1190 DVar.CKind = OMPC_shared; 1191 1192 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 1193 // in a region but not in construct] 1194 // Variables with static storage duration that are declared in called 1195 // routines in the region are shared. 1196 if (VD && VD->hasGlobalStorage()) 1197 DVar.CKind = OMPC_shared; 1198 1199 // Non-static data members are shared by default. 1200 if (FD) 1201 DVar.CKind = OMPC_shared; 1202 1203 return DVar; 1204 } 1205 1206 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1207 // in a Construct, C/C++, predetermined, p.1] 1208 // Variables with automatic storage duration that are declared in a scope 1209 // inside the construct are private. 1210 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 1211 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 1212 DVar.CKind = OMPC_private; 1213 return DVar; 1214 } 1215 1216 DVar.DKind = Iter->Directive; 1217 // Explicitly specified attributes and local variables with predetermined 1218 // attributes. 1219 if (Iter->SharingMap.count(D)) { 1220 const DSAInfo &Data = Iter->SharingMap.lookup(D); 1221 DVar.RefExpr = Data.RefExpr.getPointer(); 1222 DVar.PrivateCopy = Data.PrivateCopy; 1223 DVar.CKind = Data.Attributes; 1224 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1225 DVar.Modifier = Data.Modifier; 1226 DVar.AppliedToPointee = Data.AppliedToPointee; 1227 return DVar; 1228 } 1229 1230 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1231 // in a Construct, C/C++, implicitly determined, p.1] 1232 // In a parallel or task construct, the data-sharing attributes of these 1233 // variables are determined by the default clause, if present. 1234 switch (Iter->DefaultAttr) { 1235 case DSA_shared: 1236 DVar.CKind = OMPC_shared; 1237 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1238 return DVar; 1239 case DSA_none: 1240 return DVar; 1241 case DSA_firstprivate: 1242 if (VD && VD->getStorageDuration() == SD_Static && 1243 VD->getDeclContext()->isFileContext()) { 1244 DVar.CKind = OMPC_unknown; 1245 } else { 1246 DVar.CKind = OMPC_firstprivate; 1247 } 1248 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1249 return DVar; 1250 case DSA_private: 1251 // each variable with static storage duration that is declared 1252 // in a namespace or global scope and referenced in the construct, 1253 // and that does not have a predetermined data-sharing attribute 1254 if (VD && VD->getStorageDuration() == SD_Static && 1255 VD->getDeclContext()->isFileContext()) { 1256 DVar.CKind = OMPC_unknown; 1257 } else { 1258 DVar.CKind = OMPC_private; 1259 } 1260 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1261 return DVar; 1262 case DSA_unspecified: 1263 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1264 // in a Construct, implicitly determined, p.2] 1265 // In a parallel construct, if no default clause is present, these 1266 // variables are shared. 1267 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 1268 if ((isOpenMPParallelDirective(DVar.DKind) && 1269 !isOpenMPTaskLoopDirective(DVar.DKind)) || 1270 isOpenMPTeamsDirective(DVar.DKind)) { 1271 DVar.CKind = OMPC_shared; 1272 return DVar; 1273 } 1274 1275 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1276 // in a Construct, implicitly determined, p.4] 1277 // In a task construct, if no default clause is present, a variable that in 1278 // the enclosing context is determined to be shared by all implicit tasks 1279 // bound to the current team is shared. 1280 if (isOpenMPTaskingDirective(DVar.DKind)) { 1281 DSAVarData DVarTemp; 1282 const_iterator I = Iter, E = end(); 1283 do { 1284 ++I; 1285 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 1286 // Referenced in a Construct, implicitly determined, p.6] 1287 // In a task construct, if no default clause is present, a variable 1288 // whose data-sharing attribute is not determined by the rules above is 1289 // firstprivate. 1290 DVarTemp = getDSA(I, D); 1291 if (DVarTemp.CKind != OMPC_shared) { 1292 DVar.RefExpr = nullptr; 1293 DVar.CKind = OMPC_firstprivate; 1294 return DVar; 1295 } 1296 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 1297 DVar.CKind = 1298 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 1299 return DVar; 1300 } 1301 } 1302 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1303 // in a Construct, implicitly determined, p.3] 1304 // For constructs other than task, if no default clause is present, these 1305 // variables inherit their data-sharing attributes from the enclosing 1306 // context. 1307 return getDSA(++Iter, D); 1308 } 1309 1310 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 1311 const Expr *NewDE) { 1312 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1313 D = getCanonicalDecl(D); 1314 SharingMapTy &StackElem = getTopOfStack(); 1315 auto It = StackElem.AlignedMap.find(D); 1316 if (It == StackElem.AlignedMap.end()) { 1317 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1318 StackElem.AlignedMap[D] = NewDE; 1319 return nullptr; 1320 } 1321 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1322 return It->second; 1323 } 1324 1325 const Expr *DSAStackTy::addUniqueNontemporal(const ValueDecl *D, 1326 const Expr *NewDE) { 1327 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 1328 D = getCanonicalDecl(D); 1329 SharingMapTy &StackElem = getTopOfStack(); 1330 auto It = StackElem.NontemporalMap.find(D); 1331 if (It == StackElem.NontemporalMap.end()) { 1332 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 1333 StackElem.NontemporalMap[D] = NewDE; 1334 return nullptr; 1335 } 1336 assert(It->second && "Unexpected nullptr expr in the aligned map"); 1337 return It->second; 1338 } 1339 1340 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 1341 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1342 D = getCanonicalDecl(D); 1343 SharingMapTy &StackElem = getTopOfStack(); 1344 StackElem.LCVMap.try_emplace( 1345 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 1346 } 1347 1348 const DSAStackTy::LCDeclInfo 1349 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 1350 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1351 D = getCanonicalDecl(D); 1352 const SharingMapTy &StackElem = getTopOfStack(); 1353 auto It = StackElem.LCVMap.find(D); 1354 if (It != StackElem.LCVMap.end()) 1355 return It->second; 1356 return {0, nullptr}; 1357 } 1358 1359 const DSAStackTy::LCDeclInfo 1360 DSAStackTy::isLoopControlVariable(const ValueDecl *D, unsigned Level) const { 1361 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1362 D = getCanonicalDecl(D); 1363 for (unsigned I = Level + 1; I > 0; --I) { 1364 const SharingMapTy &StackElem = getStackElemAtLevel(I - 1); 1365 auto It = StackElem.LCVMap.find(D); 1366 if (It != StackElem.LCVMap.end()) 1367 return It->second; 1368 } 1369 return {0, nullptr}; 1370 } 1371 1372 const DSAStackTy::LCDeclInfo 1373 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 1374 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1375 assert(Parent && "Data-sharing attributes stack is empty"); 1376 D = getCanonicalDecl(D); 1377 auto It = Parent->LCVMap.find(D); 1378 if (It != Parent->LCVMap.end()) 1379 return It->second; 1380 return {0, nullptr}; 1381 } 1382 1383 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 1384 const SharingMapTy *Parent = getSecondOnStackOrNull(); 1385 assert(Parent && "Data-sharing attributes stack is empty"); 1386 if (Parent->LCVMap.size() < I) 1387 return nullptr; 1388 for (const auto &Pair : Parent->LCVMap) 1389 if (Pair.second.first == I) 1390 return Pair.first; 1391 return nullptr; 1392 } 1393 1394 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 1395 DeclRefExpr *PrivateCopy, unsigned Modifier, 1396 bool AppliedToPointee) { 1397 D = getCanonicalDecl(D); 1398 if (A == OMPC_threadprivate) { 1399 DSAInfo &Data = Threadprivates[D]; 1400 Data.Attributes = A; 1401 Data.RefExpr.setPointer(E); 1402 Data.PrivateCopy = nullptr; 1403 Data.Modifier = Modifier; 1404 } else { 1405 DSAInfo &Data = getTopOfStack().SharingMap[D]; 1406 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 1407 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 1408 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 1409 (isLoopControlVariable(D).first && A == OMPC_private)); 1410 Data.Modifier = Modifier; 1411 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 1412 Data.RefExpr.setInt(/*IntVal=*/true); 1413 return; 1414 } 1415 const bool IsLastprivate = 1416 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 1417 Data.Attributes = A; 1418 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 1419 Data.PrivateCopy = PrivateCopy; 1420 Data.AppliedToPointee = AppliedToPointee; 1421 if (PrivateCopy) { 1422 DSAInfo &Data = getTopOfStack().SharingMap[PrivateCopy->getDecl()]; 1423 Data.Modifier = Modifier; 1424 Data.Attributes = A; 1425 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 1426 Data.PrivateCopy = nullptr; 1427 Data.AppliedToPointee = AppliedToPointee; 1428 } 1429 } 1430 } 1431 1432 /// Build a variable declaration for OpenMP loop iteration variable. 1433 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 1434 StringRef Name, const AttrVec *Attrs = nullptr, 1435 DeclRefExpr *OrigRef = nullptr) { 1436 DeclContext *DC = SemaRef.CurContext; 1437 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 1438 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 1439 auto *Decl = 1440 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 1441 if (Attrs) { 1442 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 1443 I != E; ++I) 1444 Decl->addAttr(*I); 1445 } 1446 Decl->setImplicit(); 1447 if (OrigRef) { 1448 Decl->addAttr( 1449 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1450 } 1451 return Decl; 1452 } 1453 1454 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1455 SourceLocation Loc, 1456 bool RefersToCapture = false) { 1457 D->setReferenced(); 1458 D->markUsed(S.Context); 1459 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1460 SourceLocation(), D, RefersToCapture, Loc, Ty, 1461 VK_LValue); 1462 } 1463 1464 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1465 BinaryOperatorKind BOK) { 1466 D = getCanonicalDecl(D); 1467 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1468 assert( 1469 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1470 "Additional reduction info may be specified only for reduction items."); 1471 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1472 assert(ReductionData.ReductionRange.isInvalid() && 1473 (getTopOfStack().Directive == OMPD_taskgroup || 1474 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1475 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1476 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1477 "Additional reduction info may be specified only once for reduction " 1478 "items."); 1479 ReductionData.set(BOK, SR); 1480 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef; 1481 if (!TaskgroupReductionRef) { 1482 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1483 SemaRef.Context.VoidPtrTy, ".task_red."); 1484 TaskgroupReductionRef = 1485 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1486 } 1487 } 1488 1489 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1490 const Expr *ReductionRef) { 1491 D = getCanonicalDecl(D); 1492 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1493 assert( 1494 getTopOfStack().SharingMap[D].Attributes == OMPC_reduction && 1495 "Additional reduction info may be specified only for reduction items."); 1496 ReductionData &ReductionData = getTopOfStack().ReductionMap[D]; 1497 assert(ReductionData.ReductionRange.isInvalid() && 1498 (getTopOfStack().Directive == OMPD_taskgroup || 1499 ((isOpenMPParallelDirective(getTopOfStack().Directive) || 1500 isOpenMPWorksharingDirective(getTopOfStack().Directive)) && 1501 !isOpenMPSimdDirective(getTopOfStack().Directive))) && 1502 "Additional reduction info may be specified only once for reduction " 1503 "items."); 1504 ReductionData.set(ReductionRef, SR); 1505 Expr *&TaskgroupReductionRef = getTopOfStack().TaskgroupReductionRef; 1506 if (!TaskgroupReductionRef) { 1507 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1508 SemaRef.Context.VoidPtrTy, ".task_red."); 1509 TaskgroupReductionRef = 1510 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1511 } 1512 } 1513 1514 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1515 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1516 Expr *&TaskgroupDescriptor) const { 1517 D = getCanonicalDecl(D); 1518 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1519 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1520 const DSAInfo &Data = I->SharingMap.lookup(D); 1521 if (Data.Attributes != OMPC_reduction || 1522 Data.Modifier != OMPC_REDUCTION_task) 1523 continue; 1524 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1525 if (!ReductionData.ReductionOp || 1526 ReductionData.ReductionOp.is<const Expr *>()) 1527 return DSAVarData(); 1528 SR = ReductionData.ReductionRange; 1529 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1530 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1531 "expression for the descriptor is not " 1532 "set."); 1533 TaskgroupDescriptor = I->TaskgroupReductionRef; 1534 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1535 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1536 /*AppliedToPointee=*/false); 1537 } 1538 return DSAVarData(); 1539 } 1540 1541 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1542 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1543 Expr *&TaskgroupDescriptor) const { 1544 D = getCanonicalDecl(D); 1545 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1546 for (const_iterator I = begin() + 1, E = end(); I != E; ++I) { 1547 const DSAInfo &Data = I->SharingMap.lookup(D); 1548 if (Data.Attributes != OMPC_reduction || 1549 Data.Modifier != OMPC_REDUCTION_task) 1550 continue; 1551 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1552 if (!ReductionData.ReductionOp || 1553 !ReductionData.ReductionOp.is<const Expr *>()) 1554 return DSAVarData(); 1555 SR = ReductionData.ReductionRange; 1556 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1557 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1558 "expression for the descriptor is not " 1559 "set."); 1560 TaskgroupDescriptor = I->TaskgroupReductionRef; 1561 return DSAVarData(I->Directive, OMPC_reduction, Data.RefExpr.getPointer(), 1562 Data.PrivateCopy, I->DefaultAttrLoc, OMPC_REDUCTION_task, 1563 /*AppliedToPointee=*/false); 1564 } 1565 return DSAVarData(); 1566 } 1567 1568 bool DSAStackTy::isOpenMPLocal(VarDecl *D, const_iterator I) const { 1569 D = D->getCanonicalDecl(); 1570 for (const_iterator E = end(); I != E; ++I) { 1571 if (isImplicitOrExplicitTaskingRegion(I->Directive) || 1572 isOpenMPTargetExecutionDirective(I->Directive)) { 1573 if (I->CurScope) { 1574 Scope *TopScope = I->CurScope->getParent(); 1575 Scope *CurScope = getCurScope(); 1576 while (CurScope && CurScope != TopScope && !CurScope->isDeclScope(D)) 1577 CurScope = CurScope->getParent(); 1578 return CurScope != TopScope; 1579 } 1580 for (DeclContext *DC = D->getDeclContext(); DC; DC = DC->getParent()) 1581 if (I->Context == DC) 1582 return true; 1583 return false; 1584 } 1585 } 1586 return false; 1587 } 1588 1589 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1590 bool AcceptIfMutable = true, 1591 bool *IsClassType = nullptr) { 1592 ASTContext &Context = SemaRef.getASTContext(); 1593 Type = Type.getNonReferenceType().getCanonicalType(); 1594 bool IsConstant = Type.isConstant(Context); 1595 Type = Context.getBaseElementType(Type); 1596 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1597 ? Type->getAsCXXRecordDecl() 1598 : nullptr; 1599 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1600 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1601 RD = CTD->getTemplatedDecl(); 1602 if (IsClassType) 1603 *IsClassType = RD; 1604 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1605 RD->hasDefinition() && RD->hasMutableFields()); 1606 } 1607 1608 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1609 QualType Type, OpenMPClauseKind CKind, 1610 SourceLocation ELoc, 1611 bool AcceptIfMutable = true, 1612 bool ListItemNotVar = false) { 1613 ASTContext &Context = SemaRef.getASTContext(); 1614 bool IsClassType; 1615 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1616 unsigned Diag = ListItemNotVar ? diag::err_omp_const_list_item 1617 : IsClassType ? diag::err_omp_const_not_mutable_variable 1618 : diag::err_omp_const_variable; 1619 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1620 if (!ListItemNotVar && D) { 1621 const VarDecl *VD = dyn_cast<VarDecl>(D); 1622 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1623 VarDecl::DeclarationOnly; 1624 SemaRef.Diag(D->getLocation(), 1625 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1626 << D; 1627 } 1628 return true; 1629 } 1630 return false; 1631 } 1632 1633 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1634 bool FromParent) { 1635 D = getCanonicalDecl(D); 1636 DSAVarData DVar; 1637 1638 auto *VD = dyn_cast<VarDecl>(D); 1639 auto TI = Threadprivates.find(D); 1640 if (TI != Threadprivates.end()) { 1641 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1642 DVar.CKind = OMPC_threadprivate; 1643 DVar.Modifier = TI->getSecond().Modifier; 1644 return DVar; 1645 } 1646 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1647 DVar.RefExpr = buildDeclRefExpr( 1648 SemaRef, VD, D->getType().getNonReferenceType(), 1649 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1650 DVar.CKind = OMPC_threadprivate; 1651 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1652 return DVar; 1653 } 1654 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1655 // in a Construct, C/C++, predetermined, p.1] 1656 // Variables appearing in threadprivate directives are threadprivate. 1657 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1658 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1659 SemaRef.getLangOpts().OpenMPUseTLS && 1660 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1661 (VD && VD->getStorageClass() == SC_Register && 1662 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1663 DVar.RefExpr = buildDeclRefExpr( 1664 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1665 DVar.CKind = OMPC_threadprivate; 1666 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1667 return DVar; 1668 } 1669 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1670 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1671 !isLoopControlVariable(D).first) { 1672 const_iterator IterTarget = 1673 std::find_if(begin(), end(), [](const SharingMapTy &Data) { 1674 return isOpenMPTargetExecutionDirective(Data.Directive); 1675 }); 1676 if (IterTarget != end()) { 1677 const_iterator ParentIterTarget = IterTarget + 1; 1678 for (const_iterator Iter = begin(); Iter != ParentIterTarget; ++Iter) { 1679 if (isOpenMPLocal(VD, Iter)) { 1680 DVar.RefExpr = 1681 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1682 D->getLocation()); 1683 DVar.CKind = OMPC_threadprivate; 1684 return DVar; 1685 } 1686 } 1687 if (!isClauseParsingMode() || IterTarget != begin()) { 1688 auto DSAIter = IterTarget->SharingMap.find(D); 1689 if (DSAIter != IterTarget->SharingMap.end() && 1690 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1691 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1692 DVar.CKind = OMPC_threadprivate; 1693 return DVar; 1694 } 1695 const_iterator End = end(); 1696 if (!SemaRef.isOpenMPCapturedByRef(D, 1697 std::distance(ParentIterTarget, End), 1698 /*OpenMPCaptureLevel=*/0)) { 1699 DVar.RefExpr = 1700 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1701 IterTarget->ConstructLoc); 1702 DVar.CKind = OMPC_threadprivate; 1703 return DVar; 1704 } 1705 } 1706 } 1707 } 1708 1709 if (isStackEmpty()) 1710 // Not in OpenMP execution region and top scope was already checked. 1711 return DVar; 1712 1713 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1714 // in a Construct, C/C++, predetermined, p.4] 1715 // Static data members are shared. 1716 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1717 // in a Construct, C/C++, predetermined, p.7] 1718 // Variables with static storage duration that are declared in a scope 1719 // inside the construct are shared. 1720 if (VD && VD->isStaticDataMember()) { 1721 // Check for explicitly specified attributes. 1722 const_iterator I = begin(); 1723 const_iterator EndI = end(); 1724 if (FromParent && I != EndI) 1725 ++I; 1726 if (I != EndI) { 1727 auto It = I->SharingMap.find(D); 1728 if (It != I->SharingMap.end()) { 1729 const DSAInfo &Data = It->getSecond(); 1730 DVar.RefExpr = Data.RefExpr.getPointer(); 1731 DVar.PrivateCopy = Data.PrivateCopy; 1732 DVar.CKind = Data.Attributes; 1733 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1734 DVar.DKind = I->Directive; 1735 DVar.Modifier = Data.Modifier; 1736 DVar.AppliedToPointee = Data.AppliedToPointee; 1737 return DVar; 1738 } 1739 } 1740 1741 DVar.CKind = OMPC_shared; 1742 return DVar; 1743 } 1744 1745 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1746 // The predetermined shared attribute for const-qualified types having no 1747 // mutable members was removed after OpenMP 3.1. 1748 if (SemaRef.LangOpts.OpenMP <= 31) { 1749 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1750 // in a Construct, C/C++, predetermined, p.6] 1751 // Variables with const qualified type having no mutable member are 1752 // shared. 1753 if (isConstNotMutableType(SemaRef, D->getType())) { 1754 // Variables with const-qualified type having no mutable member may be 1755 // listed in a firstprivate clause, even if they are static data members. 1756 DSAVarData DVarTemp = hasInnermostDSA( 1757 D, 1758 [](OpenMPClauseKind C, bool) { 1759 return C == OMPC_firstprivate || C == OMPC_shared; 1760 }, 1761 MatchesAlways, FromParent); 1762 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1763 return DVarTemp; 1764 1765 DVar.CKind = OMPC_shared; 1766 return DVar; 1767 } 1768 } 1769 1770 // Explicitly specified attributes and local variables with predetermined 1771 // attributes. 1772 const_iterator I = begin(); 1773 const_iterator EndI = end(); 1774 if (FromParent && I != EndI) 1775 ++I; 1776 if (I == EndI) 1777 return DVar; 1778 auto It = I->SharingMap.find(D); 1779 if (It != I->SharingMap.end()) { 1780 const DSAInfo &Data = It->getSecond(); 1781 DVar.RefExpr = Data.RefExpr.getPointer(); 1782 DVar.PrivateCopy = Data.PrivateCopy; 1783 DVar.CKind = Data.Attributes; 1784 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1785 DVar.DKind = I->Directive; 1786 DVar.Modifier = Data.Modifier; 1787 DVar.AppliedToPointee = Data.AppliedToPointee; 1788 } 1789 1790 return DVar; 1791 } 1792 1793 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1794 bool FromParent) const { 1795 if (isStackEmpty()) { 1796 const_iterator I; 1797 return getDSA(I, D); 1798 } 1799 D = getCanonicalDecl(D); 1800 const_iterator StartI = begin(); 1801 const_iterator EndI = end(); 1802 if (FromParent && StartI != EndI) 1803 ++StartI; 1804 return getDSA(StartI, D); 1805 } 1806 1807 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1808 unsigned Level) const { 1809 if (getStackSize() <= Level) 1810 return DSAVarData(); 1811 D = getCanonicalDecl(D); 1812 const_iterator StartI = std::next(begin(), getStackSize() - 1 - Level); 1813 return getDSA(StartI, D); 1814 } 1815 1816 const DSAStackTy::DSAVarData 1817 DSAStackTy::hasDSA(ValueDecl *D, 1818 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1819 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1820 bool FromParent) const { 1821 if (isStackEmpty()) 1822 return {}; 1823 D = getCanonicalDecl(D); 1824 const_iterator I = begin(); 1825 const_iterator EndI = end(); 1826 if (FromParent && I != EndI) 1827 ++I; 1828 for (; I != EndI; ++I) { 1829 if (!DPred(I->Directive) && 1830 !isImplicitOrExplicitTaskingRegion(I->Directive)) 1831 continue; 1832 const_iterator NewI = I; 1833 DSAVarData DVar = getDSA(NewI, D); 1834 if (I == NewI && CPred(DVar.CKind, DVar.AppliedToPointee)) 1835 return DVar; 1836 } 1837 return {}; 1838 } 1839 1840 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1841 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1842 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1843 bool FromParent) const { 1844 if (isStackEmpty()) 1845 return {}; 1846 D = getCanonicalDecl(D); 1847 const_iterator StartI = begin(); 1848 const_iterator EndI = end(); 1849 if (FromParent && StartI != EndI) 1850 ++StartI; 1851 if (StartI == EndI || !DPred(StartI->Directive)) 1852 return {}; 1853 const_iterator NewI = StartI; 1854 DSAVarData DVar = getDSA(NewI, D); 1855 return (NewI == StartI && CPred(DVar.CKind, DVar.AppliedToPointee)) 1856 ? DVar 1857 : DSAVarData(); 1858 } 1859 1860 bool DSAStackTy::hasExplicitDSA( 1861 const ValueDecl *D, 1862 const llvm::function_ref<bool(OpenMPClauseKind, bool)> CPred, 1863 unsigned Level, bool NotLastprivate) const { 1864 if (getStackSize() <= Level) 1865 return false; 1866 D = getCanonicalDecl(D); 1867 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1868 auto I = StackElem.SharingMap.find(D); 1869 if (I != StackElem.SharingMap.end() && I->getSecond().RefExpr.getPointer() && 1870 CPred(I->getSecond().Attributes, I->getSecond().AppliedToPointee) && 1871 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1872 return true; 1873 // Check predetermined rules for the loop control variables. 1874 auto LI = StackElem.LCVMap.find(D); 1875 if (LI != StackElem.LCVMap.end()) 1876 return CPred(OMPC_private, /*AppliedToPointee=*/false); 1877 return false; 1878 } 1879 1880 bool DSAStackTy::hasExplicitDirective( 1881 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1882 unsigned Level) const { 1883 if (getStackSize() <= Level) 1884 return false; 1885 const SharingMapTy &StackElem = getStackElemAtLevel(Level); 1886 return DPred(StackElem.Directive); 1887 } 1888 1889 bool DSAStackTy::hasDirective( 1890 const llvm::function_ref<bool(OpenMPDirectiveKind, 1891 const DeclarationNameInfo &, SourceLocation)> 1892 DPred, 1893 bool FromParent) const { 1894 // We look only in the enclosing region. 1895 size_t Skip = FromParent ? 2 : 1; 1896 for (const_iterator I = begin() + std::min(Skip, getStackSize()), E = end(); 1897 I != E; ++I) { 1898 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1899 return true; 1900 } 1901 return false; 1902 } 1903 1904 void Sema::InitDataSharingAttributesStack() { 1905 VarDataSharingAttributesStack = new DSAStackTy(*this); 1906 } 1907 1908 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1909 1910 void Sema::pushOpenMPFunctionRegion() { DSAStack->pushFunction(); } 1911 1912 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1913 DSAStack->popFunction(OldFSI); 1914 } 1915 1916 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1917 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1918 "Expected OpenMP device compilation."); 1919 return !S.isInOpenMPTargetExecutionDirective(); 1920 } 1921 1922 namespace { 1923 /// Status of the function emission on the host/device. 1924 enum class FunctionEmissionStatus { 1925 Emitted, 1926 Discarded, 1927 Unknown, 1928 }; 1929 } // anonymous namespace 1930 1931 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1932 unsigned DiagID, 1933 FunctionDecl *FD) { 1934 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1935 "Expected OpenMP device compilation."); 1936 1937 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop; 1938 if (FD) { 1939 FunctionEmissionStatus FES = getEmissionStatus(FD); 1940 switch (FES) { 1941 case FunctionEmissionStatus::Emitted: 1942 Kind = SemaDiagnosticBuilder::K_Immediate; 1943 break; 1944 case FunctionEmissionStatus::Unknown: 1945 // TODO: We should always delay diagnostics here in case a target 1946 // region is in a function we do not emit. However, as the 1947 // current diagnostics are associated with the function containing 1948 // the target region and we do not emit that one, we would miss out 1949 // on diagnostics for the target region itself. We need to anchor 1950 // the diagnostics with the new generated function *or* ensure we 1951 // emit diagnostics associated with the surrounding function. 1952 Kind = isOpenMPDeviceDelayedContext(*this) 1953 ? SemaDiagnosticBuilder::K_Deferred 1954 : SemaDiagnosticBuilder::K_Immediate; 1955 break; 1956 case FunctionEmissionStatus::TemplateDiscarded: 1957 case FunctionEmissionStatus::OMPDiscarded: 1958 Kind = SemaDiagnosticBuilder::K_Nop; 1959 break; 1960 case FunctionEmissionStatus::CUDADiscarded: 1961 llvm_unreachable("CUDADiscarded unexpected in OpenMP device compilation"); 1962 break; 1963 } 1964 } 1965 1966 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this); 1967 } 1968 1969 Sema::SemaDiagnosticBuilder Sema::diagIfOpenMPHostCode(SourceLocation Loc, 1970 unsigned DiagID, 1971 FunctionDecl *FD) { 1972 assert(LangOpts.OpenMP && !LangOpts.OpenMPIsDevice && 1973 "Expected OpenMP host compilation."); 1974 1975 SemaDiagnosticBuilder::Kind Kind = SemaDiagnosticBuilder::K_Nop; 1976 if (FD) { 1977 FunctionEmissionStatus FES = getEmissionStatus(FD); 1978 switch (FES) { 1979 case FunctionEmissionStatus::Emitted: 1980 Kind = SemaDiagnosticBuilder::K_Immediate; 1981 break; 1982 case FunctionEmissionStatus::Unknown: 1983 Kind = SemaDiagnosticBuilder::K_Deferred; 1984 break; 1985 case FunctionEmissionStatus::TemplateDiscarded: 1986 case FunctionEmissionStatus::OMPDiscarded: 1987 case FunctionEmissionStatus::CUDADiscarded: 1988 Kind = SemaDiagnosticBuilder::K_Nop; 1989 break; 1990 } 1991 } 1992 1993 return SemaDiagnosticBuilder(Kind, Loc, DiagID, FD, *this); 1994 } 1995 1996 static OpenMPDefaultmapClauseKind 1997 getVariableCategoryFromDecl(const LangOptions &LO, const ValueDecl *VD) { 1998 if (LO.OpenMP <= 45) { 1999 if (VD->getType().getNonReferenceType()->isScalarType()) 2000 return OMPC_DEFAULTMAP_scalar; 2001 return OMPC_DEFAULTMAP_aggregate; 2002 } 2003 if (VD->getType().getNonReferenceType()->isAnyPointerType()) 2004 return OMPC_DEFAULTMAP_pointer; 2005 if (VD->getType().getNonReferenceType()->isScalarType()) 2006 return OMPC_DEFAULTMAP_scalar; 2007 return OMPC_DEFAULTMAP_aggregate; 2008 } 2009 2010 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level, 2011 unsigned OpenMPCaptureLevel) const { 2012 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2013 2014 ASTContext &Ctx = getASTContext(); 2015 bool IsByRef = true; 2016 2017 // Find the directive that is associated with the provided scope. 2018 D = cast<ValueDecl>(D->getCanonicalDecl()); 2019 QualType Ty = D->getType(); 2020 2021 bool IsVariableUsedInMapClause = false; 2022 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 2023 // This table summarizes how a given variable should be passed to the device 2024 // given its type and the clauses where it appears. This table is based on 2025 // the description in OpenMP 4.5 [2.10.4, target Construct] and 2026 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 2027 // 2028 // ========================================================================= 2029 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 2030 // | |(tofrom:scalar)| | pvt | | | | 2031 // ========================================================================= 2032 // | scl | | | | - | | bycopy| 2033 // | scl | | - | x | - | - | bycopy| 2034 // | scl | | x | - | - | - | null | 2035 // | scl | x | | | - | | byref | 2036 // | scl | x | - | x | - | - | bycopy| 2037 // | scl | x | x | - | - | - | null | 2038 // | scl | | - | - | - | x | byref | 2039 // | scl | x | - | - | - | x | byref | 2040 // 2041 // | agg | n.a. | | | - | | byref | 2042 // | agg | n.a. | - | x | - | - | byref | 2043 // | agg | n.a. | x | - | - | - | null | 2044 // | agg | n.a. | - | - | - | x | byref | 2045 // | agg | n.a. | - | - | - | x[] | byref | 2046 // 2047 // | ptr | n.a. | | | - | | bycopy| 2048 // | ptr | n.a. | - | x | - | - | bycopy| 2049 // | ptr | n.a. | x | - | - | - | null | 2050 // | ptr | n.a. | - | - | - | x | byref | 2051 // | ptr | n.a. | - | - | - | x[] | bycopy| 2052 // | ptr | n.a. | - | - | x | | bycopy| 2053 // | ptr | n.a. | - | - | x | x | bycopy| 2054 // | ptr | n.a. | - | - | x | x[] | bycopy| 2055 // ========================================================================= 2056 // Legend: 2057 // scl - scalar 2058 // ptr - pointer 2059 // agg - aggregate 2060 // x - applies 2061 // - - invalid in this combination 2062 // [] - mapped with an array section 2063 // byref - should be mapped by reference 2064 // byval - should be mapped by value 2065 // null - initialize a local variable to null on the device 2066 // 2067 // Observations: 2068 // - All scalar declarations that show up in a map clause have to be passed 2069 // by reference, because they may have been mapped in the enclosing data 2070 // environment. 2071 // - If the scalar value does not fit the size of uintptr, it has to be 2072 // passed by reference, regardless the result in the table above. 2073 // - For pointers mapped by value that have either an implicit map or an 2074 // array section, the runtime library may pass the NULL value to the 2075 // device instead of the value passed to it by the compiler. 2076 2077 if (Ty->isReferenceType()) 2078 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 2079 2080 // Locate map clauses and see if the variable being captured is referred to 2081 // in any of those clauses. Here we only care about variables, not fields, 2082 // because fields are part of aggregates. 2083 bool IsVariableAssociatedWithSection = false; 2084 2085 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2086 D, Level, 2087 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, 2088 D](OMPClauseMappableExprCommon::MappableExprComponentListRef 2089 MapExprComponents, 2090 OpenMPClauseKind WhereFoundClauseKind) { 2091 // Only the map clause information influences how a variable is 2092 // captured. E.g. is_device_ptr does not require changing the default 2093 // behavior. 2094 if (WhereFoundClauseKind != OMPC_map) 2095 return false; 2096 2097 auto EI = MapExprComponents.rbegin(); 2098 auto EE = MapExprComponents.rend(); 2099 2100 assert(EI != EE && "Invalid map expression!"); 2101 2102 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 2103 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 2104 2105 ++EI; 2106 if (EI == EE) 2107 return false; 2108 2109 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 2110 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 2111 isa<MemberExpr>(EI->getAssociatedExpression()) || 2112 isa<OMPArrayShapingExpr>(EI->getAssociatedExpression())) { 2113 IsVariableAssociatedWithSection = true; 2114 // There is nothing more we need to know about this variable. 2115 return true; 2116 } 2117 2118 // Keep looking for more map info. 2119 return false; 2120 }); 2121 2122 if (IsVariableUsedInMapClause) { 2123 // If variable is identified in a map clause it is always captured by 2124 // reference except if it is a pointer that is dereferenced somehow. 2125 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 2126 } else { 2127 // By default, all the data that has a scalar type is mapped by copy 2128 // (except for reduction variables). 2129 // Defaultmap scalar is mutual exclusive to defaultmap pointer 2130 IsByRef = (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 2131 !Ty->isAnyPointerType()) || 2132 !Ty->isScalarType() || 2133 DSAStack->isDefaultmapCapturedByRef( 2134 Level, getVariableCategoryFromDecl(LangOpts, D)) || 2135 DSAStack->hasExplicitDSA( 2136 D, 2137 [](OpenMPClauseKind K, bool AppliedToPointee) { 2138 return K == OMPC_reduction && !AppliedToPointee; 2139 }, 2140 Level); 2141 } 2142 } 2143 2144 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 2145 IsByRef = 2146 ((IsVariableUsedInMapClause && 2147 DSAStack->getCaptureRegion(Level, OpenMPCaptureLevel) == 2148 OMPD_target) || 2149 !(DSAStack->hasExplicitDSA( 2150 D, 2151 [](OpenMPClauseKind K, bool AppliedToPointee) -> bool { 2152 return K == OMPC_firstprivate || 2153 (K == OMPC_reduction && AppliedToPointee); 2154 }, 2155 Level, /*NotLastprivate=*/true) || 2156 DSAStack->isUsesAllocatorsDecl(Level, D))) && 2157 // If the variable is artificial and must be captured by value - try to 2158 // capture by value. 2159 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 2160 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()) && 2161 // If the variable is implicitly firstprivate and scalar - capture by 2162 // copy 2163 !((DSAStack->getDefaultDSA() == DSA_firstprivate || 2164 DSAStack->getDefaultDSA() == DSA_private) && 2165 !DSAStack->hasExplicitDSA( 2166 D, [](OpenMPClauseKind K, bool) { return K != OMPC_unknown; }, 2167 Level) && 2168 !DSAStack->isLoopControlVariable(D, Level).first); 2169 } 2170 2171 // When passing data by copy, we need to make sure it fits the uintptr size 2172 // and alignment, because the runtime library only deals with uintptr types. 2173 // If it does not fit the uintptr size, we need to pass the data by reference 2174 // instead. 2175 if (!IsByRef && 2176 (Ctx.getTypeSizeInChars(Ty) > 2177 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 2178 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 2179 IsByRef = true; 2180 } 2181 2182 return IsByRef; 2183 } 2184 2185 unsigned Sema::getOpenMPNestingLevel() const { 2186 assert(getLangOpts().OpenMP); 2187 return DSAStack->getNestingLevel(); 2188 } 2189 2190 bool Sema::isInOpenMPTaskUntiedContext() const { 2191 return isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 2192 DSAStack->isUntiedRegion(); 2193 } 2194 2195 bool Sema::isInOpenMPTargetExecutionDirective() const { 2196 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 2197 !DSAStack->isClauseParsingMode()) || 2198 DSAStack->hasDirective( 2199 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2200 SourceLocation) -> bool { 2201 return isOpenMPTargetExecutionDirective(K); 2202 }, 2203 false); 2204 } 2205 2206 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D, bool CheckScopeInfo, 2207 unsigned StopAt) { 2208 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2209 D = getCanonicalDecl(D); 2210 2211 auto *VD = dyn_cast<VarDecl>(D); 2212 // Do not capture constexpr variables. 2213 if (VD && VD->isConstexpr()) 2214 return nullptr; 2215 2216 // If we want to determine whether the variable should be captured from the 2217 // perspective of the current capturing scope, and we've already left all the 2218 // capturing scopes of the top directive on the stack, check from the 2219 // perspective of its parent directive (if any) instead. 2220 DSAStackTy::ParentDirectiveScope InParentDirectiveRAII( 2221 *DSAStack, CheckScopeInfo && DSAStack->isBodyComplete()); 2222 2223 // If we are attempting to capture a global variable in a directive with 2224 // 'target' we return true so that this global is also mapped to the device. 2225 // 2226 if (VD && !VD->hasLocalStorage() && 2227 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 2228 if (isInOpenMPTargetExecutionDirective()) { 2229 DSAStackTy::DSAVarData DVarTop = 2230 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2231 if (DVarTop.CKind != OMPC_unknown && DVarTop.RefExpr) 2232 return VD; 2233 // If the declaration is enclosed in a 'declare target' directive, 2234 // then it should not be captured. 2235 // 2236 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2237 return nullptr; 2238 CapturedRegionScopeInfo *CSI = nullptr; 2239 for (FunctionScopeInfo *FSI : llvm::drop_begin( 2240 llvm::reverse(FunctionScopes), 2241 CheckScopeInfo ? (FunctionScopes.size() - (StopAt + 1)) : 0)) { 2242 if (!isa<CapturingScopeInfo>(FSI)) 2243 return nullptr; 2244 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2245 if (RSI->CapRegionKind == CR_OpenMP) { 2246 CSI = RSI; 2247 break; 2248 } 2249 } 2250 assert(CSI && "Failed to find CapturedRegionScopeInfo"); 2251 SmallVector<OpenMPDirectiveKind, 4> Regions; 2252 getOpenMPCaptureRegions(Regions, 2253 DSAStack->getDirective(CSI->OpenMPLevel)); 2254 if (Regions[CSI->OpenMPCaptureLevel] != OMPD_task) 2255 return VD; 2256 } 2257 if (isInOpenMPDeclareTargetContext()) { 2258 // Try to mark variable as declare target if it is used in capturing 2259 // regions. 2260 if (LangOpts.OpenMP <= 45 && 2261 !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 2262 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 2263 return nullptr; 2264 } 2265 } 2266 2267 if (CheckScopeInfo) { 2268 bool OpenMPFound = false; 2269 for (unsigned I = StopAt + 1; I > 0; --I) { 2270 FunctionScopeInfo *FSI = FunctionScopes[I - 1]; 2271 if (!isa<CapturingScopeInfo>(FSI)) 2272 return nullptr; 2273 if (auto *RSI = dyn_cast<CapturedRegionScopeInfo>(FSI)) 2274 if (RSI->CapRegionKind == CR_OpenMP) { 2275 OpenMPFound = true; 2276 break; 2277 } 2278 } 2279 if (!OpenMPFound) 2280 return nullptr; 2281 } 2282 2283 if (DSAStack->getCurrentDirective() != OMPD_unknown && 2284 (!DSAStack->isClauseParsingMode() || 2285 DSAStack->getParentDirective() != OMPD_unknown)) { 2286 auto &&Info = DSAStack->isLoopControlVariable(D); 2287 if (Info.first || 2288 (VD && VD->hasLocalStorage() && 2289 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 2290 (VD && DSAStack->isForceVarCapturing())) 2291 return VD ? VD : Info.second; 2292 DSAStackTy::DSAVarData DVarTop = 2293 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 2294 if (DVarTop.CKind != OMPC_unknown && isOpenMPPrivate(DVarTop.CKind) && 2295 (!VD || VD->hasLocalStorage() || !DVarTop.AppliedToPointee)) 2296 return VD ? VD : cast<VarDecl>(DVarTop.PrivateCopy->getDecl()); 2297 // Threadprivate variables must not be captured. 2298 if (isOpenMPThreadPrivate(DVarTop.CKind)) 2299 return nullptr; 2300 // The variable is not private or it is the variable in the directive with 2301 // default(none) clause and not used in any clause. 2302 DSAStackTy::DSAVarData DVarPrivate = DSAStack->hasDSA( 2303 D, 2304 [](OpenMPClauseKind C, bool AppliedToPointee) { 2305 return isOpenMPPrivate(C) && !AppliedToPointee; 2306 }, 2307 [](OpenMPDirectiveKind) { return true; }, 2308 DSAStack->isClauseParsingMode()); 2309 // Global shared must not be captured. 2310 if (VD && !VD->hasLocalStorage() && DVarPrivate.CKind == OMPC_unknown && 2311 ((DSAStack->getDefaultDSA() != DSA_none && 2312 DSAStack->getDefaultDSA() != DSA_private && 2313 DSAStack->getDefaultDSA() != DSA_firstprivate) || 2314 DVarTop.CKind == OMPC_shared)) 2315 return nullptr; 2316 if (DVarPrivate.CKind != OMPC_unknown || 2317 (VD && (DSAStack->getDefaultDSA() == DSA_none || 2318 DSAStack->getDefaultDSA() == DSA_private || 2319 DSAStack->getDefaultDSA() == DSA_firstprivate))) 2320 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 2321 } 2322 return nullptr; 2323 } 2324 2325 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 2326 unsigned Level) const { 2327 FunctionScopesIndex -= getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2328 } 2329 2330 void Sema::startOpenMPLoop() { 2331 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2332 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 2333 DSAStack->loopInit(); 2334 } 2335 2336 void Sema::startOpenMPCXXRangeFor() { 2337 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 2338 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2339 DSAStack->resetPossibleLoopCounter(); 2340 DSAStack->loopStart(); 2341 } 2342 } 2343 2344 OpenMPClauseKind Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level, 2345 unsigned CapLevel) const { 2346 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2347 if (DSAStack->hasExplicitDirective(isOpenMPTaskingDirective, Level)) { 2348 bool IsTriviallyCopyable = 2349 D->getType().getNonReferenceType().isTriviallyCopyableType(Context) && 2350 !D->getType() 2351 .getNonReferenceType() 2352 .getCanonicalType() 2353 ->getAsCXXRecordDecl(); 2354 OpenMPDirectiveKind DKind = DSAStack->getDirective(Level); 2355 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2356 getOpenMPCaptureRegions(CaptureRegions, DKind); 2357 if (isOpenMPTaskingDirective(CaptureRegions[CapLevel]) && 2358 (IsTriviallyCopyable || 2359 !isOpenMPTaskLoopDirective(CaptureRegions[CapLevel]))) { 2360 if (DSAStack->hasExplicitDSA( 2361 D, 2362 [](OpenMPClauseKind K, bool) { return K == OMPC_firstprivate; }, 2363 Level, /*NotLastprivate=*/true)) 2364 return OMPC_firstprivate; 2365 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2366 if (DVar.CKind != OMPC_shared && 2367 !DSAStack->isLoopControlVariable(D, Level).first && !DVar.RefExpr) { 2368 DSAStack->addImplicitTaskFirstprivate(Level, D); 2369 return OMPC_firstprivate; 2370 } 2371 } 2372 } 2373 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2374 if (DSAStack->getAssociatedLoops() > 0 && !DSAStack->isLoopStarted()) { 2375 DSAStack->resetPossibleLoopCounter(D); 2376 DSAStack->loopStart(); 2377 return OMPC_private; 2378 } 2379 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 2380 DSAStack->isLoopControlVariable(D).first) && 2381 !DSAStack->hasExplicitDSA( 2382 D, [](OpenMPClauseKind K, bool) { return K != OMPC_private; }, 2383 Level) && 2384 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 2385 return OMPC_private; 2386 } 2387 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2388 if (DSAStack->isThreadPrivate(const_cast<VarDecl *>(VD)) && 2389 DSAStack->isForceVarCapturing() && 2390 !DSAStack->hasExplicitDSA( 2391 D, [](OpenMPClauseKind K, bool) { return K == OMPC_copyin; }, 2392 Level)) 2393 return OMPC_private; 2394 } 2395 // User-defined allocators are private since they must be defined in the 2396 // context of target region. 2397 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level) && 2398 DSAStack->isUsesAllocatorsDecl(Level, D).value_or( 2399 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 2400 DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator) 2401 return OMPC_private; 2402 return (DSAStack->hasExplicitDSA( 2403 D, [](OpenMPClauseKind K, bool) { return K == OMPC_private; }, 2404 Level) || 2405 (DSAStack->isClauseParsingMode() && 2406 DSAStack->getClauseParsingMode() == OMPC_private) || 2407 // Consider taskgroup reduction descriptor variable a private 2408 // to avoid possible capture in the region. 2409 (DSAStack->hasExplicitDirective( 2410 [](OpenMPDirectiveKind K) { 2411 return K == OMPD_taskgroup || 2412 ((isOpenMPParallelDirective(K) || 2413 isOpenMPWorksharingDirective(K)) && 2414 !isOpenMPSimdDirective(K)); 2415 }, 2416 Level) && 2417 DSAStack->isTaskgroupReductionRef(D, Level))) 2418 ? OMPC_private 2419 : OMPC_unknown; 2420 } 2421 2422 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 2423 unsigned Level) { 2424 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2425 D = getCanonicalDecl(D); 2426 OpenMPClauseKind OMPC = OMPC_unknown; 2427 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 2428 const unsigned NewLevel = I - 1; 2429 if (DSAStack->hasExplicitDSA( 2430 D, 2431 [&OMPC](const OpenMPClauseKind K, bool AppliedToPointee) { 2432 if (isOpenMPPrivate(K) && !AppliedToPointee) { 2433 OMPC = K; 2434 return true; 2435 } 2436 return false; 2437 }, 2438 NewLevel)) 2439 break; 2440 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 2441 D, NewLevel, 2442 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2443 OpenMPClauseKind) { return true; })) { 2444 OMPC = OMPC_map; 2445 break; 2446 } 2447 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2448 NewLevel)) { 2449 OMPC = OMPC_map; 2450 if (DSAStack->mustBeFirstprivateAtLevel( 2451 NewLevel, getVariableCategoryFromDecl(LangOpts, D))) 2452 OMPC = OMPC_firstprivate; 2453 break; 2454 } 2455 } 2456 if (OMPC != OMPC_unknown) 2457 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, unsigned(OMPC))); 2458 } 2459 2460 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, unsigned Level, 2461 unsigned CaptureLevel) const { 2462 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2463 // Return true if the current level is no longer enclosed in a target region. 2464 2465 SmallVector<OpenMPDirectiveKind, 4> Regions; 2466 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 2467 const auto *VD = dyn_cast<VarDecl>(D); 2468 return VD && !VD->hasLocalStorage() && 2469 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 2470 Level) && 2471 Regions[CaptureLevel] != OMPD_task; 2472 } 2473 2474 bool Sema::isOpenMPGlobalCapturedDecl(ValueDecl *D, unsigned Level, 2475 unsigned CaptureLevel) const { 2476 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 2477 // Return true if the current level is no longer enclosed in a target region. 2478 2479 if (const auto *VD = dyn_cast<VarDecl>(D)) { 2480 if (!VD->hasLocalStorage()) { 2481 if (isInOpenMPTargetExecutionDirective()) 2482 return true; 2483 DSAStackTy::DSAVarData TopDVar = 2484 DSAStack->getTopDSA(D, /*FromParent=*/false); 2485 unsigned NumLevels = 2486 getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 2487 if (Level == 0) 2488 // non-file scope static variale with default(firstprivate) 2489 // should be gloabal captured. 2490 return (NumLevels == CaptureLevel + 1 && 2491 (TopDVar.CKind != OMPC_shared || 2492 DSAStack->getDefaultDSA() == DSA_firstprivate)); 2493 do { 2494 --Level; 2495 DSAStackTy::DSAVarData DVar = DSAStack->getImplicitDSA(D, Level); 2496 if (DVar.CKind != OMPC_shared) 2497 return true; 2498 } while (Level > 0); 2499 } 2500 } 2501 return true; 2502 } 2503 2504 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 2505 2506 void Sema::ActOnOpenMPBeginDeclareVariant(SourceLocation Loc, 2507 OMPTraitInfo &TI) { 2508 OMPDeclareVariantScopes.push_back(OMPDeclareVariantScope(TI)); 2509 } 2510 2511 void Sema::ActOnOpenMPEndDeclareVariant() { 2512 assert(isInOpenMPDeclareVariantScope() && 2513 "Not in OpenMP declare variant scope!"); 2514 2515 OMPDeclareVariantScopes.pop_back(); 2516 } 2517 2518 void Sema::finalizeOpenMPDelayedAnalysis(const FunctionDecl *Caller, 2519 const FunctionDecl *Callee, 2520 SourceLocation Loc) { 2521 assert(LangOpts.OpenMP && "Expected OpenMP compilation mode."); 2522 Optional<OMPDeclareTargetDeclAttr::DevTypeTy> DevTy = 2523 OMPDeclareTargetDeclAttr::getDeviceType(Caller->getMostRecentDecl()); 2524 // Ignore host functions during device analyzis. 2525 if (LangOpts.OpenMPIsDevice && 2526 (!DevTy || *DevTy == OMPDeclareTargetDeclAttr::DT_Host)) 2527 return; 2528 // Ignore nohost functions during host analyzis. 2529 if (!LangOpts.OpenMPIsDevice && DevTy && 2530 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) 2531 return; 2532 const FunctionDecl *FD = Callee->getMostRecentDecl(); 2533 DevTy = OMPDeclareTargetDeclAttr::getDeviceType(FD); 2534 if (LangOpts.OpenMPIsDevice && DevTy && 2535 *DevTy == OMPDeclareTargetDeclAttr::DT_Host) { 2536 // Diagnose host function called during device codegen. 2537 StringRef HostDevTy = 2538 getOpenMPSimpleClauseTypeName(OMPC_device_type, OMPC_DEVICE_TYPE_host); 2539 Diag(Loc, diag::err_omp_wrong_device_function_call) << HostDevTy << 0; 2540 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2541 diag::note_omp_marked_device_type_here) 2542 << HostDevTy; 2543 return; 2544 } 2545 if (!LangOpts.OpenMPIsDevice && !LangOpts.OpenMPOffloadMandatory && DevTy && 2546 *DevTy == OMPDeclareTargetDeclAttr::DT_NoHost) { 2547 // Diagnose nohost function called during host codegen. 2548 StringRef NoHostDevTy = getOpenMPSimpleClauseTypeName( 2549 OMPC_device_type, OMPC_DEVICE_TYPE_nohost); 2550 Diag(Loc, diag::err_omp_wrong_device_function_call) << NoHostDevTy << 1; 2551 Diag(*OMPDeclareTargetDeclAttr::getLocation(FD), 2552 diag::note_omp_marked_device_type_here) 2553 << NoHostDevTy; 2554 } 2555 } 2556 2557 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 2558 const DeclarationNameInfo &DirName, 2559 Scope *CurScope, SourceLocation Loc) { 2560 DSAStack->push(DKind, DirName, CurScope, Loc); 2561 PushExpressionEvaluationContext( 2562 ExpressionEvaluationContext::PotentiallyEvaluated); 2563 } 2564 2565 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 2566 DSAStack->setClauseParsingMode(K); 2567 } 2568 2569 void Sema::EndOpenMPClause() { 2570 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 2571 CleanupVarDeclMarking(); 2572 } 2573 2574 static std::pair<ValueDecl *, bool> 2575 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 2576 SourceRange &ERange, bool AllowArraySection = false); 2577 2578 /// Check consistency of the reduction clauses. 2579 static void checkReductionClauses(Sema &S, DSAStackTy *Stack, 2580 ArrayRef<OMPClause *> Clauses) { 2581 bool InscanFound = false; 2582 SourceLocation InscanLoc; 2583 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions. 2584 // A reduction clause without the inscan reduction-modifier may not appear on 2585 // a construct on which a reduction clause with the inscan reduction-modifier 2586 // appears. 2587 for (OMPClause *C : Clauses) { 2588 if (C->getClauseKind() != OMPC_reduction) 2589 continue; 2590 auto *RC = cast<OMPReductionClause>(C); 2591 if (RC->getModifier() == OMPC_REDUCTION_inscan) { 2592 InscanFound = true; 2593 InscanLoc = RC->getModifierLoc(); 2594 continue; 2595 } 2596 if (RC->getModifier() == OMPC_REDUCTION_task) { 2597 // OpenMP 5.0, 2.19.5.4 reduction Clause. 2598 // A reduction clause with the task reduction-modifier may only appear on 2599 // a parallel construct, a worksharing construct or a combined or 2600 // composite construct for which any of the aforementioned constructs is a 2601 // constituent construct and simd or loop are not constituent constructs. 2602 OpenMPDirectiveKind CurDir = Stack->getCurrentDirective(); 2603 if (!(isOpenMPParallelDirective(CurDir) || 2604 isOpenMPWorksharingDirective(CurDir)) || 2605 isOpenMPSimdDirective(CurDir)) 2606 S.Diag(RC->getModifierLoc(), 2607 diag::err_omp_reduction_task_not_parallel_or_worksharing); 2608 continue; 2609 } 2610 } 2611 if (InscanFound) { 2612 for (OMPClause *C : Clauses) { 2613 if (C->getClauseKind() != OMPC_reduction) 2614 continue; 2615 auto *RC = cast<OMPReductionClause>(C); 2616 if (RC->getModifier() != OMPC_REDUCTION_inscan) { 2617 S.Diag(RC->getModifier() == OMPC_REDUCTION_unknown 2618 ? RC->getBeginLoc() 2619 : RC->getModifierLoc(), 2620 diag::err_omp_inscan_reduction_expected); 2621 S.Diag(InscanLoc, diag::note_omp_previous_inscan_reduction); 2622 continue; 2623 } 2624 for (Expr *Ref : RC->varlists()) { 2625 assert(Ref && "NULL expr in OpenMP nontemporal clause."); 2626 SourceLocation ELoc; 2627 SourceRange ERange; 2628 Expr *SimpleRefExpr = Ref; 2629 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 2630 /*AllowArraySection=*/true); 2631 ValueDecl *D = Res.first; 2632 if (!D) 2633 continue; 2634 if (!Stack->isUsedInScanDirective(getCanonicalDecl(D))) { 2635 S.Diag(Ref->getExprLoc(), 2636 diag::err_omp_reduction_not_inclusive_exclusive) 2637 << Ref->getSourceRange(); 2638 } 2639 } 2640 } 2641 } 2642 } 2643 2644 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 2645 ArrayRef<OMPClause *> Clauses); 2646 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2647 bool WithInit); 2648 2649 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2650 const ValueDecl *D, 2651 const DSAStackTy::DSAVarData &DVar, 2652 bool IsLoopIterVar = false); 2653 2654 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 2655 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 2656 // A variable of class type (or array thereof) that appears in a lastprivate 2657 // clause requires an accessible, unambiguous default constructor for the 2658 // class type, unless the list item is also specified in a firstprivate 2659 // clause. 2660 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 2661 for (OMPClause *C : D->clauses()) { 2662 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 2663 SmallVector<Expr *, 8> PrivateCopies; 2664 for (Expr *DE : Clause->varlists()) { 2665 if (DE->isValueDependent() || DE->isTypeDependent()) { 2666 PrivateCopies.push_back(nullptr); 2667 continue; 2668 } 2669 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 2670 auto *VD = cast<VarDecl>(DRE->getDecl()); 2671 QualType Type = VD->getType().getNonReferenceType(); 2672 const DSAStackTy::DSAVarData DVar = 2673 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2674 if (DVar.CKind == OMPC_lastprivate) { 2675 // Generate helper private variable and initialize it with the 2676 // default value. The address of the original variable is replaced 2677 // by the address of the new private variable in CodeGen. This new 2678 // variable is not added to IdResolver, so the code in the OpenMP 2679 // region uses original variable for proper diagnostics. 2680 VarDecl *VDPrivate = buildVarDecl( 2681 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 2682 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 2683 ActOnUninitializedDecl(VDPrivate); 2684 if (VDPrivate->isInvalidDecl()) { 2685 PrivateCopies.push_back(nullptr); 2686 continue; 2687 } 2688 PrivateCopies.push_back(buildDeclRefExpr( 2689 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 2690 } else { 2691 // The variable is also a firstprivate, so initialization sequence 2692 // for private copy is generated already. 2693 PrivateCopies.push_back(nullptr); 2694 } 2695 } 2696 Clause->setPrivateCopies(PrivateCopies); 2697 continue; 2698 } 2699 // Finalize nontemporal clause by handling private copies, if any. 2700 if (auto *Clause = dyn_cast<OMPNontemporalClause>(C)) { 2701 SmallVector<Expr *, 8> PrivateRefs; 2702 for (Expr *RefExpr : Clause->varlists()) { 2703 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 2704 SourceLocation ELoc; 2705 SourceRange ERange; 2706 Expr *SimpleRefExpr = RefExpr; 2707 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 2708 if (Res.second) 2709 // It will be analyzed later. 2710 PrivateRefs.push_back(RefExpr); 2711 ValueDecl *D = Res.first; 2712 if (!D) 2713 continue; 2714 2715 const DSAStackTy::DSAVarData DVar = 2716 DSAStack->getTopDSA(D, /*FromParent=*/false); 2717 PrivateRefs.push_back(DVar.PrivateCopy ? DVar.PrivateCopy 2718 : SimpleRefExpr); 2719 } 2720 Clause->setPrivateRefs(PrivateRefs); 2721 continue; 2722 } 2723 if (auto *Clause = dyn_cast<OMPUsesAllocatorsClause>(C)) { 2724 for (unsigned I = 0, E = Clause->getNumberOfAllocators(); I < E; ++I) { 2725 OMPUsesAllocatorsClause::Data D = Clause->getAllocatorData(I); 2726 auto *DRE = dyn_cast<DeclRefExpr>(D.Allocator->IgnoreParenImpCasts()); 2727 if (!DRE) 2728 continue; 2729 ValueDecl *VD = DRE->getDecl(); 2730 if (!VD || !isa<VarDecl>(VD)) 2731 continue; 2732 DSAStackTy::DSAVarData DVar = 2733 DSAStack->getTopDSA(VD, /*FromParent=*/false); 2734 // OpenMP [2.12.5, target Construct] 2735 // Memory allocators that appear in a uses_allocators clause cannot 2736 // appear in other data-sharing attribute clauses or data-mapping 2737 // attribute clauses in the same construct. 2738 Expr *MapExpr = nullptr; 2739 if (DVar.RefExpr || 2740 DSAStack->checkMappableExprComponentListsForDecl( 2741 VD, /*CurrentRegionOnly=*/true, 2742 [VD, &MapExpr]( 2743 OMPClauseMappableExprCommon::MappableExprComponentListRef 2744 MapExprComponents, 2745 OpenMPClauseKind C) { 2746 auto MI = MapExprComponents.rbegin(); 2747 auto ME = MapExprComponents.rend(); 2748 if (MI != ME && 2749 MI->getAssociatedDeclaration()->getCanonicalDecl() == 2750 VD->getCanonicalDecl()) { 2751 MapExpr = MI->getAssociatedExpression(); 2752 return true; 2753 } 2754 return false; 2755 })) { 2756 Diag(D.Allocator->getExprLoc(), 2757 diag::err_omp_allocator_used_in_clauses) 2758 << D.Allocator->getSourceRange(); 2759 if (DVar.RefExpr) 2760 reportOriginalDsa(*this, DSAStack, VD, DVar); 2761 else 2762 Diag(MapExpr->getExprLoc(), diag::note_used_here) 2763 << MapExpr->getSourceRange(); 2764 } 2765 } 2766 continue; 2767 } 2768 } 2769 // Check allocate clauses. 2770 if (!CurContext->isDependentContext()) 2771 checkAllocateClauses(*this, DSAStack, D->clauses()); 2772 checkReductionClauses(*this, DSAStack, D->clauses()); 2773 } 2774 2775 DSAStack->pop(); 2776 DiscardCleanupsInEvaluationContext(); 2777 PopExpressionEvaluationContext(); 2778 } 2779 2780 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 2781 Expr *NumIterations, Sema &SemaRef, 2782 Scope *S, DSAStackTy *Stack); 2783 2784 namespace { 2785 2786 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 2787 private: 2788 Sema &SemaRef; 2789 2790 public: 2791 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 2792 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2793 NamedDecl *ND = Candidate.getCorrectionDecl(); 2794 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 2795 return VD->hasGlobalStorage() && 2796 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2797 SemaRef.getCurScope()); 2798 } 2799 return false; 2800 } 2801 2802 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2803 return std::make_unique<VarDeclFilterCCC>(*this); 2804 } 2805 }; 2806 2807 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 2808 private: 2809 Sema &SemaRef; 2810 2811 public: 2812 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 2813 bool ValidateCandidate(const TypoCorrection &Candidate) override { 2814 NamedDecl *ND = Candidate.getCorrectionDecl(); 2815 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 2816 isa<FunctionDecl>(ND))) { 2817 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 2818 SemaRef.getCurScope()); 2819 } 2820 return false; 2821 } 2822 2823 std::unique_ptr<CorrectionCandidateCallback> clone() override { 2824 return std::make_unique<VarOrFuncDeclFilterCCC>(*this); 2825 } 2826 }; 2827 2828 } // namespace 2829 2830 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 2831 CXXScopeSpec &ScopeSpec, 2832 const DeclarationNameInfo &Id, 2833 OpenMPDirectiveKind Kind) { 2834 LookupResult Lookup(*this, Id, LookupOrdinaryName); 2835 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 2836 2837 if (Lookup.isAmbiguous()) 2838 return ExprError(); 2839 2840 VarDecl *VD; 2841 if (!Lookup.isSingleResult()) { 2842 VarDeclFilterCCC CCC(*this); 2843 if (TypoCorrection Corrected = 2844 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 2845 CTK_ErrorRecovery)) { 2846 diagnoseTypo(Corrected, 2847 PDiag(Lookup.empty() 2848 ? diag::err_undeclared_var_use_suggest 2849 : diag::err_omp_expected_var_arg_suggest) 2850 << Id.getName()); 2851 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2852 } else { 2853 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2854 : diag::err_omp_expected_var_arg) 2855 << Id.getName(); 2856 return ExprError(); 2857 } 2858 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2859 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2860 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2861 return ExprError(); 2862 } 2863 Lookup.suppressDiagnostics(); 2864 2865 // OpenMP [2.9.2, Syntax, C/C++] 2866 // Variables must be file-scope, namespace-scope, or static block-scope. 2867 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2868 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2869 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2870 bool IsDecl = 2871 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2872 Diag(VD->getLocation(), 2873 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2874 << VD; 2875 return ExprError(); 2876 } 2877 2878 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2879 NamedDecl *ND = CanonicalVD; 2880 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2881 // A threadprivate directive for file-scope variables must appear outside 2882 // any definition or declaration. 2883 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2884 !getCurLexicalContext()->isTranslationUnit()) { 2885 Diag(Id.getLoc(), diag::err_omp_var_scope) 2886 << getOpenMPDirectiveName(Kind) << VD; 2887 bool IsDecl = 2888 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2889 Diag(VD->getLocation(), 2890 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2891 << VD; 2892 return ExprError(); 2893 } 2894 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2895 // A threadprivate directive for static class member variables must appear 2896 // in the class definition, in the same scope in which the member 2897 // variables are declared. 2898 if (CanonicalVD->isStaticDataMember() && 2899 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2900 Diag(Id.getLoc(), diag::err_omp_var_scope) 2901 << getOpenMPDirectiveName(Kind) << VD; 2902 bool IsDecl = 2903 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2904 Diag(VD->getLocation(), 2905 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2906 << VD; 2907 return ExprError(); 2908 } 2909 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2910 // A threadprivate directive for namespace-scope variables must appear 2911 // outside any definition or declaration other than the namespace 2912 // definition itself. 2913 if (CanonicalVD->getDeclContext()->isNamespace() && 2914 (!getCurLexicalContext()->isFileContext() || 2915 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2916 Diag(Id.getLoc(), diag::err_omp_var_scope) 2917 << getOpenMPDirectiveName(Kind) << VD; 2918 bool IsDecl = 2919 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2920 Diag(VD->getLocation(), 2921 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2922 << VD; 2923 return ExprError(); 2924 } 2925 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2926 // A threadprivate directive for static block-scope variables must appear 2927 // in the scope of the variable and not in a nested scope. 2928 if (CanonicalVD->isLocalVarDecl() && CurScope && 2929 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2930 Diag(Id.getLoc(), diag::err_omp_var_scope) 2931 << getOpenMPDirectiveName(Kind) << VD; 2932 bool IsDecl = 2933 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2934 Diag(VD->getLocation(), 2935 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2936 << VD; 2937 return ExprError(); 2938 } 2939 2940 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2941 // A threadprivate directive must lexically precede all references to any 2942 // of the variables in its list. 2943 if (Kind == OMPD_threadprivate && VD->isUsed() && 2944 !DSAStack->isThreadPrivate(VD)) { 2945 Diag(Id.getLoc(), diag::err_omp_var_used) 2946 << getOpenMPDirectiveName(Kind) << VD; 2947 return ExprError(); 2948 } 2949 2950 QualType ExprType = VD->getType().getNonReferenceType(); 2951 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2952 SourceLocation(), VD, 2953 /*RefersToEnclosingVariableOrCapture=*/false, 2954 Id.getLoc(), ExprType, VK_LValue); 2955 } 2956 2957 Sema::DeclGroupPtrTy 2958 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2959 ArrayRef<Expr *> VarList) { 2960 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2961 CurContext->addDecl(D); 2962 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2963 } 2964 return nullptr; 2965 } 2966 2967 namespace { 2968 class LocalVarRefChecker final 2969 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2970 Sema &SemaRef; 2971 2972 public: 2973 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2974 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2975 if (VD->hasLocalStorage()) { 2976 SemaRef.Diag(E->getBeginLoc(), 2977 diag::err_omp_local_var_in_threadprivate_init) 2978 << E->getSourceRange(); 2979 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2980 << VD << VD->getSourceRange(); 2981 return true; 2982 } 2983 } 2984 return false; 2985 } 2986 bool VisitStmt(const Stmt *S) { 2987 for (const Stmt *Child : S->children()) { 2988 if (Child && Visit(Child)) 2989 return true; 2990 } 2991 return false; 2992 } 2993 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2994 }; 2995 } // namespace 2996 2997 OMPThreadPrivateDecl * 2998 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2999 SmallVector<Expr *, 8> Vars; 3000 for (Expr *RefExpr : VarList) { 3001 auto *DE = cast<DeclRefExpr>(RefExpr); 3002 auto *VD = cast<VarDecl>(DE->getDecl()); 3003 SourceLocation ILoc = DE->getExprLoc(); 3004 3005 // Mark variable as used. 3006 VD->setReferenced(); 3007 VD->markUsed(Context); 3008 3009 QualType QType = VD->getType(); 3010 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 3011 // It will be analyzed later. 3012 Vars.push_back(DE); 3013 continue; 3014 } 3015 3016 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 3017 // A threadprivate variable must not have an incomplete type. 3018 if (RequireCompleteType(ILoc, VD->getType(), 3019 diag::err_omp_threadprivate_incomplete_type)) { 3020 continue; 3021 } 3022 3023 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 3024 // A threadprivate variable must not have a reference type. 3025 if (VD->getType()->isReferenceType()) { 3026 Diag(ILoc, diag::err_omp_ref_type_arg) 3027 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 3028 bool IsDecl = 3029 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3030 Diag(VD->getLocation(), 3031 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3032 << VD; 3033 continue; 3034 } 3035 3036 // Check if this is a TLS variable. If TLS is not being supported, produce 3037 // the corresponding diagnostic. 3038 if ((VD->getTLSKind() != VarDecl::TLS_None && 3039 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 3040 getLangOpts().OpenMPUseTLS && 3041 getASTContext().getTargetInfo().isTLSSupported())) || 3042 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3043 !VD->isLocalVarDecl())) { 3044 Diag(ILoc, diag::err_omp_var_thread_local) 3045 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 3046 bool IsDecl = 3047 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 3048 Diag(VD->getLocation(), 3049 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3050 << VD; 3051 continue; 3052 } 3053 3054 // Check if initial value of threadprivate variable reference variable with 3055 // local storage (it is not supported by runtime). 3056 if (const Expr *Init = VD->getAnyInitializer()) { 3057 LocalVarRefChecker Checker(*this); 3058 if (Checker.Visit(Init)) 3059 continue; 3060 } 3061 3062 Vars.push_back(RefExpr); 3063 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 3064 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 3065 Context, SourceRange(Loc, Loc))); 3066 if (ASTMutationListener *ML = Context.getASTMutationListener()) 3067 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 3068 } 3069 OMPThreadPrivateDecl *D = nullptr; 3070 if (!Vars.empty()) { 3071 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 3072 Vars); 3073 D->setAccess(AS_public); 3074 } 3075 return D; 3076 } 3077 3078 static OMPAllocateDeclAttr::AllocatorTypeTy 3079 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 3080 if (!Allocator) 3081 return OMPAllocateDeclAttr::OMPNullMemAlloc; 3082 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3083 Allocator->isInstantiationDependent() || 3084 Allocator->containsUnexpandedParameterPack()) 3085 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3086 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 3087 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3088 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 3089 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 3090 const Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 3091 llvm::FoldingSetNodeID AEId, DAEId; 3092 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 3093 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 3094 if (AEId == DAEId) { 3095 AllocatorKindRes = AllocatorKind; 3096 break; 3097 } 3098 } 3099 return AllocatorKindRes; 3100 } 3101 3102 static bool checkPreviousOMPAllocateAttribute( 3103 Sema &S, DSAStackTy *Stack, Expr *RefExpr, VarDecl *VD, 3104 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, Expr *Allocator) { 3105 if (!VD->hasAttr<OMPAllocateDeclAttr>()) 3106 return false; 3107 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 3108 Expr *PrevAllocator = A->getAllocator(); 3109 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 3110 getAllocatorKind(S, Stack, PrevAllocator); 3111 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 3112 if (AllocatorsMatch && 3113 AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc && 3114 Allocator && PrevAllocator) { 3115 const Expr *AE = Allocator->IgnoreParenImpCasts(); 3116 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 3117 llvm::FoldingSetNodeID AEId, PAEId; 3118 AE->Profile(AEId, S.Context, /*Canonical=*/true); 3119 PAE->Profile(PAEId, S.Context, /*Canonical=*/true); 3120 AllocatorsMatch = AEId == PAEId; 3121 } 3122 if (!AllocatorsMatch) { 3123 SmallString<256> AllocatorBuffer; 3124 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 3125 if (Allocator) 3126 Allocator->printPretty(AllocatorStream, nullptr, S.getPrintingPolicy()); 3127 SmallString<256> PrevAllocatorBuffer; 3128 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 3129 if (PrevAllocator) 3130 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 3131 S.getPrintingPolicy()); 3132 3133 SourceLocation AllocatorLoc = 3134 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 3135 SourceRange AllocatorRange = 3136 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 3137 SourceLocation PrevAllocatorLoc = 3138 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 3139 SourceRange PrevAllocatorRange = 3140 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 3141 S.Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 3142 << (Allocator ? 1 : 0) << AllocatorStream.str() 3143 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 3144 << AllocatorRange; 3145 S.Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 3146 << PrevAllocatorRange; 3147 return true; 3148 } 3149 return false; 3150 } 3151 3152 static void 3153 applyOMPAllocateAttribute(Sema &S, VarDecl *VD, 3154 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 3155 Expr *Allocator, Expr *Alignment, SourceRange SR) { 3156 if (VD->hasAttr<OMPAllocateDeclAttr>()) 3157 return; 3158 if (Alignment && 3159 (Alignment->isTypeDependent() || Alignment->isValueDependent() || 3160 Alignment->isInstantiationDependent() || 3161 Alignment->containsUnexpandedParameterPack())) 3162 // Apply later when we have a usable value. 3163 return; 3164 if (Allocator && 3165 (Allocator->isTypeDependent() || Allocator->isValueDependent() || 3166 Allocator->isInstantiationDependent() || 3167 Allocator->containsUnexpandedParameterPack())) 3168 return; 3169 auto *A = OMPAllocateDeclAttr::CreateImplicit(S.Context, AllocatorKind, 3170 Allocator, Alignment, SR); 3171 VD->addAttr(A); 3172 if (ASTMutationListener *ML = S.Context.getASTMutationListener()) 3173 ML->DeclarationMarkedOpenMPAllocate(VD, A); 3174 } 3175 3176 Sema::DeclGroupPtrTy 3177 Sema::ActOnOpenMPAllocateDirective(SourceLocation Loc, ArrayRef<Expr *> VarList, 3178 ArrayRef<OMPClause *> Clauses, 3179 DeclContext *Owner) { 3180 assert(Clauses.size() <= 2 && "Expected at most two clauses."); 3181 Expr *Alignment = nullptr; 3182 Expr *Allocator = nullptr; 3183 if (Clauses.empty()) { 3184 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 3185 // allocate directives that appear in a target region must specify an 3186 // allocator clause unless a requires directive with the dynamic_allocators 3187 // clause is present in the same compilation unit. 3188 if (LangOpts.OpenMPIsDevice && 3189 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 3190 targetDiag(Loc, diag::err_expected_allocator_clause); 3191 } else { 3192 for (const OMPClause *C : Clauses) 3193 if (const auto *AC = dyn_cast<OMPAllocatorClause>(C)) 3194 Allocator = AC->getAllocator(); 3195 else if (const auto *AC = dyn_cast<OMPAlignClause>(C)) 3196 Alignment = AC->getAlignment(); 3197 else 3198 llvm_unreachable("Unexpected clause on allocate directive"); 3199 } 3200 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 3201 getAllocatorKind(*this, DSAStack, Allocator); 3202 SmallVector<Expr *, 8> Vars; 3203 for (Expr *RefExpr : VarList) { 3204 auto *DE = cast<DeclRefExpr>(RefExpr); 3205 auto *VD = cast<VarDecl>(DE->getDecl()); 3206 3207 // Check if this is a TLS variable or global register. 3208 if (VD->getTLSKind() != VarDecl::TLS_None || 3209 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 3210 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 3211 !VD->isLocalVarDecl())) 3212 continue; 3213 3214 // If the used several times in the allocate directive, the same allocator 3215 // must be used. 3216 if (checkPreviousOMPAllocateAttribute(*this, DSAStack, RefExpr, VD, 3217 AllocatorKind, Allocator)) 3218 continue; 3219 3220 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 3221 // If a list item has a static storage type, the allocator expression in the 3222 // allocator clause must be a constant expression that evaluates to one of 3223 // the predefined memory allocator values. 3224 if (Allocator && VD->hasGlobalStorage()) { 3225 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 3226 Diag(Allocator->getExprLoc(), 3227 diag::err_omp_expected_predefined_allocator) 3228 << Allocator->getSourceRange(); 3229 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 3230 VarDecl::DeclarationOnly; 3231 Diag(VD->getLocation(), 3232 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 3233 << VD; 3234 continue; 3235 } 3236 } 3237 3238 Vars.push_back(RefExpr); 3239 applyOMPAllocateAttribute(*this, VD, AllocatorKind, Allocator, Alignment, 3240 DE->getSourceRange()); 3241 } 3242 if (Vars.empty()) 3243 return nullptr; 3244 if (!Owner) 3245 Owner = getCurLexicalContext(); 3246 auto *D = OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 3247 D->setAccess(AS_public); 3248 Owner->addDecl(D); 3249 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3250 } 3251 3252 Sema::DeclGroupPtrTy 3253 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 3254 ArrayRef<OMPClause *> ClauseList) { 3255 OMPRequiresDecl *D = nullptr; 3256 if (!CurContext->isFileContext()) { 3257 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 3258 } else { 3259 D = CheckOMPRequiresDecl(Loc, ClauseList); 3260 if (D) { 3261 CurContext->addDecl(D); 3262 DSAStack->addRequiresDecl(D); 3263 } 3264 } 3265 return DeclGroupPtrTy::make(DeclGroupRef(D)); 3266 } 3267 3268 void Sema::ActOnOpenMPAssumesDirective(SourceLocation Loc, 3269 OpenMPDirectiveKind DKind, 3270 ArrayRef<std::string> Assumptions, 3271 bool SkippedClauses) { 3272 if (!SkippedClauses && Assumptions.empty()) 3273 Diag(Loc, diag::err_omp_no_clause_for_directive) 3274 << llvm::omp::getAllAssumeClauseOptions() 3275 << llvm::omp::getOpenMPDirectiveName(DKind); 3276 3277 auto *AA = AssumptionAttr::Create(Context, llvm::join(Assumptions, ","), Loc); 3278 if (DKind == llvm::omp::Directive::OMPD_begin_assumes) { 3279 OMPAssumeScoped.push_back(AA); 3280 return; 3281 } 3282 3283 // Global assumes without assumption clauses are ignored. 3284 if (Assumptions.empty()) 3285 return; 3286 3287 assert(DKind == llvm::omp::Directive::OMPD_assumes && 3288 "Unexpected omp assumption directive!"); 3289 OMPAssumeGlobal.push_back(AA); 3290 3291 // The OMPAssumeGlobal scope above will take care of new declarations but 3292 // we also want to apply the assumption to existing ones, e.g., to 3293 // declarations in included headers. To this end, we traverse all existing 3294 // declaration contexts and annotate function declarations here. 3295 SmallVector<DeclContext *, 8> DeclContexts; 3296 auto *Ctx = CurContext; 3297 while (Ctx->getLexicalParent()) 3298 Ctx = Ctx->getLexicalParent(); 3299 DeclContexts.push_back(Ctx); 3300 while (!DeclContexts.empty()) { 3301 DeclContext *DC = DeclContexts.pop_back_val(); 3302 for (auto *SubDC : DC->decls()) { 3303 if (SubDC->isInvalidDecl()) 3304 continue; 3305 if (auto *CTD = dyn_cast<ClassTemplateDecl>(SubDC)) { 3306 DeclContexts.push_back(CTD->getTemplatedDecl()); 3307 llvm::append_range(DeclContexts, CTD->specializations()); 3308 continue; 3309 } 3310 if (auto *DC = dyn_cast<DeclContext>(SubDC)) 3311 DeclContexts.push_back(DC); 3312 if (auto *F = dyn_cast<FunctionDecl>(SubDC)) { 3313 F->addAttr(AA); 3314 continue; 3315 } 3316 } 3317 } 3318 } 3319 3320 void Sema::ActOnOpenMPEndAssumesDirective() { 3321 assert(isInOpenMPAssumeScope() && "Not in OpenMP assumes scope!"); 3322 OMPAssumeScoped.pop_back(); 3323 } 3324 3325 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 3326 ArrayRef<OMPClause *> ClauseList) { 3327 /// For target specific clauses, the requires directive cannot be 3328 /// specified after the handling of any of the target regions in the 3329 /// current compilation unit. 3330 ArrayRef<SourceLocation> TargetLocations = 3331 DSAStack->getEncounteredTargetLocs(); 3332 SourceLocation AtomicLoc = DSAStack->getAtomicDirectiveLoc(); 3333 if (!TargetLocations.empty() || !AtomicLoc.isInvalid()) { 3334 for (const OMPClause *CNew : ClauseList) { 3335 // Check if any of the requires clauses affect target regions. 3336 if (isa<OMPUnifiedSharedMemoryClause>(CNew) || 3337 isa<OMPUnifiedAddressClause>(CNew) || 3338 isa<OMPReverseOffloadClause>(CNew) || 3339 isa<OMPDynamicAllocatorsClause>(CNew)) { 3340 Diag(Loc, diag::err_omp_directive_before_requires) 3341 << "target" << getOpenMPClauseName(CNew->getClauseKind()); 3342 for (SourceLocation TargetLoc : TargetLocations) { 3343 Diag(TargetLoc, diag::note_omp_requires_encountered_directive) 3344 << "target"; 3345 } 3346 } else if (!AtomicLoc.isInvalid() && 3347 isa<OMPAtomicDefaultMemOrderClause>(CNew)) { 3348 Diag(Loc, diag::err_omp_directive_before_requires) 3349 << "atomic" << getOpenMPClauseName(CNew->getClauseKind()); 3350 Diag(AtomicLoc, diag::note_omp_requires_encountered_directive) 3351 << "atomic"; 3352 } 3353 } 3354 } 3355 3356 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 3357 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 3358 ClauseList); 3359 return nullptr; 3360 } 3361 3362 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 3363 const ValueDecl *D, 3364 const DSAStackTy::DSAVarData &DVar, 3365 bool IsLoopIterVar) { 3366 if (DVar.RefExpr) { 3367 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 3368 << getOpenMPClauseName(DVar.CKind); 3369 return; 3370 } 3371 enum { 3372 PDSA_StaticMemberShared, 3373 PDSA_StaticLocalVarShared, 3374 PDSA_LoopIterVarPrivate, 3375 PDSA_LoopIterVarLinear, 3376 PDSA_LoopIterVarLastprivate, 3377 PDSA_ConstVarShared, 3378 PDSA_GlobalVarShared, 3379 PDSA_TaskVarFirstprivate, 3380 PDSA_LocalVarPrivate, 3381 PDSA_Implicit 3382 } Reason = PDSA_Implicit; 3383 bool ReportHint = false; 3384 auto ReportLoc = D->getLocation(); 3385 auto *VD = dyn_cast<VarDecl>(D); 3386 if (IsLoopIterVar) { 3387 if (DVar.CKind == OMPC_private) 3388 Reason = PDSA_LoopIterVarPrivate; 3389 else if (DVar.CKind == OMPC_lastprivate) 3390 Reason = PDSA_LoopIterVarLastprivate; 3391 else 3392 Reason = PDSA_LoopIterVarLinear; 3393 } else if (isOpenMPTaskingDirective(DVar.DKind) && 3394 DVar.CKind == OMPC_firstprivate) { 3395 Reason = PDSA_TaskVarFirstprivate; 3396 ReportLoc = DVar.ImplicitDSALoc; 3397 } else if (VD && VD->isStaticLocal()) 3398 Reason = PDSA_StaticLocalVarShared; 3399 else if (VD && VD->isStaticDataMember()) 3400 Reason = PDSA_StaticMemberShared; 3401 else if (VD && VD->isFileVarDecl()) 3402 Reason = PDSA_GlobalVarShared; 3403 else if (D->getType().isConstant(SemaRef.getASTContext())) 3404 Reason = PDSA_ConstVarShared; 3405 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 3406 ReportHint = true; 3407 Reason = PDSA_LocalVarPrivate; 3408 } 3409 if (Reason != PDSA_Implicit) { 3410 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 3411 << Reason << ReportHint 3412 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 3413 } else if (DVar.ImplicitDSALoc.isValid()) { 3414 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 3415 << getOpenMPClauseName(DVar.CKind); 3416 } 3417 } 3418 3419 static OpenMPMapClauseKind 3420 getMapClauseKindFromModifier(OpenMPDefaultmapClauseModifier M, 3421 bool IsAggregateOrDeclareTarget) { 3422 OpenMPMapClauseKind Kind = OMPC_MAP_unknown; 3423 switch (M) { 3424 case OMPC_DEFAULTMAP_MODIFIER_alloc: 3425 Kind = OMPC_MAP_alloc; 3426 break; 3427 case OMPC_DEFAULTMAP_MODIFIER_to: 3428 Kind = OMPC_MAP_to; 3429 break; 3430 case OMPC_DEFAULTMAP_MODIFIER_from: 3431 Kind = OMPC_MAP_from; 3432 break; 3433 case OMPC_DEFAULTMAP_MODIFIER_tofrom: 3434 Kind = OMPC_MAP_tofrom; 3435 break; 3436 case OMPC_DEFAULTMAP_MODIFIER_present: 3437 // OpenMP 5.1 [2.21.7.3] defaultmap clause, Description] 3438 // If implicit-behavior is present, each variable referenced in the 3439 // construct in the category specified by variable-category is treated as if 3440 // it had been listed in a map clause with the map-type of alloc and 3441 // map-type-modifier of present. 3442 Kind = OMPC_MAP_alloc; 3443 break; 3444 case OMPC_DEFAULTMAP_MODIFIER_firstprivate: 3445 case OMPC_DEFAULTMAP_MODIFIER_last: 3446 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3447 case OMPC_DEFAULTMAP_MODIFIER_none: 3448 case OMPC_DEFAULTMAP_MODIFIER_default: 3449 case OMPC_DEFAULTMAP_MODIFIER_unknown: 3450 // IsAggregateOrDeclareTarget could be true if: 3451 // 1. the implicit behavior for aggregate is tofrom 3452 // 2. it's a declare target link 3453 if (IsAggregateOrDeclareTarget) { 3454 Kind = OMPC_MAP_tofrom; 3455 break; 3456 } 3457 llvm_unreachable("Unexpected defaultmap implicit behavior"); 3458 } 3459 assert(Kind != OMPC_MAP_unknown && "Expect map kind to be known"); 3460 return Kind; 3461 } 3462 3463 namespace { 3464 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 3465 DSAStackTy *Stack; 3466 Sema &SemaRef; 3467 bool ErrorFound = false; 3468 bool TryCaptureCXXThisMembers = false; 3469 CapturedStmt *CS = nullptr; 3470 const static unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1; 3471 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 3472 llvm::SmallVector<Expr *, 4> ImplicitPrivate; 3473 llvm::SmallVector<Expr *, 4> ImplicitMap[DefaultmapKindNum][OMPC_MAP_delete]; 3474 llvm::SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> 3475 ImplicitMapModifier[DefaultmapKindNum]; 3476 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 3477 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 3478 3479 void VisitSubCaptures(OMPExecutableDirective *S) { 3480 // Check implicitly captured variables. 3481 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 3482 return; 3483 if (S->getDirectiveKind() == OMPD_atomic || 3484 S->getDirectiveKind() == OMPD_critical || 3485 S->getDirectiveKind() == OMPD_section || 3486 S->getDirectiveKind() == OMPD_master || 3487 S->getDirectiveKind() == OMPD_masked || 3488 isOpenMPLoopTransformationDirective(S->getDirectiveKind())) { 3489 Visit(S->getAssociatedStmt()); 3490 return; 3491 } 3492 visitSubCaptures(S->getInnermostCapturedStmt()); 3493 // Try to capture inner this->member references to generate correct mappings 3494 // and diagnostics. 3495 if (TryCaptureCXXThisMembers || 3496 (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3497 llvm::any_of(S->getInnermostCapturedStmt()->captures(), 3498 [](const CapturedStmt::Capture &C) { 3499 return C.capturesThis(); 3500 }))) { 3501 bool SavedTryCaptureCXXThisMembers = TryCaptureCXXThisMembers; 3502 TryCaptureCXXThisMembers = true; 3503 Visit(S->getInnermostCapturedStmt()->getCapturedStmt()); 3504 TryCaptureCXXThisMembers = SavedTryCaptureCXXThisMembers; 3505 } 3506 // In tasks firstprivates are not captured anymore, need to analyze them 3507 // explicitly. 3508 if (isOpenMPTaskingDirective(S->getDirectiveKind()) && 3509 !isOpenMPTaskLoopDirective(S->getDirectiveKind())) { 3510 for (OMPClause *C : S->clauses()) 3511 if (auto *FC = dyn_cast<OMPFirstprivateClause>(C)) { 3512 for (Expr *Ref : FC->varlists()) 3513 Visit(Ref); 3514 } 3515 } 3516 } 3517 3518 public: 3519 void VisitDeclRefExpr(DeclRefExpr *E) { 3520 if (TryCaptureCXXThisMembers || E->isTypeDependent() || 3521 E->isValueDependent() || E->containsUnexpandedParameterPack() || 3522 E->isInstantiationDependent()) 3523 return; 3524 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 3525 // Check the datasharing rules for the expressions in the clauses. 3526 if (!CS || (isa<OMPCapturedExprDecl>(VD) && !CS->capturesVariable(VD) && 3527 !Stack->getTopDSA(VD, /*FromParent=*/false).RefExpr)) { 3528 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3529 if (!CED->hasAttr<OMPCaptureNoInitAttr>()) { 3530 Visit(CED->getInit()); 3531 return; 3532 } 3533 } else if (VD->isImplicit() || isa<OMPCapturedExprDecl>(VD)) 3534 // Do not analyze internal variables and do not enclose them into 3535 // implicit clauses. 3536 return; 3537 VD = VD->getCanonicalDecl(); 3538 // Skip internally declared variables. 3539 if (VD->hasLocalStorage() && CS && !CS->capturesVariable(VD) && 3540 !Stack->isImplicitTaskFirstprivate(VD)) 3541 return; 3542 // Skip allocators in uses_allocators clauses. 3543 if (Stack->isUsesAllocatorsDecl(VD)) 3544 return; 3545 3546 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 3547 // Check if the variable has explicit DSA set and stop analysis if it so. 3548 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 3549 return; 3550 3551 // Skip internally declared static variables. 3552 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 3553 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 3554 if (VD->hasGlobalStorage() && CS && !CS->capturesVariable(VD) && 3555 (Stack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 3556 !Res || *Res != OMPDeclareTargetDeclAttr::MT_Link) && 3557 !Stack->isImplicitTaskFirstprivate(VD)) 3558 return; 3559 3560 SourceLocation ELoc = E->getExprLoc(); 3561 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3562 // The default(none) clause requires that each variable that is referenced 3563 // in the construct, and does not have a predetermined data-sharing 3564 // attribute, must have its data-sharing attribute explicitly determined 3565 // by being listed in a data-sharing attribute clause. 3566 if (DVar.CKind == OMPC_unknown && 3567 (Stack->getDefaultDSA() == DSA_none || 3568 Stack->getDefaultDSA() == DSA_private || 3569 Stack->getDefaultDSA() == DSA_firstprivate) && 3570 isImplicitOrExplicitTaskingRegion(DKind) && 3571 VarsWithInheritedDSA.count(VD) == 0) { 3572 bool InheritedDSA = Stack->getDefaultDSA() == DSA_none; 3573 if (!InheritedDSA && (Stack->getDefaultDSA() == DSA_firstprivate || 3574 Stack->getDefaultDSA() == DSA_private)) { 3575 DSAStackTy::DSAVarData DVar = 3576 Stack->getImplicitDSA(VD, /*FromParent=*/false); 3577 InheritedDSA = DVar.CKind == OMPC_unknown; 3578 } 3579 if (InheritedDSA) 3580 VarsWithInheritedDSA[VD] = E; 3581 if (Stack->getDefaultDSA() == DSA_none) 3582 return; 3583 } 3584 3585 // OpenMP 5.0 [2.19.7.2, defaultmap clause, Description] 3586 // If implicit-behavior is none, each variable referenced in the 3587 // construct that does not have a predetermined data-sharing attribute 3588 // and does not appear in a to or link clause on a declare target 3589 // directive must be listed in a data-mapping attribute clause, a 3590 // data-sharing attribute clause (including a data-sharing attribute 3591 // clause on a combined construct where target. is one of the 3592 // constituent constructs), or an is_device_ptr clause. 3593 OpenMPDefaultmapClauseKind ClauseKind = 3594 getVariableCategoryFromDecl(SemaRef.getLangOpts(), VD); 3595 if (SemaRef.getLangOpts().OpenMP >= 50) { 3596 bool IsModifierNone = Stack->getDefaultmapModifier(ClauseKind) == 3597 OMPC_DEFAULTMAP_MODIFIER_none; 3598 if (DVar.CKind == OMPC_unknown && IsModifierNone && 3599 VarsWithInheritedDSA.count(VD) == 0 && !Res) { 3600 // Only check for data-mapping attribute and is_device_ptr here 3601 // since we have already make sure that the declaration does not 3602 // have a data-sharing attribute above 3603 if (!Stack->checkMappableExprComponentListsForDecl( 3604 VD, /*CurrentRegionOnly=*/true, 3605 [VD](OMPClauseMappableExprCommon::MappableExprComponentListRef 3606 MapExprComponents, 3607 OpenMPClauseKind) { 3608 auto MI = MapExprComponents.rbegin(); 3609 auto ME = MapExprComponents.rend(); 3610 return MI != ME && MI->getAssociatedDeclaration() == VD; 3611 })) { 3612 VarsWithInheritedDSA[VD] = E; 3613 return; 3614 } 3615 } 3616 } 3617 if (SemaRef.getLangOpts().OpenMP > 50) { 3618 bool IsModifierPresent = Stack->getDefaultmapModifier(ClauseKind) == 3619 OMPC_DEFAULTMAP_MODIFIER_present; 3620 if (IsModifierPresent) { 3621 if (llvm::find(ImplicitMapModifier[ClauseKind], 3622 OMPC_MAP_MODIFIER_present) == 3623 std::end(ImplicitMapModifier[ClauseKind])) { 3624 ImplicitMapModifier[ClauseKind].push_back( 3625 OMPC_MAP_MODIFIER_present); 3626 } 3627 } 3628 } 3629 3630 if (isOpenMPTargetExecutionDirective(DKind) && 3631 !Stack->isLoopControlVariable(VD).first) { 3632 if (!Stack->checkMappableExprComponentListsForDecl( 3633 VD, /*CurrentRegionOnly=*/true, 3634 [this](OMPClauseMappableExprCommon::MappableExprComponentListRef 3635 StackComponents, 3636 OpenMPClauseKind) { 3637 if (SemaRef.LangOpts.OpenMP >= 50) 3638 return !StackComponents.empty(); 3639 // Variable is used if it has been marked as an array, array 3640 // section, array shaping or the variable iself. 3641 return StackComponents.size() == 1 || 3642 std::all_of( 3643 std::next(StackComponents.rbegin()), 3644 StackComponents.rend(), 3645 [](const OMPClauseMappableExprCommon:: 3646 MappableComponent &MC) { 3647 return MC.getAssociatedDeclaration() == 3648 nullptr && 3649 (isa<OMPArraySectionExpr>( 3650 MC.getAssociatedExpression()) || 3651 isa<OMPArrayShapingExpr>( 3652 MC.getAssociatedExpression()) || 3653 isa<ArraySubscriptExpr>( 3654 MC.getAssociatedExpression())); 3655 }); 3656 })) { 3657 bool IsFirstprivate = false; 3658 // By default lambdas are captured as firstprivates. 3659 if (const auto *RD = 3660 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 3661 IsFirstprivate = RD->isLambda(); 3662 IsFirstprivate = 3663 IsFirstprivate || (Stack->mustBeFirstprivate(ClauseKind) && !Res); 3664 if (IsFirstprivate) { 3665 ImplicitFirstprivate.emplace_back(E); 3666 } else { 3667 OpenMPDefaultmapClauseModifier M = 3668 Stack->getDefaultmapModifier(ClauseKind); 3669 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3670 M, ClauseKind == OMPC_DEFAULTMAP_aggregate || Res); 3671 ImplicitMap[ClauseKind][Kind].emplace_back(E); 3672 } 3673 return; 3674 } 3675 } 3676 3677 // OpenMP [2.9.3.6, Restrictions, p.2] 3678 // A list item that appears in a reduction clause of the innermost 3679 // enclosing worksharing or parallel construct may not be accessed in an 3680 // explicit task. 3681 DVar = Stack->hasInnermostDSA( 3682 VD, 3683 [](OpenMPClauseKind C, bool AppliedToPointee) { 3684 return C == OMPC_reduction && !AppliedToPointee; 3685 }, 3686 [](OpenMPDirectiveKind K) { 3687 return isOpenMPParallelDirective(K) || 3688 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3689 }, 3690 /*FromParent=*/true); 3691 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3692 ErrorFound = true; 3693 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3694 reportOriginalDsa(SemaRef, Stack, VD, DVar); 3695 return; 3696 } 3697 3698 // Define implicit data-sharing attributes for task. 3699 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 3700 if (((isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared) || 3701 (((Stack->getDefaultDSA() == DSA_firstprivate && 3702 DVar.CKind == OMPC_firstprivate) || 3703 (Stack->getDefaultDSA() == DSA_private && 3704 DVar.CKind == OMPC_private)) && 3705 !DVar.RefExpr)) && 3706 !Stack->isLoopControlVariable(VD).first) { 3707 if (Stack->getDefaultDSA() == DSA_private) 3708 ImplicitPrivate.push_back(E); 3709 else 3710 ImplicitFirstprivate.push_back(E); 3711 return; 3712 } 3713 3714 // Store implicitly used globals with declare target link for parent 3715 // target. 3716 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 3717 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 3718 Stack->addToParentTargetRegionLinkGlobals(E); 3719 return; 3720 } 3721 } 3722 } 3723 void VisitMemberExpr(MemberExpr *E) { 3724 if (E->isTypeDependent() || E->isValueDependent() || 3725 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 3726 return; 3727 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 3728 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 3729 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParenCasts())) { 3730 if (!FD) 3731 return; 3732 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 3733 // Check if the variable has explicit DSA set and stop analysis if it 3734 // so. 3735 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 3736 return; 3737 3738 if (isOpenMPTargetExecutionDirective(DKind) && 3739 !Stack->isLoopControlVariable(FD).first && 3740 !Stack->checkMappableExprComponentListsForDecl( 3741 FD, /*CurrentRegionOnly=*/true, 3742 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 3743 StackComponents, 3744 OpenMPClauseKind) { 3745 return isa<CXXThisExpr>( 3746 cast<MemberExpr>( 3747 StackComponents.back().getAssociatedExpression()) 3748 ->getBase() 3749 ->IgnoreParens()); 3750 })) { 3751 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 3752 // A bit-field cannot appear in a map clause. 3753 // 3754 if (FD->isBitField()) 3755 return; 3756 3757 // Check to see if the member expression is referencing a class that 3758 // has already been explicitly mapped 3759 if (Stack->isClassPreviouslyMapped(TE->getType())) 3760 return; 3761 3762 OpenMPDefaultmapClauseModifier Modifier = 3763 Stack->getDefaultmapModifier(OMPC_DEFAULTMAP_aggregate); 3764 OpenMPDefaultmapClauseKind ClauseKind = 3765 getVariableCategoryFromDecl(SemaRef.getLangOpts(), FD); 3766 OpenMPMapClauseKind Kind = getMapClauseKindFromModifier( 3767 Modifier, /*IsAggregateOrDeclareTarget*/ true); 3768 ImplicitMap[ClauseKind][Kind].emplace_back(E); 3769 return; 3770 } 3771 3772 SourceLocation ELoc = E->getExprLoc(); 3773 // OpenMP [2.9.3.6, Restrictions, p.2] 3774 // A list item that appears in a reduction clause of the innermost 3775 // enclosing worksharing or parallel construct may not be accessed in 3776 // an explicit task. 3777 DVar = Stack->hasInnermostDSA( 3778 FD, 3779 [](OpenMPClauseKind C, bool AppliedToPointee) { 3780 return C == OMPC_reduction && !AppliedToPointee; 3781 }, 3782 [](OpenMPDirectiveKind K) { 3783 return isOpenMPParallelDirective(K) || 3784 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 3785 }, 3786 /*FromParent=*/true); 3787 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 3788 ErrorFound = true; 3789 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 3790 reportOriginalDsa(SemaRef, Stack, FD, DVar); 3791 return; 3792 } 3793 3794 // Define implicit data-sharing attributes for task. 3795 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 3796 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 3797 !Stack->isLoopControlVariable(FD).first) { 3798 // Check if there is a captured expression for the current field in the 3799 // region. Do not mark it as firstprivate unless there is no captured 3800 // expression. 3801 // TODO: try to make it firstprivate. 3802 if (DVar.CKind != OMPC_unknown) 3803 ImplicitFirstprivate.push_back(E); 3804 } 3805 return; 3806 } 3807 if (isOpenMPTargetExecutionDirective(DKind)) { 3808 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 3809 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 3810 Stack->getCurrentDirective(), 3811 /*NoDiagnose=*/true)) 3812 return; 3813 const auto *VD = cast<ValueDecl>( 3814 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 3815 if (!Stack->checkMappableExprComponentListsForDecl( 3816 VD, /*CurrentRegionOnly=*/true, 3817 [&CurComponents]( 3818 OMPClauseMappableExprCommon::MappableExprComponentListRef 3819 StackComponents, 3820 OpenMPClauseKind) { 3821 auto CCI = CurComponents.rbegin(); 3822 auto CCE = CurComponents.rend(); 3823 for (const auto &SC : llvm::reverse(StackComponents)) { 3824 // Do both expressions have the same kind? 3825 if (CCI->getAssociatedExpression()->getStmtClass() != 3826 SC.getAssociatedExpression()->getStmtClass()) 3827 if (!((isa<OMPArraySectionExpr>( 3828 SC.getAssociatedExpression()) || 3829 isa<OMPArrayShapingExpr>( 3830 SC.getAssociatedExpression())) && 3831 isa<ArraySubscriptExpr>( 3832 CCI->getAssociatedExpression()))) 3833 return false; 3834 3835 const Decl *CCD = CCI->getAssociatedDeclaration(); 3836 const Decl *SCD = SC.getAssociatedDeclaration(); 3837 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 3838 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 3839 if (SCD != CCD) 3840 return false; 3841 std::advance(CCI, 1); 3842 if (CCI == CCE) 3843 break; 3844 } 3845 return true; 3846 })) { 3847 Visit(E->getBase()); 3848 } 3849 } else if (!TryCaptureCXXThisMembers) { 3850 Visit(E->getBase()); 3851 } 3852 } 3853 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 3854 for (OMPClause *C : S->clauses()) { 3855 // Skip analysis of arguments of private clauses for task|target 3856 // directives. 3857 if (isa_and_nonnull<OMPPrivateClause>(C)) 3858 continue; 3859 // Skip analysis of arguments of implicitly defined firstprivate clause 3860 // for task|target directives. 3861 // Skip analysis of arguments of implicitly defined map clause for target 3862 // directives. 3863 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 3864 C->isImplicit() && 3865 !isOpenMPTaskingDirective(Stack->getCurrentDirective()))) { 3866 for (Stmt *CC : C->children()) { 3867 if (CC) 3868 Visit(CC); 3869 } 3870 } 3871 } 3872 // Check implicitly captured variables. 3873 VisitSubCaptures(S); 3874 } 3875 3876 void VisitOMPLoopTransformationDirective(OMPLoopTransformationDirective *S) { 3877 // Loop transformation directives do not introduce data sharing 3878 VisitStmt(S); 3879 } 3880 3881 void VisitCallExpr(CallExpr *S) { 3882 for (Stmt *C : S->arguments()) { 3883 if (C) { 3884 // Check implicitly captured variables in the task-based directives to 3885 // check if they must be firstprivatized. 3886 Visit(C); 3887 } 3888 } 3889 if (Expr *Callee = S->getCallee()) 3890 if (auto *CE = dyn_cast<MemberExpr>(Callee->IgnoreParenImpCasts())) 3891 Visit(CE->getBase()); 3892 } 3893 void VisitStmt(Stmt *S) { 3894 for (Stmt *C : S->children()) { 3895 if (C) { 3896 // Check implicitly captured variables in the task-based directives to 3897 // check if they must be firstprivatized. 3898 Visit(C); 3899 } 3900 } 3901 } 3902 3903 void visitSubCaptures(CapturedStmt *S) { 3904 for (const CapturedStmt::Capture &Cap : S->captures()) { 3905 if (!Cap.capturesVariable() && !Cap.capturesVariableByCopy()) 3906 continue; 3907 VarDecl *VD = Cap.getCapturedVar(); 3908 // Do not try to map the variable if it or its sub-component was mapped 3909 // already. 3910 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 3911 Stack->checkMappableExprComponentListsForDecl( 3912 VD, /*CurrentRegionOnly=*/true, 3913 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 3914 OpenMPClauseKind) { return true; })) 3915 continue; 3916 DeclRefExpr *DRE = buildDeclRefExpr( 3917 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 3918 Cap.getLocation(), /*RefersToCapture=*/true); 3919 Visit(DRE); 3920 } 3921 } 3922 bool isErrorFound() const { return ErrorFound; } 3923 ArrayRef<Expr *> getImplicitFirstprivate() const { 3924 return ImplicitFirstprivate; 3925 } 3926 ArrayRef<Expr *> getImplicitPrivate() const { return ImplicitPrivate; } 3927 ArrayRef<Expr *> getImplicitMap(OpenMPDefaultmapClauseKind DK, 3928 OpenMPMapClauseKind MK) const { 3929 return ImplicitMap[DK][MK]; 3930 } 3931 ArrayRef<OpenMPMapModifierKind> 3932 getImplicitMapModifier(OpenMPDefaultmapClauseKind Kind) const { 3933 return ImplicitMapModifier[Kind]; 3934 } 3935 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 3936 return VarsWithInheritedDSA; 3937 } 3938 3939 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 3940 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 3941 // Process declare target link variables for the target directives. 3942 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 3943 for (DeclRefExpr *E : Stack->getLinkGlobals()) 3944 Visit(E); 3945 } 3946 } 3947 }; 3948 } // namespace 3949 3950 static void handleDeclareVariantConstructTrait(DSAStackTy *Stack, 3951 OpenMPDirectiveKind DKind, 3952 bool ScopeEntry) { 3953 SmallVector<llvm::omp::TraitProperty, 8> Traits; 3954 if (isOpenMPTargetExecutionDirective(DKind)) 3955 Traits.emplace_back(llvm::omp::TraitProperty::construct_target_target); 3956 if (isOpenMPTeamsDirective(DKind)) 3957 Traits.emplace_back(llvm::omp::TraitProperty::construct_teams_teams); 3958 if (isOpenMPParallelDirective(DKind)) 3959 Traits.emplace_back(llvm::omp::TraitProperty::construct_parallel_parallel); 3960 if (isOpenMPWorksharingDirective(DKind)) 3961 Traits.emplace_back(llvm::omp::TraitProperty::construct_for_for); 3962 if (isOpenMPSimdDirective(DKind)) 3963 Traits.emplace_back(llvm::omp::TraitProperty::construct_simd_simd); 3964 Stack->handleConstructTrait(Traits, ScopeEntry); 3965 } 3966 3967 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 3968 switch (DKind) { 3969 case OMPD_parallel: 3970 case OMPD_parallel_for: 3971 case OMPD_parallel_for_simd: 3972 case OMPD_parallel_sections: 3973 case OMPD_parallel_master: 3974 case OMPD_parallel_masked: 3975 case OMPD_parallel_loop: 3976 case OMPD_teams: 3977 case OMPD_teams_distribute: 3978 case OMPD_teams_distribute_simd: { 3979 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3980 QualType KmpInt32PtrTy = 3981 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3982 Sema::CapturedParamNameType Params[] = { 3983 std::make_pair(".global_tid.", KmpInt32PtrTy), 3984 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3985 std::make_pair(StringRef(), QualType()) // __context with shared vars 3986 }; 3987 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3988 Params); 3989 break; 3990 } 3991 case OMPD_target_teams: 3992 case OMPD_target_parallel: 3993 case OMPD_target_parallel_for: 3994 case OMPD_target_parallel_for_simd: 3995 case OMPD_target_teams_loop: 3996 case OMPD_target_parallel_loop: 3997 case OMPD_target_teams_distribute: 3998 case OMPD_target_teams_distribute_simd: { 3999 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4000 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4001 QualType KmpInt32PtrTy = 4002 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4003 QualType Args[] = {VoidPtrTy}; 4004 FunctionProtoType::ExtProtoInfo EPI; 4005 EPI.Variadic = true; 4006 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4007 Sema::CapturedParamNameType Params[] = { 4008 std::make_pair(".global_tid.", KmpInt32Ty), 4009 std::make_pair(".part_id.", KmpInt32PtrTy), 4010 std::make_pair(".privates.", VoidPtrTy), 4011 std::make_pair( 4012 ".copy_fn.", 4013 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4014 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4015 std::make_pair(StringRef(), QualType()) // __context with shared vars 4016 }; 4017 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4018 Params, /*OpenMPCaptureLevel=*/0); 4019 // Mark this captured region as inlined, because we don't use outlined 4020 // function directly. 4021 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4022 AlwaysInlineAttr::CreateImplicit( 4023 Context, {}, AttributeCommonInfo::AS_Keyword, 4024 AlwaysInlineAttr::Keyword_forceinline)); 4025 Sema::CapturedParamNameType ParamsTarget[] = { 4026 std::make_pair(StringRef(), QualType()) // __context with shared vars 4027 }; 4028 // Start a captured region for 'target' with no implicit parameters. 4029 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4030 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4031 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 4032 std::make_pair(".global_tid.", KmpInt32PtrTy), 4033 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4034 std::make_pair(StringRef(), QualType()) // __context with shared vars 4035 }; 4036 // Start a captured region for 'teams' or 'parallel'. Both regions have 4037 // the same implicit parameters. 4038 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4039 ParamsTeamsOrParallel, /*OpenMPCaptureLevel=*/2); 4040 break; 4041 } 4042 case OMPD_target: 4043 case OMPD_target_simd: { 4044 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4045 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4046 QualType KmpInt32PtrTy = 4047 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4048 QualType Args[] = {VoidPtrTy}; 4049 FunctionProtoType::ExtProtoInfo EPI; 4050 EPI.Variadic = true; 4051 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4052 Sema::CapturedParamNameType Params[] = { 4053 std::make_pair(".global_tid.", KmpInt32Ty), 4054 std::make_pair(".part_id.", KmpInt32PtrTy), 4055 std::make_pair(".privates.", VoidPtrTy), 4056 std::make_pair( 4057 ".copy_fn.", 4058 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4059 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4060 std::make_pair(StringRef(), QualType()) // __context with shared vars 4061 }; 4062 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4063 Params, /*OpenMPCaptureLevel=*/0); 4064 // Mark this captured region as inlined, because we don't use outlined 4065 // function directly. 4066 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4067 AlwaysInlineAttr::CreateImplicit( 4068 Context, {}, AttributeCommonInfo::AS_Keyword, 4069 AlwaysInlineAttr::Keyword_forceinline)); 4070 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4071 std::make_pair(StringRef(), QualType()), 4072 /*OpenMPCaptureLevel=*/1); 4073 break; 4074 } 4075 case OMPD_atomic: 4076 case OMPD_critical: 4077 case OMPD_section: 4078 case OMPD_master: 4079 case OMPD_masked: 4080 case OMPD_tile: 4081 case OMPD_unroll: 4082 break; 4083 case OMPD_loop: 4084 // TODO: 'loop' may require additional parameters depending on the binding. 4085 // Treat similar to OMPD_simd/OMPD_for for now. 4086 case OMPD_simd: 4087 case OMPD_for: 4088 case OMPD_for_simd: 4089 case OMPD_sections: 4090 case OMPD_single: 4091 case OMPD_taskgroup: 4092 case OMPD_distribute: 4093 case OMPD_distribute_simd: 4094 case OMPD_ordered: 4095 case OMPD_target_data: 4096 case OMPD_dispatch: { 4097 Sema::CapturedParamNameType Params[] = { 4098 std::make_pair(StringRef(), QualType()) // __context with shared vars 4099 }; 4100 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4101 Params); 4102 break; 4103 } 4104 case OMPD_task: { 4105 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4106 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4107 QualType KmpInt32PtrTy = 4108 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4109 QualType Args[] = {VoidPtrTy}; 4110 FunctionProtoType::ExtProtoInfo EPI; 4111 EPI.Variadic = true; 4112 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4113 Sema::CapturedParamNameType Params[] = { 4114 std::make_pair(".global_tid.", KmpInt32Ty), 4115 std::make_pair(".part_id.", KmpInt32PtrTy), 4116 std::make_pair(".privates.", VoidPtrTy), 4117 std::make_pair( 4118 ".copy_fn.", 4119 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4120 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4121 std::make_pair(StringRef(), QualType()) // __context with shared vars 4122 }; 4123 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4124 Params); 4125 // Mark this captured region as inlined, because we don't use outlined 4126 // function directly. 4127 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4128 AlwaysInlineAttr::CreateImplicit( 4129 Context, {}, AttributeCommonInfo::AS_Keyword, 4130 AlwaysInlineAttr::Keyword_forceinline)); 4131 break; 4132 } 4133 case OMPD_taskloop: 4134 case OMPD_taskloop_simd: 4135 case OMPD_master_taskloop: 4136 case OMPD_masked_taskloop: 4137 case OMPD_master_taskloop_simd: { 4138 QualType KmpInt32Ty = 4139 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4140 .withConst(); 4141 QualType KmpUInt64Ty = 4142 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4143 .withConst(); 4144 QualType KmpInt64Ty = 4145 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4146 .withConst(); 4147 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4148 QualType KmpInt32PtrTy = 4149 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4150 QualType Args[] = {VoidPtrTy}; 4151 FunctionProtoType::ExtProtoInfo EPI; 4152 EPI.Variadic = true; 4153 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4154 Sema::CapturedParamNameType Params[] = { 4155 std::make_pair(".global_tid.", KmpInt32Ty), 4156 std::make_pair(".part_id.", KmpInt32PtrTy), 4157 std::make_pair(".privates.", VoidPtrTy), 4158 std::make_pair( 4159 ".copy_fn.", 4160 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4161 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4162 std::make_pair(".lb.", KmpUInt64Ty), 4163 std::make_pair(".ub.", KmpUInt64Ty), 4164 std::make_pair(".st.", KmpInt64Ty), 4165 std::make_pair(".liter.", KmpInt32Ty), 4166 std::make_pair(".reductions.", VoidPtrTy), 4167 std::make_pair(StringRef(), QualType()) // __context with shared vars 4168 }; 4169 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4170 Params); 4171 // Mark this captured region as inlined, because we don't use outlined 4172 // function directly. 4173 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4174 AlwaysInlineAttr::CreateImplicit( 4175 Context, {}, AttributeCommonInfo::AS_Keyword, 4176 AlwaysInlineAttr::Keyword_forceinline)); 4177 break; 4178 } 4179 case OMPD_parallel_master_taskloop: 4180 case OMPD_parallel_master_taskloop_simd: { 4181 QualType KmpInt32Ty = 4182 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 4183 .withConst(); 4184 QualType KmpUInt64Ty = 4185 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 4186 .withConst(); 4187 QualType KmpInt64Ty = 4188 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 4189 .withConst(); 4190 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4191 QualType KmpInt32PtrTy = 4192 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4193 Sema::CapturedParamNameType ParamsParallel[] = { 4194 std::make_pair(".global_tid.", KmpInt32PtrTy), 4195 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4196 std::make_pair(StringRef(), QualType()) // __context with shared vars 4197 }; 4198 // Start a captured region for 'parallel'. 4199 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4200 ParamsParallel, /*OpenMPCaptureLevel=*/0); 4201 QualType Args[] = {VoidPtrTy}; 4202 FunctionProtoType::ExtProtoInfo EPI; 4203 EPI.Variadic = true; 4204 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4205 Sema::CapturedParamNameType Params[] = { 4206 std::make_pair(".global_tid.", KmpInt32Ty), 4207 std::make_pair(".part_id.", KmpInt32PtrTy), 4208 std::make_pair(".privates.", VoidPtrTy), 4209 std::make_pair( 4210 ".copy_fn.", 4211 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4212 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4213 std::make_pair(".lb.", KmpUInt64Ty), 4214 std::make_pair(".ub.", KmpUInt64Ty), 4215 std::make_pair(".st.", KmpInt64Ty), 4216 std::make_pair(".liter.", KmpInt32Ty), 4217 std::make_pair(".reductions.", VoidPtrTy), 4218 std::make_pair(StringRef(), QualType()) // __context with shared vars 4219 }; 4220 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4221 Params, /*OpenMPCaptureLevel=*/1); 4222 // Mark this captured region as inlined, because we don't use outlined 4223 // function directly. 4224 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4225 AlwaysInlineAttr::CreateImplicit( 4226 Context, {}, AttributeCommonInfo::AS_Keyword, 4227 AlwaysInlineAttr::Keyword_forceinline)); 4228 break; 4229 } 4230 case OMPD_distribute_parallel_for_simd: 4231 case OMPD_distribute_parallel_for: { 4232 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4233 QualType KmpInt32PtrTy = 4234 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4235 Sema::CapturedParamNameType Params[] = { 4236 std::make_pair(".global_tid.", KmpInt32PtrTy), 4237 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4238 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4239 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4240 std::make_pair(StringRef(), QualType()) // __context with shared vars 4241 }; 4242 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4243 Params); 4244 break; 4245 } 4246 case OMPD_target_teams_distribute_parallel_for: 4247 case OMPD_target_teams_distribute_parallel_for_simd: { 4248 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4249 QualType KmpInt32PtrTy = 4250 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4251 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4252 4253 QualType Args[] = {VoidPtrTy}; 4254 FunctionProtoType::ExtProtoInfo EPI; 4255 EPI.Variadic = true; 4256 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4257 Sema::CapturedParamNameType Params[] = { 4258 std::make_pair(".global_tid.", KmpInt32Ty), 4259 std::make_pair(".part_id.", KmpInt32PtrTy), 4260 std::make_pair(".privates.", VoidPtrTy), 4261 std::make_pair( 4262 ".copy_fn.", 4263 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4264 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4265 std::make_pair(StringRef(), QualType()) // __context with shared vars 4266 }; 4267 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4268 Params, /*OpenMPCaptureLevel=*/0); 4269 // Mark this captured region as inlined, because we don't use outlined 4270 // function directly. 4271 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4272 AlwaysInlineAttr::CreateImplicit( 4273 Context, {}, AttributeCommonInfo::AS_Keyword, 4274 AlwaysInlineAttr::Keyword_forceinline)); 4275 Sema::CapturedParamNameType ParamsTarget[] = { 4276 std::make_pair(StringRef(), QualType()) // __context with shared vars 4277 }; 4278 // Start a captured region for 'target' with no implicit parameters. 4279 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4280 ParamsTarget, /*OpenMPCaptureLevel=*/1); 4281 4282 Sema::CapturedParamNameType ParamsTeams[] = { 4283 std::make_pair(".global_tid.", KmpInt32PtrTy), 4284 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4285 std::make_pair(StringRef(), QualType()) // __context with shared vars 4286 }; 4287 // Start a captured region for 'target' with no implicit parameters. 4288 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4289 ParamsTeams, /*OpenMPCaptureLevel=*/2); 4290 4291 Sema::CapturedParamNameType ParamsParallel[] = { 4292 std::make_pair(".global_tid.", KmpInt32PtrTy), 4293 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4294 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4295 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4296 std::make_pair(StringRef(), QualType()) // __context with shared vars 4297 }; 4298 // Start a captured region for 'teams' or 'parallel'. Both regions have 4299 // the same implicit parameters. 4300 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4301 ParamsParallel, /*OpenMPCaptureLevel=*/3); 4302 break; 4303 } 4304 4305 case OMPD_teams_loop: { 4306 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4307 QualType KmpInt32PtrTy = 4308 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4309 4310 Sema::CapturedParamNameType ParamsTeams[] = { 4311 std::make_pair(".global_tid.", KmpInt32PtrTy), 4312 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4313 std::make_pair(StringRef(), QualType()) // __context with shared vars 4314 }; 4315 // Start a captured region for 'teams'. 4316 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4317 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4318 break; 4319 } 4320 4321 case OMPD_teams_distribute_parallel_for: 4322 case OMPD_teams_distribute_parallel_for_simd: { 4323 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4324 QualType KmpInt32PtrTy = 4325 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4326 4327 Sema::CapturedParamNameType ParamsTeams[] = { 4328 std::make_pair(".global_tid.", KmpInt32PtrTy), 4329 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4330 std::make_pair(StringRef(), QualType()) // __context with shared vars 4331 }; 4332 // Start a captured region for 'target' with no implicit parameters. 4333 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4334 ParamsTeams, /*OpenMPCaptureLevel=*/0); 4335 4336 Sema::CapturedParamNameType ParamsParallel[] = { 4337 std::make_pair(".global_tid.", KmpInt32PtrTy), 4338 std::make_pair(".bound_tid.", KmpInt32PtrTy), 4339 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 4340 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 4341 std::make_pair(StringRef(), QualType()) // __context with shared vars 4342 }; 4343 // Start a captured region for 'teams' or 'parallel'. Both regions have 4344 // the same implicit parameters. 4345 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4346 ParamsParallel, /*OpenMPCaptureLevel=*/1); 4347 break; 4348 } 4349 case OMPD_target_update: 4350 case OMPD_target_enter_data: 4351 case OMPD_target_exit_data: { 4352 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 4353 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 4354 QualType KmpInt32PtrTy = 4355 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 4356 QualType Args[] = {VoidPtrTy}; 4357 FunctionProtoType::ExtProtoInfo EPI; 4358 EPI.Variadic = true; 4359 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 4360 Sema::CapturedParamNameType Params[] = { 4361 std::make_pair(".global_tid.", KmpInt32Ty), 4362 std::make_pair(".part_id.", KmpInt32PtrTy), 4363 std::make_pair(".privates.", VoidPtrTy), 4364 std::make_pair( 4365 ".copy_fn.", 4366 Context.getPointerType(CopyFnType).withConst().withRestrict()), 4367 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 4368 std::make_pair(StringRef(), QualType()) // __context with shared vars 4369 }; 4370 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 4371 Params); 4372 // Mark this captured region as inlined, because we don't use outlined 4373 // function directly. 4374 getCurCapturedRegion()->TheCapturedDecl->addAttr( 4375 AlwaysInlineAttr::CreateImplicit( 4376 Context, {}, AttributeCommonInfo::AS_Keyword, 4377 AlwaysInlineAttr::Keyword_forceinline)); 4378 break; 4379 } 4380 case OMPD_threadprivate: 4381 case OMPD_allocate: 4382 case OMPD_taskyield: 4383 case OMPD_barrier: 4384 case OMPD_taskwait: 4385 case OMPD_cancellation_point: 4386 case OMPD_cancel: 4387 case OMPD_flush: 4388 case OMPD_depobj: 4389 case OMPD_scan: 4390 case OMPD_declare_reduction: 4391 case OMPD_declare_mapper: 4392 case OMPD_declare_simd: 4393 case OMPD_declare_target: 4394 case OMPD_end_declare_target: 4395 case OMPD_requires: 4396 case OMPD_declare_variant: 4397 case OMPD_begin_declare_variant: 4398 case OMPD_end_declare_variant: 4399 case OMPD_metadirective: 4400 llvm_unreachable("OpenMP Directive is not allowed"); 4401 case OMPD_unknown: 4402 default: 4403 llvm_unreachable("Unknown OpenMP directive"); 4404 } 4405 DSAStack->setContext(CurContext); 4406 handleDeclareVariantConstructTrait(DSAStack, DKind, /* ScopeEntry */ true); 4407 } 4408 4409 int Sema::getNumberOfConstructScopes(unsigned Level) const { 4410 return getOpenMPCaptureLevels(DSAStack->getDirective(Level)); 4411 } 4412 4413 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 4414 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4415 getOpenMPCaptureRegions(CaptureRegions, DKind); 4416 return CaptureRegions.size(); 4417 } 4418 4419 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 4420 Expr *CaptureExpr, bool WithInit, 4421 bool AsExpression) { 4422 assert(CaptureExpr); 4423 ASTContext &C = S.getASTContext(); 4424 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 4425 QualType Ty = Init->getType(); 4426 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 4427 if (S.getLangOpts().CPlusPlus) { 4428 Ty = C.getLValueReferenceType(Ty); 4429 } else { 4430 Ty = C.getPointerType(Ty); 4431 ExprResult Res = 4432 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 4433 if (!Res.isUsable()) 4434 return nullptr; 4435 Init = Res.get(); 4436 } 4437 WithInit = true; 4438 } 4439 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 4440 CaptureExpr->getBeginLoc()); 4441 if (!WithInit) 4442 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 4443 S.CurContext->addHiddenDecl(CED); 4444 Sema::TentativeAnalysisScope Trap(S); 4445 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 4446 return CED; 4447 } 4448 4449 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 4450 bool WithInit) { 4451 OMPCapturedExprDecl *CD; 4452 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 4453 CD = cast<OMPCapturedExprDecl>(VD); 4454 else 4455 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 4456 /*AsExpression=*/false); 4457 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4458 CaptureExpr->getExprLoc()); 4459 } 4460 4461 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 4462 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 4463 if (!Ref) { 4464 OMPCapturedExprDecl *CD = buildCaptureDecl( 4465 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 4466 /*WithInit=*/true, /*AsExpression=*/true); 4467 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 4468 CaptureExpr->getExprLoc()); 4469 } 4470 ExprResult Res = Ref; 4471 if (!S.getLangOpts().CPlusPlus && 4472 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 4473 Ref->getType()->isPointerType()) { 4474 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 4475 if (!Res.isUsable()) 4476 return ExprError(); 4477 } 4478 return S.DefaultLvalueConversion(Res.get()); 4479 } 4480 4481 namespace { 4482 // OpenMP directives parsed in this section are represented as a 4483 // CapturedStatement with an associated statement. If a syntax error 4484 // is detected during the parsing of the associated statement, the 4485 // compiler must abort processing and close the CapturedStatement. 4486 // 4487 // Combined directives such as 'target parallel' have more than one 4488 // nested CapturedStatements. This RAII ensures that we unwind out 4489 // of all the nested CapturedStatements when an error is found. 4490 class CaptureRegionUnwinderRAII { 4491 private: 4492 Sema &S; 4493 bool &ErrorFound; 4494 OpenMPDirectiveKind DKind = OMPD_unknown; 4495 4496 public: 4497 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 4498 OpenMPDirectiveKind DKind) 4499 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 4500 ~CaptureRegionUnwinderRAII() { 4501 if (ErrorFound) { 4502 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 4503 while (--ThisCaptureLevel >= 0) 4504 S.ActOnCapturedRegionError(); 4505 } 4506 } 4507 }; 4508 } // namespace 4509 4510 void Sema::tryCaptureOpenMPLambdas(ValueDecl *V) { 4511 // Capture variables captured by reference in lambdas for target-based 4512 // directives. 4513 if (!CurContext->isDependentContext() && 4514 (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) || 4515 isOpenMPTargetDataManagementDirective( 4516 DSAStack->getCurrentDirective()))) { 4517 QualType Type = V->getType(); 4518 if (const auto *RD = Type.getCanonicalType() 4519 .getNonReferenceType() 4520 ->getAsCXXRecordDecl()) { 4521 bool SavedForceCaptureByReferenceInTargetExecutable = 4522 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 4523 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4524 /*V=*/true); 4525 if (RD->isLambda()) { 4526 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 4527 FieldDecl *ThisCapture; 4528 RD->getCaptureFields(Captures, ThisCapture); 4529 for (const LambdaCapture &LC : RD->captures()) { 4530 if (LC.getCaptureKind() == LCK_ByRef) { 4531 VarDecl *VD = LC.getCapturedVar(); 4532 DeclContext *VDC = VD->getDeclContext(); 4533 if (!VDC->Encloses(CurContext)) 4534 continue; 4535 MarkVariableReferenced(LC.getLocation(), VD); 4536 } else if (LC.getCaptureKind() == LCK_This) { 4537 QualType ThisTy = getCurrentThisType(); 4538 if (!ThisTy.isNull() && 4539 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 4540 CheckCXXThisCapture(LC.getLocation()); 4541 } 4542 } 4543 } 4544 DSAStack->setForceCaptureByReferenceInTargetExecutable( 4545 SavedForceCaptureByReferenceInTargetExecutable); 4546 } 4547 } 4548 } 4549 4550 static bool checkOrderedOrderSpecified(Sema &S, 4551 const ArrayRef<OMPClause *> Clauses) { 4552 const OMPOrderedClause *Ordered = nullptr; 4553 const OMPOrderClause *Order = nullptr; 4554 4555 for (const OMPClause *Clause : Clauses) { 4556 if (Clause->getClauseKind() == OMPC_ordered) 4557 Ordered = cast<OMPOrderedClause>(Clause); 4558 else if (Clause->getClauseKind() == OMPC_order) { 4559 Order = cast<OMPOrderClause>(Clause); 4560 if (Order->getKind() != OMPC_ORDER_concurrent) 4561 Order = nullptr; 4562 } 4563 if (Ordered && Order) 4564 break; 4565 } 4566 4567 if (Ordered && Order) { 4568 S.Diag(Order->getKindKwLoc(), 4569 diag::err_omp_simple_clause_incompatible_with_ordered) 4570 << getOpenMPClauseName(OMPC_order) 4571 << getOpenMPSimpleClauseTypeName(OMPC_order, OMPC_ORDER_concurrent) 4572 << SourceRange(Order->getBeginLoc(), Order->getEndLoc()); 4573 S.Diag(Ordered->getBeginLoc(), diag::note_omp_ordered_param) 4574 << 0 << SourceRange(Ordered->getBeginLoc(), Ordered->getEndLoc()); 4575 return true; 4576 } 4577 return false; 4578 } 4579 4580 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 4581 ArrayRef<OMPClause *> Clauses) { 4582 handleDeclareVariantConstructTrait(DSAStack, DSAStack->getCurrentDirective(), 4583 /* ScopeEntry */ false); 4584 if (DSAStack->getCurrentDirective() == OMPD_atomic || 4585 DSAStack->getCurrentDirective() == OMPD_critical || 4586 DSAStack->getCurrentDirective() == OMPD_section || 4587 DSAStack->getCurrentDirective() == OMPD_master || 4588 DSAStack->getCurrentDirective() == OMPD_masked) 4589 return S; 4590 4591 bool ErrorFound = false; 4592 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 4593 *this, ErrorFound, DSAStack->getCurrentDirective()); 4594 if (!S.isUsable()) { 4595 ErrorFound = true; 4596 return StmtError(); 4597 } 4598 4599 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 4600 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 4601 OMPOrderedClause *OC = nullptr; 4602 OMPScheduleClause *SC = nullptr; 4603 SmallVector<const OMPLinearClause *, 4> LCs; 4604 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 4605 // This is required for proper codegen. 4606 for (OMPClause *Clause : Clauses) { 4607 if (!LangOpts.OpenMPSimd && 4608 (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) || 4609 DSAStack->getCurrentDirective() == OMPD_target) && 4610 Clause->getClauseKind() == OMPC_in_reduction) { 4611 // Capture taskgroup task_reduction descriptors inside the tasking regions 4612 // with the corresponding in_reduction items. 4613 auto *IRC = cast<OMPInReductionClause>(Clause); 4614 for (Expr *E : IRC->taskgroup_descriptors()) 4615 if (E) 4616 MarkDeclarationsReferencedInExpr(E); 4617 } 4618 if (isOpenMPPrivate(Clause->getClauseKind()) || 4619 Clause->getClauseKind() == OMPC_copyprivate || 4620 (getLangOpts().OpenMPUseTLS && 4621 getASTContext().getTargetInfo().isTLSSupported() && 4622 Clause->getClauseKind() == OMPC_copyin)) { 4623 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 4624 // Mark all variables in private list clauses as used in inner region. 4625 for (Stmt *VarRef : Clause->children()) { 4626 if (auto *E = cast_or_null<Expr>(VarRef)) { 4627 MarkDeclarationsReferencedInExpr(E); 4628 } 4629 } 4630 DSAStack->setForceVarCapturing(/*V=*/false); 4631 } else if (isOpenMPLoopTransformationDirective( 4632 DSAStack->getCurrentDirective())) { 4633 assert(CaptureRegions.empty() && 4634 "No captured regions in loop transformation directives."); 4635 } else if (CaptureRegions.size() > 1 || 4636 CaptureRegions.back() != OMPD_unknown) { 4637 if (auto *C = OMPClauseWithPreInit::get(Clause)) 4638 PICs.push_back(C); 4639 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 4640 if (Expr *E = C->getPostUpdateExpr()) 4641 MarkDeclarationsReferencedInExpr(E); 4642 } 4643 } 4644 if (Clause->getClauseKind() == OMPC_schedule) 4645 SC = cast<OMPScheduleClause>(Clause); 4646 else if (Clause->getClauseKind() == OMPC_ordered) 4647 OC = cast<OMPOrderedClause>(Clause); 4648 else if (Clause->getClauseKind() == OMPC_linear) 4649 LCs.push_back(cast<OMPLinearClause>(Clause)); 4650 } 4651 // Capture allocator expressions if used. 4652 for (Expr *E : DSAStack->getInnerAllocators()) 4653 MarkDeclarationsReferencedInExpr(E); 4654 // OpenMP, 2.7.1 Loop Construct, Restrictions 4655 // The nonmonotonic modifier cannot be specified if an ordered clause is 4656 // specified. 4657 if (SC && 4658 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 4659 SC->getSecondScheduleModifier() == 4660 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 4661 OC) { 4662 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 4663 ? SC->getFirstScheduleModifierLoc() 4664 : SC->getSecondScheduleModifierLoc(), 4665 diag::err_omp_simple_clause_incompatible_with_ordered) 4666 << getOpenMPClauseName(OMPC_schedule) 4667 << getOpenMPSimpleClauseTypeName(OMPC_schedule, 4668 OMPC_SCHEDULE_MODIFIER_nonmonotonic) 4669 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4670 ErrorFound = true; 4671 } 4672 // OpenMP 5.0, 2.9.2 Worksharing-Loop Construct, Restrictions. 4673 // If an order(concurrent) clause is present, an ordered clause may not appear 4674 // on the same directive. 4675 if (checkOrderedOrderSpecified(*this, Clauses)) 4676 ErrorFound = true; 4677 if (!LCs.empty() && OC && OC->getNumForLoops()) { 4678 for (const OMPLinearClause *C : LCs) { 4679 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 4680 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 4681 } 4682 ErrorFound = true; 4683 } 4684 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 4685 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 4686 OC->getNumForLoops()) { 4687 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 4688 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 4689 ErrorFound = true; 4690 } 4691 if (ErrorFound) { 4692 return StmtError(); 4693 } 4694 StmtResult SR = S; 4695 unsigned CompletedRegions = 0; 4696 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 4697 // Mark all variables in private list clauses as used in inner region. 4698 // Required for proper codegen of combined directives. 4699 // TODO: add processing for other clauses. 4700 if (ThisCaptureRegion != OMPD_unknown) { 4701 for (const clang::OMPClauseWithPreInit *C : PICs) { 4702 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 4703 // Find the particular capture region for the clause if the 4704 // directive is a combined one with multiple capture regions. 4705 // If the directive is not a combined one, the capture region 4706 // associated with the clause is OMPD_unknown and is generated 4707 // only once. 4708 if (CaptureRegion == ThisCaptureRegion || 4709 CaptureRegion == OMPD_unknown) { 4710 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 4711 for (Decl *D : DS->decls()) 4712 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 4713 } 4714 } 4715 } 4716 } 4717 if (ThisCaptureRegion == OMPD_target) { 4718 // Capture allocator traits in the target region. They are used implicitly 4719 // and, thus, are not captured by default. 4720 for (OMPClause *C : Clauses) { 4721 if (const auto *UAC = dyn_cast<OMPUsesAllocatorsClause>(C)) { 4722 for (unsigned I = 0, End = UAC->getNumberOfAllocators(); I < End; 4723 ++I) { 4724 OMPUsesAllocatorsClause::Data D = UAC->getAllocatorData(I); 4725 if (Expr *E = D.AllocatorTraits) 4726 MarkDeclarationsReferencedInExpr(E); 4727 } 4728 continue; 4729 } 4730 } 4731 } 4732 if (ThisCaptureRegion == OMPD_parallel) { 4733 // Capture temp arrays for inscan reductions and locals in aligned 4734 // clauses. 4735 for (OMPClause *C : Clauses) { 4736 if (auto *RC = dyn_cast<OMPReductionClause>(C)) { 4737 if (RC->getModifier() != OMPC_REDUCTION_inscan) 4738 continue; 4739 for (Expr *E : RC->copy_array_temps()) 4740 MarkDeclarationsReferencedInExpr(E); 4741 } 4742 if (auto *AC = dyn_cast<OMPAlignedClause>(C)) { 4743 for (Expr *E : AC->varlists()) 4744 MarkDeclarationsReferencedInExpr(E); 4745 } 4746 } 4747 } 4748 if (++CompletedRegions == CaptureRegions.size()) 4749 DSAStack->setBodyComplete(); 4750 SR = ActOnCapturedRegionEnd(SR.get()); 4751 } 4752 return SR; 4753 } 4754 4755 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 4756 OpenMPDirectiveKind CancelRegion, 4757 SourceLocation StartLoc) { 4758 // CancelRegion is only needed for cancel and cancellation_point. 4759 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 4760 return false; 4761 4762 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 4763 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 4764 return false; 4765 4766 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4767 << getOpenMPDirectiveName(CancelRegion); 4768 return true; 4769 } 4770 4771 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 4772 OpenMPDirectiveKind CurrentRegion, 4773 const DeclarationNameInfo &CurrentName, 4774 OpenMPDirectiveKind CancelRegion, 4775 OpenMPBindClauseKind BindKind, 4776 SourceLocation StartLoc) { 4777 if (Stack->getCurScope()) { 4778 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 4779 OpenMPDirectiveKind OffendingRegion = ParentRegion; 4780 bool NestingProhibited = false; 4781 bool CloseNesting = true; 4782 bool OrphanSeen = false; 4783 enum { 4784 NoRecommend, 4785 ShouldBeInParallelRegion, 4786 ShouldBeInOrderedRegion, 4787 ShouldBeInTargetRegion, 4788 ShouldBeInTeamsRegion, 4789 ShouldBeInLoopSimdRegion, 4790 } Recommend = NoRecommend; 4791 if (isOpenMPSimdDirective(ParentRegion) && 4792 ((SemaRef.LangOpts.OpenMP <= 45 && CurrentRegion != OMPD_ordered) || 4793 (SemaRef.LangOpts.OpenMP >= 50 && CurrentRegion != OMPD_ordered && 4794 CurrentRegion != OMPD_simd && CurrentRegion != OMPD_atomic && 4795 CurrentRegion != OMPD_scan))) { 4796 // OpenMP [2.16, Nesting of Regions] 4797 // OpenMP constructs may not be nested inside a simd region. 4798 // OpenMP [2.8.1,simd Construct, Restrictions] 4799 // An ordered construct with the simd clause is the only OpenMP 4800 // construct that can appear in the simd region. 4801 // Allowing a SIMD construct nested in another SIMD construct is an 4802 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 4803 // message. 4804 // OpenMP 5.0 [2.9.3.1, simd Construct, Restrictions] 4805 // The only OpenMP constructs that can be encountered during execution of 4806 // a simd region are the atomic construct, the loop construct, the simd 4807 // construct and the ordered construct with the simd clause. 4808 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 4809 ? diag::err_omp_prohibited_region_simd 4810 : diag::warn_omp_nesting_simd) 4811 << (SemaRef.LangOpts.OpenMP >= 50 ? 1 : 0); 4812 return CurrentRegion != OMPD_simd; 4813 } 4814 if (ParentRegion == OMPD_atomic) { 4815 // OpenMP [2.16, Nesting of Regions] 4816 // OpenMP constructs may not be nested inside an atomic region. 4817 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 4818 return true; 4819 } 4820 if (CurrentRegion == OMPD_section) { 4821 // OpenMP [2.7.2, sections Construct, Restrictions] 4822 // Orphaned section directives are prohibited. That is, the section 4823 // directives must appear within the sections construct and must not be 4824 // encountered elsewhere in the sections region. 4825 if (ParentRegion != OMPD_sections && 4826 ParentRegion != OMPD_parallel_sections) { 4827 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 4828 << (ParentRegion != OMPD_unknown) 4829 << getOpenMPDirectiveName(ParentRegion); 4830 return true; 4831 } 4832 return false; 4833 } 4834 // Allow some constructs (except teams and cancellation constructs) to be 4835 // orphaned (they could be used in functions, called from OpenMP regions 4836 // with the required preconditions). 4837 if (ParentRegion == OMPD_unknown && 4838 !isOpenMPNestingTeamsDirective(CurrentRegion) && 4839 CurrentRegion != OMPD_cancellation_point && 4840 CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_scan) 4841 return false; 4842 if (CurrentRegion == OMPD_cancellation_point || 4843 CurrentRegion == OMPD_cancel) { 4844 // OpenMP [2.16, Nesting of Regions] 4845 // A cancellation point construct for which construct-type-clause is 4846 // taskgroup must be nested inside a task construct. A cancellation 4847 // point construct for which construct-type-clause is not taskgroup must 4848 // be closely nested inside an OpenMP construct that matches the type 4849 // specified in construct-type-clause. 4850 // A cancel construct for which construct-type-clause is taskgroup must be 4851 // nested inside a task construct. A cancel construct for which 4852 // construct-type-clause is not taskgroup must be closely nested inside an 4853 // OpenMP construct that matches the type specified in 4854 // construct-type-clause. 4855 NestingProhibited = 4856 !((CancelRegion == OMPD_parallel && 4857 (ParentRegion == OMPD_parallel || 4858 ParentRegion == OMPD_target_parallel)) || 4859 (CancelRegion == OMPD_for && 4860 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 4861 ParentRegion == OMPD_target_parallel_for || 4862 ParentRegion == OMPD_distribute_parallel_for || 4863 ParentRegion == OMPD_teams_distribute_parallel_for || 4864 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 4865 (CancelRegion == OMPD_taskgroup && 4866 (ParentRegion == OMPD_task || 4867 (SemaRef.getLangOpts().OpenMP >= 50 && 4868 (ParentRegion == OMPD_taskloop || 4869 ParentRegion == OMPD_master_taskloop || 4870 ParentRegion == OMPD_masked_taskloop || 4871 ParentRegion == OMPD_parallel_master_taskloop)))) || 4872 (CancelRegion == OMPD_sections && 4873 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 4874 ParentRegion == OMPD_parallel_sections))); 4875 OrphanSeen = ParentRegion == OMPD_unknown; 4876 } else if (CurrentRegion == OMPD_master || CurrentRegion == OMPD_masked) { 4877 // OpenMP 5.1 [2.22, Nesting of Regions] 4878 // A masked region may not be closely nested inside a worksharing, loop, 4879 // atomic, task, or taskloop region. 4880 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 4881 isOpenMPGenericLoopDirective(ParentRegion) || 4882 isOpenMPTaskingDirective(ParentRegion); 4883 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 4884 // OpenMP [2.16, Nesting of Regions] 4885 // A critical region may not be nested (closely or otherwise) inside a 4886 // critical region with the same name. Note that this restriction is not 4887 // sufficient to prevent deadlock. 4888 SourceLocation PreviousCriticalLoc; 4889 bool DeadLock = Stack->hasDirective( 4890 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 4891 const DeclarationNameInfo &DNI, 4892 SourceLocation Loc) { 4893 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 4894 PreviousCriticalLoc = Loc; 4895 return true; 4896 } 4897 return false; 4898 }, 4899 false /* skip top directive */); 4900 if (DeadLock) { 4901 SemaRef.Diag(StartLoc, 4902 diag::err_omp_prohibited_region_critical_same_name) 4903 << CurrentName.getName(); 4904 if (PreviousCriticalLoc.isValid()) 4905 SemaRef.Diag(PreviousCriticalLoc, 4906 diag::note_omp_previous_critical_region); 4907 return true; 4908 } 4909 } else if (CurrentRegion == OMPD_barrier) { 4910 // OpenMP 5.1 [2.22, Nesting of Regions] 4911 // A barrier region may not be closely nested inside a worksharing, loop, 4912 // task, taskloop, critical, ordered, atomic, or masked region. 4913 NestingProhibited = 4914 isOpenMPWorksharingDirective(ParentRegion) || 4915 isOpenMPGenericLoopDirective(ParentRegion) || 4916 isOpenMPTaskingDirective(ParentRegion) || 4917 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 4918 ParentRegion == OMPD_parallel_master || 4919 ParentRegion == OMPD_parallel_masked || 4920 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 4921 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 4922 !isOpenMPParallelDirective(CurrentRegion) && 4923 !isOpenMPTeamsDirective(CurrentRegion)) { 4924 // OpenMP 5.1 [2.22, Nesting of Regions] 4925 // A loop region that binds to a parallel region or a worksharing region 4926 // may not be closely nested inside a worksharing, loop, task, taskloop, 4927 // critical, ordered, atomic, or masked region. 4928 NestingProhibited = 4929 isOpenMPWorksharingDirective(ParentRegion) || 4930 isOpenMPGenericLoopDirective(ParentRegion) || 4931 isOpenMPTaskingDirective(ParentRegion) || 4932 ParentRegion == OMPD_master || ParentRegion == OMPD_masked || 4933 ParentRegion == OMPD_parallel_master || 4934 ParentRegion == OMPD_parallel_masked || 4935 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 4936 Recommend = ShouldBeInParallelRegion; 4937 } else if (CurrentRegion == OMPD_ordered) { 4938 // OpenMP [2.16, Nesting of Regions] 4939 // An ordered region may not be closely nested inside a critical, 4940 // atomic, or explicit task region. 4941 // An ordered region must be closely nested inside a loop region (or 4942 // parallel loop region) with an ordered clause. 4943 // OpenMP [2.8.1,simd Construct, Restrictions] 4944 // An ordered construct with the simd clause is the only OpenMP construct 4945 // that can appear in the simd region. 4946 NestingProhibited = ParentRegion == OMPD_critical || 4947 isOpenMPTaskingDirective(ParentRegion) || 4948 !(isOpenMPSimdDirective(ParentRegion) || 4949 Stack->isParentOrderedRegion()); 4950 Recommend = ShouldBeInOrderedRegion; 4951 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 4952 // OpenMP [2.16, Nesting of Regions] 4953 // If specified, a teams construct must be contained within a target 4954 // construct. 4955 NestingProhibited = 4956 (SemaRef.LangOpts.OpenMP <= 45 && ParentRegion != OMPD_target) || 4957 (SemaRef.LangOpts.OpenMP >= 50 && ParentRegion != OMPD_unknown && 4958 ParentRegion != OMPD_target); 4959 OrphanSeen = ParentRegion == OMPD_unknown; 4960 Recommend = ShouldBeInTargetRegion; 4961 } else if (CurrentRegion == OMPD_scan) { 4962 // OpenMP [2.16, Nesting of Regions] 4963 // If specified, a teams construct must be contained within a target 4964 // construct. 4965 NestingProhibited = 4966 SemaRef.LangOpts.OpenMP < 50 || 4967 (ParentRegion != OMPD_simd && ParentRegion != OMPD_for && 4968 ParentRegion != OMPD_for_simd && ParentRegion != OMPD_parallel_for && 4969 ParentRegion != OMPD_parallel_for_simd); 4970 OrphanSeen = ParentRegion == OMPD_unknown; 4971 Recommend = ShouldBeInLoopSimdRegion; 4972 } 4973 if (!NestingProhibited && 4974 !isOpenMPTargetExecutionDirective(CurrentRegion) && 4975 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 4976 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 4977 // OpenMP [5.1, 2.22, Nesting of Regions] 4978 // distribute, distribute simd, distribute parallel worksharing-loop, 4979 // distribute parallel worksharing-loop SIMD, loop, parallel regions, 4980 // including any parallel regions arising from combined constructs, 4981 // omp_get_num_teams() regions, and omp_get_team_num() regions are the 4982 // only OpenMP regions that may be strictly nested inside the teams 4983 // region. 4984 // 4985 // As an extension, we permit atomic within teams as well. 4986 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 4987 !isOpenMPDistributeDirective(CurrentRegion) && 4988 CurrentRegion != OMPD_loop && 4989 !(SemaRef.getLangOpts().OpenMPExtensions && 4990 CurrentRegion == OMPD_atomic); 4991 Recommend = ShouldBeInParallelRegion; 4992 } 4993 if (!NestingProhibited && CurrentRegion == OMPD_loop) { 4994 // OpenMP [5.1, 2.11.7, loop Construct, Restrictions] 4995 // If the bind clause is present on the loop construct and binding is 4996 // teams then the corresponding loop region must be strictly nested inside 4997 // a teams region. 4998 NestingProhibited = BindKind == OMPC_BIND_teams && 4999 ParentRegion != OMPD_teams && 5000 ParentRegion != OMPD_target_teams; 5001 Recommend = ShouldBeInTeamsRegion; 5002 } 5003 if (!NestingProhibited && 5004 isOpenMPNestingDistributeDirective(CurrentRegion)) { 5005 // OpenMP 4.5 [2.17 Nesting of Regions] 5006 // The region associated with the distribute construct must be strictly 5007 // nested inside a teams region 5008 NestingProhibited = 5009 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 5010 Recommend = ShouldBeInTeamsRegion; 5011 } 5012 if (!NestingProhibited && 5013 (isOpenMPTargetExecutionDirective(CurrentRegion) || 5014 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 5015 // OpenMP 4.5 [2.17 Nesting of Regions] 5016 // If a target, target update, target data, target enter data, or 5017 // target exit data construct is encountered during execution of a 5018 // target region, the behavior is unspecified. 5019 NestingProhibited = Stack->hasDirective( 5020 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 5021 SourceLocation) { 5022 if (isOpenMPTargetExecutionDirective(K)) { 5023 OffendingRegion = K; 5024 return true; 5025 } 5026 return false; 5027 }, 5028 false /* don't skip top directive */); 5029 CloseNesting = false; 5030 } 5031 if (NestingProhibited) { 5032 if (OrphanSeen) { 5033 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 5034 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 5035 } else { 5036 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 5037 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 5038 << Recommend << getOpenMPDirectiveName(CurrentRegion); 5039 } 5040 return true; 5041 } 5042 } 5043 return false; 5044 } 5045 5046 struct Kind2Unsigned { 5047 using argument_type = OpenMPDirectiveKind; 5048 unsigned operator()(argument_type DK) { return unsigned(DK); } 5049 }; 5050 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 5051 ArrayRef<OMPClause *> Clauses, 5052 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 5053 bool ErrorFound = false; 5054 unsigned NamedModifiersNumber = 0; 5055 llvm::IndexedMap<const OMPIfClause *, Kind2Unsigned> FoundNameModifiers; 5056 FoundNameModifiers.resize(llvm::omp::Directive_enumSize + 1); 5057 SmallVector<SourceLocation, 4> NameModifierLoc; 5058 for (const OMPClause *C : Clauses) { 5059 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 5060 // At most one if clause without a directive-name-modifier can appear on 5061 // the directive. 5062 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 5063 if (FoundNameModifiers[CurNM]) { 5064 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 5065 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 5066 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 5067 ErrorFound = true; 5068 } else if (CurNM != OMPD_unknown) { 5069 NameModifierLoc.push_back(IC->getNameModifierLoc()); 5070 ++NamedModifiersNumber; 5071 } 5072 FoundNameModifiers[CurNM] = IC; 5073 if (CurNM == OMPD_unknown) 5074 continue; 5075 // Check if the specified name modifier is allowed for the current 5076 // directive. 5077 // At most one if clause with the particular directive-name-modifier can 5078 // appear on the directive. 5079 if (!llvm::is_contained(AllowedNameModifiers, CurNM)) { 5080 S.Diag(IC->getNameModifierLoc(), 5081 diag::err_omp_wrong_if_directive_name_modifier) 5082 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 5083 ErrorFound = true; 5084 } 5085 } 5086 } 5087 // If any if clause on the directive includes a directive-name-modifier then 5088 // all if clauses on the directive must include a directive-name-modifier. 5089 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 5090 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 5091 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 5092 diag::err_omp_no_more_if_clause); 5093 } else { 5094 std::string Values; 5095 std::string Sep(", "); 5096 unsigned AllowedCnt = 0; 5097 unsigned TotalAllowedNum = 5098 AllowedNameModifiers.size() - NamedModifiersNumber; 5099 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 5100 ++Cnt) { 5101 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 5102 if (!FoundNameModifiers[NM]) { 5103 Values += "'"; 5104 Values += getOpenMPDirectiveName(NM); 5105 Values += "'"; 5106 if (AllowedCnt + 2 == TotalAllowedNum) 5107 Values += " or "; 5108 else if (AllowedCnt + 1 != TotalAllowedNum) 5109 Values += Sep; 5110 ++AllowedCnt; 5111 } 5112 } 5113 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 5114 diag::err_omp_unnamed_if_clause) 5115 << (TotalAllowedNum > 1) << Values; 5116 } 5117 for (SourceLocation Loc : NameModifierLoc) { 5118 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 5119 } 5120 ErrorFound = true; 5121 } 5122 return ErrorFound; 5123 } 5124 5125 static std::pair<ValueDecl *, bool> getPrivateItem(Sema &S, Expr *&RefExpr, 5126 SourceLocation &ELoc, 5127 SourceRange &ERange, 5128 bool AllowArraySection) { 5129 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 5130 RefExpr->containsUnexpandedParameterPack()) 5131 return std::make_pair(nullptr, true); 5132 5133 // OpenMP [3.1, C/C++] 5134 // A list item is a variable name. 5135 // OpenMP [2.9.3.3, Restrictions, p.1] 5136 // A variable that is part of another variable (as an array or 5137 // structure element) cannot appear in a private clause. 5138 RefExpr = RefExpr->IgnoreParens(); 5139 enum { 5140 NoArrayExpr = -1, 5141 ArraySubscript = 0, 5142 OMPArraySection = 1 5143 } IsArrayExpr = NoArrayExpr; 5144 if (AllowArraySection) { 5145 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 5146 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 5147 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 5148 Base = TempASE->getBase()->IgnoreParenImpCasts(); 5149 RefExpr = Base; 5150 IsArrayExpr = ArraySubscript; 5151 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 5152 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 5153 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 5154 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 5155 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 5156 Base = TempASE->getBase()->IgnoreParenImpCasts(); 5157 RefExpr = Base; 5158 IsArrayExpr = OMPArraySection; 5159 } 5160 } 5161 ELoc = RefExpr->getExprLoc(); 5162 ERange = RefExpr->getSourceRange(); 5163 RefExpr = RefExpr->IgnoreParenImpCasts(); 5164 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 5165 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 5166 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 5167 (S.getCurrentThisType().isNull() || !ME || 5168 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 5169 !isa<FieldDecl>(ME->getMemberDecl()))) { 5170 if (IsArrayExpr != NoArrayExpr) { 5171 S.Diag(ELoc, diag::err_omp_expected_base_var_name) 5172 << IsArrayExpr << ERange; 5173 } else { 5174 S.Diag(ELoc, 5175 AllowArraySection 5176 ? diag::err_omp_expected_var_name_member_expr_or_array_item 5177 : diag::err_omp_expected_var_name_member_expr) 5178 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 5179 } 5180 return std::make_pair(nullptr, false); 5181 } 5182 return std::make_pair( 5183 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 5184 } 5185 5186 namespace { 5187 /// Checks if the allocator is used in uses_allocators clause to be allowed in 5188 /// target regions. 5189 class AllocatorChecker final : public ConstStmtVisitor<AllocatorChecker, bool> { 5190 DSAStackTy *S = nullptr; 5191 5192 public: 5193 bool VisitDeclRefExpr(const DeclRefExpr *E) { 5194 return S->isUsesAllocatorsDecl(E->getDecl()) 5195 .value_or(DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait) == 5196 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait; 5197 } 5198 bool VisitStmt(const Stmt *S) { 5199 for (const Stmt *Child : S->children()) { 5200 if (Child && Visit(Child)) 5201 return true; 5202 } 5203 return false; 5204 } 5205 explicit AllocatorChecker(DSAStackTy *S) : S(S) {} 5206 }; 5207 } // namespace 5208 5209 static void checkAllocateClauses(Sema &S, DSAStackTy *Stack, 5210 ArrayRef<OMPClause *> Clauses) { 5211 assert(!S.CurContext->isDependentContext() && 5212 "Expected non-dependent context."); 5213 auto AllocateRange = 5214 llvm::make_filter_range(Clauses, OMPAllocateClause::classof); 5215 llvm::DenseMap<CanonicalDeclPtr<Decl>, CanonicalDeclPtr<VarDecl>> DeclToCopy; 5216 auto PrivateRange = llvm::make_filter_range(Clauses, [](const OMPClause *C) { 5217 return isOpenMPPrivate(C->getClauseKind()); 5218 }); 5219 for (OMPClause *Cl : PrivateRange) { 5220 MutableArrayRef<Expr *>::iterator I, It, Et; 5221 if (Cl->getClauseKind() == OMPC_private) { 5222 auto *PC = cast<OMPPrivateClause>(Cl); 5223 I = PC->private_copies().begin(); 5224 It = PC->varlist_begin(); 5225 Et = PC->varlist_end(); 5226 } else if (Cl->getClauseKind() == OMPC_firstprivate) { 5227 auto *PC = cast<OMPFirstprivateClause>(Cl); 5228 I = PC->private_copies().begin(); 5229 It = PC->varlist_begin(); 5230 Et = PC->varlist_end(); 5231 } else if (Cl->getClauseKind() == OMPC_lastprivate) { 5232 auto *PC = cast<OMPLastprivateClause>(Cl); 5233 I = PC->private_copies().begin(); 5234 It = PC->varlist_begin(); 5235 Et = PC->varlist_end(); 5236 } else if (Cl->getClauseKind() == OMPC_linear) { 5237 auto *PC = cast<OMPLinearClause>(Cl); 5238 I = PC->privates().begin(); 5239 It = PC->varlist_begin(); 5240 Et = PC->varlist_end(); 5241 } else if (Cl->getClauseKind() == OMPC_reduction) { 5242 auto *PC = cast<OMPReductionClause>(Cl); 5243 I = PC->privates().begin(); 5244 It = PC->varlist_begin(); 5245 Et = PC->varlist_end(); 5246 } else if (Cl->getClauseKind() == OMPC_task_reduction) { 5247 auto *PC = cast<OMPTaskReductionClause>(Cl); 5248 I = PC->privates().begin(); 5249 It = PC->varlist_begin(); 5250 Et = PC->varlist_end(); 5251 } else if (Cl->getClauseKind() == OMPC_in_reduction) { 5252 auto *PC = cast<OMPInReductionClause>(Cl); 5253 I = PC->privates().begin(); 5254 It = PC->varlist_begin(); 5255 Et = PC->varlist_end(); 5256 } else { 5257 llvm_unreachable("Expected private clause."); 5258 } 5259 for (Expr *E : llvm::make_range(It, Et)) { 5260 if (!*I) { 5261 ++I; 5262 continue; 5263 } 5264 SourceLocation ELoc; 5265 SourceRange ERange; 5266 Expr *SimpleRefExpr = E; 5267 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 5268 /*AllowArraySection=*/true); 5269 DeclToCopy.try_emplace(Res.first, 5270 cast<VarDecl>(cast<DeclRefExpr>(*I)->getDecl())); 5271 ++I; 5272 } 5273 } 5274 for (OMPClause *C : AllocateRange) { 5275 auto *AC = cast<OMPAllocateClause>(C); 5276 if (S.getLangOpts().OpenMP >= 50 && 5277 !Stack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>() && 5278 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 5279 AC->getAllocator()) { 5280 Expr *Allocator = AC->getAllocator(); 5281 // OpenMP, 2.12.5 target Construct 5282 // Memory allocators that do not appear in a uses_allocators clause cannot 5283 // appear as an allocator in an allocate clause or be used in the target 5284 // region unless a requires directive with the dynamic_allocators clause 5285 // is present in the same compilation unit. 5286 AllocatorChecker Checker(Stack); 5287 if (Checker.Visit(Allocator)) 5288 S.Diag(Allocator->getExprLoc(), 5289 diag::err_omp_allocator_not_in_uses_allocators) 5290 << Allocator->getSourceRange(); 5291 } 5292 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 5293 getAllocatorKind(S, Stack, AC->getAllocator()); 5294 // OpenMP, 2.11.4 allocate Clause, Restrictions. 5295 // For task, taskloop or target directives, allocation requests to memory 5296 // allocators with the trait access set to thread result in unspecified 5297 // behavior. 5298 if (AllocatorKind == OMPAllocateDeclAttr::OMPThreadMemAlloc && 5299 (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 5300 isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()))) { 5301 S.Diag(AC->getAllocator()->getExprLoc(), 5302 diag::warn_omp_allocate_thread_on_task_target_directive) 5303 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 5304 } 5305 for (Expr *E : AC->varlists()) { 5306 SourceLocation ELoc; 5307 SourceRange ERange; 5308 Expr *SimpleRefExpr = E; 5309 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 5310 ValueDecl *VD = Res.first; 5311 DSAStackTy::DSAVarData Data = Stack->getTopDSA(VD, /*FromParent=*/false); 5312 if (!isOpenMPPrivate(Data.CKind)) { 5313 S.Diag(E->getExprLoc(), 5314 diag::err_omp_expected_private_copy_for_allocate); 5315 continue; 5316 } 5317 VarDecl *PrivateVD = DeclToCopy[VD]; 5318 if (checkPreviousOMPAllocateAttribute(S, Stack, E, PrivateVD, 5319 AllocatorKind, AC->getAllocator())) 5320 continue; 5321 // Placeholder until allocate clause supports align modifier. 5322 Expr *Alignment = nullptr; 5323 applyOMPAllocateAttribute(S, PrivateVD, AllocatorKind, AC->getAllocator(), 5324 Alignment, E->getSourceRange()); 5325 } 5326 } 5327 } 5328 5329 namespace { 5330 /// Rewrite statements and expressions for Sema \p Actions CurContext. 5331 /// 5332 /// Used to wrap already parsed statements/expressions into a new CapturedStmt 5333 /// context. DeclRefExpr used inside the new context are changed to refer to the 5334 /// captured variable instead. 5335 class CaptureVars : public TreeTransform<CaptureVars> { 5336 using BaseTransform = TreeTransform<CaptureVars>; 5337 5338 public: 5339 CaptureVars(Sema &Actions) : BaseTransform(Actions) {} 5340 5341 bool AlwaysRebuild() { return true; } 5342 }; 5343 } // namespace 5344 5345 static VarDecl *precomputeExpr(Sema &Actions, 5346 SmallVectorImpl<Stmt *> &BodyStmts, Expr *E, 5347 StringRef Name) { 5348 Expr *NewE = AssertSuccess(CaptureVars(Actions).TransformExpr(E)); 5349 VarDecl *NewVar = buildVarDecl(Actions, {}, NewE->getType(), Name, nullptr, 5350 dyn_cast<DeclRefExpr>(E->IgnoreImplicit())); 5351 auto *NewDeclStmt = cast<DeclStmt>(AssertSuccess( 5352 Actions.ActOnDeclStmt(Actions.ConvertDeclToDeclGroup(NewVar), {}, {}))); 5353 Actions.AddInitializerToDecl(NewDeclStmt->getSingleDecl(), NewE, false); 5354 BodyStmts.push_back(NewDeclStmt); 5355 return NewVar; 5356 } 5357 5358 /// Create a closure that computes the number of iterations of a loop. 5359 /// 5360 /// \param Actions The Sema object. 5361 /// \param LogicalTy Type for the logical iteration number. 5362 /// \param Rel Comparison operator of the loop condition. 5363 /// \param StartExpr Value of the loop counter at the first iteration. 5364 /// \param StopExpr Expression the loop counter is compared against in the loop 5365 /// condition. \param StepExpr Amount of increment after each iteration. 5366 /// 5367 /// \return Closure (CapturedStmt) of the distance calculation. 5368 static CapturedStmt *buildDistanceFunc(Sema &Actions, QualType LogicalTy, 5369 BinaryOperator::Opcode Rel, 5370 Expr *StartExpr, Expr *StopExpr, 5371 Expr *StepExpr) { 5372 ASTContext &Ctx = Actions.getASTContext(); 5373 TypeSourceInfo *LogicalTSI = Ctx.getTrivialTypeSourceInfo(LogicalTy); 5374 5375 // Captured regions currently don't support return values, we use an 5376 // out-parameter instead. All inputs are implicit captures. 5377 // TODO: Instead of capturing each DeclRefExpr occurring in 5378 // StartExpr/StopExpr/Step, these could also be passed as a value capture. 5379 QualType ResultTy = Ctx.getLValueReferenceType(LogicalTy); 5380 Sema::CapturedParamNameType Params[] = {{"Distance", ResultTy}, 5381 {StringRef(), QualType()}}; 5382 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5383 5384 Stmt *Body; 5385 { 5386 Sema::CompoundScopeRAII CompoundScope(Actions); 5387 CapturedDecl *CS = cast<CapturedDecl>(Actions.CurContext); 5388 5389 // Get the LValue expression for the result. 5390 ImplicitParamDecl *DistParam = CS->getParam(0); 5391 DeclRefExpr *DistRef = Actions.BuildDeclRefExpr( 5392 DistParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5393 5394 SmallVector<Stmt *, 4> BodyStmts; 5395 5396 // Capture all referenced variable references. 5397 // TODO: Instead of computing NewStart/NewStop/NewStep inside the 5398 // CapturedStmt, we could compute them before and capture the result, to be 5399 // used jointly with the LoopVar function. 5400 VarDecl *NewStart = precomputeExpr(Actions, BodyStmts, StartExpr, ".start"); 5401 VarDecl *NewStop = precomputeExpr(Actions, BodyStmts, StopExpr, ".stop"); 5402 VarDecl *NewStep = precomputeExpr(Actions, BodyStmts, StepExpr, ".step"); 5403 auto BuildVarRef = [&](VarDecl *VD) { 5404 return buildDeclRefExpr(Actions, VD, VD->getType(), {}); 5405 }; 5406 5407 IntegerLiteral *Zero = IntegerLiteral::Create( 5408 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 0), LogicalTy, {}); 5409 IntegerLiteral *One = IntegerLiteral::Create( 5410 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {}); 5411 Expr *Dist; 5412 if (Rel == BO_NE) { 5413 // When using a != comparison, the increment can be +1 or -1. This can be 5414 // dynamic at runtime, so we need to check for the direction. 5415 Expr *IsNegStep = AssertSuccess( 5416 Actions.BuildBinOp(nullptr, {}, BO_LT, BuildVarRef(NewStep), Zero)); 5417 5418 // Positive increment. 5419 Expr *ForwardRange = AssertSuccess(Actions.BuildBinOp( 5420 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5421 ForwardRange = AssertSuccess( 5422 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, ForwardRange)); 5423 Expr *ForwardDist = AssertSuccess(Actions.BuildBinOp( 5424 nullptr, {}, BO_Div, ForwardRange, BuildVarRef(NewStep))); 5425 5426 // Negative increment. 5427 Expr *BackwardRange = AssertSuccess(Actions.BuildBinOp( 5428 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5429 BackwardRange = AssertSuccess( 5430 Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, BackwardRange)); 5431 Expr *NegIncAmount = AssertSuccess( 5432 Actions.BuildUnaryOp(nullptr, {}, UO_Minus, BuildVarRef(NewStep))); 5433 Expr *BackwardDist = AssertSuccess( 5434 Actions.BuildBinOp(nullptr, {}, BO_Div, BackwardRange, NegIncAmount)); 5435 5436 // Use the appropriate case. 5437 Dist = AssertSuccess(Actions.ActOnConditionalOp( 5438 {}, {}, IsNegStep, BackwardDist, ForwardDist)); 5439 } else { 5440 assert((Rel == BO_LT || Rel == BO_LE || Rel == BO_GE || Rel == BO_GT) && 5441 "Expected one of these relational operators"); 5442 5443 // We can derive the direction from any other comparison operator. It is 5444 // non well-formed OpenMP if Step increments/decrements in the other 5445 // directions. Whether at least the first iteration passes the loop 5446 // condition. 5447 Expr *HasAnyIteration = AssertSuccess(Actions.BuildBinOp( 5448 nullptr, {}, Rel, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5449 5450 // Compute the range between first and last counter value. 5451 Expr *Range; 5452 if (Rel == BO_GE || Rel == BO_GT) 5453 Range = AssertSuccess(Actions.BuildBinOp( 5454 nullptr, {}, BO_Sub, BuildVarRef(NewStart), BuildVarRef(NewStop))); 5455 else 5456 Range = AssertSuccess(Actions.BuildBinOp( 5457 nullptr, {}, BO_Sub, BuildVarRef(NewStop), BuildVarRef(NewStart))); 5458 5459 // Ensure unsigned range space. 5460 Range = 5461 AssertSuccess(Actions.BuildCStyleCastExpr({}, LogicalTSI, {}, Range)); 5462 5463 if (Rel == BO_LE || Rel == BO_GE) { 5464 // Add one to the range if the relational operator is inclusive. 5465 Range = 5466 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, Range, One)); 5467 } 5468 5469 // Divide by the absolute step amount. If the range is not a multiple of 5470 // the step size, rounding-up the effective upper bound ensures that the 5471 // last iteration is included. 5472 // Note that the rounding-up may cause an overflow in a temporry that 5473 // could be avoided, but would have occurred in a C-style for-loop as well. 5474 Expr *Divisor = BuildVarRef(NewStep); 5475 if (Rel == BO_GE || Rel == BO_GT) 5476 Divisor = 5477 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Minus, Divisor)); 5478 Expr *DivisorMinusOne = 5479 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Sub, Divisor, One)); 5480 Expr *RangeRoundUp = AssertSuccess( 5481 Actions.BuildBinOp(nullptr, {}, BO_Add, Range, DivisorMinusOne)); 5482 Dist = AssertSuccess( 5483 Actions.BuildBinOp(nullptr, {}, BO_Div, RangeRoundUp, Divisor)); 5484 5485 // If there is not at least one iteration, the range contains garbage. Fix 5486 // to zero in this case. 5487 Dist = AssertSuccess( 5488 Actions.ActOnConditionalOp({}, {}, HasAnyIteration, Dist, Zero)); 5489 } 5490 5491 // Assign the result to the out-parameter. 5492 Stmt *ResultAssign = AssertSuccess(Actions.BuildBinOp( 5493 Actions.getCurScope(), {}, BO_Assign, DistRef, Dist)); 5494 BodyStmts.push_back(ResultAssign); 5495 5496 Body = AssertSuccess(Actions.ActOnCompoundStmt({}, {}, BodyStmts, false)); 5497 } 5498 5499 return cast<CapturedStmt>( 5500 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5501 } 5502 5503 /// Create a closure that computes the loop variable from the logical iteration 5504 /// number. 5505 /// 5506 /// \param Actions The Sema object. 5507 /// \param LoopVarTy Type for the loop variable used for result value. 5508 /// \param LogicalTy Type for the logical iteration number. 5509 /// \param StartExpr Value of the loop counter at the first iteration. 5510 /// \param Step Amount of increment after each iteration. 5511 /// \param Deref Whether the loop variable is a dereference of the loop 5512 /// counter variable. 5513 /// 5514 /// \return Closure (CapturedStmt) of the loop value calculation. 5515 static CapturedStmt *buildLoopVarFunc(Sema &Actions, QualType LoopVarTy, 5516 QualType LogicalTy, 5517 DeclRefExpr *StartExpr, Expr *Step, 5518 bool Deref) { 5519 ASTContext &Ctx = Actions.getASTContext(); 5520 5521 // Pass the result as an out-parameter. Passing as return value would require 5522 // the OpenMPIRBuilder to know additional C/C++ semantics, such as how to 5523 // invoke a copy constructor. 5524 QualType TargetParamTy = Ctx.getLValueReferenceType(LoopVarTy); 5525 Sema::CapturedParamNameType Params[] = {{"LoopVar", TargetParamTy}, 5526 {"Logical", LogicalTy}, 5527 {StringRef(), QualType()}}; 5528 Actions.ActOnCapturedRegionStart({}, nullptr, CR_Default, Params); 5529 5530 // Capture the initial iterator which represents the LoopVar value at the 5531 // zero's logical iteration. Since the original ForStmt/CXXForRangeStmt update 5532 // it in every iteration, capture it by value before it is modified. 5533 VarDecl *StartVar = cast<VarDecl>(StartExpr->getDecl()); 5534 bool Invalid = Actions.tryCaptureVariable(StartVar, {}, 5535 Sema::TryCapture_ExplicitByVal, {}); 5536 (void)Invalid; 5537 assert(!Invalid && "Expecting capture-by-value to work."); 5538 5539 Expr *Body; 5540 { 5541 Sema::CompoundScopeRAII CompoundScope(Actions); 5542 auto *CS = cast<CapturedDecl>(Actions.CurContext); 5543 5544 ImplicitParamDecl *TargetParam = CS->getParam(0); 5545 DeclRefExpr *TargetRef = Actions.BuildDeclRefExpr( 5546 TargetParam, LoopVarTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5547 ImplicitParamDecl *IndvarParam = CS->getParam(1); 5548 DeclRefExpr *LogicalRef = Actions.BuildDeclRefExpr( 5549 IndvarParam, LogicalTy, VK_LValue, {}, nullptr, nullptr, {}, nullptr); 5550 5551 // Capture the Start expression. 5552 CaptureVars Recap(Actions); 5553 Expr *NewStart = AssertSuccess(Recap.TransformExpr(StartExpr)); 5554 Expr *NewStep = AssertSuccess(Recap.TransformExpr(Step)); 5555 5556 Expr *Skip = AssertSuccess( 5557 Actions.BuildBinOp(nullptr, {}, BO_Mul, NewStep, LogicalRef)); 5558 // TODO: Explicitly cast to the iterator's difference_type instead of 5559 // relying on implicit conversion. 5560 Expr *Advanced = 5561 AssertSuccess(Actions.BuildBinOp(nullptr, {}, BO_Add, NewStart, Skip)); 5562 5563 if (Deref) { 5564 // For range-based for-loops convert the loop counter value to a concrete 5565 // loop variable value by dereferencing the iterator. 5566 Advanced = 5567 AssertSuccess(Actions.BuildUnaryOp(nullptr, {}, UO_Deref, Advanced)); 5568 } 5569 5570 // Assign the result to the output parameter. 5571 Body = AssertSuccess(Actions.BuildBinOp(Actions.getCurScope(), {}, 5572 BO_Assign, TargetRef, Advanced)); 5573 } 5574 return cast<CapturedStmt>( 5575 AssertSuccess(Actions.ActOnCapturedRegionEnd(Body))); 5576 } 5577 5578 StmtResult Sema::ActOnOpenMPCanonicalLoop(Stmt *AStmt) { 5579 ASTContext &Ctx = getASTContext(); 5580 5581 // Extract the common elements of ForStmt and CXXForRangeStmt: 5582 // Loop variable, repeat condition, increment 5583 Expr *Cond, *Inc; 5584 VarDecl *LIVDecl, *LUVDecl; 5585 if (auto *For = dyn_cast<ForStmt>(AStmt)) { 5586 Stmt *Init = For->getInit(); 5587 if (auto *LCVarDeclStmt = dyn_cast<DeclStmt>(Init)) { 5588 // For statement declares loop variable. 5589 LIVDecl = cast<VarDecl>(LCVarDeclStmt->getSingleDecl()); 5590 } else if (auto *LCAssign = dyn_cast<BinaryOperator>(Init)) { 5591 // For statement reuses variable. 5592 assert(LCAssign->getOpcode() == BO_Assign && 5593 "init part must be a loop variable assignment"); 5594 auto *CounterRef = cast<DeclRefExpr>(LCAssign->getLHS()); 5595 LIVDecl = cast<VarDecl>(CounterRef->getDecl()); 5596 } else 5597 llvm_unreachable("Cannot determine loop variable"); 5598 LUVDecl = LIVDecl; 5599 5600 Cond = For->getCond(); 5601 Inc = For->getInc(); 5602 } else if (auto *RangeFor = dyn_cast<CXXForRangeStmt>(AStmt)) { 5603 DeclStmt *BeginStmt = RangeFor->getBeginStmt(); 5604 LIVDecl = cast<VarDecl>(BeginStmt->getSingleDecl()); 5605 LUVDecl = RangeFor->getLoopVariable(); 5606 5607 Cond = RangeFor->getCond(); 5608 Inc = RangeFor->getInc(); 5609 } else 5610 llvm_unreachable("unhandled kind of loop"); 5611 5612 QualType CounterTy = LIVDecl->getType(); 5613 QualType LVTy = LUVDecl->getType(); 5614 5615 // Analyze the loop condition. 5616 Expr *LHS, *RHS; 5617 BinaryOperator::Opcode CondRel; 5618 Cond = Cond->IgnoreImplicit(); 5619 if (auto *CondBinExpr = dyn_cast<BinaryOperator>(Cond)) { 5620 LHS = CondBinExpr->getLHS(); 5621 RHS = CondBinExpr->getRHS(); 5622 CondRel = CondBinExpr->getOpcode(); 5623 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Cond)) { 5624 assert(CondCXXOp->getNumArgs() == 2 && "Comparison should have 2 operands"); 5625 LHS = CondCXXOp->getArg(0); 5626 RHS = CondCXXOp->getArg(1); 5627 switch (CondCXXOp->getOperator()) { 5628 case OO_ExclaimEqual: 5629 CondRel = BO_NE; 5630 break; 5631 case OO_Less: 5632 CondRel = BO_LT; 5633 break; 5634 case OO_LessEqual: 5635 CondRel = BO_LE; 5636 break; 5637 case OO_Greater: 5638 CondRel = BO_GT; 5639 break; 5640 case OO_GreaterEqual: 5641 CondRel = BO_GE; 5642 break; 5643 default: 5644 llvm_unreachable("unexpected iterator operator"); 5645 } 5646 } else 5647 llvm_unreachable("unexpected loop condition"); 5648 5649 // Normalize such that the loop counter is on the LHS. 5650 if (!isa<DeclRefExpr>(LHS->IgnoreImplicit()) || 5651 cast<DeclRefExpr>(LHS->IgnoreImplicit())->getDecl() != LIVDecl) { 5652 std::swap(LHS, RHS); 5653 CondRel = BinaryOperator::reverseComparisonOp(CondRel); 5654 } 5655 auto *CounterRef = cast<DeclRefExpr>(LHS->IgnoreImplicit()); 5656 5657 // Decide the bit width for the logical iteration counter. By default use the 5658 // unsigned ptrdiff_t integer size (for iterators and pointers). 5659 // TODO: For iterators, use iterator::difference_type, 5660 // std::iterator_traits<>::difference_type or decltype(it - end). 5661 QualType LogicalTy = Ctx.getUnsignedPointerDiffType(); 5662 if (CounterTy->isIntegerType()) { 5663 unsigned BitWidth = Ctx.getIntWidth(CounterTy); 5664 LogicalTy = Ctx.getIntTypeForBitwidth(BitWidth, false); 5665 } 5666 5667 // Analyze the loop increment. 5668 Expr *Step; 5669 if (auto *IncUn = dyn_cast<UnaryOperator>(Inc)) { 5670 int Direction; 5671 switch (IncUn->getOpcode()) { 5672 case UO_PreInc: 5673 case UO_PostInc: 5674 Direction = 1; 5675 break; 5676 case UO_PreDec: 5677 case UO_PostDec: 5678 Direction = -1; 5679 break; 5680 default: 5681 llvm_unreachable("unhandled unary increment operator"); 5682 } 5683 Step = IntegerLiteral::Create( 5684 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), Direction), LogicalTy, {}); 5685 } else if (auto *IncBin = dyn_cast<BinaryOperator>(Inc)) { 5686 if (IncBin->getOpcode() == BO_AddAssign) { 5687 Step = IncBin->getRHS(); 5688 } else if (IncBin->getOpcode() == BO_SubAssign) { 5689 Step = 5690 AssertSuccess(BuildUnaryOp(nullptr, {}, UO_Minus, IncBin->getRHS())); 5691 } else 5692 llvm_unreachable("unhandled binary increment operator"); 5693 } else if (auto *CondCXXOp = dyn_cast<CXXOperatorCallExpr>(Inc)) { 5694 switch (CondCXXOp->getOperator()) { 5695 case OO_PlusPlus: 5696 Step = IntegerLiteral::Create( 5697 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), 1), LogicalTy, {}); 5698 break; 5699 case OO_MinusMinus: 5700 Step = IntegerLiteral::Create( 5701 Ctx, llvm::APInt(Ctx.getIntWidth(LogicalTy), -1), LogicalTy, {}); 5702 break; 5703 case OO_PlusEqual: 5704 Step = CondCXXOp->getArg(1); 5705 break; 5706 case OO_MinusEqual: 5707 Step = AssertSuccess( 5708 BuildUnaryOp(nullptr, {}, UO_Minus, CondCXXOp->getArg(1))); 5709 break; 5710 default: 5711 llvm_unreachable("unhandled overloaded increment operator"); 5712 } 5713 } else 5714 llvm_unreachable("unknown increment expression"); 5715 5716 CapturedStmt *DistanceFunc = 5717 buildDistanceFunc(*this, LogicalTy, CondRel, LHS, RHS, Step); 5718 CapturedStmt *LoopVarFunc = buildLoopVarFunc( 5719 *this, LVTy, LogicalTy, CounterRef, Step, isa<CXXForRangeStmt>(AStmt)); 5720 DeclRefExpr *LVRef = BuildDeclRefExpr(LUVDecl, LUVDecl->getType(), VK_LValue, 5721 {}, nullptr, nullptr, {}, nullptr); 5722 return OMPCanonicalLoop::create(getASTContext(), AStmt, DistanceFunc, 5723 LoopVarFunc, LVRef); 5724 } 5725 5726 StmtResult Sema::ActOnOpenMPLoopnest(Stmt *AStmt) { 5727 // Handle a literal loop. 5728 if (isa<ForStmt>(AStmt) || isa<CXXForRangeStmt>(AStmt)) 5729 return ActOnOpenMPCanonicalLoop(AStmt); 5730 5731 // If not a literal loop, it must be the result of a loop transformation. 5732 OMPExecutableDirective *LoopTransform = cast<OMPExecutableDirective>(AStmt); 5733 assert( 5734 isOpenMPLoopTransformationDirective(LoopTransform->getDirectiveKind()) && 5735 "Loop transformation directive expected"); 5736 return LoopTransform; 5737 } 5738 5739 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 5740 CXXScopeSpec &MapperIdScopeSpec, 5741 const DeclarationNameInfo &MapperId, 5742 QualType Type, 5743 Expr *UnresolvedMapper); 5744 5745 /// Perform DFS through the structure/class data members trying to find 5746 /// member(s) with user-defined 'default' mapper and generate implicit map 5747 /// clauses for such members with the found 'default' mapper. 5748 static void 5749 processImplicitMapsWithDefaultMappers(Sema &S, DSAStackTy *Stack, 5750 SmallVectorImpl<OMPClause *> &Clauses) { 5751 // Check for the deault mapper for data members. 5752 if (S.getLangOpts().OpenMP < 50) 5753 return; 5754 SmallVector<OMPClause *, 4> ImplicitMaps; 5755 for (int Cnt = 0, EndCnt = Clauses.size(); Cnt < EndCnt; ++Cnt) { 5756 auto *C = dyn_cast<OMPMapClause>(Clauses[Cnt]); 5757 if (!C) 5758 continue; 5759 SmallVector<Expr *, 4> SubExprs; 5760 auto *MI = C->mapperlist_begin(); 5761 for (auto I = C->varlist_begin(), End = C->varlist_end(); I != End; 5762 ++I, ++MI) { 5763 // Expression is mapped using mapper - skip it. 5764 if (*MI) 5765 continue; 5766 Expr *E = *I; 5767 // Expression is dependent - skip it, build the mapper when it gets 5768 // instantiated. 5769 if (E->isTypeDependent() || E->isValueDependent() || 5770 E->containsUnexpandedParameterPack()) 5771 continue; 5772 // Array section - need to check for the mapping of the array section 5773 // element. 5774 QualType CanonType = E->getType().getCanonicalType(); 5775 if (CanonType->isSpecificBuiltinType(BuiltinType::OMPArraySection)) { 5776 const auto *OASE = cast<OMPArraySectionExpr>(E->IgnoreParenImpCasts()); 5777 QualType BaseType = 5778 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 5779 QualType ElemType; 5780 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 5781 ElemType = ATy->getElementType(); 5782 else 5783 ElemType = BaseType->getPointeeType(); 5784 CanonType = ElemType; 5785 } 5786 5787 // DFS over data members in structures/classes. 5788 SmallVector<std::pair<QualType, FieldDecl *>, 4> Types( 5789 1, {CanonType, nullptr}); 5790 llvm::DenseMap<const Type *, Expr *> Visited; 5791 SmallVector<std::pair<FieldDecl *, unsigned>, 4> ParentChain( 5792 1, {nullptr, 1}); 5793 while (!Types.empty()) { 5794 QualType BaseType; 5795 FieldDecl *CurFD; 5796 std::tie(BaseType, CurFD) = Types.pop_back_val(); 5797 while (ParentChain.back().second == 0) 5798 ParentChain.pop_back(); 5799 --ParentChain.back().second; 5800 if (BaseType.isNull()) 5801 continue; 5802 // Only structs/classes are allowed to have mappers. 5803 const RecordDecl *RD = BaseType.getCanonicalType()->getAsRecordDecl(); 5804 if (!RD) 5805 continue; 5806 auto It = Visited.find(BaseType.getTypePtr()); 5807 if (It == Visited.end()) { 5808 // Try to find the associated user-defined mapper. 5809 CXXScopeSpec MapperIdScopeSpec; 5810 DeclarationNameInfo DefaultMapperId; 5811 DefaultMapperId.setName(S.Context.DeclarationNames.getIdentifier( 5812 &S.Context.Idents.get("default"))); 5813 DefaultMapperId.setLoc(E->getExprLoc()); 5814 ExprResult ER = buildUserDefinedMapperRef( 5815 S, Stack->getCurScope(), MapperIdScopeSpec, DefaultMapperId, 5816 BaseType, /*UnresolvedMapper=*/nullptr); 5817 if (ER.isInvalid()) 5818 continue; 5819 It = Visited.try_emplace(BaseType.getTypePtr(), ER.get()).first; 5820 } 5821 // Found default mapper. 5822 if (It->second) { 5823 auto *OE = new (S.Context) OpaqueValueExpr(E->getExprLoc(), CanonType, 5824 VK_LValue, OK_Ordinary, E); 5825 OE->setIsUnique(/*V=*/true); 5826 Expr *BaseExpr = OE; 5827 for (const auto &P : ParentChain) { 5828 if (P.first) { 5829 BaseExpr = S.BuildMemberExpr( 5830 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 5831 NestedNameSpecifierLoc(), SourceLocation(), P.first, 5832 DeclAccessPair::make(P.first, P.first->getAccess()), 5833 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 5834 P.first->getType(), VK_LValue, OK_Ordinary); 5835 BaseExpr = S.DefaultLvalueConversion(BaseExpr).get(); 5836 } 5837 } 5838 if (CurFD) 5839 BaseExpr = S.BuildMemberExpr( 5840 BaseExpr, /*IsArrow=*/false, E->getExprLoc(), 5841 NestedNameSpecifierLoc(), SourceLocation(), CurFD, 5842 DeclAccessPair::make(CurFD, CurFD->getAccess()), 5843 /*HadMultipleCandidates=*/false, DeclarationNameInfo(), 5844 CurFD->getType(), VK_LValue, OK_Ordinary); 5845 SubExprs.push_back(BaseExpr); 5846 continue; 5847 } 5848 // Check for the "default" mapper for data members. 5849 bool FirstIter = true; 5850 for (FieldDecl *FD : RD->fields()) { 5851 if (!FD) 5852 continue; 5853 QualType FieldTy = FD->getType(); 5854 if (FieldTy.isNull() || 5855 !(FieldTy->isStructureOrClassType() || FieldTy->isUnionType())) 5856 continue; 5857 if (FirstIter) { 5858 FirstIter = false; 5859 ParentChain.emplace_back(CurFD, 1); 5860 } else { 5861 ++ParentChain.back().second; 5862 } 5863 Types.emplace_back(FieldTy, FD); 5864 } 5865 } 5866 } 5867 if (SubExprs.empty()) 5868 continue; 5869 CXXScopeSpec MapperIdScopeSpec; 5870 DeclarationNameInfo MapperId; 5871 if (OMPClause *NewClause = S.ActOnOpenMPMapClause( 5872 C->getMapTypeModifiers(), C->getMapTypeModifiersLoc(), 5873 MapperIdScopeSpec, MapperId, C->getMapType(), 5874 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 5875 SubExprs, OMPVarListLocTy())) 5876 Clauses.push_back(NewClause); 5877 } 5878 } 5879 5880 StmtResult Sema::ActOnOpenMPExecutableDirective( 5881 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 5882 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 5883 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5884 StmtResult Res = StmtError(); 5885 OpenMPBindClauseKind BindKind = OMPC_BIND_unknown; 5886 if (const OMPBindClause *BC = 5887 OMPExecutableDirective::getSingleClause<OMPBindClause>(Clauses)) 5888 BindKind = BC->getBindKind(); 5889 // First check CancelRegion which is then used in checkNestingOfRegions. 5890 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 5891 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 5892 BindKind, StartLoc)) 5893 return StmtError(); 5894 5895 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 5896 VarsWithInheritedDSAType VarsWithInheritedDSA; 5897 bool ErrorFound = false; 5898 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 5899 if (AStmt && !CurContext->isDependentContext() && Kind != OMPD_atomic && 5900 Kind != OMPD_critical && Kind != OMPD_section && Kind != OMPD_master && 5901 Kind != OMPD_masked && !isOpenMPLoopTransformationDirective(Kind)) { 5902 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5903 5904 // Check default data sharing attributes for referenced variables. 5905 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 5906 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 5907 Stmt *S = AStmt; 5908 while (--ThisCaptureLevel >= 0) 5909 S = cast<CapturedStmt>(S)->getCapturedStmt(); 5910 DSAChecker.Visit(S); 5911 if (!isOpenMPTargetDataManagementDirective(Kind) && 5912 !isOpenMPTaskingDirective(Kind)) { 5913 // Visit subcaptures to generate implicit clauses for captured vars. 5914 auto *CS = cast<CapturedStmt>(AStmt); 5915 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 5916 getOpenMPCaptureRegions(CaptureRegions, Kind); 5917 // Ignore outer tasking regions for target directives. 5918 if (CaptureRegions.size() > 1 && CaptureRegions.front() == OMPD_task) 5919 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 5920 DSAChecker.visitSubCaptures(CS); 5921 } 5922 if (DSAChecker.isErrorFound()) 5923 return StmtError(); 5924 // Generate list of implicitly defined firstprivate variables. 5925 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 5926 5927 SmallVector<Expr *, 4> ImplicitFirstprivates( 5928 DSAChecker.getImplicitFirstprivate().begin(), 5929 DSAChecker.getImplicitFirstprivate().end()); 5930 SmallVector<Expr *, 4> ImplicitPrivates( 5931 DSAChecker.getImplicitPrivate().begin(), 5932 DSAChecker.getImplicitPrivate().end()); 5933 const unsigned DefaultmapKindNum = OMPC_DEFAULTMAP_pointer + 1; 5934 SmallVector<Expr *, 4> ImplicitMaps[DefaultmapKindNum][OMPC_MAP_delete]; 5935 SmallVector<OpenMPMapModifierKind, NumberOfOMPMapClauseModifiers> 5936 ImplicitMapModifiers[DefaultmapKindNum]; 5937 SmallVector<SourceLocation, NumberOfOMPMapClauseModifiers> 5938 ImplicitMapModifiersLoc[DefaultmapKindNum]; 5939 // Get the original location of present modifier from Defaultmap clause. 5940 SourceLocation PresentModifierLocs[DefaultmapKindNum]; 5941 for (OMPClause *C : Clauses) { 5942 if (auto *DMC = dyn_cast<OMPDefaultmapClause>(C)) 5943 if (DMC->getDefaultmapModifier() == OMPC_DEFAULTMAP_MODIFIER_present) 5944 PresentModifierLocs[DMC->getDefaultmapKind()] = 5945 DMC->getDefaultmapModifierLoc(); 5946 } 5947 for (unsigned VC = 0; VC < DefaultmapKindNum; ++VC) { 5948 auto Kind = static_cast<OpenMPDefaultmapClauseKind>(VC); 5949 for (unsigned I = 0; I < OMPC_MAP_delete; ++I) { 5950 ArrayRef<Expr *> ImplicitMap = DSAChecker.getImplicitMap( 5951 Kind, static_cast<OpenMPMapClauseKind>(I)); 5952 ImplicitMaps[VC][I].append(ImplicitMap.begin(), ImplicitMap.end()); 5953 } 5954 ArrayRef<OpenMPMapModifierKind> ImplicitModifier = 5955 DSAChecker.getImplicitMapModifier(Kind); 5956 ImplicitMapModifiers[VC].append(ImplicitModifier.begin(), 5957 ImplicitModifier.end()); 5958 std::fill_n(std::back_inserter(ImplicitMapModifiersLoc[VC]), 5959 ImplicitModifier.size(), PresentModifierLocs[VC]); 5960 } 5961 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 5962 for (OMPClause *C : Clauses) { 5963 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 5964 for (Expr *E : IRC->taskgroup_descriptors()) 5965 if (E) 5966 ImplicitFirstprivates.emplace_back(E); 5967 } 5968 // OpenMP 5.0, 2.10.1 task Construct 5969 // [detach clause]... The event-handle will be considered as if it was 5970 // specified on a firstprivate clause. 5971 if (auto *DC = dyn_cast<OMPDetachClause>(C)) 5972 ImplicitFirstprivates.push_back(DC->getEventHandler()); 5973 } 5974 if (!ImplicitFirstprivates.empty()) { 5975 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 5976 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 5977 SourceLocation())) { 5978 ClausesWithImplicit.push_back(Implicit); 5979 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 5980 ImplicitFirstprivates.size(); 5981 } else { 5982 ErrorFound = true; 5983 } 5984 } 5985 if (!ImplicitPrivates.empty()) { 5986 if (OMPClause *Implicit = 5987 ActOnOpenMPPrivateClause(ImplicitPrivates, SourceLocation(), 5988 SourceLocation(), SourceLocation())) { 5989 ClausesWithImplicit.push_back(Implicit); 5990 ErrorFound = cast<OMPPrivateClause>(Implicit)->varlist_size() != 5991 ImplicitPrivates.size(); 5992 } else { 5993 ErrorFound = true; 5994 } 5995 } 5996 // OpenMP 5.0 [2.19.7] 5997 // If a list item appears in a reduction, lastprivate or linear 5998 // clause on a combined target construct then it is treated as 5999 // if it also appears in a map clause with a map-type of tofrom 6000 if (getLangOpts().OpenMP >= 50 && Kind != OMPD_target && 6001 isOpenMPTargetExecutionDirective(Kind)) { 6002 SmallVector<Expr *, 4> ImplicitExprs; 6003 for (OMPClause *C : Clauses) { 6004 if (auto *RC = dyn_cast<OMPReductionClause>(C)) 6005 for (Expr *E : RC->varlists()) 6006 if (!isa<DeclRefExpr>(E->IgnoreParenImpCasts())) 6007 ImplicitExprs.emplace_back(E); 6008 } 6009 if (!ImplicitExprs.empty()) { 6010 ArrayRef<Expr *> Exprs = ImplicitExprs; 6011 CXXScopeSpec MapperIdScopeSpec; 6012 DeclarationNameInfo MapperId; 6013 if (OMPClause *Implicit = ActOnOpenMPMapClause( 6014 OMPC_MAP_MODIFIER_unknown, SourceLocation(), MapperIdScopeSpec, 6015 MapperId, OMPC_MAP_tofrom, 6016 /*IsMapTypeImplicit=*/true, SourceLocation(), SourceLocation(), 6017 Exprs, OMPVarListLocTy(), /*NoDiagnose=*/true)) 6018 ClausesWithImplicit.emplace_back(Implicit); 6019 } 6020 } 6021 for (unsigned I = 0, E = DefaultmapKindNum; I < E; ++I) { 6022 int ClauseKindCnt = -1; 6023 for (ArrayRef<Expr *> ImplicitMap : ImplicitMaps[I]) { 6024 ++ClauseKindCnt; 6025 if (ImplicitMap.empty()) 6026 continue; 6027 CXXScopeSpec MapperIdScopeSpec; 6028 DeclarationNameInfo MapperId; 6029 auto Kind = static_cast<OpenMPMapClauseKind>(ClauseKindCnt); 6030 if (OMPClause *Implicit = ActOnOpenMPMapClause( 6031 ImplicitMapModifiers[I], ImplicitMapModifiersLoc[I], 6032 MapperIdScopeSpec, MapperId, Kind, /*IsMapTypeImplicit=*/true, 6033 SourceLocation(), SourceLocation(), ImplicitMap, 6034 OMPVarListLocTy())) { 6035 ClausesWithImplicit.emplace_back(Implicit); 6036 ErrorFound |= cast<OMPMapClause>(Implicit)->varlist_size() != 6037 ImplicitMap.size(); 6038 } else { 6039 ErrorFound = true; 6040 } 6041 } 6042 } 6043 // Build expressions for implicit maps of data members with 'default' 6044 // mappers. 6045 if (LangOpts.OpenMP >= 50) 6046 processImplicitMapsWithDefaultMappers(*this, DSAStack, 6047 ClausesWithImplicit); 6048 } 6049 6050 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 6051 switch (Kind) { 6052 case OMPD_parallel: 6053 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 6054 EndLoc); 6055 AllowedNameModifiers.push_back(OMPD_parallel); 6056 break; 6057 case OMPD_simd: 6058 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 6059 VarsWithInheritedDSA); 6060 if (LangOpts.OpenMP >= 50) 6061 AllowedNameModifiers.push_back(OMPD_simd); 6062 break; 6063 case OMPD_tile: 6064 Res = 6065 ActOnOpenMPTileDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6066 break; 6067 case OMPD_unroll: 6068 Res = ActOnOpenMPUnrollDirective(ClausesWithImplicit, AStmt, StartLoc, 6069 EndLoc); 6070 break; 6071 case OMPD_for: 6072 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 6073 VarsWithInheritedDSA); 6074 break; 6075 case OMPD_for_simd: 6076 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6077 EndLoc, VarsWithInheritedDSA); 6078 if (LangOpts.OpenMP >= 50) 6079 AllowedNameModifiers.push_back(OMPD_simd); 6080 break; 6081 case OMPD_sections: 6082 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 6083 EndLoc); 6084 break; 6085 case OMPD_section: 6086 assert(ClausesWithImplicit.empty() && 6087 "No clauses are allowed for 'omp section' directive"); 6088 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 6089 break; 6090 case OMPD_single: 6091 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 6092 EndLoc); 6093 break; 6094 case OMPD_master: 6095 assert(ClausesWithImplicit.empty() && 6096 "No clauses are allowed for 'omp master' directive"); 6097 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 6098 break; 6099 case OMPD_masked: 6100 Res = ActOnOpenMPMaskedDirective(ClausesWithImplicit, AStmt, StartLoc, 6101 EndLoc); 6102 break; 6103 case OMPD_critical: 6104 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 6105 StartLoc, EndLoc); 6106 break; 6107 case OMPD_parallel_for: 6108 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 6109 EndLoc, VarsWithInheritedDSA); 6110 AllowedNameModifiers.push_back(OMPD_parallel); 6111 break; 6112 case OMPD_parallel_for_simd: 6113 Res = ActOnOpenMPParallelForSimdDirective( 6114 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6115 AllowedNameModifiers.push_back(OMPD_parallel); 6116 if (LangOpts.OpenMP >= 50) 6117 AllowedNameModifiers.push_back(OMPD_simd); 6118 break; 6119 case OMPD_parallel_master: 6120 Res = ActOnOpenMPParallelMasterDirective(ClausesWithImplicit, AStmt, 6121 StartLoc, EndLoc); 6122 AllowedNameModifiers.push_back(OMPD_parallel); 6123 break; 6124 case OMPD_parallel_masked: 6125 Res = ActOnOpenMPParallelMaskedDirective(ClausesWithImplicit, AStmt, 6126 StartLoc, EndLoc); 6127 AllowedNameModifiers.push_back(OMPD_parallel); 6128 break; 6129 case OMPD_parallel_sections: 6130 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 6131 StartLoc, EndLoc); 6132 AllowedNameModifiers.push_back(OMPD_parallel); 6133 break; 6134 case OMPD_task: 6135 Res = 6136 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6137 AllowedNameModifiers.push_back(OMPD_task); 6138 break; 6139 case OMPD_taskyield: 6140 assert(ClausesWithImplicit.empty() && 6141 "No clauses are allowed for 'omp taskyield' directive"); 6142 assert(AStmt == nullptr && 6143 "No associated statement allowed for 'omp taskyield' directive"); 6144 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 6145 break; 6146 case OMPD_barrier: 6147 assert(ClausesWithImplicit.empty() && 6148 "No clauses are allowed for 'omp barrier' directive"); 6149 assert(AStmt == nullptr && 6150 "No associated statement allowed for 'omp barrier' directive"); 6151 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 6152 break; 6153 case OMPD_taskwait: 6154 assert(AStmt == nullptr && 6155 "No associated statement allowed for 'omp taskwait' directive"); 6156 Res = ActOnOpenMPTaskwaitDirective(ClausesWithImplicit, StartLoc, EndLoc); 6157 break; 6158 case OMPD_taskgroup: 6159 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 6160 EndLoc); 6161 break; 6162 case OMPD_flush: 6163 assert(AStmt == nullptr && 6164 "No associated statement allowed for 'omp flush' directive"); 6165 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 6166 break; 6167 case OMPD_depobj: 6168 assert(AStmt == nullptr && 6169 "No associated statement allowed for 'omp depobj' directive"); 6170 Res = ActOnOpenMPDepobjDirective(ClausesWithImplicit, StartLoc, EndLoc); 6171 break; 6172 case OMPD_scan: 6173 assert(AStmt == nullptr && 6174 "No associated statement allowed for 'omp scan' directive"); 6175 Res = ActOnOpenMPScanDirective(ClausesWithImplicit, StartLoc, EndLoc); 6176 break; 6177 case OMPD_ordered: 6178 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 6179 EndLoc); 6180 break; 6181 case OMPD_atomic: 6182 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 6183 EndLoc); 6184 break; 6185 case OMPD_teams: 6186 Res = 6187 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 6188 break; 6189 case OMPD_target: 6190 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 6191 EndLoc); 6192 AllowedNameModifiers.push_back(OMPD_target); 6193 break; 6194 case OMPD_target_parallel: 6195 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 6196 StartLoc, EndLoc); 6197 AllowedNameModifiers.push_back(OMPD_target); 6198 AllowedNameModifiers.push_back(OMPD_parallel); 6199 break; 6200 case OMPD_target_parallel_for: 6201 Res = ActOnOpenMPTargetParallelForDirective( 6202 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6203 AllowedNameModifiers.push_back(OMPD_target); 6204 AllowedNameModifiers.push_back(OMPD_parallel); 6205 break; 6206 case OMPD_cancellation_point: 6207 assert(ClausesWithImplicit.empty() && 6208 "No clauses are allowed for 'omp cancellation point' directive"); 6209 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 6210 "cancellation point' directive"); 6211 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 6212 break; 6213 case OMPD_cancel: 6214 assert(AStmt == nullptr && 6215 "No associated statement allowed for 'omp cancel' directive"); 6216 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 6217 CancelRegion); 6218 AllowedNameModifiers.push_back(OMPD_cancel); 6219 break; 6220 case OMPD_target_data: 6221 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 6222 EndLoc); 6223 AllowedNameModifiers.push_back(OMPD_target_data); 6224 break; 6225 case OMPD_target_enter_data: 6226 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 6227 EndLoc, AStmt); 6228 AllowedNameModifiers.push_back(OMPD_target_enter_data); 6229 break; 6230 case OMPD_target_exit_data: 6231 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 6232 EndLoc, AStmt); 6233 AllowedNameModifiers.push_back(OMPD_target_exit_data); 6234 break; 6235 case OMPD_taskloop: 6236 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 6237 EndLoc, VarsWithInheritedDSA); 6238 AllowedNameModifiers.push_back(OMPD_taskloop); 6239 break; 6240 case OMPD_taskloop_simd: 6241 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6242 EndLoc, VarsWithInheritedDSA); 6243 AllowedNameModifiers.push_back(OMPD_taskloop); 6244 if (LangOpts.OpenMP >= 50) 6245 AllowedNameModifiers.push_back(OMPD_simd); 6246 break; 6247 case OMPD_master_taskloop: 6248 Res = ActOnOpenMPMasterTaskLoopDirective( 6249 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6250 AllowedNameModifiers.push_back(OMPD_taskloop); 6251 break; 6252 case OMPD_masked_taskloop: 6253 Res = ActOnOpenMPMaskedTaskLoopDirective( 6254 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6255 AllowedNameModifiers.push_back(OMPD_taskloop); 6256 break; 6257 case OMPD_master_taskloop_simd: 6258 Res = ActOnOpenMPMasterTaskLoopSimdDirective( 6259 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6260 AllowedNameModifiers.push_back(OMPD_taskloop); 6261 if (LangOpts.OpenMP >= 50) 6262 AllowedNameModifiers.push_back(OMPD_simd); 6263 break; 6264 case OMPD_parallel_master_taskloop: 6265 Res = ActOnOpenMPParallelMasterTaskLoopDirective( 6266 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6267 AllowedNameModifiers.push_back(OMPD_taskloop); 6268 AllowedNameModifiers.push_back(OMPD_parallel); 6269 break; 6270 case OMPD_parallel_master_taskloop_simd: 6271 Res = ActOnOpenMPParallelMasterTaskLoopSimdDirective( 6272 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6273 AllowedNameModifiers.push_back(OMPD_taskloop); 6274 AllowedNameModifiers.push_back(OMPD_parallel); 6275 if (LangOpts.OpenMP >= 50) 6276 AllowedNameModifiers.push_back(OMPD_simd); 6277 break; 6278 case OMPD_distribute: 6279 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 6280 EndLoc, VarsWithInheritedDSA); 6281 break; 6282 case OMPD_target_update: 6283 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 6284 EndLoc, AStmt); 6285 AllowedNameModifiers.push_back(OMPD_target_update); 6286 break; 6287 case OMPD_distribute_parallel_for: 6288 Res = ActOnOpenMPDistributeParallelForDirective( 6289 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6290 AllowedNameModifiers.push_back(OMPD_parallel); 6291 break; 6292 case OMPD_distribute_parallel_for_simd: 6293 Res = ActOnOpenMPDistributeParallelForSimdDirective( 6294 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6295 AllowedNameModifiers.push_back(OMPD_parallel); 6296 if (LangOpts.OpenMP >= 50) 6297 AllowedNameModifiers.push_back(OMPD_simd); 6298 break; 6299 case OMPD_distribute_simd: 6300 Res = ActOnOpenMPDistributeSimdDirective( 6301 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6302 if (LangOpts.OpenMP >= 50) 6303 AllowedNameModifiers.push_back(OMPD_simd); 6304 break; 6305 case OMPD_target_parallel_for_simd: 6306 Res = ActOnOpenMPTargetParallelForSimdDirective( 6307 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6308 AllowedNameModifiers.push_back(OMPD_target); 6309 AllowedNameModifiers.push_back(OMPD_parallel); 6310 if (LangOpts.OpenMP >= 50) 6311 AllowedNameModifiers.push_back(OMPD_simd); 6312 break; 6313 case OMPD_target_simd: 6314 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 6315 EndLoc, VarsWithInheritedDSA); 6316 AllowedNameModifiers.push_back(OMPD_target); 6317 if (LangOpts.OpenMP >= 50) 6318 AllowedNameModifiers.push_back(OMPD_simd); 6319 break; 6320 case OMPD_teams_distribute: 6321 Res = ActOnOpenMPTeamsDistributeDirective( 6322 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6323 break; 6324 case OMPD_teams_distribute_simd: 6325 Res = ActOnOpenMPTeamsDistributeSimdDirective( 6326 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6327 if (LangOpts.OpenMP >= 50) 6328 AllowedNameModifiers.push_back(OMPD_simd); 6329 break; 6330 case OMPD_teams_distribute_parallel_for_simd: 6331 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 6332 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6333 AllowedNameModifiers.push_back(OMPD_parallel); 6334 if (LangOpts.OpenMP >= 50) 6335 AllowedNameModifiers.push_back(OMPD_simd); 6336 break; 6337 case OMPD_teams_distribute_parallel_for: 6338 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 6339 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6340 AllowedNameModifiers.push_back(OMPD_parallel); 6341 break; 6342 case OMPD_target_teams: 6343 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 6344 EndLoc); 6345 AllowedNameModifiers.push_back(OMPD_target); 6346 break; 6347 case OMPD_target_teams_distribute: 6348 Res = ActOnOpenMPTargetTeamsDistributeDirective( 6349 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6350 AllowedNameModifiers.push_back(OMPD_target); 6351 break; 6352 case OMPD_target_teams_distribute_parallel_for: 6353 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 6354 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6355 AllowedNameModifiers.push_back(OMPD_target); 6356 AllowedNameModifiers.push_back(OMPD_parallel); 6357 break; 6358 case OMPD_target_teams_distribute_parallel_for_simd: 6359 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 6360 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6361 AllowedNameModifiers.push_back(OMPD_target); 6362 AllowedNameModifiers.push_back(OMPD_parallel); 6363 if (LangOpts.OpenMP >= 50) 6364 AllowedNameModifiers.push_back(OMPD_simd); 6365 break; 6366 case OMPD_target_teams_distribute_simd: 6367 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 6368 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6369 AllowedNameModifiers.push_back(OMPD_target); 6370 if (LangOpts.OpenMP >= 50) 6371 AllowedNameModifiers.push_back(OMPD_simd); 6372 break; 6373 case OMPD_interop: 6374 assert(AStmt == nullptr && 6375 "No associated statement allowed for 'omp interop' directive"); 6376 Res = ActOnOpenMPInteropDirective(ClausesWithImplicit, StartLoc, EndLoc); 6377 break; 6378 case OMPD_dispatch: 6379 Res = ActOnOpenMPDispatchDirective(ClausesWithImplicit, AStmt, StartLoc, 6380 EndLoc); 6381 break; 6382 case OMPD_loop: 6383 Res = ActOnOpenMPGenericLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 6384 EndLoc, VarsWithInheritedDSA); 6385 break; 6386 case OMPD_teams_loop: 6387 Res = ActOnOpenMPTeamsGenericLoopDirective( 6388 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6389 break; 6390 case OMPD_target_teams_loop: 6391 Res = ActOnOpenMPTargetTeamsGenericLoopDirective( 6392 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6393 break; 6394 case OMPD_parallel_loop: 6395 Res = ActOnOpenMPParallelGenericLoopDirective( 6396 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6397 break; 6398 case OMPD_target_parallel_loop: 6399 Res = ActOnOpenMPTargetParallelGenericLoopDirective( 6400 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 6401 break; 6402 case OMPD_declare_target: 6403 case OMPD_end_declare_target: 6404 case OMPD_threadprivate: 6405 case OMPD_allocate: 6406 case OMPD_declare_reduction: 6407 case OMPD_declare_mapper: 6408 case OMPD_declare_simd: 6409 case OMPD_requires: 6410 case OMPD_declare_variant: 6411 case OMPD_begin_declare_variant: 6412 case OMPD_end_declare_variant: 6413 llvm_unreachable("OpenMP Directive is not allowed"); 6414 case OMPD_unknown: 6415 default: 6416 llvm_unreachable("Unknown OpenMP directive"); 6417 } 6418 6419 ErrorFound = Res.isInvalid() || ErrorFound; 6420 6421 // Check variables in the clauses if default(none) or 6422 // default(firstprivate) was specified. 6423 if (DSAStack->getDefaultDSA() == DSA_none || 6424 DSAStack->getDefaultDSA() == DSA_private || 6425 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6426 DSAAttrChecker DSAChecker(DSAStack, *this, nullptr); 6427 for (OMPClause *C : Clauses) { 6428 switch (C->getClauseKind()) { 6429 case OMPC_num_threads: 6430 case OMPC_dist_schedule: 6431 // Do not analyse if no parent teams directive. 6432 if (isOpenMPTeamsDirective(Kind)) 6433 break; 6434 continue; 6435 case OMPC_if: 6436 if (isOpenMPTeamsDirective(Kind) && 6437 cast<OMPIfClause>(C)->getNameModifier() != OMPD_target) 6438 break; 6439 if (isOpenMPParallelDirective(Kind) && 6440 isOpenMPTaskLoopDirective(Kind) && 6441 cast<OMPIfClause>(C)->getNameModifier() != OMPD_parallel) 6442 break; 6443 continue; 6444 case OMPC_schedule: 6445 case OMPC_detach: 6446 break; 6447 case OMPC_grainsize: 6448 case OMPC_num_tasks: 6449 case OMPC_final: 6450 case OMPC_priority: 6451 case OMPC_novariants: 6452 case OMPC_nocontext: 6453 // Do not analyze if no parent parallel directive. 6454 if (isOpenMPParallelDirective(Kind)) 6455 break; 6456 continue; 6457 case OMPC_ordered: 6458 case OMPC_device: 6459 case OMPC_num_teams: 6460 case OMPC_thread_limit: 6461 case OMPC_hint: 6462 case OMPC_collapse: 6463 case OMPC_safelen: 6464 case OMPC_simdlen: 6465 case OMPC_sizes: 6466 case OMPC_default: 6467 case OMPC_proc_bind: 6468 case OMPC_private: 6469 case OMPC_firstprivate: 6470 case OMPC_lastprivate: 6471 case OMPC_shared: 6472 case OMPC_reduction: 6473 case OMPC_task_reduction: 6474 case OMPC_in_reduction: 6475 case OMPC_linear: 6476 case OMPC_aligned: 6477 case OMPC_copyin: 6478 case OMPC_copyprivate: 6479 case OMPC_nowait: 6480 case OMPC_untied: 6481 case OMPC_mergeable: 6482 case OMPC_allocate: 6483 case OMPC_read: 6484 case OMPC_write: 6485 case OMPC_update: 6486 case OMPC_capture: 6487 case OMPC_compare: 6488 case OMPC_seq_cst: 6489 case OMPC_acq_rel: 6490 case OMPC_acquire: 6491 case OMPC_release: 6492 case OMPC_relaxed: 6493 case OMPC_depend: 6494 case OMPC_threads: 6495 case OMPC_simd: 6496 case OMPC_map: 6497 case OMPC_nogroup: 6498 case OMPC_defaultmap: 6499 case OMPC_to: 6500 case OMPC_from: 6501 case OMPC_use_device_ptr: 6502 case OMPC_use_device_addr: 6503 case OMPC_is_device_ptr: 6504 case OMPC_has_device_addr: 6505 case OMPC_nontemporal: 6506 case OMPC_order: 6507 case OMPC_destroy: 6508 case OMPC_inclusive: 6509 case OMPC_exclusive: 6510 case OMPC_uses_allocators: 6511 case OMPC_affinity: 6512 case OMPC_bind: 6513 case OMPC_filter: 6514 continue; 6515 case OMPC_allocator: 6516 case OMPC_flush: 6517 case OMPC_depobj: 6518 case OMPC_threadprivate: 6519 case OMPC_uniform: 6520 case OMPC_unknown: 6521 case OMPC_unified_address: 6522 case OMPC_unified_shared_memory: 6523 case OMPC_reverse_offload: 6524 case OMPC_dynamic_allocators: 6525 case OMPC_atomic_default_mem_order: 6526 case OMPC_device_type: 6527 case OMPC_match: 6528 case OMPC_when: 6529 default: 6530 llvm_unreachable("Unexpected clause"); 6531 } 6532 for (Stmt *CC : C->children()) { 6533 if (CC) 6534 DSAChecker.Visit(CC); 6535 } 6536 } 6537 for (const auto &P : DSAChecker.getVarsWithInheritedDSA()) 6538 VarsWithInheritedDSA[P.getFirst()] = P.getSecond(); 6539 } 6540 for (const auto &P : VarsWithInheritedDSA) { 6541 if (P.getFirst()->isImplicit() || isa<OMPCapturedExprDecl>(P.getFirst())) 6542 continue; 6543 ErrorFound = true; 6544 if (DSAStack->getDefaultDSA() == DSA_none || 6545 DSAStack->getDefaultDSA() == DSA_private || 6546 DSAStack->getDefaultDSA() == DSA_firstprivate) { 6547 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 6548 << P.first << P.second->getSourceRange(); 6549 Diag(DSAStack->getDefaultDSALocation(), diag::note_omp_default_dsa_none); 6550 } else if (getLangOpts().OpenMP >= 50) { 6551 Diag(P.second->getExprLoc(), 6552 diag::err_omp_defaultmap_no_attr_for_variable) 6553 << P.first << P.second->getSourceRange(); 6554 Diag(DSAStack->getDefaultDSALocation(), 6555 diag::note_omp_defaultmap_attr_none); 6556 } 6557 } 6558 6559 if (!AllowedNameModifiers.empty()) 6560 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 6561 ErrorFound; 6562 6563 if (ErrorFound) 6564 return StmtError(); 6565 6566 if (!CurContext->isDependentContext() && 6567 isOpenMPTargetExecutionDirective(Kind) && 6568 !(DSAStack->hasRequiresDeclWithClause<OMPUnifiedSharedMemoryClause>() || 6569 DSAStack->hasRequiresDeclWithClause<OMPUnifiedAddressClause>() || 6570 DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>() || 6571 DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>())) { 6572 // Register target to DSA Stack. 6573 DSAStack->addTargetDirLocation(StartLoc); 6574 } 6575 6576 return Res; 6577 } 6578 6579 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 6580 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 6581 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 6582 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 6583 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 6584 assert(Aligneds.size() == Alignments.size()); 6585 assert(Linears.size() == LinModifiers.size()); 6586 assert(Linears.size() == Steps.size()); 6587 if (!DG || DG.get().isNull()) 6588 return DeclGroupPtrTy(); 6589 6590 const int SimdId = 0; 6591 if (!DG.get().isSingleDecl()) { 6592 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 6593 << SimdId; 6594 return DG; 6595 } 6596 Decl *ADecl = DG.get().getSingleDecl(); 6597 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 6598 ADecl = FTD->getTemplatedDecl(); 6599 6600 auto *FD = dyn_cast<FunctionDecl>(ADecl); 6601 if (!FD) { 6602 Diag(ADecl->getLocation(), diag::err_omp_function_expected) << SimdId; 6603 return DeclGroupPtrTy(); 6604 } 6605 6606 // OpenMP [2.8.2, declare simd construct, Description] 6607 // The parameter of the simdlen clause must be a constant positive integer 6608 // expression. 6609 ExprResult SL; 6610 if (Simdlen) 6611 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 6612 // OpenMP [2.8.2, declare simd construct, Description] 6613 // The special this pointer can be used as if was one of the arguments to the 6614 // function in any of the linear, aligned, or uniform clauses. 6615 // The uniform clause declares one or more arguments to have an invariant 6616 // value for all concurrent invocations of the function in the execution of a 6617 // single SIMD loop. 6618 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 6619 const Expr *UniformedLinearThis = nullptr; 6620 for (const Expr *E : Uniforms) { 6621 E = E->IgnoreParenImpCasts(); 6622 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6623 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 6624 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6625 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6626 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 6627 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 6628 continue; 6629 } 6630 if (isa<CXXThisExpr>(E)) { 6631 UniformedLinearThis = E; 6632 continue; 6633 } 6634 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6635 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6636 } 6637 // OpenMP [2.8.2, declare simd construct, Description] 6638 // The aligned clause declares that the object to which each list item points 6639 // is aligned to the number of bytes expressed in the optional parameter of 6640 // the aligned clause. 6641 // The special this pointer can be used as if was one of the arguments to the 6642 // function in any of the linear, aligned, or uniform clauses. 6643 // The type of list items appearing in the aligned clause must be array, 6644 // pointer, reference to array, or reference to pointer. 6645 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 6646 const Expr *AlignedThis = nullptr; 6647 for (const Expr *E : Aligneds) { 6648 E = E->IgnoreParenImpCasts(); 6649 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6650 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6651 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6652 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6653 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6654 ->getCanonicalDecl() == CanonPVD) { 6655 // OpenMP [2.8.1, simd construct, Restrictions] 6656 // A list-item cannot appear in more than one aligned clause. 6657 if (AlignedArgs.count(CanonPVD) > 0) { 6658 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 6659 << 1 << getOpenMPClauseName(OMPC_aligned) 6660 << E->getSourceRange(); 6661 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 6662 diag::note_omp_explicit_dsa) 6663 << getOpenMPClauseName(OMPC_aligned); 6664 continue; 6665 } 6666 AlignedArgs[CanonPVD] = E; 6667 QualType QTy = PVD->getType() 6668 .getNonReferenceType() 6669 .getUnqualifiedType() 6670 .getCanonicalType(); 6671 const Type *Ty = QTy.getTypePtrOrNull(); 6672 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 6673 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 6674 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 6675 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 6676 } 6677 continue; 6678 } 6679 } 6680 if (isa<CXXThisExpr>(E)) { 6681 if (AlignedThis) { 6682 Diag(E->getExprLoc(), diag::err_omp_used_in_clause_twice) 6683 << 2 << getOpenMPClauseName(OMPC_aligned) << E->getSourceRange(); 6684 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 6685 << getOpenMPClauseName(OMPC_aligned); 6686 } 6687 AlignedThis = E; 6688 continue; 6689 } 6690 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6691 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6692 } 6693 // The optional parameter of the aligned clause, alignment, must be a constant 6694 // positive integer expression. If no optional parameter is specified, 6695 // implementation-defined default alignments for SIMD instructions on the 6696 // target platforms are assumed. 6697 SmallVector<const Expr *, 4> NewAligns; 6698 for (Expr *E : Alignments) { 6699 ExprResult Align; 6700 if (E) 6701 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 6702 NewAligns.push_back(Align.get()); 6703 } 6704 // OpenMP [2.8.2, declare simd construct, Description] 6705 // The linear clause declares one or more list items to be private to a SIMD 6706 // lane and to have a linear relationship with respect to the iteration space 6707 // of a loop. 6708 // The special this pointer can be used as if was one of the arguments to the 6709 // function in any of the linear, aligned, or uniform clauses. 6710 // When a linear-step expression is specified in a linear clause it must be 6711 // either a constant integer expression or an integer-typed parameter that is 6712 // specified in a uniform clause on the directive. 6713 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 6714 const bool IsUniformedThis = UniformedLinearThis != nullptr; 6715 auto MI = LinModifiers.begin(); 6716 for (const Expr *E : Linears) { 6717 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 6718 ++MI; 6719 E = E->IgnoreParenImpCasts(); 6720 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 6721 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6722 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6723 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 6724 FD->getParamDecl(PVD->getFunctionScopeIndex()) 6725 ->getCanonicalDecl() == CanonPVD) { 6726 // OpenMP [2.15.3.7, linear Clause, Restrictions] 6727 // A list-item cannot appear in more than one linear clause. 6728 if (LinearArgs.count(CanonPVD) > 0) { 6729 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6730 << getOpenMPClauseName(OMPC_linear) 6731 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 6732 Diag(LinearArgs[CanonPVD]->getExprLoc(), 6733 diag::note_omp_explicit_dsa) 6734 << getOpenMPClauseName(OMPC_linear); 6735 continue; 6736 } 6737 // Each argument can appear in at most one uniform or linear clause. 6738 if (UniformedArgs.count(CanonPVD) > 0) { 6739 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6740 << getOpenMPClauseName(OMPC_linear) 6741 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 6742 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 6743 diag::note_omp_explicit_dsa) 6744 << getOpenMPClauseName(OMPC_uniform); 6745 continue; 6746 } 6747 LinearArgs[CanonPVD] = E; 6748 if (E->isValueDependent() || E->isTypeDependent() || 6749 E->isInstantiationDependent() || 6750 E->containsUnexpandedParameterPack()) 6751 continue; 6752 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 6753 PVD->getOriginalType(), 6754 /*IsDeclareSimd=*/true); 6755 continue; 6756 } 6757 } 6758 if (isa<CXXThisExpr>(E)) { 6759 if (UniformedLinearThis) { 6760 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 6761 << getOpenMPClauseName(OMPC_linear) 6762 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 6763 << E->getSourceRange(); 6764 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 6765 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 6766 : OMPC_linear); 6767 continue; 6768 } 6769 UniformedLinearThis = E; 6770 if (E->isValueDependent() || E->isTypeDependent() || 6771 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 6772 continue; 6773 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 6774 E->getType(), /*IsDeclareSimd=*/true); 6775 continue; 6776 } 6777 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 6778 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 6779 } 6780 Expr *Step = nullptr; 6781 Expr *NewStep = nullptr; 6782 SmallVector<Expr *, 4> NewSteps; 6783 for (Expr *E : Steps) { 6784 // Skip the same step expression, it was checked already. 6785 if (Step == E || !E) { 6786 NewSteps.push_back(E ? NewStep : nullptr); 6787 continue; 6788 } 6789 Step = E; 6790 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 6791 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 6792 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 6793 if (UniformedArgs.count(CanonPVD) == 0) { 6794 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 6795 << Step->getSourceRange(); 6796 } else if (E->isValueDependent() || E->isTypeDependent() || 6797 E->isInstantiationDependent() || 6798 E->containsUnexpandedParameterPack() || 6799 CanonPVD->getType()->hasIntegerRepresentation()) { 6800 NewSteps.push_back(Step); 6801 } else { 6802 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 6803 << Step->getSourceRange(); 6804 } 6805 continue; 6806 } 6807 NewStep = Step; 6808 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 6809 !Step->isInstantiationDependent() && 6810 !Step->containsUnexpandedParameterPack()) { 6811 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 6812 .get(); 6813 if (NewStep) 6814 NewStep = 6815 VerifyIntegerConstantExpression(NewStep, /*FIXME*/ AllowFold).get(); 6816 } 6817 NewSteps.push_back(NewStep); 6818 } 6819 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 6820 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 6821 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 6822 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 6823 const_cast<Expr **>(Linears.data()), Linears.size(), 6824 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 6825 NewSteps.data(), NewSteps.size(), SR); 6826 ADecl->addAttr(NewAttr); 6827 return DG; 6828 } 6829 6830 static void setPrototype(Sema &S, FunctionDecl *FD, FunctionDecl *FDWithProto, 6831 QualType NewType) { 6832 assert(NewType->isFunctionProtoType() && 6833 "Expected function type with prototype."); 6834 assert(FD->getType()->isFunctionNoProtoType() && 6835 "Expected function with type with no prototype."); 6836 assert(FDWithProto->getType()->isFunctionProtoType() && 6837 "Expected function with prototype."); 6838 // Synthesize parameters with the same types. 6839 FD->setType(NewType); 6840 SmallVector<ParmVarDecl *, 16> Params; 6841 for (const ParmVarDecl *P : FDWithProto->parameters()) { 6842 auto *Param = ParmVarDecl::Create(S.getASTContext(), FD, SourceLocation(), 6843 SourceLocation(), nullptr, P->getType(), 6844 /*TInfo=*/nullptr, SC_None, nullptr); 6845 Param->setScopeInfo(0, Params.size()); 6846 Param->setImplicit(); 6847 Params.push_back(Param); 6848 } 6849 6850 FD->setParams(Params); 6851 } 6852 6853 void Sema::ActOnFinishedFunctionDefinitionInOpenMPAssumeScope(Decl *D) { 6854 if (D->isInvalidDecl()) 6855 return; 6856 FunctionDecl *FD = nullptr; 6857 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 6858 FD = UTemplDecl->getTemplatedDecl(); 6859 else 6860 FD = cast<FunctionDecl>(D); 6861 assert(FD && "Expected a function declaration!"); 6862 6863 // If we are instantiating templates we do *not* apply scoped assumptions but 6864 // only global ones. We apply scoped assumption to the template definition 6865 // though. 6866 if (!inTemplateInstantiation()) { 6867 for (AssumptionAttr *AA : OMPAssumeScoped) 6868 FD->addAttr(AA); 6869 } 6870 for (AssumptionAttr *AA : OMPAssumeGlobal) 6871 FD->addAttr(AA); 6872 } 6873 6874 Sema::OMPDeclareVariantScope::OMPDeclareVariantScope(OMPTraitInfo &TI) 6875 : TI(&TI), NameSuffix(TI.getMangledName()) {} 6876 6877 void Sema::ActOnStartOfFunctionDefinitionInOpenMPDeclareVariantScope( 6878 Scope *S, Declarator &D, MultiTemplateParamsArg TemplateParamLists, 6879 SmallVectorImpl<FunctionDecl *> &Bases) { 6880 if (!D.getIdentifier()) 6881 return; 6882 6883 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 6884 6885 // Template specialization is an extension, check if we do it. 6886 bool IsTemplated = !TemplateParamLists.empty(); 6887 if (IsTemplated & 6888 !DVScope.TI->isExtensionActive( 6889 llvm::omp::TraitProperty::implementation_extension_allow_templates)) 6890 return; 6891 6892 IdentifierInfo *BaseII = D.getIdentifier(); 6893 LookupResult Lookup(*this, DeclarationName(BaseII), D.getIdentifierLoc(), 6894 LookupOrdinaryName); 6895 LookupParsedName(Lookup, S, &D.getCXXScopeSpec()); 6896 6897 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 6898 QualType FType = TInfo->getType(); 6899 6900 bool IsConstexpr = 6901 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Constexpr; 6902 bool IsConsteval = 6903 D.getDeclSpec().getConstexprSpecifier() == ConstexprSpecKind::Consteval; 6904 6905 for (auto *Candidate : Lookup) { 6906 auto *CandidateDecl = Candidate->getUnderlyingDecl(); 6907 FunctionDecl *UDecl = nullptr; 6908 if (IsTemplated && isa<FunctionTemplateDecl>(CandidateDecl)) { 6909 auto *FTD = cast<FunctionTemplateDecl>(CandidateDecl); 6910 if (FTD->getTemplateParameters()->size() == TemplateParamLists.size()) 6911 UDecl = FTD->getTemplatedDecl(); 6912 } else if (!IsTemplated) 6913 UDecl = dyn_cast<FunctionDecl>(CandidateDecl); 6914 if (!UDecl) 6915 continue; 6916 6917 // Don't specialize constexpr/consteval functions with 6918 // non-constexpr/consteval functions. 6919 if (UDecl->isConstexpr() && !IsConstexpr) 6920 continue; 6921 if (UDecl->isConsteval() && !IsConsteval) 6922 continue; 6923 6924 QualType UDeclTy = UDecl->getType(); 6925 if (!UDeclTy->isDependentType()) { 6926 QualType NewType = Context.mergeFunctionTypes( 6927 FType, UDeclTy, /* OfBlockPointer */ false, 6928 /* Unqualified */ false, /* AllowCXX */ true); 6929 if (NewType.isNull()) 6930 continue; 6931 } 6932 6933 // Found a base! 6934 Bases.push_back(UDecl); 6935 } 6936 6937 bool UseImplicitBase = !DVScope.TI->isExtensionActive( 6938 llvm::omp::TraitProperty::implementation_extension_disable_implicit_base); 6939 // If no base was found we create a declaration that we use as base. 6940 if (Bases.empty() && UseImplicitBase) { 6941 D.setFunctionDefinitionKind(FunctionDefinitionKind::Declaration); 6942 Decl *BaseD = HandleDeclarator(S, D, TemplateParamLists); 6943 BaseD->setImplicit(true); 6944 if (auto *BaseTemplD = dyn_cast<FunctionTemplateDecl>(BaseD)) 6945 Bases.push_back(BaseTemplD->getTemplatedDecl()); 6946 else 6947 Bases.push_back(cast<FunctionDecl>(BaseD)); 6948 } 6949 6950 std::string MangledName; 6951 MangledName += D.getIdentifier()->getName(); 6952 MangledName += getOpenMPVariantManglingSeparatorStr(); 6953 MangledName += DVScope.NameSuffix; 6954 IdentifierInfo &VariantII = Context.Idents.get(MangledName); 6955 6956 VariantII.setMangledOpenMPVariantName(true); 6957 D.SetIdentifier(&VariantII, D.getBeginLoc()); 6958 } 6959 6960 void Sema::ActOnFinishedFunctionDefinitionInOpenMPDeclareVariantScope( 6961 Decl *D, SmallVectorImpl<FunctionDecl *> &Bases) { 6962 // Do not mark function as is used to prevent its emission if this is the 6963 // only place where it is used. 6964 EnterExpressionEvaluationContext Unevaluated( 6965 *this, Sema::ExpressionEvaluationContext::Unevaluated); 6966 6967 FunctionDecl *FD = nullptr; 6968 if (auto *UTemplDecl = dyn_cast<FunctionTemplateDecl>(D)) 6969 FD = UTemplDecl->getTemplatedDecl(); 6970 else 6971 FD = cast<FunctionDecl>(D); 6972 auto *VariantFuncRef = DeclRefExpr::Create( 6973 Context, NestedNameSpecifierLoc(), SourceLocation(), FD, 6974 /* RefersToEnclosingVariableOrCapture */ false, 6975 /* NameLoc */ FD->getLocation(), FD->getType(), 6976 ExprValueKind::VK_PRValue); 6977 6978 OMPDeclareVariantScope &DVScope = OMPDeclareVariantScopes.back(); 6979 auto *OMPDeclareVariantA = OMPDeclareVariantAttr::CreateImplicit( 6980 Context, VariantFuncRef, DVScope.TI, 6981 /*NothingArgs=*/nullptr, /*NothingArgsSize=*/0, 6982 /*NeedDevicePtrArgs=*/nullptr, /*NeedDevicePtrArgsSize=*/0, 6983 /*AppendArgs=*/nullptr, /*AppendArgsSize=*/0); 6984 for (FunctionDecl *BaseFD : Bases) 6985 BaseFD->addAttr(OMPDeclareVariantA); 6986 } 6987 6988 ExprResult Sema::ActOnOpenMPCall(ExprResult Call, Scope *Scope, 6989 SourceLocation LParenLoc, 6990 MultiExprArg ArgExprs, 6991 SourceLocation RParenLoc, Expr *ExecConfig) { 6992 // The common case is a regular call we do not want to specialize at all. Try 6993 // to make that case fast by bailing early. 6994 CallExpr *CE = dyn_cast<CallExpr>(Call.get()); 6995 if (!CE) 6996 return Call; 6997 6998 FunctionDecl *CalleeFnDecl = CE->getDirectCallee(); 6999 if (!CalleeFnDecl) 7000 return Call; 7001 7002 if (!CalleeFnDecl->hasAttr<OMPDeclareVariantAttr>()) 7003 return Call; 7004 7005 ASTContext &Context = getASTContext(); 7006 std::function<void(StringRef)> DiagUnknownTrait = [this, 7007 CE](StringRef ISATrait) { 7008 // TODO Track the selector locations in a way that is accessible here to 7009 // improve the diagnostic location. 7010 Diag(CE->getBeginLoc(), diag::warn_unknown_declare_variant_isa_trait) 7011 << ISATrait; 7012 }; 7013 TargetOMPContext OMPCtx(Context, std::move(DiagUnknownTrait), 7014 getCurFunctionDecl(), DSAStack->getConstructTraits()); 7015 7016 QualType CalleeFnType = CalleeFnDecl->getType(); 7017 7018 SmallVector<Expr *, 4> Exprs; 7019 SmallVector<VariantMatchInfo, 4> VMIs; 7020 while (CalleeFnDecl) { 7021 for (OMPDeclareVariantAttr *A : 7022 CalleeFnDecl->specific_attrs<OMPDeclareVariantAttr>()) { 7023 Expr *VariantRef = A->getVariantFuncRef(); 7024 7025 VariantMatchInfo VMI; 7026 OMPTraitInfo &TI = A->getTraitInfo(); 7027 TI.getAsVariantMatchInfo(Context, VMI); 7028 if (!isVariantApplicableInContext(VMI, OMPCtx, 7029 /* DeviceSetOnly */ false)) 7030 continue; 7031 7032 VMIs.push_back(VMI); 7033 Exprs.push_back(VariantRef); 7034 } 7035 7036 CalleeFnDecl = CalleeFnDecl->getPreviousDecl(); 7037 } 7038 7039 ExprResult NewCall; 7040 do { 7041 int BestIdx = getBestVariantMatchForContext(VMIs, OMPCtx); 7042 if (BestIdx < 0) 7043 return Call; 7044 Expr *BestExpr = cast<DeclRefExpr>(Exprs[BestIdx]); 7045 Decl *BestDecl = cast<DeclRefExpr>(BestExpr)->getDecl(); 7046 7047 { 7048 // Try to build a (member) call expression for the current best applicable 7049 // variant expression. We allow this to fail in which case we continue 7050 // with the next best variant expression. The fail case is part of the 7051 // implementation defined behavior in the OpenMP standard when it talks 7052 // about what differences in the function prototypes: "Any differences 7053 // that the specific OpenMP context requires in the prototype of the 7054 // variant from the base function prototype are implementation defined." 7055 // This wording is there to allow the specialized variant to have a 7056 // different type than the base function. This is intended and OK but if 7057 // we cannot create a call the difference is not in the "implementation 7058 // defined range" we allow. 7059 Sema::TentativeAnalysisScope Trap(*this); 7060 7061 if (auto *SpecializedMethod = dyn_cast<CXXMethodDecl>(BestDecl)) { 7062 auto *MemberCall = dyn_cast<CXXMemberCallExpr>(CE); 7063 BestExpr = MemberExpr::CreateImplicit( 7064 Context, MemberCall->getImplicitObjectArgument(), 7065 /* IsArrow */ false, SpecializedMethod, Context.BoundMemberTy, 7066 MemberCall->getValueKind(), MemberCall->getObjectKind()); 7067 } 7068 NewCall = BuildCallExpr(Scope, BestExpr, LParenLoc, ArgExprs, RParenLoc, 7069 ExecConfig); 7070 if (NewCall.isUsable()) { 7071 if (CallExpr *NCE = dyn_cast<CallExpr>(NewCall.get())) { 7072 FunctionDecl *NewCalleeFnDecl = NCE->getDirectCallee(); 7073 QualType NewType = Context.mergeFunctionTypes( 7074 CalleeFnType, NewCalleeFnDecl->getType(), 7075 /* OfBlockPointer */ false, 7076 /* Unqualified */ false, /* AllowCXX */ true); 7077 if (!NewType.isNull()) 7078 break; 7079 // Don't use the call if the function type was not compatible. 7080 NewCall = nullptr; 7081 } 7082 } 7083 } 7084 7085 VMIs.erase(VMIs.begin() + BestIdx); 7086 Exprs.erase(Exprs.begin() + BestIdx); 7087 } while (!VMIs.empty()); 7088 7089 if (!NewCall.isUsable()) 7090 return Call; 7091 return PseudoObjectExpr::Create(Context, CE, {NewCall.get()}, 0); 7092 } 7093 7094 Optional<std::pair<FunctionDecl *, Expr *>> 7095 Sema::checkOpenMPDeclareVariantFunction(Sema::DeclGroupPtrTy DG, 7096 Expr *VariantRef, OMPTraitInfo &TI, 7097 unsigned NumAppendArgs, 7098 SourceRange SR) { 7099 if (!DG || DG.get().isNull()) 7100 return None; 7101 7102 const int VariantId = 1; 7103 // Must be applied only to single decl. 7104 if (!DG.get().isSingleDecl()) { 7105 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd_variant) 7106 << VariantId << SR; 7107 return None; 7108 } 7109 Decl *ADecl = DG.get().getSingleDecl(); 7110 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 7111 ADecl = FTD->getTemplatedDecl(); 7112 7113 // Decl must be a function. 7114 auto *FD = dyn_cast<FunctionDecl>(ADecl); 7115 if (!FD) { 7116 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 7117 << VariantId << SR; 7118 return None; 7119 } 7120 7121 auto &&HasMultiVersionAttributes = [](const FunctionDecl *FD) { 7122 // The 'target' attribute needs to be separately checked because it does 7123 // not always signify a multiversion function declaration. 7124 return FD->isMultiVersion() || FD->hasAttr<TargetAttr>(); 7125 }; 7126 // OpenMP is not compatible with multiversion function attributes. 7127 if (HasMultiVersionAttributes(FD)) { 7128 Diag(FD->getLocation(), diag::err_omp_declare_variant_incompat_attributes) 7129 << SR; 7130 return None; 7131 } 7132 7133 // Allow #pragma omp declare variant only if the function is not used. 7134 if (FD->isUsed(false)) 7135 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_used) 7136 << FD->getLocation(); 7137 7138 // Check if the function was emitted already. 7139 const FunctionDecl *Definition; 7140 if (!FD->isThisDeclarationADefinition() && FD->isDefined(Definition) && 7141 (LangOpts.EmitAllDecls || Context.DeclMustBeEmitted(Definition))) 7142 Diag(SR.getBegin(), diag::warn_omp_declare_variant_after_emitted) 7143 << FD->getLocation(); 7144 7145 // The VariantRef must point to function. 7146 if (!VariantRef) { 7147 Diag(SR.getBegin(), diag::err_omp_function_expected) << VariantId; 7148 return None; 7149 } 7150 7151 auto ShouldDelayChecks = [](Expr *&E, bool) { 7152 return E && (E->isTypeDependent() || E->isValueDependent() || 7153 E->containsUnexpandedParameterPack() || 7154 E->isInstantiationDependent()); 7155 }; 7156 // Do not check templates, wait until instantiation. 7157 if (FD->isDependentContext() || ShouldDelayChecks(VariantRef, false) || 7158 TI.anyScoreOrCondition(ShouldDelayChecks)) 7159 return std::make_pair(FD, VariantRef); 7160 7161 // Deal with non-constant score and user condition expressions. 7162 auto HandleNonConstantScoresAndConditions = [this](Expr *&E, 7163 bool IsScore) -> bool { 7164 if (!E || E->isIntegerConstantExpr(Context)) 7165 return false; 7166 7167 if (IsScore) { 7168 // We warn on non-constant scores and pretend they were not present. 7169 Diag(E->getExprLoc(), diag::warn_omp_declare_variant_score_not_constant) 7170 << E; 7171 E = nullptr; 7172 } else { 7173 // We could replace a non-constant user condition with "false" but we 7174 // will soon need to handle these anyway for the dynamic version of 7175 // OpenMP context selectors. 7176 Diag(E->getExprLoc(), 7177 diag::err_omp_declare_variant_user_condition_not_constant) 7178 << E; 7179 } 7180 return true; 7181 }; 7182 if (TI.anyScoreOrCondition(HandleNonConstantScoresAndConditions)) 7183 return None; 7184 7185 QualType AdjustedFnType = FD->getType(); 7186 if (NumAppendArgs) { 7187 const auto *PTy = AdjustedFnType->getAsAdjusted<FunctionProtoType>(); 7188 if (!PTy) { 7189 Diag(FD->getLocation(), diag::err_omp_declare_variant_prototype_required) 7190 << SR; 7191 return None; 7192 } 7193 // Adjust the function type to account for an extra omp_interop_t for each 7194 // specified in the append_args clause. 7195 const TypeDecl *TD = nullptr; 7196 LookupResult Result(*this, &Context.Idents.get("omp_interop_t"), 7197 SR.getBegin(), Sema::LookupOrdinaryName); 7198 if (LookupName(Result, getCurScope())) { 7199 NamedDecl *ND = Result.getFoundDecl(); 7200 TD = dyn_cast_or_null<TypeDecl>(ND); 7201 } 7202 if (!TD) { 7203 Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR; 7204 return None; 7205 } 7206 QualType InteropType = Context.getTypeDeclType(TD); 7207 if (PTy->isVariadic()) { 7208 Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR; 7209 return None; 7210 } 7211 llvm::SmallVector<QualType, 8> Params; 7212 Params.append(PTy->param_type_begin(), PTy->param_type_end()); 7213 Params.insert(Params.end(), NumAppendArgs, InteropType); 7214 AdjustedFnType = Context.getFunctionType(PTy->getReturnType(), Params, 7215 PTy->getExtProtoInfo()); 7216 } 7217 7218 // Convert VariantRef expression to the type of the original function to 7219 // resolve possible conflicts. 7220 ExprResult VariantRefCast = VariantRef; 7221 if (LangOpts.CPlusPlus) { 7222 QualType FnPtrType; 7223 auto *Method = dyn_cast<CXXMethodDecl>(FD); 7224 if (Method && !Method->isStatic()) { 7225 const Type *ClassType = 7226 Context.getTypeDeclType(Method->getParent()).getTypePtr(); 7227 FnPtrType = Context.getMemberPointerType(AdjustedFnType, ClassType); 7228 ExprResult ER; 7229 { 7230 // Build adrr_of unary op to correctly handle type checks for member 7231 // functions. 7232 Sema::TentativeAnalysisScope Trap(*this); 7233 ER = CreateBuiltinUnaryOp(VariantRef->getBeginLoc(), UO_AddrOf, 7234 VariantRef); 7235 } 7236 if (!ER.isUsable()) { 7237 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7238 << VariantId << VariantRef->getSourceRange(); 7239 return None; 7240 } 7241 VariantRef = ER.get(); 7242 } else { 7243 FnPtrType = Context.getPointerType(AdjustedFnType); 7244 } 7245 QualType VarianPtrType = Context.getPointerType(VariantRef->getType()); 7246 if (VarianPtrType.getUnqualifiedType() != FnPtrType.getUnqualifiedType()) { 7247 ImplicitConversionSequence ICS = TryImplicitConversion( 7248 VariantRef, FnPtrType.getUnqualifiedType(), 7249 /*SuppressUserConversions=*/false, AllowedExplicit::None, 7250 /*InOverloadResolution=*/false, 7251 /*CStyle=*/false, 7252 /*AllowObjCWritebackConversion=*/false); 7253 if (ICS.isFailure()) { 7254 Diag(VariantRef->getExprLoc(), 7255 diag::err_omp_declare_variant_incompat_types) 7256 << VariantRef->getType() 7257 << ((Method && !Method->isStatic()) ? FnPtrType : FD->getType()) 7258 << (NumAppendArgs ? 1 : 0) << VariantRef->getSourceRange(); 7259 return None; 7260 } 7261 VariantRefCast = PerformImplicitConversion( 7262 VariantRef, FnPtrType.getUnqualifiedType(), AA_Converting); 7263 if (!VariantRefCast.isUsable()) 7264 return None; 7265 } 7266 // Drop previously built artificial addr_of unary op for member functions. 7267 if (Method && !Method->isStatic()) { 7268 Expr *PossibleAddrOfVariantRef = VariantRefCast.get(); 7269 if (auto *UO = dyn_cast<UnaryOperator>( 7270 PossibleAddrOfVariantRef->IgnoreImplicit())) 7271 VariantRefCast = UO->getSubExpr(); 7272 } 7273 } 7274 7275 ExprResult ER = CheckPlaceholderExpr(VariantRefCast.get()); 7276 if (!ER.isUsable() || 7277 !ER.get()->IgnoreParenImpCasts()->getType()->isFunctionType()) { 7278 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7279 << VariantId << VariantRef->getSourceRange(); 7280 return None; 7281 } 7282 7283 // The VariantRef must point to function. 7284 auto *DRE = dyn_cast<DeclRefExpr>(ER.get()->IgnoreParenImpCasts()); 7285 if (!DRE) { 7286 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7287 << VariantId << VariantRef->getSourceRange(); 7288 return None; 7289 } 7290 auto *NewFD = dyn_cast_or_null<FunctionDecl>(DRE->getDecl()); 7291 if (!NewFD) { 7292 Diag(VariantRef->getExprLoc(), diag::err_omp_function_expected) 7293 << VariantId << VariantRef->getSourceRange(); 7294 return None; 7295 } 7296 7297 if (FD->getCanonicalDecl() == NewFD->getCanonicalDecl()) { 7298 Diag(VariantRef->getExprLoc(), 7299 diag::err_omp_declare_variant_same_base_function) 7300 << VariantRef->getSourceRange(); 7301 return None; 7302 } 7303 7304 // Check if function types are compatible in C. 7305 if (!LangOpts.CPlusPlus) { 7306 QualType NewType = 7307 Context.mergeFunctionTypes(AdjustedFnType, NewFD->getType()); 7308 if (NewType.isNull()) { 7309 Diag(VariantRef->getExprLoc(), 7310 diag::err_omp_declare_variant_incompat_types) 7311 << NewFD->getType() << FD->getType() << (NumAppendArgs ? 1 : 0) 7312 << VariantRef->getSourceRange(); 7313 return None; 7314 } 7315 if (NewType->isFunctionProtoType()) { 7316 if (FD->getType()->isFunctionNoProtoType()) 7317 setPrototype(*this, FD, NewFD, NewType); 7318 else if (NewFD->getType()->isFunctionNoProtoType()) 7319 setPrototype(*this, NewFD, FD, NewType); 7320 } 7321 } 7322 7323 // Check if variant function is not marked with declare variant directive. 7324 if (NewFD->hasAttrs() && NewFD->hasAttr<OMPDeclareVariantAttr>()) { 7325 Diag(VariantRef->getExprLoc(), 7326 diag::warn_omp_declare_variant_marked_as_declare_variant) 7327 << VariantRef->getSourceRange(); 7328 SourceRange SR = 7329 NewFD->specific_attr_begin<OMPDeclareVariantAttr>()->getRange(); 7330 Diag(SR.getBegin(), diag::note_omp_marked_declare_variant_here) << SR; 7331 return None; 7332 } 7333 7334 enum DoesntSupport { 7335 VirtFuncs = 1, 7336 Constructors = 3, 7337 Destructors = 4, 7338 DeletedFuncs = 5, 7339 DefaultedFuncs = 6, 7340 ConstexprFuncs = 7, 7341 ConstevalFuncs = 8, 7342 }; 7343 if (const auto *CXXFD = dyn_cast<CXXMethodDecl>(FD)) { 7344 if (CXXFD->isVirtual()) { 7345 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7346 << VirtFuncs; 7347 return None; 7348 } 7349 7350 if (isa<CXXConstructorDecl>(FD)) { 7351 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7352 << Constructors; 7353 return None; 7354 } 7355 7356 if (isa<CXXDestructorDecl>(FD)) { 7357 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7358 << Destructors; 7359 return None; 7360 } 7361 } 7362 7363 if (FD->isDeleted()) { 7364 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7365 << DeletedFuncs; 7366 return None; 7367 } 7368 7369 if (FD->isDefaulted()) { 7370 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7371 << DefaultedFuncs; 7372 return None; 7373 } 7374 7375 if (FD->isConstexpr()) { 7376 Diag(FD->getLocation(), diag::err_omp_declare_variant_doesnt_support) 7377 << (NewFD->isConsteval() ? ConstevalFuncs : ConstexprFuncs); 7378 return None; 7379 } 7380 7381 // Check general compatibility. 7382 if (areMultiversionVariantFunctionsCompatible( 7383 FD, NewFD, PartialDiagnostic::NullDiagnostic(), 7384 PartialDiagnosticAt(SourceLocation(), 7385 PartialDiagnostic::NullDiagnostic()), 7386 PartialDiagnosticAt( 7387 VariantRef->getExprLoc(), 7388 PDiag(diag::err_omp_declare_variant_doesnt_support)), 7389 PartialDiagnosticAt(VariantRef->getExprLoc(), 7390 PDiag(diag::err_omp_declare_variant_diff) 7391 << FD->getLocation()), 7392 /*TemplatesSupported=*/true, /*ConstexprSupported=*/false, 7393 /*CLinkageMayDiffer=*/true)) 7394 return None; 7395 return std::make_pair(FD, cast<Expr>(DRE)); 7396 } 7397 7398 void Sema::ActOnOpenMPDeclareVariantDirective( 7399 FunctionDecl *FD, Expr *VariantRef, OMPTraitInfo &TI, 7400 ArrayRef<Expr *> AdjustArgsNothing, 7401 ArrayRef<Expr *> AdjustArgsNeedDevicePtr, 7402 ArrayRef<OMPDeclareVariantAttr::InteropType> AppendArgs, 7403 SourceLocation AdjustArgsLoc, SourceLocation AppendArgsLoc, 7404 SourceRange SR) { 7405 7406 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions] 7407 // An adjust_args clause or append_args clause can only be specified if the 7408 // dispatch selector of the construct selector set appears in the match 7409 // clause. 7410 7411 SmallVector<Expr *, 8> AllAdjustArgs; 7412 llvm::append_range(AllAdjustArgs, AdjustArgsNothing); 7413 llvm::append_range(AllAdjustArgs, AdjustArgsNeedDevicePtr); 7414 7415 if (!AllAdjustArgs.empty() || !AppendArgs.empty()) { 7416 VariantMatchInfo VMI; 7417 TI.getAsVariantMatchInfo(Context, VMI); 7418 if (!llvm::is_contained( 7419 VMI.ConstructTraits, 7420 llvm::omp::TraitProperty::construct_dispatch_dispatch)) { 7421 if (!AllAdjustArgs.empty()) 7422 Diag(AdjustArgsLoc, diag::err_omp_clause_requires_dispatch_construct) 7423 << getOpenMPClauseName(OMPC_adjust_args); 7424 if (!AppendArgs.empty()) 7425 Diag(AppendArgsLoc, diag::err_omp_clause_requires_dispatch_construct) 7426 << getOpenMPClauseName(OMPC_append_args); 7427 return; 7428 } 7429 } 7430 7431 // OpenMP 5.1 [2.3.5, declare variant directive, Restrictions] 7432 // Each argument can only appear in a single adjust_args clause for each 7433 // declare variant directive. 7434 llvm::SmallPtrSet<const VarDecl *, 4> AdjustVars; 7435 7436 for (Expr *E : AllAdjustArgs) { 7437 E = E->IgnoreParenImpCasts(); 7438 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) { 7439 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 7440 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 7441 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 7442 FD->getParamDecl(PVD->getFunctionScopeIndex()) 7443 ->getCanonicalDecl() == CanonPVD) { 7444 // It's a parameter of the function, check duplicates. 7445 if (!AdjustVars.insert(CanonPVD).second) { 7446 Diag(DRE->getLocation(), diag::err_omp_adjust_arg_multiple_clauses) 7447 << PVD; 7448 return; 7449 } 7450 continue; 7451 } 7452 } 7453 } 7454 // Anything that is not a function parameter is an error. 7455 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) << FD << 0; 7456 return; 7457 } 7458 7459 auto *NewAttr = OMPDeclareVariantAttr::CreateImplicit( 7460 Context, VariantRef, &TI, const_cast<Expr **>(AdjustArgsNothing.data()), 7461 AdjustArgsNothing.size(), 7462 const_cast<Expr **>(AdjustArgsNeedDevicePtr.data()), 7463 AdjustArgsNeedDevicePtr.size(), 7464 const_cast<OMPDeclareVariantAttr::InteropType *>(AppendArgs.data()), 7465 AppendArgs.size(), SR); 7466 FD->addAttr(NewAttr); 7467 } 7468 7469 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 7470 Stmt *AStmt, 7471 SourceLocation StartLoc, 7472 SourceLocation EndLoc) { 7473 if (!AStmt) 7474 return StmtError(); 7475 7476 auto *CS = cast<CapturedStmt>(AStmt); 7477 // 1.2.2 OpenMP Language Terminology 7478 // Structured block - An executable statement with a single entry at the 7479 // top and a single exit at the bottom. 7480 // The point of exit cannot be a branch out of the structured block. 7481 // longjmp() and throw() must not violate the entry/exit criteria. 7482 CS->getCapturedDecl()->setNothrow(); 7483 7484 setFunctionHasBranchProtectedScope(); 7485 7486 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7487 DSAStack->getTaskgroupReductionRef(), 7488 DSAStack->isCancelRegion()); 7489 } 7490 7491 namespace { 7492 /// Iteration space of a single for loop. 7493 struct LoopIterationSpace final { 7494 /// True if the condition operator is the strict compare operator (<, > or 7495 /// !=). 7496 bool IsStrictCompare = false; 7497 /// Condition of the loop. 7498 Expr *PreCond = nullptr; 7499 /// This expression calculates the number of iterations in the loop. 7500 /// It is always possible to calculate it before starting the loop. 7501 Expr *NumIterations = nullptr; 7502 /// The loop counter variable. 7503 Expr *CounterVar = nullptr; 7504 /// Private loop counter variable. 7505 Expr *PrivateCounterVar = nullptr; 7506 /// This is initializer for the initial value of #CounterVar. 7507 Expr *CounterInit = nullptr; 7508 /// This is step for the #CounterVar used to generate its update: 7509 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 7510 Expr *CounterStep = nullptr; 7511 /// Should step be subtracted? 7512 bool Subtract = false; 7513 /// Source range of the loop init. 7514 SourceRange InitSrcRange; 7515 /// Source range of the loop condition. 7516 SourceRange CondSrcRange; 7517 /// Source range of the loop increment. 7518 SourceRange IncSrcRange; 7519 /// Minimum value that can have the loop control variable. Used to support 7520 /// non-rectangular loops. Applied only for LCV with the non-iterator types, 7521 /// since only such variables can be used in non-loop invariant expressions. 7522 Expr *MinValue = nullptr; 7523 /// Maximum value that can have the loop control variable. Used to support 7524 /// non-rectangular loops. Applied only for LCV with the non-iterator type, 7525 /// since only such variables can be used in non-loop invariant expressions. 7526 Expr *MaxValue = nullptr; 7527 /// true, if the lower bound depends on the outer loop control var. 7528 bool IsNonRectangularLB = false; 7529 /// true, if the upper bound depends on the outer loop control var. 7530 bool IsNonRectangularUB = false; 7531 /// Index of the loop this loop depends on and forms non-rectangular loop 7532 /// nest. 7533 unsigned LoopDependentIdx = 0; 7534 /// Final condition for the non-rectangular loop nest support. It is used to 7535 /// check that the number of iterations for this particular counter must be 7536 /// finished. 7537 Expr *FinalCondition = nullptr; 7538 }; 7539 7540 /// Helper class for checking canonical form of the OpenMP loops and 7541 /// extracting iteration space of each loop in the loop nest, that will be used 7542 /// for IR generation. 7543 class OpenMPIterationSpaceChecker { 7544 /// Reference to Sema. 7545 Sema &SemaRef; 7546 /// Does the loop associated directive support non-rectangular loops? 7547 bool SupportsNonRectangular; 7548 /// Data-sharing stack. 7549 DSAStackTy &Stack; 7550 /// A location for diagnostics (when there is no some better location). 7551 SourceLocation DefaultLoc; 7552 /// A location for diagnostics (when increment is not compatible). 7553 SourceLocation ConditionLoc; 7554 /// A source location for referring to loop init later. 7555 SourceRange InitSrcRange; 7556 /// A source location for referring to condition later. 7557 SourceRange ConditionSrcRange; 7558 /// A source location for referring to increment later. 7559 SourceRange IncrementSrcRange; 7560 /// Loop variable. 7561 ValueDecl *LCDecl = nullptr; 7562 /// Reference to loop variable. 7563 Expr *LCRef = nullptr; 7564 /// Lower bound (initializer for the var). 7565 Expr *LB = nullptr; 7566 /// Upper bound. 7567 Expr *UB = nullptr; 7568 /// Loop step (increment). 7569 Expr *Step = nullptr; 7570 /// This flag is true when condition is one of: 7571 /// Var < UB 7572 /// Var <= UB 7573 /// UB > Var 7574 /// UB >= Var 7575 /// This will have no value when the condition is != 7576 llvm::Optional<bool> TestIsLessOp; 7577 /// This flag is true when condition is strict ( < or > ). 7578 bool TestIsStrictOp = false; 7579 /// This flag is true when step is subtracted on each iteration. 7580 bool SubtractStep = false; 7581 /// The outer loop counter this loop depends on (if any). 7582 const ValueDecl *DepDecl = nullptr; 7583 /// Contains number of loop (starts from 1) on which loop counter init 7584 /// expression of this loop depends on. 7585 Optional<unsigned> InitDependOnLC; 7586 /// Contains number of loop (starts from 1) on which loop counter condition 7587 /// expression of this loop depends on. 7588 Optional<unsigned> CondDependOnLC; 7589 /// Checks if the provide statement depends on the loop counter. 7590 Optional<unsigned> doesDependOnLoopCounter(const Stmt *S, bool IsInitializer); 7591 /// Original condition required for checking of the exit condition for 7592 /// non-rectangular loop. 7593 Expr *Condition = nullptr; 7594 7595 public: 7596 OpenMPIterationSpaceChecker(Sema &SemaRef, bool SupportsNonRectangular, 7597 DSAStackTy &Stack, SourceLocation DefaultLoc) 7598 : SemaRef(SemaRef), SupportsNonRectangular(SupportsNonRectangular), 7599 Stack(Stack), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 7600 /// Check init-expr for canonical loop form and save loop counter 7601 /// variable - #Var and its initialization value - #LB. 7602 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 7603 /// Check test-expr for canonical form, save upper-bound (#UB), flags 7604 /// for less/greater and for strict/non-strict comparison. 7605 bool checkAndSetCond(Expr *S); 7606 /// Check incr-expr for canonical loop form and return true if it 7607 /// does not conform, otherwise save loop step (#Step). 7608 bool checkAndSetInc(Expr *S); 7609 /// Return the loop counter variable. 7610 ValueDecl *getLoopDecl() const { return LCDecl; } 7611 /// Return the reference expression to loop counter variable. 7612 Expr *getLoopDeclRefExpr() const { return LCRef; } 7613 /// Source range of the loop init. 7614 SourceRange getInitSrcRange() const { return InitSrcRange; } 7615 /// Source range of the loop condition. 7616 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 7617 /// Source range of the loop increment. 7618 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 7619 /// True if the step should be subtracted. 7620 bool shouldSubtractStep() const { return SubtractStep; } 7621 /// True, if the compare operator is strict (<, > or !=). 7622 bool isStrictTestOp() const { return TestIsStrictOp; } 7623 /// Build the expression to calculate the number of iterations. 7624 Expr *buildNumIterations( 7625 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 7626 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7627 /// Build the precondition expression for the loops. 7628 Expr * 7629 buildPreCond(Scope *S, Expr *Cond, 7630 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7631 /// Build reference expression to the counter be used for codegen. 7632 DeclRefExpr * 7633 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7634 DSAStackTy &DSA) const; 7635 /// Build reference expression to the private counter be used for 7636 /// codegen. 7637 Expr *buildPrivateCounterVar() const; 7638 /// Build initialization of the counter be used for codegen. 7639 Expr *buildCounterInit() const; 7640 /// Build step of the counter be used for codegen. 7641 Expr *buildCounterStep() const; 7642 /// Build loop data with counter value for depend clauses in ordered 7643 /// directives. 7644 Expr * 7645 buildOrderedLoopData(Scope *S, Expr *Counter, 7646 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 7647 SourceLocation Loc, Expr *Inc = nullptr, 7648 OverloadedOperatorKind OOK = OO_Amp); 7649 /// Builds the minimum value for the loop counter. 7650 std::pair<Expr *, Expr *> buildMinMaxValues( 7651 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 7652 /// Builds final condition for the non-rectangular loops. 7653 Expr *buildFinalCondition(Scope *S) const; 7654 /// Return true if any expression is dependent. 7655 bool dependent() const; 7656 /// Returns true if the initializer forms non-rectangular loop. 7657 bool doesInitDependOnLC() const { return InitDependOnLC.hasValue(); } 7658 /// Returns true if the condition forms non-rectangular loop. 7659 bool doesCondDependOnLC() const { return CondDependOnLC.hasValue(); } 7660 /// Returns index of the loop we depend on (starting from 1), or 0 otherwise. 7661 unsigned getLoopDependentIdx() const { 7662 return InitDependOnLC.value_or(CondDependOnLC.value_or(0)); 7663 } 7664 7665 private: 7666 /// Check the right-hand side of an assignment in the increment 7667 /// expression. 7668 bool checkAndSetIncRHS(Expr *RHS); 7669 /// Helper to set loop counter variable and its initializer. 7670 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB, 7671 bool EmitDiags); 7672 /// Helper to set upper bound. 7673 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 7674 SourceRange SR, SourceLocation SL); 7675 /// Helper to set loop increment. 7676 bool setStep(Expr *NewStep, bool Subtract); 7677 }; 7678 7679 bool OpenMPIterationSpaceChecker::dependent() const { 7680 if (!LCDecl) { 7681 assert(!LB && !UB && !Step); 7682 return false; 7683 } 7684 return LCDecl->getType()->isDependentType() || 7685 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 7686 (Step && Step->isValueDependent()); 7687 } 7688 7689 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 7690 Expr *NewLCRefExpr, 7691 Expr *NewLB, bool EmitDiags) { 7692 // State consistency checking to ensure correct usage. 7693 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 7694 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 7695 if (!NewLCDecl || !NewLB || NewLB->containsErrors()) 7696 return true; 7697 LCDecl = getCanonicalDecl(NewLCDecl); 7698 LCRef = NewLCRefExpr; 7699 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 7700 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 7701 if ((Ctor->isCopyOrMoveConstructor() || 7702 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 7703 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 7704 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 7705 LB = NewLB; 7706 if (EmitDiags) 7707 InitDependOnLC = doesDependOnLoopCounter(LB, /*IsInitializer=*/true); 7708 return false; 7709 } 7710 7711 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 7712 llvm::Optional<bool> LessOp, 7713 bool StrictOp, SourceRange SR, 7714 SourceLocation SL) { 7715 // State consistency checking to ensure correct usage. 7716 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 7717 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 7718 if (!NewUB || NewUB->containsErrors()) 7719 return true; 7720 UB = NewUB; 7721 if (LessOp) 7722 TestIsLessOp = LessOp; 7723 TestIsStrictOp = StrictOp; 7724 ConditionSrcRange = SR; 7725 ConditionLoc = SL; 7726 CondDependOnLC = doesDependOnLoopCounter(UB, /*IsInitializer=*/false); 7727 return false; 7728 } 7729 7730 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 7731 // State consistency checking to ensure correct usage. 7732 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 7733 if (!NewStep || NewStep->containsErrors()) 7734 return true; 7735 if (!NewStep->isValueDependent()) { 7736 // Check that the step is integer expression. 7737 SourceLocation StepLoc = NewStep->getBeginLoc(); 7738 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 7739 StepLoc, getExprAsWritten(NewStep)); 7740 if (Val.isInvalid()) 7741 return true; 7742 NewStep = Val.get(); 7743 7744 // OpenMP [2.6, Canonical Loop Form, Restrictions] 7745 // If test-expr is of form var relational-op b and relational-op is < or 7746 // <= then incr-expr must cause var to increase on each iteration of the 7747 // loop. If test-expr is of form var relational-op b and relational-op is 7748 // > or >= then incr-expr must cause var to decrease on each iteration of 7749 // the loop. 7750 // If test-expr is of form b relational-op var and relational-op is < or 7751 // <= then incr-expr must cause var to decrease on each iteration of the 7752 // loop. If test-expr is of form b relational-op var and relational-op is 7753 // > or >= then incr-expr must cause var to increase on each iteration of 7754 // the loop. 7755 Optional<llvm::APSInt> Result = 7756 NewStep->getIntegerConstantExpr(SemaRef.Context); 7757 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 7758 bool IsConstNeg = 7759 Result && Result->isSigned() && (Subtract != Result->isNegative()); 7760 bool IsConstPos = 7761 Result && Result->isSigned() && (Subtract == Result->isNegative()); 7762 bool IsConstZero = Result && !Result->getBoolValue(); 7763 7764 // != with increment is treated as <; != with decrement is treated as > 7765 if (!TestIsLessOp) 7766 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 7767 if (UB && 7768 (IsConstZero || (TestIsLessOp.getValue() 7769 ? (IsConstNeg || (IsUnsigned && Subtract)) 7770 : (IsConstPos || (IsUnsigned && !Subtract))))) { 7771 SemaRef.Diag(NewStep->getExprLoc(), 7772 diag::err_omp_loop_incr_not_compatible) 7773 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 7774 SemaRef.Diag(ConditionLoc, 7775 diag::note_omp_loop_cond_requres_compatible_incr) 7776 << TestIsLessOp.getValue() << ConditionSrcRange; 7777 return true; 7778 } 7779 if (TestIsLessOp.getValue() == Subtract) { 7780 NewStep = 7781 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 7782 .get(); 7783 Subtract = !Subtract; 7784 } 7785 } 7786 7787 Step = NewStep; 7788 SubtractStep = Subtract; 7789 return false; 7790 } 7791 7792 namespace { 7793 /// Checker for the non-rectangular loops. Checks if the initializer or 7794 /// condition expression references loop counter variable. 7795 class LoopCounterRefChecker final 7796 : public ConstStmtVisitor<LoopCounterRefChecker, bool> { 7797 Sema &SemaRef; 7798 DSAStackTy &Stack; 7799 const ValueDecl *CurLCDecl = nullptr; 7800 const ValueDecl *DepDecl = nullptr; 7801 const ValueDecl *PrevDepDecl = nullptr; 7802 bool IsInitializer = true; 7803 bool SupportsNonRectangular; 7804 unsigned BaseLoopId = 0; 7805 bool checkDecl(const Expr *E, const ValueDecl *VD) { 7806 if (getCanonicalDecl(VD) == getCanonicalDecl(CurLCDecl)) { 7807 SemaRef.Diag(E->getExprLoc(), diag::err_omp_stmt_depends_on_loop_counter) 7808 << (IsInitializer ? 0 : 1); 7809 return false; 7810 } 7811 const auto &&Data = Stack.isLoopControlVariable(VD); 7812 // OpenMP, 2.9.1 Canonical Loop Form, Restrictions. 7813 // The type of the loop iterator on which we depend may not have a random 7814 // access iterator type. 7815 if (Data.first && VD->getType()->isRecordType()) { 7816 SmallString<128> Name; 7817 llvm::raw_svector_ostream OS(Name); 7818 VD->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 7819 /*Qualified=*/true); 7820 SemaRef.Diag(E->getExprLoc(), 7821 diag::err_omp_wrong_dependency_iterator_type) 7822 << OS.str(); 7823 SemaRef.Diag(VD->getLocation(), diag::note_previous_decl) << VD; 7824 return false; 7825 } 7826 if (Data.first && !SupportsNonRectangular) { 7827 SemaRef.Diag(E->getExprLoc(), diag::err_omp_invariant_dependency); 7828 return false; 7829 } 7830 if (Data.first && 7831 (DepDecl || (PrevDepDecl && 7832 getCanonicalDecl(VD) != getCanonicalDecl(PrevDepDecl)))) { 7833 if (!DepDecl && PrevDepDecl) 7834 DepDecl = PrevDepDecl; 7835 SmallString<128> Name; 7836 llvm::raw_svector_ostream OS(Name); 7837 DepDecl->getNameForDiagnostic(OS, SemaRef.getPrintingPolicy(), 7838 /*Qualified=*/true); 7839 SemaRef.Diag(E->getExprLoc(), 7840 diag::err_omp_invariant_or_linear_dependency) 7841 << OS.str(); 7842 return false; 7843 } 7844 if (Data.first) { 7845 DepDecl = VD; 7846 BaseLoopId = Data.first; 7847 } 7848 return Data.first; 7849 } 7850 7851 public: 7852 bool VisitDeclRefExpr(const DeclRefExpr *E) { 7853 const ValueDecl *VD = E->getDecl(); 7854 if (isa<VarDecl>(VD)) 7855 return checkDecl(E, VD); 7856 return false; 7857 } 7858 bool VisitMemberExpr(const MemberExpr *E) { 7859 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 7860 const ValueDecl *VD = E->getMemberDecl(); 7861 if (isa<VarDecl>(VD) || isa<FieldDecl>(VD)) 7862 return checkDecl(E, VD); 7863 } 7864 return false; 7865 } 7866 bool VisitStmt(const Stmt *S) { 7867 bool Res = false; 7868 for (const Stmt *Child : S->children()) 7869 Res = (Child && Visit(Child)) || Res; 7870 return Res; 7871 } 7872 explicit LoopCounterRefChecker(Sema &SemaRef, DSAStackTy &Stack, 7873 const ValueDecl *CurLCDecl, bool IsInitializer, 7874 const ValueDecl *PrevDepDecl = nullptr, 7875 bool SupportsNonRectangular = true) 7876 : SemaRef(SemaRef), Stack(Stack), CurLCDecl(CurLCDecl), 7877 PrevDepDecl(PrevDepDecl), IsInitializer(IsInitializer), 7878 SupportsNonRectangular(SupportsNonRectangular) {} 7879 unsigned getBaseLoopId() const { 7880 assert(CurLCDecl && "Expected loop dependency."); 7881 return BaseLoopId; 7882 } 7883 const ValueDecl *getDepDecl() const { 7884 assert(CurLCDecl && "Expected loop dependency."); 7885 return DepDecl; 7886 } 7887 }; 7888 } // namespace 7889 7890 Optional<unsigned> 7891 OpenMPIterationSpaceChecker::doesDependOnLoopCounter(const Stmt *S, 7892 bool IsInitializer) { 7893 // Check for the non-rectangular loops. 7894 LoopCounterRefChecker LoopStmtChecker(SemaRef, Stack, LCDecl, IsInitializer, 7895 DepDecl, SupportsNonRectangular); 7896 if (LoopStmtChecker.Visit(S)) { 7897 DepDecl = LoopStmtChecker.getDepDecl(); 7898 return LoopStmtChecker.getBaseLoopId(); 7899 } 7900 return llvm::None; 7901 } 7902 7903 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 7904 // Check init-expr for canonical loop form and save loop counter 7905 // variable - #Var and its initialization value - #LB. 7906 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 7907 // var = lb 7908 // integer-type var = lb 7909 // random-access-iterator-type var = lb 7910 // pointer-type var = lb 7911 // 7912 if (!S) { 7913 if (EmitDiags) { 7914 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 7915 } 7916 return true; 7917 } 7918 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 7919 if (!ExprTemp->cleanupsHaveSideEffects()) 7920 S = ExprTemp->getSubExpr(); 7921 7922 InitSrcRange = S->getSourceRange(); 7923 if (Expr *E = dyn_cast<Expr>(S)) 7924 S = E->IgnoreParens(); 7925 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 7926 if (BO->getOpcode() == BO_Assign) { 7927 Expr *LHS = BO->getLHS()->IgnoreParens(); 7928 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 7929 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 7930 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 7931 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7932 EmitDiags); 7933 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS(), EmitDiags); 7934 } 7935 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 7936 if (ME->isArrow() && 7937 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 7938 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7939 EmitDiags); 7940 } 7941 } 7942 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 7943 if (DS->isSingleDecl()) { 7944 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 7945 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 7946 // Accept non-canonical init form here but emit ext. warning. 7947 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 7948 SemaRef.Diag(S->getBeginLoc(), 7949 diag::ext_omp_loop_not_canonical_init) 7950 << S->getSourceRange(); 7951 return setLCDeclAndLB( 7952 Var, 7953 buildDeclRefExpr(SemaRef, Var, 7954 Var->getType().getNonReferenceType(), 7955 DS->getBeginLoc()), 7956 Var->getInit(), EmitDiags); 7957 } 7958 } 7959 } 7960 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 7961 if (CE->getOperator() == OO_Equal) { 7962 Expr *LHS = CE->getArg(0); 7963 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 7964 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 7965 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 7966 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7967 EmitDiags); 7968 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1), EmitDiags); 7969 } 7970 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 7971 if (ME->isArrow() && 7972 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 7973 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS(), 7974 EmitDiags); 7975 } 7976 } 7977 } 7978 7979 if (dependent() || SemaRef.CurContext->isDependentContext()) 7980 return false; 7981 if (EmitDiags) { 7982 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 7983 << S->getSourceRange(); 7984 } 7985 return true; 7986 } 7987 7988 /// Ignore parenthesizes, implicit casts, copy constructor and return the 7989 /// variable (which may be the loop variable) if possible. 7990 static const ValueDecl *getInitLCDecl(const Expr *E) { 7991 if (!E) 7992 return nullptr; 7993 E = getExprAsWritten(E); 7994 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 7995 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 7996 if ((Ctor->isCopyOrMoveConstructor() || 7997 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 7998 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 7999 E = CE->getArg(0)->IgnoreParenImpCasts(); 8000 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 8001 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 8002 return getCanonicalDecl(VD); 8003 } 8004 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 8005 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 8006 return getCanonicalDecl(ME->getMemberDecl()); 8007 return nullptr; 8008 } 8009 8010 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 8011 // Check test-expr for canonical form, save upper-bound UB, flags for 8012 // less/greater and for strict/non-strict comparison. 8013 // OpenMP [2.9] Canonical loop form. Test-expr may be one of the following: 8014 // var relational-op b 8015 // b relational-op var 8016 // 8017 bool IneqCondIsCanonical = SemaRef.getLangOpts().OpenMP >= 50; 8018 if (!S) { 8019 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) 8020 << (IneqCondIsCanonical ? 1 : 0) << LCDecl; 8021 return true; 8022 } 8023 Condition = S; 8024 S = getExprAsWritten(S); 8025 SourceLocation CondLoc = S->getBeginLoc(); 8026 auto &&CheckAndSetCond = [this, IneqCondIsCanonical]( 8027 BinaryOperatorKind Opcode, const Expr *LHS, 8028 const Expr *RHS, SourceRange SR, 8029 SourceLocation OpLoc) -> llvm::Optional<bool> { 8030 if (BinaryOperator::isRelationalOp(Opcode)) { 8031 if (getInitLCDecl(LHS) == LCDecl) 8032 return setUB(const_cast<Expr *>(RHS), 8033 (Opcode == BO_LT || Opcode == BO_LE), 8034 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc); 8035 if (getInitLCDecl(RHS) == LCDecl) 8036 return setUB(const_cast<Expr *>(LHS), 8037 (Opcode == BO_GT || Opcode == BO_GE), 8038 (Opcode == BO_LT || Opcode == BO_GT), SR, OpLoc); 8039 } else if (IneqCondIsCanonical && Opcode == BO_NE) { 8040 return setUB(const_cast<Expr *>(getInitLCDecl(LHS) == LCDecl ? RHS : LHS), 8041 /*LessOp=*/llvm::None, 8042 /*StrictOp=*/true, SR, OpLoc); 8043 } 8044 return llvm::None; 8045 }; 8046 llvm::Optional<bool> Res; 8047 if (auto *RBO = dyn_cast<CXXRewrittenBinaryOperator>(S)) { 8048 CXXRewrittenBinaryOperator::DecomposedForm DF = RBO->getDecomposedForm(); 8049 Res = CheckAndSetCond(DF.Opcode, DF.LHS, DF.RHS, RBO->getSourceRange(), 8050 RBO->getOperatorLoc()); 8051 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8052 Res = CheckAndSetCond(BO->getOpcode(), BO->getLHS(), BO->getRHS(), 8053 BO->getSourceRange(), BO->getOperatorLoc()); 8054 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8055 if (CE->getNumArgs() == 2) { 8056 Res = CheckAndSetCond( 8057 BinaryOperator::getOverloadedOpcode(CE->getOperator()), CE->getArg(0), 8058 CE->getArg(1), CE->getSourceRange(), CE->getOperatorLoc()); 8059 } 8060 } 8061 if (Res) 8062 return *Res; 8063 if (dependent() || SemaRef.CurContext->isDependentContext()) 8064 return false; 8065 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 8066 << (IneqCondIsCanonical ? 1 : 0) << S->getSourceRange() << LCDecl; 8067 return true; 8068 } 8069 8070 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 8071 // RHS of canonical loop form increment can be: 8072 // var + incr 8073 // incr + var 8074 // var - incr 8075 // 8076 RHS = RHS->IgnoreParenImpCasts(); 8077 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 8078 if (BO->isAdditiveOp()) { 8079 bool IsAdd = BO->getOpcode() == BO_Add; 8080 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8081 return setStep(BO->getRHS(), !IsAdd); 8082 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 8083 return setStep(BO->getLHS(), /*Subtract=*/false); 8084 } 8085 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 8086 bool IsAdd = CE->getOperator() == OO_Plus; 8087 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 8088 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8089 return setStep(CE->getArg(1), !IsAdd); 8090 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 8091 return setStep(CE->getArg(0), /*Subtract=*/false); 8092 } 8093 } 8094 if (dependent() || SemaRef.CurContext->isDependentContext()) 8095 return false; 8096 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 8097 << RHS->getSourceRange() << LCDecl; 8098 return true; 8099 } 8100 8101 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 8102 // Check incr-expr for canonical loop form and return true if it 8103 // does not conform. 8104 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 8105 // ++var 8106 // var++ 8107 // --var 8108 // var-- 8109 // var += incr 8110 // var -= incr 8111 // var = var + incr 8112 // var = incr + var 8113 // var = var - incr 8114 // 8115 if (!S) { 8116 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 8117 return true; 8118 } 8119 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 8120 if (!ExprTemp->cleanupsHaveSideEffects()) 8121 S = ExprTemp->getSubExpr(); 8122 8123 IncrementSrcRange = S->getSourceRange(); 8124 S = S->IgnoreParens(); 8125 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 8126 if (UO->isIncrementDecrementOp() && 8127 getInitLCDecl(UO->getSubExpr()) == LCDecl) 8128 return setStep(SemaRef 8129 .ActOnIntegerConstant(UO->getBeginLoc(), 8130 (UO->isDecrementOp() ? -1 : 1)) 8131 .get(), 8132 /*Subtract=*/false); 8133 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 8134 switch (BO->getOpcode()) { 8135 case BO_AddAssign: 8136 case BO_SubAssign: 8137 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8138 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 8139 break; 8140 case BO_Assign: 8141 if (getInitLCDecl(BO->getLHS()) == LCDecl) 8142 return checkAndSetIncRHS(BO->getRHS()); 8143 break; 8144 default: 8145 break; 8146 } 8147 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 8148 switch (CE->getOperator()) { 8149 case OO_PlusPlus: 8150 case OO_MinusMinus: 8151 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8152 return setStep(SemaRef 8153 .ActOnIntegerConstant( 8154 CE->getBeginLoc(), 8155 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 8156 .get(), 8157 /*Subtract=*/false); 8158 break; 8159 case OO_PlusEqual: 8160 case OO_MinusEqual: 8161 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8162 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 8163 break; 8164 case OO_Equal: 8165 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 8166 return checkAndSetIncRHS(CE->getArg(1)); 8167 break; 8168 default: 8169 break; 8170 } 8171 } 8172 if (dependent() || SemaRef.CurContext->isDependentContext()) 8173 return false; 8174 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 8175 << S->getSourceRange() << LCDecl; 8176 return true; 8177 } 8178 8179 static ExprResult 8180 tryBuildCapture(Sema &SemaRef, Expr *Capture, 8181 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8182 if (SemaRef.CurContext->isDependentContext() || Capture->containsErrors()) 8183 return Capture; 8184 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 8185 return SemaRef.PerformImplicitConversion( 8186 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 8187 /*AllowExplicit=*/true); 8188 auto I = Captures.find(Capture); 8189 if (I != Captures.end()) 8190 return buildCapture(SemaRef, Capture, I->second); 8191 DeclRefExpr *Ref = nullptr; 8192 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 8193 Captures[Capture] = Ref; 8194 return Res; 8195 } 8196 8197 /// Calculate number of iterations, transforming to unsigned, if number of 8198 /// iterations may be larger than the original type. 8199 static Expr * 8200 calculateNumIters(Sema &SemaRef, Scope *S, SourceLocation DefaultLoc, 8201 Expr *Lower, Expr *Upper, Expr *Step, QualType LCTy, 8202 bool TestIsStrictOp, bool RoundToStep, 8203 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8204 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 8205 if (!NewStep.isUsable()) 8206 return nullptr; 8207 llvm::APSInt LRes, SRes; 8208 bool IsLowerConst = false, IsStepConst = false; 8209 if (Optional<llvm::APSInt> Res = 8210 Lower->getIntegerConstantExpr(SemaRef.Context)) { 8211 LRes = *Res; 8212 IsLowerConst = true; 8213 } 8214 if (Optional<llvm::APSInt> Res = 8215 Step->getIntegerConstantExpr(SemaRef.Context)) { 8216 SRes = *Res; 8217 IsStepConst = true; 8218 } 8219 bool NoNeedToConvert = IsLowerConst && !RoundToStep && 8220 ((!TestIsStrictOp && LRes.isNonNegative()) || 8221 (TestIsStrictOp && LRes.isStrictlyPositive())); 8222 bool NeedToReorganize = false; 8223 // Check if any subexpressions in Lower -Step [+ 1] lead to overflow. 8224 if (!NoNeedToConvert && IsLowerConst && 8225 (TestIsStrictOp || (RoundToStep && IsStepConst))) { 8226 NoNeedToConvert = true; 8227 if (RoundToStep) { 8228 unsigned BW = LRes.getBitWidth() > SRes.getBitWidth() 8229 ? LRes.getBitWidth() 8230 : SRes.getBitWidth(); 8231 LRes = LRes.extend(BW + 1); 8232 LRes.setIsSigned(true); 8233 SRes = SRes.extend(BW + 1); 8234 SRes.setIsSigned(true); 8235 LRes -= SRes; 8236 NoNeedToConvert = LRes.trunc(BW).extend(BW + 1) == LRes; 8237 LRes = LRes.trunc(BW); 8238 } 8239 if (TestIsStrictOp) { 8240 unsigned BW = LRes.getBitWidth(); 8241 LRes = LRes.extend(BW + 1); 8242 LRes.setIsSigned(true); 8243 ++LRes; 8244 NoNeedToConvert = 8245 NoNeedToConvert && LRes.trunc(BW).extend(BW + 1) == LRes; 8246 // truncate to the original bitwidth. 8247 LRes = LRes.trunc(BW); 8248 } 8249 NeedToReorganize = NoNeedToConvert; 8250 } 8251 llvm::APSInt URes; 8252 bool IsUpperConst = false; 8253 if (Optional<llvm::APSInt> Res = 8254 Upper->getIntegerConstantExpr(SemaRef.Context)) { 8255 URes = *Res; 8256 IsUpperConst = true; 8257 } 8258 if (NoNeedToConvert && IsLowerConst && IsUpperConst && 8259 (!RoundToStep || IsStepConst)) { 8260 unsigned BW = LRes.getBitWidth() > URes.getBitWidth() ? LRes.getBitWidth() 8261 : URes.getBitWidth(); 8262 LRes = LRes.extend(BW + 1); 8263 LRes.setIsSigned(true); 8264 URes = URes.extend(BW + 1); 8265 URes.setIsSigned(true); 8266 URes -= LRes; 8267 NoNeedToConvert = URes.trunc(BW).extend(BW + 1) == URes; 8268 NeedToReorganize = NoNeedToConvert; 8269 } 8270 // If the boundaries are not constant or (Lower - Step [+ 1]) is not constant 8271 // or less than zero (Upper - (Lower - Step [+ 1]) may overflow) - promote to 8272 // unsigned. 8273 if ((!NoNeedToConvert || (LRes.isNegative() && !IsUpperConst)) && 8274 !LCTy->isDependentType() && LCTy->isIntegerType()) { 8275 QualType LowerTy = Lower->getType(); 8276 QualType UpperTy = Upper->getType(); 8277 uint64_t LowerSize = SemaRef.Context.getTypeSize(LowerTy); 8278 uint64_t UpperSize = SemaRef.Context.getTypeSize(UpperTy); 8279 if ((LowerSize <= UpperSize && UpperTy->hasSignedIntegerRepresentation()) || 8280 (LowerSize > UpperSize && LowerTy->hasSignedIntegerRepresentation())) { 8281 QualType CastType = SemaRef.Context.getIntTypeForBitwidth( 8282 LowerSize > UpperSize ? LowerSize : UpperSize, /*Signed=*/0); 8283 Upper = 8284 SemaRef 8285 .PerformImplicitConversion( 8286 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 8287 CastType, Sema::AA_Converting) 8288 .get(); 8289 Lower = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(); 8290 NewStep = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, NewStep.get()); 8291 } 8292 } 8293 if (!Lower || !Upper || NewStep.isInvalid()) 8294 return nullptr; 8295 8296 ExprResult Diff; 8297 // If need to reorganize, then calculate the form as Upper - (Lower - Step [+ 8298 // 1]). 8299 if (NeedToReorganize) { 8300 Diff = Lower; 8301 8302 if (RoundToStep) { 8303 // Lower - Step 8304 Diff = 8305 SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Diff.get(), NewStep.get()); 8306 if (!Diff.isUsable()) 8307 return nullptr; 8308 } 8309 8310 // Lower - Step [+ 1] 8311 if (TestIsStrictOp) 8312 Diff = SemaRef.BuildBinOp( 8313 S, DefaultLoc, BO_Add, Diff.get(), 8314 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8315 if (!Diff.isUsable()) 8316 return nullptr; 8317 8318 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8319 if (!Diff.isUsable()) 8320 return nullptr; 8321 8322 // Upper - (Lower - Step [+ 1]). 8323 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Diff.get()); 8324 if (!Diff.isUsable()) 8325 return nullptr; 8326 } else { 8327 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 8328 8329 if (!Diff.isUsable() && LCTy->getAsCXXRecordDecl()) { 8330 // BuildBinOp already emitted error, this one is to point user to upper 8331 // and lower bound, and to tell what is passed to 'operator-'. 8332 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 8333 << Upper->getSourceRange() << Lower->getSourceRange(); 8334 return nullptr; 8335 } 8336 8337 if (!Diff.isUsable()) 8338 return nullptr; 8339 8340 // Upper - Lower [- 1] 8341 if (TestIsStrictOp) 8342 Diff = SemaRef.BuildBinOp( 8343 S, DefaultLoc, BO_Sub, Diff.get(), 8344 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 8345 if (!Diff.isUsable()) 8346 return nullptr; 8347 8348 if (RoundToStep) { 8349 // Upper - Lower [- 1] + Step 8350 Diff = 8351 SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 8352 if (!Diff.isUsable()) 8353 return nullptr; 8354 } 8355 } 8356 8357 // Parentheses (for dumping/debugging purposes only). 8358 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8359 if (!Diff.isUsable()) 8360 return nullptr; 8361 8362 // (Upper - Lower [- 1] + Step) / Step or (Upper - Lower) / Step 8363 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 8364 if (!Diff.isUsable()) 8365 return nullptr; 8366 8367 return Diff.get(); 8368 } 8369 8370 /// Build the expression to calculate the number of iterations. 8371 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 8372 Scope *S, ArrayRef<LoopIterationSpace> ResultIterSpaces, bool LimitedType, 8373 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8374 QualType VarType = LCDecl->getType().getNonReferenceType(); 8375 if (!VarType->isIntegerType() && !VarType->isPointerType() && 8376 !SemaRef.getLangOpts().CPlusPlus) 8377 return nullptr; 8378 Expr *LBVal = LB; 8379 Expr *UBVal = UB; 8380 // LB = TestIsLessOp.getValue() ? min(LB(MinVal), LB(MaxVal)) : 8381 // max(LB(MinVal), LB(MaxVal)) 8382 if (InitDependOnLC) { 8383 const LoopIterationSpace &IS = ResultIterSpaces[*InitDependOnLC - 1]; 8384 if (!IS.MinValue || !IS.MaxValue) 8385 return nullptr; 8386 // OuterVar = Min 8387 ExprResult MinValue = 8388 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8389 if (!MinValue.isUsable()) 8390 return nullptr; 8391 8392 ExprResult LBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8393 IS.CounterVar, MinValue.get()); 8394 if (!LBMinVal.isUsable()) 8395 return nullptr; 8396 // OuterVar = Min, LBVal 8397 LBMinVal = 8398 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMinVal.get(), LBVal); 8399 if (!LBMinVal.isUsable()) 8400 return nullptr; 8401 // (OuterVar = Min, LBVal) 8402 LBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMinVal.get()); 8403 if (!LBMinVal.isUsable()) 8404 return nullptr; 8405 8406 // OuterVar = Max 8407 ExprResult MaxValue = 8408 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8409 if (!MaxValue.isUsable()) 8410 return nullptr; 8411 8412 ExprResult LBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8413 IS.CounterVar, MaxValue.get()); 8414 if (!LBMaxVal.isUsable()) 8415 return nullptr; 8416 // OuterVar = Max, LBVal 8417 LBMaxVal = 8418 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, LBMaxVal.get(), LBVal); 8419 if (!LBMaxVal.isUsable()) 8420 return nullptr; 8421 // (OuterVar = Max, LBVal) 8422 LBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, LBMaxVal.get()); 8423 if (!LBMaxVal.isUsable()) 8424 return nullptr; 8425 8426 Expr *LBMin = tryBuildCapture(SemaRef, LBMinVal.get(), Captures).get(); 8427 Expr *LBMax = tryBuildCapture(SemaRef, LBMaxVal.get(), Captures).get(); 8428 if (!LBMin || !LBMax) 8429 return nullptr; 8430 // LB(MinVal) < LB(MaxVal) 8431 ExprResult MinLessMaxRes = 8432 SemaRef.BuildBinOp(S, DefaultLoc, BO_LT, LBMin, LBMax); 8433 if (!MinLessMaxRes.isUsable()) 8434 return nullptr; 8435 Expr *MinLessMax = 8436 tryBuildCapture(SemaRef, MinLessMaxRes.get(), Captures).get(); 8437 if (!MinLessMax) 8438 return nullptr; 8439 if (*TestIsLessOp) { 8440 // LB(MinVal) < LB(MaxVal) ? LB(MinVal) : LB(MaxVal) - min(LB(MinVal), 8441 // LB(MaxVal)) 8442 ExprResult MinLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8443 MinLessMax, LBMin, LBMax); 8444 if (!MinLB.isUsable()) 8445 return nullptr; 8446 LBVal = MinLB.get(); 8447 } else { 8448 // LB(MinVal) < LB(MaxVal) ? LB(MaxVal) : LB(MinVal) - max(LB(MinVal), 8449 // LB(MaxVal)) 8450 ExprResult MaxLB = SemaRef.ActOnConditionalOp(DefaultLoc, DefaultLoc, 8451 MinLessMax, LBMax, LBMin); 8452 if (!MaxLB.isUsable()) 8453 return nullptr; 8454 LBVal = MaxLB.get(); 8455 } 8456 } 8457 // UB = TestIsLessOp.getValue() ? max(UB(MinVal), UB(MaxVal)) : 8458 // min(UB(MinVal), UB(MaxVal)) 8459 if (CondDependOnLC) { 8460 const LoopIterationSpace &IS = ResultIterSpaces[*CondDependOnLC - 1]; 8461 if (!IS.MinValue || !IS.MaxValue) 8462 return nullptr; 8463 // OuterVar = Min 8464 ExprResult MinValue = 8465 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MinValue); 8466 if (!MinValue.isUsable()) 8467 return nullptr; 8468 8469 ExprResult UBMinVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8470 IS.CounterVar, MinValue.get()); 8471 if (!UBMinVal.isUsable()) 8472 return nullptr; 8473 // OuterVar = Min, UBVal 8474 UBMinVal = 8475 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMinVal.get(), UBVal); 8476 if (!UBMinVal.isUsable()) 8477 return nullptr; 8478 // (OuterVar = Min, UBVal) 8479 UBMinVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMinVal.get()); 8480 if (!UBMinVal.isUsable()) 8481 return nullptr; 8482 8483 // OuterVar = Max 8484 ExprResult MaxValue = 8485 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, IS.MaxValue); 8486 if (!MaxValue.isUsable()) 8487 return nullptr; 8488 8489 ExprResult UBMaxVal = SemaRef.BuildBinOp(S, DefaultLoc, BO_Assign, 8490 IS.CounterVar, MaxValue.get()); 8491 if (!UBMaxVal.isUsable()) 8492 return nullptr; 8493 // OuterVar = Max, UBVal 8494 UBMaxVal = 8495 SemaRef.BuildBinOp(S, DefaultLoc, BO_Comma, UBMaxVal.get(), UBVal); 8496 if (!UBMaxVal.isUsable()) 8497 return nullptr; 8498 // (OuterVar = Max, UBVal) 8499 UBMaxVal = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, UBMaxVal.get()); 8500 if (!UBMaxVal.isUsable()) 8501 return nullptr; 8502 8503 Expr *UBMin = tryBuildCapture(SemaRef, UBMinVal.get(), Captures).get(); 8504 Expr *UBMax = tryBuildCapture(SemaRef, UBMaxVal.get(), Captures).get(); 8505 if (!UBMin || !UBMax) 8506 return nullptr; 8507 // UB(MinVal) > UB(MaxVal) 8508 ExprResult MinGreaterMaxRes = 8509 SemaRef.BuildBinOp(S, DefaultLoc, BO_GT, UBMin, UBMax); 8510 if (!MinGreaterMaxRes.isUsable()) 8511 return nullptr; 8512 Expr *MinGreaterMax = 8513 tryBuildCapture(SemaRef, MinGreaterMaxRes.get(), Captures).get(); 8514 if (!MinGreaterMax) 8515 return nullptr; 8516 if (*TestIsLessOp) { 8517 // UB(MinVal) > UB(MaxVal) ? UB(MinVal) : UB(MaxVal) - max(UB(MinVal), 8518 // UB(MaxVal)) 8519 ExprResult MaxUB = SemaRef.ActOnConditionalOp( 8520 DefaultLoc, DefaultLoc, MinGreaterMax, UBMin, UBMax); 8521 if (!MaxUB.isUsable()) 8522 return nullptr; 8523 UBVal = MaxUB.get(); 8524 } else { 8525 // UB(MinVal) > UB(MaxVal) ? UB(MaxVal) : UB(MinVal) - min(UB(MinVal), 8526 // UB(MaxVal)) 8527 ExprResult MinUB = SemaRef.ActOnConditionalOp( 8528 DefaultLoc, DefaultLoc, MinGreaterMax, UBMax, UBMin); 8529 if (!MinUB.isUsable()) 8530 return nullptr; 8531 UBVal = MinUB.get(); 8532 } 8533 } 8534 Expr *UBExpr = TestIsLessOp.getValue() ? UBVal : LBVal; 8535 Expr *LBExpr = TestIsLessOp.getValue() ? LBVal : UBVal; 8536 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 8537 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 8538 if (!Upper || !Lower) 8539 return nullptr; 8540 8541 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 8542 Step, VarType, TestIsStrictOp, 8543 /*RoundToStep=*/true, Captures); 8544 if (!Diff.isUsable()) 8545 return nullptr; 8546 8547 // OpenMP runtime requires 32-bit or 64-bit loop variables. 8548 QualType Type = Diff.get()->getType(); 8549 ASTContext &C = SemaRef.Context; 8550 bool UseVarType = VarType->hasIntegerRepresentation() && 8551 C.getTypeSize(Type) > C.getTypeSize(VarType); 8552 if (!Type->isIntegerType() || UseVarType) { 8553 unsigned NewSize = 8554 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 8555 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 8556 : Type->hasSignedIntegerRepresentation(); 8557 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 8558 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 8559 Diff = SemaRef.PerformImplicitConversion( 8560 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 8561 if (!Diff.isUsable()) 8562 return nullptr; 8563 } 8564 } 8565 if (LimitedType) { 8566 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 8567 if (NewSize != C.getTypeSize(Type)) { 8568 if (NewSize < C.getTypeSize(Type)) { 8569 assert(NewSize == 64 && "incorrect loop var size"); 8570 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 8571 << InitSrcRange << ConditionSrcRange; 8572 } 8573 QualType NewType = C.getIntTypeForBitwidth( 8574 NewSize, Type->hasSignedIntegerRepresentation() || 8575 C.getTypeSize(Type) < NewSize); 8576 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 8577 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 8578 Sema::AA_Converting, true); 8579 if (!Diff.isUsable()) 8580 return nullptr; 8581 } 8582 } 8583 } 8584 8585 return Diff.get(); 8586 } 8587 8588 std::pair<Expr *, Expr *> OpenMPIterationSpaceChecker::buildMinMaxValues( 8589 Scope *S, llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8590 // Do not build for iterators, they cannot be used in non-rectangular loop 8591 // nests. 8592 if (LCDecl->getType()->isRecordType()) 8593 return std::make_pair(nullptr, nullptr); 8594 // If we subtract, the min is in the condition, otherwise the min is in the 8595 // init value. 8596 Expr *MinExpr = nullptr; 8597 Expr *MaxExpr = nullptr; 8598 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 8599 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 8600 bool LBNonRect = TestIsLessOp.getValue() ? InitDependOnLC.hasValue() 8601 : CondDependOnLC.hasValue(); 8602 bool UBNonRect = TestIsLessOp.getValue() ? CondDependOnLC.hasValue() 8603 : InitDependOnLC.hasValue(); 8604 Expr *Lower = 8605 LBNonRect ? LBExpr : tryBuildCapture(SemaRef, LBExpr, Captures).get(); 8606 Expr *Upper = 8607 UBNonRect ? UBExpr : tryBuildCapture(SemaRef, UBExpr, Captures).get(); 8608 if (!Upper || !Lower) 8609 return std::make_pair(nullptr, nullptr); 8610 8611 if (*TestIsLessOp) 8612 MinExpr = Lower; 8613 else 8614 MaxExpr = Upper; 8615 8616 // Build minimum/maximum value based on number of iterations. 8617 QualType VarType = LCDecl->getType().getNonReferenceType(); 8618 8619 ExprResult Diff = calculateNumIters(SemaRef, S, DefaultLoc, Lower, Upper, 8620 Step, VarType, TestIsStrictOp, 8621 /*RoundToStep=*/false, Captures); 8622 if (!Diff.isUsable()) 8623 return std::make_pair(nullptr, nullptr); 8624 8625 // ((Upper - Lower [- 1]) / Step) * Step 8626 // Parentheses (for dumping/debugging purposes only). 8627 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8628 if (!Diff.isUsable()) 8629 return std::make_pair(nullptr, nullptr); 8630 8631 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 8632 if (!NewStep.isUsable()) 8633 return std::make_pair(nullptr, nullptr); 8634 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Mul, Diff.get(), NewStep.get()); 8635 if (!Diff.isUsable()) 8636 return std::make_pair(nullptr, nullptr); 8637 8638 // Parentheses (for dumping/debugging purposes only). 8639 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 8640 if (!Diff.isUsable()) 8641 return std::make_pair(nullptr, nullptr); 8642 8643 // Convert to the ptrdiff_t, if original type is pointer. 8644 if (VarType->isAnyPointerType() && 8645 !SemaRef.Context.hasSameType( 8646 Diff.get()->getType(), 8647 SemaRef.Context.getUnsignedPointerDiffType())) { 8648 Diff = SemaRef.PerformImplicitConversion( 8649 Diff.get(), SemaRef.Context.getUnsignedPointerDiffType(), 8650 Sema::AA_Converting, /*AllowExplicit=*/true); 8651 } 8652 if (!Diff.isUsable()) 8653 return std::make_pair(nullptr, nullptr); 8654 8655 if (*TestIsLessOp) { 8656 // MinExpr = Lower; 8657 // MaxExpr = Lower + (((Upper - Lower [- 1]) / Step) * Step) 8658 Diff = SemaRef.BuildBinOp( 8659 S, DefaultLoc, BO_Add, 8660 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Lower).get(), 8661 Diff.get()); 8662 if (!Diff.isUsable()) 8663 return std::make_pair(nullptr, nullptr); 8664 } else { 8665 // MaxExpr = Upper; 8666 // MinExpr = Upper - (((Upper - Lower [- 1]) / Step) * Step) 8667 Diff = SemaRef.BuildBinOp( 8668 S, DefaultLoc, BO_Sub, 8669 SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Upper).get(), 8670 Diff.get()); 8671 if (!Diff.isUsable()) 8672 return std::make_pair(nullptr, nullptr); 8673 } 8674 8675 // Convert to the original type. 8676 if (SemaRef.Context.hasSameType(Diff.get()->getType(), VarType)) 8677 Diff = SemaRef.PerformImplicitConversion(Diff.get(), VarType, 8678 Sema::AA_Converting, 8679 /*AllowExplicit=*/true); 8680 if (!Diff.isUsable()) 8681 return std::make_pair(nullptr, nullptr); 8682 8683 Sema::TentativeAnalysisScope Trap(SemaRef); 8684 Diff = SemaRef.ActOnFinishFullExpr(Diff.get(), /*DiscardedValue=*/false); 8685 if (!Diff.isUsable()) 8686 return std::make_pair(nullptr, nullptr); 8687 8688 if (*TestIsLessOp) 8689 MaxExpr = Diff.get(); 8690 else 8691 MinExpr = Diff.get(); 8692 8693 return std::make_pair(MinExpr, MaxExpr); 8694 } 8695 8696 Expr *OpenMPIterationSpaceChecker::buildFinalCondition(Scope *S) const { 8697 if (InitDependOnLC || CondDependOnLC) 8698 return Condition; 8699 return nullptr; 8700 } 8701 8702 Expr *OpenMPIterationSpaceChecker::buildPreCond( 8703 Scope *S, Expr *Cond, 8704 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 8705 // Do not build a precondition when the condition/initialization is dependent 8706 // to prevent pessimistic early loop exit. 8707 // TODO: this can be improved by calculating min/max values but not sure that 8708 // it will be very effective. 8709 if (CondDependOnLC || InitDependOnLC) 8710 return SemaRef 8711 .PerformImplicitConversion( 8712 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(), 8713 SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 8714 /*AllowExplicit=*/true) 8715 .get(); 8716 8717 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 8718 Sema::TentativeAnalysisScope Trap(SemaRef); 8719 8720 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 8721 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 8722 if (!NewLB.isUsable() || !NewUB.isUsable()) 8723 return nullptr; 8724 8725 ExprResult CondExpr = SemaRef.BuildBinOp( 8726 S, DefaultLoc, 8727 TestIsLessOp.getValue() ? (TestIsStrictOp ? BO_LT : BO_LE) 8728 : (TestIsStrictOp ? BO_GT : BO_GE), 8729 NewLB.get(), NewUB.get()); 8730 if (CondExpr.isUsable()) { 8731 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 8732 SemaRef.Context.BoolTy)) 8733 CondExpr = SemaRef.PerformImplicitConversion( 8734 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 8735 /*AllowExplicit=*/true); 8736 } 8737 8738 // Otherwise use original loop condition and evaluate it in runtime. 8739 return CondExpr.isUsable() ? CondExpr.get() : Cond; 8740 } 8741 8742 /// Build reference expression to the counter be used for codegen. 8743 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 8744 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 8745 DSAStackTy &DSA) const { 8746 auto *VD = dyn_cast<VarDecl>(LCDecl); 8747 if (!VD) { 8748 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 8749 DeclRefExpr *Ref = buildDeclRefExpr( 8750 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 8751 const DSAStackTy::DSAVarData Data = 8752 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 8753 // If the loop control decl is explicitly marked as private, do not mark it 8754 // as captured again. 8755 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 8756 Captures.insert(std::make_pair(LCRef, Ref)); 8757 return Ref; 8758 } 8759 return cast<DeclRefExpr>(LCRef); 8760 } 8761 8762 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 8763 if (LCDecl && !LCDecl->isInvalidDecl()) { 8764 QualType Type = LCDecl->getType().getNonReferenceType(); 8765 VarDecl *PrivateVar = buildVarDecl( 8766 SemaRef, DefaultLoc, Type, LCDecl->getName(), 8767 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 8768 isa<VarDecl>(LCDecl) 8769 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 8770 : nullptr); 8771 if (PrivateVar->isInvalidDecl()) 8772 return nullptr; 8773 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 8774 } 8775 return nullptr; 8776 } 8777 8778 /// Build initialization of the counter to be used for codegen. 8779 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 8780 8781 /// Build step of the counter be used for codegen. 8782 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 8783 8784 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 8785 Scope *S, Expr *Counter, 8786 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 8787 Expr *Inc, OverloadedOperatorKind OOK) { 8788 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 8789 if (!Cnt) 8790 return nullptr; 8791 if (Inc) { 8792 assert((OOK == OO_Plus || OOK == OO_Minus) && 8793 "Expected only + or - operations for depend clauses."); 8794 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 8795 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 8796 if (!Cnt) 8797 return nullptr; 8798 } 8799 QualType VarType = LCDecl->getType().getNonReferenceType(); 8800 if (!VarType->isIntegerType() && !VarType->isPointerType() && 8801 !SemaRef.getLangOpts().CPlusPlus) 8802 return nullptr; 8803 // Upper - Lower 8804 Expr *Upper = TestIsLessOp.getValue() 8805 ? Cnt 8806 : tryBuildCapture(SemaRef, LB, Captures).get(); 8807 Expr *Lower = TestIsLessOp.getValue() 8808 ? tryBuildCapture(SemaRef, LB, Captures).get() 8809 : Cnt; 8810 if (!Upper || !Lower) 8811 return nullptr; 8812 8813 ExprResult Diff = calculateNumIters( 8814 SemaRef, S, DefaultLoc, Lower, Upper, Step, VarType, 8815 /*TestIsStrictOp=*/false, /*RoundToStep=*/false, Captures); 8816 if (!Diff.isUsable()) 8817 return nullptr; 8818 8819 return Diff.get(); 8820 } 8821 } // namespace 8822 8823 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 8824 assert(getLangOpts().OpenMP && "OpenMP is not active."); 8825 assert(Init && "Expected loop in canonical form."); 8826 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 8827 if (AssociatedLoops > 0 && 8828 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 8829 DSAStack->loopStart(); 8830 OpenMPIterationSpaceChecker ISC(*this, /*SupportsNonRectangular=*/true, 8831 *DSAStack, ForLoc); 8832 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 8833 if (ValueDecl *D = ISC.getLoopDecl()) { 8834 auto *VD = dyn_cast<VarDecl>(D); 8835 DeclRefExpr *PrivateRef = nullptr; 8836 if (!VD) { 8837 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 8838 VD = Private; 8839 } else { 8840 PrivateRef = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 8841 /*WithInit=*/false); 8842 VD = cast<VarDecl>(PrivateRef->getDecl()); 8843 } 8844 } 8845 DSAStack->addLoopControlVariable(D, VD); 8846 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 8847 if (LD != D->getCanonicalDecl()) { 8848 DSAStack->resetPossibleLoopCounter(); 8849 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 8850 MarkDeclarationsReferencedInExpr( 8851 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 8852 Var->getType().getNonLValueExprType(Context), 8853 ForLoc, /*RefersToCapture=*/true)); 8854 } 8855 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 8856 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables 8857 // Referenced in a Construct, C/C++]. The loop iteration variable in the 8858 // associated for-loop of a simd construct with just one associated 8859 // for-loop may be listed in a linear clause with a constant-linear-step 8860 // that is the increment of the associated for-loop. The loop iteration 8861 // variable(s) in the associated for-loop(s) of a for or parallel for 8862 // construct may be listed in a private or lastprivate clause. 8863 DSAStackTy::DSAVarData DVar = 8864 DSAStack->getTopDSA(D, /*FromParent=*/false); 8865 // If LoopVarRefExpr is nullptr it means the corresponding loop variable 8866 // is declared in the loop and it is predetermined as a private. 8867 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 8868 OpenMPClauseKind PredeterminedCKind = 8869 isOpenMPSimdDirective(DKind) 8870 ? (DSAStack->hasMutipleLoops() ? OMPC_lastprivate : OMPC_linear) 8871 : OMPC_private; 8872 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 8873 DVar.CKind != PredeterminedCKind && DVar.RefExpr && 8874 (LangOpts.OpenMP <= 45 || (DVar.CKind != OMPC_lastprivate && 8875 DVar.CKind != OMPC_private))) || 8876 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 8877 DKind == OMPD_master_taskloop || 8878 DKind == OMPD_masked_taskloop || 8879 DKind == OMPD_parallel_master_taskloop || 8880 isOpenMPDistributeDirective(DKind)) && 8881 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 8882 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 8883 (DVar.CKind != OMPC_private || DVar.RefExpr)) { 8884 Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 8885 << getOpenMPClauseName(DVar.CKind) 8886 << getOpenMPDirectiveName(DKind) 8887 << getOpenMPClauseName(PredeterminedCKind); 8888 if (DVar.RefExpr == nullptr) 8889 DVar.CKind = PredeterminedCKind; 8890 reportOriginalDsa(*this, DSAStack, D, DVar, 8891 /*IsLoopIterVar=*/true); 8892 } else if (LoopDeclRefExpr) { 8893 // Make the loop iteration variable private (for worksharing 8894 // constructs), linear (for simd directives with the only one 8895 // associated loop) or lastprivate (for simd directives with several 8896 // collapsed or ordered loops). 8897 if (DVar.CKind == OMPC_unknown) 8898 DSAStack->addDSA(D, LoopDeclRefExpr, PredeterminedCKind, 8899 PrivateRef); 8900 } 8901 } 8902 } 8903 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 8904 } 8905 } 8906 8907 /// Called on a for stmt to check and extract its iteration space 8908 /// for further processing (such as collapsing). 8909 static bool checkOpenMPIterationSpace( 8910 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 8911 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 8912 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 8913 Expr *OrderedLoopCountExpr, 8914 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 8915 llvm::MutableArrayRef<LoopIterationSpace> ResultIterSpaces, 8916 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 8917 bool SupportsNonRectangular = !isOpenMPLoopTransformationDirective(DKind); 8918 // OpenMP [2.9.1, Canonical Loop Form] 8919 // for (init-expr; test-expr; incr-expr) structured-block 8920 // for (range-decl: range-expr) structured-block 8921 if (auto *CanonLoop = dyn_cast_or_null<OMPCanonicalLoop>(S)) 8922 S = CanonLoop->getLoopStmt(); 8923 auto *For = dyn_cast_or_null<ForStmt>(S); 8924 auto *CXXFor = dyn_cast_or_null<CXXForRangeStmt>(S); 8925 // Ranged for is supported only in OpenMP 5.0. 8926 if (!For && (SemaRef.LangOpts.OpenMP <= 45 || !CXXFor)) { 8927 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 8928 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 8929 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 8930 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 8931 if (TotalNestedLoopCount > 1) { 8932 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 8933 SemaRef.Diag(DSA.getConstructLoc(), 8934 diag::note_omp_collapse_ordered_expr) 8935 << 2 << CollapseLoopCountExpr->getSourceRange() 8936 << OrderedLoopCountExpr->getSourceRange(); 8937 else if (CollapseLoopCountExpr) 8938 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 8939 diag::note_omp_collapse_ordered_expr) 8940 << 0 << CollapseLoopCountExpr->getSourceRange(); 8941 else 8942 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 8943 diag::note_omp_collapse_ordered_expr) 8944 << 1 << OrderedLoopCountExpr->getSourceRange(); 8945 } 8946 return true; 8947 } 8948 assert(((For && For->getBody()) || (CXXFor && CXXFor->getBody())) && 8949 "No loop body."); 8950 // Postpone analysis in dependent contexts for ranged for loops. 8951 if (CXXFor && SemaRef.CurContext->isDependentContext()) 8952 return false; 8953 8954 OpenMPIterationSpaceChecker ISC(SemaRef, SupportsNonRectangular, DSA, 8955 For ? For->getForLoc() : CXXFor->getForLoc()); 8956 8957 // Check init. 8958 Stmt *Init = For ? For->getInit() : CXXFor->getBeginStmt(); 8959 if (ISC.checkAndSetInit(Init)) 8960 return true; 8961 8962 bool HasErrors = false; 8963 8964 // Check loop variable's type. 8965 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 8966 // OpenMP [2.6, Canonical Loop Form] 8967 // Var is one of the following: 8968 // A variable of signed or unsigned integer type. 8969 // For C++, a variable of a random access iterator type. 8970 // For C, a variable of a pointer type. 8971 QualType VarType = LCDecl->getType().getNonReferenceType(); 8972 if (!VarType->isDependentType() && !VarType->isIntegerType() && 8973 !VarType->isPointerType() && 8974 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 8975 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 8976 << SemaRef.getLangOpts().CPlusPlus; 8977 HasErrors = true; 8978 } 8979 8980 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 8981 // a Construct 8982 // The loop iteration variable(s) in the associated for-loop(s) of a for or 8983 // parallel for construct is (are) private. 8984 // The loop iteration variable in the associated for-loop of a simd 8985 // construct with just one associated for-loop is linear with a 8986 // constant-linear-step that is the increment of the associated for-loop. 8987 // Exclude loop var from the list of variables with implicitly defined data 8988 // sharing attributes. 8989 VarsWithImplicitDSA.erase(LCDecl); 8990 8991 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 8992 8993 // Check test-expr. 8994 HasErrors |= ISC.checkAndSetCond(For ? For->getCond() : CXXFor->getCond()); 8995 8996 // Check incr-expr. 8997 HasErrors |= ISC.checkAndSetInc(For ? For->getInc() : CXXFor->getInc()); 8998 } 8999 9000 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 9001 return HasErrors; 9002 9003 // Build the loop's iteration space representation. 9004 ResultIterSpaces[CurrentNestedLoopCount].PreCond = ISC.buildPreCond( 9005 DSA.getCurScope(), For ? For->getCond() : CXXFor->getCond(), Captures); 9006 ResultIterSpaces[CurrentNestedLoopCount].NumIterations = 9007 ISC.buildNumIterations(DSA.getCurScope(), ResultIterSpaces, 9008 (isOpenMPWorksharingDirective(DKind) || 9009 isOpenMPGenericLoopDirective(DKind) || 9010 isOpenMPTaskLoopDirective(DKind) || 9011 isOpenMPDistributeDirective(DKind) || 9012 isOpenMPLoopTransformationDirective(DKind)), 9013 Captures); 9014 ResultIterSpaces[CurrentNestedLoopCount].CounterVar = 9015 ISC.buildCounterVar(Captures, DSA); 9016 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar = 9017 ISC.buildPrivateCounterVar(); 9018 ResultIterSpaces[CurrentNestedLoopCount].CounterInit = ISC.buildCounterInit(); 9019 ResultIterSpaces[CurrentNestedLoopCount].CounterStep = ISC.buildCounterStep(); 9020 ResultIterSpaces[CurrentNestedLoopCount].InitSrcRange = ISC.getInitSrcRange(); 9021 ResultIterSpaces[CurrentNestedLoopCount].CondSrcRange = 9022 ISC.getConditionSrcRange(); 9023 ResultIterSpaces[CurrentNestedLoopCount].IncSrcRange = 9024 ISC.getIncrementSrcRange(); 9025 ResultIterSpaces[CurrentNestedLoopCount].Subtract = ISC.shouldSubtractStep(); 9026 ResultIterSpaces[CurrentNestedLoopCount].IsStrictCompare = 9027 ISC.isStrictTestOp(); 9028 std::tie(ResultIterSpaces[CurrentNestedLoopCount].MinValue, 9029 ResultIterSpaces[CurrentNestedLoopCount].MaxValue) = 9030 ISC.buildMinMaxValues(DSA.getCurScope(), Captures); 9031 ResultIterSpaces[CurrentNestedLoopCount].FinalCondition = 9032 ISC.buildFinalCondition(DSA.getCurScope()); 9033 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularLB = 9034 ISC.doesInitDependOnLC(); 9035 ResultIterSpaces[CurrentNestedLoopCount].IsNonRectangularUB = 9036 ISC.doesCondDependOnLC(); 9037 ResultIterSpaces[CurrentNestedLoopCount].LoopDependentIdx = 9038 ISC.getLoopDependentIdx(); 9039 9040 HasErrors |= 9041 (ResultIterSpaces[CurrentNestedLoopCount].PreCond == nullptr || 9042 ResultIterSpaces[CurrentNestedLoopCount].NumIterations == nullptr || 9043 ResultIterSpaces[CurrentNestedLoopCount].CounterVar == nullptr || 9044 ResultIterSpaces[CurrentNestedLoopCount].PrivateCounterVar == nullptr || 9045 ResultIterSpaces[CurrentNestedLoopCount].CounterInit == nullptr || 9046 ResultIterSpaces[CurrentNestedLoopCount].CounterStep == nullptr); 9047 if (!HasErrors && DSA.isOrderedRegion()) { 9048 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 9049 if (CurrentNestedLoopCount < 9050 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 9051 DSA.getOrderedRegionParam().second->setLoopNumIterations( 9052 CurrentNestedLoopCount, 9053 ResultIterSpaces[CurrentNestedLoopCount].NumIterations); 9054 DSA.getOrderedRegionParam().second->setLoopCounter( 9055 CurrentNestedLoopCount, 9056 ResultIterSpaces[CurrentNestedLoopCount].CounterVar); 9057 } 9058 } 9059 for (auto &Pair : DSA.getDoacrossDependClauses()) { 9060 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 9061 // Erroneous case - clause has some problems. 9062 continue; 9063 } 9064 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 9065 Pair.second.size() <= CurrentNestedLoopCount) { 9066 // Erroneous case - clause has some problems. 9067 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 9068 continue; 9069 } 9070 Expr *CntValue; 9071 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 9072 CntValue = ISC.buildOrderedLoopData( 9073 DSA.getCurScope(), 9074 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 9075 Pair.first->getDependencyLoc()); 9076 else 9077 CntValue = ISC.buildOrderedLoopData( 9078 DSA.getCurScope(), 9079 ResultIterSpaces[CurrentNestedLoopCount].CounterVar, Captures, 9080 Pair.first->getDependencyLoc(), 9081 Pair.second[CurrentNestedLoopCount].first, 9082 Pair.second[CurrentNestedLoopCount].second); 9083 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 9084 } 9085 } 9086 9087 return HasErrors; 9088 } 9089 9090 /// Build 'VarRef = Start. 9091 static ExprResult 9092 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 9093 ExprResult Start, bool IsNonRectangularLB, 9094 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9095 // Build 'VarRef = Start. 9096 ExprResult NewStart = IsNonRectangularLB 9097 ? Start.get() 9098 : tryBuildCapture(SemaRef, Start.get(), Captures); 9099 if (!NewStart.isUsable()) 9100 return ExprError(); 9101 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 9102 VarRef.get()->getType())) { 9103 NewStart = SemaRef.PerformImplicitConversion( 9104 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 9105 /*AllowExplicit=*/true); 9106 if (!NewStart.isUsable()) 9107 return ExprError(); 9108 } 9109 9110 ExprResult Init = 9111 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 9112 return Init; 9113 } 9114 9115 /// Build 'VarRef = Start + Iter * Step'. 9116 static ExprResult buildCounterUpdate( 9117 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 9118 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 9119 bool IsNonRectangularLB, 9120 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 9121 // Add parentheses (for debugging purposes only). 9122 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 9123 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 9124 !Step.isUsable()) 9125 return ExprError(); 9126 9127 ExprResult NewStep = Step; 9128 if (Captures) 9129 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 9130 if (NewStep.isInvalid()) 9131 return ExprError(); 9132 ExprResult Update = 9133 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 9134 if (!Update.isUsable()) 9135 return ExprError(); 9136 9137 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 9138 // 'VarRef = Start (+|-) Iter * Step'. 9139 if (!Start.isUsable()) 9140 return ExprError(); 9141 ExprResult NewStart = SemaRef.ActOnParenExpr(Loc, Loc, Start.get()); 9142 if (!NewStart.isUsable()) 9143 return ExprError(); 9144 if (Captures && !IsNonRectangularLB) 9145 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 9146 if (NewStart.isInvalid()) 9147 return ExprError(); 9148 9149 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 9150 ExprResult SavedUpdate = Update; 9151 ExprResult UpdateVal; 9152 if (VarRef.get()->getType()->isOverloadableType() || 9153 NewStart.get()->getType()->isOverloadableType() || 9154 Update.get()->getType()->isOverloadableType()) { 9155 Sema::TentativeAnalysisScope Trap(SemaRef); 9156 9157 Update = 9158 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 9159 if (Update.isUsable()) { 9160 UpdateVal = 9161 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 9162 VarRef.get(), SavedUpdate.get()); 9163 if (UpdateVal.isUsable()) { 9164 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 9165 UpdateVal.get()); 9166 } 9167 } 9168 } 9169 9170 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 9171 if (!Update.isUsable() || !UpdateVal.isUsable()) { 9172 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 9173 NewStart.get(), SavedUpdate.get()); 9174 if (!Update.isUsable()) 9175 return ExprError(); 9176 9177 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 9178 VarRef.get()->getType())) { 9179 Update = SemaRef.PerformImplicitConversion( 9180 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 9181 if (!Update.isUsable()) 9182 return ExprError(); 9183 } 9184 9185 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 9186 } 9187 return Update; 9188 } 9189 9190 /// Convert integer expression \a E to make it have at least \a Bits 9191 /// bits. 9192 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 9193 if (E == nullptr) 9194 return ExprError(); 9195 ASTContext &C = SemaRef.Context; 9196 QualType OldType = E->getType(); 9197 unsigned HasBits = C.getTypeSize(OldType); 9198 if (HasBits >= Bits) 9199 return ExprResult(E); 9200 // OK to convert to signed, because new type has more bits than old. 9201 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 9202 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 9203 true); 9204 } 9205 9206 /// Check if the given expression \a E is a constant integer that fits 9207 /// into \a Bits bits. 9208 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 9209 if (E == nullptr) 9210 return false; 9211 if (Optional<llvm::APSInt> Result = 9212 E->getIntegerConstantExpr(SemaRef.Context)) 9213 return Signed ? Result->isSignedIntN(Bits) : Result->isIntN(Bits); 9214 return false; 9215 } 9216 9217 /// Build preinits statement for the given declarations. 9218 static Stmt *buildPreInits(ASTContext &Context, 9219 MutableArrayRef<Decl *> PreInits) { 9220 if (!PreInits.empty()) { 9221 return new (Context) DeclStmt( 9222 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 9223 SourceLocation(), SourceLocation()); 9224 } 9225 return nullptr; 9226 } 9227 9228 /// Build preinits statement for the given declarations. 9229 static Stmt * 9230 buildPreInits(ASTContext &Context, 9231 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 9232 if (!Captures.empty()) { 9233 SmallVector<Decl *, 16> PreInits; 9234 for (const auto &Pair : Captures) 9235 PreInits.push_back(Pair.second->getDecl()); 9236 return buildPreInits(Context, PreInits); 9237 } 9238 return nullptr; 9239 } 9240 9241 /// Build postupdate expression for the given list of postupdates expressions. 9242 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 9243 Expr *PostUpdate = nullptr; 9244 if (!PostUpdates.empty()) { 9245 for (Expr *E : PostUpdates) { 9246 Expr *ConvE = S.BuildCStyleCastExpr( 9247 E->getExprLoc(), 9248 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 9249 E->getExprLoc(), E) 9250 .get(); 9251 PostUpdate = PostUpdate 9252 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 9253 PostUpdate, ConvE) 9254 .get() 9255 : ConvE; 9256 } 9257 } 9258 return PostUpdate; 9259 } 9260 9261 /// Called on a for stmt to check itself and nested loops (if any). 9262 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 9263 /// number of collapsed loops otherwise. 9264 static unsigned 9265 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 9266 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 9267 DSAStackTy &DSA, 9268 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 9269 OMPLoopBasedDirective::HelperExprs &Built) { 9270 unsigned NestedLoopCount = 1; 9271 bool SupportsNonPerfectlyNested = (SemaRef.LangOpts.OpenMP >= 50) && 9272 !isOpenMPLoopTransformationDirective(DKind); 9273 9274 if (CollapseLoopCountExpr) { 9275 // Found 'collapse' clause - calculate collapse number. 9276 Expr::EvalResult Result; 9277 if (!CollapseLoopCountExpr->isValueDependent() && 9278 CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 9279 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 9280 } else { 9281 Built.clear(/*Size=*/1); 9282 return 1; 9283 } 9284 } 9285 unsigned OrderedLoopCount = 1; 9286 if (OrderedLoopCountExpr) { 9287 // Found 'ordered' clause - calculate collapse number. 9288 Expr::EvalResult EVResult; 9289 if (!OrderedLoopCountExpr->isValueDependent() && 9290 OrderedLoopCountExpr->EvaluateAsInt(EVResult, 9291 SemaRef.getASTContext())) { 9292 llvm::APSInt Result = EVResult.Val.getInt(); 9293 if (Result.getLimitedValue() < NestedLoopCount) { 9294 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 9295 diag::err_omp_wrong_ordered_loop_count) 9296 << OrderedLoopCountExpr->getSourceRange(); 9297 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 9298 diag::note_collapse_loop_count) 9299 << CollapseLoopCountExpr->getSourceRange(); 9300 } 9301 OrderedLoopCount = Result.getLimitedValue(); 9302 } else { 9303 Built.clear(/*Size=*/1); 9304 return 1; 9305 } 9306 } 9307 // This is helper routine for loop directives (e.g., 'for', 'simd', 9308 // 'for simd', etc.). 9309 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9310 unsigned NumLoops = std::max(OrderedLoopCount, NestedLoopCount); 9311 SmallVector<LoopIterationSpace, 4> IterSpaces(NumLoops); 9312 if (!OMPLoopBasedDirective::doForAllLoops( 9313 AStmt->IgnoreContainers(!isOpenMPLoopTransformationDirective(DKind)), 9314 SupportsNonPerfectlyNested, NumLoops, 9315 [DKind, &SemaRef, &DSA, NumLoops, NestedLoopCount, 9316 CollapseLoopCountExpr, OrderedLoopCountExpr, &VarsWithImplicitDSA, 9317 &IterSpaces, &Captures](unsigned Cnt, Stmt *CurStmt) { 9318 if (checkOpenMPIterationSpace( 9319 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 9320 NumLoops, CollapseLoopCountExpr, OrderedLoopCountExpr, 9321 VarsWithImplicitDSA, IterSpaces, Captures)) 9322 return true; 9323 if (Cnt > 0 && Cnt >= NestedLoopCount && 9324 IterSpaces[Cnt].CounterVar) { 9325 // Handle initialization of captured loop iterator variables. 9326 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 9327 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 9328 Captures[DRE] = DRE; 9329 } 9330 } 9331 return false; 9332 }, 9333 [&SemaRef, &Captures](OMPLoopTransformationDirective *Transform) { 9334 Stmt *DependentPreInits = Transform->getPreInits(); 9335 if (!DependentPreInits) 9336 return; 9337 for (Decl *C : cast<DeclStmt>(DependentPreInits)->getDeclGroup()) { 9338 auto *D = cast<VarDecl>(C); 9339 DeclRefExpr *Ref = buildDeclRefExpr(SemaRef, D, D->getType(), 9340 Transform->getBeginLoc()); 9341 Captures[Ref] = Ref; 9342 } 9343 })) 9344 return 0; 9345 9346 Built.clear(/* size */ NestedLoopCount); 9347 9348 if (SemaRef.CurContext->isDependentContext()) 9349 return NestedLoopCount; 9350 9351 // An example of what is generated for the following code: 9352 // 9353 // #pragma omp simd collapse(2) ordered(2) 9354 // for (i = 0; i < NI; ++i) 9355 // for (k = 0; k < NK; ++k) 9356 // for (j = J0; j < NJ; j+=2) { 9357 // <loop body> 9358 // } 9359 // 9360 // We generate the code below. 9361 // Note: the loop body may be outlined in CodeGen. 9362 // Note: some counters may be C++ classes, operator- is used to find number of 9363 // iterations and operator+= to calculate counter value. 9364 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 9365 // or i64 is currently supported). 9366 // 9367 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 9368 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 9369 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 9370 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 9371 // // similar updates for vars in clauses (e.g. 'linear') 9372 // <loop body (using local i and j)> 9373 // } 9374 // i = NI; // assign final values of counters 9375 // j = NJ; 9376 // 9377 9378 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 9379 // the iteration counts of the collapsed for loops. 9380 // Precondition tests if there is at least one iteration (all conditions are 9381 // true). 9382 auto PreCond = ExprResult(IterSpaces[0].PreCond); 9383 Expr *N0 = IterSpaces[0].NumIterations; 9384 ExprResult LastIteration32 = 9385 widenIterationCount(/*Bits=*/32, 9386 SemaRef 9387 .PerformImplicitConversion( 9388 N0->IgnoreImpCasts(), N0->getType(), 9389 Sema::AA_Converting, /*AllowExplicit=*/true) 9390 .get(), 9391 SemaRef); 9392 ExprResult LastIteration64 = widenIterationCount( 9393 /*Bits=*/64, 9394 SemaRef 9395 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 9396 Sema::AA_Converting, 9397 /*AllowExplicit=*/true) 9398 .get(), 9399 SemaRef); 9400 9401 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 9402 return NestedLoopCount; 9403 9404 ASTContext &C = SemaRef.Context; 9405 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 9406 9407 Scope *CurScope = DSA.getCurScope(); 9408 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 9409 if (PreCond.isUsable()) { 9410 PreCond = 9411 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 9412 PreCond.get(), IterSpaces[Cnt].PreCond); 9413 } 9414 Expr *N = IterSpaces[Cnt].NumIterations; 9415 SourceLocation Loc = N->getExprLoc(); 9416 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 9417 if (LastIteration32.isUsable()) 9418 LastIteration32 = SemaRef.BuildBinOp( 9419 CurScope, Loc, BO_Mul, LastIteration32.get(), 9420 SemaRef 9421 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9422 Sema::AA_Converting, 9423 /*AllowExplicit=*/true) 9424 .get()); 9425 if (LastIteration64.isUsable()) 9426 LastIteration64 = SemaRef.BuildBinOp( 9427 CurScope, Loc, BO_Mul, LastIteration64.get(), 9428 SemaRef 9429 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 9430 Sema::AA_Converting, 9431 /*AllowExplicit=*/true) 9432 .get()); 9433 } 9434 9435 // Choose either the 32-bit or 64-bit version. 9436 ExprResult LastIteration = LastIteration64; 9437 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 9438 (LastIteration32.isUsable() && 9439 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 9440 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 9441 fitsInto( 9442 /*Bits=*/32, 9443 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 9444 LastIteration64.get(), SemaRef)))) 9445 LastIteration = LastIteration32; 9446 QualType VType = LastIteration.get()->getType(); 9447 QualType RealVType = VType; 9448 QualType StrideVType = VType; 9449 if (isOpenMPTaskLoopDirective(DKind)) { 9450 VType = 9451 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 9452 StrideVType = 9453 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 9454 } 9455 9456 if (!LastIteration.isUsable()) 9457 return 0; 9458 9459 // Save the number of iterations. 9460 ExprResult NumIterations = LastIteration; 9461 { 9462 LastIteration = SemaRef.BuildBinOp( 9463 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 9464 LastIteration.get(), 9465 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9466 if (!LastIteration.isUsable()) 9467 return 0; 9468 } 9469 9470 // Calculate the last iteration number beforehand instead of doing this on 9471 // each iteration. Do not do this if the number of iterations may be kfold-ed. 9472 bool IsConstant = LastIteration.get()->isIntegerConstantExpr(SemaRef.Context); 9473 ExprResult CalcLastIteration; 9474 if (!IsConstant) { 9475 ExprResult SaveRef = 9476 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 9477 LastIteration = SaveRef; 9478 9479 // Prepare SaveRef + 1. 9480 NumIterations = SemaRef.BuildBinOp( 9481 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 9482 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 9483 if (!NumIterations.isUsable()) 9484 return 0; 9485 } 9486 9487 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 9488 9489 // Build variables passed into runtime, necessary for worksharing directives. 9490 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 9491 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 9492 isOpenMPDistributeDirective(DKind) || 9493 isOpenMPGenericLoopDirective(DKind) || 9494 isOpenMPLoopTransformationDirective(DKind)) { 9495 // Lower bound variable, initialized with zero. 9496 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 9497 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 9498 SemaRef.AddInitializerToDecl(LBDecl, 9499 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9500 /*DirectInit*/ false); 9501 9502 // Upper bound variable, initialized with last iteration number. 9503 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 9504 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 9505 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 9506 /*DirectInit*/ false); 9507 9508 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 9509 // This will be used to implement clause 'lastprivate'. 9510 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 9511 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 9512 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 9513 SemaRef.AddInitializerToDecl(ILDecl, 9514 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9515 /*DirectInit*/ false); 9516 9517 // Stride variable returned by runtime (we initialize it to 1 by default). 9518 VarDecl *STDecl = 9519 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 9520 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 9521 SemaRef.AddInitializerToDecl(STDecl, 9522 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 9523 /*DirectInit*/ false); 9524 9525 // Build expression: UB = min(UB, LastIteration) 9526 // It is necessary for CodeGen of directives with static scheduling. 9527 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 9528 UB.get(), LastIteration.get()); 9529 ExprResult CondOp = SemaRef.ActOnConditionalOp( 9530 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 9531 LastIteration.get(), UB.get()); 9532 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 9533 CondOp.get()); 9534 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 9535 9536 // If we have a combined directive that combines 'distribute', 'for' or 9537 // 'simd' we need to be able to access the bounds of the schedule of the 9538 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 9539 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 9540 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9541 // Lower bound variable, initialized with zero. 9542 VarDecl *CombLBDecl = 9543 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 9544 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 9545 SemaRef.AddInitializerToDecl( 9546 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 9547 /*DirectInit*/ false); 9548 9549 // Upper bound variable, initialized with last iteration number. 9550 VarDecl *CombUBDecl = 9551 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 9552 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 9553 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 9554 /*DirectInit*/ false); 9555 9556 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 9557 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 9558 ExprResult CombCondOp = 9559 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 9560 LastIteration.get(), CombUB.get()); 9561 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 9562 CombCondOp.get()); 9563 CombEUB = 9564 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 9565 9566 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 9567 // We expect to have at least 2 more parameters than the 'parallel' 9568 // directive does - the lower and upper bounds of the previous schedule. 9569 assert(CD->getNumParams() >= 4 && 9570 "Unexpected number of parameters in loop combined directive"); 9571 9572 // Set the proper type for the bounds given what we learned from the 9573 // enclosed loops. 9574 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 9575 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 9576 9577 // Previous lower and upper bounds are obtained from the region 9578 // parameters. 9579 PrevLB = 9580 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 9581 PrevUB = 9582 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 9583 } 9584 } 9585 9586 // Build the iteration variable and its initialization before loop. 9587 ExprResult IV; 9588 ExprResult Init, CombInit; 9589 { 9590 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 9591 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 9592 Expr *RHS = (isOpenMPWorksharingDirective(DKind) || 9593 isOpenMPGenericLoopDirective(DKind) || 9594 isOpenMPTaskLoopDirective(DKind) || 9595 isOpenMPDistributeDirective(DKind) || 9596 isOpenMPLoopTransformationDirective(DKind)) 9597 ? LB.get() 9598 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 9599 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 9600 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 9601 9602 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9603 Expr *CombRHS = 9604 (isOpenMPWorksharingDirective(DKind) || 9605 isOpenMPGenericLoopDirective(DKind) || 9606 isOpenMPTaskLoopDirective(DKind) || 9607 isOpenMPDistributeDirective(DKind)) 9608 ? CombLB.get() 9609 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 9610 CombInit = 9611 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 9612 CombInit = 9613 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 9614 } 9615 } 9616 9617 bool UseStrictCompare = 9618 RealVType->hasUnsignedIntegerRepresentation() && 9619 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 9620 return LIS.IsStrictCompare; 9621 }); 9622 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 9623 // unsigned IV)) for worksharing loops. 9624 SourceLocation CondLoc = AStmt->getBeginLoc(); 9625 Expr *BoundUB = UB.get(); 9626 if (UseStrictCompare) { 9627 BoundUB = 9628 SemaRef 9629 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 9630 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9631 .get(); 9632 BoundUB = 9633 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 9634 } 9635 ExprResult Cond = 9636 (isOpenMPWorksharingDirective(DKind) || 9637 isOpenMPGenericLoopDirective(DKind) || 9638 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind) || 9639 isOpenMPLoopTransformationDirective(DKind)) 9640 ? SemaRef.BuildBinOp(CurScope, CondLoc, 9641 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 9642 BoundUB) 9643 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 9644 NumIterations.get()); 9645 ExprResult CombDistCond; 9646 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9647 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 9648 NumIterations.get()); 9649 } 9650 9651 ExprResult CombCond; 9652 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9653 Expr *BoundCombUB = CombUB.get(); 9654 if (UseStrictCompare) { 9655 BoundCombUB = 9656 SemaRef 9657 .BuildBinOp( 9658 CurScope, CondLoc, BO_Add, BoundCombUB, 9659 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9660 .get(); 9661 BoundCombUB = 9662 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 9663 .get(); 9664 } 9665 CombCond = 9666 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 9667 IV.get(), BoundCombUB); 9668 } 9669 // Loop increment (IV = IV + 1) 9670 SourceLocation IncLoc = AStmt->getBeginLoc(); 9671 ExprResult Inc = 9672 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 9673 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 9674 if (!Inc.isUsable()) 9675 return 0; 9676 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 9677 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 9678 if (!Inc.isUsable()) 9679 return 0; 9680 9681 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 9682 // Used for directives with static scheduling. 9683 // In combined construct, add combined version that use CombLB and CombUB 9684 // base variables for the update 9685 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 9686 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 9687 isOpenMPGenericLoopDirective(DKind) || 9688 isOpenMPDistributeDirective(DKind) || 9689 isOpenMPLoopTransformationDirective(DKind)) { 9690 // LB + ST 9691 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 9692 if (!NextLB.isUsable()) 9693 return 0; 9694 // LB = LB + ST 9695 NextLB = 9696 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 9697 NextLB = 9698 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 9699 if (!NextLB.isUsable()) 9700 return 0; 9701 // UB + ST 9702 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 9703 if (!NextUB.isUsable()) 9704 return 0; 9705 // UB = UB + ST 9706 NextUB = 9707 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 9708 NextUB = 9709 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 9710 if (!NextUB.isUsable()) 9711 return 0; 9712 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9713 CombNextLB = 9714 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 9715 if (!NextLB.isUsable()) 9716 return 0; 9717 // LB = LB + ST 9718 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 9719 CombNextLB.get()); 9720 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 9721 /*DiscardedValue*/ false); 9722 if (!CombNextLB.isUsable()) 9723 return 0; 9724 // UB + ST 9725 CombNextUB = 9726 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 9727 if (!CombNextUB.isUsable()) 9728 return 0; 9729 // UB = UB + ST 9730 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 9731 CombNextUB.get()); 9732 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 9733 /*DiscardedValue*/ false); 9734 if (!CombNextUB.isUsable()) 9735 return 0; 9736 } 9737 } 9738 9739 // Create increment expression for distribute loop when combined in a same 9740 // directive with for as IV = IV + ST; ensure upper bound expression based 9741 // on PrevUB instead of NumIterations - used to implement 'for' when found 9742 // in combination with 'distribute', like in 'distribute parallel for' 9743 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 9744 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 9745 if (isOpenMPLoopBoundSharingDirective(DKind)) { 9746 DistCond = SemaRef.BuildBinOp( 9747 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 9748 assert(DistCond.isUsable() && "distribute cond expr was not built"); 9749 9750 DistInc = 9751 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 9752 assert(DistInc.isUsable() && "distribute inc expr was not built"); 9753 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 9754 DistInc.get()); 9755 DistInc = 9756 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 9757 assert(DistInc.isUsable() && "distribute inc expr was not built"); 9758 9759 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 9760 // construct 9761 ExprResult NewPrevUB = PrevUB; 9762 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 9763 if (!SemaRef.Context.hasSameType(UB.get()->getType(), 9764 PrevUB.get()->getType())) { 9765 NewPrevUB = SemaRef.BuildCStyleCastExpr( 9766 DistEUBLoc, 9767 SemaRef.Context.getTrivialTypeSourceInfo(UB.get()->getType()), 9768 DistEUBLoc, NewPrevUB.get()); 9769 if (!NewPrevUB.isUsable()) 9770 return 0; 9771 } 9772 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, 9773 UB.get(), NewPrevUB.get()); 9774 ExprResult CondOp = SemaRef.ActOnConditionalOp( 9775 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), NewPrevUB.get(), UB.get()); 9776 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 9777 CondOp.get()); 9778 PrevEUB = 9779 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 9780 9781 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 9782 // parallel for is in combination with a distribute directive with 9783 // schedule(static, 1) 9784 Expr *BoundPrevUB = PrevUB.get(); 9785 if (UseStrictCompare) { 9786 BoundPrevUB = 9787 SemaRef 9788 .BuildBinOp( 9789 CurScope, CondLoc, BO_Add, BoundPrevUB, 9790 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 9791 .get(); 9792 BoundPrevUB = 9793 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 9794 .get(); 9795 } 9796 ParForInDistCond = 9797 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 9798 IV.get(), BoundPrevUB); 9799 } 9800 9801 // Build updates and final values of the loop counters. 9802 bool HasErrors = false; 9803 Built.Counters.resize(NestedLoopCount); 9804 Built.Inits.resize(NestedLoopCount); 9805 Built.Updates.resize(NestedLoopCount); 9806 Built.Finals.resize(NestedLoopCount); 9807 Built.DependentCounters.resize(NestedLoopCount); 9808 Built.DependentInits.resize(NestedLoopCount); 9809 Built.FinalsConditions.resize(NestedLoopCount); 9810 { 9811 // We implement the following algorithm for obtaining the 9812 // original loop iteration variable values based on the 9813 // value of the collapsed loop iteration variable IV. 9814 // 9815 // Let n+1 be the number of collapsed loops in the nest. 9816 // Iteration variables (I0, I1, .... In) 9817 // Iteration counts (N0, N1, ... Nn) 9818 // 9819 // Acc = IV; 9820 // 9821 // To compute Ik for loop k, 0 <= k <= n, generate: 9822 // Prod = N(k+1) * N(k+2) * ... * Nn; 9823 // Ik = Acc / Prod; 9824 // Acc -= Ik * Prod; 9825 // 9826 ExprResult Acc = IV; 9827 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 9828 LoopIterationSpace &IS = IterSpaces[Cnt]; 9829 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 9830 ExprResult Iter; 9831 9832 // Compute prod 9833 ExprResult Prod = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 9834 for (unsigned int K = Cnt + 1; K < NestedLoopCount; ++K) 9835 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 9836 IterSpaces[K].NumIterations); 9837 9838 // Iter = Acc / Prod 9839 // If there is at least one more inner loop to avoid 9840 // multiplication by 1. 9841 if (Cnt + 1 < NestedLoopCount) 9842 Iter = 9843 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, Acc.get(), Prod.get()); 9844 else 9845 Iter = Acc; 9846 if (!Iter.isUsable()) { 9847 HasErrors = true; 9848 break; 9849 } 9850 9851 // Update Acc: 9852 // Acc -= Iter * Prod 9853 // Check if there is at least one more inner loop to avoid 9854 // multiplication by 1. 9855 if (Cnt + 1 < NestedLoopCount) 9856 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Iter.get(), 9857 Prod.get()); 9858 else 9859 Prod = Iter; 9860 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, Acc.get(), Prod.get()); 9861 9862 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 9863 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 9864 DeclRefExpr *CounterVar = buildDeclRefExpr( 9865 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 9866 /*RefersToCapture=*/true); 9867 ExprResult Init = 9868 buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 9869 IS.CounterInit, IS.IsNonRectangularLB, Captures); 9870 if (!Init.isUsable()) { 9871 HasErrors = true; 9872 break; 9873 } 9874 ExprResult Update = buildCounterUpdate( 9875 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 9876 IS.CounterStep, IS.Subtract, IS.IsNonRectangularLB, &Captures); 9877 if (!Update.isUsable()) { 9878 HasErrors = true; 9879 break; 9880 } 9881 9882 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 9883 ExprResult Final = 9884 buildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 9885 IS.CounterInit, IS.NumIterations, IS.CounterStep, 9886 IS.Subtract, IS.IsNonRectangularLB, &Captures); 9887 if (!Final.isUsable()) { 9888 HasErrors = true; 9889 break; 9890 } 9891 9892 if (!Update.isUsable() || !Final.isUsable()) { 9893 HasErrors = true; 9894 break; 9895 } 9896 // Save results 9897 Built.Counters[Cnt] = IS.CounterVar; 9898 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 9899 Built.Inits[Cnt] = Init.get(); 9900 Built.Updates[Cnt] = Update.get(); 9901 Built.Finals[Cnt] = Final.get(); 9902 Built.DependentCounters[Cnt] = nullptr; 9903 Built.DependentInits[Cnt] = nullptr; 9904 Built.FinalsConditions[Cnt] = nullptr; 9905 if (IS.IsNonRectangularLB || IS.IsNonRectangularUB) { 9906 Built.DependentCounters[Cnt] = 9907 Built.Counters[NestedLoopCount - 1 - IS.LoopDependentIdx]; 9908 Built.DependentInits[Cnt] = 9909 Built.Inits[NestedLoopCount - 1 - IS.LoopDependentIdx]; 9910 Built.FinalsConditions[Cnt] = IS.FinalCondition; 9911 } 9912 } 9913 } 9914 9915 if (HasErrors) 9916 return 0; 9917 9918 // Save results 9919 Built.IterationVarRef = IV.get(); 9920 Built.LastIteration = LastIteration.get(); 9921 Built.NumIterations = NumIterations.get(); 9922 Built.CalcLastIteration = SemaRef 9923 .ActOnFinishFullExpr(CalcLastIteration.get(), 9924 /*DiscardedValue=*/false) 9925 .get(); 9926 Built.PreCond = PreCond.get(); 9927 Built.PreInits = buildPreInits(C, Captures); 9928 Built.Cond = Cond.get(); 9929 Built.Init = Init.get(); 9930 Built.Inc = Inc.get(); 9931 Built.LB = LB.get(); 9932 Built.UB = UB.get(); 9933 Built.IL = IL.get(); 9934 Built.ST = ST.get(); 9935 Built.EUB = EUB.get(); 9936 Built.NLB = NextLB.get(); 9937 Built.NUB = NextUB.get(); 9938 Built.PrevLB = PrevLB.get(); 9939 Built.PrevUB = PrevUB.get(); 9940 Built.DistInc = DistInc.get(); 9941 Built.PrevEUB = PrevEUB.get(); 9942 Built.DistCombinedFields.LB = CombLB.get(); 9943 Built.DistCombinedFields.UB = CombUB.get(); 9944 Built.DistCombinedFields.EUB = CombEUB.get(); 9945 Built.DistCombinedFields.Init = CombInit.get(); 9946 Built.DistCombinedFields.Cond = CombCond.get(); 9947 Built.DistCombinedFields.NLB = CombNextLB.get(); 9948 Built.DistCombinedFields.NUB = CombNextUB.get(); 9949 Built.DistCombinedFields.DistCond = CombDistCond.get(); 9950 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 9951 9952 return NestedLoopCount; 9953 } 9954 9955 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 9956 auto CollapseClauses = 9957 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 9958 if (CollapseClauses.begin() != CollapseClauses.end()) 9959 return (*CollapseClauses.begin())->getNumForLoops(); 9960 return nullptr; 9961 } 9962 9963 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 9964 auto OrderedClauses = 9965 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 9966 if (OrderedClauses.begin() != OrderedClauses.end()) 9967 return (*OrderedClauses.begin())->getNumForLoops(); 9968 return nullptr; 9969 } 9970 9971 static bool checkSimdlenSafelenSpecified(Sema &S, 9972 const ArrayRef<OMPClause *> Clauses) { 9973 const OMPSafelenClause *Safelen = nullptr; 9974 const OMPSimdlenClause *Simdlen = nullptr; 9975 9976 for (const OMPClause *Clause : Clauses) { 9977 if (Clause->getClauseKind() == OMPC_safelen) 9978 Safelen = cast<OMPSafelenClause>(Clause); 9979 else if (Clause->getClauseKind() == OMPC_simdlen) 9980 Simdlen = cast<OMPSimdlenClause>(Clause); 9981 if (Safelen && Simdlen) 9982 break; 9983 } 9984 9985 if (Simdlen && Safelen) { 9986 const Expr *SimdlenLength = Simdlen->getSimdlen(); 9987 const Expr *SafelenLength = Safelen->getSafelen(); 9988 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 9989 SimdlenLength->isInstantiationDependent() || 9990 SimdlenLength->containsUnexpandedParameterPack()) 9991 return false; 9992 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 9993 SafelenLength->isInstantiationDependent() || 9994 SafelenLength->containsUnexpandedParameterPack()) 9995 return false; 9996 Expr::EvalResult SimdlenResult, SafelenResult; 9997 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 9998 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 9999 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 10000 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 10001 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 10002 // If both simdlen and safelen clauses are specified, the value of the 10003 // simdlen parameter must be less than or equal to the value of the safelen 10004 // parameter. 10005 if (SimdlenRes > SafelenRes) { 10006 S.Diag(SimdlenLength->getExprLoc(), 10007 diag::err_omp_wrong_simdlen_safelen_values) 10008 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 10009 return true; 10010 } 10011 } 10012 return false; 10013 } 10014 10015 StmtResult 10016 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 10017 SourceLocation StartLoc, SourceLocation EndLoc, 10018 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10019 if (!AStmt) 10020 return StmtError(); 10021 10022 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10023 OMPLoopBasedDirective::HelperExprs B; 10024 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10025 // define the nested loops number. 10026 unsigned NestedLoopCount = checkOpenMPLoop( 10027 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10028 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10029 if (NestedLoopCount == 0) 10030 return StmtError(); 10031 10032 assert((CurContext->isDependentContext() || B.builtAll()) && 10033 "omp simd loop exprs were not built"); 10034 10035 if (!CurContext->isDependentContext()) { 10036 // Finalize the clauses that need pre-built expressions for CodeGen. 10037 for (OMPClause *C : Clauses) { 10038 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10039 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10040 B.NumIterations, *this, CurScope, 10041 DSAStack)) 10042 return StmtError(); 10043 } 10044 } 10045 10046 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10047 return StmtError(); 10048 10049 setFunctionHasBranchProtectedScope(); 10050 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 10051 Clauses, AStmt, B); 10052 } 10053 10054 StmtResult 10055 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 10056 SourceLocation StartLoc, SourceLocation EndLoc, 10057 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10058 if (!AStmt) 10059 return StmtError(); 10060 10061 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10062 OMPLoopBasedDirective::HelperExprs B; 10063 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10064 // define the nested loops number. 10065 unsigned NestedLoopCount = checkOpenMPLoop( 10066 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10067 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10068 if (NestedLoopCount == 0) 10069 return StmtError(); 10070 10071 assert((CurContext->isDependentContext() || B.builtAll()) && 10072 "omp for loop exprs were not built"); 10073 10074 if (!CurContext->isDependentContext()) { 10075 // Finalize the clauses that need pre-built expressions for CodeGen. 10076 for (OMPClause *C : Clauses) { 10077 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10078 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10079 B.NumIterations, *this, CurScope, 10080 DSAStack)) 10081 return StmtError(); 10082 } 10083 } 10084 10085 setFunctionHasBranchProtectedScope(); 10086 return OMPForDirective::Create( 10087 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10088 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10089 } 10090 10091 StmtResult Sema::ActOnOpenMPForSimdDirective( 10092 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10093 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10094 if (!AStmt) 10095 return StmtError(); 10096 10097 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10098 OMPLoopBasedDirective::HelperExprs B; 10099 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10100 // define the nested loops number. 10101 unsigned NestedLoopCount = 10102 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 10103 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10104 VarsWithImplicitDSA, B); 10105 if (NestedLoopCount == 0) 10106 return StmtError(); 10107 10108 assert((CurContext->isDependentContext() || B.builtAll()) && 10109 "omp for simd loop exprs were not built"); 10110 10111 if (!CurContext->isDependentContext()) { 10112 // Finalize the clauses that need pre-built expressions for CodeGen. 10113 for (OMPClause *C : Clauses) { 10114 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10115 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10116 B.NumIterations, *this, CurScope, 10117 DSAStack)) 10118 return StmtError(); 10119 } 10120 } 10121 10122 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10123 return StmtError(); 10124 10125 setFunctionHasBranchProtectedScope(); 10126 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 10127 Clauses, AStmt, B); 10128 } 10129 10130 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 10131 Stmt *AStmt, 10132 SourceLocation StartLoc, 10133 SourceLocation EndLoc) { 10134 if (!AStmt) 10135 return StmtError(); 10136 10137 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10138 auto BaseStmt = AStmt; 10139 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 10140 BaseStmt = CS->getCapturedStmt(); 10141 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 10142 auto S = C->children(); 10143 if (S.begin() == S.end()) 10144 return StmtError(); 10145 // All associated statements must be '#pragma omp section' except for 10146 // the first one. 10147 for (Stmt *SectionStmt : llvm::drop_begin(S)) { 10148 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 10149 if (SectionStmt) 10150 Diag(SectionStmt->getBeginLoc(), 10151 diag::err_omp_sections_substmt_not_section); 10152 return StmtError(); 10153 } 10154 cast<OMPSectionDirective>(SectionStmt) 10155 ->setHasCancel(DSAStack->isCancelRegion()); 10156 } 10157 } else { 10158 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 10159 return StmtError(); 10160 } 10161 10162 setFunctionHasBranchProtectedScope(); 10163 10164 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10165 DSAStack->getTaskgroupReductionRef(), 10166 DSAStack->isCancelRegion()); 10167 } 10168 10169 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 10170 SourceLocation StartLoc, 10171 SourceLocation EndLoc) { 10172 if (!AStmt) 10173 return StmtError(); 10174 10175 setFunctionHasBranchProtectedScope(); 10176 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 10177 10178 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 10179 DSAStack->isCancelRegion()); 10180 } 10181 10182 static Expr *getDirectCallExpr(Expr *E) { 10183 E = E->IgnoreParenCasts()->IgnoreImplicit(); 10184 if (auto *CE = dyn_cast<CallExpr>(E)) 10185 if (CE->getDirectCallee()) 10186 return E; 10187 return nullptr; 10188 } 10189 10190 StmtResult Sema::ActOnOpenMPDispatchDirective(ArrayRef<OMPClause *> Clauses, 10191 Stmt *AStmt, 10192 SourceLocation StartLoc, 10193 SourceLocation EndLoc) { 10194 if (!AStmt) 10195 return StmtError(); 10196 10197 Stmt *S = cast<CapturedStmt>(AStmt)->getCapturedStmt(); 10198 10199 // 5.1 OpenMP 10200 // expression-stmt : an expression statement with one of the following forms: 10201 // expression = target-call ( [expression-list] ); 10202 // target-call ( [expression-list] ); 10203 10204 SourceLocation TargetCallLoc; 10205 10206 if (!CurContext->isDependentContext()) { 10207 Expr *TargetCall = nullptr; 10208 10209 auto *E = dyn_cast<Expr>(S); 10210 if (!E) { 10211 Diag(S->getBeginLoc(), diag::err_omp_dispatch_statement_call); 10212 return StmtError(); 10213 } 10214 10215 E = E->IgnoreParenCasts()->IgnoreImplicit(); 10216 10217 if (auto *BO = dyn_cast<BinaryOperator>(E)) { 10218 if (BO->getOpcode() == BO_Assign) 10219 TargetCall = getDirectCallExpr(BO->getRHS()); 10220 } else { 10221 if (auto *COCE = dyn_cast<CXXOperatorCallExpr>(E)) 10222 if (COCE->getOperator() == OO_Equal) 10223 TargetCall = getDirectCallExpr(COCE->getArg(1)); 10224 if (!TargetCall) 10225 TargetCall = getDirectCallExpr(E); 10226 } 10227 if (!TargetCall) { 10228 Diag(E->getBeginLoc(), diag::err_omp_dispatch_statement_call); 10229 return StmtError(); 10230 } 10231 TargetCallLoc = TargetCall->getExprLoc(); 10232 } 10233 10234 setFunctionHasBranchProtectedScope(); 10235 10236 return OMPDispatchDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10237 TargetCallLoc); 10238 } 10239 10240 static bool checkGenericLoopLastprivate(Sema &S, ArrayRef<OMPClause *> Clauses, 10241 OpenMPDirectiveKind K, 10242 DSAStackTy *Stack) { 10243 bool ErrorFound = false; 10244 for (OMPClause *C : Clauses) { 10245 if (auto *LPC = dyn_cast<OMPLastprivateClause>(C)) { 10246 for (Expr *RefExpr : LPC->varlists()) { 10247 SourceLocation ELoc; 10248 SourceRange ERange; 10249 Expr *SimpleRefExpr = RefExpr; 10250 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange); 10251 if (ValueDecl *D = Res.first) { 10252 auto &&Info = Stack->isLoopControlVariable(D); 10253 if (!Info.first) { 10254 S.Diag(ELoc, diag::err_omp_lastprivate_loop_var_non_loop_iteration) 10255 << getOpenMPDirectiveName(K); 10256 ErrorFound = true; 10257 } 10258 } 10259 } 10260 } 10261 } 10262 return ErrorFound; 10263 } 10264 10265 StmtResult Sema::ActOnOpenMPGenericLoopDirective( 10266 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10267 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10268 if (!AStmt) 10269 return StmtError(); 10270 10271 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10272 // A list item may not appear in a lastprivate clause unless it is the 10273 // loop iteration variable of a loop that is associated with the construct. 10274 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_loop, DSAStack)) 10275 return StmtError(); 10276 10277 auto *CS = cast<CapturedStmt>(AStmt); 10278 // 1.2.2 OpenMP Language Terminology 10279 // Structured block - An executable statement with a single entry at the 10280 // top and a single exit at the bottom. 10281 // The point of exit cannot be a branch out of the structured block. 10282 // longjmp() and throw() must not violate the entry/exit criteria. 10283 CS->getCapturedDecl()->setNothrow(); 10284 10285 OMPLoopDirective::HelperExprs B; 10286 // In presence of clause 'collapse', it will define the nested loops number. 10287 unsigned NestedLoopCount = checkOpenMPLoop( 10288 OMPD_loop, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 10289 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 10290 if (NestedLoopCount == 0) 10291 return StmtError(); 10292 10293 assert((CurContext->isDependentContext() || B.builtAll()) && 10294 "omp loop exprs were not built"); 10295 10296 setFunctionHasBranchProtectedScope(); 10297 return OMPGenericLoopDirective::Create(Context, StartLoc, EndLoc, 10298 NestedLoopCount, Clauses, AStmt, B); 10299 } 10300 10301 StmtResult Sema::ActOnOpenMPTeamsGenericLoopDirective( 10302 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10303 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10304 if (!AStmt) 10305 return StmtError(); 10306 10307 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10308 // A list item may not appear in a lastprivate clause unless it is the 10309 // loop iteration variable of a loop that is associated with the construct. 10310 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_teams_loop, DSAStack)) 10311 return StmtError(); 10312 10313 auto *CS = cast<CapturedStmt>(AStmt); 10314 // 1.2.2 OpenMP Language Terminology 10315 // Structured block - An executable statement with a single entry at the 10316 // top and a single exit at the bottom. 10317 // The point of exit cannot be a branch out of the structured block. 10318 // longjmp() and throw() must not violate the entry/exit criteria. 10319 CS->getCapturedDecl()->setNothrow(); 10320 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_loop); 10321 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10322 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10323 // 1.2.2 OpenMP Language Terminology 10324 // Structured block - An executable statement with a single entry at the 10325 // top and a single exit at the bottom. 10326 // The point of exit cannot be a branch out of the structured block. 10327 // longjmp() and throw() must not violate the entry/exit criteria. 10328 CS->getCapturedDecl()->setNothrow(); 10329 } 10330 10331 OMPLoopDirective::HelperExprs B; 10332 // In presence of clause 'collapse', it will define the nested loops number. 10333 unsigned NestedLoopCount = 10334 checkOpenMPLoop(OMPD_teams_loop, getCollapseNumberExpr(Clauses), 10335 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10336 VarsWithImplicitDSA, B); 10337 if (NestedLoopCount == 0) 10338 return StmtError(); 10339 10340 assert((CurContext->isDependentContext() || B.builtAll()) && 10341 "omp loop exprs were not built"); 10342 10343 setFunctionHasBranchProtectedScope(); 10344 DSAStack->setParentTeamsRegionLoc(StartLoc); 10345 10346 return OMPTeamsGenericLoopDirective::Create( 10347 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10348 } 10349 10350 StmtResult Sema::ActOnOpenMPTargetTeamsGenericLoopDirective( 10351 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10352 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10353 if (!AStmt) 10354 return StmtError(); 10355 10356 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10357 // A list item may not appear in a lastprivate clause unless it is the 10358 // loop iteration variable of a loop that is associated with the construct. 10359 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_teams_loop, 10360 DSAStack)) 10361 return StmtError(); 10362 10363 auto *CS = cast<CapturedStmt>(AStmt); 10364 // 1.2.2 OpenMP Language Terminology 10365 // Structured block - An executable statement with a single entry at the 10366 // top and a single exit at the bottom. 10367 // The point of exit cannot be a branch out of the structured block. 10368 // longjmp() and throw() must not violate the entry/exit criteria. 10369 CS->getCapturedDecl()->setNothrow(); 10370 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams_loop); 10371 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10372 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10373 // 1.2.2 OpenMP Language Terminology 10374 // Structured block - An executable statement with a single entry at the 10375 // top and a single exit at the bottom. 10376 // The point of exit cannot be a branch out of the structured block. 10377 // longjmp() and throw() must not violate the entry/exit criteria. 10378 CS->getCapturedDecl()->setNothrow(); 10379 } 10380 10381 OMPLoopDirective::HelperExprs B; 10382 // In presence of clause 'collapse', it will define the nested loops number. 10383 unsigned NestedLoopCount = 10384 checkOpenMPLoop(OMPD_target_teams_loop, getCollapseNumberExpr(Clauses), 10385 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10386 VarsWithImplicitDSA, B); 10387 if (NestedLoopCount == 0) 10388 return StmtError(); 10389 10390 assert((CurContext->isDependentContext() || B.builtAll()) && 10391 "omp loop exprs were not built"); 10392 10393 setFunctionHasBranchProtectedScope(); 10394 10395 return OMPTargetTeamsGenericLoopDirective::Create( 10396 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10397 } 10398 10399 StmtResult Sema::ActOnOpenMPParallelGenericLoopDirective( 10400 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10401 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10402 if (!AStmt) 10403 return StmtError(); 10404 10405 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10406 // A list item may not appear in a lastprivate clause unless it is the 10407 // loop iteration variable of a loop that is associated with the construct. 10408 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_parallel_loop, DSAStack)) 10409 return StmtError(); 10410 10411 auto *CS = cast<CapturedStmt>(AStmt); 10412 // 1.2.2 OpenMP Language Terminology 10413 // Structured block - An executable statement with a single entry at the 10414 // top and a single exit at the bottom. 10415 // The point of exit cannot be a branch out of the structured block. 10416 // longjmp() and throw() must not violate the entry/exit criteria. 10417 CS->getCapturedDecl()->setNothrow(); 10418 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_parallel_loop); 10419 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10420 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10421 // 1.2.2 OpenMP Language Terminology 10422 // Structured block - An executable statement with a single entry at the 10423 // top and a single exit at the bottom. 10424 // The point of exit cannot be a branch out of the structured block. 10425 // longjmp() and throw() must not violate the entry/exit criteria. 10426 CS->getCapturedDecl()->setNothrow(); 10427 } 10428 10429 OMPLoopDirective::HelperExprs B; 10430 // In presence of clause 'collapse', it will define the nested loops number. 10431 unsigned NestedLoopCount = 10432 checkOpenMPLoop(OMPD_parallel_loop, getCollapseNumberExpr(Clauses), 10433 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10434 VarsWithImplicitDSA, B); 10435 if (NestedLoopCount == 0) 10436 return StmtError(); 10437 10438 assert((CurContext->isDependentContext() || B.builtAll()) && 10439 "omp loop exprs were not built"); 10440 10441 setFunctionHasBranchProtectedScope(); 10442 10443 return OMPParallelGenericLoopDirective::Create( 10444 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10445 } 10446 10447 StmtResult Sema::ActOnOpenMPTargetParallelGenericLoopDirective( 10448 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10449 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10450 if (!AStmt) 10451 return StmtError(); 10452 10453 // OpenMP 5.1 [2.11.7, loop construct, Restrictions] 10454 // A list item may not appear in a lastprivate clause unless it is the 10455 // loop iteration variable of a loop that is associated with the construct. 10456 if (checkGenericLoopLastprivate(*this, Clauses, OMPD_target_parallel_loop, 10457 DSAStack)) 10458 return StmtError(); 10459 10460 auto *CS = cast<CapturedStmt>(AStmt); 10461 // 1.2.2 OpenMP Language Terminology 10462 // Structured block - An executable statement with a single entry at the 10463 // top and a single exit at the bottom. 10464 // The point of exit cannot be a branch out of the structured block. 10465 // longjmp() and throw() must not violate the entry/exit criteria. 10466 CS->getCapturedDecl()->setNothrow(); 10467 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_loop); 10468 ThisCaptureLevel > 1; --ThisCaptureLevel) { 10469 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 10470 // 1.2.2 OpenMP Language Terminology 10471 // Structured block - An executable statement with a single entry at the 10472 // top and a single exit at the bottom. 10473 // The point of exit cannot be a branch out of the structured block. 10474 // longjmp() and throw() must not violate the entry/exit criteria. 10475 CS->getCapturedDecl()->setNothrow(); 10476 } 10477 10478 OMPLoopDirective::HelperExprs B; 10479 // In presence of clause 'collapse', it will define the nested loops number. 10480 unsigned NestedLoopCount = 10481 checkOpenMPLoop(OMPD_target_parallel_loop, getCollapseNumberExpr(Clauses), 10482 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 10483 VarsWithImplicitDSA, B); 10484 if (NestedLoopCount == 0) 10485 return StmtError(); 10486 10487 assert((CurContext->isDependentContext() || B.builtAll()) && 10488 "omp loop exprs were not built"); 10489 10490 setFunctionHasBranchProtectedScope(); 10491 10492 return OMPTargetParallelGenericLoopDirective::Create( 10493 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10494 } 10495 10496 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 10497 Stmt *AStmt, 10498 SourceLocation StartLoc, 10499 SourceLocation EndLoc) { 10500 if (!AStmt) 10501 return StmtError(); 10502 10503 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10504 10505 setFunctionHasBranchProtectedScope(); 10506 10507 // OpenMP [2.7.3, single Construct, Restrictions] 10508 // The copyprivate clause must not be used with the nowait clause. 10509 const OMPClause *Nowait = nullptr; 10510 const OMPClause *Copyprivate = nullptr; 10511 for (const OMPClause *Clause : Clauses) { 10512 if (Clause->getClauseKind() == OMPC_nowait) 10513 Nowait = Clause; 10514 else if (Clause->getClauseKind() == OMPC_copyprivate) 10515 Copyprivate = Clause; 10516 if (Copyprivate && Nowait) { 10517 Diag(Copyprivate->getBeginLoc(), 10518 diag::err_omp_single_copyprivate_with_nowait); 10519 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 10520 return StmtError(); 10521 } 10522 } 10523 10524 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10525 } 10526 10527 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 10528 SourceLocation StartLoc, 10529 SourceLocation EndLoc) { 10530 if (!AStmt) 10531 return StmtError(); 10532 10533 setFunctionHasBranchProtectedScope(); 10534 10535 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 10536 } 10537 10538 StmtResult Sema::ActOnOpenMPMaskedDirective(ArrayRef<OMPClause *> Clauses, 10539 Stmt *AStmt, 10540 SourceLocation StartLoc, 10541 SourceLocation EndLoc) { 10542 if (!AStmt) 10543 return StmtError(); 10544 10545 setFunctionHasBranchProtectedScope(); 10546 10547 return OMPMaskedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 10548 } 10549 10550 StmtResult Sema::ActOnOpenMPCriticalDirective( 10551 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 10552 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 10553 if (!AStmt) 10554 return StmtError(); 10555 10556 bool ErrorFound = false; 10557 llvm::APSInt Hint; 10558 SourceLocation HintLoc; 10559 bool DependentHint = false; 10560 for (const OMPClause *C : Clauses) { 10561 if (C->getClauseKind() == OMPC_hint) { 10562 if (!DirName.getName()) { 10563 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 10564 ErrorFound = true; 10565 } 10566 Expr *E = cast<OMPHintClause>(C)->getHint(); 10567 if (E->isTypeDependent() || E->isValueDependent() || 10568 E->isInstantiationDependent()) { 10569 DependentHint = true; 10570 } else { 10571 Hint = E->EvaluateKnownConstInt(Context); 10572 HintLoc = C->getBeginLoc(); 10573 } 10574 } 10575 } 10576 if (ErrorFound) 10577 return StmtError(); 10578 const auto Pair = DSAStack->getCriticalWithHint(DirName); 10579 if (Pair.first && DirName.getName() && !DependentHint) { 10580 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 10581 Diag(StartLoc, diag::err_omp_critical_with_hint); 10582 if (HintLoc.isValid()) 10583 Diag(HintLoc, diag::note_omp_critical_hint_here) 10584 << 0 << toString(Hint, /*Radix=*/10, /*Signed=*/false); 10585 else 10586 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 10587 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 10588 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 10589 << 1 10590 << toString(C->getHint()->EvaluateKnownConstInt(Context), 10591 /*Radix=*/10, /*Signed=*/false); 10592 } else { 10593 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 10594 } 10595 } 10596 } 10597 10598 setFunctionHasBranchProtectedScope(); 10599 10600 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 10601 Clauses, AStmt); 10602 if (!Pair.first && DirName.getName() && !DependentHint) 10603 DSAStack->addCriticalWithHint(Dir, Hint); 10604 return Dir; 10605 } 10606 10607 StmtResult Sema::ActOnOpenMPParallelForDirective( 10608 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10609 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10610 if (!AStmt) 10611 return StmtError(); 10612 10613 auto *CS = cast<CapturedStmt>(AStmt); 10614 // 1.2.2 OpenMP Language Terminology 10615 // Structured block - An executable statement with a single entry at the 10616 // top and a single exit at the bottom. 10617 // The point of exit cannot be a branch out of the structured block. 10618 // longjmp() and throw() must not violate the entry/exit criteria. 10619 CS->getCapturedDecl()->setNothrow(); 10620 10621 OMPLoopBasedDirective::HelperExprs B; 10622 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10623 // define the nested loops number. 10624 unsigned NestedLoopCount = 10625 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 10626 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10627 VarsWithImplicitDSA, B); 10628 if (NestedLoopCount == 0) 10629 return StmtError(); 10630 10631 assert((CurContext->isDependentContext() || B.builtAll()) && 10632 "omp parallel for loop exprs were not built"); 10633 10634 if (!CurContext->isDependentContext()) { 10635 // Finalize the clauses that need pre-built expressions for CodeGen. 10636 for (OMPClause *C : Clauses) { 10637 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10638 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10639 B.NumIterations, *this, CurScope, 10640 DSAStack)) 10641 return StmtError(); 10642 } 10643 } 10644 10645 setFunctionHasBranchProtectedScope(); 10646 return OMPParallelForDirective::Create( 10647 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 10648 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10649 } 10650 10651 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 10652 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 10653 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 10654 if (!AStmt) 10655 return StmtError(); 10656 10657 auto *CS = cast<CapturedStmt>(AStmt); 10658 // 1.2.2 OpenMP Language Terminology 10659 // Structured block - An executable statement with a single entry at the 10660 // top and a single exit at the bottom. 10661 // The point of exit cannot be a branch out of the structured block. 10662 // longjmp() and throw() must not violate the entry/exit criteria. 10663 CS->getCapturedDecl()->setNothrow(); 10664 10665 OMPLoopBasedDirective::HelperExprs B; 10666 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 10667 // define the nested loops number. 10668 unsigned NestedLoopCount = 10669 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 10670 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 10671 VarsWithImplicitDSA, B); 10672 if (NestedLoopCount == 0) 10673 return StmtError(); 10674 10675 if (!CurContext->isDependentContext()) { 10676 // Finalize the clauses that need pre-built expressions for CodeGen. 10677 for (OMPClause *C : Clauses) { 10678 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 10679 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 10680 B.NumIterations, *this, CurScope, 10681 DSAStack)) 10682 return StmtError(); 10683 } 10684 } 10685 10686 if (checkSimdlenSafelenSpecified(*this, Clauses)) 10687 return StmtError(); 10688 10689 setFunctionHasBranchProtectedScope(); 10690 return OMPParallelForSimdDirective::Create( 10691 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 10692 } 10693 10694 StmtResult 10695 Sema::ActOnOpenMPParallelMasterDirective(ArrayRef<OMPClause *> Clauses, 10696 Stmt *AStmt, SourceLocation StartLoc, 10697 SourceLocation EndLoc) { 10698 if (!AStmt) 10699 return StmtError(); 10700 10701 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10702 auto *CS = cast<CapturedStmt>(AStmt); 10703 // 1.2.2 OpenMP Language Terminology 10704 // Structured block - An executable statement with a single entry at the 10705 // top and a single exit at the bottom. 10706 // The point of exit cannot be a branch out of the structured block. 10707 // longjmp() and throw() must not violate the entry/exit criteria. 10708 CS->getCapturedDecl()->setNothrow(); 10709 10710 setFunctionHasBranchProtectedScope(); 10711 10712 return OMPParallelMasterDirective::Create( 10713 Context, StartLoc, EndLoc, Clauses, AStmt, 10714 DSAStack->getTaskgroupReductionRef()); 10715 } 10716 10717 StmtResult 10718 Sema::ActOnOpenMPParallelMaskedDirective(ArrayRef<OMPClause *> Clauses, 10719 Stmt *AStmt, SourceLocation StartLoc, 10720 SourceLocation EndLoc) { 10721 if (!AStmt) 10722 return StmtError(); 10723 10724 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10725 auto *CS = cast<CapturedStmt>(AStmt); 10726 // 1.2.2 OpenMP Language Terminology 10727 // Structured block - An executable statement with a single entry at the 10728 // top and a single exit at the bottom. 10729 // The point of exit cannot be a branch out of the structured block. 10730 // longjmp() and throw() must not violate the entry/exit criteria. 10731 CS->getCapturedDecl()->setNothrow(); 10732 10733 setFunctionHasBranchProtectedScope(); 10734 10735 return OMPParallelMaskedDirective::Create( 10736 Context, StartLoc, EndLoc, Clauses, AStmt, 10737 DSAStack->getTaskgroupReductionRef()); 10738 } 10739 10740 StmtResult 10741 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 10742 Stmt *AStmt, SourceLocation StartLoc, 10743 SourceLocation EndLoc) { 10744 if (!AStmt) 10745 return StmtError(); 10746 10747 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10748 auto BaseStmt = AStmt; 10749 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 10750 BaseStmt = CS->getCapturedStmt(); 10751 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 10752 auto S = C->children(); 10753 if (S.begin() == S.end()) 10754 return StmtError(); 10755 // All associated statements must be '#pragma omp section' except for 10756 // the first one. 10757 for (Stmt *SectionStmt : llvm::drop_begin(S)) { 10758 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 10759 if (SectionStmt) 10760 Diag(SectionStmt->getBeginLoc(), 10761 diag::err_omp_parallel_sections_substmt_not_section); 10762 return StmtError(); 10763 } 10764 cast<OMPSectionDirective>(SectionStmt) 10765 ->setHasCancel(DSAStack->isCancelRegion()); 10766 } 10767 } else { 10768 Diag(AStmt->getBeginLoc(), 10769 diag::err_omp_parallel_sections_not_compound_stmt); 10770 return StmtError(); 10771 } 10772 10773 setFunctionHasBranchProtectedScope(); 10774 10775 return OMPParallelSectionsDirective::Create( 10776 Context, StartLoc, EndLoc, Clauses, AStmt, 10777 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 10778 } 10779 10780 /// Find and diagnose mutually exclusive clause kinds. 10781 static bool checkMutuallyExclusiveClauses( 10782 Sema &S, ArrayRef<OMPClause *> Clauses, 10783 ArrayRef<OpenMPClauseKind> MutuallyExclusiveClauses) { 10784 const OMPClause *PrevClause = nullptr; 10785 bool ErrorFound = false; 10786 for (const OMPClause *C : Clauses) { 10787 if (llvm::is_contained(MutuallyExclusiveClauses, C->getClauseKind())) { 10788 if (!PrevClause) { 10789 PrevClause = C; 10790 } else if (PrevClause->getClauseKind() != C->getClauseKind()) { 10791 S.Diag(C->getBeginLoc(), diag::err_omp_clauses_mutually_exclusive) 10792 << getOpenMPClauseName(C->getClauseKind()) 10793 << getOpenMPClauseName(PrevClause->getClauseKind()); 10794 S.Diag(PrevClause->getBeginLoc(), diag::note_omp_previous_clause) 10795 << getOpenMPClauseName(PrevClause->getClauseKind()); 10796 ErrorFound = true; 10797 } 10798 } 10799 } 10800 return ErrorFound; 10801 } 10802 10803 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 10804 Stmt *AStmt, SourceLocation StartLoc, 10805 SourceLocation EndLoc) { 10806 if (!AStmt) 10807 return StmtError(); 10808 10809 // OpenMP 5.0, 2.10.1 task Construct 10810 // If a detach clause appears on the directive, then a mergeable clause cannot 10811 // appear on the same directive. 10812 if (checkMutuallyExclusiveClauses(*this, Clauses, 10813 {OMPC_detach, OMPC_mergeable})) 10814 return StmtError(); 10815 10816 auto *CS = cast<CapturedStmt>(AStmt); 10817 // 1.2.2 OpenMP Language Terminology 10818 // Structured block - An executable statement with a single entry at the 10819 // top and a single exit at the bottom. 10820 // The point of exit cannot be a branch out of the structured block. 10821 // longjmp() and throw() must not violate the entry/exit criteria. 10822 CS->getCapturedDecl()->setNothrow(); 10823 10824 setFunctionHasBranchProtectedScope(); 10825 10826 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 10827 DSAStack->isCancelRegion()); 10828 } 10829 10830 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 10831 SourceLocation EndLoc) { 10832 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 10833 } 10834 10835 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 10836 SourceLocation EndLoc) { 10837 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 10838 } 10839 10840 StmtResult Sema::ActOnOpenMPTaskwaitDirective(ArrayRef<OMPClause *> Clauses, 10841 SourceLocation StartLoc, 10842 SourceLocation EndLoc) { 10843 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc, Clauses); 10844 } 10845 10846 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 10847 Stmt *AStmt, 10848 SourceLocation StartLoc, 10849 SourceLocation EndLoc) { 10850 if (!AStmt) 10851 return StmtError(); 10852 10853 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 10854 10855 setFunctionHasBranchProtectedScope(); 10856 10857 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 10858 AStmt, 10859 DSAStack->getTaskgroupReductionRef()); 10860 } 10861 10862 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 10863 SourceLocation StartLoc, 10864 SourceLocation EndLoc) { 10865 OMPFlushClause *FC = nullptr; 10866 OMPClause *OrderClause = nullptr; 10867 for (OMPClause *C : Clauses) { 10868 if (C->getClauseKind() == OMPC_flush) 10869 FC = cast<OMPFlushClause>(C); 10870 else 10871 OrderClause = C; 10872 } 10873 OpenMPClauseKind MemOrderKind = OMPC_unknown; 10874 SourceLocation MemOrderLoc; 10875 for (const OMPClause *C : Clauses) { 10876 if (C->getClauseKind() == OMPC_acq_rel || 10877 C->getClauseKind() == OMPC_acquire || 10878 C->getClauseKind() == OMPC_release) { 10879 if (MemOrderKind != OMPC_unknown) { 10880 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 10881 << getOpenMPDirectiveName(OMPD_flush) << 1 10882 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 10883 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 10884 << getOpenMPClauseName(MemOrderKind); 10885 } else { 10886 MemOrderKind = C->getClauseKind(); 10887 MemOrderLoc = C->getBeginLoc(); 10888 } 10889 } 10890 } 10891 if (FC && OrderClause) { 10892 Diag(FC->getLParenLoc(), diag::err_omp_flush_order_clause_and_list) 10893 << getOpenMPClauseName(OrderClause->getClauseKind()); 10894 Diag(OrderClause->getBeginLoc(), diag::note_omp_flush_order_clause_here) 10895 << getOpenMPClauseName(OrderClause->getClauseKind()); 10896 return StmtError(); 10897 } 10898 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 10899 } 10900 10901 StmtResult Sema::ActOnOpenMPDepobjDirective(ArrayRef<OMPClause *> Clauses, 10902 SourceLocation StartLoc, 10903 SourceLocation EndLoc) { 10904 if (Clauses.empty()) { 10905 Diag(StartLoc, diag::err_omp_depobj_expected); 10906 return StmtError(); 10907 } else if (Clauses[0]->getClauseKind() != OMPC_depobj) { 10908 Diag(Clauses[0]->getBeginLoc(), diag::err_omp_depobj_expected); 10909 return StmtError(); 10910 } 10911 // Only depobj expression and another single clause is allowed. 10912 if (Clauses.size() > 2) { 10913 Diag(Clauses[2]->getBeginLoc(), 10914 diag::err_omp_depobj_single_clause_expected); 10915 return StmtError(); 10916 } else if (Clauses.size() < 1) { 10917 Diag(Clauses[0]->getEndLoc(), diag::err_omp_depobj_single_clause_expected); 10918 return StmtError(); 10919 } 10920 return OMPDepobjDirective::Create(Context, StartLoc, EndLoc, Clauses); 10921 } 10922 10923 StmtResult Sema::ActOnOpenMPScanDirective(ArrayRef<OMPClause *> Clauses, 10924 SourceLocation StartLoc, 10925 SourceLocation EndLoc) { 10926 // Check that exactly one clause is specified. 10927 if (Clauses.size() != 1) { 10928 Diag(Clauses.empty() ? EndLoc : Clauses[1]->getBeginLoc(), 10929 diag::err_omp_scan_single_clause_expected); 10930 return StmtError(); 10931 } 10932 // Check that scan directive is used in the scopeof the OpenMP loop body. 10933 if (Scope *S = DSAStack->getCurScope()) { 10934 Scope *ParentS = S->getParent(); 10935 if (!ParentS || ParentS->getParent() != ParentS->getBreakParent() || 10936 !ParentS->getBreakParent()->isOpenMPLoopScope()) 10937 return StmtError(Diag(StartLoc, diag::err_omp_orphaned_device_directive) 10938 << getOpenMPDirectiveName(OMPD_scan) << 5); 10939 } 10940 // Check that only one instance of scan directives is used in the same outer 10941 // region. 10942 if (DSAStack->doesParentHasScanDirective()) { 10943 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "scan"; 10944 Diag(DSAStack->getParentScanDirectiveLoc(), 10945 diag::note_omp_previous_directive) 10946 << "scan"; 10947 return StmtError(); 10948 } 10949 DSAStack->setParentHasScanDirective(StartLoc); 10950 return OMPScanDirective::Create(Context, StartLoc, EndLoc, Clauses); 10951 } 10952 10953 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 10954 Stmt *AStmt, 10955 SourceLocation StartLoc, 10956 SourceLocation EndLoc) { 10957 const OMPClause *DependFound = nullptr; 10958 const OMPClause *DependSourceClause = nullptr; 10959 const OMPClause *DependSinkClause = nullptr; 10960 bool ErrorFound = false; 10961 const OMPThreadsClause *TC = nullptr; 10962 const OMPSIMDClause *SC = nullptr; 10963 for (const OMPClause *C : Clauses) { 10964 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 10965 DependFound = C; 10966 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 10967 if (DependSourceClause) { 10968 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 10969 << getOpenMPDirectiveName(OMPD_ordered) 10970 << getOpenMPClauseName(OMPC_depend) << 2; 10971 ErrorFound = true; 10972 } else { 10973 DependSourceClause = C; 10974 } 10975 if (DependSinkClause) { 10976 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 10977 << 0; 10978 ErrorFound = true; 10979 } 10980 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 10981 if (DependSourceClause) { 10982 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 10983 << 1; 10984 ErrorFound = true; 10985 } 10986 DependSinkClause = C; 10987 } 10988 } else if (C->getClauseKind() == OMPC_threads) { 10989 TC = cast<OMPThreadsClause>(C); 10990 } else if (C->getClauseKind() == OMPC_simd) { 10991 SC = cast<OMPSIMDClause>(C); 10992 } 10993 } 10994 if (!ErrorFound && !SC && 10995 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 10996 // OpenMP [2.8.1,simd Construct, Restrictions] 10997 // An ordered construct with the simd clause is the only OpenMP construct 10998 // that can appear in the simd region. 10999 Diag(StartLoc, diag::err_omp_prohibited_region_simd) 11000 << (LangOpts.OpenMP >= 50 ? 1 : 0); 11001 ErrorFound = true; 11002 } else if (DependFound && (TC || SC)) { 11003 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 11004 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 11005 ErrorFound = true; 11006 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 11007 Diag(DependFound->getBeginLoc(), 11008 diag::err_omp_ordered_directive_without_param); 11009 ErrorFound = true; 11010 } else if (TC || Clauses.empty()) { 11011 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 11012 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 11013 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 11014 << (TC != nullptr); 11015 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param) << 1; 11016 ErrorFound = true; 11017 } 11018 } 11019 if ((!AStmt && !DependFound) || ErrorFound) 11020 return StmtError(); 11021 11022 // OpenMP 5.0, 2.17.9, ordered Construct, Restrictions. 11023 // During execution of an iteration of a worksharing-loop or a loop nest 11024 // within a worksharing-loop, simd, or worksharing-loop SIMD region, a thread 11025 // must not execute more than one ordered region corresponding to an ordered 11026 // construct without a depend clause. 11027 if (!DependFound) { 11028 if (DSAStack->doesParentHasOrderedDirective()) { 11029 Diag(StartLoc, diag::err_omp_several_directives_in_region) << "ordered"; 11030 Diag(DSAStack->getParentOrderedDirectiveLoc(), 11031 diag::note_omp_previous_directive) 11032 << "ordered"; 11033 return StmtError(); 11034 } 11035 DSAStack->setParentHasOrderedDirective(StartLoc); 11036 } 11037 11038 if (AStmt) { 11039 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 11040 11041 setFunctionHasBranchProtectedScope(); 11042 } 11043 11044 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 11045 } 11046 11047 namespace { 11048 /// Helper class for checking expression in 'omp atomic [update]' 11049 /// construct. 11050 class OpenMPAtomicUpdateChecker { 11051 /// Error results for atomic update expressions. 11052 enum ExprAnalysisErrorCode { 11053 /// A statement is not an expression statement. 11054 NotAnExpression, 11055 /// Expression is not builtin binary or unary operation. 11056 NotABinaryOrUnaryExpression, 11057 /// Unary operation is not post-/pre- increment/decrement operation. 11058 NotAnUnaryIncDecExpression, 11059 /// An expression is not of scalar type. 11060 NotAScalarType, 11061 /// A binary operation is not an assignment operation. 11062 NotAnAssignmentOp, 11063 /// RHS part of the binary operation is not a binary expression. 11064 NotABinaryExpression, 11065 /// RHS part is not additive/multiplicative/shift/biwise binary 11066 /// expression. 11067 NotABinaryOperator, 11068 /// RHS binary operation does not have reference to the updated LHS 11069 /// part. 11070 NotAnUpdateExpression, 11071 /// No errors is found. 11072 NoError 11073 }; 11074 /// Reference to Sema. 11075 Sema &SemaRef; 11076 /// A location for note diagnostics (when error is found). 11077 SourceLocation NoteLoc; 11078 /// 'x' lvalue part of the source atomic expression. 11079 Expr *X; 11080 /// 'expr' rvalue part of the source atomic expression. 11081 Expr *E; 11082 /// Helper expression of the form 11083 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 11084 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 11085 Expr *UpdateExpr; 11086 /// Is 'x' a LHS in a RHS part of full update expression. It is 11087 /// important for non-associative operations. 11088 bool IsXLHSInRHSPart; 11089 BinaryOperatorKind Op; 11090 SourceLocation OpLoc; 11091 /// true if the source expression is a postfix unary operation, false 11092 /// if it is a prefix unary operation. 11093 bool IsPostfixUpdate; 11094 11095 public: 11096 OpenMPAtomicUpdateChecker(Sema &SemaRef) 11097 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 11098 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 11099 /// Check specified statement that it is suitable for 'atomic update' 11100 /// constructs and extract 'x', 'expr' and Operation from the original 11101 /// expression. If DiagId and NoteId == 0, then only check is performed 11102 /// without error notification. 11103 /// \param DiagId Diagnostic which should be emitted if error is found. 11104 /// \param NoteId Diagnostic note for the main error message. 11105 /// \return true if statement is not an update expression, false otherwise. 11106 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 11107 /// Return the 'x' lvalue part of the source atomic expression. 11108 Expr *getX() const { return X; } 11109 /// Return the 'expr' rvalue part of the source atomic expression. 11110 Expr *getExpr() const { return E; } 11111 /// Return the update expression used in calculation of the updated 11112 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 11113 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 11114 Expr *getUpdateExpr() const { return UpdateExpr; } 11115 /// Return true if 'x' is LHS in RHS part of full update expression, 11116 /// false otherwise. 11117 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 11118 11119 /// true if the source expression is a postfix unary operation, false 11120 /// if it is a prefix unary operation. 11121 bool isPostfixUpdate() const { return IsPostfixUpdate; } 11122 11123 private: 11124 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 11125 unsigned NoteId = 0); 11126 }; 11127 11128 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 11129 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 11130 ExprAnalysisErrorCode ErrorFound = NoError; 11131 SourceLocation ErrorLoc, NoteLoc; 11132 SourceRange ErrorRange, NoteRange; 11133 // Allowed constructs are: 11134 // x = x binop expr; 11135 // x = expr binop x; 11136 if (AtomicBinOp->getOpcode() == BO_Assign) { 11137 X = AtomicBinOp->getLHS(); 11138 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 11139 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 11140 if (AtomicInnerBinOp->isMultiplicativeOp() || 11141 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 11142 AtomicInnerBinOp->isBitwiseOp()) { 11143 Op = AtomicInnerBinOp->getOpcode(); 11144 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 11145 Expr *LHS = AtomicInnerBinOp->getLHS(); 11146 Expr *RHS = AtomicInnerBinOp->getRHS(); 11147 llvm::FoldingSetNodeID XId, LHSId, RHSId; 11148 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 11149 /*Canonical=*/true); 11150 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 11151 /*Canonical=*/true); 11152 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 11153 /*Canonical=*/true); 11154 if (XId == LHSId) { 11155 E = RHS; 11156 IsXLHSInRHSPart = true; 11157 } else if (XId == RHSId) { 11158 E = LHS; 11159 IsXLHSInRHSPart = false; 11160 } else { 11161 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 11162 ErrorRange = AtomicInnerBinOp->getSourceRange(); 11163 NoteLoc = X->getExprLoc(); 11164 NoteRange = X->getSourceRange(); 11165 ErrorFound = NotAnUpdateExpression; 11166 } 11167 } else { 11168 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 11169 ErrorRange = AtomicInnerBinOp->getSourceRange(); 11170 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 11171 NoteRange = SourceRange(NoteLoc, NoteLoc); 11172 ErrorFound = NotABinaryOperator; 11173 } 11174 } else { 11175 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 11176 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 11177 ErrorFound = NotABinaryExpression; 11178 } 11179 } else { 11180 ErrorLoc = AtomicBinOp->getExprLoc(); 11181 ErrorRange = AtomicBinOp->getSourceRange(); 11182 NoteLoc = AtomicBinOp->getOperatorLoc(); 11183 NoteRange = SourceRange(NoteLoc, NoteLoc); 11184 ErrorFound = NotAnAssignmentOp; 11185 } 11186 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 11187 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 11188 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 11189 return true; 11190 } 11191 if (SemaRef.CurContext->isDependentContext()) 11192 E = X = UpdateExpr = nullptr; 11193 return ErrorFound != NoError; 11194 } 11195 11196 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 11197 unsigned NoteId) { 11198 ExprAnalysisErrorCode ErrorFound = NoError; 11199 SourceLocation ErrorLoc, NoteLoc; 11200 SourceRange ErrorRange, NoteRange; 11201 // Allowed constructs are: 11202 // x++; 11203 // x--; 11204 // ++x; 11205 // --x; 11206 // x binop= expr; 11207 // x = x binop expr; 11208 // x = expr binop x; 11209 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 11210 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 11211 if (AtomicBody->getType()->isScalarType() || 11212 AtomicBody->isInstantiationDependent()) { 11213 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 11214 AtomicBody->IgnoreParenImpCasts())) { 11215 // Check for Compound Assignment Operation 11216 Op = BinaryOperator::getOpForCompoundAssignment( 11217 AtomicCompAssignOp->getOpcode()); 11218 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 11219 E = AtomicCompAssignOp->getRHS(); 11220 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 11221 IsXLHSInRHSPart = true; 11222 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 11223 AtomicBody->IgnoreParenImpCasts())) { 11224 // Check for Binary Operation 11225 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 11226 return true; 11227 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 11228 AtomicBody->IgnoreParenImpCasts())) { 11229 // Check for Unary Operation 11230 if (AtomicUnaryOp->isIncrementDecrementOp()) { 11231 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 11232 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 11233 OpLoc = AtomicUnaryOp->getOperatorLoc(); 11234 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 11235 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 11236 IsXLHSInRHSPart = true; 11237 } else { 11238 ErrorFound = NotAnUnaryIncDecExpression; 11239 ErrorLoc = AtomicUnaryOp->getExprLoc(); 11240 ErrorRange = AtomicUnaryOp->getSourceRange(); 11241 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 11242 NoteRange = SourceRange(NoteLoc, NoteLoc); 11243 } 11244 } else if (!AtomicBody->isInstantiationDependent()) { 11245 ErrorFound = NotABinaryOrUnaryExpression; 11246 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 11247 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 11248 } 11249 } else { 11250 ErrorFound = NotAScalarType; 11251 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 11252 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 11253 } 11254 } else { 11255 ErrorFound = NotAnExpression; 11256 NoteLoc = ErrorLoc = S->getBeginLoc(); 11257 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 11258 } 11259 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 11260 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 11261 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 11262 return true; 11263 } 11264 if (SemaRef.CurContext->isDependentContext()) 11265 E = X = UpdateExpr = nullptr; 11266 if (ErrorFound == NoError && E && X) { 11267 // Build an update expression of form 'OpaqueValueExpr(x) binop 11268 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 11269 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 11270 auto *OVEX = new (SemaRef.getASTContext()) 11271 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_PRValue); 11272 auto *OVEExpr = new (SemaRef.getASTContext()) 11273 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_PRValue); 11274 ExprResult Update = 11275 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 11276 IsXLHSInRHSPart ? OVEExpr : OVEX); 11277 if (Update.isInvalid()) 11278 return true; 11279 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 11280 Sema::AA_Casting); 11281 if (Update.isInvalid()) 11282 return true; 11283 UpdateExpr = Update.get(); 11284 } 11285 return ErrorFound != NoError; 11286 } 11287 11288 /// Get the node id of the fixed point of an expression \a S. 11289 llvm::FoldingSetNodeID getNodeId(ASTContext &Context, const Expr *S) { 11290 llvm::FoldingSetNodeID Id; 11291 S->IgnoreParenImpCasts()->Profile(Id, Context, true); 11292 return Id; 11293 } 11294 11295 /// Check if two expressions are same. 11296 bool checkIfTwoExprsAreSame(ASTContext &Context, const Expr *LHS, 11297 const Expr *RHS) { 11298 return getNodeId(Context, LHS) == getNodeId(Context, RHS); 11299 } 11300 11301 class OpenMPAtomicCompareChecker { 11302 public: 11303 /// All kinds of errors that can occur in `atomic compare` 11304 enum ErrorTy { 11305 /// Empty compound statement. 11306 NoStmt = 0, 11307 /// More than one statement in a compound statement. 11308 MoreThanOneStmt, 11309 /// Not an assignment binary operator. 11310 NotAnAssignment, 11311 /// Not a conditional operator. 11312 NotCondOp, 11313 /// Wrong false expr. According to the spec, 'x' should be at the false 11314 /// expression of a conditional expression. 11315 WrongFalseExpr, 11316 /// The condition of a conditional expression is not a binary operator. 11317 NotABinaryOp, 11318 /// Invalid binary operator (not <, >, or ==). 11319 InvalidBinaryOp, 11320 /// Invalid comparison (not x == e, e == x, x ordop expr, or expr ordop x). 11321 InvalidComparison, 11322 /// X is not a lvalue. 11323 XNotLValue, 11324 /// Not a scalar. 11325 NotScalar, 11326 /// Not an integer. 11327 NotInteger, 11328 /// 'else' statement is not expected. 11329 UnexpectedElse, 11330 /// Not an equality operator. 11331 NotEQ, 11332 /// Invalid assignment (not v == x). 11333 InvalidAssignment, 11334 /// Not if statement 11335 NotIfStmt, 11336 /// More than two statements in a compund statement. 11337 MoreThanTwoStmts, 11338 /// Not a compound statement. 11339 NotCompoundStmt, 11340 /// No else statement. 11341 NoElse, 11342 /// Not 'if (r)'. 11343 InvalidCondition, 11344 /// No error. 11345 NoError, 11346 }; 11347 11348 struct ErrorInfoTy { 11349 ErrorTy Error; 11350 SourceLocation ErrorLoc; 11351 SourceRange ErrorRange; 11352 SourceLocation NoteLoc; 11353 SourceRange NoteRange; 11354 }; 11355 11356 OpenMPAtomicCompareChecker(Sema &S) : ContextRef(S.getASTContext()) {} 11357 11358 /// Check if statement \a S is valid for <tt>atomic compare</tt>. 11359 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11360 11361 Expr *getX() const { return X; } 11362 Expr *getE() const { return E; } 11363 Expr *getD() const { return D; } 11364 Expr *getCond() const { return C; } 11365 bool isXBinopExpr() const { return IsXBinopExpr; } 11366 11367 protected: 11368 /// Reference to ASTContext 11369 ASTContext &ContextRef; 11370 /// 'x' lvalue part of the source atomic expression. 11371 Expr *X = nullptr; 11372 /// 'expr' or 'e' rvalue part of the source atomic expression. 11373 Expr *E = nullptr; 11374 /// 'd' rvalue part of the source atomic expression. 11375 Expr *D = nullptr; 11376 /// 'cond' part of the source atomic expression. It is in one of the following 11377 /// forms: 11378 /// expr ordop x 11379 /// x ordop expr 11380 /// x == e 11381 /// e == x 11382 Expr *C = nullptr; 11383 /// True if the cond expr is in the form of 'x ordop expr'. 11384 bool IsXBinopExpr = true; 11385 11386 /// Check if it is a valid conditional update statement (cond-update-stmt). 11387 bool checkCondUpdateStmt(IfStmt *S, ErrorInfoTy &ErrorInfo); 11388 11389 /// Check if it is a valid conditional expression statement (cond-expr-stmt). 11390 bool checkCondExprStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11391 11392 /// Check if all captured values have right type. 11393 bool checkType(ErrorInfoTy &ErrorInfo) const; 11394 11395 static bool CheckValue(const Expr *E, ErrorInfoTy &ErrorInfo, 11396 bool ShouldBeLValue) { 11397 if (ShouldBeLValue && !E->isLValue()) { 11398 ErrorInfo.Error = ErrorTy::XNotLValue; 11399 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11400 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11401 return false; 11402 } 11403 11404 if (!E->isInstantiationDependent()) { 11405 QualType QTy = E->getType(); 11406 if (!QTy->isScalarType()) { 11407 ErrorInfo.Error = ErrorTy::NotScalar; 11408 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11409 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11410 return false; 11411 } 11412 11413 if (!QTy->isIntegerType()) { 11414 ErrorInfo.Error = ErrorTy::NotInteger; 11415 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = E->getExprLoc(); 11416 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = E->getSourceRange(); 11417 return false; 11418 } 11419 } 11420 11421 return true; 11422 } 11423 }; 11424 11425 bool OpenMPAtomicCompareChecker::checkCondUpdateStmt(IfStmt *S, 11426 ErrorInfoTy &ErrorInfo) { 11427 auto *Then = S->getThen(); 11428 if (auto *CS = dyn_cast<CompoundStmt>(Then)) { 11429 if (CS->body_empty()) { 11430 ErrorInfo.Error = ErrorTy::NoStmt; 11431 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11432 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11433 return false; 11434 } 11435 if (CS->size() > 1) { 11436 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11437 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11438 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11439 return false; 11440 } 11441 Then = CS->body_front(); 11442 } 11443 11444 auto *BO = dyn_cast<BinaryOperator>(Then); 11445 if (!BO) { 11446 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11447 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc(); 11448 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange(); 11449 return false; 11450 } 11451 if (BO->getOpcode() != BO_Assign) { 11452 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11453 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11454 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11455 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11456 return false; 11457 } 11458 11459 X = BO->getLHS(); 11460 11461 auto *Cond = dyn_cast<BinaryOperator>(S->getCond()); 11462 if (!Cond) { 11463 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11464 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc(); 11465 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange(); 11466 return false; 11467 } 11468 11469 switch (Cond->getOpcode()) { 11470 case BO_EQ: { 11471 C = Cond; 11472 D = BO->getRHS(); 11473 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11474 E = Cond->getRHS(); 11475 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11476 E = Cond->getLHS(); 11477 } else { 11478 ErrorInfo.Error = ErrorTy::InvalidComparison; 11479 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11480 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11481 return false; 11482 } 11483 break; 11484 } 11485 case BO_LT: 11486 case BO_GT: { 11487 E = BO->getRHS(); 11488 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && 11489 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { 11490 C = Cond; 11491 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) && 11492 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11493 C = Cond; 11494 IsXBinopExpr = false; 11495 } else { 11496 ErrorInfo.Error = ErrorTy::InvalidComparison; 11497 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11498 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11499 return false; 11500 } 11501 break; 11502 } 11503 default: 11504 ErrorInfo.Error = ErrorTy::InvalidBinaryOp; 11505 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11506 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11507 return false; 11508 } 11509 11510 if (S->getElse()) { 11511 ErrorInfo.Error = ErrorTy::UnexpectedElse; 11512 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getElse()->getBeginLoc(); 11513 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getElse()->getSourceRange(); 11514 return false; 11515 } 11516 11517 return true; 11518 } 11519 11520 bool OpenMPAtomicCompareChecker::checkCondExprStmt(Stmt *S, 11521 ErrorInfoTy &ErrorInfo) { 11522 auto *BO = dyn_cast<BinaryOperator>(S); 11523 if (!BO) { 11524 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11525 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 11526 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11527 return false; 11528 } 11529 if (BO->getOpcode() != BO_Assign) { 11530 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11531 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11532 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11533 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11534 return false; 11535 } 11536 11537 X = BO->getLHS(); 11538 11539 auto *CO = dyn_cast<ConditionalOperator>(BO->getRHS()->IgnoreParenImpCasts()); 11540 if (!CO) { 11541 ErrorInfo.Error = ErrorTy::NotCondOp; 11542 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getRHS()->getExprLoc(); 11543 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getRHS()->getSourceRange(); 11544 return false; 11545 } 11546 11547 if (!checkIfTwoExprsAreSame(ContextRef, X, CO->getFalseExpr())) { 11548 ErrorInfo.Error = ErrorTy::WrongFalseExpr; 11549 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getFalseExpr()->getExprLoc(); 11550 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11551 CO->getFalseExpr()->getSourceRange(); 11552 return false; 11553 } 11554 11555 auto *Cond = dyn_cast<BinaryOperator>(CO->getCond()); 11556 if (!Cond) { 11557 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11558 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CO->getCond()->getExprLoc(); 11559 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11560 CO->getCond()->getSourceRange(); 11561 return false; 11562 } 11563 11564 switch (Cond->getOpcode()) { 11565 case BO_EQ: { 11566 C = Cond; 11567 D = CO->getTrueExpr(); 11568 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11569 E = Cond->getRHS(); 11570 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11571 E = Cond->getLHS(); 11572 } else { 11573 ErrorInfo.Error = ErrorTy::InvalidComparison; 11574 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11575 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11576 return false; 11577 } 11578 break; 11579 } 11580 case BO_LT: 11581 case BO_GT: { 11582 E = CO->getTrueExpr(); 11583 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS()) && 11584 checkIfTwoExprsAreSame(ContextRef, E, Cond->getRHS())) { 11585 C = Cond; 11586 } else if (checkIfTwoExprsAreSame(ContextRef, E, Cond->getLHS()) && 11587 checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11588 C = Cond; 11589 IsXBinopExpr = false; 11590 } else { 11591 ErrorInfo.Error = ErrorTy::InvalidComparison; 11592 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11593 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11594 return false; 11595 } 11596 break; 11597 } 11598 default: 11599 ErrorInfo.Error = ErrorTy::InvalidBinaryOp; 11600 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11601 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11602 return false; 11603 } 11604 11605 return true; 11606 } 11607 11608 bool OpenMPAtomicCompareChecker::checkType(ErrorInfoTy &ErrorInfo) const { 11609 // 'x' and 'e' cannot be nullptr 11610 assert(X && E && "X and E cannot be nullptr"); 11611 11612 if (!CheckValue(X, ErrorInfo, true)) 11613 return false; 11614 11615 if (!CheckValue(E, ErrorInfo, false)) 11616 return false; 11617 11618 if (D && !CheckValue(D, ErrorInfo, false)) 11619 return false; 11620 11621 return true; 11622 } 11623 11624 bool OpenMPAtomicCompareChecker::checkStmt( 11625 Stmt *S, OpenMPAtomicCompareChecker::ErrorInfoTy &ErrorInfo) { 11626 auto *CS = dyn_cast<CompoundStmt>(S); 11627 if (CS) { 11628 if (CS->body_empty()) { 11629 ErrorInfo.Error = ErrorTy::NoStmt; 11630 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11631 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11632 return false; 11633 } 11634 11635 if (CS->size() != 1) { 11636 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11637 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11638 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11639 return false; 11640 } 11641 S = CS->body_front(); 11642 } 11643 11644 auto Res = false; 11645 11646 if (auto *IS = dyn_cast<IfStmt>(S)) { 11647 // Check if the statement is in one of the following forms 11648 // (cond-update-stmt): 11649 // if (expr ordop x) { x = expr; } 11650 // if (x ordop expr) { x = expr; } 11651 // if (x == e) { x = d; } 11652 Res = checkCondUpdateStmt(IS, ErrorInfo); 11653 } else { 11654 // Check if the statement is in one of the following forms (cond-expr-stmt): 11655 // x = expr ordop x ? expr : x; 11656 // x = x ordop expr ? expr : x; 11657 // x = x == e ? d : x; 11658 Res = checkCondExprStmt(S, ErrorInfo); 11659 } 11660 11661 if (!Res) 11662 return false; 11663 11664 return checkType(ErrorInfo); 11665 } 11666 11667 class OpenMPAtomicCompareCaptureChecker final 11668 : public OpenMPAtomicCompareChecker { 11669 public: 11670 OpenMPAtomicCompareCaptureChecker(Sema &S) : OpenMPAtomicCompareChecker(S) {} 11671 11672 Expr *getV() const { return V; } 11673 Expr *getR() const { return R; } 11674 bool isFailOnly() const { return IsFailOnly; } 11675 bool isPostfixUpdate() const { return IsPostfixUpdate; } 11676 11677 /// Check if statement \a S is valid for <tt>atomic compare capture</tt>. 11678 bool checkStmt(Stmt *S, ErrorInfoTy &ErrorInfo); 11679 11680 private: 11681 bool checkType(ErrorInfoTy &ErrorInfo); 11682 11683 // NOTE: Form 3, 4, 5 in the following comments mean the 3rd, 4th, and 5th 11684 // form of 'conditional-update-capture-atomic' structured block on the v5.2 11685 // spec p.p. 82: 11686 // (1) { v = x; cond-update-stmt } 11687 // (2) { cond-update-stmt v = x; } 11688 // (3) if(x == e) { x = d; } else { v = x; } 11689 // (4) { r = x == e; if(r) { x = d; } } 11690 // (5) { r = x == e; if(r) { x = d; } else { v = x; } } 11691 11692 /// Check if it is valid 'if(x == e) { x = d; } else { v = x; }' (form 3) 11693 bool checkForm3(IfStmt *S, ErrorInfoTy &ErrorInfo); 11694 11695 /// Check if it is valid '{ r = x == e; if(r) { x = d; } }', 11696 /// or '{ r = x == e; if(r) { x = d; } else { v = x; } }' (form 4 and 5) 11697 bool checkForm45(Stmt *S, ErrorInfoTy &ErrorInfo); 11698 11699 /// 'v' lvalue part of the source atomic expression. 11700 Expr *V = nullptr; 11701 /// 'r' lvalue part of the source atomic expression. 11702 Expr *R = nullptr; 11703 /// If 'v' is only updated when the comparison fails. 11704 bool IsFailOnly = false; 11705 /// If original value of 'x' must be stored in 'v', not an updated one. 11706 bool IsPostfixUpdate = false; 11707 }; 11708 11709 bool OpenMPAtomicCompareCaptureChecker::checkType(ErrorInfoTy &ErrorInfo) { 11710 if (!OpenMPAtomicCompareChecker::checkType(ErrorInfo)) 11711 return false; 11712 11713 if (V && !CheckValue(V, ErrorInfo, true)) 11714 return false; 11715 11716 if (R && !CheckValue(R, ErrorInfo, true)) 11717 return false; 11718 11719 return true; 11720 } 11721 11722 bool OpenMPAtomicCompareCaptureChecker::checkForm3(IfStmt *S, 11723 ErrorInfoTy &ErrorInfo) { 11724 IsFailOnly = true; 11725 11726 auto *Then = S->getThen(); 11727 if (auto *CS = dyn_cast<CompoundStmt>(Then)) { 11728 if (CS->body_empty()) { 11729 ErrorInfo.Error = ErrorTy::NoStmt; 11730 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11731 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11732 return false; 11733 } 11734 if (CS->size() > 1) { 11735 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11736 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11737 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11738 return false; 11739 } 11740 Then = CS->body_front(); 11741 } 11742 11743 auto *BO = dyn_cast<BinaryOperator>(Then); 11744 if (!BO) { 11745 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11746 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Then->getBeginLoc(); 11747 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Then->getSourceRange(); 11748 return false; 11749 } 11750 if (BO->getOpcode() != BO_Assign) { 11751 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11752 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11753 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11754 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11755 return false; 11756 } 11757 11758 X = BO->getLHS(); 11759 D = BO->getRHS(); 11760 11761 auto *Cond = dyn_cast<BinaryOperator>(S->getCond()); 11762 if (!Cond) { 11763 ErrorInfo.Error = ErrorTy::NotABinaryOp; 11764 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getCond()->getExprLoc(); 11765 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getCond()->getSourceRange(); 11766 return false; 11767 } 11768 if (Cond->getOpcode() != BO_EQ) { 11769 ErrorInfo.Error = ErrorTy::NotEQ; 11770 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11771 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11772 return false; 11773 } 11774 11775 if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getLHS())) { 11776 E = Cond->getRHS(); 11777 } else if (checkIfTwoExprsAreSame(ContextRef, X, Cond->getRHS())) { 11778 E = Cond->getLHS(); 11779 } else { 11780 ErrorInfo.Error = ErrorTy::InvalidComparison; 11781 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Cond->getExprLoc(); 11782 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Cond->getSourceRange(); 11783 return false; 11784 } 11785 11786 C = Cond; 11787 11788 if (!S->getElse()) { 11789 ErrorInfo.Error = ErrorTy::NoElse; 11790 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 11791 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11792 return false; 11793 } 11794 11795 auto *Else = S->getElse(); 11796 if (auto *CS = dyn_cast<CompoundStmt>(Else)) { 11797 if (CS->body_empty()) { 11798 ErrorInfo.Error = ErrorTy::NoStmt; 11799 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11800 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11801 return false; 11802 } 11803 if (CS->size() > 1) { 11804 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11805 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11806 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11807 return false; 11808 } 11809 Else = CS->body_front(); 11810 } 11811 11812 auto *ElseBO = dyn_cast<BinaryOperator>(Else); 11813 if (!ElseBO) { 11814 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11815 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc(); 11816 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange(); 11817 return false; 11818 } 11819 if (ElseBO->getOpcode() != BO_Assign) { 11820 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11821 ErrorInfo.ErrorLoc = ElseBO->getExprLoc(); 11822 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc(); 11823 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange(); 11824 return false; 11825 } 11826 11827 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) { 11828 ErrorInfo.Error = ErrorTy::InvalidAssignment; 11829 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseBO->getRHS()->getExprLoc(); 11830 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11831 ElseBO->getRHS()->getSourceRange(); 11832 return false; 11833 } 11834 11835 V = ElseBO->getLHS(); 11836 11837 return checkType(ErrorInfo); 11838 } 11839 11840 bool OpenMPAtomicCompareCaptureChecker::checkForm45(Stmt *S, 11841 ErrorInfoTy &ErrorInfo) { 11842 // We don't check here as they should be already done before call this 11843 // function. 11844 auto *CS = cast<CompoundStmt>(S); 11845 assert(CS->size() == 2 && "CompoundStmt size is not expected"); 11846 auto *S1 = cast<BinaryOperator>(CS->body_front()); 11847 auto *S2 = cast<IfStmt>(CS->body_back()); 11848 assert(S1->getOpcode() == BO_Assign && "unexpected binary operator"); 11849 11850 if (!checkIfTwoExprsAreSame(ContextRef, S1->getLHS(), S2->getCond())) { 11851 ErrorInfo.Error = ErrorTy::InvalidCondition; 11852 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getCond()->getExprLoc(); 11853 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S1->getLHS()->getSourceRange(); 11854 return false; 11855 } 11856 11857 R = S1->getLHS(); 11858 11859 auto *Then = S2->getThen(); 11860 if (auto *ThenCS = dyn_cast<CompoundStmt>(Then)) { 11861 if (ThenCS->body_empty()) { 11862 ErrorInfo.Error = ErrorTy::NoStmt; 11863 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc(); 11864 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange(); 11865 return false; 11866 } 11867 if (ThenCS->size() > 1) { 11868 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11869 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ThenCS->getBeginLoc(); 11870 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenCS->getSourceRange(); 11871 return false; 11872 } 11873 Then = ThenCS->body_front(); 11874 } 11875 11876 auto *ThenBO = dyn_cast<BinaryOperator>(Then); 11877 if (!ThenBO) { 11878 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11879 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S2->getBeginLoc(); 11880 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S2->getSourceRange(); 11881 return false; 11882 } 11883 if (ThenBO->getOpcode() != BO_Assign) { 11884 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11885 ErrorInfo.ErrorLoc = ThenBO->getExprLoc(); 11886 ErrorInfo.NoteLoc = ThenBO->getOperatorLoc(); 11887 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ThenBO->getSourceRange(); 11888 return false; 11889 } 11890 11891 X = ThenBO->getLHS(); 11892 D = ThenBO->getRHS(); 11893 11894 auto *BO = cast<BinaryOperator>(S1->getRHS()->IgnoreImpCasts()); 11895 if (BO->getOpcode() != BO_EQ) { 11896 ErrorInfo.Error = ErrorTy::NotEQ; 11897 ErrorInfo.ErrorLoc = BO->getExprLoc(); 11898 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 11899 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11900 return false; 11901 } 11902 11903 C = BO; 11904 11905 if (checkIfTwoExprsAreSame(ContextRef, X, BO->getLHS())) { 11906 E = BO->getRHS(); 11907 } else if (checkIfTwoExprsAreSame(ContextRef, X, BO->getRHS())) { 11908 E = BO->getLHS(); 11909 } else { 11910 ErrorInfo.Error = ErrorTy::InvalidComparison; 11911 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = BO->getExprLoc(); 11912 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 11913 return false; 11914 } 11915 11916 if (S2->getElse()) { 11917 IsFailOnly = true; 11918 11919 auto *Else = S2->getElse(); 11920 if (auto *ElseCS = dyn_cast<CompoundStmt>(Else)) { 11921 if (ElseCS->body_empty()) { 11922 ErrorInfo.Error = ErrorTy::NoStmt; 11923 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc(); 11924 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange(); 11925 return false; 11926 } 11927 if (ElseCS->size() > 1) { 11928 ErrorInfo.Error = ErrorTy::MoreThanOneStmt; 11929 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = ElseCS->getBeginLoc(); 11930 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseCS->getSourceRange(); 11931 return false; 11932 } 11933 Else = ElseCS->body_front(); 11934 } 11935 11936 auto *ElseBO = dyn_cast<BinaryOperator>(Else); 11937 if (!ElseBO) { 11938 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11939 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = Else->getBeginLoc(); 11940 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = Else->getSourceRange(); 11941 return false; 11942 } 11943 if (ElseBO->getOpcode() != BO_Assign) { 11944 ErrorInfo.Error = ErrorTy::NotAnAssignment; 11945 ErrorInfo.ErrorLoc = ElseBO->getExprLoc(); 11946 ErrorInfo.NoteLoc = ElseBO->getOperatorLoc(); 11947 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = ElseBO->getSourceRange(); 11948 return false; 11949 } 11950 if (!checkIfTwoExprsAreSame(ContextRef, X, ElseBO->getRHS())) { 11951 ErrorInfo.Error = ErrorTy::InvalidAssignment; 11952 ErrorInfo.ErrorLoc = ElseBO->getRHS()->getExprLoc(); 11953 ErrorInfo.NoteLoc = X->getExprLoc(); 11954 ErrorInfo.ErrorRange = ElseBO->getRHS()->getSourceRange(); 11955 ErrorInfo.NoteRange = X->getSourceRange(); 11956 return false; 11957 } 11958 11959 V = ElseBO->getLHS(); 11960 } 11961 11962 return checkType(ErrorInfo); 11963 } 11964 11965 bool OpenMPAtomicCompareCaptureChecker::checkStmt(Stmt *S, 11966 ErrorInfoTy &ErrorInfo) { 11967 // if(x == e) { x = d; } else { v = x; } 11968 if (auto *IS = dyn_cast<IfStmt>(S)) 11969 return checkForm3(IS, ErrorInfo); 11970 11971 auto *CS = dyn_cast<CompoundStmt>(S); 11972 if (!CS) { 11973 ErrorInfo.Error = ErrorTy::NotCompoundStmt; 11974 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = S->getBeginLoc(); 11975 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = S->getSourceRange(); 11976 return false; 11977 } 11978 if (CS->body_empty()) { 11979 ErrorInfo.Error = ErrorTy::NoStmt; 11980 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 11981 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 11982 return false; 11983 } 11984 11985 // { if(x == e) { x = d; } else { v = x; } } 11986 if (CS->size() == 1) { 11987 auto *IS = dyn_cast<IfStmt>(CS->body_front()); 11988 if (!IS) { 11989 ErrorInfo.Error = ErrorTy::NotIfStmt; 11990 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->body_front()->getBeginLoc(); 11991 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = 11992 CS->body_front()->getSourceRange(); 11993 return false; 11994 } 11995 11996 return checkForm3(IS, ErrorInfo); 11997 } else if (CS->size() == 2) { 11998 auto *S1 = CS->body_front(); 11999 auto *S2 = CS->body_back(); 12000 12001 Stmt *UpdateStmt = nullptr; 12002 Stmt *CondUpdateStmt = nullptr; 12003 12004 if (auto *BO = dyn_cast<BinaryOperator>(S1)) { 12005 // { v = x; cond-update-stmt } or form 45. 12006 UpdateStmt = S1; 12007 CondUpdateStmt = S2; 12008 // Check if form 45. 12009 if (isa<BinaryOperator>(BO->getRHS()->IgnoreImpCasts()) && 12010 isa<IfStmt>(S2)) 12011 return checkForm45(CS, ErrorInfo); 12012 // It cannot be set before we the check for form45. 12013 IsPostfixUpdate = true; 12014 } else { 12015 // { cond-update-stmt v = x; } 12016 UpdateStmt = S2; 12017 CondUpdateStmt = S1; 12018 } 12019 12020 auto CheckCondUpdateStmt = [this, &ErrorInfo](Stmt *CUS) { 12021 auto *IS = dyn_cast<IfStmt>(CUS); 12022 if (!IS) { 12023 ErrorInfo.Error = ErrorTy::NotIfStmt; 12024 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CUS->getBeginLoc(); 12025 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CUS->getSourceRange(); 12026 return false; 12027 } 12028 12029 if (!checkCondUpdateStmt(IS, ErrorInfo)) 12030 return false; 12031 12032 return true; 12033 }; 12034 12035 // CheckUpdateStmt has to be called *after* CheckCondUpdateStmt. 12036 auto CheckUpdateStmt = [this, &ErrorInfo](Stmt *US) { 12037 auto *BO = dyn_cast<BinaryOperator>(US); 12038 if (!BO) { 12039 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12040 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = US->getBeginLoc(); 12041 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = US->getSourceRange(); 12042 return false; 12043 } 12044 if (BO->getOpcode() != BO_Assign) { 12045 ErrorInfo.Error = ErrorTy::NotAnAssignment; 12046 ErrorInfo.ErrorLoc = BO->getExprLoc(); 12047 ErrorInfo.NoteLoc = BO->getOperatorLoc(); 12048 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = BO->getSourceRange(); 12049 return false; 12050 } 12051 if (!checkIfTwoExprsAreSame(ContextRef, this->X, BO->getRHS())) { 12052 ErrorInfo.Error = ErrorTy::InvalidAssignment; 12053 ErrorInfo.ErrorLoc = BO->getRHS()->getExprLoc(); 12054 ErrorInfo.NoteLoc = this->X->getExprLoc(); 12055 ErrorInfo.ErrorRange = BO->getRHS()->getSourceRange(); 12056 ErrorInfo.NoteRange = this->X->getSourceRange(); 12057 return false; 12058 } 12059 12060 this->V = BO->getLHS(); 12061 12062 return true; 12063 }; 12064 12065 if (!CheckCondUpdateStmt(CondUpdateStmt)) 12066 return false; 12067 if (!CheckUpdateStmt(UpdateStmt)) 12068 return false; 12069 } else { 12070 ErrorInfo.Error = ErrorTy::MoreThanTwoStmts; 12071 ErrorInfo.ErrorLoc = ErrorInfo.NoteLoc = CS->getBeginLoc(); 12072 ErrorInfo.ErrorRange = ErrorInfo.NoteRange = CS->getSourceRange(); 12073 return false; 12074 } 12075 12076 return checkType(ErrorInfo); 12077 } 12078 } // namespace 12079 12080 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 12081 Stmt *AStmt, 12082 SourceLocation StartLoc, 12083 SourceLocation EndLoc) { 12084 // Register location of the first atomic directive. 12085 DSAStack->addAtomicDirectiveLoc(StartLoc); 12086 if (!AStmt) 12087 return StmtError(); 12088 12089 // 1.2.2 OpenMP Language Terminology 12090 // Structured block - An executable statement with a single entry at the 12091 // top and a single exit at the bottom. 12092 // The point of exit cannot be a branch out of the structured block. 12093 // longjmp() and throw() must not violate the entry/exit criteria. 12094 OpenMPClauseKind AtomicKind = OMPC_unknown; 12095 SourceLocation AtomicKindLoc; 12096 OpenMPClauseKind MemOrderKind = OMPC_unknown; 12097 SourceLocation MemOrderLoc; 12098 bool MutexClauseEncountered = false; 12099 llvm::SmallSet<OpenMPClauseKind, 2> EncounteredAtomicKinds; 12100 for (const OMPClause *C : Clauses) { 12101 switch (C->getClauseKind()) { 12102 case OMPC_read: 12103 case OMPC_write: 12104 case OMPC_update: 12105 MutexClauseEncountered = true; 12106 LLVM_FALLTHROUGH; 12107 case OMPC_capture: 12108 case OMPC_compare: { 12109 if (AtomicKind != OMPC_unknown && MutexClauseEncountered) { 12110 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 12111 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12112 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 12113 << getOpenMPClauseName(AtomicKind); 12114 } else { 12115 AtomicKind = C->getClauseKind(); 12116 AtomicKindLoc = C->getBeginLoc(); 12117 if (!EncounteredAtomicKinds.insert(C->getClauseKind()).second) { 12118 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 12119 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12120 Diag(AtomicKindLoc, diag::note_omp_previous_mem_order_clause) 12121 << getOpenMPClauseName(AtomicKind); 12122 } 12123 } 12124 break; 12125 } 12126 case OMPC_seq_cst: 12127 case OMPC_acq_rel: 12128 case OMPC_acquire: 12129 case OMPC_release: 12130 case OMPC_relaxed: { 12131 if (MemOrderKind != OMPC_unknown) { 12132 Diag(C->getBeginLoc(), diag::err_omp_several_mem_order_clauses) 12133 << getOpenMPDirectiveName(OMPD_atomic) << 0 12134 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 12135 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 12136 << getOpenMPClauseName(MemOrderKind); 12137 } else { 12138 MemOrderKind = C->getClauseKind(); 12139 MemOrderLoc = C->getBeginLoc(); 12140 } 12141 break; 12142 } 12143 // The following clauses are allowed, but we don't need to do anything here. 12144 case OMPC_hint: 12145 break; 12146 default: 12147 llvm_unreachable("unknown clause is encountered"); 12148 } 12149 } 12150 bool IsCompareCapture = false; 12151 if (EncounteredAtomicKinds.contains(OMPC_compare) && 12152 EncounteredAtomicKinds.contains(OMPC_capture)) { 12153 IsCompareCapture = true; 12154 AtomicKind = OMPC_compare; 12155 } 12156 // OpenMP 5.0, 2.17.7 atomic Construct, Restrictions 12157 // If atomic-clause is read then memory-order-clause must not be acq_rel or 12158 // release. 12159 // If atomic-clause is write then memory-order-clause must not be acq_rel or 12160 // acquire. 12161 // If atomic-clause is update or not present then memory-order-clause must not 12162 // be acq_rel or acquire. 12163 if ((AtomicKind == OMPC_read && 12164 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_release)) || 12165 ((AtomicKind == OMPC_write || AtomicKind == OMPC_update || 12166 AtomicKind == OMPC_unknown) && 12167 (MemOrderKind == OMPC_acq_rel || MemOrderKind == OMPC_acquire))) { 12168 SourceLocation Loc = AtomicKindLoc; 12169 if (AtomicKind == OMPC_unknown) 12170 Loc = StartLoc; 12171 Diag(Loc, diag::err_omp_atomic_incompatible_mem_order_clause) 12172 << getOpenMPClauseName(AtomicKind) 12173 << (AtomicKind == OMPC_unknown ? 1 : 0) 12174 << getOpenMPClauseName(MemOrderKind); 12175 Diag(MemOrderLoc, diag::note_omp_previous_mem_order_clause) 12176 << getOpenMPClauseName(MemOrderKind); 12177 } 12178 12179 Stmt *Body = AStmt; 12180 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 12181 Body = EWC->getSubExpr(); 12182 12183 Expr *X = nullptr; 12184 Expr *V = nullptr; 12185 Expr *E = nullptr; 12186 Expr *UE = nullptr; 12187 Expr *D = nullptr; 12188 Expr *CE = nullptr; 12189 Expr *R = nullptr; 12190 bool IsXLHSInRHSPart = false; 12191 bool IsPostfixUpdate = false; 12192 bool IsFailOnly = false; 12193 // OpenMP [2.12.6, atomic Construct] 12194 // In the next expressions: 12195 // * x and v (as applicable) are both l-value expressions with scalar type. 12196 // * During the execution of an atomic region, multiple syntactic 12197 // occurrences of x must designate the same storage location. 12198 // * Neither of v and expr (as applicable) may access the storage location 12199 // designated by x. 12200 // * Neither of x and expr (as applicable) may access the storage location 12201 // designated by v. 12202 // * expr is an expression with scalar type. 12203 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 12204 // * binop, binop=, ++, and -- are not overloaded operators. 12205 // * The expression x binop expr must be numerically equivalent to x binop 12206 // (expr). This requirement is satisfied if the operators in expr have 12207 // precedence greater than binop, or by using parentheses around expr or 12208 // subexpressions of expr. 12209 // * The expression expr binop x must be numerically equivalent to (expr) 12210 // binop x. This requirement is satisfied if the operators in expr have 12211 // precedence equal to or greater than binop, or by using parentheses around 12212 // expr or subexpressions of expr. 12213 // * For forms that allow multiple occurrences of x, the number of times 12214 // that x is evaluated is unspecified. 12215 if (AtomicKind == OMPC_read) { 12216 enum { 12217 NotAnExpression, 12218 NotAnAssignmentOp, 12219 NotAScalarType, 12220 NotAnLValue, 12221 NoError 12222 } ErrorFound = NoError; 12223 SourceLocation ErrorLoc, NoteLoc; 12224 SourceRange ErrorRange, NoteRange; 12225 // If clause is read: 12226 // v = x; 12227 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12228 const auto *AtomicBinOp = 12229 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12230 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12231 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 12232 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 12233 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 12234 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 12235 if (!X->isLValue() || !V->isLValue()) { 12236 const Expr *NotLValueExpr = X->isLValue() ? V : X; 12237 ErrorFound = NotAnLValue; 12238 ErrorLoc = AtomicBinOp->getExprLoc(); 12239 ErrorRange = AtomicBinOp->getSourceRange(); 12240 NoteLoc = NotLValueExpr->getExprLoc(); 12241 NoteRange = NotLValueExpr->getSourceRange(); 12242 } 12243 } else if (!X->isInstantiationDependent() || 12244 !V->isInstantiationDependent()) { 12245 const Expr *NotScalarExpr = 12246 (X->isInstantiationDependent() || X->getType()->isScalarType()) 12247 ? V 12248 : X; 12249 ErrorFound = NotAScalarType; 12250 ErrorLoc = AtomicBinOp->getExprLoc(); 12251 ErrorRange = AtomicBinOp->getSourceRange(); 12252 NoteLoc = NotScalarExpr->getExprLoc(); 12253 NoteRange = NotScalarExpr->getSourceRange(); 12254 } 12255 } else if (!AtomicBody->isInstantiationDependent()) { 12256 ErrorFound = NotAnAssignmentOp; 12257 ErrorLoc = AtomicBody->getExprLoc(); 12258 ErrorRange = AtomicBody->getSourceRange(); 12259 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12260 : AtomicBody->getExprLoc(); 12261 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12262 : AtomicBody->getSourceRange(); 12263 } 12264 } else { 12265 ErrorFound = NotAnExpression; 12266 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12267 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 12268 } 12269 if (ErrorFound != NoError) { 12270 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 12271 << ErrorRange; 12272 Diag(NoteLoc, diag::note_omp_atomic_read_write) 12273 << ErrorFound << NoteRange; 12274 return StmtError(); 12275 } 12276 if (CurContext->isDependentContext()) 12277 V = X = nullptr; 12278 } else if (AtomicKind == OMPC_write) { 12279 enum { 12280 NotAnExpression, 12281 NotAnAssignmentOp, 12282 NotAScalarType, 12283 NotAnLValue, 12284 NoError 12285 } ErrorFound = NoError; 12286 SourceLocation ErrorLoc, NoteLoc; 12287 SourceRange ErrorRange, NoteRange; 12288 // If clause is write: 12289 // x = expr; 12290 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12291 const auto *AtomicBinOp = 12292 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12293 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12294 X = AtomicBinOp->getLHS(); 12295 E = AtomicBinOp->getRHS(); 12296 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 12297 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 12298 if (!X->isLValue()) { 12299 ErrorFound = NotAnLValue; 12300 ErrorLoc = AtomicBinOp->getExprLoc(); 12301 ErrorRange = AtomicBinOp->getSourceRange(); 12302 NoteLoc = X->getExprLoc(); 12303 NoteRange = X->getSourceRange(); 12304 } 12305 } else if (!X->isInstantiationDependent() || 12306 !E->isInstantiationDependent()) { 12307 const Expr *NotScalarExpr = 12308 (X->isInstantiationDependent() || X->getType()->isScalarType()) 12309 ? E 12310 : X; 12311 ErrorFound = NotAScalarType; 12312 ErrorLoc = AtomicBinOp->getExprLoc(); 12313 ErrorRange = AtomicBinOp->getSourceRange(); 12314 NoteLoc = NotScalarExpr->getExprLoc(); 12315 NoteRange = NotScalarExpr->getSourceRange(); 12316 } 12317 } else if (!AtomicBody->isInstantiationDependent()) { 12318 ErrorFound = NotAnAssignmentOp; 12319 ErrorLoc = AtomicBody->getExprLoc(); 12320 ErrorRange = AtomicBody->getSourceRange(); 12321 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12322 : AtomicBody->getExprLoc(); 12323 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12324 : AtomicBody->getSourceRange(); 12325 } 12326 } else { 12327 ErrorFound = NotAnExpression; 12328 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12329 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 12330 } 12331 if (ErrorFound != NoError) { 12332 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 12333 << ErrorRange; 12334 Diag(NoteLoc, diag::note_omp_atomic_read_write) 12335 << ErrorFound << NoteRange; 12336 return StmtError(); 12337 } 12338 if (CurContext->isDependentContext()) 12339 E = X = nullptr; 12340 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 12341 // If clause is update: 12342 // x++; 12343 // x--; 12344 // ++x; 12345 // --x; 12346 // x binop= expr; 12347 // x = x binop expr; 12348 // x = expr binop x; 12349 OpenMPAtomicUpdateChecker Checker(*this); 12350 if (Checker.checkStatement( 12351 Body, 12352 (AtomicKind == OMPC_update) 12353 ? diag::err_omp_atomic_update_not_expression_statement 12354 : diag::err_omp_atomic_not_expression_statement, 12355 diag::note_omp_atomic_update)) 12356 return StmtError(); 12357 if (!CurContext->isDependentContext()) { 12358 E = Checker.getExpr(); 12359 X = Checker.getX(); 12360 UE = Checker.getUpdateExpr(); 12361 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12362 } 12363 } else if (AtomicKind == OMPC_capture) { 12364 enum { 12365 NotAnAssignmentOp, 12366 NotACompoundStatement, 12367 NotTwoSubstatements, 12368 NotASpecificExpression, 12369 NoError 12370 } ErrorFound = NoError; 12371 SourceLocation ErrorLoc, NoteLoc; 12372 SourceRange ErrorRange, NoteRange; 12373 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 12374 // If clause is a capture: 12375 // v = x++; 12376 // v = x--; 12377 // v = ++x; 12378 // v = --x; 12379 // v = x binop= expr; 12380 // v = x = x binop expr; 12381 // v = x = expr binop x; 12382 const auto *AtomicBinOp = 12383 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 12384 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 12385 V = AtomicBinOp->getLHS(); 12386 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 12387 OpenMPAtomicUpdateChecker Checker(*this); 12388 if (Checker.checkStatement( 12389 Body, diag::err_omp_atomic_capture_not_expression_statement, 12390 diag::note_omp_atomic_update)) 12391 return StmtError(); 12392 E = Checker.getExpr(); 12393 X = Checker.getX(); 12394 UE = Checker.getUpdateExpr(); 12395 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12396 IsPostfixUpdate = Checker.isPostfixUpdate(); 12397 } else if (!AtomicBody->isInstantiationDependent()) { 12398 ErrorLoc = AtomicBody->getExprLoc(); 12399 ErrorRange = AtomicBody->getSourceRange(); 12400 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 12401 : AtomicBody->getExprLoc(); 12402 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 12403 : AtomicBody->getSourceRange(); 12404 ErrorFound = NotAnAssignmentOp; 12405 } 12406 if (ErrorFound != NoError) { 12407 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 12408 << ErrorRange; 12409 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 12410 return StmtError(); 12411 } 12412 if (CurContext->isDependentContext()) 12413 UE = V = E = X = nullptr; 12414 } else { 12415 // If clause is a capture: 12416 // { v = x; x = expr; } 12417 // { v = x; x++; } 12418 // { v = x; x--; } 12419 // { v = x; ++x; } 12420 // { v = x; --x; } 12421 // { v = x; x binop= expr; } 12422 // { v = x; x = x binop expr; } 12423 // { v = x; x = expr binop x; } 12424 // { x++; v = x; } 12425 // { x--; v = x; } 12426 // { ++x; v = x; } 12427 // { --x; v = x; } 12428 // { x binop= expr; v = x; } 12429 // { x = x binop expr; v = x; } 12430 // { x = expr binop x; v = x; } 12431 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 12432 // Check that this is { expr1; expr2; } 12433 if (CS->size() == 2) { 12434 Stmt *First = CS->body_front(); 12435 Stmt *Second = CS->body_back(); 12436 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 12437 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 12438 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 12439 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 12440 // Need to find what subexpression is 'v' and what is 'x'. 12441 OpenMPAtomicUpdateChecker Checker(*this); 12442 bool IsUpdateExprFound = !Checker.checkStatement(Second); 12443 BinaryOperator *BinOp = nullptr; 12444 if (IsUpdateExprFound) { 12445 BinOp = dyn_cast<BinaryOperator>(First); 12446 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 12447 } 12448 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 12449 // { v = x; x++; } 12450 // { v = x; x--; } 12451 // { v = x; ++x; } 12452 // { v = x; --x; } 12453 // { v = x; x binop= expr; } 12454 // { v = x; x = x binop expr; } 12455 // { v = x; x = expr binop x; } 12456 // Check that the first expression has form v = x. 12457 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 12458 llvm::FoldingSetNodeID XId, PossibleXId; 12459 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 12460 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 12461 IsUpdateExprFound = XId == PossibleXId; 12462 if (IsUpdateExprFound) { 12463 V = BinOp->getLHS(); 12464 X = Checker.getX(); 12465 E = Checker.getExpr(); 12466 UE = Checker.getUpdateExpr(); 12467 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12468 IsPostfixUpdate = true; 12469 } 12470 } 12471 if (!IsUpdateExprFound) { 12472 IsUpdateExprFound = !Checker.checkStatement(First); 12473 BinOp = nullptr; 12474 if (IsUpdateExprFound) { 12475 BinOp = dyn_cast<BinaryOperator>(Second); 12476 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 12477 } 12478 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 12479 // { x++; v = x; } 12480 // { x--; v = x; } 12481 // { ++x; v = x; } 12482 // { --x; v = x; } 12483 // { x binop= expr; v = x; } 12484 // { x = x binop expr; v = x; } 12485 // { x = expr binop x; v = x; } 12486 // Check that the second expression has form v = x. 12487 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 12488 llvm::FoldingSetNodeID XId, PossibleXId; 12489 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 12490 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 12491 IsUpdateExprFound = XId == PossibleXId; 12492 if (IsUpdateExprFound) { 12493 V = BinOp->getLHS(); 12494 X = Checker.getX(); 12495 E = Checker.getExpr(); 12496 UE = Checker.getUpdateExpr(); 12497 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 12498 IsPostfixUpdate = false; 12499 } 12500 } 12501 } 12502 if (!IsUpdateExprFound) { 12503 // { v = x; x = expr; } 12504 auto *FirstExpr = dyn_cast<Expr>(First); 12505 auto *SecondExpr = dyn_cast<Expr>(Second); 12506 if (!FirstExpr || !SecondExpr || 12507 !(FirstExpr->isInstantiationDependent() || 12508 SecondExpr->isInstantiationDependent())) { 12509 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 12510 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 12511 ErrorFound = NotAnAssignmentOp; 12512 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 12513 : First->getBeginLoc(); 12514 NoteRange = ErrorRange = FirstBinOp 12515 ? FirstBinOp->getSourceRange() 12516 : SourceRange(ErrorLoc, ErrorLoc); 12517 } else { 12518 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 12519 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 12520 ErrorFound = NotAnAssignmentOp; 12521 NoteLoc = ErrorLoc = SecondBinOp 12522 ? SecondBinOp->getOperatorLoc() 12523 : Second->getBeginLoc(); 12524 NoteRange = ErrorRange = 12525 SecondBinOp ? SecondBinOp->getSourceRange() 12526 : SourceRange(ErrorLoc, ErrorLoc); 12527 } else { 12528 Expr *PossibleXRHSInFirst = 12529 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 12530 Expr *PossibleXLHSInSecond = 12531 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 12532 llvm::FoldingSetNodeID X1Id, X2Id; 12533 PossibleXRHSInFirst->Profile(X1Id, Context, 12534 /*Canonical=*/true); 12535 PossibleXLHSInSecond->Profile(X2Id, Context, 12536 /*Canonical=*/true); 12537 IsUpdateExprFound = X1Id == X2Id; 12538 if (IsUpdateExprFound) { 12539 V = FirstBinOp->getLHS(); 12540 X = SecondBinOp->getLHS(); 12541 E = SecondBinOp->getRHS(); 12542 UE = nullptr; 12543 IsXLHSInRHSPart = false; 12544 IsPostfixUpdate = true; 12545 } else { 12546 ErrorFound = NotASpecificExpression; 12547 ErrorLoc = FirstBinOp->getExprLoc(); 12548 ErrorRange = FirstBinOp->getSourceRange(); 12549 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 12550 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 12551 } 12552 } 12553 } 12554 } 12555 } 12556 } else { 12557 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12558 NoteRange = ErrorRange = 12559 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 12560 ErrorFound = NotTwoSubstatements; 12561 } 12562 } else { 12563 NoteLoc = ErrorLoc = Body->getBeginLoc(); 12564 NoteRange = ErrorRange = 12565 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 12566 ErrorFound = NotACompoundStatement; 12567 } 12568 } 12569 if (ErrorFound != NoError) { 12570 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 12571 << ErrorRange; 12572 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 12573 return StmtError(); 12574 } 12575 if (CurContext->isDependentContext()) 12576 UE = V = E = X = nullptr; 12577 } else if (AtomicKind == OMPC_compare) { 12578 if (IsCompareCapture) { 12579 OpenMPAtomicCompareCaptureChecker::ErrorInfoTy ErrorInfo; 12580 OpenMPAtomicCompareCaptureChecker Checker(*this); 12581 if (!Checker.checkStmt(Body, ErrorInfo)) { 12582 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare_capture) 12583 << ErrorInfo.ErrorRange; 12584 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare) 12585 << ErrorInfo.Error << ErrorInfo.NoteRange; 12586 return StmtError(); 12587 } 12588 X = Checker.getX(); 12589 E = Checker.getE(); 12590 D = Checker.getD(); 12591 CE = Checker.getCond(); 12592 V = Checker.getV(); 12593 R = Checker.getR(); 12594 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'. 12595 IsXLHSInRHSPart = Checker.isXBinopExpr(); 12596 IsFailOnly = Checker.isFailOnly(); 12597 IsPostfixUpdate = Checker.isPostfixUpdate(); 12598 } else { 12599 OpenMPAtomicCompareChecker::ErrorInfoTy ErrorInfo; 12600 OpenMPAtomicCompareChecker Checker(*this); 12601 if (!Checker.checkStmt(Body, ErrorInfo)) { 12602 Diag(ErrorInfo.ErrorLoc, diag::err_omp_atomic_compare) 12603 << ErrorInfo.ErrorRange; 12604 Diag(ErrorInfo.NoteLoc, diag::note_omp_atomic_compare) 12605 << ErrorInfo.Error << ErrorInfo.NoteRange; 12606 return StmtError(); 12607 } 12608 X = Checker.getX(); 12609 E = Checker.getE(); 12610 D = Checker.getD(); 12611 CE = Checker.getCond(); 12612 // We reuse IsXLHSInRHSPart to tell if it is in the form 'x ordop expr'. 12613 IsXLHSInRHSPart = Checker.isXBinopExpr(); 12614 } 12615 } 12616 12617 setFunctionHasBranchProtectedScope(); 12618 12619 return OMPAtomicDirective::Create( 12620 Context, StartLoc, EndLoc, Clauses, AStmt, 12621 {X, V, R, E, UE, D, CE, IsXLHSInRHSPart, IsPostfixUpdate, IsFailOnly}); 12622 } 12623 12624 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 12625 Stmt *AStmt, 12626 SourceLocation StartLoc, 12627 SourceLocation EndLoc) { 12628 if (!AStmt) 12629 return StmtError(); 12630 12631 auto *CS = cast<CapturedStmt>(AStmt); 12632 // 1.2.2 OpenMP Language Terminology 12633 // Structured block - An executable statement with a single entry at the 12634 // top and a single exit at the bottom. 12635 // The point of exit cannot be a branch out of the structured block. 12636 // longjmp() and throw() must not violate the entry/exit criteria. 12637 CS->getCapturedDecl()->setNothrow(); 12638 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 12639 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12640 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12641 // 1.2.2 OpenMP Language Terminology 12642 // Structured block - An executable statement with a single entry at the 12643 // top and a single exit at the bottom. 12644 // The point of exit cannot be a branch out of the structured block. 12645 // longjmp() and throw() must not violate the entry/exit criteria. 12646 CS->getCapturedDecl()->setNothrow(); 12647 } 12648 12649 // OpenMP [2.16, Nesting of Regions] 12650 // If specified, a teams construct must be contained within a target 12651 // construct. That target construct must contain no statements or directives 12652 // outside of the teams construct. 12653 if (DSAStack->hasInnerTeamsRegion()) { 12654 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 12655 bool OMPTeamsFound = true; 12656 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 12657 auto I = CS->body_begin(); 12658 while (I != CS->body_end()) { 12659 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 12660 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 12661 OMPTeamsFound) { 12662 12663 OMPTeamsFound = false; 12664 break; 12665 } 12666 ++I; 12667 } 12668 assert(I != CS->body_end() && "Not found statement"); 12669 S = *I; 12670 } else { 12671 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 12672 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 12673 } 12674 if (!OMPTeamsFound) { 12675 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 12676 Diag(DSAStack->getInnerTeamsRegionLoc(), 12677 diag::note_omp_nested_teams_construct_here); 12678 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 12679 << isa<OMPExecutableDirective>(S); 12680 return StmtError(); 12681 } 12682 } 12683 12684 setFunctionHasBranchProtectedScope(); 12685 12686 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 12687 } 12688 12689 StmtResult 12690 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 12691 Stmt *AStmt, SourceLocation StartLoc, 12692 SourceLocation EndLoc) { 12693 if (!AStmt) 12694 return StmtError(); 12695 12696 auto *CS = cast<CapturedStmt>(AStmt); 12697 // 1.2.2 OpenMP Language Terminology 12698 // Structured block - An executable statement with a single entry at the 12699 // top and a single exit at the bottom. 12700 // The point of exit cannot be a branch out of the structured block. 12701 // longjmp() and throw() must not violate the entry/exit criteria. 12702 CS->getCapturedDecl()->setNothrow(); 12703 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 12704 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12705 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12706 // 1.2.2 OpenMP Language Terminology 12707 // Structured block - An executable statement with a single entry at the 12708 // top and a single exit at the bottom. 12709 // The point of exit cannot be a branch out of the structured block. 12710 // longjmp() and throw() must not violate the entry/exit criteria. 12711 CS->getCapturedDecl()->setNothrow(); 12712 } 12713 12714 setFunctionHasBranchProtectedScope(); 12715 12716 return OMPTargetParallelDirective::Create( 12717 Context, StartLoc, EndLoc, Clauses, AStmt, 12718 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 12719 } 12720 12721 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 12722 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 12723 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 12724 if (!AStmt) 12725 return StmtError(); 12726 12727 auto *CS = cast<CapturedStmt>(AStmt); 12728 // 1.2.2 OpenMP Language Terminology 12729 // Structured block - An executable statement with a single entry at the 12730 // top and a single exit at the bottom. 12731 // The point of exit cannot be a branch out of the structured block. 12732 // longjmp() and throw() must not violate the entry/exit criteria. 12733 CS->getCapturedDecl()->setNothrow(); 12734 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 12735 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12736 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12737 // 1.2.2 OpenMP Language Terminology 12738 // Structured block - An executable statement with a single entry at the 12739 // top and a single exit at the bottom. 12740 // The point of exit cannot be a branch out of the structured block. 12741 // longjmp() and throw() must not violate the entry/exit criteria. 12742 CS->getCapturedDecl()->setNothrow(); 12743 } 12744 12745 OMPLoopBasedDirective::HelperExprs B; 12746 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 12747 // define the nested loops number. 12748 unsigned NestedLoopCount = 12749 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 12750 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 12751 VarsWithImplicitDSA, B); 12752 if (NestedLoopCount == 0) 12753 return StmtError(); 12754 12755 assert((CurContext->isDependentContext() || B.builtAll()) && 12756 "omp target parallel for loop exprs were not built"); 12757 12758 if (!CurContext->isDependentContext()) { 12759 // Finalize the clauses that need pre-built expressions for CodeGen. 12760 for (OMPClause *C : Clauses) { 12761 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 12762 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 12763 B.NumIterations, *this, CurScope, 12764 DSAStack)) 12765 return StmtError(); 12766 } 12767 } 12768 12769 setFunctionHasBranchProtectedScope(); 12770 return OMPTargetParallelForDirective::Create( 12771 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 12772 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 12773 } 12774 12775 /// Check for existence of a map clause in the list of clauses. 12776 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 12777 const OpenMPClauseKind K) { 12778 return llvm::any_of( 12779 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 12780 } 12781 12782 template <typename... Params> 12783 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 12784 const Params... ClauseTypes) { 12785 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 12786 } 12787 12788 /// Check if the variables in the mapping clause are externally visible. 12789 static bool isClauseMappable(ArrayRef<OMPClause *> Clauses) { 12790 for (const OMPClause *C : Clauses) { 12791 if (auto *TC = dyn_cast<OMPToClause>(C)) 12792 return llvm::all_of(TC->all_decls(), [](ValueDecl *VD) { 12793 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() || 12794 (VD->isExternallyVisible() && 12795 VD->getVisibility() != HiddenVisibility); 12796 }); 12797 else if (auto *FC = dyn_cast<OMPFromClause>(C)) 12798 return llvm::all_of(FC->all_decls(), [](ValueDecl *VD) { 12799 return !VD || !VD->hasAttr<OMPDeclareTargetDeclAttr>() || 12800 (VD->isExternallyVisible() && 12801 VD->getVisibility() != HiddenVisibility); 12802 }); 12803 } 12804 12805 return true; 12806 } 12807 12808 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 12809 Stmt *AStmt, 12810 SourceLocation StartLoc, 12811 SourceLocation EndLoc) { 12812 if (!AStmt) 12813 return StmtError(); 12814 12815 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 12816 12817 // OpenMP [2.12.2, target data Construct, Restrictions] 12818 // At least one map, use_device_addr or use_device_ptr clause must appear on 12819 // the directive. 12820 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr) && 12821 (LangOpts.OpenMP < 50 || !hasClauses(Clauses, OMPC_use_device_addr))) { 12822 StringRef Expected; 12823 if (LangOpts.OpenMP < 50) 12824 Expected = "'map' or 'use_device_ptr'"; 12825 else 12826 Expected = "'map', 'use_device_ptr', or 'use_device_addr'"; 12827 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 12828 << Expected << getOpenMPDirectiveName(OMPD_target_data); 12829 return StmtError(); 12830 } 12831 12832 setFunctionHasBranchProtectedScope(); 12833 12834 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 12835 AStmt); 12836 } 12837 12838 StmtResult 12839 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 12840 SourceLocation StartLoc, 12841 SourceLocation EndLoc, Stmt *AStmt) { 12842 if (!AStmt) 12843 return StmtError(); 12844 12845 auto *CS = cast<CapturedStmt>(AStmt); 12846 // 1.2.2 OpenMP Language Terminology 12847 // Structured block - An executable statement with a single entry at the 12848 // top and a single exit at the bottom. 12849 // The point of exit cannot be a branch out of the structured block. 12850 // longjmp() and throw() must not violate the entry/exit criteria. 12851 CS->getCapturedDecl()->setNothrow(); 12852 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 12853 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12854 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12855 // 1.2.2 OpenMP Language Terminology 12856 // Structured block - An executable statement with a single entry at the 12857 // top and a single exit at the bottom. 12858 // The point of exit cannot be a branch out of the structured block. 12859 // longjmp() and throw() must not violate the entry/exit criteria. 12860 CS->getCapturedDecl()->setNothrow(); 12861 } 12862 12863 // OpenMP [2.10.2, Restrictions, p. 99] 12864 // At least one map clause must appear on the directive. 12865 if (!hasClauses(Clauses, OMPC_map)) { 12866 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 12867 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 12868 return StmtError(); 12869 } 12870 12871 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 12872 AStmt); 12873 } 12874 12875 StmtResult 12876 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 12877 SourceLocation StartLoc, 12878 SourceLocation EndLoc, Stmt *AStmt) { 12879 if (!AStmt) 12880 return StmtError(); 12881 12882 auto *CS = cast<CapturedStmt>(AStmt); 12883 // 1.2.2 OpenMP Language Terminology 12884 // Structured block - An executable statement with a single entry at the 12885 // top and a single exit at the bottom. 12886 // The point of exit cannot be a branch out of the structured block. 12887 // longjmp() and throw() must not violate the entry/exit criteria. 12888 CS->getCapturedDecl()->setNothrow(); 12889 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 12890 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12891 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12892 // 1.2.2 OpenMP Language Terminology 12893 // Structured block - An executable statement with a single entry at the 12894 // top and a single exit at the bottom. 12895 // The point of exit cannot be a branch out of the structured block. 12896 // longjmp() and throw() must not violate the entry/exit criteria. 12897 CS->getCapturedDecl()->setNothrow(); 12898 } 12899 12900 // OpenMP [2.10.3, Restrictions, p. 102] 12901 // At least one map clause must appear on the directive. 12902 if (!hasClauses(Clauses, OMPC_map)) { 12903 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 12904 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 12905 return StmtError(); 12906 } 12907 12908 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 12909 AStmt); 12910 } 12911 12912 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 12913 SourceLocation StartLoc, 12914 SourceLocation EndLoc, 12915 Stmt *AStmt) { 12916 if (!AStmt) 12917 return StmtError(); 12918 12919 auto *CS = cast<CapturedStmt>(AStmt); 12920 // 1.2.2 OpenMP Language Terminology 12921 // Structured block - An executable statement with a single entry at the 12922 // top and a single exit at the bottom. 12923 // The point of exit cannot be a branch out of the structured block. 12924 // longjmp() and throw() must not violate the entry/exit criteria. 12925 CS->getCapturedDecl()->setNothrow(); 12926 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 12927 ThisCaptureLevel > 1; --ThisCaptureLevel) { 12928 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 12929 // 1.2.2 OpenMP Language Terminology 12930 // Structured block - An executable statement with a single entry at the 12931 // top and a single exit at the bottom. 12932 // The point of exit cannot be a branch out of the structured block. 12933 // longjmp() and throw() must not violate the entry/exit criteria. 12934 CS->getCapturedDecl()->setNothrow(); 12935 } 12936 12937 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 12938 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 12939 return StmtError(); 12940 } 12941 12942 if (!isClauseMappable(Clauses)) { 12943 Diag(StartLoc, diag::err_omp_cannot_update_with_internal_linkage); 12944 return StmtError(); 12945 } 12946 12947 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 12948 AStmt); 12949 } 12950 12951 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 12952 Stmt *AStmt, SourceLocation StartLoc, 12953 SourceLocation EndLoc) { 12954 if (!AStmt) 12955 return StmtError(); 12956 12957 auto *CS = cast<CapturedStmt>(AStmt); 12958 // 1.2.2 OpenMP Language Terminology 12959 // Structured block - An executable statement with a single entry at the 12960 // top and a single exit at the bottom. 12961 // The point of exit cannot be a branch out of the structured block. 12962 // longjmp() and throw() must not violate the entry/exit criteria. 12963 CS->getCapturedDecl()->setNothrow(); 12964 12965 setFunctionHasBranchProtectedScope(); 12966 12967 DSAStack->setParentTeamsRegionLoc(StartLoc); 12968 12969 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 12970 } 12971 12972 StmtResult 12973 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 12974 SourceLocation EndLoc, 12975 OpenMPDirectiveKind CancelRegion) { 12976 if (DSAStack->isParentNowaitRegion()) { 12977 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 12978 return StmtError(); 12979 } 12980 if (DSAStack->isParentOrderedRegion()) { 12981 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 12982 return StmtError(); 12983 } 12984 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 12985 CancelRegion); 12986 } 12987 12988 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 12989 SourceLocation StartLoc, 12990 SourceLocation EndLoc, 12991 OpenMPDirectiveKind CancelRegion) { 12992 if (DSAStack->isParentNowaitRegion()) { 12993 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 12994 return StmtError(); 12995 } 12996 if (DSAStack->isParentOrderedRegion()) { 12997 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 12998 return StmtError(); 12999 } 13000 DSAStack->setParentCancelRegion(/*Cancel=*/true); 13001 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 13002 CancelRegion); 13003 } 13004 13005 static bool checkReductionClauseWithNogroup(Sema &S, 13006 ArrayRef<OMPClause *> Clauses) { 13007 const OMPClause *ReductionClause = nullptr; 13008 const OMPClause *NogroupClause = nullptr; 13009 for (const OMPClause *C : Clauses) { 13010 if (C->getClauseKind() == OMPC_reduction) { 13011 ReductionClause = C; 13012 if (NogroupClause) 13013 break; 13014 continue; 13015 } 13016 if (C->getClauseKind() == OMPC_nogroup) { 13017 NogroupClause = C; 13018 if (ReductionClause) 13019 break; 13020 continue; 13021 } 13022 } 13023 if (ReductionClause && NogroupClause) { 13024 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 13025 << SourceRange(NogroupClause->getBeginLoc(), 13026 NogroupClause->getEndLoc()); 13027 return true; 13028 } 13029 return false; 13030 } 13031 13032 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 13033 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13034 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13035 if (!AStmt) 13036 return StmtError(); 13037 13038 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13039 OMPLoopBasedDirective::HelperExprs B; 13040 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13041 // define the nested loops number. 13042 unsigned NestedLoopCount = 13043 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 13044 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13045 VarsWithImplicitDSA, B); 13046 if (NestedLoopCount == 0) 13047 return StmtError(); 13048 13049 assert((CurContext->isDependentContext() || B.builtAll()) && 13050 "omp for loop exprs were not built"); 13051 13052 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13053 // The grainsize clause and num_tasks clause are mutually exclusive and may 13054 // not appear on the same taskloop directive. 13055 if (checkMutuallyExclusiveClauses(*this, Clauses, 13056 {OMPC_grainsize, OMPC_num_tasks})) 13057 return StmtError(); 13058 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13059 // If a reduction clause is present on the taskloop directive, the nogroup 13060 // clause must not be specified. 13061 if (checkReductionClauseWithNogroup(*this, Clauses)) 13062 return StmtError(); 13063 13064 setFunctionHasBranchProtectedScope(); 13065 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13066 NestedLoopCount, Clauses, AStmt, B, 13067 DSAStack->isCancelRegion()); 13068 } 13069 13070 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 13071 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13072 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13073 if (!AStmt) 13074 return StmtError(); 13075 13076 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13077 OMPLoopBasedDirective::HelperExprs B; 13078 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13079 // define the nested loops number. 13080 unsigned NestedLoopCount = 13081 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 13082 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13083 VarsWithImplicitDSA, B); 13084 if (NestedLoopCount == 0) 13085 return StmtError(); 13086 13087 assert((CurContext->isDependentContext() || B.builtAll()) && 13088 "omp for loop exprs were not built"); 13089 13090 if (!CurContext->isDependentContext()) { 13091 // Finalize the clauses that need pre-built expressions for CodeGen. 13092 for (OMPClause *C : Clauses) { 13093 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13094 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13095 B.NumIterations, *this, CurScope, 13096 DSAStack)) 13097 return StmtError(); 13098 } 13099 } 13100 13101 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13102 // The grainsize clause and num_tasks clause are mutually exclusive and may 13103 // not appear on the same taskloop directive. 13104 if (checkMutuallyExclusiveClauses(*this, Clauses, 13105 {OMPC_grainsize, OMPC_num_tasks})) 13106 return StmtError(); 13107 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13108 // If a reduction clause is present on the taskloop directive, the nogroup 13109 // clause must not be specified. 13110 if (checkReductionClauseWithNogroup(*this, Clauses)) 13111 return StmtError(); 13112 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13113 return StmtError(); 13114 13115 setFunctionHasBranchProtectedScope(); 13116 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 13117 NestedLoopCount, Clauses, AStmt, B); 13118 } 13119 13120 StmtResult Sema::ActOnOpenMPMasterTaskLoopDirective( 13121 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13122 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13123 if (!AStmt) 13124 return StmtError(); 13125 13126 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13127 OMPLoopBasedDirective::HelperExprs B; 13128 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13129 // define the nested loops number. 13130 unsigned NestedLoopCount = 13131 checkOpenMPLoop(OMPD_master_taskloop, getCollapseNumberExpr(Clauses), 13132 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13133 VarsWithImplicitDSA, B); 13134 if (NestedLoopCount == 0) 13135 return StmtError(); 13136 13137 assert((CurContext->isDependentContext() || B.builtAll()) && 13138 "omp for loop exprs were not built"); 13139 13140 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13141 // The grainsize clause and num_tasks clause are mutually exclusive and may 13142 // not appear on the same taskloop directive. 13143 if (checkMutuallyExclusiveClauses(*this, Clauses, 13144 {OMPC_grainsize, OMPC_num_tasks})) 13145 return StmtError(); 13146 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13147 // If a reduction clause is present on the taskloop directive, the nogroup 13148 // clause must not be specified. 13149 if (checkReductionClauseWithNogroup(*this, Clauses)) 13150 return StmtError(); 13151 13152 setFunctionHasBranchProtectedScope(); 13153 return OMPMasterTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13154 NestedLoopCount, Clauses, AStmt, B, 13155 DSAStack->isCancelRegion()); 13156 } 13157 13158 StmtResult Sema::ActOnOpenMPMaskedTaskLoopDirective( 13159 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13160 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13161 if (!AStmt) 13162 return StmtError(); 13163 13164 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13165 OMPLoopBasedDirective::HelperExprs B; 13166 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13167 // define the nested loops number. 13168 unsigned NestedLoopCount = 13169 checkOpenMPLoop(OMPD_masked_taskloop, getCollapseNumberExpr(Clauses), 13170 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13171 VarsWithImplicitDSA, B); 13172 if (NestedLoopCount == 0) 13173 return StmtError(); 13174 13175 assert((CurContext->isDependentContext() || B.builtAll()) && 13176 "omp for loop exprs were not built"); 13177 13178 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13179 // The grainsize clause and num_tasks clause are mutually exclusive and may 13180 // not appear on the same taskloop directive. 13181 if (checkMutuallyExclusiveClauses(*this, Clauses, 13182 {OMPC_grainsize, OMPC_num_tasks})) 13183 return StmtError(); 13184 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13185 // If a reduction clause is present on the taskloop directive, the nogroup 13186 // clause must not be specified. 13187 if (checkReductionClauseWithNogroup(*this, Clauses)) 13188 return StmtError(); 13189 13190 setFunctionHasBranchProtectedScope(); 13191 return OMPMaskedTaskLoopDirective::Create(Context, StartLoc, EndLoc, 13192 NestedLoopCount, Clauses, AStmt, B, 13193 DSAStack->isCancelRegion()); 13194 } 13195 13196 StmtResult Sema::ActOnOpenMPMasterTaskLoopSimdDirective( 13197 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13198 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13199 if (!AStmt) 13200 return StmtError(); 13201 13202 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13203 OMPLoopBasedDirective::HelperExprs B; 13204 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13205 // define the nested loops number. 13206 unsigned NestedLoopCount = 13207 checkOpenMPLoop(OMPD_master_taskloop_simd, getCollapseNumberExpr(Clauses), 13208 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 13209 VarsWithImplicitDSA, B); 13210 if (NestedLoopCount == 0) 13211 return StmtError(); 13212 13213 assert((CurContext->isDependentContext() || B.builtAll()) && 13214 "omp for loop exprs were not built"); 13215 13216 if (!CurContext->isDependentContext()) { 13217 // Finalize the clauses that need pre-built expressions for CodeGen. 13218 for (OMPClause *C : Clauses) { 13219 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13220 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13221 B.NumIterations, *this, CurScope, 13222 DSAStack)) 13223 return StmtError(); 13224 } 13225 } 13226 13227 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13228 // The grainsize clause and num_tasks clause are mutually exclusive and may 13229 // not appear on the same taskloop directive. 13230 if (checkMutuallyExclusiveClauses(*this, Clauses, 13231 {OMPC_grainsize, OMPC_num_tasks})) 13232 return StmtError(); 13233 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13234 // If a reduction clause is present on the taskloop directive, the nogroup 13235 // clause must not be specified. 13236 if (checkReductionClauseWithNogroup(*this, Clauses)) 13237 return StmtError(); 13238 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13239 return StmtError(); 13240 13241 setFunctionHasBranchProtectedScope(); 13242 return OMPMasterTaskLoopSimdDirective::Create( 13243 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13244 } 13245 13246 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopDirective( 13247 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13248 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13249 if (!AStmt) 13250 return StmtError(); 13251 13252 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13253 auto *CS = cast<CapturedStmt>(AStmt); 13254 // 1.2.2 OpenMP Language Terminology 13255 // Structured block - An executable statement with a single entry at the 13256 // top and a single exit at the bottom. 13257 // The point of exit cannot be a branch out of the structured block. 13258 // longjmp() and throw() must not violate the entry/exit criteria. 13259 CS->getCapturedDecl()->setNothrow(); 13260 for (int ThisCaptureLevel = 13261 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop); 13262 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13263 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13264 // 1.2.2 OpenMP Language Terminology 13265 // Structured block - An executable statement with a single entry at the 13266 // top and a single exit at the bottom. 13267 // The point of exit cannot be a branch out of the structured block. 13268 // longjmp() and throw() must not violate the entry/exit criteria. 13269 CS->getCapturedDecl()->setNothrow(); 13270 } 13271 13272 OMPLoopBasedDirective::HelperExprs B; 13273 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13274 // define the nested loops number. 13275 unsigned NestedLoopCount = checkOpenMPLoop( 13276 OMPD_parallel_master_taskloop, getCollapseNumberExpr(Clauses), 13277 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13278 VarsWithImplicitDSA, B); 13279 if (NestedLoopCount == 0) 13280 return StmtError(); 13281 13282 assert((CurContext->isDependentContext() || B.builtAll()) && 13283 "omp for loop exprs were not built"); 13284 13285 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13286 // The grainsize clause and num_tasks clause are mutually exclusive and may 13287 // not appear on the same taskloop directive. 13288 if (checkMutuallyExclusiveClauses(*this, Clauses, 13289 {OMPC_grainsize, OMPC_num_tasks})) 13290 return StmtError(); 13291 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13292 // If a reduction clause is present on the taskloop directive, the nogroup 13293 // clause must not be specified. 13294 if (checkReductionClauseWithNogroup(*this, Clauses)) 13295 return StmtError(); 13296 13297 setFunctionHasBranchProtectedScope(); 13298 return OMPParallelMasterTaskLoopDirective::Create( 13299 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13300 DSAStack->isCancelRegion()); 13301 } 13302 13303 StmtResult Sema::ActOnOpenMPParallelMasterTaskLoopSimdDirective( 13304 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13305 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13306 if (!AStmt) 13307 return StmtError(); 13308 13309 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13310 auto *CS = cast<CapturedStmt>(AStmt); 13311 // 1.2.2 OpenMP Language Terminology 13312 // Structured block - An executable statement with a single entry at the 13313 // top and a single exit at the bottom. 13314 // The point of exit cannot be a branch out of the structured block. 13315 // longjmp() and throw() must not violate the entry/exit criteria. 13316 CS->getCapturedDecl()->setNothrow(); 13317 for (int ThisCaptureLevel = 13318 getOpenMPCaptureLevels(OMPD_parallel_master_taskloop_simd); 13319 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13320 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13321 // 1.2.2 OpenMP Language Terminology 13322 // Structured block - An executable statement with a single entry at the 13323 // top and a single exit at the bottom. 13324 // The point of exit cannot be a branch out of the structured block. 13325 // longjmp() and throw() must not violate the entry/exit criteria. 13326 CS->getCapturedDecl()->setNothrow(); 13327 } 13328 13329 OMPLoopBasedDirective::HelperExprs B; 13330 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13331 // define the nested loops number. 13332 unsigned NestedLoopCount = checkOpenMPLoop( 13333 OMPD_parallel_master_taskloop_simd, getCollapseNumberExpr(Clauses), 13334 /*OrderedLoopCountExpr=*/nullptr, CS, *this, *DSAStack, 13335 VarsWithImplicitDSA, B); 13336 if (NestedLoopCount == 0) 13337 return StmtError(); 13338 13339 assert((CurContext->isDependentContext() || B.builtAll()) && 13340 "omp for loop exprs were not built"); 13341 13342 if (!CurContext->isDependentContext()) { 13343 // Finalize the clauses that need pre-built expressions for CodeGen. 13344 for (OMPClause *C : Clauses) { 13345 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13346 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13347 B.NumIterations, *this, CurScope, 13348 DSAStack)) 13349 return StmtError(); 13350 } 13351 } 13352 13353 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13354 // The grainsize clause and num_tasks clause are mutually exclusive and may 13355 // not appear on the same taskloop directive. 13356 if (checkMutuallyExclusiveClauses(*this, Clauses, 13357 {OMPC_grainsize, OMPC_num_tasks})) 13358 return StmtError(); 13359 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 13360 // If a reduction clause is present on the taskloop directive, the nogroup 13361 // clause must not be specified. 13362 if (checkReductionClauseWithNogroup(*this, Clauses)) 13363 return StmtError(); 13364 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13365 return StmtError(); 13366 13367 setFunctionHasBranchProtectedScope(); 13368 return OMPParallelMasterTaskLoopSimdDirective::Create( 13369 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13370 } 13371 13372 StmtResult Sema::ActOnOpenMPDistributeDirective( 13373 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13374 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13375 if (!AStmt) 13376 return StmtError(); 13377 13378 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 13379 OMPLoopBasedDirective::HelperExprs B; 13380 // In presence of clause 'collapse' with number of loops, it will 13381 // define the nested loops number. 13382 unsigned NestedLoopCount = 13383 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 13384 nullptr /*ordered not a clause on distribute*/, AStmt, 13385 *this, *DSAStack, VarsWithImplicitDSA, B); 13386 if (NestedLoopCount == 0) 13387 return StmtError(); 13388 13389 assert((CurContext->isDependentContext() || B.builtAll()) && 13390 "omp for loop exprs were not built"); 13391 13392 setFunctionHasBranchProtectedScope(); 13393 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 13394 NestedLoopCount, Clauses, AStmt, B); 13395 } 13396 13397 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 13398 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13399 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13400 if (!AStmt) 13401 return StmtError(); 13402 13403 auto *CS = cast<CapturedStmt>(AStmt); 13404 // 1.2.2 OpenMP Language Terminology 13405 // Structured block - An executable statement with a single entry at the 13406 // top and a single exit at the bottom. 13407 // The point of exit cannot be a branch out of the structured block. 13408 // longjmp() and throw() must not violate the entry/exit criteria. 13409 CS->getCapturedDecl()->setNothrow(); 13410 for (int ThisCaptureLevel = 13411 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 13412 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13413 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13414 // 1.2.2 OpenMP Language Terminology 13415 // Structured block - An executable statement with a single entry at the 13416 // top and a single exit at the bottom. 13417 // The point of exit cannot be a branch out of the structured block. 13418 // longjmp() and throw() must not violate the entry/exit criteria. 13419 CS->getCapturedDecl()->setNothrow(); 13420 } 13421 13422 OMPLoopBasedDirective::HelperExprs B; 13423 // In presence of clause 'collapse' with number of loops, it will 13424 // define the nested loops number. 13425 unsigned NestedLoopCount = checkOpenMPLoop( 13426 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 13427 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13428 VarsWithImplicitDSA, B); 13429 if (NestedLoopCount == 0) 13430 return StmtError(); 13431 13432 assert((CurContext->isDependentContext() || B.builtAll()) && 13433 "omp for loop exprs were not built"); 13434 13435 setFunctionHasBranchProtectedScope(); 13436 return OMPDistributeParallelForDirective::Create( 13437 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13438 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13439 } 13440 13441 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 13442 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13443 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13444 if (!AStmt) 13445 return StmtError(); 13446 13447 auto *CS = cast<CapturedStmt>(AStmt); 13448 // 1.2.2 OpenMP Language Terminology 13449 // Structured block - An executable statement with a single entry at the 13450 // top and a single exit at the bottom. 13451 // The point of exit cannot be a branch out of the structured block. 13452 // longjmp() and throw() must not violate the entry/exit criteria. 13453 CS->getCapturedDecl()->setNothrow(); 13454 for (int ThisCaptureLevel = 13455 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 13456 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13457 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13458 // 1.2.2 OpenMP Language Terminology 13459 // Structured block - An executable statement with a single entry at the 13460 // top and a single exit at the bottom. 13461 // The point of exit cannot be a branch out of the structured block. 13462 // longjmp() and throw() must not violate the entry/exit criteria. 13463 CS->getCapturedDecl()->setNothrow(); 13464 } 13465 13466 OMPLoopBasedDirective::HelperExprs B; 13467 // In presence of clause 'collapse' with number of loops, it will 13468 // define the nested loops number. 13469 unsigned NestedLoopCount = checkOpenMPLoop( 13470 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 13471 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13472 VarsWithImplicitDSA, B); 13473 if (NestedLoopCount == 0) 13474 return StmtError(); 13475 13476 assert((CurContext->isDependentContext() || B.builtAll()) && 13477 "omp for loop exprs were not built"); 13478 13479 if (!CurContext->isDependentContext()) { 13480 // Finalize the clauses that need pre-built expressions for CodeGen. 13481 for (OMPClause *C : Clauses) { 13482 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13483 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13484 B.NumIterations, *this, CurScope, 13485 DSAStack)) 13486 return StmtError(); 13487 } 13488 } 13489 13490 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13491 return StmtError(); 13492 13493 setFunctionHasBranchProtectedScope(); 13494 return OMPDistributeParallelForSimdDirective::Create( 13495 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13496 } 13497 13498 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 13499 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13500 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13501 if (!AStmt) 13502 return StmtError(); 13503 13504 auto *CS = cast<CapturedStmt>(AStmt); 13505 // 1.2.2 OpenMP Language Terminology 13506 // Structured block - An executable statement with a single entry at the 13507 // top and a single exit at the bottom. 13508 // The point of exit cannot be a branch out of the structured block. 13509 // longjmp() and throw() must not violate the entry/exit criteria. 13510 CS->getCapturedDecl()->setNothrow(); 13511 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 13512 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13513 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13514 // 1.2.2 OpenMP Language Terminology 13515 // Structured block - An executable statement with a single entry at the 13516 // top and a single exit at the bottom. 13517 // The point of exit cannot be a branch out of the structured block. 13518 // longjmp() and throw() must not violate the entry/exit criteria. 13519 CS->getCapturedDecl()->setNothrow(); 13520 } 13521 13522 OMPLoopBasedDirective::HelperExprs B; 13523 // In presence of clause 'collapse' with number of loops, it will 13524 // define the nested loops number. 13525 unsigned NestedLoopCount = 13526 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 13527 nullptr /*ordered not a clause on distribute*/, CS, *this, 13528 *DSAStack, VarsWithImplicitDSA, B); 13529 if (NestedLoopCount == 0) 13530 return StmtError(); 13531 13532 assert((CurContext->isDependentContext() || B.builtAll()) && 13533 "omp for loop exprs were not built"); 13534 13535 if (!CurContext->isDependentContext()) { 13536 // Finalize the clauses that need pre-built expressions for CodeGen. 13537 for (OMPClause *C : Clauses) { 13538 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13539 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13540 B.NumIterations, *this, CurScope, 13541 DSAStack)) 13542 return StmtError(); 13543 } 13544 } 13545 13546 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13547 return StmtError(); 13548 13549 setFunctionHasBranchProtectedScope(); 13550 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 13551 NestedLoopCount, Clauses, AStmt, B); 13552 } 13553 13554 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 13555 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13556 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13557 if (!AStmt) 13558 return StmtError(); 13559 13560 auto *CS = cast<CapturedStmt>(AStmt); 13561 // 1.2.2 OpenMP Language Terminology 13562 // Structured block - An executable statement with a single entry at the 13563 // top and a single exit at the bottom. 13564 // The point of exit cannot be a branch out of the structured block. 13565 // longjmp() and throw() must not violate the entry/exit criteria. 13566 CS->getCapturedDecl()->setNothrow(); 13567 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 13568 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13569 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13570 // 1.2.2 OpenMP Language Terminology 13571 // Structured block - An executable statement with a single entry at the 13572 // top and a single exit at the bottom. 13573 // The point of exit cannot be a branch out of the structured block. 13574 // longjmp() and throw() must not violate the entry/exit criteria. 13575 CS->getCapturedDecl()->setNothrow(); 13576 } 13577 13578 OMPLoopBasedDirective::HelperExprs B; 13579 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 13580 // define the nested loops number. 13581 unsigned NestedLoopCount = checkOpenMPLoop( 13582 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 13583 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, VarsWithImplicitDSA, 13584 B); 13585 if (NestedLoopCount == 0) 13586 return StmtError(); 13587 13588 assert((CurContext->isDependentContext() || B.builtAll()) && 13589 "omp target parallel for simd loop exprs were not built"); 13590 13591 if (!CurContext->isDependentContext()) { 13592 // Finalize the clauses that need pre-built expressions for CodeGen. 13593 for (OMPClause *C : Clauses) { 13594 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13595 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13596 B.NumIterations, *this, CurScope, 13597 DSAStack)) 13598 return StmtError(); 13599 } 13600 } 13601 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13602 return StmtError(); 13603 13604 setFunctionHasBranchProtectedScope(); 13605 return OMPTargetParallelForSimdDirective::Create( 13606 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13607 } 13608 13609 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 13610 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13611 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13612 if (!AStmt) 13613 return StmtError(); 13614 13615 auto *CS = cast<CapturedStmt>(AStmt); 13616 // 1.2.2 OpenMP Language Terminology 13617 // Structured block - An executable statement with a single entry at the 13618 // top and a single exit at the bottom. 13619 // The point of exit cannot be a branch out of the structured block. 13620 // longjmp() and throw() must not violate the entry/exit criteria. 13621 CS->getCapturedDecl()->setNothrow(); 13622 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 13623 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13624 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13625 // 1.2.2 OpenMP Language Terminology 13626 // Structured block - An executable statement with a single entry at the 13627 // top and a single exit at the bottom. 13628 // The point of exit cannot be a branch out of the structured block. 13629 // longjmp() and throw() must not violate the entry/exit criteria. 13630 CS->getCapturedDecl()->setNothrow(); 13631 } 13632 13633 OMPLoopBasedDirective::HelperExprs B; 13634 // In presence of clause 'collapse' with number of loops, it will define the 13635 // nested loops number. 13636 unsigned NestedLoopCount = 13637 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 13638 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 13639 VarsWithImplicitDSA, B); 13640 if (NestedLoopCount == 0) 13641 return StmtError(); 13642 13643 assert((CurContext->isDependentContext() || B.builtAll()) && 13644 "omp target simd loop exprs were not built"); 13645 13646 if (!CurContext->isDependentContext()) { 13647 // Finalize the clauses that need pre-built expressions for CodeGen. 13648 for (OMPClause *C : Clauses) { 13649 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13650 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13651 B.NumIterations, *this, CurScope, 13652 DSAStack)) 13653 return StmtError(); 13654 } 13655 } 13656 13657 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13658 return StmtError(); 13659 13660 setFunctionHasBranchProtectedScope(); 13661 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 13662 NestedLoopCount, Clauses, AStmt, B); 13663 } 13664 13665 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 13666 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13667 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13668 if (!AStmt) 13669 return StmtError(); 13670 13671 auto *CS = cast<CapturedStmt>(AStmt); 13672 // 1.2.2 OpenMP Language Terminology 13673 // Structured block - An executable statement with a single entry at the 13674 // top and a single exit at the bottom. 13675 // The point of exit cannot be a branch out of the structured block. 13676 // longjmp() and throw() must not violate the entry/exit criteria. 13677 CS->getCapturedDecl()->setNothrow(); 13678 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 13679 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13680 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13681 // 1.2.2 OpenMP Language Terminology 13682 // Structured block - An executable statement with a single entry at the 13683 // top and a single exit at the bottom. 13684 // The point of exit cannot be a branch out of the structured block. 13685 // longjmp() and throw() must not violate the entry/exit criteria. 13686 CS->getCapturedDecl()->setNothrow(); 13687 } 13688 13689 OMPLoopBasedDirective::HelperExprs B; 13690 // In presence of clause 'collapse' with number of loops, it will 13691 // define the nested loops number. 13692 unsigned NestedLoopCount = 13693 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 13694 nullptr /*ordered not a clause on distribute*/, CS, *this, 13695 *DSAStack, VarsWithImplicitDSA, B); 13696 if (NestedLoopCount == 0) 13697 return StmtError(); 13698 13699 assert((CurContext->isDependentContext() || B.builtAll()) && 13700 "omp teams distribute loop exprs were not built"); 13701 13702 setFunctionHasBranchProtectedScope(); 13703 13704 DSAStack->setParentTeamsRegionLoc(StartLoc); 13705 13706 return OMPTeamsDistributeDirective::Create( 13707 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13708 } 13709 13710 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 13711 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13712 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13713 if (!AStmt) 13714 return StmtError(); 13715 13716 auto *CS = cast<CapturedStmt>(AStmt); 13717 // 1.2.2 OpenMP Language Terminology 13718 // Structured block - An executable statement with a single entry at the 13719 // top and a single exit at the bottom. 13720 // The point of exit cannot be a branch out of the structured block. 13721 // longjmp() and throw() must not violate the entry/exit criteria. 13722 CS->getCapturedDecl()->setNothrow(); 13723 for (int ThisCaptureLevel = 13724 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 13725 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13726 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13727 // 1.2.2 OpenMP Language Terminology 13728 // Structured block - An executable statement with a single entry at the 13729 // top and a single exit at the bottom. 13730 // The point of exit cannot be a branch out of the structured block. 13731 // longjmp() and throw() must not violate the entry/exit criteria. 13732 CS->getCapturedDecl()->setNothrow(); 13733 } 13734 13735 OMPLoopBasedDirective::HelperExprs B; 13736 // In presence of clause 'collapse' with number of loops, it will 13737 // define the nested loops number. 13738 unsigned NestedLoopCount = checkOpenMPLoop( 13739 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 13740 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13741 VarsWithImplicitDSA, B); 13742 13743 if (NestedLoopCount == 0) 13744 return StmtError(); 13745 13746 assert((CurContext->isDependentContext() || B.builtAll()) && 13747 "omp teams distribute simd loop exprs were not built"); 13748 13749 if (!CurContext->isDependentContext()) { 13750 // Finalize the clauses that need pre-built expressions for CodeGen. 13751 for (OMPClause *C : Clauses) { 13752 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13753 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13754 B.NumIterations, *this, CurScope, 13755 DSAStack)) 13756 return StmtError(); 13757 } 13758 } 13759 13760 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13761 return StmtError(); 13762 13763 setFunctionHasBranchProtectedScope(); 13764 13765 DSAStack->setParentTeamsRegionLoc(StartLoc); 13766 13767 return OMPTeamsDistributeSimdDirective::Create( 13768 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13769 } 13770 13771 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 13772 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13773 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13774 if (!AStmt) 13775 return StmtError(); 13776 13777 auto *CS = cast<CapturedStmt>(AStmt); 13778 // 1.2.2 OpenMP Language Terminology 13779 // Structured block - An executable statement with a single entry at the 13780 // top and a single exit at the bottom. 13781 // The point of exit cannot be a branch out of the structured block. 13782 // longjmp() and throw() must not violate the entry/exit criteria. 13783 CS->getCapturedDecl()->setNothrow(); 13784 13785 for (int ThisCaptureLevel = 13786 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 13787 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13788 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13789 // 1.2.2 OpenMP Language Terminology 13790 // Structured block - An executable statement with a single entry at the 13791 // top and a single exit at the bottom. 13792 // The point of exit cannot be a branch out of the structured block. 13793 // longjmp() and throw() must not violate the entry/exit criteria. 13794 CS->getCapturedDecl()->setNothrow(); 13795 } 13796 13797 OMPLoopBasedDirective::HelperExprs B; 13798 // In presence of clause 'collapse' with number of loops, it will 13799 // define the nested loops number. 13800 unsigned NestedLoopCount = checkOpenMPLoop( 13801 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 13802 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13803 VarsWithImplicitDSA, B); 13804 13805 if (NestedLoopCount == 0) 13806 return StmtError(); 13807 13808 assert((CurContext->isDependentContext() || B.builtAll()) && 13809 "omp for loop exprs were not built"); 13810 13811 if (!CurContext->isDependentContext()) { 13812 // Finalize the clauses that need pre-built expressions for CodeGen. 13813 for (OMPClause *C : Clauses) { 13814 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13815 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13816 B.NumIterations, *this, CurScope, 13817 DSAStack)) 13818 return StmtError(); 13819 } 13820 } 13821 13822 if (checkSimdlenSafelenSpecified(*this, Clauses)) 13823 return StmtError(); 13824 13825 setFunctionHasBranchProtectedScope(); 13826 13827 DSAStack->setParentTeamsRegionLoc(StartLoc); 13828 13829 return OMPTeamsDistributeParallelForSimdDirective::Create( 13830 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13831 } 13832 13833 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 13834 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13835 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13836 if (!AStmt) 13837 return StmtError(); 13838 13839 auto *CS = cast<CapturedStmt>(AStmt); 13840 // 1.2.2 OpenMP Language Terminology 13841 // Structured block - An executable statement with a single entry at the 13842 // top and a single exit at the bottom. 13843 // The point of exit cannot be a branch out of the structured block. 13844 // longjmp() and throw() must not violate the entry/exit criteria. 13845 CS->getCapturedDecl()->setNothrow(); 13846 13847 for (int ThisCaptureLevel = 13848 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 13849 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13850 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13851 // 1.2.2 OpenMP Language Terminology 13852 // Structured block - An executable statement with a single entry at the 13853 // top and a single exit at the bottom. 13854 // The point of exit cannot be a branch out of the structured block. 13855 // longjmp() and throw() must not violate the entry/exit criteria. 13856 CS->getCapturedDecl()->setNothrow(); 13857 } 13858 13859 OMPLoopBasedDirective::HelperExprs B; 13860 // In presence of clause 'collapse' with number of loops, it will 13861 // define the nested loops number. 13862 unsigned NestedLoopCount = checkOpenMPLoop( 13863 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 13864 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13865 VarsWithImplicitDSA, B); 13866 13867 if (NestedLoopCount == 0) 13868 return StmtError(); 13869 13870 assert((CurContext->isDependentContext() || B.builtAll()) && 13871 "omp for loop exprs were not built"); 13872 13873 setFunctionHasBranchProtectedScope(); 13874 13875 DSAStack->setParentTeamsRegionLoc(StartLoc); 13876 13877 return OMPTeamsDistributeParallelForDirective::Create( 13878 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 13879 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 13880 } 13881 13882 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 13883 Stmt *AStmt, 13884 SourceLocation StartLoc, 13885 SourceLocation EndLoc) { 13886 if (!AStmt) 13887 return StmtError(); 13888 13889 auto *CS = cast<CapturedStmt>(AStmt); 13890 // 1.2.2 OpenMP Language Terminology 13891 // Structured block - An executable statement with a single entry at the 13892 // top and a single exit at the bottom. 13893 // The point of exit cannot be a branch out of the structured block. 13894 // longjmp() and throw() must not violate the entry/exit criteria. 13895 CS->getCapturedDecl()->setNothrow(); 13896 13897 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 13898 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13899 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13900 // 1.2.2 OpenMP Language Terminology 13901 // Structured block - An executable statement with a single entry at the 13902 // top and a single exit at the bottom. 13903 // The point of exit cannot be a branch out of the structured block. 13904 // longjmp() and throw() must not violate the entry/exit criteria. 13905 CS->getCapturedDecl()->setNothrow(); 13906 } 13907 setFunctionHasBranchProtectedScope(); 13908 13909 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 13910 AStmt); 13911 } 13912 13913 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 13914 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13915 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13916 if (!AStmt) 13917 return StmtError(); 13918 13919 auto *CS = cast<CapturedStmt>(AStmt); 13920 // 1.2.2 OpenMP Language Terminology 13921 // Structured block - An executable statement with a single entry at the 13922 // top and a single exit at the bottom. 13923 // The point of exit cannot be a branch out of the structured block. 13924 // longjmp() and throw() must not violate the entry/exit criteria. 13925 CS->getCapturedDecl()->setNothrow(); 13926 for (int ThisCaptureLevel = 13927 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 13928 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13929 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13930 // 1.2.2 OpenMP Language Terminology 13931 // Structured block - An executable statement with a single entry at the 13932 // top and a single exit at the bottom. 13933 // The point of exit cannot be a branch out of the structured block. 13934 // longjmp() and throw() must not violate the entry/exit criteria. 13935 CS->getCapturedDecl()->setNothrow(); 13936 } 13937 13938 OMPLoopBasedDirective::HelperExprs B; 13939 // In presence of clause 'collapse' with number of loops, it will 13940 // define the nested loops number. 13941 unsigned NestedLoopCount = checkOpenMPLoop( 13942 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 13943 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13944 VarsWithImplicitDSA, B); 13945 if (NestedLoopCount == 0) 13946 return StmtError(); 13947 13948 assert((CurContext->isDependentContext() || B.builtAll()) && 13949 "omp target teams distribute loop exprs were not built"); 13950 13951 setFunctionHasBranchProtectedScope(); 13952 return OMPTargetTeamsDistributeDirective::Create( 13953 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 13954 } 13955 13956 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 13957 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 13958 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 13959 if (!AStmt) 13960 return StmtError(); 13961 13962 auto *CS = cast<CapturedStmt>(AStmt); 13963 // 1.2.2 OpenMP Language Terminology 13964 // Structured block - An executable statement with a single entry at the 13965 // top and a single exit at the bottom. 13966 // The point of exit cannot be a branch out of the structured block. 13967 // longjmp() and throw() must not violate the entry/exit criteria. 13968 CS->getCapturedDecl()->setNothrow(); 13969 for (int ThisCaptureLevel = 13970 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 13971 ThisCaptureLevel > 1; --ThisCaptureLevel) { 13972 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 13973 // 1.2.2 OpenMP Language Terminology 13974 // Structured block - An executable statement with a single entry at the 13975 // top and a single exit at the bottom. 13976 // The point of exit cannot be a branch out of the structured block. 13977 // longjmp() and throw() must not violate the entry/exit criteria. 13978 CS->getCapturedDecl()->setNothrow(); 13979 } 13980 13981 OMPLoopBasedDirective::HelperExprs B; 13982 // In presence of clause 'collapse' with number of loops, it will 13983 // define the nested loops number. 13984 unsigned NestedLoopCount = checkOpenMPLoop( 13985 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 13986 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 13987 VarsWithImplicitDSA, B); 13988 if (NestedLoopCount == 0) 13989 return StmtError(); 13990 13991 assert((CurContext->isDependentContext() || B.builtAll()) && 13992 "omp target teams distribute parallel for loop exprs were not built"); 13993 13994 if (!CurContext->isDependentContext()) { 13995 // Finalize the clauses that need pre-built expressions for CodeGen. 13996 for (OMPClause *C : Clauses) { 13997 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 13998 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 13999 B.NumIterations, *this, CurScope, 14000 DSAStack)) 14001 return StmtError(); 14002 } 14003 } 14004 14005 setFunctionHasBranchProtectedScope(); 14006 return OMPTargetTeamsDistributeParallelForDirective::Create( 14007 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 14008 DSAStack->getTaskgroupReductionRef(), DSAStack->isCancelRegion()); 14009 } 14010 14011 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 14012 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14013 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14014 if (!AStmt) 14015 return StmtError(); 14016 14017 auto *CS = cast<CapturedStmt>(AStmt); 14018 // 1.2.2 OpenMP Language Terminology 14019 // Structured block - An executable statement with a single entry at the 14020 // top and a single exit at the bottom. 14021 // The point of exit cannot be a branch out of the structured block. 14022 // longjmp() and throw() must not violate the entry/exit criteria. 14023 CS->getCapturedDecl()->setNothrow(); 14024 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 14025 OMPD_target_teams_distribute_parallel_for_simd); 14026 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14027 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14028 // 1.2.2 OpenMP Language Terminology 14029 // Structured block - An executable statement with a single entry at the 14030 // top and a single exit at the bottom. 14031 // The point of exit cannot be a branch out of the structured block. 14032 // longjmp() and throw() must not violate the entry/exit criteria. 14033 CS->getCapturedDecl()->setNothrow(); 14034 } 14035 14036 OMPLoopBasedDirective::HelperExprs B; 14037 // In presence of clause 'collapse' with number of loops, it will 14038 // define the nested loops number. 14039 unsigned NestedLoopCount = 14040 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 14041 getCollapseNumberExpr(Clauses), 14042 nullptr /*ordered not a clause on distribute*/, CS, *this, 14043 *DSAStack, VarsWithImplicitDSA, B); 14044 if (NestedLoopCount == 0) 14045 return StmtError(); 14046 14047 assert((CurContext->isDependentContext() || B.builtAll()) && 14048 "omp target teams distribute parallel for simd loop exprs were not " 14049 "built"); 14050 14051 if (!CurContext->isDependentContext()) { 14052 // Finalize the clauses that need pre-built expressions for CodeGen. 14053 for (OMPClause *C : Clauses) { 14054 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14055 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14056 B.NumIterations, *this, CurScope, 14057 DSAStack)) 14058 return StmtError(); 14059 } 14060 } 14061 14062 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14063 return StmtError(); 14064 14065 setFunctionHasBranchProtectedScope(); 14066 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 14067 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14068 } 14069 14070 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 14071 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 14072 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 14073 if (!AStmt) 14074 return StmtError(); 14075 14076 auto *CS = cast<CapturedStmt>(AStmt); 14077 // 1.2.2 OpenMP Language Terminology 14078 // Structured block - An executable statement with a single entry at the 14079 // top and a single exit at the bottom. 14080 // The point of exit cannot be a branch out of the structured block. 14081 // longjmp() and throw() must not violate the entry/exit criteria. 14082 CS->getCapturedDecl()->setNothrow(); 14083 for (int ThisCaptureLevel = 14084 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 14085 ThisCaptureLevel > 1; --ThisCaptureLevel) { 14086 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 14087 // 1.2.2 OpenMP Language Terminology 14088 // Structured block - An executable statement with a single entry at the 14089 // top and a single exit at the bottom. 14090 // The point of exit cannot be a branch out of the structured block. 14091 // longjmp() and throw() must not violate the entry/exit criteria. 14092 CS->getCapturedDecl()->setNothrow(); 14093 } 14094 14095 OMPLoopBasedDirective::HelperExprs B; 14096 // In presence of clause 'collapse' with number of loops, it will 14097 // define the nested loops number. 14098 unsigned NestedLoopCount = checkOpenMPLoop( 14099 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 14100 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 14101 VarsWithImplicitDSA, B); 14102 if (NestedLoopCount == 0) 14103 return StmtError(); 14104 14105 assert((CurContext->isDependentContext() || B.builtAll()) && 14106 "omp target teams distribute simd loop exprs were not built"); 14107 14108 if (!CurContext->isDependentContext()) { 14109 // Finalize the clauses that need pre-built expressions for CodeGen. 14110 for (OMPClause *C : Clauses) { 14111 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 14112 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 14113 B.NumIterations, *this, CurScope, 14114 DSAStack)) 14115 return StmtError(); 14116 } 14117 } 14118 14119 if (checkSimdlenSafelenSpecified(*this, Clauses)) 14120 return StmtError(); 14121 14122 setFunctionHasBranchProtectedScope(); 14123 return OMPTargetTeamsDistributeSimdDirective::Create( 14124 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 14125 } 14126 14127 bool Sema::checkTransformableLoopNest( 14128 OpenMPDirectiveKind Kind, Stmt *AStmt, int NumLoops, 14129 SmallVectorImpl<OMPLoopBasedDirective::HelperExprs> &LoopHelpers, 14130 Stmt *&Body, 14131 SmallVectorImpl<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>> 14132 &OriginalInits) { 14133 OriginalInits.emplace_back(); 14134 bool Result = OMPLoopBasedDirective::doForAllLoops( 14135 AStmt->IgnoreContainers(), /*TryImperfectlyNestedLoops=*/false, NumLoops, 14136 [this, &LoopHelpers, &Body, &OriginalInits, Kind](unsigned Cnt, 14137 Stmt *CurStmt) { 14138 VarsWithInheritedDSAType TmpDSA; 14139 unsigned SingleNumLoops = 14140 checkOpenMPLoop(Kind, nullptr, nullptr, CurStmt, *this, *DSAStack, 14141 TmpDSA, LoopHelpers[Cnt]); 14142 if (SingleNumLoops == 0) 14143 return true; 14144 assert(SingleNumLoops == 1 && "Expect single loop iteration space"); 14145 if (auto *For = dyn_cast<ForStmt>(CurStmt)) { 14146 OriginalInits.back().push_back(For->getInit()); 14147 Body = For->getBody(); 14148 } else { 14149 assert(isa<CXXForRangeStmt>(CurStmt) && 14150 "Expected canonical for or range-based for loops."); 14151 auto *CXXFor = cast<CXXForRangeStmt>(CurStmt); 14152 OriginalInits.back().push_back(CXXFor->getBeginStmt()); 14153 Body = CXXFor->getBody(); 14154 } 14155 OriginalInits.emplace_back(); 14156 return false; 14157 }, 14158 [&OriginalInits](OMPLoopBasedDirective *Transform) { 14159 Stmt *DependentPreInits; 14160 if (auto *Dir = dyn_cast<OMPTileDirective>(Transform)) 14161 DependentPreInits = Dir->getPreInits(); 14162 else if (auto *Dir = dyn_cast<OMPUnrollDirective>(Transform)) 14163 DependentPreInits = Dir->getPreInits(); 14164 else 14165 llvm_unreachable("Unhandled loop transformation"); 14166 if (!DependentPreInits) 14167 return; 14168 llvm::append_range(OriginalInits.back(), 14169 cast<DeclStmt>(DependentPreInits)->getDeclGroup()); 14170 }); 14171 assert(OriginalInits.back().empty() && "No preinit after innermost loop"); 14172 OriginalInits.pop_back(); 14173 return Result; 14174 } 14175 14176 StmtResult Sema::ActOnOpenMPTileDirective(ArrayRef<OMPClause *> Clauses, 14177 Stmt *AStmt, SourceLocation StartLoc, 14178 SourceLocation EndLoc) { 14179 auto SizesClauses = 14180 OMPExecutableDirective::getClausesOfKind<OMPSizesClause>(Clauses); 14181 if (SizesClauses.empty()) { 14182 // A missing 'sizes' clause is already reported by the parser. 14183 return StmtError(); 14184 } 14185 const OMPSizesClause *SizesClause = *SizesClauses.begin(); 14186 unsigned NumLoops = SizesClause->getNumSizes(); 14187 14188 // Empty statement should only be possible if there already was an error. 14189 if (!AStmt) 14190 return StmtError(); 14191 14192 // Verify and diagnose loop nest. 14193 SmallVector<OMPLoopBasedDirective::HelperExprs, 4> LoopHelpers(NumLoops); 14194 Stmt *Body = nullptr; 14195 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, 4> 14196 OriginalInits; 14197 if (!checkTransformableLoopNest(OMPD_tile, AStmt, NumLoops, LoopHelpers, Body, 14198 OriginalInits)) 14199 return StmtError(); 14200 14201 // Delay tiling to when template is completely instantiated. 14202 if (CurContext->isDependentContext()) 14203 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, 14204 NumLoops, AStmt, nullptr, nullptr); 14205 14206 SmallVector<Decl *, 4> PreInits; 14207 14208 // Create iteration variables for the generated loops. 14209 SmallVector<VarDecl *, 4> FloorIndVars; 14210 SmallVector<VarDecl *, 4> TileIndVars; 14211 FloorIndVars.resize(NumLoops); 14212 TileIndVars.resize(NumLoops); 14213 for (unsigned I = 0; I < NumLoops; ++I) { 14214 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 14215 14216 assert(LoopHelper.Counters.size() == 1 && 14217 "Expect single-dimensional loop iteration space"); 14218 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); 14219 std::string OrigVarName = OrigCntVar->getNameInfo().getAsString(); 14220 DeclRefExpr *IterVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef); 14221 QualType CntTy = IterVarRef->getType(); 14222 14223 // Iteration variable for the floor (i.e. outer) loop. 14224 { 14225 std::string FloorCntName = 14226 (Twine(".floor_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 14227 VarDecl *FloorCntDecl = 14228 buildVarDecl(*this, {}, CntTy, FloorCntName, nullptr, OrigCntVar); 14229 FloorIndVars[I] = FloorCntDecl; 14230 } 14231 14232 // Iteration variable for the tile (i.e. inner) loop. 14233 { 14234 std::string TileCntName = 14235 (Twine(".tile_") + llvm::utostr(I) + ".iv." + OrigVarName).str(); 14236 14237 // Reuse the iteration variable created by checkOpenMPLoop. It is also 14238 // used by the expressions to derive the original iteration variable's 14239 // value from the logical iteration number. 14240 auto *TileCntDecl = cast<VarDecl>(IterVarRef->getDecl()); 14241 TileCntDecl->setDeclName(&PP.getIdentifierTable().get(TileCntName)); 14242 TileIndVars[I] = TileCntDecl; 14243 } 14244 for (auto &P : OriginalInits[I]) { 14245 if (auto *D = P.dyn_cast<Decl *>()) 14246 PreInits.push_back(D); 14247 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>())) 14248 PreInits.append(PI->decl_begin(), PI->decl_end()); 14249 } 14250 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) 14251 PreInits.append(PI->decl_begin(), PI->decl_end()); 14252 // Gather declarations for the data members used as counters. 14253 for (Expr *CounterRef : LoopHelper.Counters) { 14254 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl(); 14255 if (isa<OMPCapturedExprDecl>(CounterDecl)) 14256 PreInits.push_back(CounterDecl); 14257 } 14258 } 14259 14260 // Once the original iteration values are set, append the innermost body. 14261 Stmt *Inner = Body; 14262 14263 // Create tile loops from the inside to the outside. 14264 for (int I = NumLoops - 1; I >= 0; --I) { 14265 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers[I]; 14266 Expr *NumIterations = LoopHelper.NumIterations; 14267 auto *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 14268 QualType CntTy = OrigCntVar->getType(); 14269 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 14270 Scope *CurScope = getCurScope(); 14271 14272 // Commonly used variables. 14273 DeclRefExpr *TileIV = buildDeclRefExpr(*this, TileIndVars[I], CntTy, 14274 OrigCntVar->getExprLoc()); 14275 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 14276 OrigCntVar->getExprLoc()); 14277 14278 // For init-statement: auto .tile.iv = .floor.iv 14279 AddInitializerToDecl(TileIndVars[I], DefaultLvalueConversion(FloorIV).get(), 14280 /*DirectInit=*/false); 14281 Decl *CounterDecl = TileIndVars[I]; 14282 StmtResult InitStmt = new (Context) 14283 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 14284 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 14285 if (!InitStmt.isUsable()) 14286 return StmtError(); 14287 14288 // For cond-expression: .tile.iv < min(.floor.iv + DimTileSize, 14289 // NumIterations) 14290 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14291 BO_Add, FloorIV, DimTileSize); 14292 if (!EndOfTile.isUsable()) 14293 return StmtError(); 14294 ExprResult IsPartialTile = 14295 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, 14296 NumIterations, EndOfTile.get()); 14297 if (!IsPartialTile.isUsable()) 14298 return StmtError(); 14299 ExprResult MinTileAndIterSpace = ActOnConditionalOp( 14300 LoopHelper.Cond->getBeginLoc(), LoopHelper.Cond->getEndLoc(), 14301 IsPartialTile.get(), NumIterations, EndOfTile.get()); 14302 if (!MinTileAndIterSpace.isUsable()) 14303 return StmtError(); 14304 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14305 BO_LT, TileIV, MinTileAndIterSpace.get()); 14306 if (!CondExpr.isUsable()) 14307 return StmtError(); 14308 14309 // For incr-statement: ++.tile.iv 14310 ExprResult IncrStmt = 14311 BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), UO_PreInc, TileIV); 14312 if (!IncrStmt.isUsable()) 14313 return StmtError(); 14314 14315 // Statements to set the original iteration variable's value from the 14316 // logical iteration number. 14317 // Generated for loop is: 14318 // Original_for_init; 14319 // for (auto .tile.iv = .floor.iv; .tile.iv < min(.floor.iv + DimTileSize, 14320 // NumIterations); ++.tile.iv) { 14321 // Original_Body; 14322 // Original_counter_update; 14323 // } 14324 // FIXME: If the innermost body is an loop itself, inserting these 14325 // statements stops it being recognized as a perfectly nested loop (e.g. 14326 // for applying tiling again). If this is the case, sink the expressions 14327 // further into the inner loop. 14328 SmallVector<Stmt *, 4> BodyParts; 14329 BodyParts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); 14330 BodyParts.push_back(Inner); 14331 Inner = CompoundStmt::Create(Context, BodyParts, Inner->getBeginLoc(), 14332 Inner->getEndLoc()); 14333 Inner = new (Context) 14334 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 14335 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 14336 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14337 } 14338 14339 // Create floor loops from the inside to the outside. 14340 for (int I = NumLoops - 1; I >= 0; --I) { 14341 auto &LoopHelper = LoopHelpers[I]; 14342 Expr *NumIterations = LoopHelper.NumIterations; 14343 DeclRefExpr *OrigCntVar = cast<DeclRefExpr>(LoopHelper.Counters[0]); 14344 QualType CntTy = OrigCntVar->getType(); 14345 Expr *DimTileSize = SizesClause->getSizesRefs()[I]; 14346 Scope *CurScope = getCurScope(); 14347 14348 // Commonly used variables. 14349 DeclRefExpr *FloorIV = buildDeclRefExpr(*this, FloorIndVars[I], CntTy, 14350 OrigCntVar->getExprLoc()); 14351 14352 // For init-statement: auto .floor.iv = 0 14353 AddInitializerToDecl( 14354 FloorIndVars[I], 14355 ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(), 14356 /*DirectInit=*/false); 14357 Decl *CounterDecl = FloorIndVars[I]; 14358 StmtResult InitStmt = new (Context) 14359 DeclStmt(DeclGroupRef::Create(Context, &CounterDecl, 1), 14360 OrigCntVar->getBeginLoc(), OrigCntVar->getEndLoc()); 14361 if (!InitStmt.isUsable()) 14362 return StmtError(); 14363 14364 // For cond-expression: .floor.iv < NumIterations 14365 ExprResult CondExpr = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14366 BO_LT, FloorIV, NumIterations); 14367 if (!CondExpr.isUsable()) 14368 return StmtError(); 14369 14370 // For incr-statement: .floor.iv += DimTileSize 14371 ExprResult IncrStmt = BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), 14372 BO_AddAssign, FloorIV, DimTileSize); 14373 if (!IncrStmt.isUsable()) 14374 return StmtError(); 14375 14376 Inner = new (Context) 14377 ForStmt(Context, InitStmt.get(), CondExpr.get(), nullptr, 14378 IncrStmt.get(), Inner, LoopHelper.Init->getBeginLoc(), 14379 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14380 } 14381 14382 return OMPTileDirective::Create(Context, StartLoc, EndLoc, Clauses, NumLoops, 14383 AStmt, Inner, 14384 buildPreInits(Context, PreInits)); 14385 } 14386 14387 StmtResult Sema::ActOnOpenMPUnrollDirective(ArrayRef<OMPClause *> Clauses, 14388 Stmt *AStmt, 14389 SourceLocation StartLoc, 14390 SourceLocation EndLoc) { 14391 // Empty statement should only be possible if there already was an error. 14392 if (!AStmt) 14393 return StmtError(); 14394 14395 if (checkMutuallyExclusiveClauses(*this, Clauses, {OMPC_partial, OMPC_full})) 14396 return StmtError(); 14397 14398 const OMPFullClause *FullClause = 14399 OMPExecutableDirective::getSingleClause<OMPFullClause>(Clauses); 14400 const OMPPartialClause *PartialClause = 14401 OMPExecutableDirective::getSingleClause<OMPPartialClause>(Clauses); 14402 assert(!(FullClause && PartialClause) && 14403 "mutual exclusivity must have been checked before"); 14404 14405 constexpr unsigned NumLoops = 1; 14406 Stmt *Body = nullptr; 14407 SmallVector<OMPLoopBasedDirective::HelperExprs, NumLoops> LoopHelpers( 14408 NumLoops); 14409 SmallVector<SmallVector<llvm::PointerUnion<Stmt *, Decl *>, 0>, NumLoops + 1> 14410 OriginalInits; 14411 if (!checkTransformableLoopNest(OMPD_unroll, AStmt, NumLoops, LoopHelpers, 14412 Body, OriginalInits)) 14413 return StmtError(); 14414 14415 unsigned NumGeneratedLoops = PartialClause ? 1 : 0; 14416 14417 // Delay unrolling to when template is completely instantiated. 14418 if (CurContext->isDependentContext()) 14419 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14420 NumGeneratedLoops, nullptr, nullptr); 14421 14422 OMPLoopBasedDirective::HelperExprs &LoopHelper = LoopHelpers.front(); 14423 14424 if (FullClause) { 14425 if (!VerifyPositiveIntegerConstantInClause( 14426 LoopHelper.NumIterations, OMPC_full, /*StrictlyPositive=*/false, 14427 /*SuppressExprDiags=*/true) 14428 .isUsable()) { 14429 Diag(AStmt->getBeginLoc(), diag::err_omp_unroll_full_variable_trip_count); 14430 Diag(FullClause->getBeginLoc(), diag::note_omp_directive_here) 14431 << "#pragma omp unroll full"; 14432 return StmtError(); 14433 } 14434 } 14435 14436 // The generated loop may only be passed to other loop-associated directive 14437 // when a partial clause is specified. Without the requirement it is 14438 // sufficient to generate loop unroll metadata at code-generation. 14439 if (NumGeneratedLoops == 0) 14440 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14441 NumGeneratedLoops, nullptr, nullptr); 14442 14443 // Otherwise, we need to provide a de-sugared/transformed AST that can be 14444 // associated with another loop directive. 14445 // 14446 // The canonical loop analysis return by checkTransformableLoopNest assumes 14447 // the following structure to be the same loop without transformations or 14448 // directives applied: \code OriginalInits; LoopHelper.PreInits; 14449 // LoopHelper.Counters; 14450 // for (; IV < LoopHelper.NumIterations; ++IV) { 14451 // LoopHelper.Updates; 14452 // Body; 14453 // } 14454 // \endcode 14455 // where IV is a variable declared and initialized to 0 in LoopHelper.PreInits 14456 // and referenced by LoopHelper.IterationVarRef. 14457 // 14458 // The unrolling directive transforms this into the following loop: 14459 // \code 14460 // OriginalInits; \ 14461 // LoopHelper.PreInits; > NewPreInits 14462 // LoopHelper.Counters; / 14463 // for (auto UIV = 0; UIV < LoopHelper.NumIterations; UIV+=Factor) { 14464 // #pragma clang loop unroll_count(Factor) 14465 // for (IV = UIV; IV < UIV + Factor && UIV < LoopHelper.NumIterations; ++IV) 14466 // { 14467 // LoopHelper.Updates; 14468 // Body; 14469 // } 14470 // } 14471 // \endcode 14472 // where UIV is a new logical iteration counter. IV must be the same VarDecl 14473 // as the original LoopHelper.IterationVarRef because LoopHelper.Updates 14474 // references it. If the partially unrolled loop is associated with another 14475 // loop directive (like an OMPForDirective), it will use checkOpenMPLoop to 14476 // analyze this loop, i.e. the outer loop must fulfill the constraints of an 14477 // OpenMP canonical loop. The inner loop is not an associable canonical loop 14478 // and only exists to defer its unrolling to LLVM's LoopUnroll instead of 14479 // doing it in the frontend (by adding loop metadata). NewPreInits becomes a 14480 // property of the OMPLoopBasedDirective instead of statements in 14481 // CompoundStatement. This is to allow the loop to become a non-outermost loop 14482 // of a canonical loop nest where these PreInits are emitted before the 14483 // outermost directive. 14484 14485 // Determine the PreInit declarations. 14486 SmallVector<Decl *, 4> PreInits; 14487 assert(OriginalInits.size() == 1 && 14488 "Expecting a single-dimensional loop iteration space"); 14489 for (auto &P : OriginalInits[0]) { 14490 if (auto *D = P.dyn_cast<Decl *>()) 14491 PreInits.push_back(D); 14492 else if (auto *PI = dyn_cast_or_null<DeclStmt>(P.dyn_cast<Stmt *>())) 14493 PreInits.append(PI->decl_begin(), PI->decl_end()); 14494 } 14495 if (auto *PI = cast_or_null<DeclStmt>(LoopHelper.PreInits)) 14496 PreInits.append(PI->decl_begin(), PI->decl_end()); 14497 // Gather declarations for the data members used as counters. 14498 for (Expr *CounterRef : LoopHelper.Counters) { 14499 auto *CounterDecl = cast<DeclRefExpr>(CounterRef)->getDecl(); 14500 if (isa<OMPCapturedExprDecl>(CounterDecl)) 14501 PreInits.push_back(CounterDecl); 14502 } 14503 14504 auto *IterationVarRef = cast<DeclRefExpr>(LoopHelper.IterationVarRef); 14505 QualType IVTy = IterationVarRef->getType(); 14506 assert(LoopHelper.Counters.size() == 1 && 14507 "Expecting a single-dimensional loop iteration space"); 14508 auto *OrigVar = cast<DeclRefExpr>(LoopHelper.Counters.front()); 14509 14510 // Determine the unroll factor. 14511 uint64_t Factor; 14512 SourceLocation FactorLoc; 14513 if (Expr *FactorVal = PartialClause->getFactor()) { 14514 Factor = FactorVal->getIntegerConstantExpr(Context)->getZExtValue(); 14515 FactorLoc = FactorVal->getExprLoc(); 14516 } else { 14517 // TODO: Use a better profitability model. 14518 Factor = 2; 14519 } 14520 assert(Factor > 0 && "Expected positive unroll factor"); 14521 auto MakeFactorExpr = [this, Factor, IVTy, FactorLoc]() { 14522 return IntegerLiteral::Create( 14523 Context, llvm::APInt(Context.getIntWidth(IVTy), Factor), IVTy, 14524 FactorLoc); 14525 }; 14526 14527 // Iteration variable SourceLocations. 14528 SourceLocation OrigVarLoc = OrigVar->getExprLoc(); 14529 SourceLocation OrigVarLocBegin = OrigVar->getBeginLoc(); 14530 SourceLocation OrigVarLocEnd = OrigVar->getEndLoc(); 14531 14532 // Internal variable names. 14533 std::string OrigVarName = OrigVar->getNameInfo().getAsString(); 14534 std::string OuterIVName = (Twine(".unrolled.iv.") + OrigVarName).str(); 14535 std::string InnerIVName = (Twine(".unroll_inner.iv.") + OrigVarName).str(); 14536 std::string InnerTripCountName = 14537 (Twine(".unroll_inner.tripcount.") + OrigVarName).str(); 14538 14539 // Create the iteration variable for the unrolled loop. 14540 VarDecl *OuterIVDecl = 14541 buildVarDecl(*this, {}, IVTy, OuterIVName, nullptr, OrigVar); 14542 auto MakeOuterRef = [this, OuterIVDecl, IVTy, OrigVarLoc]() { 14543 return buildDeclRefExpr(*this, OuterIVDecl, IVTy, OrigVarLoc); 14544 }; 14545 14546 // Iteration variable for the inner loop: Reuse the iteration variable created 14547 // by checkOpenMPLoop. 14548 auto *InnerIVDecl = cast<VarDecl>(IterationVarRef->getDecl()); 14549 InnerIVDecl->setDeclName(&PP.getIdentifierTable().get(InnerIVName)); 14550 auto MakeInnerRef = [this, InnerIVDecl, IVTy, OrigVarLoc]() { 14551 return buildDeclRefExpr(*this, InnerIVDecl, IVTy, OrigVarLoc); 14552 }; 14553 14554 // Make a copy of the NumIterations expression for each use: By the AST 14555 // constraints, every expression object in a DeclContext must be unique. 14556 CaptureVars CopyTransformer(*this); 14557 auto MakeNumIterations = [&CopyTransformer, &LoopHelper]() -> Expr * { 14558 return AssertSuccess( 14559 CopyTransformer.TransformExpr(LoopHelper.NumIterations)); 14560 }; 14561 14562 // Inner For init-statement: auto .unroll_inner.iv = .unrolled.iv 14563 ExprResult LValueConv = DefaultLvalueConversion(MakeOuterRef()); 14564 AddInitializerToDecl(InnerIVDecl, LValueConv.get(), /*DirectInit=*/false); 14565 StmtResult InnerInit = new (Context) 14566 DeclStmt(DeclGroupRef(InnerIVDecl), OrigVarLocBegin, OrigVarLocEnd); 14567 if (!InnerInit.isUsable()) 14568 return StmtError(); 14569 14570 // Inner For cond-expression: 14571 // \code 14572 // .unroll_inner.iv < .unrolled.iv + Factor && 14573 // .unroll_inner.iv < NumIterations 14574 // \endcode 14575 // This conjunction of two conditions allows ScalarEvolution to derive the 14576 // maximum trip count of the inner loop. 14577 ExprResult EndOfTile = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14578 BO_Add, MakeOuterRef(), MakeFactorExpr()); 14579 if (!EndOfTile.isUsable()) 14580 return StmtError(); 14581 ExprResult InnerCond1 = BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), 14582 BO_LT, MakeInnerRef(), EndOfTile.get()); 14583 if (!InnerCond1.isUsable()) 14584 return StmtError(); 14585 ExprResult InnerCond2 = 14586 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeInnerRef(), 14587 MakeNumIterations()); 14588 if (!InnerCond2.isUsable()) 14589 return StmtError(); 14590 ExprResult InnerCond = 14591 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LAnd, 14592 InnerCond1.get(), InnerCond2.get()); 14593 if (!InnerCond.isUsable()) 14594 return StmtError(); 14595 14596 // Inner For incr-statement: ++.unroll_inner.iv 14597 ExprResult InnerIncr = BuildUnaryOp(CurScope, LoopHelper.Inc->getExprLoc(), 14598 UO_PreInc, MakeInnerRef()); 14599 if (!InnerIncr.isUsable()) 14600 return StmtError(); 14601 14602 // Inner For statement. 14603 SmallVector<Stmt *> InnerBodyStmts; 14604 InnerBodyStmts.append(LoopHelper.Updates.begin(), LoopHelper.Updates.end()); 14605 InnerBodyStmts.push_back(Body); 14606 CompoundStmt *InnerBody = CompoundStmt::Create( 14607 Context, InnerBodyStmts, Body->getBeginLoc(), Body->getEndLoc()); 14608 ForStmt *InnerFor = new (Context) 14609 ForStmt(Context, InnerInit.get(), InnerCond.get(), nullptr, 14610 InnerIncr.get(), InnerBody, LoopHelper.Init->getBeginLoc(), 14611 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14612 14613 // Unroll metadata for the inner loop. 14614 // This needs to take into account the remainder portion of the unrolled loop, 14615 // hence `unroll(full)` does not apply here, even though the LoopUnroll pass 14616 // supports multiple loop exits. Instead, unroll using a factor equivalent to 14617 // the maximum trip count, which will also generate a remainder loop. Just 14618 // `unroll(enable)` (which could have been useful if the user has not 14619 // specified a concrete factor; even though the outer loop cannot be 14620 // influenced anymore, would avoid more code bloat than necessary) will refuse 14621 // the loop because "Won't unroll; remainder loop could not be generated when 14622 // assuming runtime trip count". Even if it did work, it must not choose a 14623 // larger unroll factor than the maximum loop length, or it would always just 14624 // execute the remainder loop. 14625 LoopHintAttr *UnrollHintAttr = 14626 LoopHintAttr::CreateImplicit(Context, LoopHintAttr::UnrollCount, 14627 LoopHintAttr::Numeric, MakeFactorExpr()); 14628 AttributedStmt *InnerUnrolled = 14629 AttributedStmt::Create(Context, StartLoc, {UnrollHintAttr}, InnerFor); 14630 14631 // Outer For init-statement: auto .unrolled.iv = 0 14632 AddInitializerToDecl( 14633 OuterIVDecl, ActOnIntegerConstant(LoopHelper.Init->getExprLoc(), 0).get(), 14634 /*DirectInit=*/false); 14635 StmtResult OuterInit = new (Context) 14636 DeclStmt(DeclGroupRef(OuterIVDecl), OrigVarLocBegin, OrigVarLocEnd); 14637 if (!OuterInit.isUsable()) 14638 return StmtError(); 14639 14640 // Outer For cond-expression: .unrolled.iv < NumIterations 14641 ExprResult OuterConde = 14642 BuildBinOp(CurScope, LoopHelper.Cond->getExprLoc(), BO_LT, MakeOuterRef(), 14643 MakeNumIterations()); 14644 if (!OuterConde.isUsable()) 14645 return StmtError(); 14646 14647 // Outer For incr-statement: .unrolled.iv += Factor 14648 ExprResult OuterIncr = 14649 BuildBinOp(CurScope, LoopHelper.Inc->getExprLoc(), BO_AddAssign, 14650 MakeOuterRef(), MakeFactorExpr()); 14651 if (!OuterIncr.isUsable()) 14652 return StmtError(); 14653 14654 // Outer For statement. 14655 ForStmt *OuterFor = new (Context) 14656 ForStmt(Context, OuterInit.get(), OuterConde.get(), nullptr, 14657 OuterIncr.get(), InnerUnrolled, LoopHelper.Init->getBeginLoc(), 14658 LoopHelper.Init->getBeginLoc(), LoopHelper.Inc->getEndLoc()); 14659 14660 return OMPUnrollDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 14661 NumGeneratedLoops, OuterFor, 14662 buildPreInits(Context, PreInits)); 14663 } 14664 14665 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 14666 SourceLocation StartLoc, 14667 SourceLocation LParenLoc, 14668 SourceLocation EndLoc) { 14669 OMPClause *Res = nullptr; 14670 switch (Kind) { 14671 case OMPC_final: 14672 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 14673 break; 14674 case OMPC_num_threads: 14675 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 14676 break; 14677 case OMPC_safelen: 14678 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 14679 break; 14680 case OMPC_simdlen: 14681 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 14682 break; 14683 case OMPC_allocator: 14684 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 14685 break; 14686 case OMPC_collapse: 14687 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 14688 break; 14689 case OMPC_ordered: 14690 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 14691 break; 14692 case OMPC_num_teams: 14693 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 14694 break; 14695 case OMPC_thread_limit: 14696 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 14697 break; 14698 case OMPC_priority: 14699 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 14700 break; 14701 case OMPC_grainsize: 14702 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 14703 break; 14704 case OMPC_num_tasks: 14705 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 14706 break; 14707 case OMPC_hint: 14708 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 14709 break; 14710 case OMPC_depobj: 14711 Res = ActOnOpenMPDepobjClause(Expr, StartLoc, LParenLoc, EndLoc); 14712 break; 14713 case OMPC_detach: 14714 Res = ActOnOpenMPDetachClause(Expr, StartLoc, LParenLoc, EndLoc); 14715 break; 14716 case OMPC_novariants: 14717 Res = ActOnOpenMPNovariantsClause(Expr, StartLoc, LParenLoc, EndLoc); 14718 break; 14719 case OMPC_nocontext: 14720 Res = ActOnOpenMPNocontextClause(Expr, StartLoc, LParenLoc, EndLoc); 14721 break; 14722 case OMPC_filter: 14723 Res = ActOnOpenMPFilterClause(Expr, StartLoc, LParenLoc, EndLoc); 14724 break; 14725 case OMPC_partial: 14726 Res = ActOnOpenMPPartialClause(Expr, StartLoc, LParenLoc, EndLoc); 14727 break; 14728 case OMPC_align: 14729 Res = ActOnOpenMPAlignClause(Expr, StartLoc, LParenLoc, EndLoc); 14730 break; 14731 case OMPC_device: 14732 case OMPC_if: 14733 case OMPC_default: 14734 case OMPC_proc_bind: 14735 case OMPC_schedule: 14736 case OMPC_private: 14737 case OMPC_firstprivate: 14738 case OMPC_lastprivate: 14739 case OMPC_shared: 14740 case OMPC_reduction: 14741 case OMPC_task_reduction: 14742 case OMPC_in_reduction: 14743 case OMPC_linear: 14744 case OMPC_aligned: 14745 case OMPC_copyin: 14746 case OMPC_copyprivate: 14747 case OMPC_nowait: 14748 case OMPC_untied: 14749 case OMPC_mergeable: 14750 case OMPC_threadprivate: 14751 case OMPC_sizes: 14752 case OMPC_allocate: 14753 case OMPC_flush: 14754 case OMPC_read: 14755 case OMPC_write: 14756 case OMPC_update: 14757 case OMPC_capture: 14758 case OMPC_compare: 14759 case OMPC_seq_cst: 14760 case OMPC_acq_rel: 14761 case OMPC_acquire: 14762 case OMPC_release: 14763 case OMPC_relaxed: 14764 case OMPC_depend: 14765 case OMPC_threads: 14766 case OMPC_simd: 14767 case OMPC_map: 14768 case OMPC_nogroup: 14769 case OMPC_dist_schedule: 14770 case OMPC_defaultmap: 14771 case OMPC_unknown: 14772 case OMPC_uniform: 14773 case OMPC_to: 14774 case OMPC_from: 14775 case OMPC_use_device_ptr: 14776 case OMPC_use_device_addr: 14777 case OMPC_is_device_ptr: 14778 case OMPC_unified_address: 14779 case OMPC_unified_shared_memory: 14780 case OMPC_reverse_offload: 14781 case OMPC_dynamic_allocators: 14782 case OMPC_atomic_default_mem_order: 14783 case OMPC_device_type: 14784 case OMPC_match: 14785 case OMPC_nontemporal: 14786 case OMPC_order: 14787 case OMPC_destroy: 14788 case OMPC_inclusive: 14789 case OMPC_exclusive: 14790 case OMPC_uses_allocators: 14791 case OMPC_affinity: 14792 case OMPC_when: 14793 case OMPC_bind: 14794 default: 14795 llvm_unreachable("Clause is not allowed."); 14796 } 14797 return Res; 14798 } 14799 14800 // An OpenMP directive such as 'target parallel' has two captured regions: 14801 // for the 'target' and 'parallel' respectively. This function returns 14802 // the region in which to capture expressions associated with a clause. 14803 // A return value of OMPD_unknown signifies that the expression should not 14804 // be captured. 14805 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 14806 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, unsigned OpenMPVersion, 14807 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 14808 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 14809 switch (CKind) { 14810 case OMPC_if: 14811 switch (DKind) { 14812 case OMPD_target_parallel_for_simd: 14813 if (OpenMPVersion >= 50 && 14814 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 14815 CaptureRegion = OMPD_parallel; 14816 break; 14817 } 14818 LLVM_FALLTHROUGH; 14819 case OMPD_target_parallel: 14820 case OMPD_target_parallel_for: 14821 case OMPD_target_parallel_loop: 14822 // If this clause applies to the nested 'parallel' region, capture within 14823 // the 'target' region, otherwise do not capture. 14824 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 14825 CaptureRegion = OMPD_target; 14826 break; 14827 case OMPD_target_teams_distribute_parallel_for_simd: 14828 if (OpenMPVersion >= 50 && 14829 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 14830 CaptureRegion = OMPD_parallel; 14831 break; 14832 } 14833 LLVM_FALLTHROUGH; 14834 case OMPD_target_teams_distribute_parallel_for: 14835 // If this clause applies to the nested 'parallel' region, capture within 14836 // the 'teams' region, otherwise do not capture. 14837 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 14838 CaptureRegion = OMPD_teams; 14839 break; 14840 case OMPD_teams_distribute_parallel_for_simd: 14841 if (OpenMPVersion >= 50 && 14842 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) { 14843 CaptureRegion = OMPD_parallel; 14844 break; 14845 } 14846 LLVM_FALLTHROUGH; 14847 case OMPD_teams_distribute_parallel_for: 14848 CaptureRegion = OMPD_teams; 14849 break; 14850 case OMPD_target_update: 14851 case OMPD_target_enter_data: 14852 case OMPD_target_exit_data: 14853 CaptureRegion = OMPD_task; 14854 break; 14855 case OMPD_parallel_master_taskloop: 14856 if (NameModifier == OMPD_unknown || NameModifier == OMPD_taskloop) 14857 CaptureRegion = OMPD_parallel; 14858 break; 14859 case OMPD_parallel_master_taskloop_simd: 14860 if ((OpenMPVersion <= 45 && NameModifier == OMPD_unknown) || 14861 NameModifier == OMPD_taskloop) { 14862 CaptureRegion = OMPD_parallel; 14863 break; 14864 } 14865 if (OpenMPVersion <= 45) 14866 break; 14867 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14868 CaptureRegion = OMPD_taskloop; 14869 break; 14870 case OMPD_parallel_for_simd: 14871 if (OpenMPVersion <= 45) 14872 break; 14873 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14874 CaptureRegion = OMPD_parallel; 14875 break; 14876 case OMPD_taskloop_simd: 14877 case OMPD_master_taskloop_simd: 14878 if (OpenMPVersion <= 45) 14879 break; 14880 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14881 CaptureRegion = OMPD_taskloop; 14882 break; 14883 case OMPD_distribute_parallel_for_simd: 14884 if (OpenMPVersion <= 45) 14885 break; 14886 if (NameModifier == OMPD_unknown || NameModifier == OMPD_simd) 14887 CaptureRegion = OMPD_parallel; 14888 break; 14889 case OMPD_target_simd: 14890 if (OpenMPVersion >= 50 && 14891 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 14892 CaptureRegion = OMPD_target; 14893 break; 14894 case OMPD_teams_distribute_simd: 14895 case OMPD_target_teams_distribute_simd: 14896 if (OpenMPVersion >= 50 && 14897 (NameModifier == OMPD_unknown || NameModifier == OMPD_simd)) 14898 CaptureRegion = OMPD_teams; 14899 break; 14900 case OMPD_cancel: 14901 case OMPD_parallel: 14902 case OMPD_parallel_master: 14903 case OMPD_parallel_masked: 14904 case OMPD_parallel_sections: 14905 case OMPD_parallel_for: 14906 case OMPD_parallel_loop: 14907 case OMPD_target: 14908 case OMPD_target_teams: 14909 case OMPD_target_teams_distribute: 14910 case OMPD_target_teams_loop: 14911 case OMPD_distribute_parallel_for: 14912 case OMPD_task: 14913 case OMPD_taskloop: 14914 case OMPD_master_taskloop: 14915 case OMPD_masked_taskloop: 14916 case OMPD_target_data: 14917 case OMPD_simd: 14918 case OMPD_for_simd: 14919 case OMPD_distribute_simd: 14920 // Do not capture if-clause expressions. 14921 break; 14922 case OMPD_threadprivate: 14923 case OMPD_allocate: 14924 case OMPD_taskyield: 14925 case OMPD_barrier: 14926 case OMPD_taskwait: 14927 case OMPD_cancellation_point: 14928 case OMPD_flush: 14929 case OMPD_depobj: 14930 case OMPD_scan: 14931 case OMPD_declare_reduction: 14932 case OMPD_declare_mapper: 14933 case OMPD_declare_simd: 14934 case OMPD_declare_variant: 14935 case OMPD_begin_declare_variant: 14936 case OMPD_end_declare_variant: 14937 case OMPD_declare_target: 14938 case OMPD_end_declare_target: 14939 case OMPD_loop: 14940 case OMPD_teams_loop: 14941 case OMPD_teams: 14942 case OMPD_tile: 14943 case OMPD_unroll: 14944 case OMPD_for: 14945 case OMPD_sections: 14946 case OMPD_section: 14947 case OMPD_single: 14948 case OMPD_master: 14949 case OMPD_masked: 14950 case OMPD_critical: 14951 case OMPD_taskgroup: 14952 case OMPD_distribute: 14953 case OMPD_ordered: 14954 case OMPD_atomic: 14955 case OMPD_teams_distribute: 14956 case OMPD_requires: 14957 case OMPD_metadirective: 14958 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 14959 case OMPD_unknown: 14960 default: 14961 llvm_unreachable("Unknown OpenMP directive"); 14962 } 14963 break; 14964 case OMPC_num_threads: 14965 switch (DKind) { 14966 case OMPD_target_parallel: 14967 case OMPD_target_parallel_for: 14968 case OMPD_target_parallel_for_simd: 14969 case OMPD_target_parallel_loop: 14970 CaptureRegion = OMPD_target; 14971 break; 14972 case OMPD_teams_distribute_parallel_for: 14973 case OMPD_teams_distribute_parallel_for_simd: 14974 case OMPD_target_teams_distribute_parallel_for: 14975 case OMPD_target_teams_distribute_parallel_for_simd: 14976 CaptureRegion = OMPD_teams; 14977 break; 14978 case OMPD_parallel: 14979 case OMPD_parallel_master: 14980 case OMPD_parallel_masked: 14981 case OMPD_parallel_sections: 14982 case OMPD_parallel_for: 14983 case OMPD_parallel_for_simd: 14984 case OMPD_parallel_loop: 14985 case OMPD_distribute_parallel_for: 14986 case OMPD_distribute_parallel_for_simd: 14987 case OMPD_parallel_master_taskloop: 14988 case OMPD_parallel_master_taskloop_simd: 14989 // Do not capture num_threads-clause expressions. 14990 break; 14991 case OMPD_target_data: 14992 case OMPD_target_enter_data: 14993 case OMPD_target_exit_data: 14994 case OMPD_target_update: 14995 case OMPD_target: 14996 case OMPD_target_simd: 14997 case OMPD_target_teams: 14998 case OMPD_target_teams_distribute: 14999 case OMPD_target_teams_distribute_simd: 15000 case OMPD_cancel: 15001 case OMPD_task: 15002 case OMPD_taskloop: 15003 case OMPD_taskloop_simd: 15004 case OMPD_master_taskloop: 15005 case OMPD_masked_taskloop: 15006 case OMPD_master_taskloop_simd: 15007 case OMPD_threadprivate: 15008 case OMPD_allocate: 15009 case OMPD_taskyield: 15010 case OMPD_barrier: 15011 case OMPD_taskwait: 15012 case OMPD_cancellation_point: 15013 case OMPD_flush: 15014 case OMPD_depobj: 15015 case OMPD_scan: 15016 case OMPD_declare_reduction: 15017 case OMPD_declare_mapper: 15018 case OMPD_declare_simd: 15019 case OMPD_declare_variant: 15020 case OMPD_begin_declare_variant: 15021 case OMPD_end_declare_variant: 15022 case OMPD_declare_target: 15023 case OMPD_end_declare_target: 15024 case OMPD_loop: 15025 case OMPD_teams_loop: 15026 case OMPD_target_teams_loop: 15027 case OMPD_teams: 15028 case OMPD_simd: 15029 case OMPD_tile: 15030 case OMPD_unroll: 15031 case OMPD_for: 15032 case OMPD_for_simd: 15033 case OMPD_sections: 15034 case OMPD_section: 15035 case OMPD_single: 15036 case OMPD_master: 15037 case OMPD_masked: 15038 case OMPD_critical: 15039 case OMPD_taskgroup: 15040 case OMPD_distribute: 15041 case OMPD_ordered: 15042 case OMPD_atomic: 15043 case OMPD_distribute_simd: 15044 case OMPD_teams_distribute: 15045 case OMPD_teams_distribute_simd: 15046 case OMPD_requires: 15047 case OMPD_metadirective: 15048 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 15049 case OMPD_unknown: 15050 default: 15051 llvm_unreachable("Unknown OpenMP directive"); 15052 } 15053 break; 15054 case OMPC_num_teams: 15055 switch (DKind) { 15056 case OMPD_target_teams: 15057 case OMPD_target_teams_distribute: 15058 case OMPD_target_teams_distribute_simd: 15059 case OMPD_target_teams_distribute_parallel_for: 15060 case OMPD_target_teams_distribute_parallel_for_simd: 15061 case OMPD_target_teams_loop: 15062 CaptureRegion = OMPD_target; 15063 break; 15064 case OMPD_teams_distribute_parallel_for: 15065 case OMPD_teams_distribute_parallel_for_simd: 15066 case OMPD_teams: 15067 case OMPD_teams_distribute: 15068 case OMPD_teams_distribute_simd: 15069 case OMPD_teams_loop: 15070 // Do not capture num_teams-clause expressions. 15071 break; 15072 case OMPD_distribute_parallel_for: 15073 case OMPD_distribute_parallel_for_simd: 15074 case OMPD_task: 15075 case OMPD_taskloop: 15076 case OMPD_taskloop_simd: 15077 case OMPD_master_taskloop: 15078 case OMPD_masked_taskloop: 15079 case OMPD_master_taskloop_simd: 15080 case OMPD_parallel_master_taskloop: 15081 case OMPD_parallel_master_taskloop_simd: 15082 case OMPD_target_data: 15083 case OMPD_target_enter_data: 15084 case OMPD_target_exit_data: 15085 case OMPD_target_update: 15086 case OMPD_cancel: 15087 case OMPD_parallel: 15088 case OMPD_parallel_master: 15089 case OMPD_parallel_masked: 15090 case OMPD_parallel_sections: 15091 case OMPD_parallel_for: 15092 case OMPD_parallel_for_simd: 15093 case OMPD_parallel_loop: 15094 case OMPD_target: 15095 case OMPD_target_simd: 15096 case OMPD_target_parallel: 15097 case OMPD_target_parallel_for: 15098 case OMPD_target_parallel_for_simd: 15099 case OMPD_target_parallel_loop: 15100 case OMPD_threadprivate: 15101 case OMPD_allocate: 15102 case OMPD_taskyield: 15103 case OMPD_barrier: 15104 case OMPD_taskwait: 15105 case OMPD_cancellation_point: 15106 case OMPD_flush: 15107 case OMPD_depobj: 15108 case OMPD_scan: 15109 case OMPD_declare_reduction: 15110 case OMPD_declare_mapper: 15111 case OMPD_declare_simd: 15112 case OMPD_declare_variant: 15113 case OMPD_begin_declare_variant: 15114 case OMPD_end_declare_variant: 15115 case OMPD_declare_target: 15116 case OMPD_end_declare_target: 15117 case OMPD_loop: 15118 case OMPD_simd: 15119 case OMPD_tile: 15120 case OMPD_unroll: 15121 case OMPD_for: 15122 case OMPD_for_simd: 15123 case OMPD_sections: 15124 case OMPD_section: 15125 case OMPD_single: 15126 case OMPD_master: 15127 case OMPD_masked: 15128 case OMPD_critical: 15129 case OMPD_taskgroup: 15130 case OMPD_distribute: 15131 case OMPD_ordered: 15132 case OMPD_atomic: 15133 case OMPD_distribute_simd: 15134 case OMPD_requires: 15135 case OMPD_metadirective: 15136 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 15137 case OMPD_unknown: 15138 default: 15139 llvm_unreachable("Unknown OpenMP directive"); 15140 } 15141 break; 15142 case OMPC_thread_limit: 15143 switch (DKind) { 15144 case OMPD_target_teams: 15145 case OMPD_target_teams_distribute: 15146 case OMPD_target_teams_distribute_simd: 15147 case OMPD_target_teams_distribute_parallel_for: 15148 case OMPD_target_teams_distribute_parallel_for_simd: 15149 case OMPD_target_teams_loop: 15150 CaptureRegion = OMPD_target; 15151 break; 15152 case OMPD_teams_distribute_parallel_for: 15153 case OMPD_teams_distribute_parallel_for_simd: 15154 case OMPD_teams: 15155 case OMPD_teams_distribute: 15156 case OMPD_teams_distribute_simd: 15157 case OMPD_teams_loop: 15158 // Do not capture thread_limit-clause expressions. 15159 break; 15160 case OMPD_distribute_parallel_for: 15161 case OMPD_distribute_parallel_for_simd: 15162 case OMPD_task: 15163 case OMPD_taskloop: 15164 case OMPD_taskloop_simd: 15165 case OMPD_master_taskloop: 15166 case OMPD_masked_taskloop: 15167 case OMPD_master_taskloop_simd: 15168 case OMPD_parallel_master_taskloop: 15169 case OMPD_parallel_master_taskloop_simd: 15170 case OMPD_target_data: 15171 case OMPD_target_enter_data: 15172 case OMPD_target_exit_data: 15173 case OMPD_target_update: 15174 case OMPD_cancel: 15175 case OMPD_parallel: 15176 case OMPD_parallel_master: 15177 case OMPD_parallel_masked: 15178 case OMPD_parallel_sections: 15179 case OMPD_parallel_for: 15180 case OMPD_parallel_for_simd: 15181 case OMPD_parallel_loop: 15182 case OMPD_target: 15183 case OMPD_target_simd: 15184 case OMPD_target_parallel: 15185 case OMPD_target_parallel_for: 15186 case OMPD_target_parallel_for_simd: 15187 case OMPD_target_parallel_loop: 15188 case OMPD_threadprivate: 15189 case OMPD_allocate: 15190 case OMPD_taskyield: 15191 case OMPD_barrier: 15192 case OMPD_taskwait: 15193 case OMPD_cancellation_point: 15194 case OMPD_flush: 15195 case OMPD_depobj: 15196 case OMPD_scan: 15197 case OMPD_declare_reduction: 15198 case OMPD_declare_mapper: 15199 case OMPD_declare_simd: 15200 case OMPD_declare_variant: 15201 case OMPD_begin_declare_variant: 15202 case OMPD_end_declare_variant: 15203 case OMPD_declare_target: 15204 case OMPD_end_declare_target: 15205 case OMPD_loop: 15206 case OMPD_simd: 15207 case OMPD_tile: 15208 case OMPD_unroll: 15209 case OMPD_for: 15210 case OMPD_for_simd: 15211 case OMPD_sections: 15212 case OMPD_section: 15213 case OMPD_single: 15214 case OMPD_master: 15215 case OMPD_masked: 15216 case OMPD_critical: 15217 case OMPD_taskgroup: 15218 case OMPD_distribute: 15219 case OMPD_ordered: 15220 case OMPD_atomic: 15221 case OMPD_distribute_simd: 15222 case OMPD_requires: 15223 case OMPD_metadirective: 15224 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 15225 case OMPD_unknown: 15226 default: 15227 llvm_unreachable("Unknown OpenMP directive"); 15228 } 15229 break; 15230 case OMPC_schedule: 15231 switch (DKind) { 15232 case OMPD_parallel_for: 15233 case OMPD_parallel_for_simd: 15234 case OMPD_distribute_parallel_for: 15235 case OMPD_distribute_parallel_for_simd: 15236 case OMPD_teams_distribute_parallel_for: 15237 case OMPD_teams_distribute_parallel_for_simd: 15238 case OMPD_target_parallel_for: 15239 case OMPD_target_parallel_for_simd: 15240 case OMPD_target_teams_distribute_parallel_for: 15241 case OMPD_target_teams_distribute_parallel_for_simd: 15242 CaptureRegion = OMPD_parallel; 15243 break; 15244 case OMPD_for: 15245 case OMPD_for_simd: 15246 // Do not capture schedule-clause expressions. 15247 break; 15248 case OMPD_task: 15249 case OMPD_taskloop: 15250 case OMPD_taskloop_simd: 15251 case OMPD_master_taskloop: 15252 case OMPD_masked_taskloop: 15253 case OMPD_master_taskloop_simd: 15254 case OMPD_parallel_master_taskloop: 15255 case OMPD_parallel_master_taskloop_simd: 15256 case OMPD_target_data: 15257 case OMPD_target_enter_data: 15258 case OMPD_target_exit_data: 15259 case OMPD_target_update: 15260 case OMPD_teams: 15261 case OMPD_teams_distribute: 15262 case OMPD_teams_distribute_simd: 15263 case OMPD_target_teams_distribute: 15264 case OMPD_target_teams_distribute_simd: 15265 case OMPD_target: 15266 case OMPD_target_simd: 15267 case OMPD_target_parallel: 15268 case OMPD_cancel: 15269 case OMPD_parallel: 15270 case OMPD_parallel_master: 15271 case OMPD_parallel_masked: 15272 case OMPD_parallel_sections: 15273 case OMPD_threadprivate: 15274 case OMPD_allocate: 15275 case OMPD_taskyield: 15276 case OMPD_barrier: 15277 case OMPD_taskwait: 15278 case OMPD_cancellation_point: 15279 case OMPD_flush: 15280 case OMPD_depobj: 15281 case OMPD_scan: 15282 case OMPD_declare_reduction: 15283 case OMPD_declare_mapper: 15284 case OMPD_declare_simd: 15285 case OMPD_declare_variant: 15286 case OMPD_begin_declare_variant: 15287 case OMPD_end_declare_variant: 15288 case OMPD_declare_target: 15289 case OMPD_end_declare_target: 15290 case OMPD_loop: 15291 case OMPD_teams_loop: 15292 case OMPD_target_teams_loop: 15293 case OMPD_parallel_loop: 15294 case OMPD_target_parallel_loop: 15295 case OMPD_simd: 15296 case OMPD_tile: 15297 case OMPD_unroll: 15298 case OMPD_sections: 15299 case OMPD_section: 15300 case OMPD_single: 15301 case OMPD_master: 15302 case OMPD_masked: 15303 case OMPD_critical: 15304 case OMPD_taskgroup: 15305 case OMPD_distribute: 15306 case OMPD_ordered: 15307 case OMPD_atomic: 15308 case OMPD_distribute_simd: 15309 case OMPD_target_teams: 15310 case OMPD_requires: 15311 case OMPD_metadirective: 15312 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 15313 case OMPD_unknown: 15314 default: 15315 llvm_unreachable("Unknown OpenMP directive"); 15316 } 15317 break; 15318 case OMPC_dist_schedule: 15319 switch (DKind) { 15320 case OMPD_teams_distribute_parallel_for: 15321 case OMPD_teams_distribute_parallel_for_simd: 15322 case OMPD_teams_distribute: 15323 case OMPD_teams_distribute_simd: 15324 case OMPD_target_teams_distribute_parallel_for: 15325 case OMPD_target_teams_distribute_parallel_for_simd: 15326 case OMPD_target_teams_distribute: 15327 case OMPD_target_teams_distribute_simd: 15328 CaptureRegion = OMPD_teams; 15329 break; 15330 case OMPD_distribute_parallel_for: 15331 case OMPD_distribute_parallel_for_simd: 15332 case OMPD_distribute: 15333 case OMPD_distribute_simd: 15334 // Do not capture dist_schedule-clause expressions. 15335 break; 15336 case OMPD_parallel_for: 15337 case OMPD_parallel_for_simd: 15338 case OMPD_target_parallel_for_simd: 15339 case OMPD_target_parallel_for: 15340 case OMPD_task: 15341 case OMPD_taskloop: 15342 case OMPD_taskloop_simd: 15343 case OMPD_master_taskloop: 15344 case OMPD_masked_taskloop: 15345 case OMPD_master_taskloop_simd: 15346 case OMPD_parallel_master_taskloop: 15347 case OMPD_parallel_master_taskloop_simd: 15348 case OMPD_target_data: 15349 case OMPD_target_enter_data: 15350 case OMPD_target_exit_data: 15351 case OMPD_target_update: 15352 case OMPD_teams: 15353 case OMPD_target: 15354 case OMPD_target_simd: 15355 case OMPD_target_parallel: 15356 case OMPD_cancel: 15357 case OMPD_parallel: 15358 case OMPD_parallel_master: 15359 case OMPD_parallel_masked: 15360 case OMPD_parallel_sections: 15361 case OMPD_threadprivate: 15362 case OMPD_allocate: 15363 case OMPD_taskyield: 15364 case OMPD_barrier: 15365 case OMPD_taskwait: 15366 case OMPD_cancellation_point: 15367 case OMPD_flush: 15368 case OMPD_depobj: 15369 case OMPD_scan: 15370 case OMPD_declare_reduction: 15371 case OMPD_declare_mapper: 15372 case OMPD_declare_simd: 15373 case OMPD_declare_variant: 15374 case OMPD_begin_declare_variant: 15375 case OMPD_end_declare_variant: 15376 case OMPD_declare_target: 15377 case OMPD_end_declare_target: 15378 case OMPD_loop: 15379 case OMPD_teams_loop: 15380 case OMPD_target_teams_loop: 15381 case OMPD_parallel_loop: 15382 case OMPD_target_parallel_loop: 15383 case OMPD_simd: 15384 case OMPD_tile: 15385 case OMPD_unroll: 15386 case OMPD_for: 15387 case OMPD_for_simd: 15388 case OMPD_sections: 15389 case OMPD_section: 15390 case OMPD_single: 15391 case OMPD_master: 15392 case OMPD_masked: 15393 case OMPD_critical: 15394 case OMPD_taskgroup: 15395 case OMPD_ordered: 15396 case OMPD_atomic: 15397 case OMPD_target_teams: 15398 case OMPD_requires: 15399 case OMPD_metadirective: 15400 llvm_unreachable("Unexpected OpenMP directive with dist_schedule clause"); 15401 case OMPD_unknown: 15402 default: 15403 llvm_unreachable("Unknown OpenMP directive"); 15404 } 15405 break; 15406 case OMPC_device: 15407 switch (DKind) { 15408 case OMPD_target_update: 15409 case OMPD_target_enter_data: 15410 case OMPD_target_exit_data: 15411 case OMPD_target: 15412 case OMPD_target_simd: 15413 case OMPD_target_teams: 15414 case OMPD_target_parallel: 15415 case OMPD_target_teams_distribute: 15416 case OMPD_target_teams_distribute_simd: 15417 case OMPD_target_parallel_for: 15418 case OMPD_target_parallel_for_simd: 15419 case OMPD_target_parallel_loop: 15420 case OMPD_target_teams_distribute_parallel_for: 15421 case OMPD_target_teams_distribute_parallel_for_simd: 15422 case OMPD_target_teams_loop: 15423 case OMPD_dispatch: 15424 CaptureRegion = OMPD_task; 15425 break; 15426 case OMPD_target_data: 15427 case OMPD_interop: 15428 // Do not capture device-clause expressions. 15429 break; 15430 case OMPD_teams_distribute_parallel_for: 15431 case OMPD_teams_distribute_parallel_for_simd: 15432 case OMPD_teams: 15433 case OMPD_teams_distribute: 15434 case OMPD_teams_distribute_simd: 15435 case OMPD_distribute_parallel_for: 15436 case OMPD_distribute_parallel_for_simd: 15437 case OMPD_task: 15438 case OMPD_taskloop: 15439 case OMPD_taskloop_simd: 15440 case OMPD_master_taskloop: 15441 case OMPD_masked_taskloop: 15442 case OMPD_master_taskloop_simd: 15443 case OMPD_parallel_master_taskloop: 15444 case OMPD_parallel_master_taskloop_simd: 15445 case OMPD_cancel: 15446 case OMPD_parallel: 15447 case OMPD_parallel_master: 15448 case OMPD_parallel_masked: 15449 case OMPD_parallel_sections: 15450 case OMPD_parallel_for: 15451 case OMPD_parallel_for_simd: 15452 case OMPD_threadprivate: 15453 case OMPD_allocate: 15454 case OMPD_taskyield: 15455 case OMPD_barrier: 15456 case OMPD_taskwait: 15457 case OMPD_cancellation_point: 15458 case OMPD_flush: 15459 case OMPD_depobj: 15460 case OMPD_scan: 15461 case OMPD_declare_reduction: 15462 case OMPD_declare_mapper: 15463 case OMPD_declare_simd: 15464 case OMPD_declare_variant: 15465 case OMPD_begin_declare_variant: 15466 case OMPD_end_declare_variant: 15467 case OMPD_declare_target: 15468 case OMPD_end_declare_target: 15469 case OMPD_loop: 15470 case OMPD_teams_loop: 15471 case OMPD_parallel_loop: 15472 case OMPD_simd: 15473 case OMPD_tile: 15474 case OMPD_unroll: 15475 case OMPD_for: 15476 case OMPD_for_simd: 15477 case OMPD_sections: 15478 case OMPD_section: 15479 case OMPD_single: 15480 case OMPD_master: 15481 case OMPD_masked: 15482 case OMPD_critical: 15483 case OMPD_taskgroup: 15484 case OMPD_distribute: 15485 case OMPD_ordered: 15486 case OMPD_atomic: 15487 case OMPD_distribute_simd: 15488 case OMPD_requires: 15489 case OMPD_metadirective: 15490 llvm_unreachable("Unexpected OpenMP directive with device-clause"); 15491 case OMPD_unknown: 15492 default: 15493 llvm_unreachable("Unknown OpenMP directive"); 15494 } 15495 break; 15496 case OMPC_grainsize: 15497 case OMPC_num_tasks: 15498 case OMPC_final: 15499 case OMPC_priority: 15500 switch (DKind) { 15501 case OMPD_task: 15502 case OMPD_taskloop: 15503 case OMPD_taskloop_simd: 15504 case OMPD_master_taskloop: 15505 case OMPD_masked_taskloop: 15506 case OMPD_master_taskloop_simd: 15507 break; 15508 case OMPD_parallel_master_taskloop: 15509 case OMPD_parallel_master_taskloop_simd: 15510 CaptureRegion = OMPD_parallel; 15511 break; 15512 case OMPD_target_update: 15513 case OMPD_target_enter_data: 15514 case OMPD_target_exit_data: 15515 case OMPD_target: 15516 case OMPD_target_simd: 15517 case OMPD_target_teams: 15518 case OMPD_target_parallel: 15519 case OMPD_target_teams_distribute: 15520 case OMPD_target_teams_distribute_simd: 15521 case OMPD_target_parallel_for: 15522 case OMPD_target_parallel_for_simd: 15523 case OMPD_target_teams_distribute_parallel_for: 15524 case OMPD_target_teams_distribute_parallel_for_simd: 15525 case OMPD_target_data: 15526 case OMPD_teams_distribute_parallel_for: 15527 case OMPD_teams_distribute_parallel_for_simd: 15528 case OMPD_teams: 15529 case OMPD_teams_distribute: 15530 case OMPD_teams_distribute_simd: 15531 case OMPD_distribute_parallel_for: 15532 case OMPD_distribute_parallel_for_simd: 15533 case OMPD_cancel: 15534 case OMPD_parallel: 15535 case OMPD_parallel_master: 15536 case OMPD_parallel_masked: 15537 case OMPD_parallel_sections: 15538 case OMPD_parallel_for: 15539 case OMPD_parallel_for_simd: 15540 case OMPD_threadprivate: 15541 case OMPD_allocate: 15542 case OMPD_taskyield: 15543 case OMPD_barrier: 15544 case OMPD_taskwait: 15545 case OMPD_cancellation_point: 15546 case OMPD_flush: 15547 case OMPD_depobj: 15548 case OMPD_scan: 15549 case OMPD_declare_reduction: 15550 case OMPD_declare_mapper: 15551 case OMPD_declare_simd: 15552 case OMPD_declare_variant: 15553 case OMPD_begin_declare_variant: 15554 case OMPD_end_declare_variant: 15555 case OMPD_declare_target: 15556 case OMPD_end_declare_target: 15557 case OMPD_loop: 15558 case OMPD_teams_loop: 15559 case OMPD_target_teams_loop: 15560 case OMPD_parallel_loop: 15561 case OMPD_target_parallel_loop: 15562 case OMPD_simd: 15563 case OMPD_tile: 15564 case OMPD_unroll: 15565 case OMPD_for: 15566 case OMPD_for_simd: 15567 case OMPD_sections: 15568 case OMPD_section: 15569 case OMPD_single: 15570 case OMPD_master: 15571 case OMPD_masked: 15572 case OMPD_critical: 15573 case OMPD_taskgroup: 15574 case OMPD_distribute: 15575 case OMPD_ordered: 15576 case OMPD_atomic: 15577 case OMPD_distribute_simd: 15578 case OMPD_requires: 15579 case OMPD_metadirective: 15580 llvm_unreachable("Unexpected OpenMP directive with grainsize-clause"); 15581 case OMPD_unknown: 15582 default: 15583 llvm_unreachable("Unknown OpenMP directive"); 15584 } 15585 break; 15586 case OMPC_novariants: 15587 case OMPC_nocontext: 15588 switch (DKind) { 15589 case OMPD_dispatch: 15590 CaptureRegion = OMPD_task; 15591 break; 15592 default: 15593 llvm_unreachable("Unexpected OpenMP directive"); 15594 } 15595 break; 15596 case OMPC_filter: 15597 // Do not capture filter-clause expressions. 15598 break; 15599 case OMPC_when: 15600 if (DKind == OMPD_metadirective) { 15601 CaptureRegion = OMPD_metadirective; 15602 } else if (DKind == OMPD_unknown) { 15603 llvm_unreachable("Unknown OpenMP directive"); 15604 } else { 15605 llvm_unreachable("Unexpected OpenMP directive with when clause"); 15606 } 15607 break; 15608 case OMPC_firstprivate: 15609 case OMPC_lastprivate: 15610 case OMPC_reduction: 15611 case OMPC_task_reduction: 15612 case OMPC_in_reduction: 15613 case OMPC_linear: 15614 case OMPC_default: 15615 case OMPC_proc_bind: 15616 case OMPC_safelen: 15617 case OMPC_simdlen: 15618 case OMPC_sizes: 15619 case OMPC_allocator: 15620 case OMPC_collapse: 15621 case OMPC_private: 15622 case OMPC_shared: 15623 case OMPC_aligned: 15624 case OMPC_copyin: 15625 case OMPC_copyprivate: 15626 case OMPC_ordered: 15627 case OMPC_nowait: 15628 case OMPC_untied: 15629 case OMPC_mergeable: 15630 case OMPC_threadprivate: 15631 case OMPC_allocate: 15632 case OMPC_flush: 15633 case OMPC_depobj: 15634 case OMPC_read: 15635 case OMPC_write: 15636 case OMPC_update: 15637 case OMPC_capture: 15638 case OMPC_compare: 15639 case OMPC_seq_cst: 15640 case OMPC_acq_rel: 15641 case OMPC_acquire: 15642 case OMPC_release: 15643 case OMPC_relaxed: 15644 case OMPC_depend: 15645 case OMPC_threads: 15646 case OMPC_simd: 15647 case OMPC_map: 15648 case OMPC_nogroup: 15649 case OMPC_hint: 15650 case OMPC_defaultmap: 15651 case OMPC_unknown: 15652 case OMPC_uniform: 15653 case OMPC_to: 15654 case OMPC_from: 15655 case OMPC_use_device_ptr: 15656 case OMPC_use_device_addr: 15657 case OMPC_is_device_ptr: 15658 case OMPC_unified_address: 15659 case OMPC_unified_shared_memory: 15660 case OMPC_reverse_offload: 15661 case OMPC_dynamic_allocators: 15662 case OMPC_atomic_default_mem_order: 15663 case OMPC_device_type: 15664 case OMPC_match: 15665 case OMPC_nontemporal: 15666 case OMPC_order: 15667 case OMPC_destroy: 15668 case OMPC_detach: 15669 case OMPC_inclusive: 15670 case OMPC_exclusive: 15671 case OMPC_uses_allocators: 15672 case OMPC_affinity: 15673 case OMPC_bind: 15674 default: 15675 llvm_unreachable("Unexpected OpenMP clause."); 15676 } 15677 return CaptureRegion; 15678 } 15679 15680 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 15681 Expr *Condition, SourceLocation StartLoc, 15682 SourceLocation LParenLoc, 15683 SourceLocation NameModifierLoc, 15684 SourceLocation ColonLoc, 15685 SourceLocation EndLoc) { 15686 Expr *ValExpr = Condition; 15687 Stmt *HelperValStmt = nullptr; 15688 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15689 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 15690 !Condition->isInstantiationDependent() && 15691 !Condition->containsUnexpandedParameterPack()) { 15692 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 15693 if (Val.isInvalid()) 15694 return nullptr; 15695 15696 ValExpr = Val.get(); 15697 15698 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15699 CaptureRegion = getOpenMPCaptureRegionForClause( 15700 DKind, OMPC_if, LangOpts.OpenMP, NameModifier); 15701 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15702 ValExpr = MakeFullExpr(ValExpr).get(); 15703 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15704 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15705 HelperValStmt = buildPreInits(Context, Captures); 15706 } 15707 } 15708 15709 return new (Context) 15710 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 15711 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 15712 } 15713 15714 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 15715 SourceLocation StartLoc, 15716 SourceLocation LParenLoc, 15717 SourceLocation EndLoc) { 15718 Expr *ValExpr = Condition; 15719 Stmt *HelperValStmt = nullptr; 15720 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 15721 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 15722 !Condition->isInstantiationDependent() && 15723 !Condition->containsUnexpandedParameterPack()) { 15724 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 15725 if (Val.isInvalid()) 15726 return nullptr; 15727 15728 ValExpr = MakeFullExpr(Val.get()).get(); 15729 15730 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15731 CaptureRegion = 15732 getOpenMPCaptureRegionForClause(DKind, OMPC_final, LangOpts.OpenMP); 15733 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15734 ValExpr = MakeFullExpr(ValExpr).get(); 15735 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15736 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15737 HelperValStmt = buildPreInits(Context, Captures); 15738 } 15739 } 15740 15741 return new (Context) OMPFinalClause(ValExpr, HelperValStmt, CaptureRegion, 15742 StartLoc, LParenLoc, EndLoc); 15743 } 15744 15745 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 15746 Expr *Op) { 15747 if (!Op) 15748 return ExprError(); 15749 15750 class IntConvertDiagnoser : public ICEConvertDiagnoser { 15751 public: 15752 IntConvertDiagnoser() 15753 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 15754 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 15755 QualType T) override { 15756 return S.Diag(Loc, diag::err_omp_not_integral) << T; 15757 } 15758 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 15759 QualType T) override { 15760 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 15761 } 15762 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 15763 QualType T, 15764 QualType ConvTy) override { 15765 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 15766 } 15767 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 15768 QualType ConvTy) override { 15769 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 15770 << ConvTy->isEnumeralType() << ConvTy; 15771 } 15772 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 15773 QualType T) override { 15774 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 15775 } 15776 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 15777 QualType ConvTy) override { 15778 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 15779 << ConvTy->isEnumeralType() << ConvTy; 15780 } 15781 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 15782 QualType) override { 15783 llvm_unreachable("conversion functions are permitted"); 15784 } 15785 } ConvertDiagnoser; 15786 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 15787 } 15788 15789 static bool 15790 isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, OpenMPClauseKind CKind, 15791 bool StrictlyPositive, bool BuildCapture = false, 15792 OpenMPDirectiveKind DKind = OMPD_unknown, 15793 OpenMPDirectiveKind *CaptureRegion = nullptr, 15794 Stmt **HelperValStmt = nullptr) { 15795 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 15796 !ValExpr->isInstantiationDependent()) { 15797 SourceLocation Loc = ValExpr->getExprLoc(); 15798 ExprResult Value = 15799 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 15800 if (Value.isInvalid()) 15801 return false; 15802 15803 ValExpr = Value.get(); 15804 // The expression must evaluate to a non-negative integer value. 15805 if (Optional<llvm::APSInt> Result = 15806 ValExpr->getIntegerConstantExpr(SemaRef.Context)) { 15807 if (Result->isSigned() && 15808 !((!StrictlyPositive && Result->isNonNegative()) || 15809 (StrictlyPositive && Result->isStrictlyPositive()))) { 15810 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 15811 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 15812 << ValExpr->getSourceRange(); 15813 return false; 15814 } 15815 } 15816 if (!BuildCapture) 15817 return true; 15818 *CaptureRegion = 15819 getOpenMPCaptureRegionForClause(DKind, CKind, SemaRef.LangOpts.OpenMP); 15820 if (*CaptureRegion != OMPD_unknown && 15821 !SemaRef.CurContext->isDependentContext()) { 15822 ValExpr = SemaRef.MakeFullExpr(ValExpr).get(); 15823 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15824 ValExpr = tryBuildCapture(SemaRef, ValExpr, Captures).get(); 15825 *HelperValStmt = buildPreInits(SemaRef.Context, Captures); 15826 } 15827 } 15828 return true; 15829 } 15830 15831 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 15832 SourceLocation StartLoc, 15833 SourceLocation LParenLoc, 15834 SourceLocation EndLoc) { 15835 Expr *ValExpr = NumThreads; 15836 Stmt *HelperValStmt = nullptr; 15837 15838 // OpenMP [2.5, Restrictions] 15839 // The num_threads expression must evaluate to a positive integer value. 15840 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 15841 /*StrictlyPositive=*/true)) 15842 return nullptr; 15843 15844 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 15845 OpenMPDirectiveKind CaptureRegion = 15846 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads, LangOpts.OpenMP); 15847 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 15848 ValExpr = MakeFullExpr(ValExpr).get(); 15849 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 15850 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 15851 HelperValStmt = buildPreInits(Context, Captures); 15852 } 15853 15854 return new (Context) OMPNumThreadsClause( 15855 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 15856 } 15857 15858 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 15859 OpenMPClauseKind CKind, 15860 bool StrictlyPositive, 15861 bool SuppressExprDiags) { 15862 if (!E) 15863 return ExprError(); 15864 if (E->isValueDependent() || E->isTypeDependent() || 15865 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 15866 return E; 15867 15868 llvm::APSInt Result; 15869 ExprResult ICE; 15870 if (SuppressExprDiags) { 15871 // Use a custom diagnoser that suppresses 'note' diagnostics about the 15872 // expression. 15873 struct SuppressedDiagnoser : public Sema::VerifyICEDiagnoser { 15874 SuppressedDiagnoser() : VerifyICEDiagnoser(/*Suppress=*/true) {} 15875 Sema::SemaDiagnosticBuilder diagnoseNotICE(Sema &S, 15876 SourceLocation Loc) override { 15877 llvm_unreachable("Diagnostic suppressed"); 15878 } 15879 } Diagnoser; 15880 ICE = VerifyIntegerConstantExpression(E, &Result, Diagnoser, AllowFold); 15881 } else { 15882 ICE = VerifyIntegerConstantExpression(E, &Result, /*FIXME*/ AllowFold); 15883 } 15884 if (ICE.isInvalid()) 15885 return ExprError(); 15886 15887 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 15888 (!StrictlyPositive && !Result.isNonNegative())) { 15889 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 15890 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 15891 << E->getSourceRange(); 15892 return ExprError(); 15893 } 15894 if ((CKind == OMPC_aligned || CKind == OMPC_align) && !Result.isPowerOf2()) { 15895 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 15896 << E->getSourceRange(); 15897 return ExprError(); 15898 } 15899 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 15900 DSAStack->setAssociatedLoops(Result.getExtValue()); 15901 else if (CKind == OMPC_ordered) 15902 DSAStack->setAssociatedLoops(Result.getExtValue()); 15903 return ICE; 15904 } 15905 15906 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 15907 SourceLocation LParenLoc, 15908 SourceLocation EndLoc) { 15909 // OpenMP [2.8.1, simd construct, Description] 15910 // The parameter of the safelen clause must be a constant 15911 // positive integer expression. 15912 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 15913 if (Safelen.isInvalid()) 15914 return nullptr; 15915 return new (Context) 15916 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 15917 } 15918 15919 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 15920 SourceLocation LParenLoc, 15921 SourceLocation EndLoc) { 15922 // OpenMP [2.8.1, simd construct, Description] 15923 // The parameter of the simdlen clause must be a constant 15924 // positive integer expression. 15925 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 15926 if (Simdlen.isInvalid()) 15927 return nullptr; 15928 return new (Context) 15929 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 15930 } 15931 15932 /// Tries to find omp_allocator_handle_t type. 15933 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 15934 DSAStackTy *Stack) { 15935 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 15936 if (!OMPAllocatorHandleT.isNull()) 15937 return true; 15938 // Build the predefined allocator expressions. 15939 bool ErrorFound = false; 15940 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 15941 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 15942 StringRef Allocator = 15943 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 15944 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 15945 auto *VD = dyn_cast_or_null<ValueDecl>( 15946 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 15947 if (!VD) { 15948 ErrorFound = true; 15949 break; 15950 } 15951 QualType AllocatorType = 15952 VD->getType().getNonLValueExprType(S.getASTContext()); 15953 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 15954 if (!Res.isUsable()) { 15955 ErrorFound = true; 15956 break; 15957 } 15958 if (OMPAllocatorHandleT.isNull()) 15959 OMPAllocatorHandleT = AllocatorType; 15960 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 15961 ErrorFound = true; 15962 break; 15963 } 15964 Stack->setAllocator(AllocatorKind, Res.get()); 15965 } 15966 if (ErrorFound) { 15967 S.Diag(Loc, diag::err_omp_implied_type_not_found) 15968 << "omp_allocator_handle_t"; 15969 return false; 15970 } 15971 OMPAllocatorHandleT.addConst(); 15972 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 15973 return true; 15974 } 15975 15976 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 15977 SourceLocation LParenLoc, 15978 SourceLocation EndLoc) { 15979 // OpenMP [2.11.3, allocate Directive, Description] 15980 // allocator is an expression of omp_allocator_handle_t type. 15981 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 15982 return nullptr; 15983 15984 ExprResult Allocator = DefaultLvalueConversion(A); 15985 if (Allocator.isInvalid()) 15986 return nullptr; 15987 Allocator = PerformImplicitConversion(Allocator.get(), 15988 DSAStack->getOMPAllocatorHandleT(), 15989 Sema::AA_Initializing, 15990 /*AllowExplicit=*/true); 15991 if (Allocator.isInvalid()) 15992 return nullptr; 15993 return new (Context) 15994 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 15995 } 15996 15997 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 15998 SourceLocation StartLoc, 15999 SourceLocation LParenLoc, 16000 SourceLocation EndLoc) { 16001 // OpenMP [2.7.1, loop construct, Description] 16002 // OpenMP [2.8.1, simd construct, Description] 16003 // OpenMP [2.9.6, distribute construct, Description] 16004 // The parameter of the collapse clause must be a constant 16005 // positive integer expression. 16006 ExprResult NumForLoopsResult = 16007 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 16008 if (NumForLoopsResult.isInvalid()) 16009 return nullptr; 16010 return new (Context) 16011 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 16012 } 16013 16014 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 16015 SourceLocation EndLoc, 16016 SourceLocation LParenLoc, 16017 Expr *NumForLoops) { 16018 // OpenMP [2.7.1, loop construct, Description] 16019 // OpenMP [2.8.1, simd construct, Description] 16020 // OpenMP [2.9.6, distribute construct, Description] 16021 // The parameter of the ordered clause must be a constant 16022 // positive integer expression if any. 16023 if (NumForLoops && LParenLoc.isValid()) { 16024 ExprResult NumForLoopsResult = 16025 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 16026 if (NumForLoopsResult.isInvalid()) 16027 return nullptr; 16028 NumForLoops = NumForLoopsResult.get(); 16029 } else { 16030 NumForLoops = nullptr; 16031 } 16032 auto *Clause = OMPOrderedClause::Create( 16033 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 16034 StartLoc, LParenLoc, EndLoc); 16035 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 16036 return Clause; 16037 } 16038 16039 OMPClause *Sema::ActOnOpenMPSimpleClause( 16040 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 16041 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16042 OMPClause *Res = nullptr; 16043 switch (Kind) { 16044 case OMPC_default: 16045 Res = ActOnOpenMPDefaultClause(static_cast<DefaultKind>(Argument), 16046 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16047 break; 16048 case OMPC_proc_bind: 16049 Res = ActOnOpenMPProcBindClause(static_cast<ProcBindKind>(Argument), 16050 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16051 break; 16052 case OMPC_atomic_default_mem_order: 16053 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 16054 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 16055 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16056 break; 16057 case OMPC_order: 16058 Res = ActOnOpenMPOrderClause(static_cast<OpenMPOrderClauseKind>(Argument), 16059 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16060 break; 16061 case OMPC_update: 16062 Res = ActOnOpenMPUpdateClause(static_cast<OpenMPDependClauseKind>(Argument), 16063 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16064 break; 16065 case OMPC_bind: 16066 Res = ActOnOpenMPBindClause(static_cast<OpenMPBindClauseKind>(Argument), 16067 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 16068 break; 16069 case OMPC_if: 16070 case OMPC_final: 16071 case OMPC_num_threads: 16072 case OMPC_safelen: 16073 case OMPC_simdlen: 16074 case OMPC_sizes: 16075 case OMPC_allocator: 16076 case OMPC_collapse: 16077 case OMPC_schedule: 16078 case OMPC_private: 16079 case OMPC_firstprivate: 16080 case OMPC_lastprivate: 16081 case OMPC_shared: 16082 case OMPC_reduction: 16083 case OMPC_task_reduction: 16084 case OMPC_in_reduction: 16085 case OMPC_linear: 16086 case OMPC_aligned: 16087 case OMPC_copyin: 16088 case OMPC_copyprivate: 16089 case OMPC_ordered: 16090 case OMPC_nowait: 16091 case OMPC_untied: 16092 case OMPC_mergeable: 16093 case OMPC_threadprivate: 16094 case OMPC_allocate: 16095 case OMPC_flush: 16096 case OMPC_depobj: 16097 case OMPC_read: 16098 case OMPC_write: 16099 case OMPC_capture: 16100 case OMPC_compare: 16101 case OMPC_seq_cst: 16102 case OMPC_acq_rel: 16103 case OMPC_acquire: 16104 case OMPC_release: 16105 case OMPC_relaxed: 16106 case OMPC_depend: 16107 case OMPC_device: 16108 case OMPC_threads: 16109 case OMPC_simd: 16110 case OMPC_map: 16111 case OMPC_num_teams: 16112 case OMPC_thread_limit: 16113 case OMPC_priority: 16114 case OMPC_grainsize: 16115 case OMPC_nogroup: 16116 case OMPC_num_tasks: 16117 case OMPC_hint: 16118 case OMPC_dist_schedule: 16119 case OMPC_defaultmap: 16120 case OMPC_unknown: 16121 case OMPC_uniform: 16122 case OMPC_to: 16123 case OMPC_from: 16124 case OMPC_use_device_ptr: 16125 case OMPC_use_device_addr: 16126 case OMPC_is_device_ptr: 16127 case OMPC_has_device_addr: 16128 case OMPC_unified_address: 16129 case OMPC_unified_shared_memory: 16130 case OMPC_reverse_offload: 16131 case OMPC_dynamic_allocators: 16132 case OMPC_device_type: 16133 case OMPC_match: 16134 case OMPC_nontemporal: 16135 case OMPC_destroy: 16136 case OMPC_novariants: 16137 case OMPC_nocontext: 16138 case OMPC_detach: 16139 case OMPC_inclusive: 16140 case OMPC_exclusive: 16141 case OMPC_uses_allocators: 16142 case OMPC_affinity: 16143 case OMPC_when: 16144 default: 16145 llvm_unreachable("Clause is not allowed."); 16146 } 16147 return Res; 16148 } 16149 16150 static std::string 16151 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 16152 ArrayRef<unsigned> Exclude = llvm::None) { 16153 SmallString<256> Buffer; 16154 llvm::raw_svector_ostream Out(Buffer); 16155 unsigned Skipped = Exclude.size(); 16156 auto S = Exclude.begin(), E = Exclude.end(); 16157 for (unsigned I = First; I < Last; ++I) { 16158 if (std::find(S, E, I) != E) { 16159 --Skipped; 16160 continue; 16161 } 16162 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 16163 if (I + Skipped + 2 == Last) 16164 Out << " or "; 16165 else if (I + Skipped + 1 != Last) 16166 Out << ", "; 16167 } 16168 return std::string(Out.str()); 16169 } 16170 16171 OMPClause *Sema::ActOnOpenMPDefaultClause(DefaultKind Kind, 16172 SourceLocation KindKwLoc, 16173 SourceLocation StartLoc, 16174 SourceLocation LParenLoc, 16175 SourceLocation EndLoc) { 16176 if (Kind == OMP_DEFAULT_unknown) { 16177 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16178 << getListOfPossibleValues(OMPC_default, /*First=*/0, 16179 /*Last=*/unsigned(OMP_DEFAULT_unknown)) 16180 << getOpenMPClauseName(OMPC_default); 16181 return nullptr; 16182 } 16183 16184 switch (Kind) { 16185 case OMP_DEFAULT_none: 16186 DSAStack->setDefaultDSANone(KindKwLoc); 16187 break; 16188 case OMP_DEFAULT_shared: 16189 DSAStack->setDefaultDSAShared(KindKwLoc); 16190 break; 16191 case OMP_DEFAULT_firstprivate: 16192 DSAStack->setDefaultDSAFirstPrivate(KindKwLoc); 16193 break; 16194 case OMP_DEFAULT_private: 16195 DSAStack->setDefaultDSAPrivate(KindKwLoc); 16196 break; 16197 default: 16198 llvm_unreachable("DSA unexpected in OpenMP default clause"); 16199 } 16200 16201 return new (Context) 16202 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16203 } 16204 16205 OMPClause *Sema::ActOnOpenMPProcBindClause(ProcBindKind Kind, 16206 SourceLocation KindKwLoc, 16207 SourceLocation StartLoc, 16208 SourceLocation LParenLoc, 16209 SourceLocation EndLoc) { 16210 if (Kind == OMP_PROC_BIND_unknown) { 16211 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16212 << getListOfPossibleValues(OMPC_proc_bind, 16213 /*First=*/unsigned(OMP_PROC_BIND_master), 16214 /*Last=*/ 16215 unsigned(LangOpts.OpenMP > 50 16216 ? OMP_PROC_BIND_primary 16217 : OMP_PROC_BIND_spread) + 16218 1) 16219 << getOpenMPClauseName(OMPC_proc_bind); 16220 return nullptr; 16221 } 16222 if (Kind == OMP_PROC_BIND_primary && LangOpts.OpenMP < 51) 16223 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16224 << getListOfPossibleValues(OMPC_proc_bind, 16225 /*First=*/unsigned(OMP_PROC_BIND_master), 16226 /*Last=*/ 16227 unsigned(OMP_PROC_BIND_spread) + 1) 16228 << getOpenMPClauseName(OMPC_proc_bind); 16229 return new (Context) 16230 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16231 } 16232 16233 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 16234 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 16235 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 16236 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 16237 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16238 << getListOfPossibleValues( 16239 OMPC_atomic_default_mem_order, /*First=*/0, 16240 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 16241 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 16242 return nullptr; 16243 } 16244 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 16245 LParenLoc, EndLoc); 16246 } 16247 16248 OMPClause *Sema::ActOnOpenMPOrderClause(OpenMPOrderClauseKind Kind, 16249 SourceLocation KindKwLoc, 16250 SourceLocation StartLoc, 16251 SourceLocation LParenLoc, 16252 SourceLocation EndLoc) { 16253 if (Kind == OMPC_ORDER_unknown) { 16254 static_assert(OMPC_ORDER_unknown > 0, 16255 "OMPC_ORDER_unknown not greater than 0"); 16256 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16257 << getListOfPossibleValues(OMPC_order, /*First=*/0, 16258 /*Last=*/OMPC_ORDER_unknown) 16259 << getOpenMPClauseName(OMPC_order); 16260 return nullptr; 16261 } 16262 return new (Context) 16263 OMPOrderClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 16264 } 16265 16266 OMPClause *Sema::ActOnOpenMPUpdateClause(OpenMPDependClauseKind Kind, 16267 SourceLocation KindKwLoc, 16268 SourceLocation StartLoc, 16269 SourceLocation LParenLoc, 16270 SourceLocation EndLoc) { 16271 if (Kind == OMPC_DEPEND_unknown || Kind == OMPC_DEPEND_source || 16272 Kind == OMPC_DEPEND_sink || Kind == OMPC_DEPEND_depobj) { 16273 SmallVector<unsigned> Except = { 16274 OMPC_DEPEND_source, OMPC_DEPEND_sink, OMPC_DEPEND_depobj, 16275 OMPC_DEPEND_outallmemory, OMPC_DEPEND_inoutallmemory}; 16276 if (LangOpts.OpenMP < 51) 16277 Except.push_back(OMPC_DEPEND_inoutset); 16278 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 16279 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 16280 /*Last=*/OMPC_DEPEND_unknown, Except) 16281 << getOpenMPClauseName(OMPC_update); 16282 return nullptr; 16283 } 16284 return OMPUpdateClause::Create(Context, StartLoc, LParenLoc, KindKwLoc, Kind, 16285 EndLoc); 16286 } 16287 16288 OMPClause *Sema::ActOnOpenMPSizesClause(ArrayRef<Expr *> SizeExprs, 16289 SourceLocation StartLoc, 16290 SourceLocation LParenLoc, 16291 SourceLocation EndLoc) { 16292 for (Expr *SizeExpr : SizeExprs) { 16293 ExprResult NumForLoopsResult = VerifyPositiveIntegerConstantInClause( 16294 SizeExpr, OMPC_sizes, /*StrictlyPositive=*/true); 16295 if (!NumForLoopsResult.isUsable()) 16296 return nullptr; 16297 } 16298 16299 DSAStack->setAssociatedLoops(SizeExprs.size()); 16300 return OMPSizesClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16301 SizeExprs); 16302 } 16303 16304 OMPClause *Sema::ActOnOpenMPFullClause(SourceLocation StartLoc, 16305 SourceLocation EndLoc) { 16306 return OMPFullClause::Create(Context, StartLoc, EndLoc); 16307 } 16308 16309 OMPClause *Sema::ActOnOpenMPPartialClause(Expr *FactorExpr, 16310 SourceLocation StartLoc, 16311 SourceLocation LParenLoc, 16312 SourceLocation EndLoc) { 16313 if (FactorExpr) { 16314 // If an argument is specified, it must be a constant (or an unevaluated 16315 // template expression). 16316 ExprResult FactorResult = VerifyPositiveIntegerConstantInClause( 16317 FactorExpr, OMPC_partial, /*StrictlyPositive=*/true); 16318 if (FactorResult.isInvalid()) 16319 return nullptr; 16320 FactorExpr = FactorResult.get(); 16321 } 16322 16323 return OMPPartialClause::Create(Context, StartLoc, LParenLoc, EndLoc, 16324 FactorExpr); 16325 } 16326 16327 OMPClause *Sema::ActOnOpenMPAlignClause(Expr *A, SourceLocation StartLoc, 16328 SourceLocation LParenLoc, 16329 SourceLocation EndLoc) { 16330 ExprResult AlignVal; 16331 AlignVal = VerifyPositiveIntegerConstantInClause(A, OMPC_align); 16332 if (AlignVal.isInvalid()) 16333 return nullptr; 16334 return OMPAlignClause::Create(Context, AlignVal.get(), StartLoc, LParenLoc, 16335 EndLoc); 16336 } 16337 16338 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 16339 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 16340 SourceLocation StartLoc, SourceLocation LParenLoc, 16341 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 16342 SourceLocation EndLoc) { 16343 OMPClause *Res = nullptr; 16344 switch (Kind) { 16345 case OMPC_schedule: 16346 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 16347 assert(Argument.size() == NumberOfElements && 16348 ArgumentLoc.size() == NumberOfElements); 16349 Res = ActOnOpenMPScheduleClause( 16350 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 16351 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 16352 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 16353 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 16354 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 16355 break; 16356 case OMPC_if: 16357 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 16358 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 16359 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 16360 DelimLoc, EndLoc); 16361 break; 16362 case OMPC_dist_schedule: 16363 Res = ActOnOpenMPDistScheduleClause( 16364 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 16365 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 16366 break; 16367 case OMPC_defaultmap: 16368 enum { Modifier, DefaultmapKind }; 16369 Res = ActOnOpenMPDefaultmapClause( 16370 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 16371 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 16372 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 16373 EndLoc); 16374 break; 16375 case OMPC_device: 16376 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 16377 Res = ActOnOpenMPDeviceClause( 16378 static_cast<OpenMPDeviceClauseModifier>(Argument.back()), Expr, 16379 StartLoc, LParenLoc, ArgumentLoc.back(), EndLoc); 16380 break; 16381 case OMPC_final: 16382 case OMPC_num_threads: 16383 case OMPC_safelen: 16384 case OMPC_simdlen: 16385 case OMPC_sizes: 16386 case OMPC_allocator: 16387 case OMPC_collapse: 16388 case OMPC_default: 16389 case OMPC_proc_bind: 16390 case OMPC_private: 16391 case OMPC_firstprivate: 16392 case OMPC_lastprivate: 16393 case OMPC_shared: 16394 case OMPC_reduction: 16395 case OMPC_task_reduction: 16396 case OMPC_in_reduction: 16397 case OMPC_linear: 16398 case OMPC_aligned: 16399 case OMPC_copyin: 16400 case OMPC_copyprivate: 16401 case OMPC_ordered: 16402 case OMPC_nowait: 16403 case OMPC_untied: 16404 case OMPC_mergeable: 16405 case OMPC_threadprivate: 16406 case OMPC_allocate: 16407 case OMPC_flush: 16408 case OMPC_depobj: 16409 case OMPC_read: 16410 case OMPC_write: 16411 case OMPC_update: 16412 case OMPC_capture: 16413 case OMPC_compare: 16414 case OMPC_seq_cst: 16415 case OMPC_acq_rel: 16416 case OMPC_acquire: 16417 case OMPC_release: 16418 case OMPC_relaxed: 16419 case OMPC_depend: 16420 case OMPC_threads: 16421 case OMPC_simd: 16422 case OMPC_map: 16423 case OMPC_num_teams: 16424 case OMPC_thread_limit: 16425 case OMPC_priority: 16426 case OMPC_grainsize: 16427 case OMPC_nogroup: 16428 case OMPC_num_tasks: 16429 case OMPC_hint: 16430 case OMPC_unknown: 16431 case OMPC_uniform: 16432 case OMPC_to: 16433 case OMPC_from: 16434 case OMPC_use_device_ptr: 16435 case OMPC_use_device_addr: 16436 case OMPC_is_device_ptr: 16437 case OMPC_has_device_addr: 16438 case OMPC_unified_address: 16439 case OMPC_unified_shared_memory: 16440 case OMPC_reverse_offload: 16441 case OMPC_dynamic_allocators: 16442 case OMPC_atomic_default_mem_order: 16443 case OMPC_device_type: 16444 case OMPC_match: 16445 case OMPC_nontemporal: 16446 case OMPC_order: 16447 case OMPC_destroy: 16448 case OMPC_novariants: 16449 case OMPC_nocontext: 16450 case OMPC_detach: 16451 case OMPC_inclusive: 16452 case OMPC_exclusive: 16453 case OMPC_uses_allocators: 16454 case OMPC_affinity: 16455 case OMPC_when: 16456 case OMPC_bind: 16457 default: 16458 llvm_unreachable("Clause is not allowed."); 16459 } 16460 return Res; 16461 } 16462 16463 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 16464 OpenMPScheduleClauseModifier M2, 16465 SourceLocation M1Loc, SourceLocation M2Loc) { 16466 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 16467 SmallVector<unsigned, 2> Excluded; 16468 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 16469 Excluded.push_back(M2); 16470 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 16471 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 16472 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 16473 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 16474 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 16475 << getListOfPossibleValues(OMPC_schedule, 16476 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 16477 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 16478 Excluded) 16479 << getOpenMPClauseName(OMPC_schedule); 16480 return true; 16481 } 16482 return false; 16483 } 16484 16485 OMPClause *Sema::ActOnOpenMPScheduleClause( 16486 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 16487 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 16488 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 16489 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 16490 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 16491 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 16492 return nullptr; 16493 // OpenMP, 2.7.1, Loop Construct, Restrictions 16494 // Either the monotonic modifier or the nonmonotonic modifier can be specified 16495 // but not both. 16496 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 16497 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 16498 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 16499 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 16500 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 16501 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 16502 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 16503 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 16504 return nullptr; 16505 } 16506 if (Kind == OMPC_SCHEDULE_unknown) { 16507 std::string Values; 16508 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 16509 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 16510 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 16511 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 16512 Exclude); 16513 } else { 16514 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 16515 /*Last=*/OMPC_SCHEDULE_unknown); 16516 } 16517 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 16518 << Values << getOpenMPClauseName(OMPC_schedule); 16519 return nullptr; 16520 } 16521 // OpenMP, 2.7.1, Loop Construct, Restrictions 16522 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 16523 // schedule(guided). 16524 // OpenMP 5.0 does not have this restriction. 16525 if (LangOpts.OpenMP < 50 && 16526 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 16527 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 16528 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 16529 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 16530 diag::err_omp_schedule_nonmonotonic_static); 16531 return nullptr; 16532 } 16533 Expr *ValExpr = ChunkSize; 16534 Stmt *HelperValStmt = nullptr; 16535 if (ChunkSize) { 16536 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 16537 !ChunkSize->isInstantiationDependent() && 16538 !ChunkSize->containsUnexpandedParameterPack()) { 16539 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 16540 ExprResult Val = 16541 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 16542 if (Val.isInvalid()) 16543 return nullptr; 16544 16545 ValExpr = Val.get(); 16546 16547 // OpenMP [2.7.1, Restrictions] 16548 // chunk_size must be a loop invariant integer expression with a positive 16549 // value. 16550 if (Optional<llvm::APSInt> Result = 16551 ValExpr->getIntegerConstantExpr(Context)) { 16552 if (Result->isSigned() && !Result->isStrictlyPositive()) { 16553 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 16554 << "schedule" << 1 << ChunkSize->getSourceRange(); 16555 return nullptr; 16556 } 16557 } else if (getOpenMPCaptureRegionForClause( 16558 DSAStack->getCurrentDirective(), OMPC_schedule, 16559 LangOpts.OpenMP) != OMPD_unknown && 16560 !CurContext->isDependentContext()) { 16561 ValExpr = MakeFullExpr(ValExpr).get(); 16562 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 16563 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 16564 HelperValStmt = buildPreInits(Context, Captures); 16565 } 16566 } 16567 } 16568 16569 return new (Context) 16570 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 16571 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 16572 } 16573 16574 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 16575 SourceLocation StartLoc, 16576 SourceLocation EndLoc) { 16577 OMPClause *Res = nullptr; 16578 switch (Kind) { 16579 case OMPC_ordered: 16580 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 16581 break; 16582 case OMPC_nowait: 16583 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 16584 break; 16585 case OMPC_untied: 16586 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 16587 break; 16588 case OMPC_mergeable: 16589 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 16590 break; 16591 case OMPC_read: 16592 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 16593 break; 16594 case OMPC_write: 16595 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 16596 break; 16597 case OMPC_update: 16598 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 16599 break; 16600 case OMPC_capture: 16601 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 16602 break; 16603 case OMPC_compare: 16604 Res = ActOnOpenMPCompareClause(StartLoc, EndLoc); 16605 break; 16606 case OMPC_seq_cst: 16607 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 16608 break; 16609 case OMPC_acq_rel: 16610 Res = ActOnOpenMPAcqRelClause(StartLoc, EndLoc); 16611 break; 16612 case OMPC_acquire: 16613 Res = ActOnOpenMPAcquireClause(StartLoc, EndLoc); 16614 break; 16615 case OMPC_release: 16616 Res = ActOnOpenMPReleaseClause(StartLoc, EndLoc); 16617 break; 16618 case OMPC_relaxed: 16619 Res = ActOnOpenMPRelaxedClause(StartLoc, EndLoc); 16620 break; 16621 case OMPC_threads: 16622 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 16623 break; 16624 case OMPC_simd: 16625 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 16626 break; 16627 case OMPC_nogroup: 16628 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 16629 break; 16630 case OMPC_unified_address: 16631 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 16632 break; 16633 case OMPC_unified_shared_memory: 16634 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 16635 break; 16636 case OMPC_reverse_offload: 16637 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 16638 break; 16639 case OMPC_dynamic_allocators: 16640 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 16641 break; 16642 case OMPC_destroy: 16643 Res = ActOnOpenMPDestroyClause(/*InteropVar=*/nullptr, StartLoc, 16644 /*LParenLoc=*/SourceLocation(), 16645 /*VarLoc=*/SourceLocation(), EndLoc); 16646 break; 16647 case OMPC_full: 16648 Res = ActOnOpenMPFullClause(StartLoc, EndLoc); 16649 break; 16650 case OMPC_partial: 16651 Res = ActOnOpenMPPartialClause(nullptr, StartLoc, /*LParenLoc=*/{}, EndLoc); 16652 break; 16653 case OMPC_if: 16654 case OMPC_final: 16655 case OMPC_num_threads: 16656 case OMPC_safelen: 16657 case OMPC_simdlen: 16658 case OMPC_sizes: 16659 case OMPC_allocator: 16660 case OMPC_collapse: 16661 case OMPC_schedule: 16662 case OMPC_private: 16663 case OMPC_firstprivate: 16664 case OMPC_lastprivate: 16665 case OMPC_shared: 16666 case OMPC_reduction: 16667 case OMPC_task_reduction: 16668 case OMPC_in_reduction: 16669 case OMPC_linear: 16670 case OMPC_aligned: 16671 case OMPC_copyin: 16672 case OMPC_copyprivate: 16673 case OMPC_default: 16674 case OMPC_proc_bind: 16675 case OMPC_threadprivate: 16676 case OMPC_allocate: 16677 case OMPC_flush: 16678 case OMPC_depobj: 16679 case OMPC_depend: 16680 case OMPC_device: 16681 case OMPC_map: 16682 case OMPC_num_teams: 16683 case OMPC_thread_limit: 16684 case OMPC_priority: 16685 case OMPC_grainsize: 16686 case OMPC_num_tasks: 16687 case OMPC_hint: 16688 case OMPC_dist_schedule: 16689 case OMPC_defaultmap: 16690 case OMPC_unknown: 16691 case OMPC_uniform: 16692 case OMPC_to: 16693 case OMPC_from: 16694 case OMPC_use_device_ptr: 16695 case OMPC_use_device_addr: 16696 case OMPC_is_device_ptr: 16697 case OMPC_has_device_addr: 16698 case OMPC_atomic_default_mem_order: 16699 case OMPC_device_type: 16700 case OMPC_match: 16701 case OMPC_nontemporal: 16702 case OMPC_order: 16703 case OMPC_novariants: 16704 case OMPC_nocontext: 16705 case OMPC_detach: 16706 case OMPC_inclusive: 16707 case OMPC_exclusive: 16708 case OMPC_uses_allocators: 16709 case OMPC_affinity: 16710 case OMPC_when: 16711 default: 16712 llvm_unreachable("Clause is not allowed."); 16713 } 16714 return Res; 16715 } 16716 16717 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 16718 SourceLocation EndLoc) { 16719 DSAStack->setNowaitRegion(); 16720 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 16721 } 16722 16723 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 16724 SourceLocation EndLoc) { 16725 DSAStack->setUntiedRegion(); 16726 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 16727 } 16728 16729 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 16730 SourceLocation EndLoc) { 16731 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 16732 } 16733 16734 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 16735 SourceLocation EndLoc) { 16736 return new (Context) OMPReadClause(StartLoc, EndLoc); 16737 } 16738 16739 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 16740 SourceLocation EndLoc) { 16741 return new (Context) OMPWriteClause(StartLoc, EndLoc); 16742 } 16743 16744 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 16745 SourceLocation EndLoc) { 16746 return OMPUpdateClause::Create(Context, StartLoc, EndLoc); 16747 } 16748 16749 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 16750 SourceLocation EndLoc) { 16751 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 16752 } 16753 16754 OMPClause *Sema::ActOnOpenMPCompareClause(SourceLocation StartLoc, 16755 SourceLocation EndLoc) { 16756 return new (Context) OMPCompareClause(StartLoc, EndLoc); 16757 } 16758 16759 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 16760 SourceLocation EndLoc) { 16761 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 16762 } 16763 16764 OMPClause *Sema::ActOnOpenMPAcqRelClause(SourceLocation StartLoc, 16765 SourceLocation EndLoc) { 16766 return new (Context) OMPAcqRelClause(StartLoc, EndLoc); 16767 } 16768 16769 OMPClause *Sema::ActOnOpenMPAcquireClause(SourceLocation StartLoc, 16770 SourceLocation EndLoc) { 16771 return new (Context) OMPAcquireClause(StartLoc, EndLoc); 16772 } 16773 16774 OMPClause *Sema::ActOnOpenMPReleaseClause(SourceLocation StartLoc, 16775 SourceLocation EndLoc) { 16776 return new (Context) OMPReleaseClause(StartLoc, EndLoc); 16777 } 16778 16779 OMPClause *Sema::ActOnOpenMPRelaxedClause(SourceLocation StartLoc, 16780 SourceLocation EndLoc) { 16781 return new (Context) OMPRelaxedClause(StartLoc, EndLoc); 16782 } 16783 16784 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 16785 SourceLocation EndLoc) { 16786 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 16787 } 16788 16789 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 16790 SourceLocation EndLoc) { 16791 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 16792 } 16793 16794 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 16795 SourceLocation EndLoc) { 16796 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 16797 } 16798 16799 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 16800 SourceLocation EndLoc) { 16801 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 16802 } 16803 16804 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 16805 SourceLocation EndLoc) { 16806 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 16807 } 16808 16809 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 16810 SourceLocation EndLoc) { 16811 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 16812 } 16813 16814 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 16815 SourceLocation EndLoc) { 16816 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 16817 } 16818 16819 StmtResult Sema::ActOnOpenMPInteropDirective(ArrayRef<OMPClause *> Clauses, 16820 SourceLocation StartLoc, 16821 SourceLocation EndLoc) { 16822 16823 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 16824 // At least one action-clause must appear on a directive. 16825 if (!hasClauses(Clauses, OMPC_init, OMPC_use, OMPC_destroy, OMPC_nowait)) { 16826 StringRef Expected = "'init', 'use', 'destroy', or 'nowait'"; 16827 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 16828 << Expected << getOpenMPDirectiveName(OMPD_interop); 16829 return StmtError(); 16830 } 16831 16832 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 16833 // A depend clause can only appear on the directive if a targetsync 16834 // interop-type is present or the interop-var was initialized with 16835 // the targetsync interop-type. 16836 16837 // If there is any 'init' clause diagnose if there is no 'init' clause with 16838 // interop-type of 'targetsync'. Cases involving other directives cannot be 16839 // diagnosed. 16840 const OMPDependClause *DependClause = nullptr; 16841 bool HasInitClause = false; 16842 bool IsTargetSync = false; 16843 for (const OMPClause *C : Clauses) { 16844 if (IsTargetSync) 16845 break; 16846 if (const auto *InitClause = dyn_cast<OMPInitClause>(C)) { 16847 HasInitClause = true; 16848 if (InitClause->getIsTargetSync()) 16849 IsTargetSync = true; 16850 } else if (const auto *DC = dyn_cast<OMPDependClause>(C)) { 16851 DependClause = DC; 16852 } 16853 } 16854 if (DependClause && HasInitClause && !IsTargetSync) { 16855 Diag(DependClause->getBeginLoc(), diag::err_omp_interop_bad_depend_clause); 16856 return StmtError(); 16857 } 16858 16859 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 16860 // Each interop-var may be specified for at most one action-clause of each 16861 // interop construct. 16862 llvm::SmallPtrSet<const VarDecl *, 4> InteropVars; 16863 for (const OMPClause *C : Clauses) { 16864 OpenMPClauseKind ClauseKind = C->getClauseKind(); 16865 const DeclRefExpr *DRE = nullptr; 16866 SourceLocation VarLoc; 16867 16868 if (ClauseKind == OMPC_init) { 16869 const auto *IC = cast<OMPInitClause>(C); 16870 VarLoc = IC->getVarLoc(); 16871 DRE = dyn_cast_or_null<DeclRefExpr>(IC->getInteropVar()); 16872 } else if (ClauseKind == OMPC_use) { 16873 const auto *UC = cast<OMPUseClause>(C); 16874 VarLoc = UC->getVarLoc(); 16875 DRE = dyn_cast_or_null<DeclRefExpr>(UC->getInteropVar()); 16876 } else if (ClauseKind == OMPC_destroy) { 16877 const auto *DC = cast<OMPDestroyClause>(C); 16878 VarLoc = DC->getVarLoc(); 16879 DRE = dyn_cast_or_null<DeclRefExpr>(DC->getInteropVar()); 16880 } 16881 16882 if (!DRE) 16883 continue; 16884 16885 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 16886 if (!InteropVars.insert(VD->getCanonicalDecl()).second) { 16887 Diag(VarLoc, diag::err_omp_interop_var_multiple_actions) << VD; 16888 return StmtError(); 16889 } 16890 } 16891 } 16892 16893 return OMPInteropDirective::Create(Context, StartLoc, EndLoc, Clauses); 16894 } 16895 16896 static bool isValidInteropVariable(Sema &SemaRef, Expr *InteropVarExpr, 16897 SourceLocation VarLoc, 16898 OpenMPClauseKind Kind) { 16899 if (InteropVarExpr->isValueDependent() || InteropVarExpr->isTypeDependent() || 16900 InteropVarExpr->isInstantiationDependent() || 16901 InteropVarExpr->containsUnexpandedParameterPack()) 16902 return true; 16903 16904 const auto *DRE = dyn_cast<DeclRefExpr>(InteropVarExpr); 16905 if (!DRE || !isa<VarDecl>(DRE->getDecl())) { 16906 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) << 0; 16907 return false; 16908 } 16909 16910 // Interop variable should be of type omp_interop_t. 16911 bool HasError = false; 16912 QualType InteropType; 16913 LookupResult Result(SemaRef, &SemaRef.Context.Idents.get("omp_interop_t"), 16914 VarLoc, Sema::LookupOrdinaryName); 16915 if (SemaRef.LookupName(Result, SemaRef.getCurScope())) { 16916 NamedDecl *ND = Result.getFoundDecl(); 16917 if (const auto *TD = dyn_cast<TypeDecl>(ND)) { 16918 InteropType = QualType(TD->getTypeForDecl(), 0); 16919 } else { 16920 HasError = true; 16921 } 16922 } else { 16923 HasError = true; 16924 } 16925 16926 if (HasError) { 16927 SemaRef.Diag(VarLoc, diag::err_omp_implied_type_not_found) 16928 << "omp_interop_t"; 16929 return false; 16930 } 16931 16932 QualType VarType = InteropVarExpr->getType().getUnqualifiedType(); 16933 if (!SemaRef.Context.hasSameType(InteropType, VarType)) { 16934 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_wrong_type); 16935 return false; 16936 } 16937 16938 // OpenMP 5.1 [2.15.1, interop Construct, Restrictions] 16939 // The interop-var passed to init or destroy must be non-const. 16940 if ((Kind == OMPC_init || Kind == OMPC_destroy) && 16941 isConstNotMutableType(SemaRef, InteropVarExpr->getType())) { 16942 SemaRef.Diag(VarLoc, diag::err_omp_interop_variable_expected) 16943 << /*non-const*/ 1; 16944 return false; 16945 } 16946 return true; 16947 } 16948 16949 OMPClause * 16950 Sema::ActOnOpenMPInitClause(Expr *InteropVar, ArrayRef<Expr *> PrefExprs, 16951 bool IsTarget, bool IsTargetSync, 16952 SourceLocation StartLoc, SourceLocation LParenLoc, 16953 SourceLocation VarLoc, SourceLocation EndLoc) { 16954 16955 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_init)) 16956 return nullptr; 16957 16958 // Check prefer_type values. These foreign-runtime-id values are either 16959 // string literals or constant integral expressions. 16960 for (const Expr *E : PrefExprs) { 16961 if (E->isValueDependent() || E->isTypeDependent() || 16962 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 16963 continue; 16964 if (E->isIntegerConstantExpr(Context)) 16965 continue; 16966 if (isa<StringLiteral>(E)) 16967 continue; 16968 Diag(E->getExprLoc(), diag::err_omp_interop_prefer_type); 16969 return nullptr; 16970 } 16971 16972 return OMPInitClause::Create(Context, InteropVar, PrefExprs, IsTarget, 16973 IsTargetSync, StartLoc, LParenLoc, VarLoc, 16974 EndLoc); 16975 } 16976 16977 OMPClause *Sema::ActOnOpenMPUseClause(Expr *InteropVar, SourceLocation StartLoc, 16978 SourceLocation LParenLoc, 16979 SourceLocation VarLoc, 16980 SourceLocation EndLoc) { 16981 16982 if (!isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_use)) 16983 return nullptr; 16984 16985 return new (Context) 16986 OMPUseClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 16987 } 16988 16989 OMPClause *Sema::ActOnOpenMPDestroyClause(Expr *InteropVar, 16990 SourceLocation StartLoc, 16991 SourceLocation LParenLoc, 16992 SourceLocation VarLoc, 16993 SourceLocation EndLoc) { 16994 if (InteropVar && 16995 !isValidInteropVariable(*this, InteropVar, VarLoc, OMPC_destroy)) 16996 return nullptr; 16997 16998 return new (Context) 16999 OMPDestroyClause(InteropVar, StartLoc, LParenLoc, VarLoc, EndLoc); 17000 } 17001 17002 OMPClause *Sema::ActOnOpenMPNovariantsClause(Expr *Condition, 17003 SourceLocation StartLoc, 17004 SourceLocation LParenLoc, 17005 SourceLocation EndLoc) { 17006 Expr *ValExpr = Condition; 17007 Stmt *HelperValStmt = nullptr; 17008 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17009 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 17010 !Condition->isInstantiationDependent() && 17011 !Condition->containsUnexpandedParameterPack()) { 17012 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 17013 if (Val.isInvalid()) 17014 return nullptr; 17015 17016 ValExpr = MakeFullExpr(Val.get()).get(); 17017 17018 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17019 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_novariants, 17020 LangOpts.OpenMP); 17021 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17022 ValExpr = MakeFullExpr(ValExpr).get(); 17023 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17024 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17025 HelperValStmt = buildPreInits(Context, Captures); 17026 } 17027 } 17028 17029 return new (Context) OMPNovariantsClause( 17030 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 17031 } 17032 17033 OMPClause *Sema::ActOnOpenMPNocontextClause(Expr *Condition, 17034 SourceLocation StartLoc, 17035 SourceLocation LParenLoc, 17036 SourceLocation EndLoc) { 17037 Expr *ValExpr = Condition; 17038 Stmt *HelperValStmt = nullptr; 17039 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 17040 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 17041 !Condition->isInstantiationDependent() && 17042 !Condition->containsUnexpandedParameterPack()) { 17043 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 17044 if (Val.isInvalid()) 17045 return nullptr; 17046 17047 ValExpr = MakeFullExpr(Val.get()).get(); 17048 17049 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17050 CaptureRegion = 17051 getOpenMPCaptureRegionForClause(DKind, OMPC_nocontext, LangOpts.OpenMP); 17052 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17053 ValExpr = MakeFullExpr(ValExpr).get(); 17054 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17055 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17056 HelperValStmt = buildPreInits(Context, Captures); 17057 } 17058 } 17059 17060 return new (Context) OMPNocontextClause(ValExpr, HelperValStmt, CaptureRegion, 17061 StartLoc, LParenLoc, EndLoc); 17062 } 17063 17064 OMPClause *Sema::ActOnOpenMPFilterClause(Expr *ThreadID, 17065 SourceLocation StartLoc, 17066 SourceLocation LParenLoc, 17067 SourceLocation EndLoc) { 17068 Expr *ValExpr = ThreadID; 17069 Stmt *HelperValStmt = nullptr; 17070 17071 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 17072 OpenMPDirectiveKind CaptureRegion = 17073 getOpenMPCaptureRegionForClause(DKind, OMPC_filter, LangOpts.OpenMP); 17074 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 17075 ValExpr = MakeFullExpr(ValExpr).get(); 17076 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 17077 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 17078 HelperValStmt = buildPreInits(Context, Captures); 17079 } 17080 17081 return new (Context) OMPFilterClause(ValExpr, HelperValStmt, CaptureRegion, 17082 StartLoc, LParenLoc, EndLoc); 17083 } 17084 17085 OMPClause *Sema::ActOnOpenMPVarListClause(OpenMPClauseKind Kind, 17086 ArrayRef<Expr *> VarList, 17087 const OMPVarListLocTy &Locs, 17088 OpenMPVarListDataTy &Data) { 17089 SourceLocation StartLoc = Locs.StartLoc; 17090 SourceLocation LParenLoc = Locs.LParenLoc; 17091 SourceLocation EndLoc = Locs.EndLoc; 17092 OMPClause *Res = nullptr; 17093 int ExtraModifier = Data.ExtraModifier; 17094 SourceLocation ExtraModifierLoc = Data.ExtraModifierLoc; 17095 SourceLocation ColonLoc = Data.ColonLoc; 17096 switch (Kind) { 17097 case OMPC_private: 17098 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17099 break; 17100 case OMPC_firstprivate: 17101 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17102 break; 17103 case OMPC_lastprivate: 17104 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LASTPRIVATE_unknown && 17105 "Unexpected lastprivate modifier."); 17106 Res = ActOnOpenMPLastprivateClause( 17107 VarList, static_cast<OpenMPLastprivateModifier>(ExtraModifier), 17108 ExtraModifierLoc, ColonLoc, StartLoc, LParenLoc, EndLoc); 17109 break; 17110 case OMPC_shared: 17111 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 17112 break; 17113 case OMPC_reduction: 17114 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_REDUCTION_unknown && 17115 "Unexpected lastprivate modifier."); 17116 Res = ActOnOpenMPReductionClause( 17117 VarList, static_cast<OpenMPReductionClauseModifier>(ExtraModifier), 17118 StartLoc, LParenLoc, ExtraModifierLoc, ColonLoc, EndLoc, 17119 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17120 break; 17121 case OMPC_task_reduction: 17122 Res = ActOnOpenMPTaskReductionClause( 17123 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, 17124 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17125 break; 17126 case OMPC_in_reduction: 17127 Res = ActOnOpenMPInReductionClause( 17128 VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, 17129 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId); 17130 break; 17131 case OMPC_linear: 17132 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_LINEAR_unknown && 17133 "Unexpected linear modifier."); 17134 Res = ActOnOpenMPLinearClause( 17135 VarList, Data.DepModOrTailExpr, StartLoc, LParenLoc, 17136 static_cast<OpenMPLinearClauseKind>(ExtraModifier), ExtraModifierLoc, 17137 ColonLoc, EndLoc); 17138 break; 17139 case OMPC_aligned: 17140 Res = ActOnOpenMPAlignedClause(VarList, Data.DepModOrTailExpr, StartLoc, 17141 LParenLoc, ColonLoc, EndLoc); 17142 break; 17143 case OMPC_copyin: 17144 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 17145 break; 17146 case OMPC_copyprivate: 17147 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 17148 break; 17149 case OMPC_flush: 17150 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 17151 break; 17152 case OMPC_depend: 17153 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_DEPEND_unknown && 17154 "Unexpected depend modifier."); 17155 Res = ActOnOpenMPDependClause( 17156 {static_cast<OpenMPDependClauseKind>(ExtraModifier), ExtraModifierLoc, 17157 ColonLoc, Data.OmpAllMemoryLoc}, 17158 Data.DepModOrTailExpr, VarList, StartLoc, LParenLoc, EndLoc); 17159 break; 17160 case OMPC_map: 17161 assert(0 <= ExtraModifier && ExtraModifier <= OMPC_MAP_unknown && 17162 "Unexpected map modifier."); 17163 Res = ActOnOpenMPMapClause( 17164 Data.MapTypeModifiers, Data.MapTypeModifiersLoc, 17165 Data.ReductionOrMapperIdScopeSpec, Data.ReductionOrMapperId, 17166 static_cast<OpenMPMapClauseKind>(ExtraModifier), Data.IsMapTypeImplicit, 17167 ExtraModifierLoc, ColonLoc, VarList, Locs); 17168 break; 17169 case OMPC_to: 17170 Res = 17171 ActOnOpenMPToClause(Data.MotionModifiers, Data.MotionModifiersLoc, 17172 Data.ReductionOrMapperIdScopeSpec, 17173 Data.ReductionOrMapperId, ColonLoc, VarList, Locs); 17174 break; 17175 case OMPC_from: 17176 Res = ActOnOpenMPFromClause(Data.MotionModifiers, Data.MotionModifiersLoc, 17177 Data.ReductionOrMapperIdScopeSpec, 17178 Data.ReductionOrMapperId, ColonLoc, VarList, 17179 Locs); 17180 break; 17181 case OMPC_use_device_ptr: 17182 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 17183 break; 17184 case OMPC_use_device_addr: 17185 Res = ActOnOpenMPUseDeviceAddrClause(VarList, Locs); 17186 break; 17187 case OMPC_is_device_ptr: 17188 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 17189 break; 17190 case OMPC_has_device_addr: 17191 Res = ActOnOpenMPHasDeviceAddrClause(VarList, Locs); 17192 break; 17193 case OMPC_allocate: 17194 Res = ActOnOpenMPAllocateClause(Data.DepModOrTailExpr, VarList, StartLoc, 17195 LParenLoc, ColonLoc, EndLoc); 17196 break; 17197 case OMPC_nontemporal: 17198 Res = ActOnOpenMPNontemporalClause(VarList, StartLoc, LParenLoc, EndLoc); 17199 break; 17200 case OMPC_inclusive: 17201 Res = ActOnOpenMPInclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 17202 break; 17203 case OMPC_exclusive: 17204 Res = ActOnOpenMPExclusiveClause(VarList, StartLoc, LParenLoc, EndLoc); 17205 break; 17206 case OMPC_affinity: 17207 Res = ActOnOpenMPAffinityClause(StartLoc, LParenLoc, ColonLoc, EndLoc, 17208 Data.DepModOrTailExpr, VarList); 17209 break; 17210 case OMPC_if: 17211 case OMPC_depobj: 17212 case OMPC_final: 17213 case OMPC_num_threads: 17214 case OMPC_safelen: 17215 case OMPC_simdlen: 17216 case OMPC_sizes: 17217 case OMPC_allocator: 17218 case OMPC_collapse: 17219 case OMPC_default: 17220 case OMPC_proc_bind: 17221 case OMPC_schedule: 17222 case OMPC_ordered: 17223 case OMPC_nowait: 17224 case OMPC_untied: 17225 case OMPC_mergeable: 17226 case OMPC_threadprivate: 17227 case OMPC_read: 17228 case OMPC_write: 17229 case OMPC_update: 17230 case OMPC_capture: 17231 case OMPC_compare: 17232 case OMPC_seq_cst: 17233 case OMPC_acq_rel: 17234 case OMPC_acquire: 17235 case OMPC_release: 17236 case OMPC_relaxed: 17237 case OMPC_device: 17238 case OMPC_threads: 17239 case OMPC_simd: 17240 case OMPC_num_teams: 17241 case OMPC_thread_limit: 17242 case OMPC_priority: 17243 case OMPC_grainsize: 17244 case OMPC_nogroup: 17245 case OMPC_num_tasks: 17246 case OMPC_hint: 17247 case OMPC_dist_schedule: 17248 case OMPC_defaultmap: 17249 case OMPC_unknown: 17250 case OMPC_uniform: 17251 case OMPC_unified_address: 17252 case OMPC_unified_shared_memory: 17253 case OMPC_reverse_offload: 17254 case OMPC_dynamic_allocators: 17255 case OMPC_atomic_default_mem_order: 17256 case OMPC_device_type: 17257 case OMPC_match: 17258 case OMPC_order: 17259 case OMPC_destroy: 17260 case OMPC_novariants: 17261 case OMPC_nocontext: 17262 case OMPC_detach: 17263 case OMPC_uses_allocators: 17264 case OMPC_when: 17265 case OMPC_bind: 17266 default: 17267 llvm_unreachable("Clause is not allowed."); 17268 } 17269 return Res; 17270 } 17271 17272 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 17273 ExprObjectKind OK, SourceLocation Loc) { 17274 ExprResult Res = BuildDeclRefExpr( 17275 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 17276 if (!Res.isUsable()) 17277 return ExprError(); 17278 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 17279 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 17280 if (!Res.isUsable()) 17281 return ExprError(); 17282 } 17283 if (VK != VK_LValue && Res.get()->isGLValue()) { 17284 Res = DefaultLvalueConversion(Res.get()); 17285 if (!Res.isUsable()) 17286 return ExprError(); 17287 } 17288 return Res; 17289 } 17290 17291 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 17292 SourceLocation StartLoc, 17293 SourceLocation LParenLoc, 17294 SourceLocation EndLoc) { 17295 SmallVector<Expr *, 8> Vars; 17296 SmallVector<Expr *, 8> PrivateCopies; 17297 for (Expr *RefExpr : VarList) { 17298 assert(RefExpr && "NULL expr in OpenMP private clause."); 17299 SourceLocation ELoc; 17300 SourceRange ERange; 17301 Expr *SimpleRefExpr = RefExpr; 17302 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17303 if (Res.second) { 17304 // It will be analyzed later. 17305 Vars.push_back(RefExpr); 17306 PrivateCopies.push_back(nullptr); 17307 } 17308 ValueDecl *D = Res.first; 17309 if (!D) 17310 continue; 17311 17312 QualType Type = D->getType(); 17313 auto *VD = dyn_cast<VarDecl>(D); 17314 17315 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 17316 // A variable that appears in a private clause must not have an incomplete 17317 // type or a reference type. 17318 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 17319 continue; 17320 Type = Type.getNonReferenceType(); 17321 17322 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 17323 // A variable that is privatized must not have a const-qualified type 17324 // unless it is of class type with a mutable member. This restriction does 17325 // not apply to the firstprivate clause. 17326 // 17327 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 17328 // A variable that appears in a private clause must not have a 17329 // const-qualified type unless it is of class type with a mutable member. 17330 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 17331 continue; 17332 17333 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17334 // in a Construct] 17335 // Variables with the predetermined data-sharing attributes may not be 17336 // listed in data-sharing attributes clauses, except for the cases 17337 // listed below. For these exceptions only, listing a predetermined 17338 // variable in a data-sharing attribute clause is allowed and overrides 17339 // the variable's predetermined data-sharing attributes. 17340 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17341 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 17342 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 17343 << getOpenMPClauseName(OMPC_private); 17344 reportOriginalDsa(*this, DSAStack, D, DVar); 17345 continue; 17346 } 17347 17348 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 17349 // Variably modified types are not supported for tasks. 17350 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 17351 isOpenMPTaskingDirective(CurrDir)) { 17352 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 17353 << getOpenMPClauseName(OMPC_private) << Type 17354 << getOpenMPDirectiveName(CurrDir); 17355 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 17356 VarDecl::DeclarationOnly; 17357 Diag(D->getLocation(), 17358 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17359 << D; 17360 continue; 17361 } 17362 17363 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17364 // A list item cannot appear in both a map clause and a data-sharing 17365 // attribute clause on the same construct 17366 // 17367 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17368 // A list item cannot appear in both a map clause and a data-sharing 17369 // attribute clause on the same construct unless the construct is a 17370 // combined construct. 17371 if ((LangOpts.OpenMP <= 45 && isOpenMPTargetExecutionDirective(CurrDir)) || 17372 CurrDir == OMPD_target) { 17373 OpenMPClauseKind ConflictKind; 17374 if (DSAStack->checkMappableExprComponentListsForDecl( 17375 VD, /*CurrentRegionOnly=*/true, 17376 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 17377 OpenMPClauseKind WhereFoundClauseKind) -> bool { 17378 ConflictKind = WhereFoundClauseKind; 17379 return true; 17380 })) { 17381 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17382 << getOpenMPClauseName(OMPC_private) 17383 << getOpenMPClauseName(ConflictKind) 17384 << getOpenMPDirectiveName(CurrDir); 17385 reportOriginalDsa(*this, DSAStack, D, DVar); 17386 continue; 17387 } 17388 } 17389 17390 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 17391 // A variable of class type (or array thereof) that appears in a private 17392 // clause requires an accessible, unambiguous default constructor for the 17393 // class type. 17394 // Generate helper private variable and initialize it with the default 17395 // value. The address of the original variable is replaced by the address of 17396 // the new private variable in CodeGen. This new variable is not added to 17397 // IdResolver, so the code in the OpenMP region uses original variable for 17398 // proper diagnostics. 17399 Type = Type.getUnqualifiedType(); 17400 VarDecl *VDPrivate = 17401 buildVarDecl(*this, ELoc, Type, D->getName(), 17402 D->hasAttrs() ? &D->getAttrs() : nullptr, 17403 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17404 ActOnUninitializedDecl(VDPrivate); 17405 if (VDPrivate->isInvalidDecl()) 17406 continue; 17407 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17408 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 17409 17410 DeclRefExpr *Ref = nullptr; 17411 if (!VD && !CurContext->isDependentContext()) 17412 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17413 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 17414 Vars.push_back((VD || CurContext->isDependentContext()) 17415 ? RefExpr->IgnoreParens() 17416 : Ref); 17417 PrivateCopies.push_back(VDPrivateRefExpr); 17418 } 17419 17420 if (Vars.empty()) 17421 return nullptr; 17422 17423 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 17424 PrivateCopies); 17425 } 17426 17427 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 17428 SourceLocation StartLoc, 17429 SourceLocation LParenLoc, 17430 SourceLocation EndLoc) { 17431 SmallVector<Expr *, 8> Vars; 17432 SmallVector<Expr *, 8> PrivateCopies; 17433 SmallVector<Expr *, 8> Inits; 17434 SmallVector<Decl *, 4> ExprCaptures; 17435 bool IsImplicitClause = 17436 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 17437 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 17438 17439 for (Expr *RefExpr : VarList) { 17440 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 17441 SourceLocation ELoc; 17442 SourceRange ERange; 17443 Expr *SimpleRefExpr = RefExpr; 17444 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17445 if (Res.second) { 17446 // It will be analyzed later. 17447 Vars.push_back(RefExpr); 17448 PrivateCopies.push_back(nullptr); 17449 Inits.push_back(nullptr); 17450 } 17451 ValueDecl *D = Res.first; 17452 if (!D) 17453 continue; 17454 17455 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 17456 QualType Type = D->getType(); 17457 auto *VD = dyn_cast<VarDecl>(D); 17458 17459 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 17460 // A variable that appears in a private clause must not have an incomplete 17461 // type or a reference type. 17462 if (RequireCompleteType(ELoc, Type, 17463 diag::err_omp_firstprivate_incomplete_type)) 17464 continue; 17465 Type = Type.getNonReferenceType(); 17466 17467 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 17468 // A variable of class type (or array thereof) that appears in a private 17469 // clause requires an accessible, unambiguous copy constructor for the 17470 // class type. 17471 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 17472 17473 // If an implicit firstprivate variable found it was checked already. 17474 DSAStackTy::DSAVarData TopDVar; 17475 if (!IsImplicitClause) { 17476 DSAStackTy::DSAVarData DVar = 17477 DSAStack->getTopDSA(D, /*FromParent=*/false); 17478 TopDVar = DVar; 17479 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 17480 bool IsConstant = ElemType.isConstant(Context); 17481 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 17482 // A list item that specifies a given variable may not appear in more 17483 // than one clause on the same directive, except that a variable may be 17484 // specified in both firstprivate and lastprivate clauses. 17485 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 17486 // A list item may appear in a firstprivate or lastprivate clause but not 17487 // both. 17488 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 17489 (isOpenMPDistributeDirective(CurrDir) || 17490 DVar.CKind != OMPC_lastprivate) && 17491 DVar.RefExpr) { 17492 Diag(ELoc, diag::err_omp_wrong_dsa) 17493 << getOpenMPClauseName(DVar.CKind) 17494 << getOpenMPClauseName(OMPC_firstprivate); 17495 reportOriginalDsa(*this, DSAStack, D, DVar); 17496 continue; 17497 } 17498 17499 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17500 // in a Construct] 17501 // Variables with the predetermined data-sharing attributes may not be 17502 // listed in data-sharing attributes clauses, except for the cases 17503 // listed below. For these exceptions only, listing a predetermined 17504 // variable in a data-sharing attribute clause is allowed and overrides 17505 // the variable's predetermined data-sharing attributes. 17506 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17507 // in a Construct, C/C++, p.2] 17508 // Variables with const-qualified type having no mutable member may be 17509 // listed in a firstprivate clause, even if they are static data members. 17510 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 17511 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 17512 Diag(ELoc, diag::err_omp_wrong_dsa) 17513 << getOpenMPClauseName(DVar.CKind) 17514 << getOpenMPClauseName(OMPC_firstprivate); 17515 reportOriginalDsa(*this, DSAStack, D, DVar); 17516 continue; 17517 } 17518 17519 // OpenMP [2.9.3.4, Restrictions, p.2] 17520 // A list item that is private within a parallel region must not appear 17521 // in a firstprivate clause on a worksharing construct if any of the 17522 // worksharing regions arising from the worksharing construct ever bind 17523 // to any of the parallel regions arising from the parallel construct. 17524 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 17525 // A list item that is private within a teams region must not appear in a 17526 // firstprivate clause on a distribute construct if any of the distribute 17527 // regions arising from the distribute construct ever bind to any of the 17528 // teams regions arising from the teams construct. 17529 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 17530 // A list item that appears in a reduction clause of a teams construct 17531 // must not appear in a firstprivate clause on a distribute construct if 17532 // any of the distribute regions arising from the distribute construct 17533 // ever bind to any of the teams regions arising from the teams construct. 17534 if ((isOpenMPWorksharingDirective(CurrDir) || 17535 isOpenMPDistributeDirective(CurrDir)) && 17536 !isOpenMPParallelDirective(CurrDir) && 17537 !isOpenMPTeamsDirective(CurrDir)) { 17538 DVar = DSAStack->getImplicitDSA(D, true); 17539 if (DVar.CKind != OMPC_shared && 17540 (isOpenMPParallelDirective(DVar.DKind) || 17541 isOpenMPTeamsDirective(DVar.DKind) || 17542 DVar.DKind == OMPD_unknown)) { 17543 Diag(ELoc, diag::err_omp_required_access) 17544 << getOpenMPClauseName(OMPC_firstprivate) 17545 << getOpenMPClauseName(OMPC_shared); 17546 reportOriginalDsa(*this, DSAStack, D, DVar); 17547 continue; 17548 } 17549 } 17550 // OpenMP [2.9.3.4, Restrictions, p.3] 17551 // A list item that appears in a reduction clause of a parallel construct 17552 // must not appear in a firstprivate clause on a worksharing or task 17553 // construct if any of the worksharing or task regions arising from the 17554 // worksharing or task construct ever bind to any of the parallel regions 17555 // arising from the parallel construct. 17556 // OpenMP [2.9.3.4, Restrictions, p.4] 17557 // A list item that appears in a reduction clause in worksharing 17558 // construct must not appear in a firstprivate clause in a task construct 17559 // encountered during execution of any of the worksharing regions arising 17560 // from the worksharing construct. 17561 if (isOpenMPTaskingDirective(CurrDir)) { 17562 DVar = DSAStack->hasInnermostDSA( 17563 D, 17564 [](OpenMPClauseKind C, bool AppliedToPointee) { 17565 return C == OMPC_reduction && !AppliedToPointee; 17566 }, 17567 [](OpenMPDirectiveKind K) { 17568 return isOpenMPParallelDirective(K) || 17569 isOpenMPWorksharingDirective(K) || 17570 isOpenMPTeamsDirective(K); 17571 }, 17572 /*FromParent=*/true); 17573 if (DVar.CKind == OMPC_reduction && 17574 (isOpenMPParallelDirective(DVar.DKind) || 17575 isOpenMPWorksharingDirective(DVar.DKind) || 17576 isOpenMPTeamsDirective(DVar.DKind))) { 17577 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 17578 << getOpenMPDirectiveName(DVar.DKind); 17579 reportOriginalDsa(*this, DSAStack, D, DVar); 17580 continue; 17581 } 17582 } 17583 17584 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 17585 // A list item cannot appear in both a map clause and a data-sharing 17586 // attribute clause on the same construct 17587 // 17588 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 17589 // A list item cannot appear in both a map clause and a data-sharing 17590 // attribute clause on the same construct unless the construct is a 17591 // combined construct. 17592 if ((LangOpts.OpenMP <= 45 && 17593 isOpenMPTargetExecutionDirective(CurrDir)) || 17594 CurrDir == OMPD_target) { 17595 OpenMPClauseKind ConflictKind; 17596 if (DSAStack->checkMappableExprComponentListsForDecl( 17597 VD, /*CurrentRegionOnly=*/true, 17598 [&ConflictKind]( 17599 OMPClauseMappableExprCommon::MappableExprComponentListRef, 17600 OpenMPClauseKind WhereFoundClauseKind) { 17601 ConflictKind = WhereFoundClauseKind; 17602 return true; 17603 })) { 17604 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 17605 << getOpenMPClauseName(OMPC_firstprivate) 17606 << getOpenMPClauseName(ConflictKind) 17607 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17608 reportOriginalDsa(*this, DSAStack, D, DVar); 17609 continue; 17610 } 17611 } 17612 } 17613 17614 // Variably modified types are not supported for tasks. 17615 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 17616 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 17617 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 17618 << getOpenMPClauseName(OMPC_firstprivate) << Type 17619 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 17620 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 17621 VarDecl::DeclarationOnly; 17622 Diag(D->getLocation(), 17623 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17624 << D; 17625 continue; 17626 } 17627 17628 Type = Type.getUnqualifiedType(); 17629 VarDecl *VDPrivate = 17630 buildVarDecl(*this, ELoc, Type, D->getName(), 17631 D->hasAttrs() ? &D->getAttrs() : nullptr, 17632 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 17633 // Generate helper private variable and initialize it with the value of the 17634 // original variable. The address of the original variable is replaced by 17635 // the address of the new private variable in the CodeGen. This new variable 17636 // is not added to IdResolver, so the code in the OpenMP region uses 17637 // original variable for proper diagnostics and variable capturing. 17638 Expr *VDInitRefExpr = nullptr; 17639 // For arrays generate initializer for single element and replace it by the 17640 // original array element in CodeGen. 17641 if (Type->isArrayType()) { 17642 VarDecl *VDInit = 17643 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 17644 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 17645 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 17646 ElemType = ElemType.getUnqualifiedType(); 17647 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 17648 ".firstprivate.temp"); 17649 InitializedEntity Entity = 17650 InitializedEntity::InitializeVariable(VDInitTemp); 17651 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 17652 17653 InitializationSequence InitSeq(*this, Entity, Kind, Init); 17654 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 17655 if (Result.isInvalid()) 17656 VDPrivate->setInvalidDecl(); 17657 else 17658 VDPrivate->setInit(Result.getAs<Expr>()); 17659 // Remove temp variable declaration. 17660 Context.Deallocate(VDInitTemp); 17661 } else { 17662 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 17663 ".firstprivate.temp"); 17664 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 17665 RefExpr->getExprLoc()); 17666 AddInitializerToDecl(VDPrivate, 17667 DefaultLvalueConversion(VDInitRefExpr).get(), 17668 /*DirectInit=*/false); 17669 } 17670 if (VDPrivate->isInvalidDecl()) { 17671 if (IsImplicitClause) { 17672 Diag(RefExpr->getExprLoc(), 17673 diag::note_omp_task_predetermined_firstprivate_here); 17674 } 17675 continue; 17676 } 17677 CurContext->addDecl(VDPrivate); 17678 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 17679 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 17680 RefExpr->getExprLoc()); 17681 DeclRefExpr *Ref = nullptr; 17682 if (!VD && !CurContext->isDependentContext()) { 17683 if (TopDVar.CKind == OMPC_lastprivate) { 17684 Ref = TopDVar.PrivateCopy; 17685 } else { 17686 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17687 if (!isOpenMPCapturedDecl(D)) 17688 ExprCaptures.push_back(Ref->getDecl()); 17689 } 17690 } 17691 if (!IsImplicitClause) 17692 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 17693 Vars.push_back((VD || CurContext->isDependentContext()) 17694 ? RefExpr->IgnoreParens() 17695 : Ref); 17696 PrivateCopies.push_back(VDPrivateRefExpr); 17697 Inits.push_back(VDInitRefExpr); 17698 } 17699 17700 if (Vars.empty()) 17701 return nullptr; 17702 17703 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17704 Vars, PrivateCopies, Inits, 17705 buildPreInits(Context, ExprCaptures)); 17706 } 17707 17708 OMPClause *Sema::ActOnOpenMPLastprivateClause( 17709 ArrayRef<Expr *> VarList, OpenMPLastprivateModifier LPKind, 17710 SourceLocation LPKindLoc, SourceLocation ColonLoc, SourceLocation StartLoc, 17711 SourceLocation LParenLoc, SourceLocation EndLoc) { 17712 if (LPKind == OMPC_LASTPRIVATE_unknown && LPKindLoc.isValid()) { 17713 assert(ColonLoc.isValid() && "Colon location must be valid."); 17714 Diag(LPKindLoc, diag::err_omp_unexpected_clause_value) 17715 << getListOfPossibleValues(OMPC_lastprivate, /*First=*/0, 17716 /*Last=*/OMPC_LASTPRIVATE_unknown) 17717 << getOpenMPClauseName(OMPC_lastprivate); 17718 return nullptr; 17719 } 17720 17721 SmallVector<Expr *, 8> Vars; 17722 SmallVector<Expr *, 8> SrcExprs; 17723 SmallVector<Expr *, 8> DstExprs; 17724 SmallVector<Expr *, 8> AssignmentOps; 17725 SmallVector<Decl *, 4> ExprCaptures; 17726 SmallVector<Expr *, 4> ExprPostUpdates; 17727 for (Expr *RefExpr : VarList) { 17728 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 17729 SourceLocation ELoc; 17730 SourceRange ERange; 17731 Expr *SimpleRefExpr = RefExpr; 17732 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17733 if (Res.second) { 17734 // It will be analyzed later. 17735 Vars.push_back(RefExpr); 17736 SrcExprs.push_back(nullptr); 17737 DstExprs.push_back(nullptr); 17738 AssignmentOps.push_back(nullptr); 17739 } 17740 ValueDecl *D = Res.first; 17741 if (!D) 17742 continue; 17743 17744 QualType Type = D->getType(); 17745 auto *VD = dyn_cast<VarDecl>(D); 17746 17747 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 17748 // A variable that appears in a lastprivate clause must not have an 17749 // incomplete type or a reference type. 17750 if (RequireCompleteType(ELoc, Type, 17751 diag::err_omp_lastprivate_incomplete_type)) 17752 continue; 17753 Type = Type.getNonReferenceType(); 17754 17755 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 17756 // A variable that is privatized must not have a const-qualified type 17757 // unless it is of class type with a mutable member. This restriction does 17758 // not apply to the firstprivate clause. 17759 // 17760 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 17761 // A variable that appears in a lastprivate clause must not have a 17762 // const-qualified type unless it is of class type with a mutable member. 17763 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 17764 continue; 17765 17766 // OpenMP 5.0 [2.19.4.5 lastprivate Clause, Restrictions] 17767 // A list item that appears in a lastprivate clause with the conditional 17768 // modifier must be a scalar variable. 17769 if (LPKind == OMPC_LASTPRIVATE_conditional && !Type->isScalarType()) { 17770 Diag(ELoc, diag::err_omp_lastprivate_conditional_non_scalar); 17771 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 17772 VarDecl::DeclarationOnly; 17773 Diag(D->getLocation(), 17774 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 17775 << D; 17776 continue; 17777 } 17778 17779 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 17780 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 17781 // in a Construct] 17782 // Variables with the predetermined data-sharing attributes may not be 17783 // listed in data-sharing attributes clauses, except for the cases 17784 // listed below. 17785 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 17786 // A list item may appear in a firstprivate or lastprivate clause but not 17787 // both. 17788 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17789 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 17790 (isOpenMPDistributeDirective(CurrDir) || 17791 DVar.CKind != OMPC_firstprivate) && 17792 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 17793 Diag(ELoc, diag::err_omp_wrong_dsa) 17794 << getOpenMPClauseName(DVar.CKind) 17795 << getOpenMPClauseName(OMPC_lastprivate); 17796 reportOriginalDsa(*this, DSAStack, D, DVar); 17797 continue; 17798 } 17799 17800 // OpenMP [2.14.3.5, Restrictions, p.2] 17801 // A list item that is private within a parallel region, or that appears in 17802 // the reduction clause of a parallel construct, must not appear in a 17803 // lastprivate clause on a worksharing construct if any of the corresponding 17804 // worksharing regions ever binds to any of the corresponding parallel 17805 // regions. 17806 DSAStackTy::DSAVarData TopDVar = DVar; 17807 if (isOpenMPWorksharingDirective(CurrDir) && 17808 !isOpenMPParallelDirective(CurrDir) && 17809 !isOpenMPTeamsDirective(CurrDir)) { 17810 DVar = DSAStack->getImplicitDSA(D, true); 17811 if (DVar.CKind != OMPC_shared) { 17812 Diag(ELoc, diag::err_omp_required_access) 17813 << getOpenMPClauseName(OMPC_lastprivate) 17814 << getOpenMPClauseName(OMPC_shared); 17815 reportOriginalDsa(*this, DSAStack, D, DVar); 17816 continue; 17817 } 17818 } 17819 17820 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 17821 // A variable of class type (or array thereof) that appears in a 17822 // lastprivate clause requires an accessible, unambiguous default 17823 // constructor for the class type, unless the list item is also specified 17824 // in a firstprivate clause. 17825 // A variable of class type (or array thereof) that appears in a 17826 // lastprivate clause requires an accessible, unambiguous copy assignment 17827 // operator for the class type. 17828 Type = Context.getBaseElementType(Type).getNonReferenceType(); 17829 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 17830 Type.getUnqualifiedType(), ".lastprivate.src", 17831 D->hasAttrs() ? &D->getAttrs() : nullptr); 17832 DeclRefExpr *PseudoSrcExpr = 17833 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 17834 VarDecl *DstVD = 17835 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 17836 D->hasAttrs() ? &D->getAttrs() : nullptr); 17837 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 17838 // For arrays generate assignment operation for single element and replace 17839 // it by the original array element in CodeGen. 17840 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 17841 PseudoDstExpr, PseudoSrcExpr); 17842 if (AssignmentOp.isInvalid()) 17843 continue; 17844 AssignmentOp = 17845 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 17846 if (AssignmentOp.isInvalid()) 17847 continue; 17848 17849 DeclRefExpr *Ref = nullptr; 17850 if (!VD && !CurContext->isDependentContext()) { 17851 if (TopDVar.CKind == OMPC_firstprivate) { 17852 Ref = TopDVar.PrivateCopy; 17853 } else { 17854 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 17855 if (!isOpenMPCapturedDecl(D)) 17856 ExprCaptures.push_back(Ref->getDecl()); 17857 } 17858 if ((TopDVar.CKind == OMPC_firstprivate && !TopDVar.PrivateCopy) || 17859 (!isOpenMPCapturedDecl(D) && 17860 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 17861 ExprResult RefRes = DefaultLvalueConversion(Ref); 17862 if (!RefRes.isUsable()) 17863 continue; 17864 ExprResult PostUpdateRes = 17865 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 17866 RefRes.get()); 17867 if (!PostUpdateRes.isUsable()) 17868 continue; 17869 ExprPostUpdates.push_back( 17870 IgnoredValueConversions(PostUpdateRes.get()).get()); 17871 } 17872 } 17873 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 17874 Vars.push_back((VD || CurContext->isDependentContext()) 17875 ? RefExpr->IgnoreParens() 17876 : Ref); 17877 SrcExprs.push_back(PseudoSrcExpr); 17878 DstExprs.push_back(PseudoDstExpr); 17879 AssignmentOps.push_back(AssignmentOp.get()); 17880 } 17881 17882 if (Vars.empty()) 17883 return nullptr; 17884 17885 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 17886 Vars, SrcExprs, DstExprs, AssignmentOps, 17887 LPKind, LPKindLoc, ColonLoc, 17888 buildPreInits(Context, ExprCaptures), 17889 buildPostUpdate(*this, ExprPostUpdates)); 17890 } 17891 17892 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 17893 SourceLocation StartLoc, 17894 SourceLocation LParenLoc, 17895 SourceLocation EndLoc) { 17896 SmallVector<Expr *, 8> Vars; 17897 for (Expr *RefExpr : VarList) { 17898 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 17899 SourceLocation ELoc; 17900 SourceRange ERange; 17901 Expr *SimpleRefExpr = RefExpr; 17902 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 17903 if (Res.second) { 17904 // It will be analyzed later. 17905 Vars.push_back(RefExpr); 17906 } 17907 ValueDecl *D = Res.first; 17908 if (!D) 17909 continue; 17910 17911 auto *VD = dyn_cast<VarDecl>(D); 17912 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 17913 // in a Construct] 17914 // Variables with the predetermined data-sharing attributes may not be 17915 // listed in data-sharing attributes clauses, except for the cases 17916 // listed below. For these exceptions only, listing a predetermined 17917 // variable in a data-sharing attribute clause is allowed and overrides 17918 // the variable's predetermined data-sharing attributes. 17919 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 17920 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 17921 DVar.RefExpr) { 17922 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 17923 << getOpenMPClauseName(OMPC_shared); 17924 reportOriginalDsa(*this, DSAStack, D, DVar); 17925 continue; 17926 } 17927 17928 DeclRefExpr *Ref = nullptr; 17929 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 17930 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 17931 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 17932 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 17933 ? RefExpr->IgnoreParens() 17934 : Ref); 17935 } 17936 17937 if (Vars.empty()) 17938 return nullptr; 17939 17940 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 17941 } 17942 17943 namespace { 17944 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 17945 DSAStackTy *Stack; 17946 17947 public: 17948 bool VisitDeclRefExpr(DeclRefExpr *E) { 17949 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 17950 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 17951 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 17952 return false; 17953 if (DVar.CKind != OMPC_unknown) 17954 return true; 17955 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 17956 VD, 17957 [](OpenMPClauseKind C, bool AppliedToPointee) { 17958 return isOpenMPPrivate(C) && !AppliedToPointee; 17959 }, 17960 [](OpenMPDirectiveKind) { return true; }, 17961 /*FromParent=*/true); 17962 return DVarPrivate.CKind != OMPC_unknown; 17963 } 17964 return false; 17965 } 17966 bool VisitStmt(Stmt *S) { 17967 for (Stmt *Child : S->children()) { 17968 if (Child && Visit(Child)) 17969 return true; 17970 } 17971 return false; 17972 } 17973 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 17974 }; 17975 } // namespace 17976 17977 namespace { 17978 // Transform MemberExpression for specified FieldDecl of current class to 17979 // DeclRefExpr to specified OMPCapturedExprDecl. 17980 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 17981 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 17982 ValueDecl *Field = nullptr; 17983 DeclRefExpr *CapturedExpr = nullptr; 17984 17985 public: 17986 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 17987 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 17988 17989 ExprResult TransformMemberExpr(MemberExpr *E) { 17990 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 17991 E->getMemberDecl() == Field) { 17992 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 17993 return CapturedExpr; 17994 } 17995 return BaseTransform::TransformMemberExpr(E); 17996 } 17997 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 17998 }; 17999 } // namespace 18000 18001 template <typename T, typename U> 18002 static T filterLookupForUDReductionAndMapper( 18003 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 18004 for (U &Set : Lookups) { 18005 for (auto *D : Set) { 18006 if (T Res = Gen(cast<ValueDecl>(D))) 18007 return Res; 18008 } 18009 } 18010 return T(); 18011 } 18012 18013 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 18014 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 18015 18016 for (auto RD : D->redecls()) { 18017 // Don't bother with extra checks if we already know this one isn't visible. 18018 if (RD == D) 18019 continue; 18020 18021 auto ND = cast<NamedDecl>(RD); 18022 if (LookupResult::isVisible(SemaRef, ND)) 18023 return ND; 18024 } 18025 18026 return nullptr; 18027 } 18028 18029 static void 18030 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 18031 SourceLocation Loc, QualType Ty, 18032 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 18033 // Find all of the associated namespaces and classes based on the 18034 // arguments we have. 18035 Sema::AssociatedNamespaceSet AssociatedNamespaces; 18036 Sema::AssociatedClassSet AssociatedClasses; 18037 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 18038 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 18039 AssociatedClasses); 18040 18041 // C++ [basic.lookup.argdep]p3: 18042 // Let X be the lookup set produced by unqualified lookup (3.4.1) 18043 // and let Y be the lookup set produced by argument dependent 18044 // lookup (defined as follows). If X contains [...] then Y is 18045 // empty. Otherwise Y is the set of declarations found in the 18046 // namespaces associated with the argument types as described 18047 // below. The set of declarations found by the lookup of the name 18048 // is the union of X and Y. 18049 // 18050 // Here, we compute Y and add its members to the overloaded 18051 // candidate set. 18052 for (auto *NS : AssociatedNamespaces) { 18053 // When considering an associated namespace, the lookup is the 18054 // same as the lookup performed when the associated namespace is 18055 // used as a qualifier (3.4.3.2) except that: 18056 // 18057 // -- Any using-directives in the associated namespace are 18058 // ignored. 18059 // 18060 // -- Any namespace-scope friend functions declared in 18061 // associated classes are visible within their respective 18062 // namespaces even if they are not visible during an ordinary 18063 // lookup (11.4). 18064 DeclContext::lookup_result R = NS->lookup(Id.getName()); 18065 for (auto *D : R) { 18066 auto *Underlying = D; 18067 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 18068 Underlying = USD->getTargetDecl(); 18069 18070 if (!isa<OMPDeclareReductionDecl>(Underlying) && 18071 !isa<OMPDeclareMapperDecl>(Underlying)) 18072 continue; 18073 18074 if (!SemaRef.isVisible(D)) { 18075 D = findAcceptableDecl(SemaRef, D); 18076 if (!D) 18077 continue; 18078 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 18079 Underlying = USD->getTargetDecl(); 18080 } 18081 Lookups.emplace_back(); 18082 Lookups.back().addDecl(Underlying); 18083 } 18084 } 18085 } 18086 18087 static ExprResult 18088 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 18089 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 18090 const DeclarationNameInfo &ReductionId, QualType Ty, 18091 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 18092 if (ReductionIdScopeSpec.isInvalid()) 18093 return ExprError(); 18094 SmallVector<UnresolvedSet<8>, 4> Lookups; 18095 if (S) { 18096 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 18097 Lookup.suppressDiagnostics(); 18098 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 18099 NamedDecl *D = Lookup.getRepresentativeDecl(); 18100 do { 18101 S = S->getParent(); 18102 } while (S && !S->isDeclScope(D)); 18103 if (S) 18104 S = S->getParent(); 18105 Lookups.emplace_back(); 18106 Lookups.back().append(Lookup.begin(), Lookup.end()); 18107 Lookup.clear(); 18108 } 18109 } else if (auto *ULE = 18110 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 18111 Lookups.push_back(UnresolvedSet<8>()); 18112 Decl *PrevD = nullptr; 18113 for (NamedDecl *D : ULE->decls()) { 18114 if (D == PrevD) 18115 Lookups.push_back(UnresolvedSet<8>()); 18116 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 18117 Lookups.back().addDecl(DRD); 18118 PrevD = D; 18119 } 18120 } 18121 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 18122 Ty->isInstantiationDependentType() || 18123 Ty->containsUnexpandedParameterPack() || 18124 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 18125 return !D->isInvalidDecl() && 18126 (D->getType()->isDependentType() || 18127 D->getType()->isInstantiationDependentType() || 18128 D->getType()->containsUnexpandedParameterPack()); 18129 })) { 18130 UnresolvedSet<8> ResSet; 18131 for (const UnresolvedSet<8> &Set : Lookups) { 18132 if (Set.empty()) 18133 continue; 18134 ResSet.append(Set.begin(), Set.end()); 18135 // The last item marks the end of all declarations at the specified scope. 18136 ResSet.addDecl(Set[Set.size() - 1]); 18137 } 18138 return UnresolvedLookupExpr::Create( 18139 SemaRef.Context, /*NamingClass=*/nullptr, 18140 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 18141 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 18142 } 18143 // Lookup inside the classes. 18144 // C++ [over.match.oper]p3: 18145 // For a unary operator @ with an operand of a type whose 18146 // cv-unqualified version is T1, and for a binary operator @ with 18147 // a left operand of a type whose cv-unqualified version is T1 and 18148 // a right operand of a type whose cv-unqualified version is T2, 18149 // three sets of candidate functions, designated member 18150 // candidates, non-member candidates and built-in candidates, are 18151 // constructed as follows: 18152 // -- If T1 is a complete class type or a class currently being 18153 // defined, the set of member candidates is the result of the 18154 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 18155 // the set of member candidates is empty. 18156 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 18157 Lookup.suppressDiagnostics(); 18158 if (const auto *TyRec = Ty->getAs<RecordType>()) { 18159 // Complete the type if it can be completed. 18160 // If the type is neither complete nor being defined, bail out now. 18161 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 18162 TyRec->getDecl()->getDefinition()) { 18163 Lookup.clear(); 18164 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 18165 if (Lookup.empty()) { 18166 Lookups.emplace_back(); 18167 Lookups.back().append(Lookup.begin(), Lookup.end()); 18168 } 18169 } 18170 } 18171 // Perform ADL. 18172 if (SemaRef.getLangOpts().CPlusPlus) 18173 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 18174 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 18175 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 18176 if (!D->isInvalidDecl() && 18177 SemaRef.Context.hasSameType(D->getType(), Ty)) 18178 return D; 18179 return nullptr; 18180 })) 18181 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 18182 VK_LValue, Loc); 18183 if (SemaRef.getLangOpts().CPlusPlus) { 18184 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 18185 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 18186 if (!D->isInvalidDecl() && 18187 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 18188 !Ty.isMoreQualifiedThan(D->getType())) 18189 return D; 18190 return nullptr; 18191 })) { 18192 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 18193 /*DetectVirtual=*/false); 18194 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 18195 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 18196 VD->getType().getUnqualifiedType()))) { 18197 if (SemaRef.CheckBaseClassAccess( 18198 Loc, VD->getType(), Ty, Paths.front(), 18199 /*DiagID=*/0) != Sema::AR_inaccessible) { 18200 SemaRef.BuildBasePathArray(Paths, BasePath); 18201 return SemaRef.BuildDeclRefExpr( 18202 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 18203 } 18204 } 18205 } 18206 } 18207 } 18208 if (ReductionIdScopeSpec.isSet()) { 18209 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) 18210 << Ty << Range; 18211 return ExprError(); 18212 } 18213 return ExprEmpty(); 18214 } 18215 18216 namespace { 18217 /// Data for the reduction-based clauses. 18218 struct ReductionData { 18219 /// List of original reduction items. 18220 SmallVector<Expr *, 8> Vars; 18221 /// List of private copies of the reduction items. 18222 SmallVector<Expr *, 8> Privates; 18223 /// LHS expressions for the reduction_op expressions. 18224 SmallVector<Expr *, 8> LHSs; 18225 /// RHS expressions for the reduction_op expressions. 18226 SmallVector<Expr *, 8> RHSs; 18227 /// Reduction operation expression. 18228 SmallVector<Expr *, 8> ReductionOps; 18229 /// inscan copy operation expressions. 18230 SmallVector<Expr *, 8> InscanCopyOps; 18231 /// inscan copy temp array expressions for prefix sums. 18232 SmallVector<Expr *, 8> InscanCopyArrayTemps; 18233 /// inscan copy temp array element expressions for prefix sums. 18234 SmallVector<Expr *, 8> InscanCopyArrayElems; 18235 /// Taskgroup descriptors for the corresponding reduction items in 18236 /// in_reduction clauses. 18237 SmallVector<Expr *, 8> TaskgroupDescriptors; 18238 /// List of captures for clause. 18239 SmallVector<Decl *, 4> ExprCaptures; 18240 /// List of postupdate expressions. 18241 SmallVector<Expr *, 4> ExprPostUpdates; 18242 /// Reduction modifier. 18243 unsigned RedModifier = 0; 18244 ReductionData() = delete; 18245 /// Reserves required memory for the reduction data. 18246 ReductionData(unsigned Size, unsigned Modifier = 0) : RedModifier(Modifier) { 18247 Vars.reserve(Size); 18248 Privates.reserve(Size); 18249 LHSs.reserve(Size); 18250 RHSs.reserve(Size); 18251 ReductionOps.reserve(Size); 18252 if (RedModifier == OMPC_REDUCTION_inscan) { 18253 InscanCopyOps.reserve(Size); 18254 InscanCopyArrayTemps.reserve(Size); 18255 InscanCopyArrayElems.reserve(Size); 18256 } 18257 TaskgroupDescriptors.reserve(Size); 18258 ExprCaptures.reserve(Size); 18259 ExprPostUpdates.reserve(Size); 18260 } 18261 /// Stores reduction item and reduction operation only (required for dependent 18262 /// reduction item). 18263 void push(Expr *Item, Expr *ReductionOp) { 18264 Vars.emplace_back(Item); 18265 Privates.emplace_back(nullptr); 18266 LHSs.emplace_back(nullptr); 18267 RHSs.emplace_back(nullptr); 18268 ReductionOps.emplace_back(ReductionOp); 18269 TaskgroupDescriptors.emplace_back(nullptr); 18270 if (RedModifier == OMPC_REDUCTION_inscan) { 18271 InscanCopyOps.push_back(nullptr); 18272 InscanCopyArrayTemps.push_back(nullptr); 18273 InscanCopyArrayElems.push_back(nullptr); 18274 } 18275 } 18276 /// Stores reduction data. 18277 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 18278 Expr *TaskgroupDescriptor, Expr *CopyOp, Expr *CopyArrayTemp, 18279 Expr *CopyArrayElem) { 18280 Vars.emplace_back(Item); 18281 Privates.emplace_back(Private); 18282 LHSs.emplace_back(LHS); 18283 RHSs.emplace_back(RHS); 18284 ReductionOps.emplace_back(ReductionOp); 18285 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 18286 if (RedModifier == OMPC_REDUCTION_inscan) { 18287 InscanCopyOps.push_back(CopyOp); 18288 InscanCopyArrayTemps.push_back(CopyArrayTemp); 18289 InscanCopyArrayElems.push_back(CopyArrayElem); 18290 } else { 18291 assert(CopyOp == nullptr && CopyArrayTemp == nullptr && 18292 CopyArrayElem == nullptr && 18293 "Copy operation must be used for inscan reductions only."); 18294 } 18295 } 18296 }; 18297 } // namespace 18298 18299 static bool checkOMPArraySectionConstantForReduction( 18300 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 18301 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 18302 const Expr *Length = OASE->getLength(); 18303 if (Length == nullptr) { 18304 // For array sections of the form [1:] or [:], we would need to analyze 18305 // the lower bound... 18306 if (OASE->getColonLocFirst().isValid()) 18307 return false; 18308 18309 // This is an array subscript which has implicit length 1! 18310 SingleElement = true; 18311 ArraySizes.push_back(llvm::APSInt::get(1)); 18312 } else { 18313 Expr::EvalResult Result; 18314 if (!Length->EvaluateAsInt(Result, Context)) 18315 return false; 18316 18317 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 18318 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 18319 ArraySizes.push_back(ConstantLengthValue); 18320 } 18321 18322 // Get the base of this array section and walk up from there. 18323 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 18324 18325 // We require length = 1 for all array sections except the right-most to 18326 // guarantee that the memory region is contiguous and has no holes in it. 18327 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 18328 Length = TempOASE->getLength(); 18329 if (Length == nullptr) { 18330 // For array sections of the form [1:] or [:], we would need to analyze 18331 // the lower bound... 18332 if (OASE->getColonLocFirst().isValid()) 18333 return false; 18334 18335 // This is an array subscript which has implicit length 1! 18336 ArraySizes.push_back(llvm::APSInt::get(1)); 18337 } else { 18338 Expr::EvalResult Result; 18339 if (!Length->EvaluateAsInt(Result, Context)) 18340 return false; 18341 18342 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 18343 if (ConstantLengthValue.getSExtValue() != 1) 18344 return false; 18345 18346 ArraySizes.push_back(ConstantLengthValue); 18347 } 18348 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 18349 } 18350 18351 // If we have a single element, we don't need to add the implicit lengths. 18352 if (!SingleElement) { 18353 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 18354 // Has implicit length 1! 18355 ArraySizes.push_back(llvm::APSInt::get(1)); 18356 Base = TempASE->getBase()->IgnoreParenImpCasts(); 18357 } 18358 } 18359 18360 // This array section can be privatized as a single value or as a constant 18361 // sized array. 18362 return true; 18363 } 18364 18365 static BinaryOperatorKind 18366 getRelatedCompoundReductionOp(BinaryOperatorKind BOK) { 18367 if (BOK == BO_Add) 18368 return BO_AddAssign; 18369 if (BOK == BO_Mul) 18370 return BO_MulAssign; 18371 if (BOK == BO_And) 18372 return BO_AndAssign; 18373 if (BOK == BO_Or) 18374 return BO_OrAssign; 18375 if (BOK == BO_Xor) 18376 return BO_XorAssign; 18377 return BOK; 18378 } 18379 18380 static bool actOnOMPReductionKindClause( 18381 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 18382 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 18383 SourceLocation ColonLoc, SourceLocation EndLoc, 18384 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 18385 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 18386 DeclarationName DN = ReductionId.getName(); 18387 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 18388 BinaryOperatorKind BOK = BO_Comma; 18389 18390 ASTContext &Context = S.Context; 18391 // OpenMP [2.14.3.6, reduction clause] 18392 // C 18393 // reduction-identifier is either an identifier or one of the following 18394 // operators: +, -, *, &, |, ^, && and || 18395 // C++ 18396 // reduction-identifier is either an id-expression or one of the following 18397 // operators: +, -, *, &, |, ^, && and || 18398 switch (OOK) { 18399 case OO_Plus: 18400 case OO_Minus: 18401 BOK = BO_Add; 18402 break; 18403 case OO_Star: 18404 BOK = BO_Mul; 18405 break; 18406 case OO_Amp: 18407 BOK = BO_And; 18408 break; 18409 case OO_Pipe: 18410 BOK = BO_Or; 18411 break; 18412 case OO_Caret: 18413 BOK = BO_Xor; 18414 break; 18415 case OO_AmpAmp: 18416 BOK = BO_LAnd; 18417 break; 18418 case OO_PipePipe: 18419 BOK = BO_LOr; 18420 break; 18421 case OO_New: 18422 case OO_Delete: 18423 case OO_Array_New: 18424 case OO_Array_Delete: 18425 case OO_Slash: 18426 case OO_Percent: 18427 case OO_Tilde: 18428 case OO_Exclaim: 18429 case OO_Equal: 18430 case OO_Less: 18431 case OO_Greater: 18432 case OO_LessEqual: 18433 case OO_GreaterEqual: 18434 case OO_PlusEqual: 18435 case OO_MinusEqual: 18436 case OO_StarEqual: 18437 case OO_SlashEqual: 18438 case OO_PercentEqual: 18439 case OO_CaretEqual: 18440 case OO_AmpEqual: 18441 case OO_PipeEqual: 18442 case OO_LessLess: 18443 case OO_GreaterGreater: 18444 case OO_LessLessEqual: 18445 case OO_GreaterGreaterEqual: 18446 case OO_EqualEqual: 18447 case OO_ExclaimEqual: 18448 case OO_Spaceship: 18449 case OO_PlusPlus: 18450 case OO_MinusMinus: 18451 case OO_Comma: 18452 case OO_ArrowStar: 18453 case OO_Arrow: 18454 case OO_Call: 18455 case OO_Subscript: 18456 case OO_Conditional: 18457 case OO_Coawait: 18458 case NUM_OVERLOADED_OPERATORS: 18459 llvm_unreachable("Unexpected reduction identifier"); 18460 case OO_None: 18461 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 18462 if (II->isStr("max")) 18463 BOK = BO_GT; 18464 else if (II->isStr("min")) 18465 BOK = BO_LT; 18466 } 18467 break; 18468 } 18469 SourceRange ReductionIdRange; 18470 if (ReductionIdScopeSpec.isValid()) 18471 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 18472 else 18473 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 18474 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 18475 18476 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 18477 bool FirstIter = true; 18478 for (Expr *RefExpr : VarList) { 18479 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 18480 // OpenMP [2.1, C/C++] 18481 // A list item is a variable or array section, subject to the restrictions 18482 // specified in Section 2.4 on page 42 and in each of the sections 18483 // describing clauses and directives for which a list appears. 18484 // OpenMP [2.14.3.3, Restrictions, p.1] 18485 // A variable that is part of another variable (as an array or 18486 // structure element) cannot appear in a private clause. 18487 if (!FirstIter && IR != ER) 18488 ++IR; 18489 FirstIter = false; 18490 SourceLocation ELoc; 18491 SourceRange ERange; 18492 Expr *SimpleRefExpr = RefExpr; 18493 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 18494 /*AllowArraySection=*/true); 18495 if (Res.second) { 18496 // Try to find 'declare reduction' corresponding construct before using 18497 // builtin/overloaded operators. 18498 QualType Type = Context.DependentTy; 18499 CXXCastPath BasePath; 18500 ExprResult DeclareReductionRef = buildDeclareReductionRef( 18501 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 18502 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 18503 Expr *ReductionOp = nullptr; 18504 if (S.CurContext->isDependentContext() && 18505 (DeclareReductionRef.isUnset() || 18506 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 18507 ReductionOp = DeclareReductionRef.get(); 18508 // It will be analyzed later. 18509 RD.push(RefExpr, ReductionOp); 18510 } 18511 ValueDecl *D = Res.first; 18512 if (!D) 18513 continue; 18514 18515 Expr *TaskgroupDescriptor = nullptr; 18516 QualType Type; 18517 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 18518 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 18519 if (ASE) { 18520 Type = ASE->getType().getNonReferenceType(); 18521 } else if (OASE) { 18522 QualType BaseType = 18523 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 18524 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 18525 Type = ATy->getElementType(); 18526 else 18527 Type = BaseType->getPointeeType(); 18528 Type = Type.getNonReferenceType(); 18529 } else { 18530 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 18531 } 18532 auto *VD = dyn_cast<VarDecl>(D); 18533 18534 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 18535 // A variable that appears in a private clause must not have an incomplete 18536 // type or a reference type. 18537 if (S.RequireCompleteType(ELoc, D->getType(), 18538 diag::err_omp_reduction_incomplete_type)) 18539 continue; 18540 // OpenMP [2.14.3.6, reduction clause, Restrictions] 18541 // A list item that appears in a reduction clause must not be 18542 // const-qualified. 18543 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 18544 /*AcceptIfMutable*/ false, ASE || OASE)) 18545 continue; 18546 18547 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 18548 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 18549 // If a list-item is a reference type then it must bind to the same object 18550 // for all threads of the team. 18551 if (!ASE && !OASE) { 18552 if (VD) { 18553 VarDecl *VDDef = VD->getDefinition(); 18554 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 18555 DSARefChecker Check(Stack); 18556 if (Check.Visit(VDDef->getInit())) { 18557 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 18558 << getOpenMPClauseName(ClauseKind) << ERange; 18559 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 18560 continue; 18561 } 18562 } 18563 } 18564 18565 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 18566 // in a Construct] 18567 // Variables with the predetermined data-sharing attributes may not be 18568 // listed in data-sharing attributes clauses, except for the cases 18569 // listed below. For these exceptions only, listing a predetermined 18570 // variable in a data-sharing attribute clause is allowed and overrides 18571 // the variable's predetermined data-sharing attributes. 18572 // OpenMP [2.14.3.6, Restrictions, p.3] 18573 // Any number of reduction clauses can be specified on the directive, 18574 // but a list item can appear only once in the reduction clauses for that 18575 // directive. 18576 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 18577 if (DVar.CKind == OMPC_reduction) { 18578 S.Diag(ELoc, diag::err_omp_once_referenced) 18579 << getOpenMPClauseName(ClauseKind); 18580 if (DVar.RefExpr) 18581 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 18582 continue; 18583 } 18584 if (DVar.CKind != OMPC_unknown) { 18585 S.Diag(ELoc, diag::err_omp_wrong_dsa) 18586 << getOpenMPClauseName(DVar.CKind) 18587 << getOpenMPClauseName(OMPC_reduction); 18588 reportOriginalDsa(S, Stack, D, DVar); 18589 continue; 18590 } 18591 18592 // OpenMP [2.14.3.6, Restrictions, p.1] 18593 // A list item that appears in a reduction clause of a worksharing 18594 // construct must be shared in the parallel regions to which any of the 18595 // worksharing regions arising from the worksharing construct bind. 18596 if (isOpenMPWorksharingDirective(CurrDir) && 18597 !isOpenMPParallelDirective(CurrDir) && 18598 !isOpenMPTeamsDirective(CurrDir)) { 18599 DVar = Stack->getImplicitDSA(D, true); 18600 if (DVar.CKind != OMPC_shared) { 18601 S.Diag(ELoc, diag::err_omp_required_access) 18602 << getOpenMPClauseName(OMPC_reduction) 18603 << getOpenMPClauseName(OMPC_shared); 18604 reportOriginalDsa(S, Stack, D, DVar); 18605 continue; 18606 } 18607 } 18608 } else { 18609 // Threadprivates cannot be shared between threads, so dignose if the base 18610 // is a threadprivate variable. 18611 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 18612 if (DVar.CKind == OMPC_threadprivate) { 18613 S.Diag(ELoc, diag::err_omp_wrong_dsa) 18614 << getOpenMPClauseName(DVar.CKind) 18615 << getOpenMPClauseName(OMPC_reduction); 18616 reportOriginalDsa(S, Stack, D, DVar); 18617 continue; 18618 } 18619 } 18620 18621 // Try to find 'declare reduction' corresponding construct before using 18622 // builtin/overloaded operators. 18623 CXXCastPath BasePath; 18624 ExprResult DeclareReductionRef = buildDeclareReductionRef( 18625 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 18626 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 18627 if (DeclareReductionRef.isInvalid()) 18628 continue; 18629 if (S.CurContext->isDependentContext() && 18630 (DeclareReductionRef.isUnset() || 18631 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 18632 RD.push(RefExpr, DeclareReductionRef.get()); 18633 continue; 18634 } 18635 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 18636 // Not allowed reduction identifier is found. 18637 S.Diag(ReductionId.getBeginLoc(), 18638 diag::err_omp_unknown_reduction_identifier) 18639 << Type << ReductionIdRange; 18640 continue; 18641 } 18642 18643 // OpenMP [2.14.3.6, reduction clause, Restrictions] 18644 // The type of a list item that appears in a reduction clause must be valid 18645 // for the reduction-identifier. For a max or min reduction in C, the type 18646 // of the list item must be an allowed arithmetic data type: char, int, 18647 // float, double, or _Bool, possibly modified with long, short, signed, or 18648 // unsigned. For a max or min reduction in C++, the type of the list item 18649 // must be an allowed arithmetic data type: char, wchar_t, int, float, 18650 // double, or bool, possibly modified with long, short, signed, or unsigned. 18651 if (DeclareReductionRef.isUnset()) { 18652 if ((BOK == BO_GT || BOK == BO_LT) && 18653 !(Type->isScalarType() || 18654 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 18655 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 18656 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 18657 if (!ASE && !OASE) { 18658 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18659 VarDecl::DeclarationOnly; 18660 S.Diag(D->getLocation(), 18661 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18662 << D; 18663 } 18664 continue; 18665 } 18666 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 18667 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 18668 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 18669 << getOpenMPClauseName(ClauseKind); 18670 if (!ASE && !OASE) { 18671 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18672 VarDecl::DeclarationOnly; 18673 S.Diag(D->getLocation(), 18674 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18675 << D; 18676 } 18677 continue; 18678 } 18679 } 18680 18681 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 18682 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 18683 D->hasAttrs() ? &D->getAttrs() : nullptr); 18684 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 18685 D->hasAttrs() ? &D->getAttrs() : nullptr); 18686 QualType PrivateTy = Type; 18687 18688 // Try if we can determine constant lengths for all array sections and avoid 18689 // the VLA. 18690 bool ConstantLengthOASE = false; 18691 if (OASE) { 18692 bool SingleElement; 18693 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 18694 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 18695 Context, OASE, SingleElement, ArraySizes); 18696 18697 // If we don't have a single element, we must emit a constant array type. 18698 if (ConstantLengthOASE && !SingleElement) { 18699 for (llvm::APSInt &Size : ArraySizes) 18700 PrivateTy = Context.getConstantArrayType(PrivateTy, Size, nullptr, 18701 ArrayType::Normal, 18702 /*IndexTypeQuals=*/0); 18703 } 18704 } 18705 18706 if ((OASE && !ConstantLengthOASE) || 18707 (!OASE && !ASE && 18708 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 18709 if (!Context.getTargetInfo().isVLASupported()) { 18710 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective())) { 18711 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 18712 S.Diag(ELoc, diag::note_vla_unsupported); 18713 continue; 18714 } else { 18715 S.targetDiag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 18716 S.targetDiag(ELoc, diag::note_vla_unsupported); 18717 } 18718 } 18719 // For arrays/array sections only: 18720 // Create pseudo array type for private copy. The size for this array will 18721 // be generated during codegen. 18722 // For array subscripts or single variables Private Ty is the same as Type 18723 // (type of the variable or single array element). 18724 PrivateTy = Context.getVariableArrayType( 18725 Type, 18726 new (Context) 18727 OpaqueValueExpr(ELoc, Context.getSizeType(), VK_PRValue), 18728 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 18729 } else if (!ASE && !OASE && 18730 Context.getAsArrayType(D->getType().getNonReferenceType())) { 18731 PrivateTy = D->getType().getNonReferenceType(); 18732 } 18733 // Private copy. 18734 VarDecl *PrivateVD = 18735 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 18736 D->hasAttrs() ? &D->getAttrs() : nullptr, 18737 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 18738 // Add initializer for private variable. 18739 Expr *Init = nullptr; 18740 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 18741 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 18742 if (DeclareReductionRef.isUsable()) { 18743 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 18744 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 18745 if (DRD->getInitializer()) { 18746 Init = DRDRef; 18747 RHSVD->setInit(DRDRef); 18748 RHSVD->setInitStyle(VarDecl::CallInit); 18749 } 18750 } else { 18751 switch (BOK) { 18752 case BO_Add: 18753 case BO_Xor: 18754 case BO_Or: 18755 case BO_LOr: 18756 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 18757 if (Type->isScalarType() || Type->isAnyComplexType()) 18758 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 18759 break; 18760 case BO_Mul: 18761 case BO_LAnd: 18762 if (Type->isScalarType() || Type->isAnyComplexType()) { 18763 // '*' and '&&' reduction ops - initializer is '1'. 18764 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 18765 } 18766 break; 18767 case BO_And: { 18768 // '&' reduction op - initializer is '~0'. 18769 QualType OrigType = Type; 18770 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 18771 Type = ComplexTy->getElementType(); 18772 if (Type->isRealFloatingType()) { 18773 llvm::APFloat InitValue = llvm::APFloat::getAllOnesValue( 18774 Context.getFloatTypeSemantics(Type)); 18775 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 18776 Type, ELoc); 18777 } else if (Type->isScalarType()) { 18778 uint64_t Size = Context.getTypeSize(Type); 18779 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 18780 llvm::APInt InitValue = llvm::APInt::getAllOnes(Size); 18781 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 18782 } 18783 if (Init && OrigType->isAnyComplexType()) { 18784 // Init = 0xFFFF + 0xFFFFi; 18785 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 18786 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 18787 } 18788 Type = OrigType; 18789 break; 18790 } 18791 case BO_LT: 18792 case BO_GT: { 18793 // 'min' reduction op - initializer is 'Largest representable number in 18794 // the reduction list item type'. 18795 // 'max' reduction op - initializer is 'Least representable number in 18796 // the reduction list item type'. 18797 if (Type->isIntegerType() || Type->isPointerType()) { 18798 bool IsSigned = Type->hasSignedIntegerRepresentation(); 18799 uint64_t Size = Context.getTypeSize(Type); 18800 QualType IntTy = 18801 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 18802 llvm::APInt InitValue = 18803 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 18804 : llvm::APInt::getMinValue(Size) 18805 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 18806 : llvm::APInt::getMaxValue(Size); 18807 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 18808 if (Type->isPointerType()) { 18809 // Cast to pointer type. 18810 ExprResult CastExpr = S.BuildCStyleCastExpr( 18811 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 18812 if (CastExpr.isInvalid()) 18813 continue; 18814 Init = CastExpr.get(); 18815 } 18816 } else if (Type->isRealFloatingType()) { 18817 llvm::APFloat InitValue = llvm::APFloat::getLargest( 18818 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 18819 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 18820 Type, ELoc); 18821 } 18822 break; 18823 } 18824 case BO_PtrMemD: 18825 case BO_PtrMemI: 18826 case BO_MulAssign: 18827 case BO_Div: 18828 case BO_Rem: 18829 case BO_Sub: 18830 case BO_Shl: 18831 case BO_Shr: 18832 case BO_LE: 18833 case BO_GE: 18834 case BO_EQ: 18835 case BO_NE: 18836 case BO_Cmp: 18837 case BO_AndAssign: 18838 case BO_XorAssign: 18839 case BO_OrAssign: 18840 case BO_Assign: 18841 case BO_AddAssign: 18842 case BO_SubAssign: 18843 case BO_DivAssign: 18844 case BO_RemAssign: 18845 case BO_ShlAssign: 18846 case BO_ShrAssign: 18847 case BO_Comma: 18848 llvm_unreachable("Unexpected reduction operation"); 18849 } 18850 } 18851 if (Init && DeclareReductionRef.isUnset()) { 18852 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 18853 // Store initializer for single element in private copy. Will be used 18854 // during codegen. 18855 PrivateVD->setInit(RHSVD->getInit()); 18856 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 18857 } else if (!Init) { 18858 S.ActOnUninitializedDecl(RHSVD); 18859 // Store initializer for single element in private copy. Will be used 18860 // during codegen. 18861 PrivateVD->setInit(RHSVD->getInit()); 18862 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 18863 } 18864 if (RHSVD->isInvalidDecl()) 18865 continue; 18866 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 18867 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 18868 << Type << ReductionIdRange; 18869 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 18870 VarDecl::DeclarationOnly; 18871 S.Diag(D->getLocation(), 18872 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 18873 << D; 18874 continue; 18875 } 18876 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 18877 ExprResult ReductionOp; 18878 if (DeclareReductionRef.isUsable()) { 18879 QualType RedTy = DeclareReductionRef.get()->getType(); 18880 QualType PtrRedTy = Context.getPointerType(RedTy); 18881 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 18882 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 18883 if (!BasePath.empty()) { 18884 LHS = S.DefaultLvalueConversion(LHS.get()); 18885 RHS = S.DefaultLvalueConversion(RHS.get()); 18886 LHS = ImplicitCastExpr::Create( 18887 Context, PtrRedTy, CK_UncheckedDerivedToBase, LHS.get(), &BasePath, 18888 LHS.get()->getValueKind(), FPOptionsOverride()); 18889 RHS = ImplicitCastExpr::Create( 18890 Context, PtrRedTy, CK_UncheckedDerivedToBase, RHS.get(), &BasePath, 18891 RHS.get()->getValueKind(), FPOptionsOverride()); 18892 } 18893 FunctionProtoType::ExtProtoInfo EPI; 18894 QualType Params[] = {PtrRedTy, PtrRedTy}; 18895 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 18896 auto *OVE = new (Context) OpaqueValueExpr( 18897 ELoc, Context.getPointerType(FnTy), VK_PRValue, OK_Ordinary, 18898 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 18899 Expr *Args[] = {LHS.get(), RHS.get()}; 18900 ReductionOp = 18901 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_PRValue, ELoc, 18902 S.CurFPFeatureOverrides()); 18903 } else { 18904 BinaryOperatorKind CombBOK = getRelatedCompoundReductionOp(BOK); 18905 if (Type->isRecordType() && CombBOK != BOK) { 18906 Sema::TentativeAnalysisScope Trap(S); 18907 ReductionOp = 18908 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 18909 CombBOK, LHSDRE, RHSDRE); 18910 } 18911 if (!ReductionOp.isUsable()) { 18912 ReductionOp = 18913 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, 18914 LHSDRE, RHSDRE); 18915 if (ReductionOp.isUsable()) { 18916 if (BOK != BO_LT && BOK != BO_GT) { 18917 ReductionOp = 18918 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 18919 BO_Assign, LHSDRE, ReductionOp.get()); 18920 } else { 18921 auto *ConditionalOp = new (Context) 18922 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, 18923 RHSDRE, Type, VK_LValue, OK_Ordinary); 18924 ReductionOp = 18925 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 18926 BO_Assign, LHSDRE, ConditionalOp); 18927 } 18928 } 18929 } 18930 if (ReductionOp.isUsable()) 18931 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 18932 /*DiscardedValue*/ false); 18933 if (!ReductionOp.isUsable()) 18934 continue; 18935 } 18936 18937 // Add copy operations for inscan reductions. 18938 // LHS = RHS; 18939 ExprResult CopyOpRes, TempArrayRes, TempArrayElem; 18940 if (ClauseKind == OMPC_reduction && 18941 RD.RedModifier == OMPC_REDUCTION_inscan) { 18942 ExprResult RHS = S.DefaultLvalueConversion(RHSDRE); 18943 CopyOpRes = S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, LHSDRE, 18944 RHS.get()); 18945 if (!CopyOpRes.isUsable()) 18946 continue; 18947 CopyOpRes = 18948 S.ActOnFinishFullExpr(CopyOpRes.get(), /*DiscardedValue=*/true); 18949 if (!CopyOpRes.isUsable()) 18950 continue; 18951 // For simd directive and simd-based directives in simd mode no need to 18952 // construct temp array, need just a single temp element. 18953 if (Stack->getCurrentDirective() == OMPD_simd || 18954 (S.getLangOpts().OpenMPSimd && 18955 isOpenMPSimdDirective(Stack->getCurrentDirective()))) { 18956 VarDecl *TempArrayVD = 18957 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 18958 D->hasAttrs() ? &D->getAttrs() : nullptr); 18959 // Add a constructor to the temp decl. 18960 S.ActOnUninitializedDecl(TempArrayVD); 18961 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, PrivateTy, ELoc); 18962 } else { 18963 // Build temp array for prefix sum. 18964 auto *Dim = new (S.Context) 18965 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue); 18966 QualType ArrayTy = 18967 S.Context.getVariableArrayType(PrivateTy, Dim, ArrayType::Normal, 18968 /*IndexTypeQuals=*/0, {ELoc, ELoc}); 18969 VarDecl *TempArrayVD = 18970 buildVarDecl(S, ELoc, ArrayTy, D->getName(), 18971 D->hasAttrs() ? &D->getAttrs() : nullptr); 18972 // Add a constructor to the temp decl. 18973 S.ActOnUninitializedDecl(TempArrayVD); 18974 TempArrayRes = buildDeclRefExpr(S, TempArrayVD, ArrayTy, ELoc); 18975 TempArrayElem = 18976 S.DefaultFunctionArrayLvalueConversion(TempArrayRes.get()); 18977 auto *Idx = new (S.Context) 18978 OpaqueValueExpr(ELoc, S.Context.getSizeType(), VK_PRValue); 18979 TempArrayElem = S.CreateBuiltinArraySubscriptExpr(TempArrayElem.get(), 18980 ELoc, Idx, ELoc); 18981 } 18982 } 18983 18984 // OpenMP [2.15.4.6, Restrictions, p.2] 18985 // A list item that appears in an in_reduction clause of a task construct 18986 // must appear in a task_reduction clause of a construct associated with a 18987 // taskgroup region that includes the participating task in its taskgroup 18988 // set. The construct associated with the innermost region that meets this 18989 // condition must specify the same reduction-identifier as the in_reduction 18990 // clause. 18991 if (ClauseKind == OMPC_in_reduction) { 18992 SourceRange ParentSR; 18993 BinaryOperatorKind ParentBOK; 18994 const Expr *ParentReductionOp = nullptr; 18995 Expr *ParentBOKTD = nullptr, *ParentReductionOpTD = nullptr; 18996 DSAStackTy::DSAVarData ParentBOKDSA = 18997 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 18998 ParentBOKTD); 18999 DSAStackTy::DSAVarData ParentReductionOpDSA = 19000 Stack->getTopMostTaskgroupReductionData( 19001 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 19002 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 19003 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 19004 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 19005 (DeclareReductionRef.isUsable() && IsParentBOK) || 19006 (IsParentBOK && BOK != ParentBOK) || IsParentReductionOp) { 19007 bool EmitError = true; 19008 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 19009 llvm::FoldingSetNodeID RedId, ParentRedId; 19010 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 19011 DeclareReductionRef.get()->Profile(RedId, Context, 19012 /*Canonical=*/true); 19013 EmitError = RedId != ParentRedId; 19014 } 19015 if (EmitError) { 19016 S.Diag(ReductionId.getBeginLoc(), 19017 diag::err_omp_reduction_identifier_mismatch) 19018 << ReductionIdRange << RefExpr->getSourceRange(); 19019 S.Diag(ParentSR.getBegin(), 19020 diag::note_omp_previous_reduction_identifier) 19021 << ParentSR 19022 << (IsParentBOK ? ParentBOKDSA.RefExpr 19023 : ParentReductionOpDSA.RefExpr) 19024 ->getSourceRange(); 19025 continue; 19026 } 19027 } 19028 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 19029 } 19030 19031 DeclRefExpr *Ref = nullptr; 19032 Expr *VarsExpr = RefExpr->IgnoreParens(); 19033 if (!VD && !S.CurContext->isDependentContext()) { 19034 if (ASE || OASE) { 19035 TransformExprToCaptures RebuildToCapture(S, D); 19036 VarsExpr = 19037 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 19038 Ref = RebuildToCapture.getCapturedExpr(); 19039 } else { 19040 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 19041 } 19042 if (!S.isOpenMPCapturedDecl(D)) { 19043 RD.ExprCaptures.emplace_back(Ref->getDecl()); 19044 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 19045 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 19046 if (!RefRes.isUsable()) 19047 continue; 19048 ExprResult PostUpdateRes = 19049 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 19050 RefRes.get()); 19051 if (!PostUpdateRes.isUsable()) 19052 continue; 19053 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 19054 Stack->getCurrentDirective() == OMPD_taskgroup) { 19055 S.Diag(RefExpr->getExprLoc(), 19056 diag::err_omp_reduction_non_addressable_expression) 19057 << RefExpr->getSourceRange(); 19058 continue; 19059 } 19060 RD.ExprPostUpdates.emplace_back( 19061 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 19062 } 19063 } 19064 } 19065 // All reduction items are still marked as reduction (to do not increase 19066 // code base size). 19067 unsigned Modifier = RD.RedModifier; 19068 // Consider task_reductions as reductions with task modifier. Required for 19069 // correct analysis of in_reduction clauses. 19070 if (CurrDir == OMPD_taskgroup && ClauseKind == OMPC_task_reduction) 19071 Modifier = OMPC_REDUCTION_task; 19072 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref, Modifier, 19073 ASE || OASE); 19074 if (Modifier == OMPC_REDUCTION_task && 19075 (CurrDir == OMPD_taskgroup || 19076 ((isOpenMPParallelDirective(CurrDir) || 19077 isOpenMPWorksharingDirective(CurrDir)) && 19078 !isOpenMPSimdDirective(CurrDir)))) { 19079 if (DeclareReductionRef.isUsable()) 19080 Stack->addTaskgroupReductionData(D, ReductionIdRange, 19081 DeclareReductionRef.get()); 19082 else 19083 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 19084 } 19085 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 19086 TaskgroupDescriptor, CopyOpRes.get(), TempArrayRes.get(), 19087 TempArrayElem.get()); 19088 } 19089 return RD.Vars.empty(); 19090 } 19091 19092 OMPClause *Sema::ActOnOpenMPReductionClause( 19093 ArrayRef<Expr *> VarList, OpenMPReductionClauseModifier Modifier, 19094 SourceLocation StartLoc, SourceLocation LParenLoc, 19095 SourceLocation ModifierLoc, SourceLocation ColonLoc, SourceLocation EndLoc, 19096 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19097 ArrayRef<Expr *> UnresolvedReductions) { 19098 if (ModifierLoc.isValid() && Modifier == OMPC_REDUCTION_unknown) { 19099 Diag(LParenLoc, diag::err_omp_unexpected_clause_value) 19100 << getListOfPossibleValues(OMPC_reduction, /*First=*/0, 19101 /*Last=*/OMPC_REDUCTION_unknown) 19102 << getOpenMPClauseName(OMPC_reduction); 19103 return nullptr; 19104 } 19105 // OpenMP 5.0, 2.19.5.4 reduction Clause, Restrictions 19106 // A reduction clause with the inscan reduction-modifier may only appear on a 19107 // worksharing-loop construct, a worksharing-loop SIMD construct, a simd 19108 // construct, a parallel worksharing-loop construct or a parallel 19109 // worksharing-loop SIMD construct. 19110 if (Modifier == OMPC_REDUCTION_inscan && 19111 (DSAStack->getCurrentDirective() != OMPD_for && 19112 DSAStack->getCurrentDirective() != OMPD_for_simd && 19113 DSAStack->getCurrentDirective() != OMPD_simd && 19114 DSAStack->getCurrentDirective() != OMPD_parallel_for && 19115 DSAStack->getCurrentDirective() != OMPD_parallel_for_simd)) { 19116 Diag(ModifierLoc, diag::err_omp_wrong_inscan_reduction); 19117 return nullptr; 19118 } 19119 19120 ReductionData RD(VarList.size(), Modifier); 19121 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 19122 StartLoc, LParenLoc, ColonLoc, EndLoc, 19123 ReductionIdScopeSpec, ReductionId, 19124 UnresolvedReductions, RD)) 19125 return nullptr; 19126 19127 return OMPReductionClause::Create( 19128 Context, StartLoc, LParenLoc, ModifierLoc, ColonLoc, EndLoc, Modifier, 19129 RD.Vars, ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19130 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.InscanCopyOps, 19131 RD.InscanCopyArrayTemps, RD.InscanCopyArrayElems, 19132 buildPreInits(Context, RD.ExprCaptures), 19133 buildPostUpdate(*this, RD.ExprPostUpdates)); 19134 } 19135 19136 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 19137 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 19138 SourceLocation ColonLoc, SourceLocation EndLoc, 19139 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19140 ArrayRef<Expr *> UnresolvedReductions) { 19141 ReductionData RD(VarList.size()); 19142 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 19143 StartLoc, LParenLoc, ColonLoc, EndLoc, 19144 ReductionIdScopeSpec, ReductionId, 19145 UnresolvedReductions, RD)) 19146 return nullptr; 19147 19148 return OMPTaskReductionClause::Create( 19149 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 19150 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19151 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 19152 buildPreInits(Context, RD.ExprCaptures), 19153 buildPostUpdate(*this, RD.ExprPostUpdates)); 19154 } 19155 19156 OMPClause *Sema::ActOnOpenMPInReductionClause( 19157 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 19158 SourceLocation ColonLoc, SourceLocation EndLoc, 19159 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 19160 ArrayRef<Expr *> UnresolvedReductions) { 19161 ReductionData RD(VarList.size()); 19162 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 19163 StartLoc, LParenLoc, ColonLoc, EndLoc, 19164 ReductionIdScopeSpec, ReductionId, 19165 UnresolvedReductions, RD)) 19166 return nullptr; 19167 19168 return OMPInReductionClause::Create( 19169 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 19170 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 19171 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 19172 buildPreInits(Context, RD.ExprCaptures), 19173 buildPostUpdate(*this, RD.ExprPostUpdates)); 19174 } 19175 19176 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 19177 SourceLocation LinLoc) { 19178 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 19179 LinKind == OMPC_LINEAR_unknown) { 19180 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 19181 return true; 19182 } 19183 return false; 19184 } 19185 19186 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 19187 OpenMPLinearClauseKind LinKind, QualType Type, 19188 bool IsDeclareSimd) { 19189 const auto *VD = dyn_cast_or_null<VarDecl>(D); 19190 // A variable must not have an incomplete type or a reference type. 19191 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 19192 return true; 19193 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 19194 !Type->isReferenceType()) { 19195 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 19196 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 19197 return true; 19198 } 19199 Type = Type.getNonReferenceType(); 19200 19201 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 19202 // A variable that is privatized must not have a const-qualified type 19203 // unless it is of class type with a mutable member. This restriction does 19204 // not apply to the firstprivate clause, nor to the linear clause on 19205 // declarative directives (like declare simd). 19206 if (!IsDeclareSimd && 19207 rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 19208 return true; 19209 19210 // A list item must be of integral or pointer type. 19211 Type = Type.getUnqualifiedType().getCanonicalType(); 19212 const auto *Ty = Type.getTypePtrOrNull(); 19213 if (!Ty || (LinKind != OMPC_LINEAR_ref && !Ty->isDependentType() && 19214 !Ty->isIntegralType(Context) && !Ty->isPointerType())) { 19215 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 19216 if (D) { 19217 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19218 VarDecl::DeclarationOnly; 19219 Diag(D->getLocation(), 19220 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19221 << D; 19222 } 19223 return true; 19224 } 19225 return false; 19226 } 19227 19228 OMPClause *Sema::ActOnOpenMPLinearClause( 19229 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 19230 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 19231 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 19232 SmallVector<Expr *, 8> Vars; 19233 SmallVector<Expr *, 8> Privates; 19234 SmallVector<Expr *, 8> Inits; 19235 SmallVector<Decl *, 4> ExprCaptures; 19236 SmallVector<Expr *, 4> ExprPostUpdates; 19237 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 19238 LinKind = OMPC_LINEAR_val; 19239 for (Expr *RefExpr : VarList) { 19240 assert(RefExpr && "NULL expr in OpenMP linear clause."); 19241 SourceLocation ELoc; 19242 SourceRange ERange; 19243 Expr *SimpleRefExpr = RefExpr; 19244 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19245 if (Res.second) { 19246 // It will be analyzed later. 19247 Vars.push_back(RefExpr); 19248 Privates.push_back(nullptr); 19249 Inits.push_back(nullptr); 19250 } 19251 ValueDecl *D = Res.first; 19252 if (!D) 19253 continue; 19254 19255 QualType Type = D->getType(); 19256 auto *VD = dyn_cast<VarDecl>(D); 19257 19258 // OpenMP [2.14.3.7, linear clause] 19259 // A list-item cannot appear in more than one linear clause. 19260 // A list-item that appears in a linear clause cannot appear in any 19261 // other data-sharing attribute clause. 19262 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 19263 if (DVar.RefExpr) { 19264 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 19265 << getOpenMPClauseName(OMPC_linear); 19266 reportOriginalDsa(*this, DSAStack, D, DVar); 19267 continue; 19268 } 19269 19270 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 19271 continue; 19272 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 19273 19274 // Build private copy of original var. 19275 VarDecl *Private = 19276 buildVarDecl(*this, ELoc, Type, D->getName(), 19277 D->hasAttrs() ? &D->getAttrs() : nullptr, 19278 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 19279 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 19280 // Build var to save initial value. 19281 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 19282 Expr *InitExpr; 19283 DeclRefExpr *Ref = nullptr; 19284 if (!VD && !CurContext->isDependentContext()) { 19285 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 19286 if (!isOpenMPCapturedDecl(D)) { 19287 ExprCaptures.push_back(Ref->getDecl()); 19288 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 19289 ExprResult RefRes = DefaultLvalueConversion(Ref); 19290 if (!RefRes.isUsable()) 19291 continue; 19292 ExprResult PostUpdateRes = 19293 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 19294 SimpleRefExpr, RefRes.get()); 19295 if (!PostUpdateRes.isUsable()) 19296 continue; 19297 ExprPostUpdates.push_back( 19298 IgnoredValueConversions(PostUpdateRes.get()).get()); 19299 } 19300 } 19301 } 19302 if (LinKind == OMPC_LINEAR_uval) 19303 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 19304 else 19305 InitExpr = VD ? SimpleRefExpr : Ref; 19306 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 19307 /*DirectInit=*/false); 19308 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 19309 19310 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 19311 Vars.push_back((VD || CurContext->isDependentContext()) 19312 ? RefExpr->IgnoreParens() 19313 : Ref); 19314 Privates.push_back(PrivateRef); 19315 Inits.push_back(InitRef); 19316 } 19317 19318 if (Vars.empty()) 19319 return nullptr; 19320 19321 Expr *StepExpr = Step; 19322 Expr *CalcStepExpr = nullptr; 19323 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 19324 !Step->isInstantiationDependent() && 19325 !Step->containsUnexpandedParameterPack()) { 19326 SourceLocation StepLoc = Step->getBeginLoc(); 19327 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 19328 if (Val.isInvalid()) 19329 return nullptr; 19330 StepExpr = Val.get(); 19331 19332 // Build var to save the step value. 19333 VarDecl *SaveVar = 19334 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 19335 ExprResult SaveRef = 19336 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 19337 ExprResult CalcStep = 19338 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 19339 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 19340 19341 // Warn about zero linear step (it would be probably better specified as 19342 // making corresponding variables 'const'). 19343 if (Optional<llvm::APSInt> Result = 19344 StepExpr->getIntegerConstantExpr(Context)) { 19345 if (!Result->isNegative() && !Result->isStrictlyPositive()) 19346 Diag(StepLoc, diag::warn_omp_linear_step_zero) 19347 << Vars[0] << (Vars.size() > 1); 19348 } else if (CalcStep.isUsable()) { 19349 // Calculate the step beforehand instead of doing this on each iteration. 19350 // (This is not used if the number of iterations may be kfold-ed). 19351 CalcStepExpr = CalcStep.get(); 19352 } 19353 } 19354 19355 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 19356 ColonLoc, EndLoc, Vars, Privates, Inits, 19357 StepExpr, CalcStepExpr, 19358 buildPreInits(Context, ExprCaptures), 19359 buildPostUpdate(*this, ExprPostUpdates)); 19360 } 19361 19362 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 19363 Expr *NumIterations, Sema &SemaRef, 19364 Scope *S, DSAStackTy *Stack) { 19365 // Walk the vars and build update/final expressions for the CodeGen. 19366 SmallVector<Expr *, 8> Updates; 19367 SmallVector<Expr *, 8> Finals; 19368 SmallVector<Expr *, 8> UsedExprs; 19369 Expr *Step = Clause.getStep(); 19370 Expr *CalcStep = Clause.getCalcStep(); 19371 // OpenMP [2.14.3.7, linear clause] 19372 // If linear-step is not specified it is assumed to be 1. 19373 if (!Step) 19374 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 19375 else if (CalcStep) 19376 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 19377 bool HasErrors = false; 19378 auto CurInit = Clause.inits().begin(); 19379 auto CurPrivate = Clause.privates().begin(); 19380 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 19381 for (Expr *RefExpr : Clause.varlists()) { 19382 SourceLocation ELoc; 19383 SourceRange ERange; 19384 Expr *SimpleRefExpr = RefExpr; 19385 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 19386 ValueDecl *D = Res.first; 19387 if (Res.second || !D) { 19388 Updates.push_back(nullptr); 19389 Finals.push_back(nullptr); 19390 HasErrors = true; 19391 continue; 19392 } 19393 auto &&Info = Stack->isLoopControlVariable(D); 19394 // OpenMP [2.15.11, distribute simd Construct] 19395 // A list item may not appear in a linear clause, unless it is the loop 19396 // iteration variable. 19397 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 19398 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 19399 SemaRef.Diag(ELoc, 19400 diag::err_omp_linear_distribute_var_non_loop_iteration); 19401 Updates.push_back(nullptr); 19402 Finals.push_back(nullptr); 19403 HasErrors = true; 19404 continue; 19405 } 19406 Expr *InitExpr = *CurInit; 19407 19408 // Build privatized reference to the current linear var. 19409 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 19410 Expr *CapturedRef; 19411 if (LinKind == OMPC_LINEAR_uval) 19412 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 19413 else 19414 CapturedRef = 19415 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 19416 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 19417 /*RefersToCapture=*/true); 19418 19419 // Build update: Var = InitExpr + IV * Step 19420 ExprResult Update; 19421 if (!Info.first) 19422 Update = buildCounterUpdate( 19423 SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, InitExpr, IV, Step, 19424 /*Subtract=*/false, /*IsNonRectangularLB=*/false); 19425 else 19426 Update = *CurPrivate; 19427 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 19428 /*DiscardedValue*/ false); 19429 19430 // Build final: Var = PrivCopy; 19431 ExprResult Final; 19432 if (!Info.first) 19433 Final = SemaRef.BuildBinOp( 19434 S, RefExpr->getExprLoc(), BO_Assign, CapturedRef, 19435 SemaRef.DefaultLvalueConversion(*CurPrivate).get()); 19436 else 19437 Final = *CurPrivate; 19438 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 19439 /*DiscardedValue*/ false); 19440 19441 if (!Update.isUsable() || !Final.isUsable()) { 19442 Updates.push_back(nullptr); 19443 Finals.push_back(nullptr); 19444 UsedExprs.push_back(nullptr); 19445 HasErrors = true; 19446 } else { 19447 Updates.push_back(Update.get()); 19448 Finals.push_back(Final.get()); 19449 if (!Info.first) 19450 UsedExprs.push_back(SimpleRefExpr); 19451 } 19452 ++CurInit; 19453 ++CurPrivate; 19454 } 19455 if (Expr *S = Clause.getStep()) 19456 UsedExprs.push_back(S); 19457 // Fill the remaining part with the nullptr. 19458 UsedExprs.append(Clause.varlist_size() + 1 - UsedExprs.size(), nullptr); 19459 Clause.setUpdates(Updates); 19460 Clause.setFinals(Finals); 19461 Clause.setUsedExprs(UsedExprs); 19462 return HasErrors; 19463 } 19464 19465 OMPClause *Sema::ActOnOpenMPAlignedClause( 19466 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 19467 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 19468 SmallVector<Expr *, 8> Vars; 19469 for (Expr *RefExpr : VarList) { 19470 assert(RefExpr && "NULL expr in OpenMP linear clause."); 19471 SourceLocation ELoc; 19472 SourceRange ERange; 19473 Expr *SimpleRefExpr = RefExpr; 19474 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19475 if (Res.second) { 19476 // It will be analyzed later. 19477 Vars.push_back(RefExpr); 19478 } 19479 ValueDecl *D = Res.first; 19480 if (!D) 19481 continue; 19482 19483 QualType QType = D->getType(); 19484 auto *VD = dyn_cast<VarDecl>(D); 19485 19486 // OpenMP [2.8.1, simd construct, Restrictions] 19487 // The type of list items appearing in the aligned clause must be 19488 // array, pointer, reference to array, or reference to pointer. 19489 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 19490 const Type *Ty = QType.getTypePtrOrNull(); 19491 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 19492 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 19493 << QType << getLangOpts().CPlusPlus << ERange; 19494 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19495 VarDecl::DeclarationOnly; 19496 Diag(D->getLocation(), 19497 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19498 << D; 19499 continue; 19500 } 19501 19502 // OpenMP [2.8.1, simd construct, Restrictions] 19503 // A list-item cannot appear in more than one aligned clause. 19504 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 19505 Diag(ELoc, diag::err_omp_used_in_clause_twice) 19506 << 0 << getOpenMPClauseName(OMPC_aligned) << ERange; 19507 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 19508 << getOpenMPClauseName(OMPC_aligned); 19509 continue; 19510 } 19511 19512 DeclRefExpr *Ref = nullptr; 19513 if (!VD && isOpenMPCapturedDecl(D)) 19514 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 19515 Vars.push_back(DefaultFunctionArrayConversion( 19516 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 19517 .get()); 19518 } 19519 19520 // OpenMP [2.8.1, simd construct, Description] 19521 // The parameter of the aligned clause, alignment, must be a constant 19522 // positive integer expression. 19523 // If no optional parameter is specified, implementation-defined default 19524 // alignments for SIMD instructions on the target platforms are assumed. 19525 if (Alignment != nullptr) { 19526 ExprResult AlignResult = 19527 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 19528 if (AlignResult.isInvalid()) 19529 return nullptr; 19530 Alignment = AlignResult.get(); 19531 } 19532 if (Vars.empty()) 19533 return nullptr; 19534 19535 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 19536 EndLoc, Vars, Alignment); 19537 } 19538 19539 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 19540 SourceLocation StartLoc, 19541 SourceLocation LParenLoc, 19542 SourceLocation EndLoc) { 19543 SmallVector<Expr *, 8> Vars; 19544 SmallVector<Expr *, 8> SrcExprs; 19545 SmallVector<Expr *, 8> DstExprs; 19546 SmallVector<Expr *, 8> AssignmentOps; 19547 for (Expr *RefExpr : VarList) { 19548 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 19549 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 19550 // It will be analyzed later. 19551 Vars.push_back(RefExpr); 19552 SrcExprs.push_back(nullptr); 19553 DstExprs.push_back(nullptr); 19554 AssignmentOps.push_back(nullptr); 19555 continue; 19556 } 19557 19558 SourceLocation ELoc = RefExpr->getExprLoc(); 19559 // OpenMP [2.1, C/C++] 19560 // A list item is a variable name. 19561 // OpenMP [2.14.4.1, Restrictions, p.1] 19562 // A list item that appears in a copyin clause must be threadprivate. 19563 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 19564 if (!DE || !isa<VarDecl>(DE->getDecl())) { 19565 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 19566 << 0 << RefExpr->getSourceRange(); 19567 continue; 19568 } 19569 19570 Decl *D = DE->getDecl(); 19571 auto *VD = cast<VarDecl>(D); 19572 19573 QualType Type = VD->getType(); 19574 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 19575 // It will be analyzed later. 19576 Vars.push_back(DE); 19577 SrcExprs.push_back(nullptr); 19578 DstExprs.push_back(nullptr); 19579 AssignmentOps.push_back(nullptr); 19580 continue; 19581 } 19582 19583 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 19584 // A list item that appears in a copyin clause must be threadprivate. 19585 if (!DSAStack->isThreadPrivate(VD)) { 19586 Diag(ELoc, diag::err_omp_required_access) 19587 << getOpenMPClauseName(OMPC_copyin) 19588 << getOpenMPDirectiveName(OMPD_threadprivate); 19589 continue; 19590 } 19591 19592 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 19593 // A variable of class type (or array thereof) that appears in a 19594 // copyin clause requires an accessible, unambiguous copy assignment 19595 // operator for the class type. 19596 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 19597 VarDecl *SrcVD = 19598 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 19599 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 19600 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 19601 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 19602 VarDecl *DstVD = 19603 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 19604 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 19605 DeclRefExpr *PseudoDstExpr = 19606 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 19607 // For arrays generate assignment operation for single element and replace 19608 // it by the original array element in CodeGen. 19609 ExprResult AssignmentOp = 19610 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 19611 PseudoSrcExpr); 19612 if (AssignmentOp.isInvalid()) 19613 continue; 19614 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 19615 /*DiscardedValue*/ false); 19616 if (AssignmentOp.isInvalid()) 19617 continue; 19618 19619 DSAStack->addDSA(VD, DE, OMPC_copyin); 19620 Vars.push_back(DE); 19621 SrcExprs.push_back(PseudoSrcExpr); 19622 DstExprs.push_back(PseudoDstExpr); 19623 AssignmentOps.push_back(AssignmentOp.get()); 19624 } 19625 19626 if (Vars.empty()) 19627 return nullptr; 19628 19629 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 19630 SrcExprs, DstExprs, AssignmentOps); 19631 } 19632 19633 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 19634 SourceLocation StartLoc, 19635 SourceLocation LParenLoc, 19636 SourceLocation EndLoc) { 19637 SmallVector<Expr *, 8> Vars; 19638 SmallVector<Expr *, 8> SrcExprs; 19639 SmallVector<Expr *, 8> DstExprs; 19640 SmallVector<Expr *, 8> AssignmentOps; 19641 for (Expr *RefExpr : VarList) { 19642 assert(RefExpr && "NULL expr in OpenMP linear clause."); 19643 SourceLocation ELoc; 19644 SourceRange ERange; 19645 Expr *SimpleRefExpr = RefExpr; 19646 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 19647 if (Res.second) { 19648 // It will be analyzed later. 19649 Vars.push_back(RefExpr); 19650 SrcExprs.push_back(nullptr); 19651 DstExprs.push_back(nullptr); 19652 AssignmentOps.push_back(nullptr); 19653 } 19654 ValueDecl *D = Res.first; 19655 if (!D) 19656 continue; 19657 19658 QualType Type = D->getType(); 19659 auto *VD = dyn_cast<VarDecl>(D); 19660 19661 // OpenMP [2.14.4.2, Restrictions, p.2] 19662 // A list item that appears in a copyprivate clause may not appear in a 19663 // private or firstprivate clause on the single construct. 19664 if (!VD || !DSAStack->isThreadPrivate(VD)) { 19665 DSAStackTy::DSAVarData DVar = 19666 DSAStack->getTopDSA(D, /*FromParent=*/false); 19667 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 19668 DVar.RefExpr) { 19669 Diag(ELoc, diag::err_omp_wrong_dsa) 19670 << getOpenMPClauseName(DVar.CKind) 19671 << getOpenMPClauseName(OMPC_copyprivate); 19672 reportOriginalDsa(*this, DSAStack, D, DVar); 19673 continue; 19674 } 19675 19676 // OpenMP [2.11.4.2, Restrictions, p.1] 19677 // All list items that appear in a copyprivate clause must be either 19678 // threadprivate or private in the enclosing context. 19679 if (DVar.CKind == OMPC_unknown) { 19680 DVar = DSAStack->getImplicitDSA(D, false); 19681 if (DVar.CKind == OMPC_shared) { 19682 Diag(ELoc, diag::err_omp_required_access) 19683 << getOpenMPClauseName(OMPC_copyprivate) 19684 << "threadprivate or private in the enclosing context"; 19685 reportOriginalDsa(*this, DSAStack, D, DVar); 19686 continue; 19687 } 19688 } 19689 } 19690 19691 // Variably modified types are not supported. 19692 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 19693 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 19694 << getOpenMPClauseName(OMPC_copyprivate) << Type 19695 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 19696 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 19697 VarDecl::DeclarationOnly; 19698 Diag(D->getLocation(), 19699 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 19700 << D; 19701 continue; 19702 } 19703 19704 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 19705 // A variable of class type (or array thereof) that appears in a 19706 // copyin clause requires an accessible, unambiguous copy assignment 19707 // operator for the class type. 19708 Type = Context.getBaseElementType(Type.getNonReferenceType()) 19709 .getUnqualifiedType(); 19710 VarDecl *SrcVD = 19711 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 19712 D->hasAttrs() ? &D->getAttrs() : nullptr); 19713 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 19714 VarDecl *DstVD = 19715 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 19716 D->hasAttrs() ? &D->getAttrs() : nullptr); 19717 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 19718 ExprResult AssignmentOp = BuildBinOp( 19719 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 19720 if (AssignmentOp.isInvalid()) 19721 continue; 19722 AssignmentOp = 19723 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 19724 if (AssignmentOp.isInvalid()) 19725 continue; 19726 19727 // No need to mark vars as copyprivate, they are already threadprivate or 19728 // implicitly private. 19729 assert(VD || isOpenMPCapturedDecl(D)); 19730 Vars.push_back( 19731 VD ? RefExpr->IgnoreParens() 19732 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 19733 SrcExprs.push_back(PseudoSrcExpr); 19734 DstExprs.push_back(PseudoDstExpr); 19735 AssignmentOps.push_back(AssignmentOp.get()); 19736 } 19737 19738 if (Vars.empty()) 19739 return nullptr; 19740 19741 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 19742 Vars, SrcExprs, DstExprs, AssignmentOps); 19743 } 19744 19745 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 19746 SourceLocation StartLoc, 19747 SourceLocation LParenLoc, 19748 SourceLocation EndLoc) { 19749 if (VarList.empty()) 19750 return nullptr; 19751 19752 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 19753 } 19754 19755 /// Tries to find omp_depend_t. type. 19756 static bool findOMPDependT(Sema &S, SourceLocation Loc, DSAStackTy *Stack, 19757 bool Diagnose = true) { 19758 QualType OMPDependT = Stack->getOMPDependT(); 19759 if (!OMPDependT.isNull()) 19760 return true; 19761 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_depend_t"); 19762 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 19763 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 19764 if (Diagnose) 19765 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_depend_t"; 19766 return false; 19767 } 19768 Stack->setOMPDependT(PT.get()); 19769 return true; 19770 } 19771 19772 OMPClause *Sema::ActOnOpenMPDepobjClause(Expr *Depobj, SourceLocation StartLoc, 19773 SourceLocation LParenLoc, 19774 SourceLocation EndLoc) { 19775 if (!Depobj) 19776 return nullptr; 19777 19778 bool OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack); 19779 19780 // OpenMP 5.0, 2.17.10.1 depobj Construct 19781 // depobj is an lvalue expression of type omp_depend_t. 19782 if (!Depobj->isTypeDependent() && !Depobj->isValueDependent() && 19783 !Depobj->isInstantiationDependent() && 19784 !Depobj->containsUnexpandedParameterPack() && 19785 (OMPDependTFound && 19786 !Context.typesAreCompatible(DSAStack->getOMPDependT(), Depobj->getType(), 19787 /*CompareUnqualified=*/true))) { 19788 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 19789 << 0 << Depobj->getType() << Depobj->getSourceRange(); 19790 } 19791 19792 if (!Depobj->isLValue()) { 19793 Diag(Depobj->getExprLoc(), diag::err_omp_expected_omp_depend_t_lvalue) 19794 << 1 << Depobj->getSourceRange(); 19795 } 19796 19797 return OMPDepobjClause::Create(Context, StartLoc, LParenLoc, EndLoc, Depobj); 19798 } 19799 19800 OMPClause * 19801 Sema::ActOnOpenMPDependClause(const OMPDependClause::DependDataTy &Data, 19802 Expr *DepModifier, ArrayRef<Expr *> VarList, 19803 SourceLocation StartLoc, SourceLocation LParenLoc, 19804 SourceLocation EndLoc) { 19805 OpenMPDependClauseKind DepKind = Data.DepKind; 19806 SourceLocation DepLoc = Data.DepLoc; 19807 if (DSAStack->getCurrentDirective() == OMPD_ordered && 19808 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 19809 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 19810 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 19811 return nullptr; 19812 } 19813 if (DSAStack->getCurrentDirective() == OMPD_taskwait && 19814 DepKind == OMPC_DEPEND_mutexinoutset) { 19815 Diag(DepLoc, diag::err_omp_taskwait_depend_mutexinoutset_not_allowed); 19816 return nullptr; 19817 } 19818 if ((DSAStack->getCurrentDirective() != OMPD_ordered || 19819 DSAStack->getCurrentDirective() == OMPD_depobj) && 19820 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 19821 DepKind == OMPC_DEPEND_sink || 19822 ((LangOpts.OpenMP < 50 || 19823 DSAStack->getCurrentDirective() == OMPD_depobj) && 19824 DepKind == OMPC_DEPEND_depobj))) { 19825 SmallVector<unsigned, 6> Except = {OMPC_DEPEND_source, OMPC_DEPEND_sink, 19826 OMPC_DEPEND_outallmemory, 19827 OMPC_DEPEND_inoutallmemory}; 19828 if (LangOpts.OpenMP < 50 || DSAStack->getCurrentDirective() == OMPD_depobj) 19829 Except.push_back(OMPC_DEPEND_depobj); 19830 if (LangOpts.OpenMP < 51) 19831 Except.push_back(OMPC_DEPEND_inoutset); 19832 std::string Expected = (LangOpts.OpenMP >= 50 && !DepModifier) 19833 ? "depend modifier(iterator) or " 19834 : ""; 19835 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 19836 << Expected + getListOfPossibleValues(OMPC_depend, /*First=*/0, 19837 /*Last=*/OMPC_DEPEND_unknown, 19838 Except) 19839 << getOpenMPClauseName(OMPC_depend); 19840 return nullptr; 19841 } 19842 if (DepModifier && 19843 (DepKind == OMPC_DEPEND_source || DepKind == OMPC_DEPEND_sink)) { 19844 Diag(DepModifier->getExprLoc(), 19845 diag::err_omp_depend_sink_source_with_modifier); 19846 return nullptr; 19847 } 19848 if (DepModifier && 19849 !DepModifier->getType()->isSpecificBuiltinType(BuiltinType::OMPIterator)) 19850 Diag(DepModifier->getExprLoc(), diag::err_omp_depend_modifier_not_iterator); 19851 19852 SmallVector<Expr *, 8> Vars; 19853 DSAStackTy::OperatorOffsetTy OpsOffs; 19854 llvm::APSInt DepCounter(/*BitWidth=*/32); 19855 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 19856 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 19857 if (const Expr *OrderedCountExpr = 19858 DSAStack->getParentOrderedRegionParam().first) { 19859 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 19860 TotalDepCount.setIsUnsigned(/*Val=*/true); 19861 } 19862 } 19863 for (Expr *RefExpr : VarList) { 19864 assert(RefExpr && "NULL expr in OpenMP shared clause."); 19865 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 19866 // It will be analyzed later. 19867 Vars.push_back(RefExpr); 19868 continue; 19869 } 19870 19871 SourceLocation ELoc = RefExpr->getExprLoc(); 19872 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 19873 if (DepKind == OMPC_DEPEND_sink) { 19874 if (DSAStack->getParentOrderedRegionParam().first && 19875 DepCounter >= TotalDepCount) { 19876 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 19877 continue; 19878 } 19879 ++DepCounter; 19880 // OpenMP [2.13.9, Summary] 19881 // depend(dependence-type : vec), where dependence-type is: 19882 // 'sink' and where vec is the iteration vector, which has the form: 19883 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 19884 // where n is the value specified by the ordered clause in the loop 19885 // directive, xi denotes the loop iteration variable of the i-th nested 19886 // loop associated with the loop directive, and di is a constant 19887 // non-negative integer. 19888 if (CurContext->isDependentContext()) { 19889 // It will be analyzed later. 19890 Vars.push_back(RefExpr); 19891 continue; 19892 } 19893 SimpleExpr = SimpleExpr->IgnoreImplicit(); 19894 OverloadedOperatorKind OOK = OO_None; 19895 SourceLocation OOLoc; 19896 Expr *LHS = SimpleExpr; 19897 Expr *RHS = nullptr; 19898 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 19899 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 19900 OOLoc = BO->getOperatorLoc(); 19901 LHS = BO->getLHS()->IgnoreParenImpCasts(); 19902 RHS = BO->getRHS()->IgnoreParenImpCasts(); 19903 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 19904 OOK = OCE->getOperator(); 19905 OOLoc = OCE->getOperatorLoc(); 19906 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 19907 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 19908 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 19909 OOK = MCE->getMethodDecl() 19910 ->getNameInfo() 19911 .getName() 19912 .getCXXOverloadedOperator(); 19913 OOLoc = MCE->getCallee()->getExprLoc(); 19914 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 19915 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 19916 } 19917 SourceLocation ELoc; 19918 SourceRange ERange; 19919 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 19920 if (Res.second) { 19921 // It will be analyzed later. 19922 Vars.push_back(RefExpr); 19923 } 19924 ValueDecl *D = Res.first; 19925 if (!D) 19926 continue; 19927 19928 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 19929 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 19930 continue; 19931 } 19932 if (RHS) { 19933 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 19934 RHS, OMPC_depend, /*StrictlyPositive=*/false); 19935 if (RHSRes.isInvalid()) 19936 continue; 19937 } 19938 if (!CurContext->isDependentContext() && 19939 DSAStack->getParentOrderedRegionParam().first && 19940 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 19941 const ValueDecl *VD = 19942 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 19943 if (VD) 19944 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 19945 << 1 << VD; 19946 else 19947 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 19948 continue; 19949 } 19950 OpsOffs.emplace_back(RHS, OOK); 19951 } else { 19952 bool OMPDependTFound = LangOpts.OpenMP >= 50; 19953 if (OMPDependTFound) 19954 OMPDependTFound = findOMPDependT(*this, StartLoc, DSAStack, 19955 DepKind == OMPC_DEPEND_depobj); 19956 if (DepKind == OMPC_DEPEND_depobj) { 19957 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 19958 // List items used in depend clauses with the depobj dependence type 19959 // must be expressions of the omp_depend_t type. 19960 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 19961 !RefExpr->isInstantiationDependent() && 19962 !RefExpr->containsUnexpandedParameterPack() && 19963 (OMPDependTFound && 19964 !Context.hasSameUnqualifiedType(DSAStack->getOMPDependT(), 19965 RefExpr->getType()))) { 19966 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 19967 << 0 << RefExpr->getType() << RefExpr->getSourceRange(); 19968 continue; 19969 } 19970 if (!RefExpr->isLValue()) { 19971 Diag(ELoc, diag::err_omp_expected_omp_depend_t_lvalue) 19972 << 1 << RefExpr->getType() << RefExpr->getSourceRange(); 19973 continue; 19974 } 19975 } else { 19976 // OpenMP 5.0 [2.17.11, Restrictions] 19977 // List items used in depend clauses cannot be zero-length array 19978 // sections. 19979 QualType ExprTy = RefExpr->getType().getNonReferenceType(); 19980 const auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 19981 if (OASE) { 19982 QualType BaseType = 19983 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 19984 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 19985 ExprTy = ATy->getElementType(); 19986 else 19987 ExprTy = BaseType->getPointeeType(); 19988 ExprTy = ExprTy.getNonReferenceType(); 19989 const Expr *Length = OASE->getLength(); 19990 Expr::EvalResult Result; 19991 if (Length && !Length->isValueDependent() && 19992 Length->EvaluateAsInt(Result, Context) && 19993 Result.Val.getInt().isZero()) { 19994 Diag(ELoc, 19995 diag::err_omp_depend_zero_length_array_section_not_allowed) 19996 << SimpleExpr->getSourceRange(); 19997 continue; 19998 } 19999 } 20000 20001 // OpenMP 5.0, 2.17.11 depend Clause, Restrictions, C/C++ 20002 // List items used in depend clauses with the in, out, inout, 20003 // inoutset, or mutexinoutset dependence types cannot be 20004 // expressions of the omp_depend_t type. 20005 if (!RefExpr->isValueDependent() && !RefExpr->isTypeDependent() && 20006 !RefExpr->isInstantiationDependent() && 20007 !RefExpr->containsUnexpandedParameterPack() && 20008 (!RefExpr->IgnoreParenImpCasts()->isLValue() || 20009 (OMPDependTFound && 20010 DSAStack->getOMPDependT().getTypePtr() == ExprTy.getTypePtr()))) { 20011 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 20012 << (LangOpts.OpenMP >= 50 ? 1 : 0) 20013 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 20014 continue; 20015 } 20016 20017 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 20018 if (ASE && !ASE->getBase()->isTypeDependent() && 20019 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 20020 !ASE->getBase()->getType().getNonReferenceType()->isArrayType()) { 20021 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 20022 << (LangOpts.OpenMP >= 50 ? 1 : 0) 20023 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 20024 continue; 20025 } 20026 20027 ExprResult Res; 20028 { 20029 Sema::TentativeAnalysisScope Trap(*this); 20030 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 20031 RefExpr->IgnoreParenImpCasts()); 20032 } 20033 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 20034 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 20035 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 20036 << (LangOpts.OpenMP >= 50 ? 1 : 0) 20037 << (LangOpts.OpenMP >= 50 ? 1 : 0) << RefExpr->getSourceRange(); 20038 continue; 20039 } 20040 } 20041 } 20042 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 20043 } 20044 20045 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 20046 TotalDepCount > VarList.size() && 20047 DSAStack->getParentOrderedRegionParam().first && 20048 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 20049 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 20050 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 20051 } 20052 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 20053 DepKind != OMPC_DEPEND_outallmemory && 20054 DepKind != OMPC_DEPEND_inoutallmemory && Vars.empty()) 20055 return nullptr; 20056 20057 auto *C = OMPDependClause::Create( 20058 Context, StartLoc, LParenLoc, EndLoc, 20059 {DepKind, DepLoc, Data.ColonLoc, Data.OmpAllMemoryLoc}, DepModifier, Vars, 20060 TotalDepCount.getZExtValue()); 20061 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 20062 DSAStack->isParentOrderedRegion()) 20063 DSAStack->addDoacrossDependClause(C, OpsOffs); 20064 return C; 20065 } 20066 20067 OMPClause *Sema::ActOnOpenMPDeviceClause(OpenMPDeviceClauseModifier Modifier, 20068 Expr *Device, SourceLocation StartLoc, 20069 SourceLocation LParenLoc, 20070 SourceLocation ModifierLoc, 20071 SourceLocation EndLoc) { 20072 assert((ModifierLoc.isInvalid() || LangOpts.OpenMP >= 50) && 20073 "Unexpected device modifier in OpenMP < 50."); 20074 20075 bool ErrorFound = false; 20076 if (ModifierLoc.isValid() && Modifier == OMPC_DEVICE_unknown) { 20077 std::string Values = 20078 getListOfPossibleValues(OMPC_device, /*First=*/0, OMPC_DEVICE_unknown); 20079 Diag(ModifierLoc, diag::err_omp_unexpected_clause_value) 20080 << Values << getOpenMPClauseName(OMPC_device); 20081 ErrorFound = true; 20082 } 20083 20084 Expr *ValExpr = Device; 20085 Stmt *HelperValStmt = nullptr; 20086 20087 // OpenMP [2.9.1, Restrictions] 20088 // The device expression must evaluate to a non-negative integer value. 20089 ErrorFound = !isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 20090 /*StrictlyPositive=*/false) || 20091 ErrorFound; 20092 if (ErrorFound) 20093 return nullptr; 20094 20095 // OpenMP 5.0 [2.12.5, Restrictions] 20096 // In case of ancestor device-modifier, a requires directive with 20097 // the reverse_offload clause must be specified. 20098 if (Modifier == OMPC_DEVICE_ancestor) { 20099 if (!DSAStack->hasRequiresDeclWithClause<OMPReverseOffloadClause>()) { 20100 targetDiag( 20101 StartLoc, 20102 diag::err_omp_device_ancestor_without_requires_reverse_offload); 20103 ErrorFound = true; 20104 } 20105 } 20106 20107 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 20108 OpenMPDirectiveKind CaptureRegion = 20109 getOpenMPCaptureRegionForClause(DKind, OMPC_device, LangOpts.OpenMP); 20110 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 20111 ValExpr = MakeFullExpr(ValExpr).get(); 20112 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 20113 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 20114 HelperValStmt = buildPreInits(Context, Captures); 20115 } 20116 20117 return new (Context) 20118 OMPDeviceClause(Modifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 20119 LParenLoc, ModifierLoc, EndLoc); 20120 } 20121 20122 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 20123 DSAStackTy *Stack, QualType QTy, 20124 bool FullCheck = true) { 20125 if (SemaRef.RequireCompleteType(SL, QTy, diag::err_incomplete_type)) 20126 return false; 20127 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 20128 !QTy.isTriviallyCopyableType(SemaRef.Context)) 20129 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 20130 return true; 20131 } 20132 20133 /// Return true if it can be proven that the provided array expression 20134 /// (array section or array subscript) does NOT specify the whole size of the 20135 /// array whose base type is \a BaseQTy. 20136 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 20137 const Expr *E, 20138 QualType BaseQTy) { 20139 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 20140 20141 // If this is an array subscript, it refers to the whole size if the size of 20142 // the dimension is constant and equals 1. Also, an array section assumes the 20143 // format of an array subscript if no colon is used. 20144 if (isa<ArraySubscriptExpr>(E) || 20145 (OASE && OASE->getColonLocFirst().isInvalid())) { 20146 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 20147 return ATy->getSize().getSExtValue() != 1; 20148 // Size can't be evaluated statically. 20149 return false; 20150 } 20151 20152 assert(OASE && "Expecting array section if not an array subscript."); 20153 const Expr *LowerBound = OASE->getLowerBound(); 20154 const Expr *Length = OASE->getLength(); 20155 20156 // If there is a lower bound that does not evaluates to zero, we are not 20157 // covering the whole dimension. 20158 if (LowerBound) { 20159 Expr::EvalResult Result; 20160 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 20161 return false; // Can't get the integer value as a constant. 20162 20163 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 20164 if (ConstLowerBound.getSExtValue()) 20165 return true; 20166 } 20167 20168 // If we don't have a length we covering the whole dimension. 20169 if (!Length) 20170 return false; 20171 20172 // If the base is a pointer, we don't have a way to get the size of the 20173 // pointee. 20174 if (BaseQTy->isPointerType()) 20175 return false; 20176 20177 // We can only check if the length is the same as the size of the dimension 20178 // if we have a constant array. 20179 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 20180 if (!CATy) 20181 return false; 20182 20183 Expr::EvalResult Result; 20184 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 20185 return false; // Can't get the integer value as a constant. 20186 20187 llvm::APSInt ConstLength = Result.Val.getInt(); 20188 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 20189 } 20190 20191 // Return true if it can be proven that the provided array expression (array 20192 // section or array subscript) does NOT specify a single element of the array 20193 // whose base type is \a BaseQTy. 20194 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 20195 const Expr *E, 20196 QualType BaseQTy) { 20197 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 20198 20199 // An array subscript always refer to a single element. Also, an array section 20200 // assumes the format of an array subscript if no colon is used. 20201 if (isa<ArraySubscriptExpr>(E) || 20202 (OASE && OASE->getColonLocFirst().isInvalid())) 20203 return false; 20204 20205 assert(OASE && "Expecting array section if not an array subscript."); 20206 const Expr *Length = OASE->getLength(); 20207 20208 // If we don't have a length we have to check if the array has unitary size 20209 // for this dimension. Also, we should always expect a length if the base type 20210 // is pointer. 20211 if (!Length) { 20212 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 20213 return ATy->getSize().getSExtValue() != 1; 20214 // We cannot assume anything. 20215 return false; 20216 } 20217 20218 // Check if the length evaluates to 1. 20219 Expr::EvalResult Result; 20220 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 20221 return false; // Can't get the integer value as a constant. 20222 20223 llvm::APSInt ConstLength = Result.Val.getInt(); 20224 return ConstLength.getSExtValue() != 1; 20225 } 20226 20227 // The base of elements of list in a map clause have to be either: 20228 // - a reference to variable or field. 20229 // - a member expression. 20230 // - an array expression. 20231 // 20232 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 20233 // reference to 'r'. 20234 // 20235 // If we have: 20236 // 20237 // struct SS { 20238 // Bla S; 20239 // foo() { 20240 // #pragma omp target map (S.Arr[:12]); 20241 // } 20242 // } 20243 // 20244 // We want to retrieve the member expression 'this->S'; 20245 20246 // OpenMP 5.0 [2.19.7.1, map Clause, Restrictions, p.2] 20247 // If a list item is an array section, it must specify contiguous storage. 20248 // 20249 // For this restriction it is sufficient that we make sure only references 20250 // to variables or fields and array expressions, and that no array sections 20251 // exist except in the rightmost expression (unless they cover the whole 20252 // dimension of the array). E.g. these would be invalid: 20253 // 20254 // r.ArrS[3:5].Arr[6:7] 20255 // 20256 // r.ArrS[3:5].x 20257 // 20258 // but these would be valid: 20259 // r.ArrS[3].Arr[6:7] 20260 // 20261 // r.ArrS[3].x 20262 namespace { 20263 class MapBaseChecker final : public StmtVisitor<MapBaseChecker, bool> { 20264 Sema &SemaRef; 20265 OpenMPClauseKind CKind = OMPC_unknown; 20266 OpenMPDirectiveKind DKind = OMPD_unknown; 20267 OMPClauseMappableExprCommon::MappableExprComponentList &Components; 20268 bool IsNonContiguous = false; 20269 bool NoDiagnose = false; 20270 const Expr *RelevantExpr = nullptr; 20271 bool AllowUnitySizeArraySection = true; 20272 bool AllowWholeSizeArraySection = true; 20273 bool AllowAnotherPtr = true; 20274 SourceLocation ELoc; 20275 SourceRange ERange; 20276 20277 void emitErrorMsg() { 20278 // If nothing else worked, this is not a valid map clause expression. 20279 if (SemaRef.getLangOpts().OpenMP < 50) { 20280 SemaRef.Diag(ELoc, 20281 diag::err_omp_expected_named_var_member_or_array_expression) 20282 << ERange; 20283 } else { 20284 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 20285 << getOpenMPClauseName(CKind) << ERange; 20286 } 20287 } 20288 20289 public: 20290 bool VisitDeclRefExpr(DeclRefExpr *DRE) { 20291 if (!isa<VarDecl>(DRE->getDecl())) { 20292 emitErrorMsg(); 20293 return false; 20294 } 20295 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20296 RelevantExpr = DRE; 20297 // Record the component. 20298 Components.emplace_back(DRE, DRE->getDecl(), IsNonContiguous); 20299 return true; 20300 } 20301 20302 bool VisitMemberExpr(MemberExpr *ME) { 20303 Expr *E = ME; 20304 Expr *BaseE = ME->getBase()->IgnoreParenCasts(); 20305 20306 if (isa<CXXThisExpr>(BaseE)) { 20307 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20308 // We found a base expression: this->Val. 20309 RelevantExpr = ME; 20310 } else { 20311 E = BaseE; 20312 } 20313 20314 if (!isa<FieldDecl>(ME->getMemberDecl())) { 20315 if (!NoDiagnose) { 20316 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 20317 << ME->getSourceRange(); 20318 return false; 20319 } 20320 if (RelevantExpr) 20321 return false; 20322 return Visit(E); 20323 } 20324 20325 auto *FD = cast<FieldDecl>(ME->getMemberDecl()); 20326 20327 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 20328 // A bit-field cannot appear in a map clause. 20329 // 20330 if (FD->isBitField()) { 20331 if (!NoDiagnose) { 20332 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 20333 << ME->getSourceRange() << getOpenMPClauseName(CKind); 20334 return false; 20335 } 20336 if (RelevantExpr) 20337 return false; 20338 return Visit(E); 20339 } 20340 20341 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 20342 // If the type of a list item is a reference to a type T then the type 20343 // will be considered to be T for all purposes of this clause. 20344 QualType CurType = BaseE->getType().getNonReferenceType(); 20345 20346 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 20347 // A list item cannot be a variable that is a member of a structure with 20348 // a union type. 20349 // 20350 if (CurType->isUnionType()) { 20351 if (!NoDiagnose) { 20352 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 20353 << ME->getSourceRange(); 20354 return false; 20355 } 20356 return RelevantExpr || Visit(E); 20357 } 20358 20359 // If we got a member expression, we should not expect any array section 20360 // before that: 20361 // 20362 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 20363 // If a list item is an element of a structure, only the rightmost symbol 20364 // of the variable reference can be an array section. 20365 // 20366 AllowUnitySizeArraySection = false; 20367 AllowWholeSizeArraySection = false; 20368 20369 // Record the component. 20370 Components.emplace_back(ME, FD, IsNonContiguous); 20371 return RelevantExpr || Visit(E); 20372 } 20373 20374 bool VisitArraySubscriptExpr(ArraySubscriptExpr *AE) { 20375 Expr *E = AE->getBase()->IgnoreParenImpCasts(); 20376 20377 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 20378 if (!NoDiagnose) { 20379 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 20380 << 0 << AE->getSourceRange(); 20381 return false; 20382 } 20383 return RelevantExpr || Visit(E); 20384 } 20385 20386 // If we got an array subscript that express the whole dimension we 20387 // can have any array expressions before. If it only expressing part of 20388 // the dimension, we can only have unitary-size array expressions. 20389 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, AE, E->getType())) 20390 AllowWholeSizeArraySection = false; 20391 20392 if (const auto *TE = dyn_cast<CXXThisExpr>(E->IgnoreParenCasts())) { 20393 Expr::EvalResult Result; 20394 if (!AE->getIdx()->isValueDependent() && 20395 AE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext()) && 20396 !Result.Val.getInt().isZero()) { 20397 SemaRef.Diag(AE->getIdx()->getExprLoc(), 20398 diag::err_omp_invalid_map_this_expr); 20399 SemaRef.Diag(AE->getIdx()->getExprLoc(), 20400 diag::note_omp_invalid_subscript_on_this_ptr_map); 20401 } 20402 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20403 RelevantExpr = TE; 20404 } 20405 20406 // Record the component - we don't have any declaration associated. 20407 Components.emplace_back(AE, nullptr, IsNonContiguous); 20408 20409 return RelevantExpr || Visit(E); 20410 } 20411 20412 bool VisitOMPArraySectionExpr(OMPArraySectionExpr *OASE) { 20413 // After OMP 5.0 Array section in reduction clause will be implicitly 20414 // mapped 20415 assert(!(SemaRef.getLangOpts().OpenMP < 50 && NoDiagnose) && 20416 "Array sections cannot be implicitly mapped."); 20417 Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 20418 QualType CurType = 20419 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 20420 20421 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 20422 // If the type of a list item is a reference to a type T then the type 20423 // will be considered to be T for all purposes of this clause. 20424 if (CurType->isReferenceType()) 20425 CurType = CurType->getPointeeType(); 20426 20427 bool IsPointer = CurType->isAnyPointerType(); 20428 20429 if (!IsPointer && !CurType->isArrayType()) { 20430 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 20431 << 0 << OASE->getSourceRange(); 20432 return false; 20433 } 20434 20435 bool NotWhole = 20436 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, OASE, CurType); 20437 bool NotUnity = 20438 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, OASE, CurType); 20439 20440 if (AllowWholeSizeArraySection) { 20441 // Any array section is currently allowed. Allowing a whole size array 20442 // section implies allowing a unity array section as well. 20443 // 20444 // If this array section refers to the whole dimension we can still 20445 // accept other array sections before this one, except if the base is a 20446 // pointer. Otherwise, only unitary sections are accepted. 20447 if (NotWhole || IsPointer) 20448 AllowWholeSizeArraySection = false; 20449 } else if (DKind == OMPD_target_update && 20450 SemaRef.getLangOpts().OpenMP >= 50) { 20451 if (IsPointer && !AllowAnotherPtr) 20452 SemaRef.Diag(ELoc, diag::err_omp_section_length_undefined) 20453 << /*array of unknown bound */ 1; 20454 else 20455 IsNonContiguous = true; 20456 } else if (AllowUnitySizeArraySection && NotUnity) { 20457 // A unity or whole array section is not allowed and that is not 20458 // compatible with the properties of the current array section. 20459 if (NoDiagnose) 20460 return false; 20461 SemaRef.Diag(ELoc, 20462 diag::err_array_section_does_not_specify_contiguous_storage) 20463 << OASE->getSourceRange(); 20464 return false; 20465 } 20466 20467 if (IsPointer) 20468 AllowAnotherPtr = false; 20469 20470 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 20471 Expr::EvalResult ResultR; 20472 Expr::EvalResult ResultL; 20473 if (!OASE->getLength()->isValueDependent() && 20474 OASE->getLength()->EvaluateAsInt(ResultR, SemaRef.getASTContext()) && 20475 !ResultR.Val.getInt().isOne()) { 20476 SemaRef.Diag(OASE->getLength()->getExprLoc(), 20477 diag::err_omp_invalid_map_this_expr); 20478 SemaRef.Diag(OASE->getLength()->getExprLoc(), 20479 diag::note_omp_invalid_length_on_this_ptr_mapping); 20480 } 20481 if (OASE->getLowerBound() && !OASE->getLowerBound()->isValueDependent() && 20482 OASE->getLowerBound()->EvaluateAsInt(ResultL, 20483 SemaRef.getASTContext()) && 20484 !ResultL.Val.getInt().isZero()) { 20485 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 20486 diag::err_omp_invalid_map_this_expr); 20487 SemaRef.Diag(OASE->getLowerBound()->getExprLoc(), 20488 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 20489 } 20490 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20491 RelevantExpr = TE; 20492 } 20493 20494 // Record the component - we don't have any declaration associated. 20495 Components.emplace_back(OASE, nullptr, /*IsNonContiguous=*/false); 20496 return RelevantExpr || Visit(E); 20497 } 20498 bool VisitOMPArrayShapingExpr(OMPArrayShapingExpr *E) { 20499 Expr *Base = E->getBase(); 20500 20501 // Record the component - we don't have any declaration associated. 20502 Components.emplace_back(E, nullptr, IsNonContiguous); 20503 20504 return Visit(Base->IgnoreParenImpCasts()); 20505 } 20506 20507 bool VisitUnaryOperator(UnaryOperator *UO) { 20508 if (SemaRef.getLangOpts().OpenMP < 50 || !UO->isLValue() || 20509 UO->getOpcode() != UO_Deref) { 20510 emitErrorMsg(); 20511 return false; 20512 } 20513 if (!RelevantExpr) { 20514 // Record the component if haven't found base decl. 20515 Components.emplace_back(UO, nullptr, /*IsNonContiguous=*/false); 20516 } 20517 return RelevantExpr || Visit(UO->getSubExpr()->IgnoreParenImpCasts()); 20518 } 20519 bool VisitBinaryOperator(BinaryOperator *BO) { 20520 if (SemaRef.getLangOpts().OpenMP < 50 || !BO->getType()->isPointerType()) { 20521 emitErrorMsg(); 20522 return false; 20523 } 20524 20525 // Pointer arithmetic is the only thing we expect to happen here so after we 20526 // make sure the binary operator is a pointer type, the we only thing need 20527 // to to is to visit the subtree that has the same type as root (so that we 20528 // know the other subtree is just an offset) 20529 Expr *LE = BO->getLHS()->IgnoreParenImpCasts(); 20530 Expr *RE = BO->getRHS()->IgnoreParenImpCasts(); 20531 Components.emplace_back(BO, nullptr, false); 20532 assert((LE->getType().getTypePtr() == BO->getType().getTypePtr() || 20533 RE->getType().getTypePtr() == BO->getType().getTypePtr()) && 20534 "Either LHS or RHS have base decl inside"); 20535 if (BO->getType().getTypePtr() == LE->getType().getTypePtr()) 20536 return RelevantExpr || Visit(LE); 20537 return RelevantExpr || Visit(RE); 20538 } 20539 bool VisitCXXThisExpr(CXXThisExpr *CTE) { 20540 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20541 RelevantExpr = CTE; 20542 Components.emplace_back(CTE, nullptr, IsNonContiguous); 20543 return true; 20544 } 20545 bool VisitCXXOperatorCallExpr(CXXOperatorCallExpr *COCE) { 20546 assert(!RelevantExpr && "RelevantExpr is expected to be nullptr"); 20547 Components.emplace_back(COCE, nullptr, IsNonContiguous); 20548 return true; 20549 } 20550 bool VisitOpaqueValueExpr(OpaqueValueExpr *E) { 20551 Expr *Source = E->getSourceExpr(); 20552 if (!Source) { 20553 emitErrorMsg(); 20554 return false; 20555 } 20556 return Visit(Source); 20557 } 20558 bool VisitStmt(Stmt *) { 20559 emitErrorMsg(); 20560 return false; 20561 } 20562 const Expr *getFoundBase() const { return RelevantExpr; } 20563 explicit MapBaseChecker( 20564 Sema &SemaRef, OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, 20565 OMPClauseMappableExprCommon::MappableExprComponentList &Components, 20566 bool NoDiagnose, SourceLocation &ELoc, SourceRange &ERange) 20567 : SemaRef(SemaRef), CKind(CKind), DKind(DKind), Components(Components), 20568 NoDiagnose(NoDiagnose), ELoc(ELoc), ERange(ERange) {} 20569 }; 20570 } // namespace 20571 20572 /// Return the expression of the base of the mappable expression or null if it 20573 /// cannot be determined and do all the necessary checks to see if the 20574 /// expression is valid as a standalone mappable expression. In the process, 20575 /// record all the components of the expression. 20576 static const Expr *checkMapClauseExpressionBase( 20577 Sema &SemaRef, Expr *E, 20578 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 20579 OpenMPClauseKind CKind, OpenMPDirectiveKind DKind, bool NoDiagnose) { 20580 SourceLocation ELoc = E->getExprLoc(); 20581 SourceRange ERange = E->getSourceRange(); 20582 MapBaseChecker Checker(SemaRef, CKind, DKind, CurComponents, NoDiagnose, ELoc, 20583 ERange); 20584 if (Checker.Visit(E->IgnoreParens())) { 20585 // Check if the highest dimension array section has length specified 20586 if (SemaRef.getLangOpts().OpenMP >= 50 && !CurComponents.empty() && 20587 (CKind == OMPC_to || CKind == OMPC_from)) { 20588 auto CI = CurComponents.rbegin(); 20589 auto CE = CurComponents.rend(); 20590 for (; CI != CE; ++CI) { 20591 const auto *OASE = 20592 dyn_cast<OMPArraySectionExpr>(CI->getAssociatedExpression()); 20593 if (!OASE) 20594 continue; 20595 if (OASE && OASE->getLength()) 20596 break; 20597 SemaRef.Diag(ELoc, diag::err_array_section_does_not_specify_length) 20598 << ERange; 20599 } 20600 } 20601 return Checker.getFoundBase(); 20602 } 20603 return nullptr; 20604 } 20605 20606 // Return true if expression E associated with value VD has conflicts with other 20607 // map information. 20608 static bool checkMapConflicts( 20609 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 20610 bool CurrentRegionOnly, 20611 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 20612 OpenMPClauseKind CKind) { 20613 assert(VD && E); 20614 SourceLocation ELoc = E->getExprLoc(); 20615 SourceRange ERange = E->getSourceRange(); 20616 20617 // In order to easily check the conflicts we need to match each component of 20618 // the expression under test with the components of the expressions that are 20619 // already in the stack. 20620 20621 assert(!CurComponents.empty() && "Map clause expression with no components!"); 20622 assert(CurComponents.back().getAssociatedDeclaration() == VD && 20623 "Map clause expression with unexpected base!"); 20624 20625 // Variables to help detecting enclosing problems in data environment nests. 20626 bool IsEnclosedByDataEnvironmentExpr = false; 20627 const Expr *EnclosingExpr = nullptr; 20628 20629 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 20630 VD, CurrentRegionOnly, 20631 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 20632 ERange, CKind, &EnclosingExpr, 20633 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 20634 StackComponents, 20635 OpenMPClauseKind Kind) { 20636 if (CKind == Kind && SemaRef.LangOpts.OpenMP >= 50) 20637 return false; 20638 assert(!StackComponents.empty() && 20639 "Map clause expression with no components!"); 20640 assert(StackComponents.back().getAssociatedDeclaration() == VD && 20641 "Map clause expression with unexpected base!"); 20642 (void)VD; 20643 20644 // The whole expression in the stack. 20645 const Expr *RE = StackComponents.front().getAssociatedExpression(); 20646 20647 // Expressions must start from the same base. Here we detect at which 20648 // point both expressions diverge from each other and see if we can 20649 // detect if the memory referred to both expressions is contiguous and 20650 // do not overlap. 20651 auto CI = CurComponents.rbegin(); 20652 auto CE = CurComponents.rend(); 20653 auto SI = StackComponents.rbegin(); 20654 auto SE = StackComponents.rend(); 20655 for (; CI != CE && SI != SE; ++CI, ++SI) { 20656 20657 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 20658 // At most one list item can be an array item derived from a given 20659 // variable in map clauses of the same construct. 20660 if (CurrentRegionOnly && 20661 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 20662 isa<OMPArraySectionExpr>(CI->getAssociatedExpression()) || 20663 isa<OMPArrayShapingExpr>(CI->getAssociatedExpression())) && 20664 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 20665 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()) || 20666 isa<OMPArrayShapingExpr>(SI->getAssociatedExpression()))) { 20667 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 20668 diag::err_omp_multiple_array_items_in_map_clause) 20669 << CI->getAssociatedExpression()->getSourceRange(); 20670 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 20671 diag::note_used_here) 20672 << SI->getAssociatedExpression()->getSourceRange(); 20673 return true; 20674 } 20675 20676 // Do both expressions have the same kind? 20677 if (CI->getAssociatedExpression()->getStmtClass() != 20678 SI->getAssociatedExpression()->getStmtClass()) 20679 break; 20680 20681 // Are we dealing with different variables/fields? 20682 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 20683 break; 20684 } 20685 // Check if the extra components of the expressions in the enclosing 20686 // data environment are redundant for the current base declaration. 20687 // If they are, the maps completely overlap, which is legal. 20688 for (; SI != SE; ++SI) { 20689 QualType Type; 20690 if (const auto *ASE = 20691 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 20692 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 20693 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 20694 SI->getAssociatedExpression())) { 20695 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 20696 Type = 20697 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 20698 } else if (const auto *OASE = dyn_cast<OMPArrayShapingExpr>( 20699 SI->getAssociatedExpression())) { 20700 Type = OASE->getBase()->getType()->getPointeeType(); 20701 } 20702 if (Type.isNull() || Type->isAnyPointerType() || 20703 checkArrayExpressionDoesNotReferToWholeSize( 20704 SemaRef, SI->getAssociatedExpression(), Type)) 20705 break; 20706 } 20707 20708 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 20709 // List items of map clauses in the same construct must not share 20710 // original storage. 20711 // 20712 // If the expressions are exactly the same or one is a subset of the 20713 // other, it means they are sharing storage. 20714 if (CI == CE && SI == SE) { 20715 if (CurrentRegionOnly) { 20716 if (CKind == OMPC_map) { 20717 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 20718 } else { 20719 assert(CKind == OMPC_to || CKind == OMPC_from); 20720 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 20721 << ERange; 20722 } 20723 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20724 << RE->getSourceRange(); 20725 return true; 20726 } 20727 // If we find the same expression in the enclosing data environment, 20728 // that is legal. 20729 IsEnclosedByDataEnvironmentExpr = true; 20730 return false; 20731 } 20732 20733 QualType DerivedType = 20734 std::prev(CI)->getAssociatedDeclaration()->getType(); 20735 SourceLocation DerivedLoc = 20736 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 20737 20738 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 20739 // If the type of a list item is a reference to a type T then the type 20740 // will be considered to be T for all purposes of this clause. 20741 DerivedType = DerivedType.getNonReferenceType(); 20742 20743 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 20744 // A variable for which the type is pointer and an array section 20745 // derived from that variable must not appear as list items of map 20746 // clauses of the same construct. 20747 // 20748 // Also, cover one of the cases in: 20749 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 20750 // If any part of the original storage of a list item has corresponding 20751 // storage in the device data environment, all of the original storage 20752 // must have corresponding storage in the device data environment. 20753 // 20754 if (DerivedType->isAnyPointerType()) { 20755 if (CI == CE || SI == SE) { 20756 SemaRef.Diag( 20757 DerivedLoc, 20758 diag::err_omp_pointer_mapped_along_with_derived_section) 20759 << DerivedLoc; 20760 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20761 << RE->getSourceRange(); 20762 return true; 20763 } 20764 if (CI->getAssociatedExpression()->getStmtClass() != 20765 SI->getAssociatedExpression()->getStmtClass() || 20766 CI->getAssociatedDeclaration()->getCanonicalDecl() == 20767 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 20768 assert(CI != CE && SI != SE); 20769 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 20770 << DerivedLoc; 20771 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20772 << RE->getSourceRange(); 20773 return true; 20774 } 20775 } 20776 20777 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 20778 // List items of map clauses in the same construct must not share 20779 // original storage. 20780 // 20781 // An expression is a subset of the other. 20782 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 20783 if (CKind == OMPC_map) { 20784 if (CI != CE || SI != SE) { 20785 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 20786 // a pointer. 20787 auto Begin = 20788 CI != CE ? CurComponents.begin() : StackComponents.begin(); 20789 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 20790 auto It = Begin; 20791 while (It != End && !It->getAssociatedDeclaration()) 20792 std::advance(It, 1); 20793 assert(It != End && 20794 "Expected at least one component with the declaration."); 20795 if (It != Begin && It->getAssociatedDeclaration() 20796 ->getType() 20797 .getCanonicalType() 20798 ->isAnyPointerType()) { 20799 IsEnclosedByDataEnvironmentExpr = false; 20800 EnclosingExpr = nullptr; 20801 return false; 20802 } 20803 } 20804 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 20805 } else { 20806 assert(CKind == OMPC_to || CKind == OMPC_from); 20807 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 20808 << ERange; 20809 } 20810 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 20811 << RE->getSourceRange(); 20812 return true; 20813 } 20814 20815 // The current expression uses the same base as other expression in the 20816 // data environment but does not contain it completely. 20817 if (!CurrentRegionOnly && SI != SE) 20818 EnclosingExpr = RE; 20819 20820 // The current expression is a subset of the expression in the data 20821 // environment. 20822 IsEnclosedByDataEnvironmentExpr |= 20823 (!CurrentRegionOnly && CI != CE && SI == SE); 20824 20825 return false; 20826 }); 20827 20828 if (CurrentRegionOnly) 20829 return FoundError; 20830 20831 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 20832 // If any part of the original storage of a list item has corresponding 20833 // storage in the device data environment, all of the original storage must 20834 // have corresponding storage in the device data environment. 20835 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 20836 // If a list item is an element of a structure, and a different element of 20837 // the structure has a corresponding list item in the device data environment 20838 // prior to a task encountering the construct associated with the map clause, 20839 // then the list item must also have a corresponding list item in the device 20840 // data environment prior to the task encountering the construct. 20841 // 20842 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 20843 SemaRef.Diag(ELoc, 20844 diag::err_omp_original_storage_is_shared_and_does_not_contain) 20845 << ERange; 20846 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 20847 << EnclosingExpr->getSourceRange(); 20848 return true; 20849 } 20850 20851 return FoundError; 20852 } 20853 20854 // Look up the user-defined mapper given the mapper name and mapped type, and 20855 // build a reference to it. 20856 static ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 20857 CXXScopeSpec &MapperIdScopeSpec, 20858 const DeclarationNameInfo &MapperId, 20859 QualType Type, 20860 Expr *UnresolvedMapper) { 20861 if (MapperIdScopeSpec.isInvalid()) 20862 return ExprError(); 20863 // Get the actual type for the array type. 20864 if (Type->isArrayType()) { 20865 assert(Type->getAsArrayTypeUnsafe() && "Expect to get a valid array type"); 20866 Type = Type->getAsArrayTypeUnsafe()->getElementType().getCanonicalType(); 20867 } 20868 // Find all user-defined mappers with the given MapperId. 20869 SmallVector<UnresolvedSet<8>, 4> Lookups; 20870 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 20871 Lookup.suppressDiagnostics(); 20872 if (S) { 20873 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 20874 NamedDecl *D = Lookup.getRepresentativeDecl(); 20875 while (S && !S->isDeclScope(D)) 20876 S = S->getParent(); 20877 if (S) 20878 S = S->getParent(); 20879 Lookups.emplace_back(); 20880 Lookups.back().append(Lookup.begin(), Lookup.end()); 20881 Lookup.clear(); 20882 } 20883 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 20884 // Extract the user-defined mappers with the given MapperId. 20885 Lookups.push_back(UnresolvedSet<8>()); 20886 for (NamedDecl *D : ULE->decls()) { 20887 auto *DMD = cast<OMPDeclareMapperDecl>(D); 20888 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 20889 Lookups.back().addDecl(DMD); 20890 } 20891 } 20892 // Defer the lookup for dependent types. The results will be passed through 20893 // UnresolvedMapper on instantiation. 20894 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 20895 Type->isInstantiationDependentType() || 20896 Type->containsUnexpandedParameterPack() || 20897 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 20898 return !D->isInvalidDecl() && 20899 (D->getType()->isDependentType() || 20900 D->getType()->isInstantiationDependentType() || 20901 D->getType()->containsUnexpandedParameterPack()); 20902 })) { 20903 UnresolvedSet<8> URS; 20904 for (const UnresolvedSet<8> &Set : Lookups) { 20905 if (Set.empty()) 20906 continue; 20907 URS.append(Set.begin(), Set.end()); 20908 } 20909 return UnresolvedLookupExpr::Create( 20910 SemaRef.Context, /*NamingClass=*/nullptr, 20911 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 20912 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 20913 } 20914 SourceLocation Loc = MapperId.getLoc(); 20915 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 20916 // The type must be of struct, union or class type in C and C++ 20917 if (!Type->isStructureOrClassType() && !Type->isUnionType() && 20918 (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default")) { 20919 SemaRef.Diag(Loc, diag::err_omp_mapper_wrong_type); 20920 return ExprError(); 20921 } 20922 // Perform argument dependent lookup. 20923 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 20924 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 20925 // Return the first user-defined mapper with the desired type. 20926 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 20927 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 20928 if (!D->isInvalidDecl() && 20929 SemaRef.Context.hasSameType(D->getType(), Type)) 20930 return D; 20931 return nullptr; 20932 })) 20933 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 20934 // Find the first user-defined mapper with a type derived from the desired 20935 // type. 20936 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 20937 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 20938 if (!D->isInvalidDecl() && 20939 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 20940 !Type.isMoreQualifiedThan(D->getType())) 20941 return D; 20942 return nullptr; 20943 })) { 20944 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 20945 /*DetectVirtual=*/false); 20946 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 20947 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 20948 VD->getType().getUnqualifiedType()))) { 20949 if (SemaRef.CheckBaseClassAccess( 20950 Loc, VD->getType(), Type, Paths.front(), 20951 /*DiagID=*/0) != Sema::AR_inaccessible) { 20952 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 20953 } 20954 } 20955 } 20956 } 20957 // Report error if a mapper is specified, but cannot be found. 20958 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 20959 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 20960 << Type << MapperId.getName(); 20961 return ExprError(); 20962 } 20963 return ExprEmpty(); 20964 } 20965 20966 namespace { 20967 // Utility struct that gathers all the related lists associated with a mappable 20968 // expression. 20969 struct MappableVarListInfo { 20970 // The list of expressions. 20971 ArrayRef<Expr *> VarList; 20972 // The list of processed expressions. 20973 SmallVector<Expr *, 16> ProcessedVarList; 20974 // The mappble components for each expression. 20975 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 20976 // The base declaration of the variable. 20977 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 20978 // The reference to the user-defined mapper associated with every expression. 20979 SmallVector<Expr *, 16> UDMapperList; 20980 20981 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 20982 // We have a list of components and base declarations for each entry in the 20983 // variable list. 20984 VarComponents.reserve(VarList.size()); 20985 VarBaseDeclarations.reserve(VarList.size()); 20986 } 20987 }; 20988 } // namespace 20989 20990 // Check the validity of the provided variable list for the provided clause kind 20991 // \a CKind. In the check process the valid expressions, mappable expression 20992 // components, variables, and user-defined mappers are extracted and used to 20993 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 20994 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 20995 // and \a MapperId are expected to be valid if the clause kind is 'map'. 20996 static void checkMappableExpressionList( 20997 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 20998 MappableVarListInfo &MVLI, SourceLocation StartLoc, 20999 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 21000 ArrayRef<Expr *> UnresolvedMappers, 21001 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 21002 ArrayRef<OpenMPMapModifierKind> Modifiers = None, 21003 bool IsMapTypeImplicit = false, bool NoDiagnose = false) { 21004 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 21005 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 21006 "Unexpected clause kind with mappable expressions!"); 21007 21008 // If the identifier of user-defined mapper is not specified, it is "default". 21009 // We do not change the actual name in this clause to distinguish whether a 21010 // mapper is specified explicitly, i.e., it is not explicitly specified when 21011 // MapperId.getName() is empty. 21012 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 21013 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 21014 MapperId.setName(DeclNames.getIdentifier( 21015 &SemaRef.getASTContext().Idents.get("default"))); 21016 MapperId.setLoc(StartLoc); 21017 } 21018 21019 // Iterators to find the current unresolved mapper expression. 21020 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 21021 bool UpdateUMIt = false; 21022 Expr *UnresolvedMapper = nullptr; 21023 21024 bool HasHoldModifier = 21025 llvm::is_contained(Modifiers, OMPC_MAP_MODIFIER_ompx_hold); 21026 21027 // Keep track of the mappable components and base declarations in this clause. 21028 // Each entry in the list is going to have a list of components associated. We 21029 // record each set of the components so that we can build the clause later on. 21030 // In the end we should have the same amount of declarations and component 21031 // lists. 21032 21033 for (Expr *RE : MVLI.VarList) { 21034 assert(RE && "Null expr in omp to/from/map clause"); 21035 SourceLocation ELoc = RE->getExprLoc(); 21036 21037 // Find the current unresolved mapper expression. 21038 if (UpdateUMIt && UMIt != UMEnd) { 21039 UMIt++; 21040 assert( 21041 UMIt != UMEnd && 21042 "Expect the size of UnresolvedMappers to match with that of VarList"); 21043 } 21044 UpdateUMIt = true; 21045 if (UMIt != UMEnd) 21046 UnresolvedMapper = *UMIt; 21047 21048 const Expr *VE = RE->IgnoreParenLValueCasts(); 21049 21050 if (VE->isValueDependent() || VE->isTypeDependent() || 21051 VE->isInstantiationDependent() || 21052 VE->containsUnexpandedParameterPack()) { 21053 // Try to find the associated user-defined mapper. 21054 ExprResult ER = buildUserDefinedMapperRef( 21055 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21056 VE->getType().getCanonicalType(), UnresolvedMapper); 21057 if (ER.isInvalid()) 21058 continue; 21059 MVLI.UDMapperList.push_back(ER.get()); 21060 // We can only analyze this information once the missing information is 21061 // resolved. 21062 MVLI.ProcessedVarList.push_back(RE); 21063 continue; 21064 } 21065 21066 Expr *SimpleExpr = RE->IgnoreParenCasts(); 21067 21068 if (!RE->isLValue()) { 21069 if (SemaRef.getLangOpts().OpenMP < 50) { 21070 SemaRef.Diag( 21071 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 21072 << RE->getSourceRange(); 21073 } else { 21074 SemaRef.Diag(ELoc, diag::err_omp_non_lvalue_in_map_or_motion_clauses) 21075 << getOpenMPClauseName(CKind) << RE->getSourceRange(); 21076 } 21077 continue; 21078 } 21079 21080 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 21081 ValueDecl *CurDeclaration = nullptr; 21082 21083 // Obtain the array or member expression bases if required. Also, fill the 21084 // components array with all the components identified in the process. 21085 const Expr *BE = 21086 checkMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind, 21087 DSAS->getCurrentDirective(), NoDiagnose); 21088 if (!BE) 21089 continue; 21090 21091 assert(!CurComponents.empty() && 21092 "Invalid mappable expression information."); 21093 21094 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 21095 // Add store "this" pointer to class in DSAStackTy for future checking 21096 DSAS->addMappedClassesQualTypes(TE->getType()); 21097 // Try to find the associated user-defined mapper. 21098 ExprResult ER = buildUserDefinedMapperRef( 21099 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21100 VE->getType().getCanonicalType(), UnresolvedMapper); 21101 if (ER.isInvalid()) 21102 continue; 21103 MVLI.UDMapperList.push_back(ER.get()); 21104 // Skip restriction checking for variable or field declarations 21105 MVLI.ProcessedVarList.push_back(RE); 21106 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 21107 MVLI.VarComponents.back().append(CurComponents.begin(), 21108 CurComponents.end()); 21109 MVLI.VarBaseDeclarations.push_back(nullptr); 21110 continue; 21111 } 21112 21113 // For the following checks, we rely on the base declaration which is 21114 // expected to be associated with the last component. The declaration is 21115 // expected to be a variable or a field (if 'this' is being mapped). 21116 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 21117 assert(CurDeclaration && "Null decl on map clause."); 21118 assert( 21119 CurDeclaration->isCanonicalDecl() && 21120 "Expecting components to have associated only canonical declarations."); 21121 21122 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 21123 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 21124 21125 assert((VD || FD) && "Only variables or fields are expected here!"); 21126 (void)FD; 21127 21128 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 21129 // threadprivate variables cannot appear in a map clause. 21130 // OpenMP 4.5 [2.10.5, target update Construct] 21131 // threadprivate variables cannot appear in a from clause. 21132 if (VD && DSAS->isThreadPrivate(VD)) { 21133 if (NoDiagnose) 21134 continue; 21135 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 21136 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 21137 << getOpenMPClauseName(CKind); 21138 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 21139 continue; 21140 } 21141 21142 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 21143 // A list item cannot appear in both a map clause and a data-sharing 21144 // attribute clause on the same construct. 21145 21146 // Check conflicts with other map clause expressions. We check the conflicts 21147 // with the current construct separately from the enclosing data 21148 // environment, because the restrictions are different. We only have to 21149 // check conflicts across regions for the map clauses. 21150 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 21151 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 21152 break; 21153 if (CKind == OMPC_map && 21154 (SemaRef.getLangOpts().OpenMP <= 45 || StartLoc.isValid()) && 21155 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 21156 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 21157 break; 21158 21159 // OpenMP 4.5 [2.10.5, target update Construct] 21160 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 21161 // If the type of a list item is a reference to a type T then the type will 21162 // be considered to be T for all purposes of this clause. 21163 auto I = llvm::find_if( 21164 CurComponents, 21165 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 21166 return MC.getAssociatedDeclaration(); 21167 }); 21168 assert(I != CurComponents.end() && "Null decl on map clause."); 21169 (void)I; 21170 QualType Type; 21171 auto *ASE = dyn_cast<ArraySubscriptExpr>(VE->IgnoreParens()); 21172 auto *OASE = dyn_cast<OMPArraySectionExpr>(VE->IgnoreParens()); 21173 auto *OAShE = dyn_cast<OMPArrayShapingExpr>(VE->IgnoreParens()); 21174 if (ASE) { 21175 Type = ASE->getType().getNonReferenceType(); 21176 } else if (OASE) { 21177 QualType BaseType = 21178 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 21179 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 21180 Type = ATy->getElementType(); 21181 else 21182 Type = BaseType->getPointeeType(); 21183 Type = Type.getNonReferenceType(); 21184 } else if (OAShE) { 21185 Type = OAShE->getBase()->getType()->getPointeeType(); 21186 } else { 21187 Type = VE->getType(); 21188 } 21189 21190 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 21191 // A list item in a to or from clause must have a mappable type. 21192 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 21193 // A list item must have a mappable type. 21194 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 21195 DSAS, Type, /*FullCheck=*/true)) 21196 continue; 21197 21198 if (CKind == OMPC_map) { 21199 // target enter data 21200 // OpenMP [2.10.2, Restrictions, p. 99] 21201 // A map-type must be specified in all map clauses and must be either 21202 // to or alloc. 21203 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 21204 if (DKind == OMPD_target_enter_data && 21205 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 21206 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21207 << (IsMapTypeImplicit ? 1 : 0) 21208 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21209 << getOpenMPDirectiveName(DKind); 21210 continue; 21211 } 21212 21213 // target exit_data 21214 // OpenMP [2.10.3, Restrictions, p. 102] 21215 // A map-type must be specified in all map clauses and must be either 21216 // from, release, or delete. 21217 if (DKind == OMPD_target_exit_data && 21218 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 21219 MapType == OMPC_MAP_delete)) { 21220 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21221 << (IsMapTypeImplicit ? 1 : 0) 21222 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21223 << getOpenMPDirectiveName(DKind); 21224 continue; 21225 } 21226 21227 // The 'ompx_hold' modifier is specifically intended to be used on a 21228 // 'target' or 'target data' directive to prevent data from being unmapped 21229 // during the associated statement. It is not permitted on a 'target 21230 // enter data' or 'target exit data' directive, which have no associated 21231 // statement. 21232 if ((DKind == OMPD_target_enter_data || DKind == OMPD_target_exit_data) && 21233 HasHoldModifier) { 21234 SemaRef.Diag(StartLoc, 21235 diag::err_omp_invalid_map_type_modifier_for_directive) 21236 << getOpenMPSimpleClauseTypeName(OMPC_map, 21237 OMPC_MAP_MODIFIER_ompx_hold) 21238 << getOpenMPDirectiveName(DKind); 21239 continue; 21240 } 21241 21242 // target, target data 21243 // OpenMP 5.0 [2.12.2, Restrictions, p. 163] 21244 // OpenMP 5.0 [2.12.5, Restrictions, p. 174] 21245 // A map-type in a map clause must be to, from, tofrom or alloc 21246 if ((DKind == OMPD_target_data || 21247 isOpenMPTargetExecutionDirective(DKind)) && 21248 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_from || 21249 MapType == OMPC_MAP_tofrom || MapType == OMPC_MAP_alloc)) { 21250 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 21251 << (IsMapTypeImplicit ? 1 : 0) 21252 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 21253 << getOpenMPDirectiveName(DKind); 21254 continue; 21255 } 21256 21257 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 21258 // A list item cannot appear in both a map clause and a data-sharing 21259 // attribute clause on the same construct 21260 // 21261 // OpenMP 5.0 [2.19.7.1, Restrictions, p.7] 21262 // A list item cannot appear in both a map clause and a data-sharing 21263 // attribute clause on the same construct unless the construct is a 21264 // combined construct. 21265 if (VD && ((SemaRef.LangOpts.OpenMP <= 45 && 21266 isOpenMPTargetExecutionDirective(DKind)) || 21267 DKind == OMPD_target)) { 21268 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 21269 if (isOpenMPPrivate(DVar.CKind)) { 21270 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 21271 << getOpenMPClauseName(DVar.CKind) 21272 << getOpenMPClauseName(OMPC_map) 21273 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 21274 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 21275 continue; 21276 } 21277 } 21278 } 21279 21280 // Try to find the associated user-defined mapper. 21281 ExprResult ER = buildUserDefinedMapperRef( 21282 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 21283 Type.getCanonicalType(), UnresolvedMapper); 21284 if (ER.isInvalid()) 21285 continue; 21286 MVLI.UDMapperList.push_back(ER.get()); 21287 21288 // Save the current expression. 21289 MVLI.ProcessedVarList.push_back(RE); 21290 21291 // Store the components in the stack so that they can be used to check 21292 // against other clauses later on. 21293 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 21294 /*WhereFoundClauseKind=*/OMPC_map); 21295 21296 // Save the components and declaration to create the clause. For purposes of 21297 // the clause creation, any component list that has has base 'this' uses 21298 // null as base declaration. 21299 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 21300 MVLI.VarComponents.back().append(CurComponents.begin(), 21301 CurComponents.end()); 21302 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 21303 : CurDeclaration); 21304 } 21305 } 21306 21307 OMPClause *Sema::ActOnOpenMPMapClause( 21308 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 21309 ArrayRef<SourceLocation> MapTypeModifiersLoc, 21310 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 21311 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 21312 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 21313 const OMPVarListLocTy &Locs, bool NoDiagnose, 21314 ArrayRef<Expr *> UnresolvedMappers) { 21315 OpenMPMapModifierKind Modifiers[] = { 21316 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 21317 OMPC_MAP_MODIFIER_unknown, OMPC_MAP_MODIFIER_unknown, 21318 OMPC_MAP_MODIFIER_unknown}; 21319 SourceLocation ModifiersLoc[NumberOfOMPMapClauseModifiers]; 21320 21321 // Process map-type-modifiers, flag errors for duplicate modifiers. 21322 unsigned Count = 0; 21323 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 21324 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 21325 llvm::is_contained(Modifiers, MapTypeModifiers[I])) { 21326 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 21327 continue; 21328 } 21329 assert(Count < NumberOfOMPMapClauseModifiers && 21330 "Modifiers exceed the allowed number of map type modifiers"); 21331 Modifiers[Count] = MapTypeModifiers[I]; 21332 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 21333 ++Count; 21334 } 21335 21336 MappableVarListInfo MVLI(VarList); 21337 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 21338 MapperIdScopeSpec, MapperId, UnresolvedMappers, 21339 MapType, Modifiers, IsMapTypeImplicit, 21340 NoDiagnose); 21341 21342 // We need to produce a map clause even if we don't have variables so that 21343 // other diagnostics related with non-existing map clauses are accurate. 21344 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 21345 MVLI.VarBaseDeclarations, MVLI.VarComponents, 21346 MVLI.UDMapperList, Modifiers, ModifiersLoc, 21347 MapperIdScopeSpec.getWithLocInContext(Context), 21348 MapperId, MapType, IsMapTypeImplicit, MapLoc); 21349 } 21350 21351 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 21352 TypeResult ParsedType) { 21353 assert(ParsedType.isUsable()); 21354 21355 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 21356 if (ReductionType.isNull()) 21357 return QualType(); 21358 21359 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 21360 // A type name in a declare reduction directive cannot be a function type, an 21361 // array type, a reference type, or a type qualified with const, volatile or 21362 // restrict. 21363 if (ReductionType.hasQualifiers()) { 21364 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 21365 return QualType(); 21366 } 21367 21368 if (ReductionType->isFunctionType()) { 21369 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 21370 return QualType(); 21371 } 21372 if (ReductionType->isReferenceType()) { 21373 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 21374 return QualType(); 21375 } 21376 if (ReductionType->isArrayType()) { 21377 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 21378 return QualType(); 21379 } 21380 return ReductionType; 21381 } 21382 21383 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 21384 Scope *S, DeclContext *DC, DeclarationName Name, 21385 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 21386 AccessSpecifier AS, Decl *PrevDeclInScope) { 21387 SmallVector<Decl *, 8> Decls; 21388 Decls.reserve(ReductionTypes.size()); 21389 21390 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 21391 forRedeclarationInCurContext()); 21392 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 21393 // A reduction-identifier may not be re-declared in the current scope for the 21394 // same type or for a type that is compatible according to the base language 21395 // rules. 21396 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 21397 OMPDeclareReductionDecl *PrevDRD = nullptr; 21398 bool InCompoundScope = true; 21399 if (S != nullptr) { 21400 // Find previous declaration with the same name not referenced in other 21401 // declarations. 21402 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 21403 InCompoundScope = 21404 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 21405 LookupName(Lookup, S); 21406 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 21407 /*AllowInlineNamespace=*/false); 21408 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 21409 LookupResult::Filter Filter = Lookup.makeFilter(); 21410 while (Filter.hasNext()) { 21411 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 21412 if (InCompoundScope) { 21413 auto I = UsedAsPrevious.find(PrevDecl); 21414 if (I == UsedAsPrevious.end()) 21415 UsedAsPrevious[PrevDecl] = false; 21416 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 21417 UsedAsPrevious[D] = true; 21418 } 21419 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 21420 PrevDecl->getLocation(); 21421 } 21422 Filter.done(); 21423 if (InCompoundScope) { 21424 for (const auto &PrevData : UsedAsPrevious) { 21425 if (!PrevData.second) { 21426 PrevDRD = PrevData.first; 21427 break; 21428 } 21429 } 21430 } 21431 } else if (PrevDeclInScope != nullptr) { 21432 auto *PrevDRDInScope = PrevDRD = 21433 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 21434 do { 21435 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 21436 PrevDRDInScope->getLocation(); 21437 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 21438 } while (PrevDRDInScope != nullptr); 21439 } 21440 for (const auto &TyData : ReductionTypes) { 21441 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 21442 bool Invalid = false; 21443 if (I != PreviousRedeclTypes.end()) { 21444 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 21445 << TyData.first; 21446 Diag(I->second, diag::note_previous_definition); 21447 Invalid = true; 21448 } 21449 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 21450 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 21451 Name, TyData.first, PrevDRD); 21452 DC->addDecl(DRD); 21453 DRD->setAccess(AS); 21454 Decls.push_back(DRD); 21455 if (Invalid) 21456 DRD->setInvalidDecl(); 21457 else 21458 PrevDRD = DRD; 21459 } 21460 21461 return DeclGroupPtrTy::make( 21462 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 21463 } 21464 21465 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 21466 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21467 21468 // Enter new function scope. 21469 PushFunctionScope(); 21470 setFunctionHasBranchProtectedScope(); 21471 getCurFunction()->setHasOMPDeclareReductionCombiner(); 21472 21473 if (S != nullptr) 21474 PushDeclContext(S, DRD); 21475 else 21476 CurContext = DRD; 21477 21478 PushExpressionEvaluationContext( 21479 ExpressionEvaluationContext::PotentiallyEvaluated); 21480 21481 QualType ReductionType = DRD->getType(); 21482 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 21483 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 21484 // uses semantics of argument handles by value, but it should be passed by 21485 // reference. C lang does not support references, so pass all parameters as 21486 // pointers. 21487 // Create 'T omp_in;' variable. 21488 VarDecl *OmpInParm = 21489 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 21490 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 21491 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 21492 // uses semantics of argument handles by value, but it should be passed by 21493 // reference. C lang does not support references, so pass all parameters as 21494 // pointers. 21495 // Create 'T omp_out;' variable. 21496 VarDecl *OmpOutParm = 21497 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 21498 if (S != nullptr) { 21499 PushOnScopeChains(OmpInParm, S); 21500 PushOnScopeChains(OmpOutParm, S); 21501 } else { 21502 DRD->addDecl(OmpInParm); 21503 DRD->addDecl(OmpOutParm); 21504 } 21505 Expr *InE = 21506 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 21507 Expr *OutE = 21508 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 21509 DRD->setCombinerData(InE, OutE); 21510 } 21511 21512 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 21513 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21514 DiscardCleanupsInEvaluationContext(); 21515 PopExpressionEvaluationContext(); 21516 21517 PopDeclContext(); 21518 PopFunctionScopeInfo(); 21519 21520 if (Combiner != nullptr) 21521 DRD->setCombiner(Combiner); 21522 else 21523 DRD->setInvalidDecl(); 21524 } 21525 21526 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 21527 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21528 21529 // Enter new function scope. 21530 PushFunctionScope(); 21531 setFunctionHasBranchProtectedScope(); 21532 21533 if (S != nullptr) 21534 PushDeclContext(S, DRD); 21535 else 21536 CurContext = DRD; 21537 21538 PushExpressionEvaluationContext( 21539 ExpressionEvaluationContext::PotentiallyEvaluated); 21540 21541 QualType ReductionType = DRD->getType(); 21542 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 21543 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 21544 // uses semantics of argument handles by value, but it should be passed by 21545 // reference. C lang does not support references, so pass all parameters as 21546 // pointers. 21547 // Create 'T omp_priv;' variable. 21548 VarDecl *OmpPrivParm = 21549 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 21550 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 21551 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 21552 // uses semantics of argument handles by value, but it should be passed by 21553 // reference. C lang does not support references, so pass all parameters as 21554 // pointers. 21555 // Create 'T omp_orig;' variable. 21556 VarDecl *OmpOrigParm = 21557 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 21558 if (S != nullptr) { 21559 PushOnScopeChains(OmpPrivParm, S); 21560 PushOnScopeChains(OmpOrigParm, S); 21561 } else { 21562 DRD->addDecl(OmpPrivParm); 21563 DRD->addDecl(OmpOrigParm); 21564 } 21565 Expr *OrigE = 21566 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 21567 Expr *PrivE = 21568 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 21569 DRD->setInitializerData(OrigE, PrivE); 21570 return OmpPrivParm; 21571 } 21572 21573 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 21574 VarDecl *OmpPrivParm) { 21575 auto *DRD = cast<OMPDeclareReductionDecl>(D); 21576 DiscardCleanupsInEvaluationContext(); 21577 PopExpressionEvaluationContext(); 21578 21579 PopDeclContext(); 21580 PopFunctionScopeInfo(); 21581 21582 if (Initializer != nullptr) { 21583 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 21584 } else if (OmpPrivParm->hasInit()) { 21585 DRD->setInitializer(OmpPrivParm->getInit(), 21586 OmpPrivParm->isDirectInit() 21587 ? OMPDeclareReductionDecl::DirectInit 21588 : OMPDeclareReductionDecl::CopyInit); 21589 } else { 21590 DRD->setInvalidDecl(); 21591 } 21592 } 21593 21594 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 21595 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 21596 for (Decl *D : DeclReductions.get()) { 21597 if (IsValid) { 21598 if (S) 21599 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 21600 /*AddToContext=*/false); 21601 } else { 21602 D->setInvalidDecl(); 21603 } 21604 } 21605 return DeclReductions; 21606 } 21607 21608 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 21609 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 21610 QualType T = TInfo->getType(); 21611 if (D.isInvalidType()) 21612 return true; 21613 21614 if (getLangOpts().CPlusPlus) { 21615 // Check that there are no default arguments (C++ only). 21616 CheckExtraCXXDefaultArguments(D); 21617 } 21618 21619 return CreateParsedType(T, TInfo); 21620 } 21621 21622 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 21623 TypeResult ParsedType) { 21624 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 21625 21626 QualType MapperType = GetTypeFromParser(ParsedType.get()); 21627 assert(!MapperType.isNull() && "Expect valid mapper type"); 21628 21629 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 21630 // The type must be of struct, union or class type in C and C++ 21631 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 21632 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 21633 return QualType(); 21634 } 21635 return MapperType; 21636 } 21637 21638 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareMapperDirective( 21639 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 21640 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 21641 Expr *MapperVarRef, ArrayRef<OMPClause *> Clauses, Decl *PrevDeclInScope) { 21642 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 21643 forRedeclarationInCurContext()); 21644 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 21645 // A mapper-identifier may not be redeclared in the current scope for the 21646 // same type or for a type that is compatible according to the base language 21647 // rules. 21648 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 21649 OMPDeclareMapperDecl *PrevDMD = nullptr; 21650 bool InCompoundScope = true; 21651 if (S != nullptr) { 21652 // Find previous declaration with the same name not referenced in other 21653 // declarations. 21654 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 21655 InCompoundScope = 21656 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 21657 LookupName(Lookup, S); 21658 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 21659 /*AllowInlineNamespace=*/false); 21660 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 21661 LookupResult::Filter Filter = Lookup.makeFilter(); 21662 while (Filter.hasNext()) { 21663 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 21664 if (InCompoundScope) { 21665 auto I = UsedAsPrevious.find(PrevDecl); 21666 if (I == UsedAsPrevious.end()) 21667 UsedAsPrevious[PrevDecl] = false; 21668 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 21669 UsedAsPrevious[D] = true; 21670 } 21671 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 21672 PrevDecl->getLocation(); 21673 } 21674 Filter.done(); 21675 if (InCompoundScope) { 21676 for (const auto &PrevData : UsedAsPrevious) { 21677 if (!PrevData.second) { 21678 PrevDMD = PrevData.first; 21679 break; 21680 } 21681 } 21682 } 21683 } else if (PrevDeclInScope) { 21684 auto *PrevDMDInScope = PrevDMD = 21685 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 21686 do { 21687 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 21688 PrevDMDInScope->getLocation(); 21689 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 21690 } while (PrevDMDInScope != nullptr); 21691 } 21692 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 21693 bool Invalid = false; 21694 if (I != PreviousRedeclTypes.end()) { 21695 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 21696 << MapperType << Name; 21697 Diag(I->second, diag::note_previous_definition); 21698 Invalid = true; 21699 } 21700 // Build expressions for implicit maps of data members with 'default' 21701 // mappers. 21702 SmallVector<OMPClause *, 4> ClausesWithImplicit(Clauses.begin(), 21703 Clauses.end()); 21704 if (LangOpts.OpenMP >= 50) 21705 processImplicitMapsWithDefaultMappers(*this, DSAStack, ClausesWithImplicit); 21706 auto *DMD = 21707 OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, MapperType, VN, 21708 ClausesWithImplicit, PrevDMD); 21709 if (S) 21710 PushOnScopeChains(DMD, S); 21711 else 21712 DC->addDecl(DMD); 21713 DMD->setAccess(AS); 21714 if (Invalid) 21715 DMD->setInvalidDecl(); 21716 21717 auto *VD = cast<DeclRefExpr>(MapperVarRef)->getDecl(); 21718 VD->setDeclContext(DMD); 21719 VD->setLexicalDeclContext(DMD); 21720 DMD->addDecl(VD); 21721 DMD->setMapperVarRef(MapperVarRef); 21722 21723 return DeclGroupPtrTy::make(DeclGroupRef(DMD)); 21724 } 21725 21726 ExprResult 21727 Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(Scope *S, QualType MapperType, 21728 SourceLocation StartLoc, 21729 DeclarationName VN) { 21730 TypeSourceInfo *TInfo = 21731 Context.getTrivialTypeSourceInfo(MapperType, StartLoc); 21732 auto *VD = VarDecl::Create(Context, Context.getTranslationUnitDecl(), 21733 StartLoc, StartLoc, VN.getAsIdentifierInfo(), 21734 MapperType, TInfo, SC_None); 21735 if (S) 21736 PushOnScopeChains(VD, S, /*AddToContext=*/false); 21737 Expr *E = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 21738 DSAStack->addDeclareMapperVarRef(E); 21739 return E; 21740 } 21741 21742 bool Sema::isOpenMPDeclareMapperVarDeclAllowed(const VarDecl *VD) const { 21743 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 21744 const Expr *Ref = DSAStack->getDeclareMapperVarRef(); 21745 if (const auto *DRE = cast_or_null<DeclRefExpr>(Ref)) { 21746 if (VD->getCanonicalDecl() == DRE->getDecl()->getCanonicalDecl()) 21747 return true; 21748 if (VD->isUsableInConstantExpressions(Context)) 21749 return true; 21750 return false; 21751 } 21752 return true; 21753 } 21754 21755 const ValueDecl *Sema::getOpenMPDeclareMapperVarName() const { 21756 assert(LangOpts.OpenMP && "Expected OpenMP mode."); 21757 return cast<DeclRefExpr>(DSAStack->getDeclareMapperVarRef())->getDecl(); 21758 } 21759 21760 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 21761 SourceLocation StartLoc, 21762 SourceLocation LParenLoc, 21763 SourceLocation EndLoc) { 21764 Expr *ValExpr = NumTeams; 21765 Stmt *HelperValStmt = nullptr; 21766 21767 // OpenMP [teams Constrcut, Restrictions] 21768 // The num_teams expression must evaluate to a positive integer value. 21769 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 21770 /*StrictlyPositive=*/true)) 21771 return nullptr; 21772 21773 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 21774 OpenMPDirectiveKind CaptureRegion = 21775 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams, LangOpts.OpenMP); 21776 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 21777 ValExpr = MakeFullExpr(ValExpr).get(); 21778 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 21779 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 21780 HelperValStmt = buildPreInits(Context, Captures); 21781 } 21782 21783 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 21784 StartLoc, LParenLoc, EndLoc); 21785 } 21786 21787 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 21788 SourceLocation StartLoc, 21789 SourceLocation LParenLoc, 21790 SourceLocation EndLoc) { 21791 Expr *ValExpr = ThreadLimit; 21792 Stmt *HelperValStmt = nullptr; 21793 21794 // OpenMP [teams Constrcut, Restrictions] 21795 // The thread_limit expression must evaluate to a positive integer value. 21796 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 21797 /*StrictlyPositive=*/true)) 21798 return nullptr; 21799 21800 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 21801 OpenMPDirectiveKind CaptureRegion = getOpenMPCaptureRegionForClause( 21802 DKind, OMPC_thread_limit, LangOpts.OpenMP); 21803 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 21804 ValExpr = MakeFullExpr(ValExpr).get(); 21805 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 21806 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 21807 HelperValStmt = buildPreInits(Context, Captures); 21808 } 21809 21810 return new (Context) OMPThreadLimitClause( 21811 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 21812 } 21813 21814 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 21815 SourceLocation StartLoc, 21816 SourceLocation LParenLoc, 21817 SourceLocation EndLoc) { 21818 Expr *ValExpr = Priority; 21819 Stmt *HelperValStmt = nullptr; 21820 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 21821 21822 // OpenMP [2.9.1, task Constrcut] 21823 // The priority-value is a non-negative numerical scalar expression. 21824 if (!isNonNegativeIntegerValue( 21825 ValExpr, *this, OMPC_priority, 21826 /*StrictlyPositive=*/false, /*BuildCapture=*/true, 21827 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 21828 return nullptr; 21829 21830 return new (Context) OMPPriorityClause(ValExpr, HelperValStmt, CaptureRegion, 21831 StartLoc, LParenLoc, EndLoc); 21832 } 21833 21834 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 21835 SourceLocation StartLoc, 21836 SourceLocation LParenLoc, 21837 SourceLocation EndLoc) { 21838 Expr *ValExpr = Grainsize; 21839 Stmt *HelperValStmt = nullptr; 21840 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 21841 21842 // OpenMP [2.9.2, taskloop Constrcut] 21843 // The parameter of the grainsize clause must be a positive integer 21844 // expression. 21845 if (!isNonNegativeIntegerValue( 21846 ValExpr, *this, OMPC_grainsize, 21847 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 21848 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 21849 return nullptr; 21850 21851 return new (Context) OMPGrainsizeClause(ValExpr, HelperValStmt, CaptureRegion, 21852 StartLoc, LParenLoc, EndLoc); 21853 } 21854 21855 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 21856 SourceLocation StartLoc, 21857 SourceLocation LParenLoc, 21858 SourceLocation EndLoc) { 21859 Expr *ValExpr = NumTasks; 21860 Stmt *HelperValStmt = nullptr; 21861 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 21862 21863 // OpenMP [2.9.2, taskloop Constrcut] 21864 // The parameter of the num_tasks clause must be a positive integer 21865 // expression. 21866 if (!isNonNegativeIntegerValue( 21867 ValExpr, *this, OMPC_num_tasks, 21868 /*StrictlyPositive=*/true, /*BuildCapture=*/true, 21869 DSAStack->getCurrentDirective(), &CaptureRegion, &HelperValStmt)) 21870 return nullptr; 21871 21872 return new (Context) OMPNumTasksClause(ValExpr, HelperValStmt, CaptureRegion, 21873 StartLoc, LParenLoc, EndLoc); 21874 } 21875 21876 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 21877 SourceLocation LParenLoc, 21878 SourceLocation EndLoc) { 21879 // OpenMP [2.13.2, critical construct, Description] 21880 // ... where hint-expression is an integer constant expression that evaluates 21881 // to a valid lock hint. 21882 ExprResult HintExpr = 21883 VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint, false); 21884 if (HintExpr.isInvalid()) 21885 return nullptr; 21886 return new (Context) 21887 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 21888 } 21889 21890 /// Tries to find omp_event_handle_t type. 21891 static bool findOMPEventHandleT(Sema &S, SourceLocation Loc, 21892 DSAStackTy *Stack) { 21893 QualType OMPEventHandleT = Stack->getOMPEventHandleT(); 21894 if (!OMPEventHandleT.isNull()) 21895 return true; 21896 IdentifierInfo *II = &S.PP.getIdentifierTable().get("omp_event_handle_t"); 21897 ParsedType PT = S.getTypeName(*II, Loc, S.getCurScope()); 21898 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 21899 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_event_handle_t"; 21900 return false; 21901 } 21902 Stack->setOMPEventHandleT(PT.get()); 21903 return true; 21904 } 21905 21906 OMPClause *Sema::ActOnOpenMPDetachClause(Expr *Evt, SourceLocation StartLoc, 21907 SourceLocation LParenLoc, 21908 SourceLocation EndLoc) { 21909 if (!Evt->isValueDependent() && !Evt->isTypeDependent() && 21910 !Evt->isInstantiationDependent() && 21911 !Evt->containsUnexpandedParameterPack()) { 21912 if (!findOMPEventHandleT(*this, Evt->getExprLoc(), DSAStack)) 21913 return nullptr; 21914 // OpenMP 5.0, 2.10.1 task Construct. 21915 // event-handle is a variable of the omp_event_handle_t type. 21916 auto *Ref = dyn_cast<DeclRefExpr>(Evt->IgnoreParenImpCasts()); 21917 if (!Ref) { 21918 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 21919 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 21920 return nullptr; 21921 } 21922 auto *VD = dyn_cast_or_null<VarDecl>(Ref->getDecl()); 21923 if (!VD) { 21924 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 21925 << "omp_event_handle_t" << 0 << Evt->getSourceRange(); 21926 return nullptr; 21927 } 21928 if (!Context.hasSameUnqualifiedType(DSAStack->getOMPEventHandleT(), 21929 VD->getType()) || 21930 VD->getType().isConstant(Context)) { 21931 Diag(Evt->getExprLoc(), diag::err_omp_var_expected) 21932 << "omp_event_handle_t" << 1 << VD->getType() 21933 << Evt->getSourceRange(); 21934 return nullptr; 21935 } 21936 // OpenMP 5.0, 2.10.1 task Construct 21937 // [detach clause]... The event-handle will be considered as if it was 21938 // specified on a firstprivate clause. 21939 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, /*FromParent=*/false); 21940 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 21941 DVar.RefExpr) { 21942 Diag(Evt->getExprLoc(), diag::err_omp_wrong_dsa) 21943 << getOpenMPClauseName(DVar.CKind) 21944 << getOpenMPClauseName(OMPC_firstprivate); 21945 reportOriginalDsa(*this, DSAStack, VD, DVar); 21946 return nullptr; 21947 } 21948 } 21949 21950 return new (Context) OMPDetachClause(Evt, StartLoc, LParenLoc, EndLoc); 21951 } 21952 21953 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 21954 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 21955 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 21956 SourceLocation EndLoc) { 21957 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 21958 std::string Values; 21959 Values += "'"; 21960 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 21961 Values += "'"; 21962 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 21963 << Values << getOpenMPClauseName(OMPC_dist_schedule); 21964 return nullptr; 21965 } 21966 Expr *ValExpr = ChunkSize; 21967 Stmt *HelperValStmt = nullptr; 21968 if (ChunkSize) { 21969 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 21970 !ChunkSize->isInstantiationDependent() && 21971 !ChunkSize->containsUnexpandedParameterPack()) { 21972 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 21973 ExprResult Val = 21974 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 21975 if (Val.isInvalid()) 21976 return nullptr; 21977 21978 ValExpr = Val.get(); 21979 21980 // OpenMP [2.7.1, Restrictions] 21981 // chunk_size must be a loop invariant integer expression with a positive 21982 // value. 21983 if (Optional<llvm::APSInt> Result = 21984 ValExpr->getIntegerConstantExpr(Context)) { 21985 if (Result->isSigned() && !Result->isStrictlyPositive()) { 21986 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 21987 << "dist_schedule" << ChunkSize->getSourceRange(); 21988 return nullptr; 21989 } 21990 } else if (getOpenMPCaptureRegionForClause( 21991 DSAStack->getCurrentDirective(), OMPC_dist_schedule, 21992 LangOpts.OpenMP) != OMPD_unknown && 21993 !CurContext->isDependentContext()) { 21994 ValExpr = MakeFullExpr(ValExpr).get(); 21995 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 21996 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 21997 HelperValStmt = buildPreInits(Context, Captures); 21998 } 21999 } 22000 } 22001 22002 return new (Context) 22003 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 22004 Kind, ValExpr, HelperValStmt); 22005 } 22006 22007 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 22008 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 22009 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 22010 SourceLocation KindLoc, SourceLocation EndLoc) { 22011 if (getLangOpts().OpenMP < 50) { 22012 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 22013 Kind != OMPC_DEFAULTMAP_scalar) { 22014 std::string Value; 22015 SourceLocation Loc; 22016 Value += "'"; 22017 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 22018 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 22019 OMPC_DEFAULTMAP_MODIFIER_tofrom); 22020 Loc = MLoc; 22021 } else { 22022 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 22023 OMPC_DEFAULTMAP_scalar); 22024 Loc = KindLoc; 22025 } 22026 Value += "'"; 22027 Diag(Loc, diag::err_omp_unexpected_clause_value) 22028 << Value << getOpenMPClauseName(OMPC_defaultmap); 22029 return nullptr; 22030 } 22031 } else { 22032 bool isDefaultmapModifier = (M != OMPC_DEFAULTMAP_MODIFIER_unknown); 22033 bool isDefaultmapKind = (Kind != OMPC_DEFAULTMAP_unknown) || 22034 (LangOpts.OpenMP >= 50 && KindLoc.isInvalid()); 22035 if (!isDefaultmapKind || !isDefaultmapModifier) { 22036 StringRef KindValue = "'scalar', 'aggregate', 'pointer'"; 22037 if (LangOpts.OpenMP == 50) { 22038 StringRef ModifierValue = "'alloc', 'from', 'to', 'tofrom', " 22039 "'firstprivate', 'none', 'default'"; 22040 if (!isDefaultmapKind && isDefaultmapModifier) { 22041 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22042 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22043 } else if (isDefaultmapKind && !isDefaultmapModifier) { 22044 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22045 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22046 } else { 22047 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22048 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22049 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22050 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22051 } 22052 } else { 22053 StringRef ModifierValue = 22054 "'alloc', 'from', 'to', 'tofrom', " 22055 "'firstprivate', 'none', 'default', 'present'"; 22056 if (!isDefaultmapKind && isDefaultmapModifier) { 22057 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22058 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22059 } else if (isDefaultmapKind && !isDefaultmapModifier) { 22060 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22061 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22062 } else { 22063 Diag(MLoc, diag::err_omp_unexpected_clause_value) 22064 << ModifierValue << getOpenMPClauseName(OMPC_defaultmap); 22065 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 22066 << KindValue << getOpenMPClauseName(OMPC_defaultmap); 22067 } 22068 } 22069 return nullptr; 22070 } 22071 22072 // OpenMP [5.0, 2.12.5, Restrictions, p. 174] 22073 // At most one defaultmap clause for each category can appear on the 22074 // directive. 22075 if (DSAStack->checkDefaultmapCategory(Kind)) { 22076 Diag(StartLoc, diag::err_omp_one_defaultmap_each_category); 22077 return nullptr; 22078 } 22079 } 22080 if (Kind == OMPC_DEFAULTMAP_unknown) { 22081 // Variable category is not specified - mark all categories. 22082 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_aggregate, StartLoc); 22083 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_scalar, StartLoc); 22084 DSAStack->setDefaultDMAAttr(M, OMPC_DEFAULTMAP_pointer, StartLoc); 22085 } else { 22086 DSAStack->setDefaultDMAAttr(M, Kind, StartLoc); 22087 } 22088 22089 return new (Context) 22090 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 22091 } 22092 22093 bool Sema::ActOnStartOpenMPDeclareTargetContext( 22094 DeclareTargetContextInfo &DTCI) { 22095 DeclContext *CurLexicalContext = getCurLexicalContext(); 22096 if (!CurLexicalContext->isFileContext() && 22097 !CurLexicalContext->isExternCContext() && 22098 !CurLexicalContext->isExternCXXContext() && 22099 !isa<CXXRecordDecl>(CurLexicalContext) && 22100 !isa<ClassTemplateDecl>(CurLexicalContext) && 22101 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 22102 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 22103 Diag(DTCI.Loc, diag::err_omp_region_not_file_context); 22104 return false; 22105 } 22106 DeclareTargetNesting.push_back(DTCI); 22107 return true; 22108 } 22109 22110 const Sema::DeclareTargetContextInfo 22111 Sema::ActOnOpenMPEndDeclareTargetDirective() { 22112 assert(!DeclareTargetNesting.empty() && 22113 "check isInOpenMPDeclareTargetContext() first!"); 22114 return DeclareTargetNesting.pop_back_val(); 22115 } 22116 22117 void Sema::ActOnFinishedOpenMPDeclareTargetContext( 22118 DeclareTargetContextInfo &DTCI) { 22119 for (auto &It : DTCI.ExplicitlyMapped) 22120 ActOnOpenMPDeclareTargetName(It.first, It.second.Loc, It.second.MT, DTCI); 22121 } 22122 22123 void Sema::DiagnoseUnterminatedOpenMPDeclareTarget() { 22124 if (DeclareTargetNesting.empty()) 22125 return; 22126 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); 22127 Diag(DTCI.Loc, diag::warn_omp_unterminated_declare_target) 22128 << getOpenMPDirectiveName(DTCI.Kind); 22129 } 22130 22131 NamedDecl *Sema::lookupOpenMPDeclareTargetName(Scope *CurScope, 22132 CXXScopeSpec &ScopeSpec, 22133 const DeclarationNameInfo &Id) { 22134 LookupResult Lookup(*this, Id, LookupOrdinaryName); 22135 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 22136 22137 if (Lookup.isAmbiguous()) 22138 return nullptr; 22139 Lookup.suppressDiagnostics(); 22140 22141 if (!Lookup.isSingleResult()) { 22142 VarOrFuncDeclFilterCCC CCC(*this); 22143 if (TypoCorrection Corrected = 22144 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, CCC, 22145 CTK_ErrorRecovery)) { 22146 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 22147 << Id.getName()); 22148 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 22149 return nullptr; 22150 } 22151 22152 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 22153 return nullptr; 22154 } 22155 22156 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 22157 if (!isa<VarDecl>(ND) && !isa<FunctionDecl>(ND) && 22158 !isa<FunctionTemplateDecl>(ND)) { 22159 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 22160 return nullptr; 22161 } 22162 return ND; 22163 } 22164 22165 void Sema::ActOnOpenMPDeclareTargetName(NamedDecl *ND, SourceLocation Loc, 22166 OMPDeclareTargetDeclAttr::MapTypeTy MT, 22167 DeclareTargetContextInfo &DTCI) { 22168 assert((isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 22169 isa<FunctionTemplateDecl>(ND)) && 22170 "Expected variable, function or function template."); 22171 22172 // Diagnose marking after use as it may lead to incorrect diagnosis and 22173 // codegen. 22174 if (LangOpts.OpenMP >= 50 && 22175 (ND->isUsed(/*CheckUsedAttr=*/false) || ND->isReferenced())) 22176 Diag(Loc, diag::warn_omp_declare_target_after_first_use); 22177 22178 // Explicit declare target lists have precedence. 22179 const unsigned Level = -1; 22180 22181 auto *VD = cast<ValueDecl>(ND); 22182 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr = 22183 OMPDeclareTargetDeclAttr::getActiveAttr(VD); 22184 if (ActiveAttr && ActiveAttr.getValue()->getDevType() != DTCI.DT && 22185 ActiveAttr.getValue()->getLevel() == Level) { 22186 Diag(Loc, diag::err_omp_device_type_mismatch) 22187 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr(DTCI.DT) 22188 << OMPDeclareTargetDeclAttr::ConvertDevTypeTyToStr( 22189 ActiveAttr.getValue()->getDevType()); 22190 return; 22191 } 22192 if (ActiveAttr && ActiveAttr.getValue()->getMapType() != MT && 22193 ActiveAttr.getValue()->getLevel() == Level) { 22194 Diag(Loc, diag::err_omp_declare_target_to_and_link) << ND; 22195 return; 22196 } 22197 22198 if (ActiveAttr && ActiveAttr.getValue()->getLevel() == Level) 22199 return; 22200 22201 Expr *IndirectE = nullptr; 22202 bool IsIndirect = false; 22203 if (DTCI.Indirect) { 22204 IndirectE = DTCI.Indirect.getValue(); 22205 if (!IndirectE) 22206 IsIndirect = true; 22207 } 22208 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 22209 Context, MT, DTCI.DT, IndirectE, IsIndirect, Level, 22210 SourceRange(Loc, Loc)); 22211 ND->addAttr(A); 22212 if (ASTMutationListener *ML = Context.getASTMutationListener()) 22213 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 22214 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Loc); 22215 } 22216 22217 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 22218 Sema &SemaRef, Decl *D) { 22219 if (!D || !isa<VarDecl>(D)) 22220 return; 22221 auto *VD = cast<VarDecl>(D); 22222 Optional<OMPDeclareTargetDeclAttr::MapTypeTy> MapTy = 22223 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 22224 if (SemaRef.LangOpts.OpenMP >= 50 && 22225 (SemaRef.getCurLambda(/*IgnoreNonLambdaCapturingScope=*/true) || 22226 SemaRef.getCurBlock() || SemaRef.getCurCapturedRegion()) && 22227 VD->hasGlobalStorage()) { 22228 if (!MapTy || *MapTy != OMPDeclareTargetDeclAttr::MT_To) { 22229 // OpenMP 5.0, 2.12.7 declare target Directive, Restrictions 22230 // If a lambda declaration and definition appears between a 22231 // declare target directive and the matching end declare target 22232 // directive, all variables that are captured by the lambda 22233 // expression must also appear in a to clause. 22234 SemaRef.Diag(VD->getLocation(), 22235 diag::err_omp_lambda_capture_in_declare_target_not_to); 22236 SemaRef.Diag(SL, diag::note_var_explicitly_captured_here) 22237 << VD << 0 << SR; 22238 return; 22239 } 22240 } 22241 if (MapTy) 22242 return; 22243 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 22244 SemaRef.Diag(SL, diag::note_used_here) << SR; 22245 } 22246 22247 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 22248 Sema &SemaRef, DSAStackTy *Stack, 22249 ValueDecl *VD) { 22250 return OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) || 22251 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 22252 /*FullCheck=*/false); 22253 } 22254 22255 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 22256 SourceLocation IdLoc) { 22257 if (!D || D->isInvalidDecl()) 22258 return; 22259 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 22260 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 22261 if (auto *VD = dyn_cast<VarDecl>(D)) { 22262 // Only global variables can be marked as declare target. 22263 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 22264 !VD->isStaticDataMember()) 22265 return; 22266 // 2.10.6: threadprivate variable cannot appear in a declare target 22267 // directive. 22268 if (DSAStack->isThreadPrivate(VD)) { 22269 Diag(SL, diag::err_omp_threadprivate_in_target); 22270 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 22271 return; 22272 } 22273 } 22274 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 22275 D = FTD->getTemplatedDecl(); 22276 if (auto *FD = dyn_cast<FunctionDecl>(D)) { 22277 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 22278 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 22279 if (IdLoc.isValid() && Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 22280 Diag(IdLoc, diag::err_omp_function_in_link_clause); 22281 Diag(FD->getLocation(), diag::note_defined_here) << FD; 22282 return; 22283 } 22284 } 22285 if (auto *VD = dyn_cast<ValueDecl>(D)) { 22286 // Problem if any with var declared with incomplete type will be reported 22287 // as normal, so no need to check it here. 22288 if ((E || !VD->getType()->isIncompleteType()) && 22289 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 22290 return; 22291 if (!E && isInOpenMPDeclareTargetContext()) { 22292 // Checking declaration inside declare target region. 22293 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 22294 isa<FunctionTemplateDecl>(D)) { 22295 llvm::Optional<OMPDeclareTargetDeclAttr *> ActiveAttr = 22296 OMPDeclareTargetDeclAttr::getActiveAttr(VD); 22297 unsigned Level = DeclareTargetNesting.size(); 22298 if (ActiveAttr && ActiveAttr.getValue()->getLevel() >= Level) 22299 return; 22300 DeclareTargetContextInfo &DTCI = DeclareTargetNesting.back(); 22301 Expr *IndirectE = nullptr; 22302 bool IsIndirect = false; 22303 if (DTCI.Indirect) { 22304 IndirectE = DTCI.Indirect.getValue(); 22305 if (!IndirectE) 22306 IsIndirect = true; 22307 } 22308 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 22309 Context, OMPDeclareTargetDeclAttr::MT_To, DTCI.DT, IndirectE, 22310 IsIndirect, Level, SourceRange(DTCI.Loc, DTCI.Loc)); 22311 D->addAttr(A); 22312 if (ASTMutationListener *ML = Context.getASTMutationListener()) 22313 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 22314 } 22315 return; 22316 } 22317 } 22318 if (!E) 22319 return; 22320 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 22321 } 22322 22323 OMPClause *Sema::ActOnOpenMPToClause( 22324 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 22325 ArrayRef<SourceLocation> MotionModifiersLoc, 22326 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 22327 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 22328 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 22329 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 22330 OMPC_MOTION_MODIFIER_unknown}; 22331 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 22332 22333 // Process motion-modifiers, flag errors for duplicate modifiers. 22334 unsigned Count = 0; 22335 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 22336 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 22337 llvm::is_contained(Modifiers, MotionModifiers[I])) { 22338 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 22339 continue; 22340 } 22341 assert(Count < NumberOfOMPMotionModifiers && 22342 "Modifiers exceed the allowed number of motion modifiers"); 22343 Modifiers[Count] = MotionModifiers[I]; 22344 ModifiersLoc[Count] = MotionModifiersLoc[I]; 22345 ++Count; 22346 } 22347 22348 MappableVarListInfo MVLI(VarList); 22349 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 22350 MapperIdScopeSpec, MapperId, UnresolvedMappers); 22351 if (MVLI.ProcessedVarList.empty()) 22352 return nullptr; 22353 22354 return OMPToClause::Create( 22355 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 22356 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 22357 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 22358 } 22359 22360 OMPClause *Sema::ActOnOpenMPFromClause( 22361 ArrayRef<OpenMPMotionModifierKind> MotionModifiers, 22362 ArrayRef<SourceLocation> MotionModifiersLoc, 22363 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 22364 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 22365 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 22366 OpenMPMotionModifierKind Modifiers[] = {OMPC_MOTION_MODIFIER_unknown, 22367 OMPC_MOTION_MODIFIER_unknown}; 22368 SourceLocation ModifiersLoc[NumberOfOMPMotionModifiers]; 22369 22370 // Process motion-modifiers, flag errors for duplicate modifiers. 22371 unsigned Count = 0; 22372 for (unsigned I = 0, E = MotionModifiers.size(); I < E; ++I) { 22373 if (MotionModifiers[I] != OMPC_MOTION_MODIFIER_unknown && 22374 llvm::is_contained(Modifiers, MotionModifiers[I])) { 22375 Diag(MotionModifiersLoc[I], diag::err_omp_duplicate_motion_modifier); 22376 continue; 22377 } 22378 assert(Count < NumberOfOMPMotionModifiers && 22379 "Modifiers exceed the allowed number of motion modifiers"); 22380 Modifiers[Count] = MotionModifiers[I]; 22381 ModifiersLoc[Count] = MotionModifiersLoc[I]; 22382 ++Count; 22383 } 22384 22385 MappableVarListInfo MVLI(VarList); 22386 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 22387 MapperIdScopeSpec, MapperId, UnresolvedMappers); 22388 if (MVLI.ProcessedVarList.empty()) 22389 return nullptr; 22390 22391 return OMPFromClause::Create( 22392 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 22393 MVLI.VarComponents, MVLI.UDMapperList, Modifiers, ModifiersLoc, 22394 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 22395 } 22396 22397 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 22398 const OMPVarListLocTy &Locs) { 22399 MappableVarListInfo MVLI(VarList); 22400 SmallVector<Expr *, 8> PrivateCopies; 22401 SmallVector<Expr *, 8> Inits; 22402 22403 for (Expr *RefExpr : VarList) { 22404 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 22405 SourceLocation ELoc; 22406 SourceRange ERange; 22407 Expr *SimpleRefExpr = RefExpr; 22408 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22409 if (Res.second) { 22410 // It will be analyzed later. 22411 MVLI.ProcessedVarList.push_back(RefExpr); 22412 PrivateCopies.push_back(nullptr); 22413 Inits.push_back(nullptr); 22414 } 22415 ValueDecl *D = Res.first; 22416 if (!D) 22417 continue; 22418 22419 QualType Type = D->getType(); 22420 Type = Type.getNonReferenceType().getUnqualifiedType(); 22421 22422 auto *VD = dyn_cast<VarDecl>(D); 22423 22424 // Item should be a pointer or reference to pointer. 22425 if (!Type->isPointerType()) { 22426 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 22427 << 0 << RefExpr->getSourceRange(); 22428 continue; 22429 } 22430 22431 // Build the private variable and the expression that refers to it. 22432 auto VDPrivate = 22433 buildVarDecl(*this, ELoc, Type, D->getName(), 22434 D->hasAttrs() ? &D->getAttrs() : nullptr, 22435 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 22436 if (VDPrivate->isInvalidDecl()) 22437 continue; 22438 22439 CurContext->addDecl(VDPrivate); 22440 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 22441 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 22442 22443 // Add temporary variable to initialize the private copy of the pointer. 22444 VarDecl *VDInit = 22445 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 22446 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 22447 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 22448 AddInitializerToDecl(VDPrivate, 22449 DefaultLvalueConversion(VDInitRefExpr).get(), 22450 /*DirectInit=*/false); 22451 22452 // If required, build a capture to implement the privatization initialized 22453 // with the current list item value. 22454 DeclRefExpr *Ref = nullptr; 22455 if (!VD) 22456 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 22457 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 22458 PrivateCopies.push_back(VDPrivateRefExpr); 22459 Inits.push_back(VDInitRefExpr); 22460 22461 // We need to add a data sharing attribute for this variable to make sure it 22462 // is correctly captured. A variable that shows up in a use_device_ptr has 22463 // similar properties of a first private variable. 22464 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 22465 22466 // Create a mappable component for the list item. List items in this clause 22467 // only need a component. 22468 MVLI.VarBaseDeclarations.push_back(D); 22469 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 22470 MVLI.VarComponents.back().emplace_back(SimpleRefExpr, D, 22471 /*IsNonContiguous=*/false); 22472 } 22473 22474 if (MVLI.ProcessedVarList.empty()) 22475 return nullptr; 22476 22477 return OMPUseDevicePtrClause::Create( 22478 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 22479 MVLI.VarBaseDeclarations, MVLI.VarComponents); 22480 } 22481 22482 OMPClause *Sema::ActOnOpenMPUseDeviceAddrClause(ArrayRef<Expr *> VarList, 22483 const OMPVarListLocTy &Locs) { 22484 MappableVarListInfo MVLI(VarList); 22485 22486 for (Expr *RefExpr : VarList) { 22487 assert(RefExpr && "NULL expr in OpenMP use_device_addr clause."); 22488 SourceLocation ELoc; 22489 SourceRange ERange; 22490 Expr *SimpleRefExpr = RefExpr; 22491 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22492 /*AllowArraySection=*/true); 22493 if (Res.second) { 22494 // It will be analyzed later. 22495 MVLI.ProcessedVarList.push_back(RefExpr); 22496 } 22497 ValueDecl *D = Res.first; 22498 if (!D) 22499 continue; 22500 auto *VD = dyn_cast<VarDecl>(D); 22501 22502 // If required, build a capture to implement the privatization initialized 22503 // with the current list item value. 22504 DeclRefExpr *Ref = nullptr; 22505 if (!VD) 22506 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 22507 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 22508 22509 // We need to add a data sharing attribute for this variable to make sure it 22510 // is correctly captured. A variable that shows up in a use_device_addr has 22511 // similar properties of a first private variable. 22512 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 22513 22514 // Create a mappable component for the list item. List items in this clause 22515 // only need a component. 22516 MVLI.VarBaseDeclarations.push_back(D); 22517 MVLI.VarComponents.emplace_back(); 22518 Expr *Component = SimpleRefExpr; 22519 if (VD && (isa<OMPArraySectionExpr>(RefExpr->IgnoreParenImpCasts()) || 22520 isa<ArraySubscriptExpr>(RefExpr->IgnoreParenImpCasts()))) 22521 Component = DefaultFunctionArrayLvalueConversion(SimpleRefExpr).get(); 22522 MVLI.VarComponents.back().emplace_back(Component, D, 22523 /*IsNonContiguous=*/false); 22524 } 22525 22526 if (MVLI.ProcessedVarList.empty()) 22527 return nullptr; 22528 22529 return OMPUseDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 22530 MVLI.VarBaseDeclarations, 22531 MVLI.VarComponents); 22532 } 22533 22534 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 22535 const OMPVarListLocTy &Locs) { 22536 MappableVarListInfo MVLI(VarList); 22537 for (Expr *RefExpr : VarList) { 22538 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 22539 SourceLocation ELoc; 22540 SourceRange ERange; 22541 Expr *SimpleRefExpr = RefExpr; 22542 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22543 if (Res.second) { 22544 // It will be analyzed later. 22545 MVLI.ProcessedVarList.push_back(RefExpr); 22546 } 22547 ValueDecl *D = Res.first; 22548 if (!D) 22549 continue; 22550 22551 QualType Type = D->getType(); 22552 // item should be a pointer or array or reference to pointer or array 22553 if (!Type.getNonReferenceType()->isPointerType() && 22554 !Type.getNonReferenceType()->isArrayType()) { 22555 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 22556 << 0 << RefExpr->getSourceRange(); 22557 continue; 22558 } 22559 22560 // Check if the declaration in the clause does not show up in any data 22561 // sharing attribute. 22562 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 22563 if (isOpenMPPrivate(DVar.CKind)) { 22564 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 22565 << getOpenMPClauseName(DVar.CKind) 22566 << getOpenMPClauseName(OMPC_is_device_ptr) 22567 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 22568 reportOriginalDsa(*this, DSAStack, D, DVar); 22569 continue; 22570 } 22571 22572 const Expr *ConflictExpr; 22573 if (DSAStack->checkMappableExprComponentListsForDecl( 22574 D, /*CurrentRegionOnly=*/true, 22575 [&ConflictExpr]( 22576 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 22577 OpenMPClauseKind) -> bool { 22578 ConflictExpr = R.front().getAssociatedExpression(); 22579 return true; 22580 })) { 22581 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 22582 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 22583 << ConflictExpr->getSourceRange(); 22584 continue; 22585 } 22586 22587 // Store the components in the stack so that they can be used to check 22588 // against other clauses later on. 22589 OMPClauseMappableExprCommon::MappableComponent MC( 22590 SimpleRefExpr, D, /*IsNonContiguous=*/false); 22591 DSAStack->addMappableExpressionComponents( 22592 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 22593 22594 // Record the expression we've just processed. 22595 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 22596 22597 // Create a mappable component for the list item. List items in this clause 22598 // only need a component. We use a null declaration to signal fields in 22599 // 'this'. 22600 assert((isa<DeclRefExpr>(SimpleRefExpr) || 22601 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 22602 "Unexpected device pointer expression!"); 22603 MVLI.VarBaseDeclarations.push_back( 22604 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 22605 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 22606 MVLI.VarComponents.back().push_back(MC); 22607 } 22608 22609 if (MVLI.ProcessedVarList.empty()) 22610 return nullptr; 22611 22612 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 22613 MVLI.VarBaseDeclarations, 22614 MVLI.VarComponents); 22615 } 22616 22617 OMPClause *Sema::ActOnOpenMPHasDeviceAddrClause(ArrayRef<Expr *> VarList, 22618 const OMPVarListLocTy &Locs) { 22619 MappableVarListInfo MVLI(VarList); 22620 for (Expr *RefExpr : VarList) { 22621 assert(RefExpr && "NULL expr in OpenMP has_device_addr clause."); 22622 SourceLocation ELoc; 22623 SourceRange ERange; 22624 Expr *SimpleRefExpr = RefExpr; 22625 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22626 /*AllowArraySection=*/true); 22627 if (Res.second) { 22628 // It will be analyzed later. 22629 MVLI.ProcessedVarList.push_back(RefExpr); 22630 } 22631 ValueDecl *D = Res.first; 22632 if (!D) 22633 continue; 22634 22635 // Check if the declaration in the clause does not show up in any data 22636 // sharing attribute. 22637 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 22638 if (isOpenMPPrivate(DVar.CKind)) { 22639 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 22640 << getOpenMPClauseName(DVar.CKind) 22641 << getOpenMPClauseName(OMPC_has_device_addr) 22642 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 22643 reportOriginalDsa(*this, DSAStack, D, DVar); 22644 continue; 22645 } 22646 22647 const Expr *ConflictExpr; 22648 if (DSAStack->checkMappableExprComponentListsForDecl( 22649 D, /*CurrentRegionOnly=*/true, 22650 [&ConflictExpr]( 22651 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 22652 OpenMPClauseKind) -> bool { 22653 ConflictExpr = R.front().getAssociatedExpression(); 22654 return true; 22655 })) { 22656 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 22657 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 22658 << ConflictExpr->getSourceRange(); 22659 continue; 22660 } 22661 22662 // Store the components in the stack so that they can be used to check 22663 // against other clauses later on. 22664 OMPClauseMappableExprCommon::MappableComponent MC( 22665 SimpleRefExpr, D, /*IsNonContiguous=*/false); 22666 DSAStack->addMappableExpressionComponents( 22667 D, MC, /*WhereFoundClauseKind=*/OMPC_has_device_addr); 22668 22669 // Record the expression we've just processed. 22670 auto *VD = dyn_cast<VarDecl>(D); 22671 if (!VD && !CurContext->isDependentContext()) { 22672 DeclRefExpr *Ref = 22673 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 22674 assert(Ref && "has_device_addr capture failed"); 22675 MVLI.ProcessedVarList.push_back(Ref); 22676 } else 22677 MVLI.ProcessedVarList.push_back(RefExpr->IgnoreParens()); 22678 22679 // Create a mappable component for the list item. List items in this clause 22680 // only need a component. We use a null declaration to signal fields in 22681 // 'this'. 22682 assert((isa<DeclRefExpr>(SimpleRefExpr) || 22683 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 22684 "Unexpected device pointer expression!"); 22685 MVLI.VarBaseDeclarations.push_back( 22686 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 22687 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 22688 MVLI.VarComponents.back().push_back(MC); 22689 } 22690 22691 if (MVLI.ProcessedVarList.empty()) 22692 return nullptr; 22693 22694 return OMPHasDeviceAddrClause::Create(Context, Locs, MVLI.ProcessedVarList, 22695 MVLI.VarBaseDeclarations, 22696 MVLI.VarComponents); 22697 } 22698 22699 OMPClause *Sema::ActOnOpenMPAllocateClause( 22700 Expr *Allocator, ArrayRef<Expr *> VarList, SourceLocation StartLoc, 22701 SourceLocation ColonLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 22702 if (Allocator) { 22703 // OpenMP [2.11.4 allocate Clause, Description] 22704 // allocator is an expression of omp_allocator_handle_t type. 22705 if (!findOMPAllocatorHandleT(*this, Allocator->getExprLoc(), DSAStack)) 22706 return nullptr; 22707 22708 ExprResult AllocatorRes = DefaultLvalueConversion(Allocator); 22709 if (AllocatorRes.isInvalid()) 22710 return nullptr; 22711 AllocatorRes = PerformImplicitConversion(AllocatorRes.get(), 22712 DSAStack->getOMPAllocatorHandleT(), 22713 Sema::AA_Initializing, 22714 /*AllowExplicit=*/true); 22715 if (AllocatorRes.isInvalid()) 22716 return nullptr; 22717 Allocator = AllocatorRes.get(); 22718 } else { 22719 // OpenMP 5.0, 2.11.4 allocate Clause, Restrictions. 22720 // allocate clauses that appear on a target construct or on constructs in a 22721 // target region must specify an allocator expression unless a requires 22722 // directive with the dynamic_allocators clause is present in the same 22723 // compilation unit. 22724 if (LangOpts.OpenMPIsDevice && 22725 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 22726 targetDiag(StartLoc, diag::err_expected_allocator_expression); 22727 } 22728 // Analyze and build list of variables. 22729 SmallVector<Expr *, 8> Vars; 22730 for (Expr *RefExpr : VarList) { 22731 assert(RefExpr && "NULL expr in OpenMP private clause."); 22732 SourceLocation ELoc; 22733 SourceRange ERange; 22734 Expr *SimpleRefExpr = RefExpr; 22735 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22736 if (Res.second) { 22737 // It will be analyzed later. 22738 Vars.push_back(RefExpr); 22739 } 22740 ValueDecl *D = Res.first; 22741 if (!D) 22742 continue; 22743 22744 auto *VD = dyn_cast<VarDecl>(D); 22745 DeclRefExpr *Ref = nullptr; 22746 if (!VD && !CurContext->isDependentContext()) 22747 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 22748 Vars.push_back((VD || CurContext->isDependentContext()) 22749 ? RefExpr->IgnoreParens() 22750 : Ref); 22751 } 22752 22753 if (Vars.empty()) 22754 return nullptr; 22755 22756 if (Allocator) 22757 DSAStack->addInnerAllocatorExpr(Allocator); 22758 return OMPAllocateClause::Create(Context, StartLoc, LParenLoc, Allocator, 22759 ColonLoc, EndLoc, Vars); 22760 } 22761 22762 OMPClause *Sema::ActOnOpenMPNontemporalClause(ArrayRef<Expr *> VarList, 22763 SourceLocation StartLoc, 22764 SourceLocation LParenLoc, 22765 SourceLocation EndLoc) { 22766 SmallVector<Expr *, 8> Vars; 22767 for (Expr *RefExpr : VarList) { 22768 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 22769 SourceLocation ELoc; 22770 SourceRange ERange; 22771 Expr *SimpleRefExpr = RefExpr; 22772 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 22773 if (Res.second) 22774 // It will be analyzed later. 22775 Vars.push_back(RefExpr); 22776 ValueDecl *D = Res.first; 22777 if (!D) 22778 continue; 22779 22780 // OpenMP 5.0, 2.9.3.1 simd Construct, Restrictions. 22781 // A list-item cannot appear in more than one nontemporal clause. 22782 if (const Expr *PrevRef = 22783 DSAStack->addUniqueNontemporal(D, SimpleRefExpr)) { 22784 Diag(ELoc, diag::err_omp_used_in_clause_twice) 22785 << 0 << getOpenMPClauseName(OMPC_nontemporal) << ERange; 22786 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 22787 << getOpenMPClauseName(OMPC_nontemporal); 22788 continue; 22789 } 22790 22791 Vars.push_back(RefExpr); 22792 } 22793 22794 if (Vars.empty()) 22795 return nullptr; 22796 22797 return OMPNontemporalClause::Create(Context, StartLoc, LParenLoc, EndLoc, 22798 Vars); 22799 } 22800 22801 OMPClause *Sema::ActOnOpenMPInclusiveClause(ArrayRef<Expr *> VarList, 22802 SourceLocation StartLoc, 22803 SourceLocation LParenLoc, 22804 SourceLocation EndLoc) { 22805 SmallVector<Expr *, 8> Vars; 22806 for (Expr *RefExpr : VarList) { 22807 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 22808 SourceLocation ELoc; 22809 SourceRange ERange; 22810 Expr *SimpleRefExpr = RefExpr; 22811 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22812 /*AllowArraySection=*/true); 22813 if (Res.second) 22814 // It will be analyzed later. 22815 Vars.push_back(RefExpr); 22816 ValueDecl *D = Res.first; 22817 if (!D) 22818 continue; 22819 22820 const DSAStackTy::DSAVarData DVar = 22821 DSAStack->getTopDSA(D, /*FromParent=*/true); 22822 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 22823 // A list item that appears in the inclusive or exclusive clause must appear 22824 // in a reduction clause with the inscan modifier on the enclosing 22825 // worksharing-loop, worksharing-loop SIMD, or simd construct. 22826 if (DVar.CKind != OMPC_reduction || DVar.Modifier != OMPC_REDUCTION_inscan) 22827 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 22828 << RefExpr->getSourceRange(); 22829 22830 if (DSAStack->getParentDirective() != OMPD_unknown) 22831 DSAStack->markDeclAsUsedInScanDirective(D); 22832 Vars.push_back(RefExpr); 22833 } 22834 22835 if (Vars.empty()) 22836 return nullptr; 22837 22838 return OMPInclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 22839 } 22840 22841 OMPClause *Sema::ActOnOpenMPExclusiveClause(ArrayRef<Expr *> VarList, 22842 SourceLocation StartLoc, 22843 SourceLocation LParenLoc, 22844 SourceLocation EndLoc) { 22845 SmallVector<Expr *, 8> Vars; 22846 for (Expr *RefExpr : VarList) { 22847 assert(RefExpr && "NULL expr in OpenMP nontemporal clause."); 22848 SourceLocation ELoc; 22849 SourceRange ERange; 22850 Expr *SimpleRefExpr = RefExpr; 22851 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 22852 /*AllowArraySection=*/true); 22853 if (Res.second) 22854 // It will be analyzed later. 22855 Vars.push_back(RefExpr); 22856 ValueDecl *D = Res.first; 22857 if (!D) 22858 continue; 22859 22860 OpenMPDirectiveKind ParentDirective = DSAStack->getParentDirective(); 22861 DSAStackTy::DSAVarData DVar; 22862 if (ParentDirective != OMPD_unknown) 22863 DVar = DSAStack->getTopDSA(D, /*FromParent=*/true); 22864 // OpenMP 5.0, 2.9.6, scan Directive, Restrictions. 22865 // A list item that appears in the inclusive or exclusive clause must appear 22866 // in a reduction clause with the inscan modifier on the enclosing 22867 // worksharing-loop, worksharing-loop SIMD, or simd construct. 22868 if (ParentDirective == OMPD_unknown || DVar.CKind != OMPC_reduction || 22869 DVar.Modifier != OMPC_REDUCTION_inscan) { 22870 Diag(ELoc, diag::err_omp_inclusive_exclusive_not_reduction) 22871 << RefExpr->getSourceRange(); 22872 } else { 22873 DSAStack->markDeclAsUsedInScanDirective(D); 22874 } 22875 Vars.push_back(RefExpr); 22876 } 22877 22878 if (Vars.empty()) 22879 return nullptr; 22880 22881 return OMPExclusiveClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 22882 } 22883 22884 /// Tries to find omp_alloctrait_t type. 22885 static bool findOMPAlloctraitT(Sema &S, SourceLocation Loc, DSAStackTy *Stack) { 22886 QualType OMPAlloctraitT = Stack->getOMPAlloctraitT(); 22887 if (!OMPAlloctraitT.isNull()) 22888 return true; 22889 IdentifierInfo &II = S.PP.getIdentifierTable().get("omp_alloctrait_t"); 22890 ParsedType PT = S.getTypeName(II, Loc, S.getCurScope()); 22891 if (!PT.getAsOpaquePtr() || PT.get().isNull()) { 22892 S.Diag(Loc, diag::err_omp_implied_type_not_found) << "omp_alloctrait_t"; 22893 return false; 22894 } 22895 Stack->setOMPAlloctraitT(PT.get()); 22896 return true; 22897 } 22898 22899 OMPClause *Sema::ActOnOpenMPUsesAllocatorClause( 22900 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc, 22901 ArrayRef<UsesAllocatorsData> Data) { 22902 // OpenMP [2.12.5, target Construct] 22903 // allocator is an identifier of omp_allocator_handle_t type. 22904 if (!findOMPAllocatorHandleT(*this, StartLoc, DSAStack)) 22905 return nullptr; 22906 // OpenMP [2.12.5, target Construct] 22907 // allocator-traits-array is an identifier of const omp_alloctrait_t * type. 22908 if (llvm::any_of( 22909 Data, 22910 [](const UsesAllocatorsData &D) { return D.AllocatorTraits; }) && 22911 !findOMPAlloctraitT(*this, StartLoc, DSAStack)) 22912 return nullptr; 22913 llvm::SmallPtrSet<CanonicalDeclPtr<Decl>, 4> PredefinedAllocators; 22914 for (int I = 0; I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 22915 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 22916 StringRef Allocator = 22917 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 22918 DeclarationName AllocatorName = &Context.Idents.get(Allocator); 22919 PredefinedAllocators.insert(LookupSingleName( 22920 TUScope, AllocatorName, StartLoc, Sema::LookupAnyName)); 22921 } 22922 22923 SmallVector<OMPUsesAllocatorsClause::Data, 4> NewData; 22924 for (const UsesAllocatorsData &D : Data) { 22925 Expr *AllocatorExpr = nullptr; 22926 // Check allocator expression. 22927 if (D.Allocator->isTypeDependent()) { 22928 AllocatorExpr = D.Allocator; 22929 } else { 22930 // Traits were specified - need to assign new allocator to the specified 22931 // allocator, so it must be an lvalue. 22932 AllocatorExpr = D.Allocator->IgnoreParenImpCasts(); 22933 auto *DRE = dyn_cast<DeclRefExpr>(AllocatorExpr); 22934 bool IsPredefinedAllocator = false; 22935 if (DRE) 22936 IsPredefinedAllocator = PredefinedAllocators.count(DRE->getDecl()); 22937 if (!DRE || 22938 !(Context.hasSameUnqualifiedType( 22939 AllocatorExpr->getType(), DSAStack->getOMPAllocatorHandleT()) || 22940 Context.typesAreCompatible(AllocatorExpr->getType(), 22941 DSAStack->getOMPAllocatorHandleT(), 22942 /*CompareUnqualified=*/true)) || 22943 (!IsPredefinedAllocator && 22944 (AllocatorExpr->getType().isConstant(Context) || 22945 !AllocatorExpr->isLValue()))) { 22946 Diag(D.Allocator->getExprLoc(), diag::err_omp_var_expected) 22947 << "omp_allocator_handle_t" << (DRE ? 1 : 0) 22948 << AllocatorExpr->getType() << D.Allocator->getSourceRange(); 22949 continue; 22950 } 22951 // OpenMP [2.12.5, target Construct] 22952 // Predefined allocators appearing in a uses_allocators clause cannot have 22953 // traits specified. 22954 if (IsPredefinedAllocator && D.AllocatorTraits) { 22955 Diag(D.AllocatorTraits->getExprLoc(), 22956 diag::err_omp_predefined_allocator_with_traits) 22957 << D.AllocatorTraits->getSourceRange(); 22958 Diag(D.Allocator->getExprLoc(), diag::note_omp_predefined_allocator) 22959 << cast<NamedDecl>(DRE->getDecl())->getName() 22960 << D.Allocator->getSourceRange(); 22961 continue; 22962 } 22963 // OpenMP [2.12.5, target Construct] 22964 // Non-predefined allocators appearing in a uses_allocators clause must 22965 // have traits specified. 22966 if (!IsPredefinedAllocator && !D.AllocatorTraits) { 22967 Diag(D.Allocator->getExprLoc(), 22968 diag::err_omp_nonpredefined_allocator_without_traits); 22969 continue; 22970 } 22971 // No allocator traits - just convert it to rvalue. 22972 if (!D.AllocatorTraits) 22973 AllocatorExpr = DefaultLvalueConversion(AllocatorExpr).get(); 22974 DSAStack->addUsesAllocatorsDecl( 22975 DRE->getDecl(), 22976 IsPredefinedAllocator 22977 ? DSAStackTy::UsesAllocatorsDeclKind::PredefinedAllocator 22978 : DSAStackTy::UsesAllocatorsDeclKind::UserDefinedAllocator); 22979 } 22980 Expr *AllocatorTraitsExpr = nullptr; 22981 if (D.AllocatorTraits) { 22982 if (D.AllocatorTraits->isTypeDependent()) { 22983 AllocatorTraitsExpr = D.AllocatorTraits; 22984 } else { 22985 // OpenMP [2.12.5, target Construct] 22986 // Arrays that contain allocator traits that appear in a uses_allocators 22987 // clause must be constant arrays, have constant values and be defined 22988 // in the same scope as the construct in which the clause appears. 22989 AllocatorTraitsExpr = D.AllocatorTraits->IgnoreParenImpCasts(); 22990 // Check that traits expr is a constant array. 22991 QualType TraitTy; 22992 if (const ArrayType *Ty = 22993 AllocatorTraitsExpr->getType()->getAsArrayTypeUnsafe()) 22994 if (const auto *ConstArrayTy = dyn_cast<ConstantArrayType>(Ty)) 22995 TraitTy = ConstArrayTy->getElementType(); 22996 if (TraitTy.isNull() || 22997 !(Context.hasSameUnqualifiedType(TraitTy, 22998 DSAStack->getOMPAlloctraitT()) || 22999 Context.typesAreCompatible(TraitTy, DSAStack->getOMPAlloctraitT(), 23000 /*CompareUnqualified=*/true))) { 23001 Diag(D.AllocatorTraits->getExprLoc(), 23002 diag::err_omp_expected_array_alloctraits) 23003 << AllocatorTraitsExpr->getType(); 23004 continue; 23005 } 23006 // Do not map by default allocator traits if it is a standalone 23007 // variable. 23008 if (auto *DRE = dyn_cast<DeclRefExpr>(AllocatorTraitsExpr)) 23009 DSAStack->addUsesAllocatorsDecl( 23010 DRE->getDecl(), 23011 DSAStackTy::UsesAllocatorsDeclKind::AllocatorTrait); 23012 } 23013 } 23014 OMPUsesAllocatorsClause::Data &NewD = NewData.emplace_back(); 23015 NewD.Allocator = AllocatorExpr; 23016 NewD.AllocatorTraits = AllocatorTraitsExpr; 23017 NewD.LParenLoc = D.LParenLoc; 23018 NewD.RParenLoc = D.RParenLoc; 23019 } 23020 return OMPUsesAllocatorsClause::Create(Context, StartLoc, LParenLoc, EndLoc, 23021 NewData); 23022 } 23023 23024 OMPClause *Sema::ActOnOpenMPAffinityClause( 23025 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 23026 SourceLocation EndLoc, Expr *Modifier, ArrayRef<Expr *> Locators) { 23027 SmallVector<Expr *, 8> Vars; 23028 for (Expr *RefExpr : Locators) { 23029 assert(RefExpr && "NULL expr in OpenMP shared clause."); 23030 if (isa<DependentScopeDeclRefExpr>(RefExpr) || RefExpr->isTypeDependent()) { 23031 // It will be analyzed later. 23032 Vars.push_back(RefExpr); 23033 continue; 23034 } 23035 23036 SourceLocation ELoc = RefExpr->getExprLoc(); 23037 Expr *SimpleExpr = RefExpr->IgnoreParenImpCasts(); 23038 23039 if (!SimpleExpr->isLValue()) { 23040 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 23041 << 1 << 0 << RefExpr->getSourceRange(); 23042 continue; 23043 } 23044 23045 ExprResult Res; 23046 { 23047 Sema::TentativeAnalysisScope Trap(*this); 23048 Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, SimpleExpr); 23049 } 23050 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr) && 23051 !isa<OMPArrayShapingExpr>(SimpleExpr)) { 23052 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 23053 << 1 << 0 << RefExpr->getSourceRange(); 23054 continue; 23055 } 23056 Vars.push_back(SimpleExpr); 23057 } 23058 23059 return OMPAffinityClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 23060 EndLoc, Modifier, Vars); 23061 } 23062 23063 OMPClause *Sema::ActOnOpenMPBindClause(OpenMPBindClauseKind Kind, 23064 SourceLocation KindLoc, 23065 SourceLocation StartLoc, 23066 SourceLocation LParenLoc, 23067 SourceLocation EndLoc) { 23068 if (Kind == OMPC_BIND_unknown) { 23069 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 23070 << getListOfPossibleValues(OMPC_bind, /*First=*/0, 23071 /*Last=*/unsigned(OMPC_BIND_unknown)) 23072 << getOpenMPClauseName(OMPC_bind); 23073 return nullptr; 23074 } 23075 23076 return OMPBindClause::Create(Context, Kind, KindLoc, StartLoc, LParenLoc, 23077 EndLoc); 23078 } 23079