1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 /// \file 9 /// This file implements semantic analysis for OpenMP directives and 10 /// clauses. 11 /// 12 //===----------------------------------------------------------------------===// 13 14 #include "TreeTransform.h" 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/CXXInheritance.h" 18 #include "clang/AST/Decl.h" 19 #include "clang/AST/DeclCXX.h" 20 #include "clang/AST/DeclOpenMP.h" 21 #include "clang/AST/StmtCXX.h" 22 #include "clang/AST/StmtOpenMP.h" 23 #include "clang/AST/StmtVisitor.h" 24 #include "clang/AST/TypeOrdering.h" 25 #include "clang/Basic/OpenMPKinds.h" 26 #include "clang/Sema/Initialization.h" 27 #include "clang/Sema/Lookup.h" 28 #include "clang/Sema/Scope.h" 29 #include "clang/Sema/ScopeInfo.h" 30 #include "clang/Sema/SemaInternal.h" 31 #include "llvm/ADT/PointerEmbeddedInt.h" 32 using namespace clang; 33 34 //===----------------------------------------------------------------------===// 35 // Stack of data-sharing attributes for variables 36 //===----------------------------------------------------------------------===// 37 38 static const Expr *checkMapClauseExpressionBase( 39 Sema &SemaRef, Expr *E, 40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 41 OpenMPClauseKind CKind, bool NoDiagnose); 42 43 namespace { 44 /// Default data sharing attributes, which can be applied to directive. 45 enum DefaultDataSharingAttributes { 46 DSA_unspecified = 0, /// Data sharing attribute not specified. 47 DSA_none = 1 << 0, /// Default data sharing attribute 'none'. 48 DSA_shared = 1 << 1, /// Default data sharing attribute 'shared'. 49 }; 50 51 /// Attributes of the defaultmap clause. 52 enum DefaultMapAttributes { 53 DMA_unspecified, /// Default mapping is not specified. 54 DMA_tofrom_scalar, /// Default mapping is 'tofrom:scalar'. 55 }; 56 57 /// Stack for tracking declarations used in OpenMP directives and 58 /// clauses and their data-sharing attributes. 59 class DSAStackTy { 60 public: 61 struct DSAVarData { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 const Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 69 const Expr *RefExpr, DeclRefExpr *PrivateCopy, 70 SourceLocation ImplicitDSALoc) 71 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 72 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 73 }; 74 using OperatorOffsetTy = 75 llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4>; 76 using DoacrossDependMapTy = 77 llvm::DenseMap<OMPDependClause *, OperatorOffsetTy>; 78 79 private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes = OMPC_unknown; 82 /// Pointer to a reference expression and a flag which shows that the 83 /// variable is marked as lastprivate(true) or not (false). 84 llvm::PointerIntPair<const Expr *, 1, bool> RefExpr; 85 DeclRefExpr *PrivateCopy = nullptr; 86 }; 87 using DeclSAMapTy = llvm::SmallDenseMap<const ValueDecl *, DSAInfo, 8>; 88 using AlignedMapTy = llvm::SmallDenseMap<const ValueDecl *, const Expr *, 8>; 89 using LCDeclInfo = std::pair<unsigned, VarDecl *>; 90 using LoopControlVariablesMapTy = 91 llvm::SmallDenseMap<const ValueDecl *, LCDeclInfo, 8>; 92 /// Struct that associates a component with the clause kind where they are 93 /// found. 94 struct MappedExprComponentTy { 95 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 96 OpenMPClauseKind Kind = OMPC_unknown; 97 }; 98 using MappedExprComponentsTy = 99 llvm::DenseMap<const ValueDecl *, MappedExprComponentTy>; 100 using CriticalsWithHintsTy = 101 llvm::StringMap<std::pair<const OMPCriticalDirective *, llvm::APSInt>>; 102 struct ReductionData { 103 using BOKPtrType = llvm::PointerEmbeddedInt<BinaryOperatorKind, 16>; 104 SourceRange ReductionRange; 105 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 106 ReductionData() = default; 107 void set(BinaryOperatorKind BO, SourceRange RR) { 108 ReductionRange = RR; 109 ReductionOp = BO; 110 } 111 void set(const Expr *RefExpr, SourceRange RR) { 112 ReductionRange = RR; 113 ReductionOp = RefExpr; 114 } 115 }; 116 using DeclReductionMapTy = 117 llvm::SmallDenseMap<const ValueDecl *, ReductionData, 4>; 118 119 struct SharingMapTy { 120 DeclSAMapTy SharingMap; 121 DeclReductionMapTy ReductionMap; 122 AlignedMapTy AlignedMap; 123 MappedExprComponentsTy MappedExprComponents; 124 LoopControlVariablesMapTy LCVMap; 125 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 126 SourceLocation DefaultAttrLoc; 127 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 128 SourceLocation DefaultMapAttrLoc; 129 OpenMPDirectiveKind Directive = OMPD_unknown; 130 DeclarationNameInfo DirectiveName; 131 Scope *CurScope = nullptr; 132 SourceLocation ConstructLoc; 133 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 134 /// get the data (loop counters etc.) about enclosing loop-based construct. 135 /// This data is required during codegen. 136 DoacrossDependMapTy DoacrossDepends; 137 /// First argument (Expr *) contains optional argument of the 138 /// 'ordered' clause, the second one is true if the regions has 'ordered' 139 /// clause, false otherwise. 140 llvm::Optional<std::pair<const Expr *, OMPOrderedClause *>> OrderedRegion; 141 unsigned AssociatedLoops = 1; 142 const Decl *PossiblyLoopCounter = nullptr; 143 bool NowaitRegion = false; 144 bool CancelRegion = false; 145 bool LoopStart = false; 146 SourceLocation InnerTeamsRegionLoc; 147 /// Reference to the taskgroup task_reduction reference expression. 148 Expr *TaskgroupReductionRef = nullptr; 149 llvm::DenseSet<QualType> MappedClassesQualTypes; 150 /// List of globals marked as declare target link in this target region 151 /// (isOpenMPTargetExecutionDirective(Directive) == true). 152 llvm::SmallVector<DeclRefExpr *, 4> DeclareTargetLinkVarDecls; 153 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 154 Scope *CurScope, SourceLocation Loc) 155 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 156 ConstructLoc(Loc) {} 157 SharingMapTy() = default; 158 }; 159 160 using StackTy = SmallVector<SharingMapTy, 4>; 161 162 /// Stack of used declaration and their data-sharing attributes. 163 DeclSAMapTy Threadprivates; 164 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 165 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 166 /// true, if check for DSA must be from parent directive, false, if 167 /// from current directive. 168 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 169 Sema &SemaRef; 170 bool ForceCapturing = false; 171 /// true if all the vaiables in the target executable directives must be 172 /// captured by reference. 173 bool ForceCaptureByReferenceInTargetExecutable = false; 174 CriticalsWithHintsTy Criticals; 175 176 using iterator = StackTy::const_reverse_iterator; 177 178 DSAVarData getDSA(iterator &Iter, ValueDecl *D) const; 179 180 /// Checks if the variable is a local for OpenMP region. 181 bool isOpenMPLocal(VarDecl *D, iterator Iter) const; 182 183 bool isStackEmpty() const { 184 return Stack.empty() || 185 Stack.back().second != CurrentNonCapturingFunctionScope || 186 Stack.back().first.empty(); 187 } 188 189 /// Vector of previously declared requires directives 190 SmallVector<const OMPRequiresDecl *, 2> RequiresDecls; 191 /// omp_allocator_handle_t type. 192 QualType OMPAllocatorHandleT; 193 /// Expression for the predefined allocators. 194 Expr *OMPPredefinedAllocators[OMPAllocateDeclAttr::OMPUserDefinedMemAlloc] = { 195 nullptr}; 196 197 public: 198 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 199 200 /// Sets omp_allocator_handle_t type. 201 void setOMPAllocatorHandleT(QualType Ty) { OMPAllocatorHandleT = Ty; } 202 /// Gets omp_allocator_handle_t type. 203 QualType getOMPAllocatorHandleT() const { return OMPAllocatorHandleT; } 204 /// Sets the given default allocator. 205 void setAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind, 206 Expr *Allocator) { 207 OMPPredefinedAllocators[AllocatorKind] = Allocator; 208 } 209 /// Returns the specified default allocator. 210 Expr *getAllocator(OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind) const { 211 return OMPPredefinedAllocators[AllocatorKind]; 212 } 213 214 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 215 OpenMPClauseKind getClauseParsingMode() const { 216 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 217 return ClauseKindMode; 218 } 219 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 220 221 bool isForceVarCapturing() const { return ForceCapturing; } 222 void setForceVarCapturing(bool V) { ForceCapturing = V; } 223 224 void setForceCaptureByReferenceInTargetExecutable(bool V) { 225 ForceCaptureByReferenceInTargetExecutable = V; 226 } 227 bool isForceCaptureByReferenceInTargetExecutable() const { 228 return ForceCaptureByReferenceInTargetExecutable; 229 } 230 231 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 232 Scope *CurScope, SourceLocation Loc) { 233 if (Stack.empty() || 234 Stack.back().second != CurrentNonCapturingFunctionScope) 235 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 236 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 237 Stack.back().first.back().DefaultAttrLoc = Loc; 238 } 239 240 void pop() { 241 assert(!Stack.back().first.empty() && 242 "Data-sharing attributes stack is empty!"); 243 Stack.back().first.pop_back(); 244 } 245 246 /// Marks that we're started loop parsing. 247 void loopInit() { 248 assert(isOpenMPLoopDirective(getCurrentDirective()) && 249 "Expected loop-based directive."); 250 Stack.back().first.back().LoopStart = true; 251 } 252 /// Start capturing of the variables in the loop context. 253 void loopStart() { 254 assert(isOpenMPLoopDirective(getCurrentDirective()) && 255 "Expected loop-based directive."); 256 Stack.back().first.back().LoopStart = false; 257 } 258 /// true, if variables are captured, false otherwise. 259 bool isLoopStarted() const { 260 assert(isOpenMPLoopDirective(getCurrentDirective()) && 261 "Expected loop-based directive."); 262 return !Stack.back().first.back().LoopStart; 263 } 264 /// Marks (or clears) declaration as possibly loop counter. 265 void resetPossibleLoopCounter(const Decl *D = nullptr) { 266 Stack.back().first.back().PossiblyLoopCounter = 267 D ? D->getCanonicalDecl() : D; 268 } 269 /// Gets the possible loop counter decl. 270 const Decl *getPossiblyLoopCunter() const { 271 return Stack.back().first.back().PossiblyLoopCounter; 272 } 273 /// Start new OpenMP region stack in new non-capturing function. 274 void pushFunction() { 275 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 276 assert(!isa<CapturingScopeInfo>(CurFnScope)); 277 CurrentNonCapturingFunctionScope = CurFnScope; 278 } 279 /// Pop region stack for non-capturing function. 280 void popFunction(const FunctionScopeInfo *OldFSI) { 281 if (!Stack.empty() && Stack.back().second == OldFSI) { 282 assert(Stack.back().first.empty()); 283 Stack.pop_back(); 284 } 285 CurrentNonCapturingFunctionScope = nullptr; 286 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 287 if (!isa<CapturingScopeInfo>(FSI)) { 288 CurrentNonCapturingFunctionScope = FSI; 289 break; 290 } 291 } 292 } 293 294 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 295 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 296 } 297 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 298 getCriticalWithHint(const DeclarationNameInfo &Name) const { 299 auto I = Criticals.find(Name.getAsString()); 300 if (I != Criticals.end()) 301 return I->second; 302 return std::make_pair(nullptr, llvm::APSInt()); 303 } 304 /// If 'aligned' declaration for given variable \a D was not seen yet, 305 /// add it and return NULL; otherwise return previous occurrence's expression 306 /// for diagnostics. 307 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 308 309 /// Register specified variable as loop control variable. 310 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 311 /// Check if the specified variable is a loop control variable for 312 /// current region. 313 /// \return The index of the loop control variable in the list of associated 314 /// for-loops (from outer to inner). 315 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 316 /// Check if the specified variable is a loop control variable for 317 /// parent region. 318 /// \return The index of the loop control variable in the list of associated 319 /// for-loops (from outer to inner). 320 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 321 /// Get the loop control variable for the I-th loop (or nullptr) in 322 /// parent directive. 323 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 324 325 /// Adds explicit data sharing attribute to the specified declaration. 326 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 327 DeclRefExpr *PrivateCopy = nullptr); 328 329 /// Adds additional information for the reduction items with the reduction id 330 /// represented as an operator. 331 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 332 BinaryOperatorKind BOK); 333 /// Adds additional information for the reduction items with the reduction id 334 /// represented as reduction identifier. 335 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 336 const Expr *ReductionRef); 337 /// Returns the location and reduction operation from the innermost parent 338 /// region for the given \p D. 339 const DSAVarData 340 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 341 BinaryOperatorKind &BOK, 342 Expr *&TaskgroupDescriptor) const; 343 /// Returns the location and reduction operation from the innermost parent 344 /// region for the given \p D. 345 const DSAVarData 346 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 347 const Expr *&ReductionRef, 348 Expr *&TaskgroupDescriptor) const; 349 /// Return reduction reference expression for the current taskgroup. 350 Expr *getTaskgroupReductionRef() const { 351 assert(Stack.back().first.back().Directive == OMPD_taskgroup && 352 "taskgroup reference expression requested for non taskgroup " 353 "directive."); 354 return Stack.back().first.back().TaskgroupReductionRef; 355 } 356 /// Checks if the given \p VD declaration is actually a taskgroup reduction 357 /// descriptor variable at the \p Level of OpenMP regions. 358 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 359 return Stack.back().first[Level].TaskgroupReductionRef && 360 cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef) 361 ->getDecl() == VD; 362 } 363 364 /// Returns data sharing attributes from top of the stack for the 365 /// specified declaration. 366 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 367 /// Returns data-sharing attributes for the specified declaration. 368 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 369 /// Checks if the specified variables has data-sharing attributes which 370 /// match specified \a CPred predicate in any directive which matches \a DPred 371 /// predicate. 372 const DSAVarData 373 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 374 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 375 bool FromParent) const; 376 /// Checks if the specified variables has data-sharing attributes which 377 /// match specified \a CPred predicate in any innermost directive which 378 /// matches \a DPred predicate. 379 const DSAVarData 380 hasInnermostDSA(ValueDecl *D, 381 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 382 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 383 bool FromParent) const; 384 /// Checks if the specified variables has explicit data-sharing 385 /// attributes which match specified \a CPred predicate at the specified 386 /// OpenMP region. 387 bool hasExplicitDSA(const ValueDecl *D, 388 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 389 unsigned Level, bool NotLastprivate = false) const; 390 391 /// Returns true if the directive at level \Level matches in the 392 /// specified \a DPred predicate. 393 bool hasExplicitDirective( 394 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 395 unsigned Level) const; 396 397 /// Finds a directive which matches specified \a DPred predicate. 398 bool hasDirective( 399 const llvm::function_ref<bool( 400 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 401 DPred, 402 bool FromParent) const; 403 404 /// Returns currently analyzed directive. 405 OpenMPDirectiveKind getCurrentDirective() const { 406 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive; 407 } 408 /// Returns directive kind at specified level. 409 OpenMPDirectiveKind getDirective(unsigned Level) const { 410 assert(!isStackEmpty() && "No directive at specified level."); 411 return Stack.back().first[Level].Directive; 412 } 413 /// Returns parent directive. 414 OpenMPDirectiveKind getParentDirective() const { 415 if (isStackEmpty() || Stack.back().first.size() == 1) 416 return OMPD_unknown; 417 return std::next(Stack.back().first.rbegin())->Directive; 418 } 419 420 /// Add requires decl to internal vector 421 void addRequiresDecl(OMPRequiresDecl *RD) { 422 RequiresDecls.push_back(RD); 423 } 424 425 /// Checks for a duplicate clause amongst previously declared requires 426 /// directives 427 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 428 bool IsDuplicate = false; 429 for (OMPClause *CNew : ClauseList) { 430 for (const OMPRequiresDecl *D : RequiresDecls) { 431 for (const OMPClause *CPrev : D->clauselists()) { 432 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 433 SemaRef.Diag(CNew->getBeginLoc(), 434 diag::err_omp_requires_clause_redeclaration) 435 << getOpenMPClauseName(CNew->getClauseKind()); 436 SemaRef.Diag(CPrev->getBeginLoc(), 437 diag::note_omp_requires_previous_clause) 438 << getOpenMPClauseName(CPrev->getClauseKind()); 439 IsDuplicate = true; 440 } 441 } 442 } 443 } 444 return IsDuplicate; 445 } 446 447 /// Set default data sharing attribute to none. 448 void setDefaultDSANone(SourceLocation Loc) { 449 assert(!isStackEmpty()); 450 Stack.back().first.back().DefaultAttr = DSA_none; 451 Stack.back().first.back().DefaultAttrLoc = Loc; 452 } 453 /// Set default data sharing attribute to shared. 454 void setDefaultDSAShared(SourceLocation Loc) { 455 assert(!isStackEmpty()); 456 Stack.back().first.back().DefaultAttr = DSA_shared; 457 Stack.back().first.back().DefaultAttrLoc = Loc; 458 } 459 /// Set default data mapping attribute to 'tofrom:scalar'. 460 void setDefaultDMAToFromScalar(SourceLocation Loc) { 461 assert(!isStackEmpty()); 462 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar; 463 Stack.back().first.back().DefaultMapAttrLoc = Loc; 464 } 465 466 DefaultDataSharingAttributes getDefaultDSA() const { 467 return isStackEmpty() ? DSA_unspecified 468 : Stack.back().first.back().DefaultAttr; 469 } 470 SourceLocation getDefaultDSALocation() const { 471 return isStackEmpty() ? SourceLocation() 472 : Stack.back().first.back().DefaultAttrLoc; 473 } 474 DefaultMapAttributes getDefaultDMA() const { 475 return isStackEmpty() ? DMA_unspecified 476 : Stack.back().first.back().DefaultMapAttr; 477 } 478 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 479 return Stack.back().first[Level].DefaultMapAttr; 480 } 481 SourceLocation getDefaultDMALocation() const { 482 return isStackEmpty() ? SourceLocation() 483 : Stack.back().first.back().DefaultMapAttrLoc; 484 } 485 486 /// Checks if the specified variable is a threadprivate. 487 bool isThreadPrivate(VarDecl *D) { 488 const DSAVarData DVar = getTopDSA(D, false); 489 return isOpenMPThreadPrivate(DVar.CKind); 490 } 491 492 /// Marks current region as ordered (it has an 'ordered' clause). 493 void setOrderedRegion(bool IsOrdered, const Expr *Param, 494 OMPOrderedClause *Clause) { 495 assert(!isStackEmpty()); 496 if (IsOrdered) 497 Stack.back().first.back().OrderedRegion.emplace(Param, Clause); 498 else 499 Stack.back().first.back().OrderedRegion.reset(); 500 } 501 /// Returns true, if region is ordered (has associated 'ordered' clause), 502 /// false - otherwise. 503 bool isOrderedRegion() const { 504 if (isStackEmpty()) 505 return false; 506 return Stack.back().first.rbegin()->OrderedRegion.hasValue(); 507 } 508 /// Returns optional parameter for the ordered region. 509 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 510 if (isStackEmpty() || 511 !Stack.back().first.rbegin()->OrderedRegion.hasValue()) 512 return std::make_pair(nullptr, nullptr); 513 return Stack.back().first.rbegin()->OrderedRegion.getValue(); 514 } 515 /// Returns true, if parent region is ordered (has associated 516 /// 'ordered' clause), false - otherwise. 517 bool isParentOrderedRegion() const { 518 if (isStackEmpty() || Stack.back().first.size() == 1) 519 return false; 520 return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue(); 521 } 522 /// Returns optional parameter for the ordered region. 523 std::pair<const Expr *, OMPOrderedClause *> 524 getParentOrderedRegionParam() const { 525 if (isStackEmpty() || Stack.back().first.size() == 1 || 526 !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue()) 527 return std::make_pair(nullptr, nullptr); 528 return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue(); 529 } 530 /// Marks current region as nowait (it has a 'nowait' clause). 531 void setNowaitRegion(bool IsNowait = true) { 532 assert(!isStackEmpty()); 533 Stack.back().first.back().NowaitRegion = IsNowait; 534 } 535 /// Returns true, if parent region is nowait (has associated 536 /// 'nowait' clause), false - otherwise. 537 bool isParentNowaitRegion() const { 538 if (isStackEmpty() || Stack.back().first.size() == 1) 539 return false; 540 return std::next(Stack.back().first.rbegin())->NowaitRegion; 541 } 542 /// Marks parent region as cancel region. 543 void setParentCancelRegion(bool Cancel = true) { 544 if (!isStackEmpty() && Stack.back().first.size() > 1) { 545 auto &StackElemRef = *std::next(Stack.back().first.rbegin()); 546 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel; 547 } 548 } 549 /// Return true if current region has inner cancel construct. 550 bool isCancelRegion() const { 551 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion; 552 } 553 554 /// Set collapse value for the region. 555 void setAssociatedLoops(unsigned Val) { 556 assert(!isStackEmpty()); 557 Stack.back().first.back().AssociatedLoops = Val; 558 } 559 /// Return collapse value for region. 560 unsigned getAssociatedLoops() const { 561 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops; 562 } 563 564 /// Marks current target region as one with closely nested teams 565 /// region. 566 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 567 if (!isStackEmpty() && Stack.back().first.size() > 1) { 568 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc = 569 TeamsRegionLoc; 570 } 571 } 572 /// Returns true, if current region has closely nested teams region. 573 bool hasInnerTeamsRegion() const { 574 return getInnerTeamsRegionLoc().isValid(); 575 } 576 /// Returns location of the nested teams region (if any). 577 SourceLocation getInnerTeamsRegionLoc() const { 578 return isStackEmpty() ? SourceLocation() 579 : Stack.back().first.back().InnerTeamsRegionLoc; 580 } 581 582 Scope *getCurScope() const { 583 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 584 } 585 SourceLocation getConstructLoc() const { 586 return isStackEmpty() ? SourceLocation() 587 : Stack.back().first.back().ConstructLoc; 588 } 589 590 /// Do the check specified in \a Check to all component lists and return true 591 /// if any issue is found. 592 bool checkMappableExprComponentListsForDecl( 593 const ValueDecl *VD, bool CurrentRegionOnly, 594 const llvm::function_ref< 595 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 596 OpenMPClauseKind)> 597 Check) const { 598 if (isStackEmpty()) 599 return false; 600 auto SI = Stack.back().first.rbegin(); 601 auto SE = Stack.back().first.rend(); 602 603 if (SI == SE) 604 return false; 605 606 if (CurrentRegionOnly) 607 SE = std::next(SI); 608 else 609 std::advance(SI, 1); 610 611 for (; SI != SE; ++SI) { 612 auto MI = SI->MappedExprComponents.find(VD); 613 if (MI != SI->MappedExprComponents.end()) 614 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 615 MI->second.Components) 616 if (Check(L, MI->second.Kind)) 617 return true; 618 } 619 return false; 620 } 621 622 /// Do the check specified in \a Check to all component lists at a given level 623 /// and return true if any issue is found. 624 bool checkMappableExprComponentListsForDeclAtLevel( 625 const ValueDecl *VD, unsigned Level, 626 const llvm::function_ref< 627 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 628 OpenMPClauseKind)> 629 Check) const { 630 if (isStackEmpty()) 631 return false; 632 633 auto StartI = Stack.back().first.begin(); 634 auto EndI = Stack.back().first.end(); 635 if (std::distance(StartI, EndI) <= (int)Level) 636 return false; 637 std::advance(StartI, Level); 638 639 auto MI = StartI->MappedExprComponents.find(VD); 640 if (MI != StartI->MappedExprComponents.end()) 641 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 642 MI->second.Components) 643 if (Check(L, MI->second.Kind)) 644 return true; 645 return false; 646 } 647 648 /// Create a new mappable expression component list associated with a given 649 /// declaration and initialize it with the provided list of components. 650 void addMappableExpressionComponents( 651 const ValueDecl *VD, 652 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 653 OpenMPClauseKind WhereFoundClauseKind) { 654 assert(!isStackEmpty() && 655 "Not expecting to retrieve components from a empty stack!"); 656 MappedExprComponentTy &MEC = 657 Stack.back().first.back().MappedExprComponents[VD]; 658 // Create new entry and append the new components there. 659 MEC.Components.resize(MEC.Components.size() + 1); 660 MEC.Components.back().append(Components.begin(), Components.end()); 661 MEC.Kind = WhereFoundClauseKind; 662 } 663 664 unsigned getNestingLevel() const { 665 assert(!isStackEmpty()); 666 return Stack.back().first.size() - 1; 667 } 668 void addDoacrossDependClause(OMPDependClause *C, 669 const OperatorOffsetTy &OpsOffs) { 670 assert(!isStackEmpty() && Stack.back().first.size() > 1); 671 SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 672 assert(isOpenMPWorksharingDirective(StackElem.Directive)); 673 StackElem.DoacrossDepends.try_emplace(C, OpsOffs); 674 } 675 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 676 getDoacrossDependClauses() const { 677 assert(!isStackEmpty()); 678 const SharingMapTy &StackElem = Stack.back().first.back(); 679 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 680 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 681 return llvm::make_range(Ref.begin(), Ref.end()); 682 } 683 return llvm::make_range(StackElem.DoacrossDepends.end(), 684 StackElem.DoacrossDepends.end()); 685 } 686 687 // Store types of classes which have been explicitly mapped 688 void addMappedClassesQualTypes(QualType QT) { 689 SharingMapTy &StackElem = Stack.back().first.back(); 690 StackElem.MappedClassesQualTypes.insert(QT); 691 } 692 693 // Return set of mapped classes types 694 bool isClassPreviouslyMapped(QualType QT) const { 695 const SharingMapTy &StackElem = Stack.back().first.back(); 696 return StackElem.MappedClassesQualTypes.count(QT) != 0; 697 } 698 699 /// Adds global declare target to the parent target region. 700 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 701 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 702 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 703 "Expected declare target link global."); 704 if (isStackEmpty()) 705 return; 706 auto It = Stack.back().first.rbegin(); 707 while (It != Stack.back().first.rend() && 708 !isOpenMPTargetExecutionDirective(It->Directive)) 709 ++It; 710 if (It != Stack.back().first.rend()) { 711 assert(isOpenMPTargetExecutionDirective(It->Directive) && 712 "Expected target executable directive."); 713 It->DeclareTargetLinkVarDecls.push_back(E); 714 } 715 } 716 717 /// Returns the list of globals with declare target link if current directive 718 /// is target. 719 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 720 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 721 "Expected target executable directive."); 722 return Stack.back().first.back().DeclareTargetLinkVarDecls; 723 } 724 }; 725 726 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 727 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 728 } 729 730 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 731 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || DKind == OMPD_unknown; 732 } 733 734 } // namespace 735 736 static const Expr *getExprAsWritten(const Expr *E) { 737 if (const auto *FE = dyn_cast<FullExpr>(E)) 738 E = FE->getSubExpr(); 739 740 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 741 E = MTE->GetTemporaryExpr(); 742 743 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 744 E = Binder->getSubExpr(); 745 746 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 747 E = ICE->getSubExprAsWritten(); 748 return E->IgnoreParens(); 749 } 750 751 static Expr *getExprAsWritten(Expr *E) { 752 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 753 } 754 755 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 756 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 757 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 758 D = ME->getMemberDecl(); 759 const auto *VD = dyn_cast<VarDecl>(D); 760 const auto *FD = dyn_cast<FieldDecl>(D); 761 if (VD != nullptr) { 762 VD = VD->getCanonicalDecl(); 763 D = VD; 764 } else { 765 assert(FD); 766 FD = FD->getCanonicalDecl(); 767 D = FD; 768 } 769 return D; 770 } 771 772 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 773 return const_cast<ValueDecl *>( 774 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 775 } 776 777 DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter, 778 ValueDecl *D) const { 779 D = getCanonicalDecl(D); 780 auto *VD = dyn_cast<VarDecl>(D); 781 const auto *FD = dyn_cast<FieldDecl>(D); 782 DSAVarData DVar; 783 if (isStackEmpty() || Iter == Stack.back().first.rend()) { 784 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 785 // in a region but not in construct] 786 // File-scope or namespace-scope variables referenced in called routines 787 // in the region are shared unless they appear in a threadprivate 788 // directive. 789 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 790 DVar.CKind = OMPC_shared; 791 792 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 793 // in a region but not in construct] 794 // Variables with static storage duration that are declared in called 795 // routines in the region are shared. 796 if (VD && VD->hasGlobalStorage()) 797 DVar.CKind = OMPC_shared; 798 799 // Non-static data members are shared by default. 800 if (FD) 801 DVar.CKind = OMPC_shared; 802 803 return DVar; 804 } 805 806 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 807 // in a Construct, C/C++, predetermined, p.1] 808 // Variables with automatic storage duration that are declared in a scope 809 // inside the construct are private. 810 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 811 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 812 DVar.CKind = OMPC_private; 813 return DVar; 814 } 815 816 DVar.DKind = Iter->Directive; 817 // Explicitly specified attributes and local variables with predetermined 818 // attributes. 819 if (Iter->SharingMap.count(D)) { 820 const DSAInfo &Data = Iter->SharingMap.lookup(D); 821 DVar.RefExpr = Data.RefExpr.getPointer(); 822 DVar.PrivateCopy = Data.PrivateCopy; 823 DVar.CKind = Data.Attributes; 824 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 825 return DVar; 826 } 827 828 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 829 // in a Construct, C/C++, implicitly determined, p.1] 830 // In a parallel or task construct, the data-sharing attributes of these 831 // variables are determined by the default clause, if present. 832 switch (Iter->DefaultAttr) { 833 case DSA_shared: 834 DVar.CKind = OMPC_shared; 835 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 836 return DVar; 837 case DSA_none: 838 return DVar; 839 case DSA_unspecified: 840 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 841 // in a Construct, implicitly determined, p.2] 842 // In a parallel construct, if no default clause is present, these 843 // variables are shared. 844 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 845 if (isOpenMPParallelDirective(DVar.DKind) || 846 isOpenMPTeamsDirective(DVar.DKind)) { 847 DVar.CKind = OMPC_shared; 848 return DVar; 849 } 850 851 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 852 // in a Construct, implicitly determined, p.4] 853 // In a task construct, if no default clause is present, a variable that in 854 // the enclosing context is determined to be shared by all implicit tasks 855 // bound to the current team is shared. 856 if (isOpenMPTaskingDirective(DVar.DKind)) { 857 DSAVarData DVarTemp; 858 iterator I = Iter, E = Stack.back().first.rend(); 859 do { 860 ++I; 861 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 862 // Referenced in a Construct, implicitly determined, p.6] 863 // In a task construct, if no default clause is present, a variable 864 // whose data-sharing attribute is not determined by the rules above is 865 // firstprivate. 866 DVarTemp = getDSA(I, D); 867 if (DVarTemp.CKind != OMPC_shared) { 868 DVar.RefExpr = nullptr; 869 DVar.CKind = OMPC_firstprivate; 870 return DVar; 871 } 872 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 873 DVar.CKind = 874 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 875 return DVar; 876 } 877 } 878 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 879 // in a Construct, implicitly determined, p.3] 880 // For constructs other than task, if no default clause is present, these 881 // variables inherit their data-sharing attributes from the enclosing 882 // context. 883 return getDSA(++Iter, D); 884 } 885 886 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 887 const Expr *NewDE) { 888 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 889 D = getCanonicalDecl(D); 890 SharingMapTy &StackElem = Stack.back().first.back(); 891 auto It = StackElem.AlignedMap.find(D); 892 if (It == StackElem.AlignedMap.end()) { 893 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 894 StackElem.AlignedMap[D] = NewDE; 895 return nullptr; 896 } 897 assert(It->second && "Unexpected nullptr expr in the aligned map"); 898 return It->second; 899 } 900 901 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 902 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 903 D = getCanonicalDecl(D); 904 SharingMapTy &StackElem = Stack.back().first.back(); 905 StackElem.LCVMap.try_emplace( 906 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 907 } 908 909 const DSAStackTy::LCDeclInfo 910 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 911 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 912 D = getCanonicalDecl(D); 913 const SharingMapTy &StackElem = Stack.back().first.back(); 914 auto It = StackElem.LCVMap.find(D); 915 if (It != StackElem.LCVMap.end()) 916 return It->second; 917 return {0, nullptr}; 918 } 919 920 const DSAStackTy::LCDeclInfo 921 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 922 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 923 "Data-sharing attributes stack is empty"); 924 D = getCanonicalDecl(D); 925 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 926 auto It = StackElem.LCVMap.find(D); 927 if (It != StackElem.LCVMap.end()) 928 return It->second; 929 return {0, nullptr}; 930 } 931 932 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 933 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 934 "Data-sharing attributes stack is empty"); 935 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 936 if (StackElem.LCVMap.size() < I) 937 return nullptr; 938 for (const auto &Pair : StackElem.LCVMap) 939 if (Pair.second.first == I) 940 return Pair.first; 941 return nullptr; 942 } 943 944 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 945 DeclRefExpr *PrivateCopy) { 946 D = getCanonicalDecl(D); 947 if (A == OMPC_threadprivate) { 948 DSAInfo &Data = Threadprivates[D]; 949 Data.Attributes = A; 950 Data.RefExpr.setPointer(E); 951 Data.PrivateCopy = nullptr; 952 } else { 953 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 954 DSAInfo &Data = Stack.back().first.back().SharingMap[D]; 955 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 956 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 957 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 958 (isLoopControlVariable(D).first && A == OMPC_private)); 959 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 960 Data.RefExpr.setInt(/*IntVal=*/true); 961 return; 962 } 963 const bool IsLastprivate = 964 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 965 Data.Attributes = A; 966 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 967 Data.PrivateCopy = PrivateCopy; 968 if (PrivateCopy) { 969 DSAInfo &Data = 970 Stack.back().first.back().SharingMap[PrivateCopy->getDecl()]; 971 Data.Attributes = A; 972 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 973 Data.PrivateCopy = nullptr; 974 } 975 } 976 } 977 978 /// Build a variable declaration for OpenMP loop iteration variable. 979 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 980 StringRef Name, const AttrVec *Attrs = nullptr, 981 DeclRefExpr *OrigRef = nullptr) { 982 DeclContext *DC = SemaRef.CurContext; 983 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 984 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 985 auto *Decl = 986 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 987 if (Attrs) { 988 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 989 I != E; ++I) 990 Decl->addAttr(*I); 991 } 992 Decl->setImplicit(); 993 if (OrigRef) { 994 Decl->addAttr( 995 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 996 } 997 return Decl; 998 } 999 1000 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1001 SourceLocation Loc, 1002 bool RefersToCapture = false) { 1003 D->setReferenced(); 1004 D->markUsed(S.Context); 1005 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1006 SourceLocation(), D, RefersToCapture, Loc, Ty, 1007 VK_LValue); 1008 } 1009 1010 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1011 BinaryOperatorKind BOK) { 1012 D = getCanonicalDecl(D); 1013 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1014 assert( 1015 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 1016 "Additional reduction info may be specified only for reduction items."); 1017 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 1018 assert(ReductionData.ReductionRange.isInvalid() && 1019 Stack.back().first.back().Directive == OMPD_taskgroup && 1020 "Additional reduction info may be specified only once for reduction " 1021 "items."); 1022 ReductionData.set(BOK, SR); 1023 Expr *&TaskgroupReductionRef = 1024 Stack.back().first.back().TaskgroupReductionRef; 1025 if (!TaskgroupReductionRef) { 1026 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1027 SemaRef.Context.VoidPtrTy, ".task_red."); 1028 TaskgroupReductionRef = 1029 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1030 } 1031 } 1032 1033 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1034 const Expr *ReductionRef) { 1035 D = getCanonicalDecl(D); 1036 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1037 assert( 1038 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 1039 "Additional reduction info may be specified only for reduction items."); 1040 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 1041 assert(ReductionData.ReductionRange.isInvalid() && 1042 Stack.back().first.back().Directive == OMPD_taskgroup && 1043 "Additional reduction info may be specified only once for reduction " 1044 "items."); 1045 ReductionData.set(ReductionRef, SR); 1046 Expr *&TaskgroupReductionRef = 1047 Stack.back().first.back().TaskgroupReductionRef; 1048 if (!TaskgroupReductionRef) { 1049 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1050 SemaRef.Context.VoidPtrTy, ".task_red."); 1051 TaskgroupReductionRef = 1052 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1053 } 1054 } 1055 1056 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1057 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1058 Expr *&TaskgroupDescriptor) const { 1059 D = getCanonicalDecl(D); 1060 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1061 if (Stack.back().first.empty()) 1062 return DSAVarData(); 1063 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 1064 E = Stack.back().first.rend(); 1065 I != E; std::advance(I, 1)) { 1066 const DSAInfo &Data = I->SharingMap.lookup(D); 1067 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1068 continue; 1069 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1070 if (!ReductionData.ReductionOp || 1071 ReductionData.ReductionOp.is<const Expr *>()) 1072 return DSAVarData(); 1073 SR = ReductionData.ReductionRange; 1074 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1075 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1076 "expression for the descriptor is not " 1077 "set."); 1078 TaskgroupDescriptor = I->TaskgroupReductionRef; 1079 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1080 Data.PrivateCopy, I->DefaultAttrLoc); 1081 } 1082 return DSAVarData(); 1083 } 1084 1085 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1086 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1087 Expr *&TaskgroupDescriptor) const { 1088 D = getCanonicalDecl(D); 1089 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1090 if (Stack.back().first.empty()) 1091 return DSAVarData(); 1092 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 1093 E = Stack.back().first.rend(); 1094 I != E; std::advance(I, 1)) { 1095 const DSAInfo &Data = I->SharingMap.lookup(D); 1096 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1097 continue; 1098 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1099 if (!ReductionData.ReductionOp || 1100 !ReductionData.ReductionOp.is<const Expr *>()) 1101 return DSAVarData(); 1102 SR = ReductionData.ReductionRange; 1103 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1104 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1105 "expression for the descriptor is not " 1106 "set."); 1107 TaskgroupDescriptor = I->TaskgroupReductionRef; 1108 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1109 Data.PrivateCopy, I->DefaultAttrLoc); 1110 } 1111 return DSAVarData(); 1112 } 1113 1114 bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const { 1115 D = D->getCanonicalDecl(); 1116 if (!isStackEmpty()) { 1117 iterator I = Iter, E = Stack.back().first.rend(); 1118 Scope *TopScope = nullptr; 1119 while (I != E && !isImplicitOrExplicitTaskingRegion(I->Directive) && 1120 !isOpenMPTargetExecutionDirective(I->Directive)) 1121 ++I; 1122 if (I == E) 1123 return false; 1124 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1125 Scope *CurScope = getCurScope(); 1126 while (CurScope != TopScope && !CurScope->isDeclScope(D)) 1127 CurScope = CurScope->getParent(); 1128 return CurScope != TopScope; 1129 } 1130 return false; 1131 } 1132 1133 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1134 bool AcceptIfMutable = true, 1135 bool *IsClassType = nullptr) { 1136 ASTContext &Context = SemaRef.getASTContext(); 1137 Type = Type.getNonReferenceType().getCanonicalType(); 1138 bool IsConstant = Type.isConstant(Context); 1139 Type = Context.getBaseElementType(Type); 1140 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1141 ? Type->getAsCXXRecordDecl() 1142 : nullptr; 1143 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1144 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1145 RD = CTD->getTemplatedDecl(); 1146 if (IsClassType) 1147 *IsClassType = RD; 1148 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1149 RD->hasDefinition() && RD->hasMutableFields()); 1150 } 1151 1152 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1153 QualType Type, OpenMPClauseKind CKind, 1154 SourceLocation ELoc, 1155 bool AcceptIfMutable = true, 1156 bool ListItemNotVar = false) { 1157 ASTContext &Context = SemaRef.getASTContext(); 1158 bool IsClassType; 1159 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1160 unsigned Diag = ListItemNotVar 1161 ? diag::err_omp_const_list_item 1162 : IsClassType ? diag::err_omp_const_not_mutable_variable 1163 : diag::err_omp_const_variable; 1164 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1165 if (!ListItemNotVar && D) { 1166 const VarDecl *VD = dyn_cast<VarDecl>(D); 1167 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1168 VarDecl::DeclarationOnly; 1169 SemaRef.Diag(D->getLocation(), 1170 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1171 << D; 1172 } 1173 return true; 1174 } 1175 return false; 1176 } 1177 1178 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1179 bool FromParent) { 1180 D = getCanonicalDecl(D); 1181 DSAVarData DVar; 1182 1183 auto *VD = dyn_cast<VarDecl>(D); 1184 auto TI = Threadprivates.find(D); 1185 if (TI != Threadprivates.end()) { 1186 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1187 DVar.CKind = OMPC_threadprivate; 1188 return DVar; 1189 } 1190 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1191 DVar.RefExpr = buildDeclRefExpr( 1192 SemaRef, VD, D->getType().getNonReferenceType(), 1193 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1194 DVar.CKind = OMPC_threadprivate; 1195 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1196 return DVar; 1197 } 1198 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1199 // in a Construct, C/C++, predetermined, p.1] 1200 // Variables appearing in threadprivate directives are threadprivate. 1201 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1202 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1203 SemaRef.getLangOpts().OpenMPUseTLS && 1204 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1205 (VD && VD->getStorageClass() == SC_Register && 1206 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1207 DVar.RefExpr = buildDeclRefExpr( 1208 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1209 DVar.CKind = OMPC_threadprivate; 1210 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1211 return DVar; 1212 } 1213 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1214 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1215 !isLoopControlVariable(D).first) { 1216 iterator IterTarget = 1217 std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(), 1218 [](const SharingMapTy &Data) { 1219 return isOpenMPTargetExecutionDirective(Data.Directive); 1220 }); 1221 if (IterTarget != Stack.back().first.rend()) { 1222 iterator ParentIterTarget = std::next(IterTarget, 1); 1223 for (iterator Iter = Stack.back().first.rbegin(); 1224 Iter != ParentIterTarget; std::advance(Iter, 1)) { 1225 if (isOpenMPLocal(VD, Iter)) { 1226 DVar.RefExpr = 1227 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1228 D->getLocation()); 1229 DVar.CKind = OMPC_threadprivate; 1230 return DVar; 1231 } 1232 } 1233 if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) { 1234 auto DSAIter = IterTarget->SharingMap.find(D); 1235 if (DSAIter != IterTarget->SharingMap.end() && 1236 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1237 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1238 DVar.CKind = OMPC_threadprivate; 1239 return DVar; 1240 } 1241 iterator End = Stack.back().first.rend(); 1242 if (!SemaRef.isOpenMPCapturedByRef( 1243 D, std::distance(ParentIterTarget, End))) { 1244 DVar.RefExpr = 1245 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1246 IterTarget->ConstructLoc); 1247 DVar.CKind = OMPC_threadprivate; 1248 return DVar; 1249 } 1250 } 1251 } 1252 } 1253 1254 if (isStackEmpty()) 1255 // Not in OpenMP execution region and top scope was already checked. 1256 return DVar; 1257 1258 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1259 // in a Construct, C/C++, predetermined, p.4] 1260 // Static data members are shared. 1261 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1262 // in a Construct, C/C++, predetermined, p.7] 1263 // Variables with static storage duration that are declared in a scope 1264 // inside the construct are shared. 1265 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1266 if (VD && VD->isStaticDataMember()) { 1267 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 1268 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1269 return DVar; 1270 1271 DVar.CKind = OMPC_shared; 1272 return DVar; 1273 } 1274 1275 // The predetermined shared attribute for const-qualified types having no 1276 // mutable members was removed after OpenMP 3.1. 1277 if (SemaRef.LangOpts.OpenMP <= 31) { 1278 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1279 // in a Construct, C/C++, predetermined, p.6] 1280 // Variables with const qualified type having no mutable member are 1281 // shared. 1282 if (isConstNotMutableType(SemaRef, D->getType())) { 1283 // Variables with const-qualified type having no mutable member may be 1284 // listed in a firstprivate clause, even if they are static data members. 1285 DSAVarData DVarTemp = hasInnermostDSA( 1286 D, 1287 [](OpenMPClauseKind C) { 1288 return C == OMPC_firstprivate || C == OMPC_shared; 1289 }, 1290 MatchesAlways, FromParent); 1291 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1292 return DVarTemp; 1293 1294 DVar.CKind = OMPC_shared; 1295 return DVar; 1296 } 1297 } 1298 1299 // Explicitly specified attributes and local variables with predetermined 1300 // attributes. 1301 iterator I = Stack.back().first.rbegin(); 1302 iterator EndI = Stack.back().first.rend(); 1303 if (FromParent && I != EndI) 1304 std::advance(I, 1); 1305 auto It = I->SharingMap.find(D); 1306 if (It != I->SharingMap.end()) { 1307 const DSAInfo &Data = It->getSecond(); 1308 DVar.RefExpr = Data.RefExpr.getPointer(); 1309 DVar.PrivateCopy = Data.PrivateCopy; 1310 DVar.CKind = Data.Attributes; 1311 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1312 DVar.DKind = I->Directive; 1313 } 1314 1315 return DVar; 1316 } 1317 1318 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1319 bool FromParent) const { 1320 if (isStackEmpty()) { 1321 iterator I; 1322 return getDSA(I, D); 1323 } 1324 D = getCanonicalDecl(D); 1325 iterator StartI = Stack.back().first.rbegin(); 1326 iterator EndI = Stack.back().first.rend(); 1327 if (FromParent && StartI != EndI) 1328 std::advance(StartI, 1); 1329 return getDSA(StartI, D); 1330 } 1331 1332 const DSAStackTy::DSAVarData 1333 DSAStackTy::hasDSA(ValueDecl *D, 1334 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1335 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1336 bool FromParent) const { 1337 if (isStackEmpty()) 1338 return {}; 1339 D = getCanonicalDecl(D); 1340 iterator I = Stack.back().first.rbegin(); 1341 iterator EndI = Stack.back().first.rend(); 1342 if (FromParent && I != EndI) 1343 std::advance(I, 1); 1344 for (; I != EndI; std::advance(I, 1)) { 1345 if (!DPred(I->Directive) && !isImplicitOrExplicitTaskingRegion(I->Directive)) 1346 continue; 1347 iterator NewI = I; 1348 DSAVarData DVar = getDSA(NewI, D); 1349 if (I == NewI && CPred(DVar.CKind)) 1350 return DVar; 1351 } 1352 return {}; 1353 } 1354 1355 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1356 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1357 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1358 bool FromParent) const { 1359 if (isStackEmpty()) 1360 return {}; 1361 D = getCanonicalDecl(D); 1362 iterator StartI = Stack.back().first.rbegin(); 1363 iterator EndI = Stack.back().first.rend(); 1364 if (FromParent && StartI != EndI) 1365 std::advance(StartI, 1); 1366 if (StartI == EndI || !DPred(StartI->Directive)) 1367 return {}; 1368 iterator NewI = StartI; 1369 DSAVarData DVar = getDSA(NewI, D); 1370 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1371 } 1372 1373 bool DSAStackTy::hasExplicitDSA( 1374 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1375 unsigned Level, bool NotLastprivate) const { 1376 if (isStackEmpty()) 1377 return false; 1378 D = getCanonicalDecl(D); 1379 auto StartI = Stack.back().first.begin(); 1380 auto EndI = Stack.back().first.end(); 1381 if (std::distance(StartI, EndI) <= (int)Level) 1382 return false; 1383 std::advance(StartI, Level); 1384 auto I = StartI->SharingMap.find(D); 1385 if ((I != StartI->SharingMap.end()) && 1386 I->getSecond().RefExpr.getPointer() && 1387 CPred(I->getSecond().Attributes) && 1388 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1389 return true; 1390 // Check predetermined rules for the loop control variables. 1391 auto LI = StartI->LCVMap.find(D); 1392 if (LI != StartI->LCVMap.end()) 1393 return CPred(OMPC_private); 1394 return false; 1395 } 1396 1397 bool DSAStackTy::hasExplicitDirective( 1398 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1399 unsigned Level) const { 1400 if (isStackEmpty()) 1401 return false; 1402 auto StartI = Stack.back().first.begin(); 1403 auto EndI = Stack.back().first.end(); 1404 if (std::distance(StartI, EndI) <= (int)Level) 1405 return false; 1406 std::advance(StartI, Level); 1407 return DPred(StartI->Directive); 1408 } 1409 1410 bool DSAStackTy::hasDirective( 1411 const llvm::function_ref<bool(OpenMPDirectiveKind, 1412 const DeclarationNameInfo &, SourceLocation)> 1413 DPred, 1414 bool FromParent) const { 1415 // We look only in the enclosing region. 1416 if (isStackEmpty()) 1417 return false; 1418 auto StartI = std::next(Stack.back().first.rbegin()); 1419 auto EndI = Stack.back().first.rend(); 1420 if (FromParent && StartI != EndI) 1421 StartI = std::next(StartI); 1422 for (auto I = StartI, EE = EndI; I != EE; ++I) { 1423 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1424 return true; 1425 } 1426 return false; 1427 } 1428 1429 void Sema::InitDataSharingAttributesStack() { 1430 VarDataSharingAttributesStack = new DSAStackTy(*this); 1431 } 1432 1433 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1434 1435 void Sema::pushOpenMPFunctionRegion() { 1436 DSAStack->pushFunction(); 1437 } 1438 1439 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1440 DSAStack->popFunction(OldFSI); 1441 } 1442 1443 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1444 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1445 "Expected OpenMP device compilation."); 1446 return !S.isInOpenMPTargetExecutionDirective() && 1447 !S.isInOpenMPDeclareTargetContext(); 1448 } 1449 1450 /// Do we know that we will eventually codegen the given function? 1451 static bool isKnownEmitted(Sema &S, FunctionDecl *FD) { 1452 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1453 "Expected OpenMP device compilation."); 1454 // Templates are emitted when they're instantiated. 1455 if (FD->isDependentContext()) 1456 return false; 1457 1458 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1459 FD->getCanonicalDecl())) 1460 return true; 1461 1462 // Otherwise, the function is known-emitted if it's in our set of 1463 // known-emitted functions. 1464 return S.DeviceKnownEmittedFns.count(FD) > 0; 1465 } 1466 1467 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1468 unsigned DiagID) { 1469 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1470 "Expected OpenMP device compilation."); 1471 return DeviceDiagBuilder((isOpenMPDeviceDelayedContext(*this) && 1472 !isKnownEmitted(*this, getCurFunctionDecl())) 1473 ? DeviceDiagBuilder::K_Deferred 1474 : DeviceDiagBuilder::K_Immediate, 1475 Loc, DiagID, getCurFunctionDecl(), *this); 1476 } 1477 1478 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) { 1479 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1480 "Expected OpenMP device compilation."); 1481 assert(Callee && "Callee may not be null."); 1482 FunctionDecl *Caller = getCurFunctionDecl(); 1483 1484 // If the caller is known-emitted, mark the callee as known-emitted. 1485 // Otherwise, mark the call in our call graph so we can traverse it later. 1486 if (!isOpenMPDeviceDelayedContext(*this) || 1487 (Caller && isKnownEmitted(*this, Caller))) 1488 markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted); 1489 else if (Caller) 1490 DeviceCallGraph[Caller].insert({Callee, Loc}); 1491 } 1492 1493 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1494 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1495 "OpenMP device compilation mode is expected."); 1496 QualType Ty = E->getType(); 1497 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1498 (Ty->isFloat128Type() && !Context.getTargetInfo().hasFloat128Type()) || 1499 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1500 !Context.getTargetInfo().hasInt128Type())) 1501 targetDiag(E->getExprLoc(), diag::err_type_unsupported) 1502 << Ty << E->getSourceRange(); 1503 } 1504 1505 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1506 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1507 1508 ASTContext &Ctx = getASTContext(); 1509 bool IsByRef = true; 1510 1511 // Find the directive that is associated with the provided scope. 1512 D = cast<ValueDecl>(D->getCanonicalDecl()); 1513 QualType Ty = D->getType(); 1514 1515 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1516 // This table summarizes how a given variable should be passed to the device 1517 // given its type and the clauses where it appears. This table is based on 1518 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1519 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1520 // 1521 // ========================================================================= 1522 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1523 // | |(tofrom:scalar)| | pvt | | | | 1524 // ========================================================================= 1525 // | scl | | | | - | | bycopy| 1526 // | scl | | - | x | - | - | bycopy| 1527 // | scl | | x | - | - | - | null | 1528 // | scl | x | | | - | | byref | 1529 // | scl | x | - | x | - | - | bycopy| 1530 // | scl | x | x | - | - | - | null | 1531 // | scl | | - | - | - | x | byref | 1532 // | scl | x | - | - | - | x | byref | 1533 // 1534 // | agg | n.a. | | | - | | byref | 1535 // | agg | n.a. | - | x | - | - | byref | 1536 // | agg | n.a. | x | - | - | - | null | 1537 // | agg | n.a. | - | - | - | x | byref | 1538 // | agg | n.a. | - | - | - | x[] | byref | 1539 // 1540 // | ptr | n.a. | | | - | | bycopy| 1541 // | ptr | n.a. | - | x | - | - | bycopy| 1542 // | ptr | n.a. | x | - | - | - | null | 1543 // | ptr | n.a. | - | - | - | x | byref | 1544 // | ptr | n.a. | - | - | - | x[] | bycopy| 1545 // | ptr | n.a. | - | - | x | | bycopy| 1546 // | ptr | n.a. | - | - | x | x | bycopy| 1547 // | ptr | n.a. | - | - | x | x[] | bycopy| 1548 // ========================================================================= 1549 // Legend: 1550 // scl - scalar 1551 // ptr - pointer 1552 // agg - aggregate 1553 // x - applies 1554 // - - invalid in this combination 1555 // [] - mapped with an array section 1556 // byref - should be mapped by reference 1557 // byval - should be mapped by value 1558 // null - initialize a local variable to null on the device 1559 // 1560 // Observations: 1561 // - All scalar declarations that show up in a map clause have to be passed 1562 // by reference, because they may have been mapped in the enclosing data 1563 // environment. 1564 // - If the scalar value does not fit the size of uintptr, it has to be 1565 // passed by reference, regardless the result in the table above. 1566 // - For pointers mapped by value that have either an implicit map or an 1567 // array section, the runtime library may pass the NULL value to the 1568 // device instead of the value passed to it by the compiler. 1569 1570 if (Ty->isReferenceType()) 1571 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1572 1573 // Locate map clauses and see if the variable being captured is referred to 1574 // in any of those clauses. Here we only care about variables, not fields, 1575 // because fields are part of aggregates. 1576 bool IsVariableUsedInMapClause = false; 1577 bool IsVariableAssociatedWithSection = false; 1578 1579 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1580 D, Level, 1581 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1582 OMPClauseMappableExprCommon::MappableExprComponentListRef 1583 MapExprComponents, 1584 OpenMPClauseKind WhereFoundClauseKind) { 1585 // Only the map clause information influences how a variable is 1586 // captured. E.g. is_device_ptr does not require changing the default 1587 // behavior. 1588 if (WhereFoundClauseKind != OMPC_map) 1589 return false; 1590 1591 auto EI = MapExprComponents.rbegin(); 1592 auto EE = MapExprComponents.rend(); 1593 1594 assert(EI != EE && "Invalid map expression!"); 1595 1596 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1597 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1598 1599 ++EI; 1600 if (EI == EE) 1601 return false; 1602 1603 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1604 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1605 isa<MemberExpr>(EI->getAssociatedExpression())) { 1606 IsVariableAssociatedWithSection = true; 1607 // There is nothing more we need to know about this variable. 1608 return true; 1609 } 1610 1611 // Keep looking for more map info. 1612 return false; 1613 }); 1614 1615 if (IsVariableUsedInMapClause) { 1616 // If variable is identified in a map clause it is always captured by 1617 // reference except if it is a pointer that is dereferenced somehow. 1618 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1619 } else { 1620 // By default, all the data that has a scalar type is mapped by copy 1621 // (except for reduction variables). 1622 IsByRef = 1623 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1624 !Ty->isAnyPointerType()) || 1625 !Ty->isScalarType() || 1626 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1627 DSAStack->hasExplicitDSA( 1628 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1629 } 1630 } 1631 1632 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1633 IsByRef = 1634 ((DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1635 !Ty->isAnyPointerType()) || 1636 !DSAStack->hasExplicitDSA( 1637 D, 1638 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1639 Level, /*NotLastprivate=*/true)) && 1640 // If the variable is artificial and must be captured by value - try to 1641 // capture by value. 1642 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1643 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1644 } 1645 1646 // When passing data by copy, we need to make sure it fits the uintptr size 1647 // and alignment, because the runtime library only deals with uintptr types. 1648 // If it does not fit the uintptr size, we need to pass the data by reference 1649 // instead. 1650 if (!IsByRef && 1651 (Ctx.getTypeSizeInChars(Ty) > 1652 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1653 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1654 IsByRef = true; 1655 } 1656 1657 return IsByRef; 1658 } 1659 1660 unsigned Sema::getOpenMPNestingLevel() const { 1661 assert(getLangOpts().OpenMP); 1662 return DSAStack->getNestingLevel(); 1663 } 1664 1665 bool Sema::isInOpenMPTargetExecutionDirective() const { 1666 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1667 !DSAStack->isClauseParsingMode()) || 1668 DSAStack->hasDirective( 1669 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1670 SourceLocation) -> bool { 1671 return isOpenMPTargetExecutionDirective(K); 1672 }, 1673 false); 1674 } 1675 1676 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) { 1677 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1678 D = getCanonicalDecl(D); 1679 1680 // If we are attempting to capture a global variable in a directive with 1681 // 'target' we return true so that this global is also mapped to the device. 1682 // 1683 auto *VD = dyn_cast<VarDecl>(D); 1684 if (VD && !VD->hasLocalStorage()) { 1685 if (isInOpenMPDeclareTargetContext() && 1686 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1687 // Try to mark variable as declare target if it is used in capturing 1688 // regions. 1689 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1690 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1691 return nullptr; 1692 } else if (isInOpenMPTargetExecutionDirective()) { 1693 // If the declaration is enclosed in a 'declare target' directive, 1694 // then it should not be captured. 1695 // 1696 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1697 return nullptr; 1698 return VD; 1699 } 1700 } 1701 // Capture variables captured by reference in lambdas for target-based 1702 // directives. 1703 if (VD && !DSAStack->isClauseParsingMode()) { 1704 if (const auto *RD = VD->getType() 1705 .getCanonicalType() 1706 .getNonReferenceType() 1707 ->getAsCXXRecordDecl()) { 1708 bool SavedForceCaptureByReferenceInTargetExecutable = 1709 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 1710 DSAStack->setForceCaptureByReferenceInTargetExecutable(/*V=*/true); 1711 if (RD->isLambda()) { 1712 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 1713 FieldDecl *ThisCapture; 1714 RD->getCaptureFields(Captures, ThisCapture); 1715 for (const LambdaCapture &LC : RD->captures()) { 1716 if (LC.getCaptureKind() == LCK_ByRef) { 1717 VarDecl *VD = LC.getCapturedVar(); 1718 DeclContext *VDC = VD->getDeclContext(); 1719 if (!VDC->Encloses(CurContext)) 1720 continue; 1721 DSAStackTy::DSAVarData DVarPrivate = 1722 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1723 // Do not capture already captured variables. 1724 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) && 1725 DVarPrivate.CKind == OMPC_unknown && 1726 !DSAStack->checkMappableExprComponentListsForDecl( 1727 D, /*CurrentRegionOnly=*/true, 1728 [](OMPClauseMappableExprCommon:: 1729 MappableExprComponentListRef, 1730 OpenMPClauseKind) { return true; })) 1731 MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar()); 1732 } else if (LC.getCaptureKind() == LCK_This) { 1733 QualType ThisTy = getCurrentThisType(); 1734 if (!ThisTy.isNull() && 1735 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 1736 CheckCXXThisCapture(LC.getLocation()); 1737 } 1738 } 1739 } 1740 DSAStack->setForceCaptureByReferenceInTargetExecutable( 1741 SavedForceCaptureByReferenceInTargetExecutable); 1742 } 1743 } 1744 1745 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1746 (!DSAStack->isClauseParsingMode() || 1747 DSAStack->getParentDirective() != OMPD_unknown)) { 1748 auto &&Info = DSAStack->isLoopControlVariable(D); 1749 if (Info.first || 1750 (VD && VD->hasLocalStorage() && 1751 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1752 (VD && DSAStack->isForceVarCapturing())) 1753 return VD ? VD : Info.second; 1754 DSAStackTy::DSAVarData DVarPrivate = 1755 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1756 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1757 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1758 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1759 [](OpenMPDirectiveKind) { return true; }, 1760 DSAStack->isClauseParsingMode()); 1761 if (DVarPrivate.CKind != OMPC_unknown) 1762 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1763 } 1764 return nullptr; 1765 } 1766 1767 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1768 unsigned Level) const { 1769 SmallVector<OpenMPDirectiveKind, 4> Regions; 1770 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1771 FunctionScopesIndex -= Regions.size(); 1772 } 1773 1774 void Sema::startOpenMPLoop() { 1775 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1776 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1777 DSAStack->loopInit(); 1778 } 1779 1780 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1781 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1782 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1783 if (DSAStack->getAssociatedLoops() > 0 && 1784 !DSAStack->isLoopStarted()) { 1785 DSAStack->resetPossibleLoopCounter(D); 1786 DSAStack->loopStart(); 1787 return true; 1788 } 1789 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 1790 DSAStack->isLoopControlVariable(D).first) && 1791 !DSAStack->hasExplicitDSA( 1792 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 1793 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 1794 return true; 1795 } 1796 return DSAStack->hasExplicitDSA( 1797 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1798 (DSAStack->isClauseParsingMode() && 1799 DSAStack->getClauseParsingMode() == OMPC_private) || 1800 // Consider taskgroup reduction descriptor variable a private to avoid 1801 // possible capture in the region. 1802 (DSAStack->hasExplicitDirective( 1803 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1804 Level) && 1805 DSAStack->isTaskgroupReductionRef(D, Level)); 1806 } 1807 1808 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1809 unsigned Level) { 1810 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1811 D = getCanonicalDecl(D); 1812 OpenMPClauseKind OMPC = OMPC_unknown; 1813 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1814 const unsigned NewLevel = I - 1; 1815 if (DSAStack->hasExplicitDSA(D, 1816 [&OMPC](const OpenMPClauseKind K) { 1817 if (isOpenMPPrivate(K)) { 1818 OMPC = K; 1819 return true; 1820 } 1821 return false; 1822 }, 1823 NewLevel)) 1824 break; 1825 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1826 D, NewLevel, 1827 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1828 OpenMPClauseKind) { return true; })) { 1829 OMPC = OMPC_map; 1830 break; 1831 } 1832 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1833 NewLevel)) { 1834 OMPC = OMPC_map; 1835 if (D->getType()->isScalarType() && 1836 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1837 DefaultMapAttributes::DMA_tofrom_scalar) 1838 OMPC = OMPC_firstprivate; 1839 break; 1840 } 1841 } 1842 if (OMPC != OMPC_unknown) 1843 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1844 } 1845 1846 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1847 unsigned Level) const { 1848 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1849 // Return true if the current level is no longer enclosed in a target region. 1850 1851 const auto *VD = dyn_cast<VarDecl>(D); 1852 return VD && !VD->hasLocalStorage() && 1853 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1854 Level); 1855 } 1856 1857 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1858 1859 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1860 const DeclarationNameInfo &DirName, 1861 Scope *CurScope, SourceLocation Loc) { 1862 DSAStack->push(DKind, DirName, CurScope, Loc); 1863 PushExpressionEvaluationContext( 1864 ExpressionEvaluationContext::PotentiallyEvaluated); 1865 } 1866 1867 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1868 DSAStack->setClauseParsingMode(K); 1869 } 1870 1871 void Sema::EndOpenMPClause() { 1872 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1873 } 1874 1875 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1876 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1877 // A variable of class type (or array thereof) that appears in a lastprivate 1878 // clause requires an accessible, unambiguous default constructor for the 1879 // class type, unless the list item is also specified in a firstprivate 1880 // clause. 1881 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1882 for (OMPClause *C : D->clauses()) { 1883 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1884 SmallVector<Expr *, 8> PrivateCopies; 1885 for (Expr *DE : Clause->varlists()) { 1886 if (DE->isValueDependent() || DE->isTypeDependent()) { 1887 PrivateCopies.push_back(nullptr); 1888 continue; 1889 } 1890 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1891 auto *VD = cast<VarDecl>(DRE->getDecl()); 1892 QualType Type = VD->getType().getNonReferenceType(); 1893 const DSAStackTy::DSAVarData DVar = 1894 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1895 if (DVar.CKind == OMPC_lastprivate) { 1896 // Generate helper private variable and initialize it with the 1897 // default value. The address of the original variable is replaced 1898 // by the address of the new private variable in CodeGen. This new 1899 // variable is not added to IdResolver, so the code in the OpenMP 1900 // region uses original variable for proper diagnostics. 1901 VarDecl *VDPrivate = buildVarDecl( 1902 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1903 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 1904 ActOnUninitializedDecl(VDPrivate); 1905 if (VDPrivate->isInvalidDecl()) 1906 continue; 1907 PrivateCopies.push_back(buildDeclRefExpr( 1908 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1909 } else { 1910 // The variable is also a firstprivate, so initialization sequence 1911 // for private copy is generated already. 1912 PrivateCopies.push_back(nullptr); 1913 } 1914 } 1915 // Set initializers to private copies if no errors were found. 1916 if (PrivateCopies.size() == Clause->varlist_size()) 1917 Clause->setPrivateCopies(PrivateCopies); 1918 } 1919 } 1920 } 1921 1922 DSAStack->pop(); 1923 DiscardCleanupsInEvaluationContext(); 1924 PopExpressionEvaluationContext(); 1925 } 1926 1927 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1928 Expr *NumIterations, Sema &SemaRef, 1929 Scope *S, DSAStackTy *Stack); 1930 1931 namespace { 1932 1933 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 1934 private: 1935 Sema &SemaRef; 1936 1937 public: 1938 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1939 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1940 NamedDecl *ND = Candidate.getCorrectionDecl(); 1941 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 1942 return VD->hasGlobalStorage() && 1943 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1944 SemaRef.getCurScope()); 1945 } 1946 return false; 1947 } 1948 }; 1949 1950 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 1951 private: 1952 Sema &SemaRef; 1953 1954 public: 1955 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 1956 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1957 NamedDecl *ND = Candidate.getCorrectionDecl(); 1958 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 1959 isa<FunctionDecl>(ND))) { 1960 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1961 SemaRef.getCurScope()); 1962 } 1963 return false; 1964 } 1965 }; 1966 1967 } // namespace 1968 1969 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 1970 CXXScopeSpec &ScopeSpec, 1971 const DeclarationNameInfo &Id, 1972 OpenMPDirectiveKind Kind) { 1973 LookupResult Lookup(*this, Id, LookupOrdinaryName); 1974 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 1975 1976 if (Lookup.isAmbiguous()) 1977 return ExprError(); 1978 1979 VarDecl *VD; 1980 if (!Lookup.isSingleResult()) { 1981 if (TypoCorrection Corrected = CorrectTypo( 1982 Id, LookupOrdinaryName, CurScope, nullptr, 1983 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 1984 diagnoseTypo(Corrected, 1985 PDiag(Lookup.empty() 1986 ? diag::err_undeclared_var_use_suggest 1987 : diag::err_omp_expected_var_arg_suggest) 1988 << Id.getName()); 1989 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 1990 } else { 1991 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 1992 : diag::err_omp_expected_var_arg) 1993 << Id.getName(); 1994 return ExprError(); 1995 } 1996 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 1997 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 1998 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 1999 return ExprError(); 2000 } 2001 Lookup.suppressDiagnostics(); 2002 2003 // OpenMP [2.9.2, Syntax, C/C++] 2004 // Variables must be file-scope, namespace-scope, or static block-scope. 2005 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2006 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2007 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2008 bool IsDecl = 2009 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2010 Diag(VD->getLocation(), 2011 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2012 << VD; 2013 return ExprError(); 2014 } 2015 2016 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2017 NamedDecl *ND = CanonicalVD; 2018 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2019 // A threadprivate directive for file-scope variables must appear outside 2020 // any definition or declaration. 2021 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2022 !getCurLexicalContext()->isTranslationUnit()) { 2023 Diag(Id.getLoc(), diag::err_omp_var_scope) 2024 << getOpenMPDirectiveName(Kind) << VD; 2025 bool IsDecl = 2026 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2027 Diag(VD->getLocation(), 2028 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2029 << VD; 2030 return ExprError(); 2031 } 2032 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2033 // A threadprivate directive for static class member variables must appear 2034 // in the class definition, in the same scope in which the member 2035 // variables are declared. 2036 if (CanonicalVD->isStaticDataMember() && 2037 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2038 Diag(Id.getLoc(), diag::err_omp_var_scope) 2039 << getOpenMPDirectiveName(Kind) << VD; 2040 bool IsDecl = 2041 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2042 Diag(VD->getLocation(), 2043 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2044 << VD; 2045 return ExprError(); 2046 } 2047 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2048 // A threadprivate directive for namespace-scope variables must appear 2049 // outside any definition or declaration other than the namespace 2050 // definition itself. 2051 if (CanonicalVD->getDeclContext()->isNamespace() && 2052 (!getCurLexicalContext()->isFileContext() || 2053 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2054 Diag(Id.getLoc(), diag::err_omp_var_scope) 2055 << getOpenMPDirectiveName(Kind) << VD; 2056 bool IsDecl = 2057 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2058 Diag(VD->getLocation(), 2059 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2060 << VD; 2061 return ExprError(); 2062 } 2063 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2064 // A threadprivate directive for static block-scope variables must appear 2065 // in the scope of the variable and not in a nested scope. 2066 if (CanonicalVD->isLocalVarDecl() && CurScope && 2067 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2068 Diag(Id.getLoc(), diag::err_omp_var_scope) 2069 << getOpenMPDirectiveName(Kind) << VD; 2070 bool IsDecl = 2071 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2072 Diag(VD->getLocation(), 2073 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2074 << VD; 2075 return ExprError(); 2076 } 2077 2078 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2079 // A threadprivate directive must lexically precede all references to any 2080 // of the variables in its list. 2081 if (Kind == OMPD_threadprivate && VD->isUsed() && 2082 !DSAStack->isThreadPrivate(VD)) { 2083 Diag(Id.getLoc(), diag::err_omp_var_used) 2084 << getOpenMPDirectiveName(Kind) << VD; 2085 return ExprError(); 2086 } 2087 2088 QualType ExprType = VD->getType().getNonReferenceType(); 2089 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2090 SourceLocation(), VD, 2091 /*RefersToEnclosingVariableOrCapture=*/false, 2092 Id.getLoc(), ExprType, VK_LValue); 2093 } 2094 2095 Sema::DeclGroupPtrTy 2096 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2097 ArrayRef<Expr *> VarList) { 2098 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2099 CurContext->addDecl(D); 2100 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2101 } 2102 return nullptr; 2103 } 2104 2105 namespace { 2106 class LocalVarRefChecker final 2107 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2108 Sema &SemaRef; 2109 2110 public: 2111 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2112 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2113 if (VD->hasLocalStorage()) { 2114 SemaRef.Diag(E->getBeginLoc(), 2115 diag::err_omp_local_var_in_threadprivate_init) 2116 << E->getSourceRange(); 2117 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2118 << VD << VD->getSourceRange(); 2119 return true; 2120 } 2121 } 2122 return false; 2123 } 2124 bool VisitStmt(const Stmt *S) { 2125 for (const Stmt *Child : S->children()) { 2126 if (Child && Visit(Child)) 2127 return true; 2128 } 2129 return false; 2130 } 2131 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2132 }; 2133 } // namespace 2134 2135 OMPThreadPrivateDecl * 2136 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2137 SmallVector<Expr *, 8> Vars; 2138 for (Expr *RefExpr : VarList) { 2139 auto *DE = cast<DeclRefExpr>(RefExpr); 2140 auto *VD = cast<VarDecl>(DE->getDecl()); 2141 SourceLocation ILoc = DE->getExprLoc(); 2142 2143 // Mark variable as used. 2144 VD->setReferenced(); 2145 VD->markUsed(Context); 2146 2147 QualType QType = VD->getType(); 2148 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2149 // It will be analyzed later. 2150 Vars.push_back(DE); 2151 continue; 2152 } 2153 2154 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2155 // A threadprivate variable must not have an incomplete type. 2156 if (RequireCompleteType(ILoc, VD->getType(), 2157 diag::err_omp_threadprivate_incomplete_type)) { 2158 continue; 2159 } 2160 2161 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2162 // A threadprivate variable must not have a reference type. 2163 if (VD->getType()->isReferenceType()) { 2164 Diag(ILoc, diag::err_omp_ref_type_arg) 2165 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2166 bool IsDecl = 2167 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2168 Diag(VD->getLocation(), 2169 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2170 << VD; 2171 continue; 2172 } 2173 2174 // Check if this is a TLS variable. If TLS is not being supported, produce 2175 // the corresponding diagnostic. 2176 if ((VD->getTLSKind() != VarDecl::TLS_None && 2177 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2178 getLangOpts().OpenMPUseTLS && 2179 getASTContext().getTargetInfo().isTLSSupported())) || 2180 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2181 !VD->isLocalVarDecl())) { 2182 Diag(ILoc, diag::err_omp_var_thread_local) 2183 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2184 bool IsDecl = 2185 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2186 Diag(VD->getLocation(), 2187 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2188 << VD; 2189 continue; 2190 } 2191 2192 // Check if initial value of threadprivate variable reference variable with 2193 // local storage (it is not supported by runtime). 2194 if (const Expr *Init = VD->getAnyInitializer()) { 2195 LocalVarRefChecker Checker(*this); 2196 if (Checker.Visit(Init)) 2197 continue; 2198 } 2199 2200 Vars.push_back(RefExpr); 2201 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2202 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2203 Context, SourceRange(Loc, Loc))); 2204 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2205 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2206 } 2207 OMPThreadPrivateDecl *D = nullptr; 2208 if (!Vars.empty()) { 2209 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2210 Vars); 2211 D->setAccess(AS_public); 2212 } 2213 return D; 2214 } 2215 2216 static OMPAllocateDeclAttr::AllocatorTypeTy 2217 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2218 if (!Allocator) 2219 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2220 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2221 Allocator->isInstantiationDependent() || 2222 Allocator->containsUnexpandedParameterPack()) 2223 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2224 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2225 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2226 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2227 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2228 Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2229 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2230 llvm::FoldingSetNodeID AEId, DAEId; 2231 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2232 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2233 if (AEId == DAEId) { 2234 AllocatorKindRes = AllocatorKind; 2235 break; 2236 } 2237 } 2238 return AllocatorKindRes; 2239 } 2240 2241 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2242 SourceLocation Loc, ArrayRef<Expr *> VarList, 2243 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2244 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2245 Expr *Allocator = nullptr; 2246 if (!Clauses.empty()) 2247 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2248 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2249 getAllocatorKind(*this, DSAStack, Allocator); 2250 SmallVector<Expr *, 8> Vars; 2251 for (Expr *RefExpr : VarList) { 2252 auto *DE = cast<DeclRefExpr>(RefExpr); 2253 auto *VD = cast<VarDecl>(DE->getDecl()); 2254 2255 // Check if this is a TLS variable or global register. 2256 if (VD->getTLSKind() != VarDecl::TLS_None || 2257 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2258 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2259 !VD->isLocalVarDecl())) 2260 continue; 2261 // Do not apply for parameters. 2262 if (isa<ParmVarDecl>(VD)) 2263 continue; 2264 2265 // If the used several times in the allocate directive, the same allocator 2266 // must be used. 2267 if (VD->hasAttr<OMPAllocateDeclAttr>()) { 2268 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2269 Expr *PrevAllocator = A->getAllocator(); 2270 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2271 getAllocatorKind(*this, DSAStack, PrevAllocator); 2272 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2273 if (AllocatorsMatch && Allocator && PrevAllocator) { 2274 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2275 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2276 llvm::FoldingSetNodeID AEId, PAEId; 2277 AE->Profile(AEId, Context, /*Canonical=*/true); 2278 PAE->Profile(PAEId, Context, /*Canonical=*/true); 2279 AllocatorsMatch = AEId == PAEId; 2280 } 2281 if (!AllocatorsMatch) { 2282 SmallString<256> AllocatorBuffer; 2283 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2284 if (Allocator) 2285 Allocator->printPretty(AllocatorStream, nullptr, getPrintingPolicy()); 2286 SmallString<256> PrevAllocatorBuffer; 2287 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2288 if (PrevAllocator) 2289 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2290 getPrintingPolicy()); 2291 2292 SourceLocation AllocatorLoc = 2293 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2294 SourceRange AllocatorRange = 2295 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2296 SourceLocation PrevAllocatorLoc = 2297 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2298 SourceRange PrevAllocatorRange = 2299 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2300 Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2301 << (Allocator ? 1 : 0) << AllocatorStream.str() 2302 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2303 << AllocatorRange; 2304 Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2305 << PrevAllocatorRange; 2306 continue; 2307 } 2308 } 2309 2310 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2311 // If a list item has a static storage type, the allocator expression in the 2312 // allocator clause must be a constant expression that evaluates to one of 2313 // the predefined memory allocator values. 2314 if (Allocator && VD->hasGlobalStorage()) { 2315 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2316 Diag(Allocator->getExprLoc(), 2317 diag::err_omp_expected_predefined_allocator) 2318 << Allocator->getSourceRange(); 2319 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2320 VarDecl::DeclarationOnly; 2321 Diag(VD->getLocation(), 2322 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2323 << VD; 2324 continue; 2325 } 2326 } 2327 2328 Vars.push_back(RefExpr); 2329 if ((!Allocator || (Allocator && !Allocator->isTypeDependent() && 2330 !Allocator->isValueDependent() && 2331 !Allocator->isInstantiationDependent() && 2332 !Allocator->containsUnexpandedParameterPack())) && 2333 !VD->hasAttr<OMPAllocateDeclAttr>()) { 2334 Attr *A = OMPAllocateDeclAttr::CreateImplicit( 2335 Context, AllocatorKind, Allocator, DE->getSourceRange()); 2336 VD->addAttr(A); 2337 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2338 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2339 } 2340 } 2341 if (Vars.empty()) 2342 return nullptr; 2343 if (!Owner) 2344 Owner = getCurLexicalContext(); 2345 OMPAllocateDecl *D = 2346 OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2347 D->setAccess(AS_public); 2348 Owner->addDecl(D); 2349 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2350 } 2351 2352 Sema::DeclGroupPtrTy 2353 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2354 ArrayRef<OMPClause *> ClauseList) { 2355 OMPRequiresDecl *D = nullptr; 2356 if (!CurContext->isFileContext()) { 2357 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2358 } else { 2359 D = CheckOMPRequiresDecl(Loc, ClauseList); 2360 if (D) { 2361 CurContext->addDecl(D); 2362 DSAStack->addRequiresDecl(D); 2363 } 2364 } 2365 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2366 } 2367 2368 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2369 ArrayRef<OMPClause *> ClauseList) { 2370 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2371 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2372 ClauseList); 2373 return nullptr; 2374 } 2375 2376 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2377 const ValueDecl *D, 2378 const DSAStackTy::DSAVarData &DVar, 2379 bool IsLoopIterVar = false) { 2380 if (DVar.RefExpr) { 2381 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2382 << getOpenMPClauseName(DVar.CKind); 2383 return; 2384 } 2385 enum { 2386 PDSA_StaticMemberShared, 2387 PDSA_StaticLocalVarShared, 2388 PDSA_LoopIterVarPrivate, 2389 PDSA_LoopIterVarLinear, 2390 PDSA_LoopIterVarLastprivate, 2391 PDSA_ConstVarShared, 2392 PDSA_GlobalVarShared, 2393 PDSA_TaskVarFirstprivate, 2394 PDSA_LocalVarPrivate, 2395 PDSA_Implicit 2396 } Reason = PDSA_Implicit; 2397 bool ReportHint = false; 2398 auto ReportLoc = D->getLocation(); 2399 auto *VD = dyn_cast<VarDecl>(D); 2400 if (IsLoopIterVar) { 2401 if (DVar.CKind == OMPC_private) 2402 Reason = PDSA_LoopIterVarPrivate; 2403 else if (DVar.CKind == OMPC_lastprivate) 2404 Reason = PDSA_LoopIterVarLastprivate; 2405 else 2406 Reason = PDSA_LoopIterVarLinear; 2407 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2408 DVar.CKind == OMPC_firstprivate) { 2409 Reason = PDSA_TaskVarFirstprivate; 2410 ReportLoc = DVar.ImplicitDSALoc; 2411 } else if (VD && VD->isStaticLocal()) 2412 Reason = PDSA_StaticLocalVarShared; 2413 else if (VD && VD->isStaticDataMember()) 2414 Reason = PDSA_StaticMemberShared; 2415 else if (VD && VD->isFileVarDecl()) 2416 Reason = PDSA_GlobalVarShared; 2417 else if (D->getType().isConstant(SemaRef.getASTContext())) 2418 Reason = PDSA_ConstVarShared; 2419 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2420 ReportHint = true; 2421 Reason = PDSA_LocalVarPrivate; 2422 } 2423 if (Reason != PDSA_Implicit) { 2424 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2425 << Reason << ReportHint 2426 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2427 } else if (DVar.ImplicitDSALoc.isValid()) { 2428 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2429 << getOpenMPClauseName(DVar.CKind); 2430 } 2431 } 2432 2433 namespace { 2434 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2435 DSAStackTy *Stack; 2436 Sema &SemaRef; 2437 bool ErrorFound = false; 2438 CapturedStmt *CS = nullptr; 2439 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2440 llvm::SmallVector<Expr *, 4> ImplicitMap; 2441 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2442 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2443 2444 void VisitSubCaptures(OMPExecutableDirective *S) { 2445 // Check implicitly captured variables. 2446 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2447 return; 2448 for (const CapturedStmt::Capture &Cap : 2449 S->getInnermostCapturedStmt()->captures()) { 2450 if (!Cap.capturesVariable()) 2451 continue; 2452 VarDecl *VD = Cap.getCapturedVar(); 2453 // Do not try to map the variable if it or its sub-component was mapped 2454 // already. 2455 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2456 Stack->checkMappableExprComponentListsForDecl( 2457 VD, /*CurrentRegionOnly=*/true, 2458 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2459 OpenMPClauseKind) { return true; })) 2460 continue; 2461 DeclRefExpr *DRE = buildDeclRefExpr( 2462 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 2463 Cap.getLocation(), /*RefersToCapture=*/true); 2464 Visit(DRE); 2465 } 2466 } 2467 2468 public: 2469 void VisitDeclRefExpr(DeclRefExpr *E) { 2470 if (E->isTypeDependent() || E->isValueDependent() || 2471 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2472 return; 2473 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2474 VD = VD->getCanonicalDecl(); 2475 // Skip internally declared variables. 2476 if (VD->hasLocalStorage() && !CS->capturesVariable(VD)) 2477 return; 2478 2479 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2480 // Check if the variable has explicit DSA set and stop analysis if it so. 2481 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2482 return; 2483 2484 // Skip internally declared static variables. 2485 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2486 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2487 if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) && 2488 (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2489 return; 2490 2491 SourceLocation ELoc = E->getExprLoc(); 2492 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2493 // The default(none) clause requires that each variable that is referenced 2494 // in the construct, and does not have a predetermined data-sharing 2495 // attribute, must have its data-sharing attribute explicitly determined 2496 // by being listed in a data-sharing attribute clause. 2497 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2498 isImplicitOrExplicitTaskingRegion(DKind) && 2499 VarsWithInheritedDSA.count(VD) == 0) { 2500 VarsWithInheritedDSA[VD] = E; 2501 return; 2502 } 2503 2504 if (isOpenMPTargetExecutionDirective(DKind) && 2505 !Stack->isLoopControlVariable(VD).first) { 2506 if (!Stack->checkMappableExprComponentListsForDecl( 2507 VD, /*CurrentRegionOnly=*/true, 2508 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2509 StackComponents, 2510 OpenMPClauseKind) { 2511 // Variable is used if it has been marked as an array, array 2512 // section or the variable iself. 2513 return StackComponents.size() == 1 || 2514 std::all_of( 2515 std::next(StackComponents.rbegin()), 2516 StackComponents.rend(), 2517 [](const OMPClauseMappableExprCommon:: 2518 MappableComponent &MC) { 2519 return MC.getAssociatedDeclaration() == 2520 nullptr && 2521 (isa<OMPArraySectionExpr>( 2522 MC.getAssociatedExpression()) || 2523 isa<ArraySubscriptExpr>( 2524 MC.getAssociatedExpression())); 2525 }); 2526 })) { 2527 bool IsFirstprivate = false; 2528 // By default lambdas are captured as firstprivates. 2529 if (const auto *RD = 2530 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2531 IsFirstprivate = RD->isLambda(); 2532 IsFirstprivate = 2533 IsFirstprivate || 2534 (VD->getType().getNonReferenceType()->isScalarType() && 2535 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2536 if (IsFirstprivate) 2537 ImplicitFirstprivate.emplace_back(E); 2538 else 2539 ImplicitMap.emplace_back(E); 2540 return; 2541 } 2542 } 2543 2544 // OpenMP [2.9.3.6, Restrictions, p.2] 2545 // A list item that appears in a reduction clause of the innermost 2546 // enclosing worksharing or parallel construct may not be accessed in an 2547 // explicit task. 2548 DVar = Stack->hasInnermostDSA( 2549 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2550 [](OpenMPDirectiveKind K) { 2551 return isOpenMPParallelDirective(K) || 2552 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2553 }, 2554 /*FromParent=*/true); 2555 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2556 ErrorFound = true; 2557 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2558 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2559 return; 2560 } 2561 2562 // Define implicit data-sharing attributes for task. 2563 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2564 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2565 !Stack->isLoopControlVariable(VD).first) { 2566 ImplicitFirstprivate.push_back(E); 2567 return; 2568 } 2569 2570 // Store implicitly used globals with declare target link for parent 2571 // target. 2572 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2573 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2574 Stack->addToParentTargetRegionLinkGlobals(E); 2575 return; 2576 } 2577 } 2578 } 2579 void VisitMemberExpr(MemberExpr *E) { 2580 if (E->isTypeDependent() || E->isValueDependent() || 2581 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2582 return; 2583 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2584 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2585 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2586 if (!FD) 2587 return; 2588 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2589 // Check if the variable has explicit DSA set and stop analysis if it 2590 // so. 2591 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2592 return; 2593 2594 if (isOpenMPTargetExecutionDirective(DKind) && 2595 !Stack->isLoopControlVariable(FD).first && 2596 !Stack->checkMappableExprComponentListsForDecl( 2597 FD, /*CurrentRegionOnly=*/true, 2598 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2599 StackComponents, 2600 OpenMPClauseKind) { 2601 return isa<CXXThisExpr>( 2602 cast<MemberExpr>( 2603 StackComponents.back().getAssociatedExpression()) 2604 ->getBase() 2605 ->IgnoreParens()); 2606 })) { 2607 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2608 // A bit-field cannot appear in a map clause. 2609 // 2610 if (FD->isBitField()) 2611 return; 2612 2613 // Check to see if the member expression is referencing a class that 2614 // has already been explicitly mapped 2615 if (Stack->isClassPreviouslyMapped(TE->getType())) 2616 return; 2617 2618 ImplicitMap.emplace_back(E); 2619 return; 2620 } 2621 2622 SourceLocation ELoc = E->getExprLoc(); 2623 // OpenMP [2.9.3.6, Restrictions, p.2] 2624 // A list item that appears in a reduction clause of the innermost 2625 // enclosing worksharing or parallel construct may not be accessed in 2626 // an explicit task. 2627 DVar = Stack->hasInnermostDSA( 2628 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2629 [](OpenMPDirectiveKind K) { 2630 return isOpenMPParallelDirective(K) || 2631 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2632 }, 2633 /*FromParent=*/true); 2634 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2635 ErrorFound = true; 2636 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2637 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2638 return; 2639 } 2640 2641 // Define implicit data-sharing attributes for task. 2642 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2643 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2644 !Stack->isLoopControlVariable(FD).first) { 2645 // Check if there is a captured expression for the current field in the 2646 // region. Do not mark it as firstprivate unless there is no captured 2647 // expression. 2648 // TODO: try to make it firstprivate. 2649 if (DVar.CKind != OMPC_unknown) 2650 ImplicitFirstprivate.push_back(E); 2651 } 2652 return; 2653 } 2654 if (isOpenMPTargetExecutionDirective(DKind)) { 2655 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2656 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2657 /*NoDiagnose=*/true)) 2658 return; 2659 const auto *VD = cast<ValueDecl>( 2660 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2661 if (!Stack->checkMappableExprComponentListsForDecl( 2662 VD, /*CurrentRegionOnly=*/true, 2663 [&CurComponents]( 2664 OMPClauseMappableExprCommon::MappableExprComponentListRef 2665 StackComponents, 2666 OpenMPClauseKind) { 2667 auto CCI = CurComponents.rbegin(); 2668 auto CCE = CurComponents.rend(); 2669 for (const auto &SC : llvm::reverse(StackComponents)) { 2670 // Do both expressions have the same kind? 2671 if (CCI->getAssociatedExpression()->getStmtClass() != 2672 SC.getAssociatedExpression()->getStmtClass()) 2673 if (!(isa<OMPArraySectionExpr>( 2674 SC.getAssociatedExpression()) && 2675 isa<ArraySubscriptExpr>( 2676 CCI->getAssociatedExpression()))) 2677 return false; 2678 2679 const Decl *CCD = CCI->getAssociatedDeclaration(); 2680 const Decl *SCD = SC.getAssociatedDeclaration(); 2681 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2682 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2683 if (SCD != CCD) 2684 return false; 2685 std::advance(CCI, 1); 2686 if (CCI == CCE) 2687 break; 2688 } 2689 return true; 2690 })) { 2691 Visit(E->getBase()); 2692 } 2693 } else { 2694 Visit(E->getBase()); 2695 } 2696 } 2697 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2698 for (OMPClause *C : S->clauses()) { 2699 // Skip analysis of arguments of implicitly defined firstprivate clause 2700 // for task|target directives. 2701 // Skip analysis of arguments of implicitly defined map clause for target 2702 // directives. 2703 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2704 C->isImplicit())) { 2705 for (Stmt *CC : C->children()) { 2706 if (CC) 2707 Visit(CC); 2708 } 2709 } 2710 } 2711 // Check implicitly captured variables. 2712 VisitSubCaptures(S); 2713 } 2714 void VisitStmt(Stmt *S) { 2715 for (Stmt *C : S->children()) { 2716 if (C) { 2717 // Check implicitly captured variables in the task-based directives to 2718 // check if they must be firstprivatized. 2719 Visit(C); 2720 } 2721 } 2722 } 2723 2724 bool isErrorFound() const { return ErrorFound; } 2725 ArrayRef<Expr *> getImplicitFirstprivate() const { 2726 return ImplicitFirstprivate; 2727 } 2728 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2729 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2730 return VarsWithInheritedDSA; 2731 } 2732 2733 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2734 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 2735 // Process declare target link variables for the target directives. 2736 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 2737 for (DeclRefExpr *E : Stack->getLinkGlobals()) 2738 Visit(E); 2739 } 2740 } 2741 }; 2742 } // namespace 2743 2744 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2745 switch (DKind) { 2746 case OMPD_parallel: 2747 case OMPD_parallel_for: 2748 case OMPD_parallel_for_simd: 2749 case OMPD_parallel_sections: 2750 case OMPD_teams: 2751 case OMPD_teams_distribute: 2752 case OMPD_teams_distribute_simd: { 2753 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2754 QualType KmpInt32PtrTy = 2755 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2756 Sema::CapturedParamNameType Params[] = { 2757 std::make_pair(".global_tid.", KmpInt32PtrTy), 2758 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2759 std::make_pair(StringRef(), QualType()) // __context with shared vars 2760 }; 2761 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2762 Params); 2763 break; 2764 } 2765 case OMPD_target_teams: 2766 case OMPD_target_parallel: 2767 case OMPD_target_parallel_for: 2768 case OMPD_target_parallel_for_simd: 2769 case OMPD_target_teams_distribute: 2770 case OMPD_target_teams_distribute_simd: { 2771 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2772 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2773 QualType KmpInt32PtrTy = 2774 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2775 QualType Args[] = {VoidPtrTy}; 2776 FunctionProtoType::ExtProtoInfo EPI; 2777 EPI.Variadic = true; 2778 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2779 Sema::CapturedParamNameType Params[] = { 2780 std::make_pair(".global_tid.", KmpInt32Ty), 2781 std::make_pair(".part_id.", KmpInt32PtrTy), 2782 std::make_pair(".privates.", VoidPtrTy), 2783 std::make_pair( 2784 ".copy_fn.", 2785 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2786 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2787 std::make_pair(StringRef(), QualType()) // __context with shared vars 2788 }; 2789 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2790 Params); 2791 // Mark this captured region as inlined, because we don't use outlined 2792 // function directly. 2793 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2794 AlwaysInlineAttr::CreateImplicit( 2795 Context, AlwaysInlineAttr::Keyword_forceinline)); 2796 Sema::CapturedParamNameType ParamsTarget[] = { 2797 std::make_pair(StringRef(), QualType()) // __context with shared vars 2798 }; 2799 // Start a captured region for 'target' with no implicit parameters. 2800 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2801 ParamsTarget); 2802 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2803 std::make_pair(".global_tid.", KmpInt32PtrTy), 2804 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2805 std::make_pair(StringRef(), QualType()) // __context with shared vars 2806 }; 2807 // Start a captured region for 'teams' or 'parallel'. Both regions have 2808 // the same implicit parameters. 2809 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2810 ParamsTeamsOrParallel); 2811 break; 2812 } 2813 case OMPD_target: 2814 case OMPD_target_simd: { 2815 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2816 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2817 QualType KmpInt32PtrTy = 2818 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2819 QualType Args[] = {VoidPtrTy}; 2820 FunctionProtoType::ExtProtoInfo EPI; 2821 EPI.Variadic = true; 2822 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2823 Sema::CapturedParamNameType Params[] = { 2824 std::make_pair(".global_tid.", KmpInt32Ty), 2825 std::make_pair(".part_id.", KmpInt32PtrTy), 2826 std::make_pair(".privates.", VoidPtrTy), 2827 std::make_pair( 2828 ".copy_fn.", 2829 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2830 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2831 std::make_pair(StringRef(), QualType()) // __context with shared vars 2832 }; 2833 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2834 Params); 2835 // Mark this captured region as inlined, because we don't use outlined 2836 // function directly. 2837 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2838 AlwaysInlineAttr::CreateImplicit( 2839 Context, AlwaysInlineAttr::Keyword_forceinline)); 2840 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2841 std::make_pair(StringRef(), QualType())); 2842 break; 2843 } 2844 case OMPD_simd: 2845 case OMPD_for: 2846 case OMPD_for_simd: 2847 case OMPD_sections: 2848 case OMPD_section: 2849 case OMPD_single: 2850 case OMPD_master: 2851 case OMPD_critical: 2852 case OMPD_taskgroup: 2853 case OMPD_distribute: 2854 case OMPD_distribute_simd: 2855 case OMPD_ordered: 2856 case OMPD_atomic: 2857 case OMPD_target_data: { 2858 Sema::CapturedParamNameType Params[] = { 2859 std::make_pair(StringRef(), QualType()) // __context with shared vars 2860 }; 2861 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2862 Params); 2863 break; 2864 } 2865 case OMPD_task: { 2866 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2867 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2868 QualType KmpInt32PtrTy = 2869 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2870 QualType Args[] = {VoidPtrTy}; 2871 FunctionProtoType::ExtProtoInfo EPI; 2872 EPI.Variadic = true; 2873 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2874 Sema::CapturedParamNameType Params[] = { 2875 std::make_pair(".global_tid.", KmpInt32Ty), 2876 std::make_pair(".part_id.", KmpInt32PtrTy), 2877 std::make_pair(".privates.", VoidPtrTy), 2878 std::make_pair( 2879 ".copy_fn.", 2880 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2881 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2882 std::make_pair(StringRef(), QualType()) // __context with shared vars 2883 }; 2884 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2885 Params); 2886 // Mark this captured region as inlined, because we don't use outlined 2887 // function directly. 2888 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2889 AlwaysInlineAttr::CreateImplicit( 2890 Context, AlwaysInlineAttr::Keyword_forceinline)); 2891 break; 2892 } 2893 case OMPD_taskloop: 2894 case OMPD_taskloop_simd: { 2895 QualType KmpInt32Ty = 2896 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 2897 .withConst(); 2898 QualType KmpUInt64Ty = 2899 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 2900 .withConst(); 2901 QualType KmpInt64Ty = 2902 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 2903 .withConst(); 2904 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2905 QualType KmpInt32PtrTy = 2906 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2907 QualType Args[] = {VoidPtrTy}; 2908 FunctionProtoType::ExtProtoInfo EPI; 2909 EPI.Variadic = true; 2910 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2911 Sema::CapturedParamNameType Params[] = { 2912 std::make_pair(".global_tid.", KmpInt32Ty), 2913 std::make_pair(".part_id.", KmpInt32PtrTy), 2914 std::make_pair(".privates.", VoidPtrTy), 2915 std::make_pair( 2916 ".copy_fn.", 2917 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2918 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2919 std::make_pair(".lb.", KmpUInt64Ty), 2920 std::make_pair(".ub.", KmpUInt64Ty), 2921 std::make_pair(".st.", KmpInt64Ty), 2922 std::make_pair(".liter.", KmpInt32Ty), 2923 std::make_pair(".reductions.", VoidPtrTy), 2924 std::make_pair(StringRef(), QualType()) // __context with shared vars 2925 }; 2926 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2927 Params); 2928 // Mark this captured region as inlined, because we don't use outlined 2929 // function directly. 2930 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2931 AlwaysInlineAttr::CreateImplicit( 2932 Context, AlwaysInlineAttr::Keyword_forceinline)); 2933 break; 2934 } 2935 case OMPD_distribute_parallel_for_simd: 2936 case OMPD_distribute_parallel_for: { 2937 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2938 QualType KmpInt32PtrTy = 2939 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2940 Sema::CapturedParamNameType Params[] = { 2941 std::make_pair(".global_tid.", KmpInt32PtrTy), 2942 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2943 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2944 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2945 std::make_pair(StringRef(), QualType()) // __context with shared vars 2946 }; 2947 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2948 Params); 2949 break; 2950 } 2951 case OMPD_target_teams_distribute_parallel_for: 2952 case OMPD_target_teams_distribute_parallel_for_simd: { 2953 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2954 QualType KmpInt32PtrTy = 2955 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2956 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2957 2958 QualType Args[] = {VoidPtrTy}; 2959 FunctionProtoType::ExtProtoInfo EPI; 2960 EPI.Variadic = true; 2961 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2962 Sema::CapturedParamNameType Params[] = { 2963 std::make_pair(".global_tid.", KmpInt32Ty), 2964 std::make_pair(".part_id.", KmpInt32PtrTy), 2965 std::make_pair(".privates.", VoidPtrTy), 2966 std::make_pair( 2967 ".copy_fn.", 2968 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2969 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2970 std::make_pair(StringRef(), QualType()) // __context with shared vars 2971 }; 2972 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2973 Params); 2974 // Mark this captured region as inlined, because we don't use outlined 2975 // function directly. 2976 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2977 AlwaysInlineAttr::CreateImplicit( 2978 Context, AlwaysInlineAttr::Keyword_forceinline)); 2979 Sema::CapturedParamNameType ParamsTarget[] = { 2980 std::make_pair(StringRef(), QualType()) // __context with shared vars 2981 }; 2982 // Start a captured region for 'target' with no implicit parameters. 2983 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2984 ParamsTarget); 2985 2986 Sema::CapturedParamNameType ParamsTeams[] = { 2987 std::make_pair(".global_tid.", KmpInt32PtrTy), 2988 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2989 std::make_pair(StringRef(), QualType()) // __context with shared vars 2990 }; 2991 // Start a captured region for 'target' with no implicit parameters. 2992 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2993 ParamsTeams); 2994 2995 Sema::CapturedParamNameType ParamsParallel[] = { 2996 std::make_pair(".global_tid.", KmpInt32PtrTy), 2997 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2998 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2999 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3000 std::make_pair(StringRef(), QualType()) // __context with shared vars 3001 }; 3002 // Start a captured region for 'teams' or 'parallel'. Both regions have 3003 // the same implicit parameters. 3004 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3005 ParamsParallel); 3006 break; 3007 } 3008 3009 case OMPD_teams_distribute_parallel_for: 3010 case OMPD_teams_distribute_parallel_for_simd: { 3011 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3012 QualType KmpInt32PtrTy = 3013 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3014 3015 Sema::CapturedParamNameType ParamsTeams[] = { 3016 std::make_pair(".global_tid.", KmpInt32PtrTy), 3017 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3018 std::make_pair(StringRef(), QualType()) // __context with shared vars 3019 }; 3020 // Start a captured region for 'target' with no implicit parameters. 3021 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3022 ParamsTeams); 3023 3024 Sema::CapturedParamNameType ParamsParallel[] = { 3025 std::make_pair(".global_tid.", KmpInt32PtrTy), 3026 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3027 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3028 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3029 std::make_pair(StringRef(), QualType()) // __context with shared vars 3030 }; 3031 // Start a captured region for 'teams' or 'parallel'. Both regions have 3032 // the same implicit parameters. 3033 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3034 ParamsParallel); 3035 break; 3036 } 3037 case OMPD_target_update: 3038 case OMPD_target_enter_data: 3039 case OMPD_target_exit_data: { 3040 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3041 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3042 QualType KmpInt32PtrTy = 3043 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3044 QualType Args[] = {VoidPtrTy}; 3045 FunctionProtoType::ExtProtoInfo EPI; 3046 EPI.Variadic = true; 3047 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3048 Sema::CapturedParamNameType Params[] = { 3049 std::make_pair(".global_tid.", KmpInt32Ty), 3050 std::make_pair(".part_id.", KmpInt32PtrTy), 3051 std::make_pair(".privates.", VoidPtrTy), 3052 std::make_pair( 3053 ".copy_fn.", 3054 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3055 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3056 std::make_pair(StringRef(), QualType()) // __context with shared vars 3057 }; 3058 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3059 Params); 3060 // Mark this captured region as inlined, because we don't use outlined 3061 // function directly. 3062 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3063 AlwaysInlineAttr::CreateImplicit( 3064 Context, AlwaysInlineAttr::Keyword_forceinline)); 3065 break; 3066 } 3067 case OMPD_threadprivate: 3068 case OMPD_allocate: 3069 case OMPD_taskyield: 3070 case OMPD_barrier: 3071 case OMPD_taskwait: 3072 case OMPD_cancellation_point: 3073 case OMPD_cancel: 3074 case OMPD_flush: 3075 case OMPD_declare_reduction: 3076 case OMPD_declare_mapper: 3077 case OMPD_declare_simd: 3078 case OMPD_declare_target: 3079 case OMPD_end_declare_target: 3080 case OMPD_requires: 3081 llvm_unreachable("OpenMP Directive is not allowed"); 3082 case OMPD_unknown: 3083 llvm_unreachable("Unknown OpenMP directive"); 3084 } 3085 } 3086 3087 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3088 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3089 getOpenMPCaptureRegions(CaptureRegions, DKind); 3090 return CaptureRegions.size(); 3091 } 3092 3093 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3094 Expr *CaptureExpr, bool WithInit, 3095 bool AsExpression) { 3096 assert(CaptureExpr); 3097 ASTContext &C = S.getASTContext(); 3098 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3099 QualType Ty = Init->getType(); 3100 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3101 if (S.getLangOpts().CPlusPlus) { 3102 Ty = C.getLValueReferenceType(Ty); 3103 } else { 3104 Ty = C.getPointerType(Ty); 3105 ExprResult Res = 3106 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3107 if (!Res.isUsable()) 3108 return nullptr; 3109 Init = Res.get(); 3110 } 3111 WithInit = true; 3112 } 3113 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3114 CaptureExpr->getBeginLoc()); 3115 if (!WithInit) 3116 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3117 S.CurContext->addHiddenDecl(CED); 3118 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3119 return CED; 3120 } 3121 3122 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3123 bool WithInit) { 3124 OMPCapturedExprDecl *CD; 3125 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3126 CD = cast<OMPCapturedExprDecl>(VD); 3127 else 3128 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3129 /*AsExpression=*/false); 3130 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3131 CaptureExpr->getExprLoc()); 3132 } 3133 3134 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3135 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3136 if (!Ref) { 3137 OMPCapturedExprDecl *CD = buildCaptureDecl( 3138 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3139 /*WithInit=*/true, /*AsExpression=*/true); 3140 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3141 CaptureExpr->getExprLoc()); 3142 } 3143 ExprResult Res = Ref; 3144 if (!S.getLangOpts().CPlusPlus && 3145 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3146 Ref->getType()->isPointerType()) { 3147 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3148 if (!Res.isUsable()) 3149 return ExprError(); 3150 } 3151 return S.DefaultLvalueConversion(Res.get()); 3152 } 3153 3154 namespace { 3155 // OpenMP directives parsed in this section are represented as a 3156 // CapturedStatement with an associated statement. If a syntax error 3157 // is detected during the parsing of the associated statement, the 3158 // compiler must abort processing and close the CapturedStatement. 3159 // 3160 // Combined directives such as 'target parallel' have more than one 3161 // nested CapturedStatements. This RAII ensures that we unwind out 3162 // of all the nested CapturedStatements when an error is found. 3163 class CaptureRegionUnwinderRAII { 3164 private: 3165 Sema &S; 3166 bool &ErrorFound; 3167 OpenMPDirectiveKind DKind = OMPD_unknown; 3168 3169 public: 3170 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3171 OpenMPDirectiveKind DKind) 3172 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3173 ~CaptureRegionUnwinderRAII() { 3174 if (ErrorFound) { 3175 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3176 while (--ThisCaptureLevel >= 0) 3177 S.ActOnCapturedRegionError(); 3178 } 3179 } 3180 }; 3181 } // namespace 3182 3183 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3184 ArrayRef<OMPClause *> Clauses) { 3185 bool ErrorFound = false; 3186 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3187 *this, ErrorFound, DSAStack->getCurrentDirective()); 3188 if (!S.isUsable()) { 3189 ErrorFound = true; 3190 return StmtError(); 3191 } 3192 3193 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3194 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3195 OMPOrderedClause *OC = nullptr; 3196 OMPScheduleClause *SC = nullptr; 3197 SmallVector<const OMPLinearClause *, 4> LCs; 3198 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3199 // This is required for proper codegen. 3200 for (OMPClause *Clause : Clauses) { 3201 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3202 Clause->getClauseKind() == OMPC_in_reduction) { 3203 // Capture taskgroup task_reduction descriptors inside the tasking regions 3204 // with the corresponding in_reduction items. 3205 auto *IRC = cast<OMPInReductionClause>(Clause); 3206 for (Expr *E : IRC->taskgroup_descriptors()) 3207 if (E) 3208 MarkDeclarationsReferencedInExpr(E); 3209 } 3210 if (isOpenMPPrivate(Clause->getClauseKind()) || 3211 Clause->getClauseKind() == OMPC_copyprivate || 3212 (getLangOpts().OpenMPUseTLS && 3213 getASTContext().getTargetInfo().isTLSSupported() && 3214 Clause->getClauseKind() == OMPC_copyin)) { 3215 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3216 // Mark all variables in private list clauses as used in inner region. 3217 for (Stmt *VarRef : Clause->children()) { 3218 if (auto *E = cast_or_null<Expr>(VarRef)) { 3219 MarkDeclarationsReferencedInExpr(E); 3220 } 3221 } 3222 DSAStack->setForceVarCapturing(/*V=*/false); 3223 } else if (CaptureRegions.size() > 1 || 3224 CaptureRegions.back() != OMPD_unknown) { 3225 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3226 PICs.push_back(C); 3227 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3228 if (Expr *E = C->getPostUpdateExpr()) 3229 MarkDeclarationsReferencedInExpr(E); 3230 } 3231 } 3232 if (Clause->getClauseKind() == OMPC_schedule) 3233 SC = cast<OMPScheduleClause>(Clause); 3234 else if (Clause->getClauseKind() == OMPC_ordered) 3235 OC = cast<OMPOrderedClause>(Clause); 3236 else if (Clause->getClauseKind() == OMPC_linear) 3237 LCs.push_back(cast<OMPLinearClause>(Clause)); 3238 } 3239 // OpenMP, 2.7.1 Loop Construct, Restrictions 3240 // The nonmonotonic modifier cannot be specified if an ordered clause is 3241 // specified. 3242 if (SC && 3243 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3244 SC->getSecondScheduleModifier() == 3245 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3246 OC) { 3247 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3248 ? SC->getFirstScheduleModifierLoc() 3249 : SC->getSecondScheduleModifierLoc(), 3250 diag::err_omp_schedule_nonmonotonic_ordered) 3251 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3252 ErrorFound = true; 3253 } 3254 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3255 for (const OMPLinearClause *C : LCs) { 3256 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3257 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3258 } 3259 ErrorFound = true; 3260 } 3261 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3262 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3263 OC->getNumForLoops()) { 3264 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3265 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3266 ErrorFound = true; 3267 } 3268 if (ErrorFound) { 3269 return StmtError(); 3270 } 3271 StmtResult SR = S; 3272 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3273 // Mark all variables in private list clauses as used in inner region. 3274 // Required for proper codegen of combined directives. 3275 // TODO: add processing for other clauses. 3276 if (ThisCaptureRegion != OMPD_unknown) { 3277 for (const clang::OMPClauseWithPreInit *C : PICs) { 3278 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3279 // Find the particular capture region for the clause if the 3280 // directive is a combined one with multiple capture regions. 3281 // If the directive is not a combined one, the capture region 3282 // associated with the clause is OMPD_unknown and is generated 3283 // only once. 3284 if (CaptureRegion == ThisCaptureRegion || 3285 CaptureRegion == OMPD_unknown) { 3286 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3287 for (Decl *D : DS->decls()) 3288 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3289 } 3290 } 3291 } 3292 } 3293 SR = ActOnCapturedRegionEnd(SR.get()); 3294 } 3295 return SR; 3296 } 3297 3298 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3299 OpenMPDirectiveKind CancelRegion, 3300 SourceLocation StartLoc) { 3301 // CancelRegion is only needed for cancel and cancellation_point. 3302 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3303 return false; 3304 3305 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3306 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3307 return false; 3308 3309 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3310 << getOpenMPDirectiveName(CancelRegion); 3311 return true; 3312 } 3313 3314 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3315 OpenMPDirectiveKind CurrentRegion, 3316 const DeclarationNameInfo &CurrentName, 3317 OpenMPDirectiveKind CancelRegion, 3318 SourceLocation StartLoc) { 3319 if (Stack->getCurScope()) { 3320 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3321 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3322 bool NestingProhibited = false; 3323 bool CloseNesting = true; 3324 bool OrphanSeen = false; 3325 enum { 3326 NoRecommend, 3327 ShouldBeInParallelRegion, 3328 ShouldBeInOrderedRegion, 3329 ShouldBeInTargetRegion, 3330 ShouldBeInTeamsRegion 3331 } Recommend = NoRecommend; 3332 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3333 // OpenMP [2.16, Nesting of Regions] 3334 // OpenMP constructs may not be nested inside a simd region. 3335 // OpenMP [2.8.1,simd Construct, Restrictions] 3336 // An ordered construct with the simd clause is the only OpenMP 3337 // construct that can appear in the simd region. 3338 // Allowing a SIMD construct nested in another SIMD construct is an 3339 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3340 // message. 3341 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3342 ? diag::err_omp_prohibited_region_simd 3343 : diag::warn_omp_nesting_simd); 3344 return CurrentRegion != OMPD_simd; 3345 } 3346 if (ParentRegion == OMPD_atomic) { 3347 // OpenMP [2.16, Nesting of Regions] 3348 // OpenMP constructs may not be nested inside an atomic region. 3349 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3350 return true; 3351 } 3352 if (CurrentRegion == OMPD_section) { 3353 // OpenMP [2.7.2, sections Construct, Restrictions] 3354 // Orphaned section directives are prohibited. That is, the section 3355 // directives must appear within the sections construct and must not be 3356 // encountered elsewhere in the sections region. 3357 if (ParentRegion != OMPD_sections && 3358 ParentRegion != OMPD_parallel_sections) { 3359 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3360 << (ParentRegion != OMPD_unknown) 3361 << getOpenMPDirectiveName(ParentRegion); 3362 return true; 3363 } 3364 return false; 3365 } 3366 // Allow some constructs (except teams and cancellation constructs) to be 3367 // orphaned (they could be used in functions, called from OpenMP regions 3368 // with the required preconditions). 3369 if (ParentRegion == OMPD_unknown && 3370 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3371 CurrentRegion != OMPD_cancellation_point && 3372 CurrentRegion != OMPD_cancel) 3373 return false; 3374 if (CurrentRegion == OMPD_cancellation_point || 3375 CurrentRegion == OMPD_cancel) { 3376 // OpenMP [2.16, Nesting of Regions] 3377 // A cancellation point construct for which construct-type-clause is 3378 // taskgroup must be nested inside a task construct. A cancellation 3379 // point construct for which construct-type-clause is not taskgroup must 3380 // be closely nested inside an OpenMP construct that matches the type 3381 // specified in construct-type-clause. 3382 // A cancel construct for which construct-type-clause is taskgroup must be 3383 // nested inside a task construct. A cancel construct for which 3384 // construct-type-clause is not taskgroup must be closely nested inside an 3385 // OpenMP construct that matches the type specified in 3386 // construct-type-clause. 3387 NestingProhibited = 3388 !((CancelRegion == OMPD_parallel && 3389 (ParentRegion == OMPD_parallel || 3390 ParentRegion == OMPD_target_parallel)) || 3391 (CancelRegion == OMPD_for && 3392 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3393 ParentRegion == OMPD_target_parallel_for || 3394 ParentRegion == OMPD_distribute_parallel_for || 3395 ParentRegion == OMPD_teams_distribute_parallel_for || 3396 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3397 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3398 (CancelRegion == OMPD_sections && 3399 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3400 ParentRegion == OMPD_parallel_sections))); 3401 OrphanSeen = ParentRegion == OMPD_unknown; 3402 } else if (CurrentRegion == OMPD_master) { 3403 // OpenMP [2.16, Nesting of Regions] 3404 // A master region may not be closely nested inside a worksharing, 3405 // atomic, or explicit task region. 3406 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3407 isOpenMPTaskingDirective(ParentRegion); 3408 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3409 // OpenMP [2.16, Nesting of Regions] 3410 // A critical region may not be nested (closely or otherwise) inside a 3411 // critical region with the same name. Note that this restriction is not 3412 // sufficient to prevent deadlock. 3413 SourceLocation PreviousCriticalLoc; 3414 bool DeadLock = Stack->hasDirective( 3415 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3416 const DeclarationNameInfo &DNI, 3417 SourceLocation Loc) { 3418 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3419 PreviousCriticalLoc = Loc; 3420 return true; 3421 } 3422 return false; 3423 }, 3424 false /* skip top directive */); 3425 if (DeadLock) { 3426 SemaRef.Diag(StartLoc, 3427 diag::err_omp_prohibited_region_critical_same_name) 3428 << CurrentName.getName(); 3429 if (PreviousCriticalLoc.isValid()) 3430 SemaRef.Diag(PreviousCriticalLoc, 3431 diag::note_omp_previous_critical_region); 3432 return true; 3433 } 3434 } else if (CurrentRegion == OMPD_barrier) { 3435 // OpenMP [2.16, Nesting of Regions] 3436 // A barrier region may not be closely nested inside a worksharing, 3437 // explicit task, critical, ordered, atomic, or master region. 3438 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3439 isOpenMPTaskingDirective(ParentRegion) || 3440 ParentRegion == OMPD_master || 3441 ParentRegion == OMPD_critical || 3442 ParentRegion == OMPD_ordered; 3443 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3444 !isOpenMPParallelDirective(CurrentRegion) && 3445 !isOpenMPTeamsDirective(CurrentRegion)) { 3446 // OpenMP [2.16, Nesting of Regions] 3447 // A worksharing region may not be closely nested inside a worksharing, 3448 // explicit task, critical, ordered, atomic, or master region. 3449 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3450 isOpenMPTaskingDirective(ParentRegion) || 3451 ParentRegion == OMPD_master || 3452 ParentRegion == OMPD_critical || 3453 ParentRegion == OMPD_ordered; 3454 Recommend = ShouldBeInParallelRegion; 3455 } else if (CurrentRegion == OMPD_ordered) { 3456 // OpenMP [2.16, Nesting of Regions] 3457 // An ordered region may not be closely nested inside a critical, 3458 // atomic, or explicit task region. 3459 // An ordered region must be closely nested inside a loop region (or 3460 // parallel loop region) with an ordered clause. 3461 // OpenMP [2.8.1,simd Construct, Restrictions] 3462 // An ordered construct with the simd clause is the only OpenMP construct 3463 // that can appear in the simd region. 3464 NestingProhibited = ParentRegion == OMPD_critical || 3465 isOpenMPTaskingDirective(ParentRegion) || 3466 !(isOpenMPSimdDirective(ParentRegion) || 3467 Stack->isParentOrderedRegion()); 3468 Recommend = ShouldBeInOrderedRegion; 3469 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3470 // OpenMP [2.16, Nesting of Regions] 3471 // If specified, a teams construct must be contained within a target 3472 // construct. 3473 NestingProhibited = ParentRegion != OMPD_target; 3474 OrphanSeen = ParentRegion == OMPD_unknown; 3475 Recommend = ShouldBeInTargetRegion; 3476 } 3477 if (!NestingProhibited && 3478 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3479 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3480 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3481 // OpenMP [2.16, Nesting of Regions] 3482 // distribute, parallel, parallel sections, parallel workshare, and the 3483 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3484 // constructs that can be closely nested in the teams region. 3485 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3486 !isOpenMPDistributeDirective(CurrentRegion); 3487 Recommend = ShouldBeInParallelRegion; 3488 } 3489 if (!NestingProhibited && 3490 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3491 // OpenMP 4.5 [2.17 Nesting of Regions] 3492 // The region associated with the distribute construct must be strictly 3493 // nested inside a teams region 3494 NestingProhibited = 3495 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3496 Recommend = ShouldBeInTeamsRegion; 3497 } 3498 if (!NestingProhibited && 3499 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3500 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3501 // OpenMP 4.5 [2.17 Nesting of Regions] 3502 // If a target, target update, target data, target enter data, or 3503 // target exit data construct is encountered during execution of a 3504 // target region, the behavior is unspecified. 3505 NestingProhibited = Stack->hasDirective( 3506 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3507 SourceLocation) { 3508 if (isOpenMPTargetExecutionDirective(K)) { 3509 OffendingRegion = K; 3510 return true; 3511 } 3512 return false; 3513 }, 3514 false /* don't skip top directive */); 3515 CloseNesting = false; 3516 } 3517 if (NestingProhibited) { 3518 if (OrphanSeen) { 3519 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3520 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3521 } else { 3522 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3523 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3524 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3525 } 3526 return true; 3527 } 3528 } 3529 return false; 3530 } 3531 3532 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3533 ArrayRef<OMPClause *> Clauses, 3534 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3535 bool ErrorFound = false; 3536 unsigned NamedModifiersNumber = 0; 3537 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3538 OMPD_unknown + 1); 3539 SmallVector<SourceLocation, 4> NameModifierLoc; 3540 for (const OMPClause *C : Clauses) { 3541 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3542 // At most one if clause without a directive-name-modifier can appear on 3543 // the directive. 3544 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3545 if (FoundNameModifiers[CurNM]) { 3546 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3547 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3548 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3549 ErrorFound = true; 3550 } else if (CurNM != OMPD_unknown) { 3551 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3552 ++NamedModifiersNumber; 3553 } 3554 FoundNameModifiers[CurNM] = IC; 3555 if (CurNM == OMPD_unknown) 3556 continue; 3557 // Check if the specified name modifier is allowed for the current 3558 // directive. 3559 // At most one if clause with the particular directive-name-modifier can 3560 // appear on the directive. 3561 bool MatchFound = false; 3562 for (auto NM : AllowedNameModifiers) { 3563 if (CurNM == NM) { 3564 MatchFound = true; 3565 break; 3566 } 3567 } 3568 if (!MatchFound) { 3569 S.Diag(IC->getNameModifierLoc(), 3570 diag::err_omp_wrong_if_directive_name_modifier) 3571 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3572 ErrorFound = true; 3573 } 3574 } 3575 } 3576 // If any if clause on the directive includes a directive-name-modifier then 3577 // all if clauses on the directive must include a directive-name-modifier. 3578 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3579 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3580 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3581 diag::err_omp_no_more_if_clause); 3582 } else { 3583 std::string Values; 3584 std::string Sep(", "); 3585 unsigned AllowedCnt = 0; 3586 unsigned TotalAllowedNum = 3587 AllowedNameModifiers.size() - NamedModifiersNumber; 3588 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3589 ++Cnt) { 3590 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3591 if (!FoundNameModifiers[NM]) { 3592 Values += "'"; 3593 Values += getOpenMPDirectiveName(NM); 3594 Values += "'"; 3595 if (AllowedCnt + 2 == TotalAllowedNum) 3596 Values += " or "; 3597 else if (AllowedCnt + 1 != TotalAllowedNum) 3598 Values += Sep; 3599 ++AllowedCnt; 3600 } 3601 } 3602 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3603 diag::err_omp_unnamed_if_clause) 3604 << (TotalAllowedNum > 1) << Values; 3605 } 3606 for (SourceLocation Loc : NameModifierLoc) { 3607 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3608 } 3609 ErrorFound = true; 3610 } 3611 return ErrorFound; 3612 } 3613 3614 StmtResult Sema::ActOnOpenMPExecutableDirective( 3615 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3616 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3617 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3618 StmtResult Res = StmtError(); 3619 // First check CancelRegion which is then used in checkNestingOfRegions. 3620 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 3621 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 3622 StartLoc)) 3623 return StmtError(); 3624 3625 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 3626 VarsWithInheritedDSAType VarsWithInheritedDSA; 3627 bool ErrorFound = false; 3628 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 3629 if (AStmt && !CurContext->isDependentContext()) { 3630 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3631 3632 // Check default data sharing attributes for referenced variables. 3633 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 3634 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 3635 Stmt *S = AStmt; 3636 while (--ThisCaptureLevel >= 0) 3637 S = cast<CapturedStmt>(S)->getCapturedStmt(); 3638 DSAChecker.Visit(S); 3639 if (DSAChecker.isErrorFound()) 3640 return StmtError(); 3641 // Generate list of implicitly defined firstprivate variables. 3642 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 3643 3644 SmallVector<Expr *, 4> ImplicitFirstprivates( 3645 DSAChecker.getImplicitFirstprivate().begin(), 3646 DSAChecker.getImplicitFirstprivate().end()); 3647 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 3648 DSAChecker.getImplicitMap().end()); 3649 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 3650 for (OMPClause *C : Clauses) { 3651 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 3652 for (Expr *E : IRC->taskgroup_descriptors()) 3653 if (E) 3654 ImplicitFirstprivates.emplace_back(E); 3655 } 3656 } 3657 if (!ImplicitFirstprivates.empty()) { 3658 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 3659 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 3660 SourceLocation())) { 3661 ClausesWithImplicit.push_back(Implicit); 3662 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 3663 ImplicitFirstprivates.size(); 3664 } else { 3665 ErrorFound = true; 3666 } 3667 } 3668 if (!ImplicitMaps.empty()) { 3669 CXXScopeSpec MapperIdScopeSpec; 3670 DeclarationNameInfo MapperId; 3671 if (OMPClause *Implicit = ActOnOpenMPMapClause( 3672 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 3673 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 3674 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 3675 ClausesWithImplicit.emplace_back(Implicit); 3676 ErrorFound |= 3677 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 3678 } else { 3679 ErrorFound = true; 3680 } 3681 } 3682 } 3683 3684 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 3685 switch (Kind) { 3686 case OMPD_parallel: 3687 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 3688 EndLoc); 3689 AllowedNameModifiers.push_back(OMPD_parallel); 3690 break; 3691 case OMPD_simd: 3692 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3693 VarsWithInheritedDSA); 3694 break; 3695 case OMPD_for: 3696 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3697 VarsWithInheritedDSA); 3698 break; 3699 case OMPD_for_simd: 3700 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3701 EndLoc, VarsWithInheritedDSA); 3702 break; 3703 case OMPD_sections: 3704 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 3705 EndLoc); 3706 break; 3707 case OMPD_section: 3708 assert(ClausesWithImplicit.empty() && 3709 "No clauses are allowed for 'omp section' directive"); 3710 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 3711 break; 3712 case OMPD_single: 3713 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 3714 EndLoc); 3715 break; 3716 case OMPD_master: 3717 assert(ClausesWithImplicit.empty() && 3718 "No clauses are allowed for 'omp master' directive"); 3719 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 3720 break; 3721 case OMPD_critical: 3722 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 3723 StartLoc, EndLoc); 3724 break; 3725 case OMPD_parallel_for: 3726 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 3727 EndLoc, VarsWithInheritedDSA); 3728 AllowedNameModifiers.push_back(OMPD_parallel); 3729 break; 3730 case OMPD_parallel_for_simd: 3731 Res = ActOnOpenMPParallelForSimdDirective( 3732 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3733 AllowedNameModifiers.push_back(OMPD_parallel); 3734 break; 3735 case OMPD_parallel_sections: 3736 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 3737 StartLoc, EndLoc); 3738 AllowedNameModifiers.push_back(OMPD_parallel); 3739 break; 3740 case OMPD_task: 3741 Res = 3742 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3743 AllowedNameModifiers.push_back(OMPD_task); 3744 break; 3745 case OMPD_taskyield: 3746 assert(ClausesWithImplicit.empty() && 3747 "No clauses are allowed for 'omp taskyield' directive"); 3748 assert(AStmt == nullptr && 3749 "No associated statement allowed for 'omp taskyield' directive"); 3750 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 3751 break; 3752 case OMPD_barrier: 3753 assert(ClausesWithImplicit.empty() && 3754 "No clauses are allowed for 'omp barrier' directive"); 3755 assert(AStmt == nullptr && 3756 "No associated statement allowed for 'omp barrier' directive"); 3757 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 3758 break; 3759 case OMPD_taskwait: 3760 assert(ClausesWithImplicit.empty() && 3761 "No clauses are allowed for 'omp taskwait' directive"); 3762 assert(AStmt == nullptr && 3763 "No associated statement allowed for 'omp taskwait' directive"); 3764 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 3765 break; 3766 case OMPD_taskgroup: 3767 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 3768 EndLoc); 3769 break; 3770 case OMPD_flush: 3771 assert(AStmt == nullptr && 3772 "No associated statement allowed for 'omp flush' directive"); 3773 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 3774 break; 3775 case OMPD_ordered: 3776 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 3777 EndLoc); 3778 break; 3779 case OMPD_atomic: 3780 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 3781 EndLoc); 3782 break; 3783 case OMPD_teams: 3784 Res = 3785 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3786 break; 3787 case OMPD_target: 3788 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 3789 EndLoc); 3790 AllowedNameModifiers.push_back(OMPD_target); 3791 break; 3792 case OMPD_target_parallel: 3793 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 3794 StartLoc, EndLoc); 3795 AllowedNameModifiers.push_back(OMPD_target); 3796 AllowedNameModifiers.push_back(OMPD_parallel); 3797 break; 3798 case OMPD_target_parallel_for: 3799 Res = ActOnOpenMPTargetParallelForDirective( 3800 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3801 AllowedNameModifiers.push_back(OMPD_target); 3802 AllowedNameModifiers.push_back(OMPD_parallel); 3803 break; 3804 case OMPD_cancellation_point: 3805 assert(ClausesWithImplicit.empty() && 3806 "No clauses are allowed for 'omp cancellation point' directive"); 3807 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 3808 "cancellation point' directive"); 3809 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 3810 break; 3811 case OMPD_cancel: 3812 assert(AStmt == nullptr && 3813 "No associated statement allowed for 'omp cancel' directive"); 3814 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 3815 CancelRegion); 3816 AllowedNameModifiers.push_back(OMPD_cancel); 3817 break; 3818 case OMPD_target_data: 3819 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 3820 EndLoc); 3821 AllowedNameModifiers.push_back(OMPD_target_data); 3822 break; 3823 case OMPD_target_enter_data: 3824 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 3825 EndLoc, AStmt); 3826 AllowedNameModifiers.push_back(OMPD_target_enter_data); 3827 break; 3828 case OMPD_target_exit_data: 3829 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 3830 EndLoc, AStmt); 3831 AllowedNameModifiers.push_back(OMPD_target_exit_data); 3832 break; 3833 case OMPD_taskloop: 3834 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 3835 EndLoc, VarsWithInheritedDSA); 3836 AllowedNameModifiers.push_back(OMPD_taskloop); 3837 break; 3838 case OMPD_taskloop_simd: 3839 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3840 EndLoc, VarsWithInheritedDSA); 3841 AllowedNameModifiers.push_back(OMPD_taskloop); 3842 break; 3843 case OMPD_distribute: 3844 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 3845 EndLoc, VarsWithInheritedDSA); 3846 break; 3847 case OMPD_target_update: 3848 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 3849 EndLoc, AStmt); 3850 AllowedNameModifiers.push_back(OMPD_target_update); 3851 break; 3852 case OMPD_distribute_parallel_for: 3853 Res = ActOnOpenMPDistributeParallelForDirective( 3854 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3855 AllowedNameModifiers.push_back(OMPD_parallel); 3856 break; 3857 case OMPD_distribute_parallel_for_simd: 3858 Res = ActOnOpenMPDistributeParallelForSimdDirective( 3859 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3860 AllowedNameModifiers.push_back(OMPD_parallel); 3861 break; 3862 case OMPD_distribute_simd: 3863 Res = ActOnOpenMPDistributeSimdDirective( 3864 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3865 break; 3866 case OMPD_target_parallel_for_simd: 3867 Res = ActOnOpenMPTargetParallelForSimdDirective( 3868 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3869 AllowedNameModifiers.push_back(OMPD_target); 3870 AllowedNameModifiers.push_back(OMPD_parallel); 3871 break; 3872 case OMPD_target_simd: 3873 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3874 EndLoc, VarsWithInheritedDSA); 3875 AllowedNameModifiers.push_back(OMPD_target); 3876 break; 3877 case OMPD_teams_distribute: 3878 Res = ActOnOpenMPTeamsDistributeDirective( 3879 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3880 break; 3881 case OMPD_teams_distribute_simd: 3882 Res = ActOnOpenMPTeamsDistributeSimdDirective( 3883 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3884 break; 3885 case OMPD_teams_distribute_parallel_for_simd: 3886 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 3887 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3888 AllowedNameModifiers.push_back(OMPD_parallel); 3889 break; 3890 case OMPD_teams_distribute_parallel_for: 3891 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 3892 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3893 AllowedNameModifiers.push_back(OMPD_parallel); 3894 break; 3895 case OMPD_target_teams: 3896 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 3897 EndLoc); 3898 AllowedNameModifiers.push_back(OMPD_target); 3899 break; 3900 case OMPD_target_teams_distribute: 3901 Res = ActOnOpenMPTargetTeamsDistributeDirective( 3902 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3903 AllowedNameModifiers.push_back(OMPD_target); 3904 break; 3905 case OMPD_target_teams_distribute_parallel_for: 3906 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 3907 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3908 AllowedNameModifiers.push_back(OMPD_target); 3909 AllowedNameModifiers.push_back(OMPD_parallel); 3910 break; 3911 case OMPD_target_teams_distribute_parallel_for_simd: 3912 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 3913 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3914 AllowedNameModifiers.push_back(OMPD_target); 3915 AllowedNameModifiers.push_back(OMPD_parallel); 3916 break; 3917 case OMPD_target_teams_distribute_simd: 3918 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 3919 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3920 AllowedNameModifiers.push_back(OMPD_target); 3921 break; 3922 case OMPD_declare_target: 3923 case OMPD_end_declare_target: 3924 case OMPD_threadprivate: 3925 case OMPD_allocate: 3926 case OMPD_declare_reduction: 3927 case OMPD_declare_mapper: 3928 case OMPD_declare_simd: 3929 case OMPD_requires: 3930 llvm_unreachable("OpenMP Directive is not allowed"); 3931 case OMPD_unknown: 3932 llvm_unreachable("Unknown OpenMP directive"); 3933 } 3934 3935 ErrorFound = Res.isInvalid() || ErrorFound; 3936 3937 for (const auto &P : VarsWithInheritedDSA) { 3938 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 3939 << P.first << P.second->getSourceRange(); 3940 } 3941 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 3942 3943 if (!AllowedNameModifiers.empty()) 3944 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 3945 ErrorFound; 3946 3947 if (ErrorFound) 3948 return StmtError(); 3949 3950 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 3951 Res.getAs<OMPExecutableDirective>() 3952 ->getStructuredBlock() 3953 ->setIsOMPStructuredBlock(true); 3954 } 3955 3956 return Res; 3957 } 3958 3959 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 3960 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 3961 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 3962 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 3963 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 3964 assert(Aligneds.size() == Alignments.size()); 3965 assert(Linears.size() == LinModifiers.size()); 3966 assert(Linears.size() == Steps.size()); 3967 if (!DG || DG.get().isNull()) 3968 return DeclGroupPtrTy(); 3969 3970 if (!DG.get().isSingleDecl()) { 3971 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 3972 return DG; 3973 } 3974 Decl *ADecl = DG.get().getSingleDecl(); 3975 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 3976 ADecl = FTD->getTemplatedDecl(); 3977 3978 auto *FD = dyn_cast<FunctionDecl>(ADecl); 3979 if (!FD) { 3980 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 3981 return DeclGroupPtrTy(); 3982 } 3983 3984 // OpenMP [2.8.2, declare simd construct, Description] 3985 // The parameter of the simdlen clause must be a constant positive integer 3986 // expression. 3987 ExprResult SL; 3988 if (Simdlen) 3989 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 3990 // OpenMP [2.8.2, declare simd construct, Description] 3991 // The special this pointer can be used as if was one of the arguments to the 3992 // function in any of the linear, aligned, or uniform clauses. 3993 // The uniform clause declares one or more arguments to have an invariant 3994 // value for all concurrent invocations of the function in the execution of a 3995 // single SIMD loop. 3996 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 3997 const Expr *UniformedLinearThis = nullptr; 3998 for (const Expr *E : Uniforms) { 3999 E = E->IgnoreParenImpCasts(); 4000 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4001 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4002 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4003 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4004 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4005 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4006 continue; 4007 } 4008 if (isa<CXXThisExpr>(E)) { 4009 UniformedLinearThis = E; 4010 continue; 4011 } 4012 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4013 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4014 } 4015 // OpenMP [2.8.2, declare simd construct, Description] 4016 // The aligned clause declares that the object to which each list item points 4017 // is aligned to the number of bytes expressed in the optional parameter of 4018 // the aligned clause. 4019 // The special this pointer can be used as if was one of the arguments to the 4020 // function in any of the linear, aligned, or uniform clauses. 4021 // The type of list items appearing in the aligned clause must be array, 4022 // pointer, reference to array, or reference to pointer. 4023 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4024 const Expr *AlignedThis = nullptr; 4025 for (const Expr *E : Aligneds) { 4026 E = E->IgnoreParenImpCasts(); 4027 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4028 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4029 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4030 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4031 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4032 ->getCanonicalDecl() == CanonPVD) { 4033 // OpenMP [2.8.1, simd construct, Restrictions] 4034 // A list-item cannot appear in more than one aligned clause. 4035 if (AlignedArgs.count(CanonPVD) > 0) { 4036 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4037 << 1 << E->getSourceRange(); 4038 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4039 diag::note_omp_explicit_dsa) 4040 << getOpenMPClauseName(OMPC_aligned); 4041 continue; 4042 } 4043 AlignedArgs[CanonPVD] = E; 4044 QualType QTy = PVD->getType() 4045 .getNonReferenceType() 4046 .getUnqualifiedType() 4047 .getCanonicalType(); 4048 const Type *Ty = QTy.getTypePtrOrNull(); 4049 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4050 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4051 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4052 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4053 } 4054 continue; 4055 } 4056 } 4057 if (isa<CXXThisExpr>(E)) { 4058 if (AlignedThis) { 4059 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4060 << 2 << E->getSourceRange(); 4061 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4062 << getOpenMPClauseName(OMPC_aligned); 4063 } 4064 AlignedThis = E; 4065 continue; 4066 } 4067 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4068 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4069 } 4070 // The optional parameter of the aligned clause, alignment, must be a constant 4071 // positive integer expression. If no optional parameter is specified, 4072 // implementation-defined default alignments for SIMD instructions on the 4073 // target platforms are assumed. 4074 SmallVector<const Expr *, 4> NewAligns; 4075 for (Expr *E : Alignments) { 4076 ExprResult Align; 4077 if (E) 4078 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4079 NewAligns.push_back(Align.get()); 4080 } 4081 // OpenMP [2.8.2, declare simd construct, Description] 4082 // The linear clause declares one or more list items to be private to a SIMD 4083 // lane and to have a linear relationship with respect to the iteration space 4084 // of a loop. 4085 // The special this pointer can be used as if was one of the arguments to the 4086 // function in any of the linear, aligned, or uniform clauses. 4087 // When a linear-step expression is specified in a linear clause it must be 4088 // either a constant integer expression or an integer-typed parameter that is 4089 // specified in a uniform clause on the directive. 4090 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4091 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4092 auto MI = LinModifiers.begin(); 4093 for (const Expr *E : Linears) { 4094 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4095 ++MI; 4096 E = E->IgnoreParenImpCasts(); 4097 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4098 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4099 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4100 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4101 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4102 ->getCanonicalDecl() == CanonPVD) { 4103 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4104 // A list-item cannot appear in more than one linear clause. 4105 if (LinearArgs.count(CanonPVD) > 0) { 4106 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4107 << getOpenMPClauseName(OMPC_linear) 4108 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4109 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4110 diag::note_omp_explicit_dsa) 4111 << getOpenMPClauseName(OMPC_linear); 4112 continue; 4113 } 4114 // Each argument can appear in at most one uniform or linear clause. 4115 if (UniformedArgs.count(CanonPVD) > 0) { 4116 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4117 << getOpenMPClauseName(OMPC_linear) 4118 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4119 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4120 diag::note_omp_explicit_dsa) 4121 << getOpenMPClauseName(OMPC_uniform); 4122 continue; 4123 } 4124 LinearArgs[CanonPVD] = E; 4125 if (E->isValueDependent() || E->isTypeDependent() || 4126 E->isInstantiationDependent() || 4127 E->containsUnexpandedParameterPack()) 4128 continue; 4129 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4130 PVD->getOriginalType()); 4131 continue; 4132 } 4133 } 4134 if (isa<CXXThisExpr>(E)) { 4135 if (UniformedLinearThis) { 4136 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4137 << getOpenMPClauseName(OMPC_linear) 4138 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4139 << E->getSourceRange(); 4140 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4141 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4142 : OMPC_linear); 4143 continue; 4144 } 4145 UniformedLinearThis = E; 4146 if (E->isValueDependent() || E->isTypeDependent() || 4147 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4148 continue; 4149 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4150 E->getType()); 4151 continue; 4152 } 4153 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4154 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4155 } 4156 Expr *Step = nullptr; 4157 Expr *NewStep = nullptr; 4158 SmallVector<Expr *, 4> NewSteps; 4159 for (Expr *E : Steps) { 4160 // Skip the same step expression, it was checked already. 4161 if (Step == E || !E) { 4162 NewSteps.push_back(E ? NewStep : nullptr); 4163 continue; 4164 } 4165 Step = E; 4166 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4167 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4168 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4169 if (UniformedArgs.count(CanonPVD) == 0) { 4170 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4171 << Step->getSourceRange(); 4172 } else if (E->isValueDependent() || E->isTypeDependent() || 4173 E->isInstantiationDependent() || 4174 E->containsUnexpandedParameterPack() || 4175 CanonPVD->getType()->hasIntegerRepresentation()) { 4176 NewSteps.push_back(Step); 4177 } else { 4178 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4179 << Step->getSourceRange(); 4180 } 4181 continue; 4182 } 4183 NewStep = Step; 4184 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4185 !Step->isInstantiationDependent() && 4186 !Step->containsUnexpandedParameterPack()) { 4187 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4188 .get(); 4189 if (NewStep) 4190 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4191 } 4192 NewSteps.push_back(NewStep); 4193 } 4194 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4195 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4196 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4197 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4198 const_cast<Expr **>(Linears.data()), Linears.size(), 4199 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4200 NewSteps.data(), NewSteps.size(), SR); 4201 ADecl->addAttr(NewAttr); 4202 return ConvertDeclToDeclGroup(ADecl); 4203 } 4204 4205 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4206 Stmt *AStmt, 4207 SourceLocation StartLoc, 4208 SourceLocation EndLoc) { 4209 if (!AStmt) 4210 return StmtError(); 4211 4212 auto *CS = cast<CapturedStmt>(AStmt); 4213 // 1.2.2 OpenMP Language Terminology 4214 // Structured block - An executable statement with a single entry at the 4215 // top and a single exit at the bottom. 4216 // The point of exit cannot be a branch out of the structured block. 4217 // longjmp() and throw() must not violate the entry/exit criteria. 4218 CS->getCapturedDecl()->setNothrow(); 4219 4220 setFunctionHasBranchProtectedScope(); 4221 4222 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4223 DSAStack->isCancelRegion()); 4224 } 4225 4226 namespace { 4227 /// Helper class for checking canonical form of the OpenMP loops and 4228 /// extracting iteration space of each loop in the loop nest, that will be used 4229 /// for IR generation. 4230 class OpenMPIterationSpaceChecker { 4231 /// Reference to Sema. 4232 Sema &SemaRef; 4233 /// A location for diagnostics (when there is no some better location). 4234 SourceLocation DefaultLoc; 4235 /// A location for diagnostics (when increment is not compatible). 4236 SourceLocation ConditionLoc; 4237 /// A source location for referring to loop init later. 4238 SourceRange InitSrcRange; 4239 /// A source location for referring to condition later. 4240 SourceRange ConditionSrcRange; 4241 /// A source location for referring to increment later. 4242 SourceRange IncrementSrcRange; 4243 /// Loop variable. 4244 ValueDecl *LCDecl = nullptr; 4245 /// Reference to loop variable. 4246 Expr *LCRef = nullptr; 4247 /// Lower bound (initializer for the var). 4248 Expr *LB = nullptr; 4249 /// Upper bound. 4250 Expr *UB = nullptr; 4251 /// Loop step (increment). 4252 Expr *Step = nullptr; 4253 /// This flag is true when condition is one of: 4254 /// Var < UB 4255 /// Var <= UB 4256 /// UB > Var 4257 /// UB >= Var 4258 /// This will have no value when the condition is != 4259 llvm::Optional<bool> TestIsLessOp; 4260 /// This flag is true when condition is strict ( < or > ). 4261 bool TestIsStrictOp = false; 4262 /// This flag is true when step is subtracted on each iteration. 4263 bool SubtractStep = false; 4264 4265 public: 4266 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 4267 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 4268 /// Check init-expr for canonical loop form and save loop counter 4269 /// variable - #Var and its initialization value - #LB. 4270 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 4271 /// Check test-expr for canonical form, save upper-bound (#UB), flags 4272 /// for less/greater and for strict/non-strict comparison. 4273 bool checkAndSetCond(Expr *S); 4274 /// Check incr-expr for canonical loop form and return true if it 4275 /// does not conform, otherwise save loop step (#Step). 4276 bool checkAndSetInc(Expr *S); 4277 /// Return the loop counter variable. 4278 ValueDecl *getLoopDecl() const { return LCDecl; } 4279 /// Return the reference expression to loop counter variable. 4280 Expr *getLoopDeclRefExpr() const { return LCRef; } 4281 /// Source range of the loop init. 4282 SourceRange getInitSrcRange() const { return InitSrcRange; } 4283 /// Source range of the loop condition. 4284 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 4285 /// Source range of the loop increment. 4286 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 4287 /// True if the step should be subtracted. 4288 bool shouldSubtractStep() const { return SubtractStep; } 4289 /// True, if the compare operator is strict (<, > or !=). 4290 bool isStrictTestOp() const { return TestIsStrictOp; } 4291 /// Build the expression to calculate the number of iterations. 4292 Expr *buildNumIterations( 4293 Scope *S, const bool LimitedType, 4294 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4295 /// Build the precondition expression for the loops. 4296 Expr * 4297 buildPreCond(Scope *S, Expr *Cond, 4298 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4299 /// Build reference expression to the counter be used for codegen. 4300 DeclRefExpr * 4301 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4302 DSAStackTy &DSA) const; 4303 /// Build reference expression to the private counter be used for 4304 /// codegen. 4305 Expr *buildPrivateCounterVar() const; 4306 /// Build initialization of the counter be used for codegen. 4307 Expr *buildCounterInit() const; 4308 /// Build step of the counter be used for codegen. 4309 Expr *buildCounterStep() const; 4310 /// Build loop data with counter value for depend clauses in ordered 4311 /// directives. 4312 Expr * 4313 buildOrderedLoopData(Scope *S, Expr *Counter, 4314 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4315 SourceLocation Loc, Expr *Inc = nullptr, 4316 OverloadedOperatorKind OOK = OO_Amp); 4317 /// Return true if any expression is dependent. 4318 bool dependent() const; 4319 4320 private: 4321 /// Check the right-hand side of an assignment in the increment 4322 /// expression. 4323 bool checkAndSetIncRHS(Expr *RHS); 4324 /// Helper to set loop counter variable and its initializer. 4325 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); 4326 /// Helper to set upper bound. 4327 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 4328 SourceRange SR, SourceLocation SL); 4329 /// Helper to set loop increment. 4330 bool setStep(Expr *NewStep, bool Subtract); 4331 }; 4332 4333 bool OpenMPIterationSpaceChecker::dependent() const { 4334 if (!LCDecl) { 4335 assert(!LB && !UB && !Step); 4336 return false; 4337 } 4338 return LCDecl->getType()->isDependentType() || 4339 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 4340 (Step && Step->isValueDependent()); 4341 } 4342 4343 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 4344 Expr *NewLCRefExpr, 4345 Expr *NewLB) { 4346 // State consistency checking to ensure correct usage. 4347 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 4348 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4349 if (!NewLCDecl || !NewLB) 4350 return true; 4351 LCDecl = getCanonicalDecl(NewLCDecl); 4352 LCRef = NewLCRefExpr; 4353 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 4354 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4355 if ((Ctor->isCopyOrMoveConstructor() || 4356 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4357 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4358 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 4359 LB = NewLB; 4360 return false; 4361 } 4362 4363 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 4364 llvm::Optional<bool> LessOp, 4365 bool StrictOp, SourceRange SR, 4366 SourceLocation SL) { 4367 // State consistency checking to ensure correct usage. 4368 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 4369 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4370 if (!NewUB) 4371 return true; 4372 UB = NewUB; 4373 if (LessOp) 4374 TestIsLessOp = LessOp; 4375 TestIsStrictOp = StrictOp; 4376 ConditionSrcRange = SR; 4377 ConditionLoc = SL; 4378 return false; 4379 } 4380 4381 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 4382 // State consistency checking to ensure correct usage. 4383 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 4384 if (!NewStep) 4385 return true; 4386 if (!NewStep->isValueDependent()) { 4387 // Check that the step is integer expression. 4388 SourceLocation StepLoc = NewStep->getBeginLoc(); 4389 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 4390 StepLoc, getExprAsWritten(NewStep)); 4391 if (Val.isInvalid()) 4392 return true; 4393 NewStep = Val.get(); 4394 4395 // OpenMP [2.6, Canonical Loop Form, Restrictions] 4396 // If test-expr is of form var relational-op b and relational-op is < or 4397 // <= then incr-expr must cause var to increase on each iteration of the 4398 // loop. If test-expr is of form var relational-op b and relational-op is 4399 // > or >= then incr-expr must cause var to decrease on each iteration of 4400 // the loop. 4401 // If test-expr is of form b relational-op var and relational-op is < or 4402 // <= then incr-expr must cause var to decrease on each iteration of the 4403 // loop. If test-expr is of form b relational-op var and relational-op is 4404 // > or >= then incr-expr must cause var to increase on each iteration of 4405 // the loop. 4406 llvm::APSInt Result; 4407 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 4408 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 4409 bool IsConstNeg = 4410 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 4411 bool IsConstPos = 4412 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 4413 bool IsConstZero = IsConstant && !Result.getBoolValue(); 4414 4415 // != with increment is treated as <; != with decrement is treated as > 4416 if (!TestIsLessOp.hasValue()) 4417 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 4418 if (UB && (IsConstZero || 4419 (TestIsLessOp.getValue() ? 4420 (IsConstNeg || (IsUnsigned && Subtract)) : 4421 (IsConstPos || (IsUnsigned && !Subtract))))) { 4422 SemaRef.Diag(NewStep->getExprLoc(), 4423 diag::err_omp_loop_incr_not_compatible) 4424 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 4425 SemaRef.Diag(ConditionLoc, 4426 diag::note_omp_loop_cond_requres_compatible_incr) 4427 << TestIsLessOp.getValue() << ConditionSrcRange; 4428 return true; 4429 } 4430 if (TestIsLessOp.getValue() == Subtract) { 4431 NewStep = 4432 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 4433 .get(); 4434 Subtract = !Subtract; 4435 } 4436 } 4437 4438 Step = NewStep; 4439 SubtractStep = Subtract; 4440 return false; 4441 } 4442 4443 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 4444 // Check init-expr for canonical loop form and save loop counter 4445 // variable - #Var and its initialization value - #LB. 4446 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 4447 // var = lb 4448 // integer-type var = lb 4449 // random-access-iterator-type var = lb 4450 // pointer-type var = lb 4451 // 4452 if (!S) { 4453 if (EmitDiags) { 4454 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 4455 } 4456 return true; 4457 } 4458 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4459 if (!ExprTemp->cleanupsHaveSideEffects()) 4460 S = ExprTemp->getSubExpr(); 4461 4462 InitSrcRange = S->getSourceRange(); 4463 if (Expr *E = dyn_cast<Expr>(S)) 4464 S = E->IgnoreParens(); 4465 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4466 if (BO->getOpcode() == BO_Assign) { 4467 Expr *LHS = BO->getLHS()->IgnoreParens(); 4468 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4469 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4470 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4471 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4472 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); 4473 } 4474 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4475 if (ME->isArrow() && 4476 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4477 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4478 } 4479 } 4480 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 4481 if (DS->isSingleDecl()) { 4482 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 4483 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 4484 // Accept non-canonical init form here but emit ext. warning. 4485 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 4486 SemaRef.Diag(S->getBeginLoc(), 4487 diag::ext_omp_loop_not_canonical_init) 4488 << S->getSourceRange(); 4489 return setLCDeclAndLB( 4490 Var, 4491 buildDeclRefExpr(SemaRef, Var, 4492 Var->getType().getNonReferenceType(), 4493 DS->getBeginLoc()), 4494 Var->getInit()); 4495 } 4496 } 4497 } 4498 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4499 if (CE->getOperator() == OO_Equal) { 4500 Expr *LHS = CE->getArg(0); 4501 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4502 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4503 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4504 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4505 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); 4506 } 4507 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4508 if (ME->isArrow() && 4509 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4510 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4511 } 4512 } 4513 } 4514 4515 if (dependent() || SemaRef.CurContext->isDependentContext()) 4516 return false; 4517 if (EmitDiags) { 4518 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 4519 << S->getSourceRange(); 4520 } 4521 return true; 4522 } 4523 4524 /// Ignore parenthesizes, implicit casts, copy constructor and return the 4525 /// variable (which may be the loop variable) if possible. 4526 static const ValueDecl *getInitLCDecl(const Expr *E) { 4527 if (!E) 4528 return nullptr; 4529 E = getExprAsWritten(E); 4530 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 4531 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4532 if ((Ctor->isCopyOrMoveConstructor() || 4533 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4534 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4535 E = CE->getArg(0)->IgnoreParenImpCasts(); 4536 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 4537 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 4538 return getCanonicalDecl(VD); 4539 } 4540 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 4541 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4542 return getCanonicalDecl(ME->getMemberDecl()); 4543 return nullptr; 4544 } 4545 4546 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 4547 // Check test-expr for canonical form, save upper-bound UB, flags for 4548 // less/greater and for strict/non-strict comparison. 4549 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4550 // var relational-op b 4551 // b relational-op var 4552 // 4553 if (!S) { 4554 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 4555 return true; 4556 } 4557 S = getExprAsWritten(S); 4558 SourceLocation CondLoc = S->getBeginLoc(); 4559 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4560 if (BO->isRelationalOp()) { 4561 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4562 return setUB(BO->getRHS(), 4563 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 4564 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4565 BO->getSourceRange(), BO->getOperatorLoc()); 4566 if (getInitLCDecl(BO->getRHS()) == LCDecl) 4567 return setUB(BO->getLHS(), 4568 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 4569 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4570 BO->getSourceRange(), BO->getOperatorLoc()); 4571 } else if (BO->getOpcode() == BO_NE) 4572 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? 4573 BO->getRHS() : BO->getLHS(), 4574 /*LessOp=*/llvm::None, 4575 /*StrictOp=*/true, 4576 BO->getSourceRange(), BO->getOperatorLoc()); 4577 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4578 if (CE->getNumArgs() == 2) { 4579 auto Op = CE->getOperator(); 4580 switch (Op) { 4581 case OO_Greater: 4582 case OO_GreaterEqual: 4583 case OO_Less: 4584 case OO_LessEqual: 4585 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4586 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 4587 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4588 CE->getOperatorLoc()); 4589 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 4590 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 4591 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4592 CE->getOperatorLoc()); 4593 break; 4594 case OO_ExclaimEqual: 4595 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? 4596 CE->getArg(1) : CE->getArg(0), 4597 /*LessOp=*/llvm::None, 4598 /*StrictOp=*/true, 4599 CE->getSourceRange(), 4600 CE->getOperatorLoc()); 4601 break; 4602 default: 4603 break; 4604 } 4605 } 4606 } 4607 if (dependent() || SemaRef.CurContext->isDependentContext()) 4608 return false; 4609 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 4610 << S->getSourceRange() << LCDecl; 4611 return true; 4612 } 4613 4614 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 4615 // RHS of canonical loop form increment can be: 4616 // var + incr 4617 // incr + var 4618 // var - incr 4619 // 4620 RHS = RHS->IgnoreParenImpCasts(); 4621 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 4622 if (BO->isAdditiveOp()) { 4623 bool IsAdd = BO->getOpcode() == BO_Add; 4624 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4625 return setStep(BO->getRHS(), !IsAdd); 4626 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 4627 return setStep(BO->getLHS(), /*Subtract=*/false); 4628 } 4629 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 4630 bool IsAdd = CE->getOperator() == OO_Plus; 4631 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 4632 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4633 return setStep(CE->getArg(1), !IsAdd); 4634 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 4635 return setStep(CE->getArg(0), /*Subtract=*/false); 4636 } 4637 } 4638 if (dependent() || SemaRef.CurContext->isDependentContext()) 4639 return false; 4640 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 4641 << RHS->getSourceRange() << LCDecl; 4642 return true; 4643 } 4644 4645 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 4646 // Check incr-expr for canonical loop form and return true if it 4647 // does not conform. 4648 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4649 // ++var 4650 // var++ 4651 // --var 4652 // var-- 4653 // var += incr 4654 // var -= incr 4655 // var = var + incr 4656 // var = incr + var 4657 // var = var - incr 4658 // 4659 if (!S) { 4660 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 4661 return true; 4662 } 4663 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4664 if (!ExprTemp->cleanupsHaveSideEffects()) 4665 S = ExprTemp->getSubExpr(); 4666 4667 IncrementSrcRange = S->getSourceRange(); 4668 S = S->IgnoreParens(); 4669 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 4670 if (UO->isIncrementDecrementOp() && 4671 getInitLCDecl(UO->getSubExpr()) == LCDecl) 4672 return setStep(SemaRef 4673 .ActOnIntegerConstant(UO->getBeginLoc(), 4674 (UO->isDecrementOp() ? -1 : 1)) 4675 .get(), 4676 /*Subtract=*/false); 4677 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4678 switch (BO->getOpcode()) { 4679 case BO_AddAssign: 4680 case BO_SubAssign: 4681 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4682 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 4683 break; 4684 case BO_Assign: 4685 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4686 return checkAndSetIncRHS(BO->getRHS()); 4687 break; 4688 default: 4689 break; 4690 } 4691 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4692 switch (CE->getOperator()) { 4693 case OO_PlusPlus: 4694 case OO_MinusMinus: 4695 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4696 return setStep(SemaRef 4697 .ActOnIntegerConstant( 4698 CE->getBeginLoc(), 4699 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 4700 .get(), 4701 /*Subtract=*/false); 4702 break; 4703 case OO_PlusEqual: 4704 case OO_MinusEqual: 4705 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4706 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 4707 break; 4708 case OO_Equal: 4709 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4710 return checkAndSetIncRHS(CE->getArg(1)); 4711 break; 4712 default: 4713 break; 4714 } 4715 } 4716 if (dependent() || SemaRef.CurContext->isDependentContext()) 4717 return false; 4718 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 4719 << S->getSourceRange() << LCDecl; 4720 return true; 4721 } 4722 4723 static ExprResult 4724 tryBuildCapture(Sema &SemaRef, Expr *Capture, 4725 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4726 if (SemaRef.CurContext->isDependentContext()) 4727 return ExprResult(Capture); 4728 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 4729 return SemaRef.PerformImplicitConversion( 4730 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 4731 /*AllowExplicit=*/true); 4732 auto I = Captures.find(Capture); 4733 if (I != Captures.end()) 4734 return buildCapture(SemaRef, Capture, I->second); 4735 DeclRefExpr *Ref = nullptr; 4736 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 4737 Captures[Capture] = Ref; 4738 return Res; 4739 } 4740 4741 /// Build the expression to calculate the number of iterations. 4742 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 4743 Scope *S, const bool LimitedType, 4744 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 4745 ExprResult Diff; 4746 QualType VarType = LCDecl->getType().getNonReferenceType(); 4747 if (VarType->isIntegerType() || VarType->isPointerType() || 4748 SemaRef.getLangOpts().CPlusPlus) { 4749 // Upper - Lower 4750 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 4751 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 4752 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 4753 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 4754 if (!Upper || !Lower) 4755 return nullptr; 4756 4757 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4758 4759 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4760 // BuildBinOp already emitted error, this one is to point user to upper 4761 // and lower bound, and to tell what is passed to 'operator-'. 4762 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 4763 << Upper->getSourceRange() << Lower->getSourceRange(); 4764 return nullptr; 4765 } 4766 } 4767 4768 if (!Diff.isUsable()) 4769 return nullptr; 4770 4771 // Upper - Lower [- 1] 4772 if (TestIsStrictOp) 4773 Diff = SemaRef.BuildBinOp( 4774 S, DefaultLoc, BO_Sub, Diff.get(), 4775 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4776 if (!Diff.isUsable()) 4777 return nullptr; 4778 4779 // Upper - Lower [- 1] + Step 4780 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 4781 if (!NewStep.isUsable()) 4782 return nullptr; 4783 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 4784 if (!Diff.isUsable()) 4785 return nullptr; 4786 4787 // Parentheses (for dumping/debugging purposes only). 4788 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4789 if (!Diff.isUsable()) 4790 return nullptr; 4791 4792 // (Upper - Lower [- 1] + Step) / Step 4793 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4794 if (!Diff.isUsable()) 4795 return nullptr; 4796 4797 // OpenMP runtime requires 32-bit or 64-bit loop variables. 4798 QualType Type = Diff.get()->getType(); 4799 ASTContext &C = SemaRef.Context; 4800 bool UseVarType = VarType->hasIntegerRepresentation() && 4801 C.getTypeSize(Type) > C.getTypeSize(VarType); 4802 if (!Type->isIntegerType() || UseVarType) { 4803 unsigned NewSize = 4804 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 4805 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 4806 : Type->hasSignedIntegerRepresentation(); 4807 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 4808 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 4809 Diff = SemaRef.PerformImplicitConversion( 4810 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 4811 if (!Diff.isUsable()) 4812 return nullptr; 4813 } 4814 } 4815 if (LimitedType) { 4816 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 4817 if (NewSize != C.getTypeSize(Type)) { 4818 if (NewSize < C.getTypeSize(Type)) { 4819 assert(NewSize == 64 && "incorrect loop var size"); 4820 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 4821 << InitSrcRange << ConditionSrcRange; 4822 } 4823 QualType NewType = C.getIntTypeForBitwidth( 4824 NewSize, Type->hasSignedIntegerRepresentation() || 4825 C.getTypeSize(Type) < NewSize); 4826 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 4827 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 4828 Sema::AA_Converting, true); 4829 if (!Diff.isUsable()) 4830 return nullptr; 4831 } 4832 } 4833 } 4834 4835 return Diff.get(); 4836 } 4837 4838 Expr *OpenMPIterationSpaceChecker::buildPreCond( 4839 Scope *S, Expr *Cond, 4840 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 4841 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 4842 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4843 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4844 4845 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 4846 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 4847 if (!NewLB.isUsable() || !NewUB.isUsable()) 4848 return nullptr; 4849 4850 ExprResult CondExpr = 4851 SemaRef.BuildBinOp(S, DefaultLoc, 4852 TestIsLessOp.getValue() ? 4853 (TestIsStrictOp ? BO_LT : BO_LE) : 4854 (TestIsStrictOp ? BO_GT : BO_GE), 4855 NewLB.get(), NewUB.get()); 4856 if (CondExpr.isUsable()) { 4857 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 4858 SemaRef.Context.BoolTy)) 4859 CondExpr = SemaRef.PerformImplicitConversion( 4860 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 4861 /*AllowExplicit=*/true); 4862 } 4863 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4864 // Otherwise use original loop condition and evaluate it in runtime. 4865 return CondExpr.isUsable() ? CondExpr.get() : Cond; 4866 } 4867 4868 /// Build reference expression to the counter be used for codegen. 4869 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 4870 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4871 DSAStackTy &DSA) const { 4872 auto *VD = dyn_cast<VarDecl>(LCDecl); 4873 if (!VD) { 4874 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 4875 DeclRefExpr *Ref = buildDeclRefExpr( 4876 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 4877 const DSAStackTy::DSAVarData Data = 4878 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 4879 // If the loop control decl is explicitly marked as private, do not mark it 4880 // as captured again. 4881 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 4882 Captures.insert(std::make_pair(LCRef, Ref)); 4883 return Ref; 4884 } 4885 return cast<DeclRefExpr>(LCRef); 4886 } 4887 4888 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 4889 if (LCDecl && !LCDecl->isInvalidDecl()) { 4890 QualType Type = LCDecl->getType().getNonReferenceType(); 4891 VarDecl *PrivateVar = buildVarDecl( 4892 SemaRef, DefaultLoc, Type, LCDecl->getName(), 4893 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 4894 isa<VarDecl>(LCDecl) 4895 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 4896 : nullptr); 4897 if (PrivateVar->isInvalidDecl()) 4898 return nullptr; 4899 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 4900 } 4901 return nullptr; 4902 } 4903 4904 /// Build initialization of the counter to be used for codegen. 4905 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 4906 4907 /// Build step of the counter be used for codegen. 4908 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 4909 4910 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 4911 Scope *S, Expr *Counter, 4912 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 4913 Expr *Inc, OverloadedOperatorKind OOK) { 4914 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 4915 if (!Cnt) 4916 return nullptr; 4917 if (Inc) { 4918 assert((OOK == OO_Plus || OOK == OO_Minus) && 4919 "Expected only + or - operations for depend clauses."); 4920 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 4921 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 4922 if (!Cnt) 4923 return nullptr; 4924 } 4925 ExprResult Diff; 4926 QualType VarType = LCDecl->getType().getNonReferenceType(); 4927 if (VarType->isIntegerType() || VarType->isPointerType() || 4928 SemaRef.getLangOpts().CPlusPlus) { 4929 // Upper - Lower 4930 Expr *Upper = TestIsLessOp.getValue() 4931 ? Cnt 4932 : tryBuildCapture(SemaRef, UB, Captures).get(); 4933 Expr *Lower = TestIsLessOp.getValue() 4934 ? tryBuildCapture(SemaRef, LB, Captures).get() 4935 : Cnt; 4936 if (!Upper || !Lower) 4937 return nullptr; 4938 4939 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4940 4941 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4942 // BuildBinOp already emitted error, this one is to point user to upper 4943 // and lower bound, and to tell what is passed to 'operator-'. 4944 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 4945 << Upper->getSourceRange() << Lower->getSourceRange(); 4946 return nullptr; 4947 } 4948 } 4949 4950 if (!Diff.isUsable()) 4951 return nullptr; 4952 4953 // Parentheses (for dumping/debugging purposes only). 4954 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4955 if (!Diff.isUsable()) 4956 return nullptr; 4957 4958 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 4959 if (!NewStep.isUsable()) 4960 return nullptr; 4961 // (Upper - Lower) / Step 4962 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4963 if (!Diff.isUsable()) 4964 return nullptr; 4965 4966 return Diff.get(); 4967 } 4968 4969 /// Iteration space of a single for loop. 4970 struct LoopIterationSpace final { 4971 /// True if the condition operator is the strict compare operator (<, > or 4972 /// !=). 4973 bool IsStrictCompare = false; 4974 /// Condition of the loop. 4975 Expr *PreCond = nullptr; 4976 /// This expression calculates the number of iterations in the loop. 4977 /// It is always possible to calculate it before starting the loop. 4978 Expr *NumIterations = nullptr; 4979 /// The loop counter variable. 4980 Expr *CounterVar = nullptr; 4981 /// Private loop counter variable. 4982 Expr *PrivateCounterVar = nullptr; 4983 /// This is initializer for the initial value of #CounterVar. 4984 Expr *CounterInit = nullptr; 4985 /// This is step for the #CounterVar used to generate its update: 4986 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4987 Expr *CounterStep = nullptr; 4988 /// Should step be subtracted? 4989 bool Subtract = false; 4990 /// Source range of the loop init. 4991 SourceRange InitSrcRange; 4992 /// Source range of the loop condition. 4993 SourceRange CondSrcRange; 4994 /// Source range of the loop increment. 4995 SourceRange IncSrcRange; 4996 }; 4997 4998 } // namespace 4999 5000 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 5001 assert(getLangOpts().OpenMP && "OpenMP is not active."); 5002 assert(Init && "Expected loop in canonical form."); 5003 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 5004 if (AssociatedLoops > 0 && 5005 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 5006 DSAStack->loopStart(); 5007 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 5008 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 5009 if (ValueDecl *D = ISC.getLoopDecl()) { 5010 auto *VD = dyn_cast<VarDecl>(D); 5011 if (!VD) { 5012 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 5013 VD = Private; 5014 } else { 5015 DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 5016 /*WithInit=*/false); 5017 VD = cast<VarDecl>(Ref->getDecl()); 5018 } 5019 } 5020 DSAStack->addLoopControlVariable(D, VD); 5021 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 5022 if (LD != D->getCanonicalDecl()) { 5023 DSAStack->resetPossibleLoopCounter(); 5024 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 5025 MarkDeclarationsReferencedInExpr( 5026 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 5027 Var->getType().getNonLValueExprType(Context), 5028 ForLoc, /*RefersToCapture=*/true)); 5029 } 5030 } 5031 } 5032 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 5033 } 5034 } 5035 5036 /// Called on a for stmt to check and extract its iteration space 5037 /// for further processing (such as collapsing). 5038 static bool checkOpenMPIterationSpace( 5039 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 5040 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 5041 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 5042 Expr *OrderedLoopCountExpr, 5043 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5044 LoopIterationSpace &ResultIterSpace, 5045 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5046 // OpenMP [2.6, Canonical Loop Form] 5047 // for (init-expr; test-expr; incr-expr) structured-block 5048 auto *For = dyn_cast_or_null<ForStmt>(S); 5049 if (!For) { 5050 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 5051 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 5052 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 5053 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 5054 if (TotalNestedLoopCount > 1) { 5055 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 5056 SemaRef.Diag(DSA.getConstructLoc(), 5057 diag::note_omp_collapse_ordered_expr) 5058 << 2 << CollapseLoopCountExpr->getSourceRange() 5059 << OrderedLoopCountExpr->getSourceRange(); 5060 else if (CollapseLoopCountExpr) 5061 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5062 diag::note_omp_collapse_ordered_expr) 5063 << 0 << CollapseLoopCountExpr->getSourceRange(); 5064 else 5065 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5066 diag::note_omp_collapse_ordered_expr) 5067 << 1 << OrderedLoopCountExpr->getSourceRange(); 5068 } 5069 return true; 5070 } 5071 assert(For->getBody()); 5072 5073 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 5074 5075 // Check init. 5076 Stmt *Init = For->getInit(); 5077 if (ISC.checkAndSetInit(Init)) 5078 return true; 5079 5080 bool HasErrors = false; 5081 5082 // Check loop variable's type. 5083 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 5084 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 5085 5086 // OpenMP [2.6, Canonical Loop Form] 5087 // Var is one of the following: 5088 // A variable of signed or unsigned integer type. 5089 // For C++, a variable of a random access iterator type. 5090 // For C, a variable of a pointer type. 5091 QualType VarType = LCDecl->getType().getNonReferenceType(); 5092 if (!VarType->isDependentType() && !VarType->isIntegerType() && 5093 !VarType->isPointerType() && 5094 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 5095 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 5096 << SemaRef.getLangOpts().CPlusPlus; 5097 HasErrors = true; 5098 } 5099 5100 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 5101 // a Construct 5102 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5103 // parallel for construct is (are) private. 5104 // The loop iteration variable in the associated for-loop of a simd 5105 // construct with just one associated for-loop is linear with a 5106 // constant-linear-step that is the increment of the associated for-loop. 5107 // Exclude loop var from the list of variables with implicitly defined data 5108 // sharing attributes. 5109 VarsWithImplicitDSA.erase(LCDecl); 5110 5111 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 5112 // in a Construct, C/C++]. 5113 // The loop iteration variable in the associated for-loop of a simd 5114 // construct with just one associated for-loop may be listed in a linear 5115 // clause with a constant-linear-step that is the increment of the 5116 // associated for-loop. 5117 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5118 // parallel for construct may be listed in a private or lastprivate clause. 5119 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 5120 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 5121 // declared in the loop and it is predetermined as a private. 5122 OpenMPClauseKind PredeterminedCKind = 5123 isOpenMPSimdDirective(DKind) 5124 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 5125 : OMPC_private; 5126 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5127 DVar.CKind != PredeterminedCKind) || 5128 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 5129 isOpenMPDistributeDirective(DKind)) && 5130 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5131 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 5132 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 5133 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 5134 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 5135 << getOpenMPClauseName(PredeterminedCKind); 5136 if (DVar.RefExpr == nullptr) 5137 DVar.CKind = PredeterminedCKind; 5138 reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 5139 HasErrors = true; 5140 } else if (LoopDeclRefExpr != nullptr) { 5141 // Make the loop iteration variable private (for worksharing constructs), 5142 // linear (for simd directives with the only one associated loop) or 5143 // lastprivate (for simd directives with several collapsed or ordered 5144 // loops). 5145 if (DVar.CKind == OMPC_unknown) 5146 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 5147 } 5148 5149 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 5150 5151 // Check test-expr. 5152 HasErrors |= ISC.checkAndSetCond(For->getCond()); 5153 5154 // Check incr-expr. 5155 HasErrors |= ISC.checkAndSetInc(For->getInc()); 5156 } 5157 5158 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 5159 return HasErrors; 5160 5161 // Build the loop's iteration space representation. 5162 ResultIterSpace.PreCond = 5163 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 5164 ResultIterSpace.NumIterations = ISC.buildNumIterations( 5165 DSA.getCurScope(), 5166 (isOpenMPWorksharingDirective(DKind) || 5167 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 5168 Captures); 5169 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA); 5170 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar(); 5171 ResultIterSpace.CounterInit = ISC.buildCounterInit(); 5172 ResultIterSpace.CounterStep = ISC.buildCounterStep(); 5173 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange(); 5174 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange(); 5175 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange(); 5176 ResultIterSpace.Subtract = ISC.shouldSubtractStep(); 5177 ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp(); 5178 5179 HasErrors |= (ResultIterSpace.PreCond == nullptr || 5180 ResultIterSpace.NumIterations == nullptr || 5181 ResultIterSpace.CounterVar == nullptr || 5182 ResultIterSpace.PrivateCounterVar == nullptr || 5183 ResultIterSpace.CounterInit == nullptr || 5184 ResultIterSpace.CounterStep == nullptr); 5185 if (!HasErrors && DSA.isOrderedRegion()) { 5186 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 5187 if (CurrentNestedLoopCount < 5188 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 5189 DSA.getOrderedRegionParam().second->setLoopNumIterations( 5190 CurrentNestedLoopCount, ResultIterSpace.NumIterations); 5191 DSA.getOrderedRegionParam().second->setLoopCounter( 5192 CurrentNestedLoopCount, ResultIterSpace.CounterVar); 5193 } 5194 } 5195 for (auto &Pair : DSA.getDoacrossDependClauses()) { 5196 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 5197 // Erroneous case - clause has some problems. 5198 continue; 5199 } 5200 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 5201 Pair.second.size() <= CurrentNestedLoopCount) { 5202 // Erroneous case - clause has some problems. 5203 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 5204 continue; 5205 } 5206 Expr *CntValue; 5207 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 5208 CntValue = ISC.buildOrderedLoopData( 5209 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5210 Pair.first->getDependencyLoc()); 5211 else 5212 CntValue = ISC.buildOrderedLoopData( 5213 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5214 Pair.first->getDependencyLoc(), 5215 Pair.second[CurrentNestedLoopCount].first, 5216 Pair.second[CurrentNestedLoopCount].second); 5217 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 5218 } 5219 } 5220 5221 return HasErrors; 5222 } 5223 5224 /// Build 'VarRef = Start. 5225 static ExprResult 5226 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5227 ExprResult Start, 5228 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5229 // Build 'VarRef = Start. 5230 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 5231 if (!NewStart.isUsable()) 5232 return ExprError(); 5233 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 5234 VarRef.get()->getType())) { 5235 NewStart = SemaRef.PerformImplicitConversion( 5236 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 5237 /*AllowExplicit=*/true); 5238 if (!NewStart.isUsable()) 5239 return ExprError(); 5240 } 5241 5242 ExprResult Init = 5243 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5244 return Init; 5245 } 5246 5247 /// Build 'VarRef = Start + Iter * Step'. 5248 static ExprResult buildCounterUpdate( 5249 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5250 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 5251 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 5252 // Add parentheses (for debugging purposes only). 5253 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 5254 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 5255 !Step.isUsable()) 5256 return ExprError(); 5257 5258 ExprResult NewStep = Step; 5259 if (Captures) 5260 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 5261 if (NewStep.isInvalid()) 5262 return ExprError(); 5263 ExprResult Update = 5264 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 5265 if (!Update.isUsable()) 5266 return ExprError(); 5267 5268 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 5269 // 'VarRef = Start (+|-) Iter * Step'. 5270 ExprResult NewStart = Start; 5271 if (Captures) 5272 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 5273 if (NewStart.isInvalid()) 5274 return ExprError(); 5275 5276 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 5277 ExprResult SavedUpdate = Update; 5278 ExprResult UpdateVal; 5279 if (VarRef.get()->getType()->isOverloadableType() || 5280 NewStart.get()->getType()->isOverloadableType() || 5281 Update.get()->getType()->isOverloadableType()) { 5282 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5283 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5284 Update = 5285 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5286 if (Update.isUsable()) { 5287 UpdateVal = 5288 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 5289 VarRef.get(), SavedUpdate.get()); 5290 if (UpdateVal.isUsable()) { 5291 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 5292 UpdateVal.get()); 5293 } 5294 } 5295 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5296 } 5297 5298 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 5299 if (!Update.isUsable() || !UpdateVal.isUsable()) { 5300 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 5301 NewStart.get(), SavedUpdate.get()); 5302 if (!Update.isUsable()) 5303 return ExprError(); 5304 5305 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 5306 VarRef.get()->getType())) { 5307 Update = SemaRef.PerformImplicitConversion( 5308 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 5309 if (!Update.isUsable()) 5310 return ExprError(); 5311 } 5312 5313 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 5314 } 5315 return Update; 5316 } 5317 5318 /// Convert integer expression \a E to make it have at least \a Bits 5319 /// bits. 5320 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 5321 if (E == nullptr) 5322 return ExprError(); 5323 ASTContext &C = SemaRef.Context; 5324 QualType OldType = E->getType(); 5325 unsigned HasBits = C.getTypeSize(OldType); 5326 if (HasBits >= Bits) 5327 return ExprResult(E); 5328 // OK to convert to signed, because new type has more bits than old. 5329 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 5330 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 5331 true); 5332 } 5333 5334 /// Check if the given expression \a E is a constant integer that fits 5335 /// into \a Bits bits. 5336 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 5337 if (E == nullptr) 5338 return false; 5339 llvm::APSInt Result; 5340 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 5341 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 5342 return false; 5343 } 5344 5345 /// Build preinits statement for the given declarations. 5346 static Stmt *buildPreInits(ASTContext &Context, 5347 MutableArrayRef<Decl *> PreInits) { 5348 if (!PreInits.empty()) { 5349 return new (Context) DeclStmt( 5350 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 5351 SourceLocation(), SourceLocation()); 5352 } 5353 return nullptr; 5354 } 5355 5356 /// Build preinits statement for the given declarations. 5357 static Stmt * 5358 buildPreInits(ASTContext &Context, 5359 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5360 if (!Captures.empty()) { 5361 SmallVector<Decl *, 16> PreInits; 5362 for (const auto &Pair : Captures) 5363 PreInits.push_back(Pair.second->getDecl()); 5364 return buildPreInits(Context, PreInits); 5365 } 5366 return nullptr; 5367 } 5368 5369 /// Build postupdate expression for the given list of postupdates expressions. 5370 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 5371 Expr *PostUpdate = nullptr; 5372 if (!PostUpdates.empty()) { 5373 for (Expr *E : PostUpdates) { 5374 Expr *ConvE = S.BuildCStyleCastExpr( 5375 E->getExprLoc(), 5376 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 5377 E->getExprLoc(), E) 5378 .get(); 5379 PostUpdate = PostUpdate 5380 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 5381 PostUpdate, ConvE) 5382 .get() 5383 : ConvE; 5384 } 5385 } 5386 return PostUpdate; 5387 } 5388 5389 /// Called on a for stmt to check itself and nested loops (if any). 5390 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 5391 /// number of collapsed loops otherwise. 5392 static unsigned 5393 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 5394 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 5395 DSAStackTy &DSA, 5396 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5397 OMPLoopDirective::HelperExprs &Built) { 5398 unsigned NestedLoopCount = 1; 5399 if (CollapseLoopCountExpr) { 5400 // Found 'collapse' clause - calculate collapse number. 5401 Expr::EvalResult Result; 5402 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 5403 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 5404 } 5405 unsigned OrderedLoopCount = 1; 5406 if (OrderedLoopCountExpr) { 5407 // Found 'ordered' clause - calculate collapse number. 5408 Expr::EvalResult EVResult; 5409 if (OrderedLoopCountExpr->EvaluateAsInt(EVResult, SemaRef.getASTContext())) { 5410 llvm::APSInt Result = EVResult.Val.getInt(); 5411 if (Result.getLimitedValue() < NestedLoopCount) { 5412 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5413 diag::err_omp_wrong_ordered_loop_count) 5414 << OrderedLoopCountExpr->getSourceRange(); 5415 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5416 diag::note_collapse_loop_count) 5417 << CollapseLoopCountExpr->getSourceRange(); 5418 } 5419 OrderedLoopCount = Result.getLimitedValue(); 5420 } 5421 } 5422 // This is helper routine for loop directives (e.g., 'for', 'simd', 5423 // 'for simd', etc.). 5424 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 5425 SmallVector<LoopIterationSpace, 4> IterSpaces( 5426 std::max(OrderedLoopCount, NestedLoopCount)); 5427 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 5428 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 5429 if (checkOpenMPIterationSpace( 5430 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 5431 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 5432 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 5433 Captures)) 5434 return 0; 5435 // Move on to the next nested for loop, or to the loop body. 5436 // OpenMP [2.8.1, simd construct, Restrictions] 5437 // All loops associated with the construct must be perfectly nested; that 5438 // is, there must be no intervening code nor any OpenMP directive between 5439 // any two loops. 5440 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 5441 } 5442 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 5443 if (checkOpenMPIterationSpace( 5444 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 5445 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 5446 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 5447 Captures)) 5448 return 0; 5449 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 5450 // Handle initialization of captured loop iterator variables. 5451 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 5452 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 5453 Captures[DRE] = DRE; 5454 } 5455 } 5456 // Move on to the next nested for loop, or to the loop body. 5457 // OpenMP [2.8.1, simd construct, Restrictions] 5458 // All loops associated with the construct must be perfectly nested; that 5459 // is, there must be no intervening code nor any OpenMP directive between 5460 // any two loops. 5461 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 5462 } 5463 5464 Built.clear(/* size */ NestedLoopCount); 5465 5466 if (SemaRef.CurContext->isDependentContext()) 5467 return NestedLoopCount; 5468 5469 // An example of what is generated for the following code: 5470 // 5471 // #pragma omp simd collapse(2) ordered(2) 5472 // for (i = 0; i < NI; ++i) 5473 // for (k = 0; k < NK; ++k) 5474 // for (j = J0; j < NJ; j+=2) { 5475 // <loop body> 5476 // } 5477 // 5478 // We generate the code below. 5479 // Note: the loop body may be outlined in CodeGen. 5480 // Note: some counters may be C++ classes, operator- is used to find number of 5481 // iterations and operator+= to calculate counter value. 5482 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 5483 // or i64 is currently supported). 5484 // 5485 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 5486 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 5487 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 5488 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 5489 // // similar updates for vars in clauses (e.g. 'linear') 5490 // <loop body (using local i and j)> 5491 // } 5492 // i = NI; // assign final values of counters 5493 // j = NJ; 5494 // 5495 5496 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 5497 // the iteration counts of the collapsed for loops. 5498 // Precondition tests if there is at least one iteration (all conditions are 5499 // true). 5500 auto PreCond = ExprResult(IterSpaces[0].PreCond); 5501 Expr *N0 = IterSpaces[0].NumIterations; 5502 ExprResult LastIteration32 = 5503 widenIterationCount(/*Bits=*/32, 5504 SemaRef 5505 .PerformImplicitConversion( 5506 N0->IgnoreImpCasts(), N0->getType(), 5507 Sema::AA_Converting, /*AllowExplicit=*/true) 5508 .get(), 5509 SemaRef); 5510 ExprResult LastIteration64 = widenIterationCount( 5511 /*Bits=*/64, 5512 SemaRef 5513 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 5514 Sema::AA_Converting, 5515 /*AllowExplicit=*/true) 5516 .get(), 5517 SemaRef); 5518 5519 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 5520 return NestedLoopCount; 5521 5522 ASTContext &C = SemaRef.Context; 5523 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 5524 5525 Scope *CurScope = DSA.getCurScope(); 5526 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 5527 if (PreCond.isUsable()) { 5528 PreCond = 5529 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 5530 PreCond.get(), IterSpaces[Cnt].PreCond); 5531 } 5532 Expr *N = IterSpaces[Cnt].NumIterations; 5533 SourceLocation Loc = N->getExprLoc(); 5534 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 5535 if (LastIteration32.isUsable()) 5536 LastIteration32 = SemaRef.BuildBinOp( 5537 CurScope, Loc, BO_Mul, LastIteration32.get(), 5538 SemaRef 5539 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5540 Sema::AA_Converting, 5541 /*AllowExplicit=*/true) 5542 .get()); 5543 if (LastIteration64.isUsable()) 5544 LastIteration64 = SemaRef.BuildBinOp( 5545 CurScope, Loc, BO_Mul, LastIteration64.get(), 5546 SemaRef 5547 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5548 Sema::AA_Converting, 5549 /*AllowExplicit=*/true) 5550 .get()); 5551 } 5552 5553 // Choose either the 32-bit or 64-bit version. 5554 ExprResult LastIteration = LastIteration64; 5555 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 5556 (LastIteration32.isUsable() && 5557 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 5558 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 5559 fitsInto( 5560 /*Bits=*/32, 5561 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 5562 LastIteration64.get(), SemaRef)))) 5563 LastIteration = LastIteration32; 5564 QualType VType = LastIteration.get()->getType(); 5565 QualType RealVType = VType; 5566 QualType StrideVType = VType; 5567 if (isOpenMPTaskLoopDirective(DKind)) { 5568 VType = 5569 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 5570 StrideVType = 5571 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 5572 } 5573 5574 if (!LastIteration.isUsable()) 5575 return 0; 5576 5577 // Save the number of iterations. 5578 ExprResult NumIterations = LastIteration; 5579 { 5580 LastIteration = SemaRef.BuildBinOp( 5581 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 5582 LastIteration.get(), 5583 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5584 if (!LastIteration.isUsable()) 5585 return 0; 5586 } 5587 5588 // Calculate the last iteration number beforehand instead of doing this on 5589 // each iteration. Do not do this if the number of iterations may be kfold-ed. 5590 llvm::APSInt Result; 5591 bool IsConstant = 5592 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 5593 ExprResult CalcLastIteration; 5594 if (!IsConstant) { 5595 ExprResult SaveRef = 5596 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 5597 LastIteration = SaveRef; 5598 5599 // Prepare SaveRef + 1. 5600 NumIterations = SemaRef.BuildBinOp( 5601 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 5602 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5603 if (!NumIterations.isUsable()) 5604 return 0; 5605 } 5606 5607 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 5608 5609 // Build variables passed into runtime, necessary for worksharing directives. 5610 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 5611 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5612 isOpenMPDistributeDirective(DKind)) { 5613 // Lower bound variable, initialized with zero. 5614 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 5615 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 5616 SemaRef.AddInitializerToDecl(LBDecl, 5617 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5618 /*DirectInit*/ false); 5619 5620 // Upper bound variable, initialized with last iteration number. 5621 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 5622 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 5623 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 5624 /*DirectInit*/ false); 5625 5626 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 5627 // This will be used to implement clause 'lastprivate'. 5628 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 5629 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 5630 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 5631 SemaRef.AddInitializerToDecl(ILDecl, 5632 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5633 /*DirectInit*/ false); 5634 5635 // Stride variable returned by runtime (we initialize it to 1 by default). 5636 VarDecl *STDecl = 5637 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 5638 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 5639 SemaRef.AddInitializerToDecl(STDecl, 5640 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 5641 /*DirectInit*/ false); 5642 5643 // Build expression: UB = min(UB, LastIteration) 5644 // It is necessary for CodeGen of directives with static scheduling. 5645 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 5646 UB.get(), LastIteration.get()); 5647 ExprResult CondOp = SemaRef.ActOnConditionalOp( 5648 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 5649 LastIteration.get(), UB.get()); 5650 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 5651 CondOp.get()); 5652 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 5653 5654 // If we have a combined directive that combines 'distribute', 'for' or 5655 // 'simd' we need to be able to access the bounds of the schedule of the 5656 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 5657 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 5658 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5659 // Lower bound variable, initialized with zero. 5660 VarDecl *CombLBDecl = 5661 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 5662 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 5663 SemaRef.AddInitializerToDecl( 5664 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5665 /*DirectInit*/ false); 5666 5667 // Upper bound variable, initialized with last iteration number. 5668 VarDecl *CombUBDecl = 5669 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 5670 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 5671 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 5672 /*DirectInit*/ false); 5673 5674 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 5675 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 5676 ExprResult CombCondOp = 5677 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 5678 LastIteration.get(), CombUB.get()); 5679 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 5680 CombCondOp.get()); 5681 CombEUB = 5682 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 5683 5684 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 5685 // We expect to have at least 2 more parameters than the 'parallel' 5686 // directive does - the lower and upper bounds of the previous schedule. 5687 assert(CD->getNumParams() >= 4 && 5688 "Unexpected number of parameters in loop combined directive"); 5689 5690 // Set the proper type for the bounds given what we learned from the 5691 // enclosed loops. 5692 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 5693 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 5694 5695 // Previous lower and upper bounds are obtained from the region 5696 // parameters. 5697 PrevLB = 5698 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 5699 PrevUB = 5700 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 5701 } 5702 } 5703 5704 // Build the iteration variable and its initialization before loop. 5705 ExprResult IV; 5706 ExprResult Init, CombInit; 5707 { 5708 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 5709 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 5710 Expr *RHS = 5711 (isOpenMPWorksharingDirective(DKind) || 5712 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5713 ? LB.get() 5714 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 5715 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 5716 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 5717 5718 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5719 Expr *CombRHS = 5720 (isOpenMPWorksharingDirective(DKind) || 5721 isOpenMPTaskLoopDirective(DKind) || 5722 isOpenMPDistributeDirective(DKind)) 5723 ? CombLB.get() 5724 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 5725 CombInit = 5726 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 5727 CombInit = 5728 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 5729 } 5730 } 5731 5732 bool UseStrictCompare = 5733 RealVType->hasUnsignedIntegerRepresentation() && 5734 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 5735 return LIS.IsStrictCompare; 5736 }); 5737 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 5738 // unsigned IV)) for worksharing loops. 5739 SourceLocation CondLoc = AStmt->getBeginLoc(); 5740 Expr *BoundUB = UB.get(); 5741 if (UseStrictCompare) { 5742 BoundUB = 5743 SemaRef 5744 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 5745 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 5746 .get(); 5747 BoundUB = 5748 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 5749 } 5750 ExprResult Cond = 5751 (isOpenMPWorksharingDirective(DKind) || 5752 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5753 ? SemaRef.BuildBinOp(CurScope, CondLoc, 5754 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 5755 BoundUB) 5756 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 5757 NumIterations.get()); 5758 ExprResult CombDistCond; 5759 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5760 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 5761 NumIterations.get()); 5762 } 5763 5764 ExprResult CombCond; 5765 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5766 Expr *BoundCombUB = CombUB.get(); 5767 if (UseStrictCompare) { 5768 BoundCombUB = 5769 SemaRef 5770 .BuildBinOp( 5771 CurScope, CondLoc, BO_Add, BoundCombUB, 5772 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 5773 .get(); 5774 BoundCombUB = 5775 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 5776 .get(); 5777 } 5778 CombCond = 5779 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 5780 IV.get(), BoundCombUB); 5781 } 5782 // Loop increment (IV = IV + 1) 5783 SourceLocation IncLoc = AStmt->getBeginLoc(); 5784 ExprResult Inc = 5785 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 5786 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 5787 if (!Inc.isUsable()) 5788 return 0; 5789 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 5790 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 5791 if (!Inc.isUsable()) 5792 return 0; 5793 5794 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 5795 // Used for directives with static scheduling. 5796 // In combined construct, add combined version that use CombLB and CombUB 5797 // base variables for the update 5798 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 5799 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5800 isOpenMPDistributeDirective(DKind)) { 5801 // LB + ST 5802 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 5803 if (!NextLB.isUsable()) 5804 return 0; 5805 // LB = LB + ST 5806 NextLB = 5807 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 5808 NextLB = 5809 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 5810 if (!NextLB.isUsable()) 5811 return 0; 5812 // UB + ST 5813 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 5814 if (!NextUB.isUsable()) 5815 return 0; 5816 // UB = UB + ST 5817 NextUB = 5818 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 5819 NextUB = 5820 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 5821 if (!NextUB.isUsable()) 5822 return 0; 5823 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5824 CombNextLB = 5825 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 5826 if (!NextLB.isUsable()) 5827 return 0; 5828 // LB = LB + ST 5829 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 5830 CombNextLB.get()); 5831 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 5832 /*DiscardedValue*/ false); 5833 if (!CombNextLB.isUsable()) 5834 return 0; 5835 // UB + ST 5836 CombNextUB = 5837 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 5838 if (!CombNextUB.isUsable()) 5839 return 0; 5840 // UB = UB + ST 5841 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 5842 CombNextUB.get()); 5843 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 5844 /*DiscardedValue*/ false); 5845 if (!CombNextUB.isUsable()) 5846 return 0; 5847 } 5848 } 5849 5850 // Create increment expression for distribute loop when combined in a same 5851 // directive with for as IV = IV + ST; ensure upper bound expression based 5852 // on PrevUB instead of NumIterations - used to implement 'for' when found 5853 // in combination with 'distribute', like in 'distribute parallel for' 5854 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 5855 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 5856 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5857 DistCond = SemaRef.BuildBinOp( 5858 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 5859 assert(DistCond.isUsable() && "distribute cond expr was not built"); 5860 5861 DistInc = 5862 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 5863 assert(DistInc.isUsable() && "distribute inc expr was not built"); 5864 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 5865 DistInc.get()); 5866 DistInc = 5867 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 5868 assert(DistInc.isUsable() && "distribute inc expr was not built"); 5869 5870 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 5871 // construct 5872 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 5873 ExprResult IsUBGreater = 5874 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 5875 ExprResult CondOp = SemaRef.ActOnConditionalOp( 5876 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 5877 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 5878 CondOp.get()); 5879 PrevEUB = 5880 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 5881 5882 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 5883 // parallel for is in combination with a distribute directive with 5884 // schedule(static, 1) 5885 Expr *BoundPrevUB = PrevUB.get(); 5886 if (UseStrictCompare) { 5887 BoundPrevUB = 5888 SemaRef 5889 .BuildBinOp( 5890 CurScope, CondLoc, BO_Add, BoundPrevUB, 5891 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 5892 .get(); 5893 BoundPrevUB = 5894 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 5895 .get(); 5896 } 5897 ParForInDistCond = 5898 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 5899 IV.get(), BoundPrevUB); 5900 } 5901 5902 // Build updates and final values of the loop counters. 5903 bool HasErrors = false; 5904 Built.Counters.resize(NestedLoopCount); 5905 Built.Inits.resize(NestedLoopCount); 5906 Built.Updates.resize(NestedLoopCount); 5907 Built.Finals.resize(NestedLoopCount); 5908 { 5909 // We implement the following algorithm for obtaining the 5910 // original loop iteration variable values based on the 5911 // value of the collapsed loop iteration variable IV. 5912 // 5913 // Let n+1 be the number of collapsed loops in the nest. 5914 // Iteration variables (I0, I1, .... In) 5915 // Iteration counts (N0, N1, ... Nn) 5916 // 5917 // Acc = IV; 5918 // 5919 // To compute Ik for loop k, 0 <= k <= n, generate: 5920 // Prod = N(k+1) * N(k+2) * ... * Nn; 5921 // Ik = Acc / Prod; 5922 // Acc -= Ik * Prod; 5923 // 5924 ExprResult Acc = IV; 5925 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 5926 LoopIterationSpace &IS = IterSpaces[Cnt]; 5927 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 5928 ExprResult Iter; 5929 5930 // Compute prod 5931 ExprResult Prod = 5932 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 5933 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 5934 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 5935 IterSpaces[K].NumIterations); 5936 5937 // Iter = Acc / Prod 5938 // If there is at least one more inner loop to avoid 5939 // multiplication by 1. 5940 if (Cnt + 1 < NestedLoopCount) 5941 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 5942 Acc.get(), Prod.get()); 5943 else 5944 Iter = Acc; 5945 if (!Iter.isUsable()) { 5946 HasErrors = true; 5947 break; 5948 } 5949 5950 // Update Acc: 5951 // Acc -= Iter * Prod 5952 // Check if there is at least one more inner loop to avoid 5953 // multiplication by 1. 5954 if (Cnt + 1 < NestedLoopCount) 5955 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 5956 Iter.get(), Prod.get()); 5957 else 5958 Prod = Iter; 5959 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 5960 Acc.get(), Prod.get()); 5961 5962 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 5963 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 5964 DeclRefExpr *CounterVar = buildDeclRefExpr( 5965 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 5966 /*RefersToCapture=*/true); 5967 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 5968 IS.CounterInit, Captures); 5969 if (!Init.isUsable()) { 5970 HasErrors = true; 5971 break; 5972 } 5973 ExprResult Update = buildCounterUpdate( 5974 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 5975 IS.CounterStep, IS.Subtract, &Captures); 5976 if (!Update.isUsable()) { 5977 HasErrors = true; 5978 break; 5979 } 5980 5981 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 5982 ExprResult Final = buildCounterUpdate( 5983 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 5984 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 5985 if (!Final.isUsable()) { 5986 HasErrors = true; 5987 break; 5988 } 5989 5990 if (!Update.isUsable() || !Final.isUsable()) { 5991 HasErrors = true; 5992 break; 5993 } 5994 // Save results 5995 Built.Counters[Cnt] = IS.CounterVar; 5996 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 5997 Built.Inits[Cnt] = Init.get(); 5998 Built.Updates[Cnt] = Update.get(); 5999 Built.Finals[Cnt] = Final.get(); 6000 } 6001 } 6002 6003 if (HasErrors) 6004 return 0; 6005 6006 // Save results 6007 Built.IterationVarRef = IV.get(); 6008 Built.LastIteration = LastIteration.get(); 6009 Built.NumIterations = NumIterations.get(); 6010 Built.CalcLastIteration = SemaRef 6011 .ActOnFinishFullExpr(CalcLastIteration.get(), 6012 /*DiscardedValue*/ false) 6013 .get(); 6014 Built.PreCond = PreCond.get(); 6015 Built.PreInits = buildPreInits(C, Captures); 6016 Built.Cond = Cond.get(); 6017 Built.Init = Init.get(); 6018 Built.Inc = Inc.get(); 6019 Built.LB = LB.get(); 6020 Built.UB = UB.get(); 6021 Built.IL = IL.get(); 6022 Built.ST = ST.get(); 6023 Built.EUB = EUB.get(); 6024 Built.NLB = NextLB.get(); 6025 Built.NUB = NextUB.get(); 6026 Built.PrevLB = PrevLB.get(); 6027 Built.PrevUB = PrevUB.get(); 6028 Built.DistInc = DistInc.get(); 6029 Built.PrevEUB = PrevEUB.get(); 6030 Built.DistCombinedFields.LB = CombLB.get(); 6031 Built.DistCombinedFields.UB = CombUB.get(); 6032 Built.DistCombinedFields.EUB = CombEUB.get(); 6033 Built.DistCombinedFields.Init = CombInit.get(); 6034 Built.DistCombinedFields.Cond = CombCond.get(); 6035 Built.DistCombinedFields.NLB = CombNextLB.get(); 6036 Built.DistCombinedFields.NUB = CombNextUB.get(); 6037 Built.DistCombinedFields.DistCond = CombDistCond.get(); 6038 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 6039 6040 return NestedLoopCount; 6041 } 6042 6043 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 6044 auto CollapseClauses = 6045 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 6046 if (CollapseClauses.begin() != CollapseClauses.end()) 6047 return (*CollapseClauses.begin())->getNumForLoops(); 6048 return nullptr; 6049 } 6050 6051 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 6052 auto OrderedClauses = 6053 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 6054 if (OrderedClauses.begin() != OrderedClauses.end()) 6055 return (*OrderedClauses.begin())->getNumForLoops(); 6056 return nullptr; 6057 } 6058 6059 static bool checkSimdlenSafelenSpecified(Sema &S, 6060 const ArrayRef<OMPClause *> Clauses) { 6061 const OMPSafelenClause *Safelen = nullptr; 6062 const OMPSimdlenClause *Simdlen = nullptr; 6063 6064 for (const OMPClause *Clause : Clauses) { 6065 if (Clause->getClauseKind() == OMPC_safelen) 6066 Safelen = cast<OMPSafelenClause>(Clause); 6067 else if (Clause->getClauseKind() == OMPC_simdlen) 6068 Simdlen = cast<OMPSimdlenClause>(Clause); 6069 if (Safelen && Simdlen) 6070 break; 6071 } 6072 6073 if (Simdlen && Safelen) { 6074 const Expr *SimdlenLength = Simdlen->getSimdlen(); 6075 const Expr *SafelenLength = Safelen->getSafelen(); 6076 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 6077 SimdlenLength->isInstantiationDependent() || 6078 SimdlenLength->containsUnexpandedParameterPack()) 6079 return false; 6080 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 6081 SafelenLength->isInstantiationDependent() || 6082 SafelenLength->containsUnexpandedParameterPack()) 6083 return false; 6084 Expr::EvalResult SimdlenResult, SafelenResult; 6085 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 6086 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 6087 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 6088 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 6089 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 6090 // If both simdlen and safelen clauses are specified, the value of the 6091 // simdlen parameter must be less than or equal to the value of the safelen 6092 // parameter. 6093 if (SimdlenRes > SafelenRes) { 6094 S.Diag(SimdlenLength->getExprLoc(), 6095 diag::err_omp_wrong_simdlen_safelen_values) 6096 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 6097 return true; 6098 } 6099 } 6100 return false; 6101 } 6102 6103 StmtResult 6104 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6105 SourceLocation StartLoc, SourceLocation EndLoc, 6106 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6107 if (!AStmt) 6108 return StmtError(); 6109 6110 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6111 OMPLoopDirective::HelperExprs B; 6112 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6113 // define the nested loops number. 6114 unsigned NestedLoopCount = checkOpenMPLoop( 6115 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6116 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6117 if (NestedLoopCount == 0) 6118 return StmtError(); 6119 6120 assert((CurContext->isDependentContext() || B.builtAll()) && 6121 "omp simd loop exprs were not built"); 6122 6123 if (!CurContext->isDependentContext()) { 6124 // Finalize the clauses that need pre-built expressions for CodeGen. 6125 for (OMPClause *C : Clauses) { 6126 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6127 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6128 B.NumIterations, *this, CurScope, 6129 DSAStack)) 6130 return StmtError(); 6131 } 6132 } 6133 6134 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6135 return StmtError(); 6136 6137 setFunctionHasBranchProtectedScope(); 6138 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6139 Clauses, AStmt, B); 6140 } 6141 6142 StmtResult 6143 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6144 SourceLocation StartLoc, SourceLocation EndLoc, 6145 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6146 if (!AStmt) 6147 return StmtError(); 6148 6149 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6150 OMPLoopDirective::HelperExprs B; 6151 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6152 // define the nested loops number. 6153 unsigned NestedLoopCount = checkOpenMPLoop( 6154 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6155 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6156 if (NestedLoopCount == 0) 6157 return StmtError(); 6158 6159 assert((CurContext->isDependentContext() || B.builtAll()) && 6160 "omp for loop exprs were not built"); 6161 6162 if (!CurContext->isDependentContext()) { 6163 // Finalize the clauses that need pre-built expressions for CodeGen. 6164 for (OMPClause *C : Clauses) { 6165 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6166 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6167 B.NumIterations, *this, CurScope, 6168 DSAStack)) 6169 return StmtError(); 6170 } 6171 } 6172 6173 setFunctionHasBranchProtectedScope(); 6174 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6175 Clauses, AStmt, B, DSAStack->isCancelRegion()); 6176 } 6177 6178 StmtResult Sema::ActOnOpenMPForSimdDirective( 6179 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6180 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6181 if (!AStmt) 6182 return StmtError(); 6183 6184 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6185 OMPLoopDirective::HelperExprs B; 6186 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6187 // define the nested loops number. 6188 unsigned NestedLoopCount = 6189 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 6190 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6191 VarsWithImplicitDSA, B); 6192 if (NestedLoopCount == 0) 6193 return StmtError(); 6194 6195 assert((CurContext->isDependentContext() || B.builtAll()) && 6196 "omp for simd loop exprs were not built"); 6197 6198 if (!CurContext->isDependentContext()) { 6199 // Finalize the clauses that need pre-built expressions for CodeGen. 6200 for (OMPClause *C : Clauses) { 6201 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6202 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6203 B.NumIterations, *this, CurScope, 6204 DSAStack)) 6205 return StmtError(); 6206 } 6207 } 6208 6209 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6210 return StmtError(); 6211 6212 setFunctionHasBranchProtectedScope(); 6213 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6214 Clauses, AStmt, B); 6215 } 6216 6217 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 6218 Stmt *AStmt, 6219 SourceLocation StartLoc, 6220 SourceLocation EndLoc) { 6221 if (!AStmt) 6222 return StmtError(); 6223 6224 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6225 auto BaseStmt = AStmt; 6226 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6227 BaseStmt = CS->getCapturedStmt(); 6228 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6229 auto S = C->children(); 6230 if (S.begin() == S.end()) 6231 return StmtError(); 6232 // All associated statements must be '#pragma omp section' except for 6233 // the first one. 6234 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6235 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6236 if (SectionStmt) 6237 Diag(SectionStmt->getBeginLoc(), 6238 diag::err_omp_sections_substmt_not_section); 6239 return StmtError(); 6240 } 6241 cast<OMPSectionDirective>(SectionStmt) 6242 ->setHasCancel(DSAStack->isCancelRegion()); 6243 } 6244 } else { 6245 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 6246 return StmtError(); 6247 } 6248 6249 setFunctionHasBranchProtectedScope(); 6250 6251 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6252 DSAStack->isCancelRegion()); 6253 } 6254 6255 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 6256 SourceLocation StartLoc, 6257 SourceLocation EndLoc) { 6258 if (!AStmt) 6259 return StmtError(); 6260 6261 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6262 6263 setFunctionHasBranchProtectedScope(); 6264 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 6265 6266 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 6267 DSAStack->isCancelRegion()); 6268 } 6269 6270 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 6271 Stmt *AStmt, 6272 SourceLocation StartLoc, 6273 SourceLocation EndLoc) { 6274 if (!AStmt) 6275 return StmtError(); 6276 6277 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6278 6279 setFunctionHasBranchProtectedScope(); 6280 6281 // OpenMP [2.7.3, single Construct, Restrictions] 6282 // The copyprivate clause must not be used with the nowait clause. 6283 const OMPClause *Nowait = nullptr; 6284 const OMPClause *Copyprivate = nullptr; 6285 for (const OMPClause *Clause : Clauses) { 6286 if (Clause->getClauseKind() == OMPC_nowait) 6287 Nowait = Clause; 6288 else if (Clause->getClauseKind() == OMPC_copyprivate) 6289 Copyprivate = Clause; 6290 if (Copyprivate && Nowait) { 6291 Diag(Copyprivate->getBeginLoc(), 6292 diag::err_omp_single_copyprivate_with_nowait); 6293 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 6294 return StmtError(); 6295 } 6296 } 6297 6298 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6299 } 6300 6301 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 6302 SourceLocation StartLoc, 6303 SourceLocation EndLoc) { 6304 if (!AStmt) 6305 return StmtError(); 6306 6307 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6308 6309 setFunctionHasBranchProtectedScope(); 6310 6311 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 6312 } 6313 6314 StmtResult Sema::ActOnOpenMPCriticalDirective( 6315 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 6316 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 6317 if (!AStmt) 6318 return StmtError(); 6319 6320 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6321 6322 bool ErrorFound = false; 6323 llvm::APSInt Hint; 6324 SourceLocation HintLoc; 6325 bool DependentHint = false; 6326 for (const OMPClause *C : Clauses) { 6327 if (C->getClauseKind() == OMPC_hint) { 6328 if (!DirName.getName()) { 6329 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 6330 ErrorFound = true; 6331 } 6332 Expr *E = cast<OMPHintClause>(C)->getHint(); 6333 if (E->isTypeDependent() || E->isValueDependent() || 6334 E->isInstantiationDependent()) { 6335 DependentHint = true; 6336 } else { 6337 Hint = E->EvaluateKnownConstInt(Context); 6338 HintLoc = C->getBeginLoc(); 6339 } 6340 } 6341 } 6342 if (ErrorFound) 6343 return StmtError(); 6344 const auto Pair = DSAStack->getCriticalWithHint(DirName); 6345 if (Pair.first && DirName.getName() && !DependentHint) { 6346 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 6347 Diag(StartLoc, diag::err_omp_critical_with_hint); 6348 if (HintLoc.isValid()) 6349 Diag(HintLoc, diag::note_omp_critical_hint_here) 6350 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 6351 else 6352 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 6353 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 6354 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 6355 << 1 6356 << C->getHint()->EvaluateKnownConstInt(Context).toString( 6357 /*Radix=*/10, /*Signed=*/false); 6358 } else { 6359 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 6360 } 6361 } 6362 } 6363 6364 setFunctionHasBranchProtectedScope(); 6365 6366 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 6367 Clauses, AStmt); 6368 if (!Pair.first && DirName.getName() && !DependentHint) 6369 DSAStack->addCriticalWithHint(Dir, Hint); 6370 return Dir; 6371 } 6372 6373 StmtResult Sema::ActOnOpenMPParallelForDirective( 6374 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6375 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6376 if (!AStmt) 6377 return StmtError(); 6378 6379 auto *CS = cast<CapturedStmt>(AStmt); 6380 // 1.2.2 OpenMP Language Terminology 6381 // Structured block - An executable statement with a single entry at the 6382 // top and a single exit at the bottom. 6383 // The point of exit cannot be a branch out of the structured block. 6384 // longjmp() and throw() must not violate the entry/exit criteria. 6385 CS->getCapturedDecl()->setNothrow(); 6386 6387 OMPLoopDirective::HelperExprs B; 6388 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6389 // define the nested loops number. 6390 unsigned NestedLoopCount = 6391 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 6392 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6393 VarsWithImplicitDSA, B); 6394 if (NestedLoopCount == 0) 6395 return StmtError(); 6396 6397 assert((CurContext->isDependentContext() || B.builtAll()) && 6398 "omp parallel for loop exprs were not built"); 6399 6400 if (!CurContext->isDependentContext()) { 6401 // Finalize the clauses that need pre-built expressions for CodeGen. 6402 for (OMPClause *C : Clauses) { 6403 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6404 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6405 B.NumIterations, *this, CurScope, 6406 DSAStack)) 6407 return StmtError(); 6408 } 6409 } 6410 6411 setFunctionHasBranchProtectedScope(); 6412 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 6413 NestedLoopCount, Clauses, AStmt, B, 6414 DSAStack->isCancelRegion()); 6415 } 6416 6417 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 6418 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6419 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6420 if (!AStmt) 6421 return StmtError(); 6422 6423 auto *CS = cast<CapturedStmt>(AStmt); 6424 // 1.2.2 OpenMP Language Terminology 6425 // Structured block - An executable statement with a single entry at the 6426 // top and a single exit at the bottom. 6427 // The point of exit cannot be a branch out of the structured block. 6428 // longjmp() and throw() must not violate the entry/exit criteria. 6429 CS->getCapturedDecl()->setNothrow(); 6430 6431 OMPLoopDirective::HelperExprs B; 6432 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6433 // define the nested loops number. 6434 unsigned NestedLoopCount = 6435 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 6436 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6437 VarsWithImplicitDSA, B); 6438 if (NestedLoopCount == 0) 6439 return StmtError(); 6440 6441 if (!CurContext->isDependentContext()) { 6442 // Finalize the clauses that need pre-built expressions for CodeGen. 6443 for (OMPClause *C : Clauses) { 6444 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6445 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6446 B.NumIterations, *this, CurScope, 6447 DSAStack)) 6448 return StmtError(); 6449 } 6450 } 6451 6452 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6453 return StmtError(); 6454 6455 setFunctionHasBranchProtectedScope(); 6456 return OMPParallelForSimdDirective::Create( 6457 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6458 } 6459 6460 StmtResult 6461 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 6462 Stmt *AStmt, SourceLocation StartLoc, 6463 SourceLocation EndLoc) { 6464 if (!AStmt) 6465 return StmtError(); 6466 6467 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6468 auto BaseStmt = AStmt; 6469 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6470 BaseStmt = CS->getCapturedStmt(); 6471 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6472 auto S = C->children(); 6473 if (S.begin() == S.end()) 6474 return StmtError(); 6475 // All associated statements must be '#pragma omp section' except for 6476 // the first one. 6477 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6478 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6479 if (SectionStmt) 6480 Diag(SectionStmt->getBeginLoc(), 6481 diag::err_omp_parallel_sections_substmt_not_section); 6482 return StmtError(); 6483 } 6484 cast<OMPSectionDirective>(SectionStmt) 6485 ->setHasCancel(DSAStack->isCancelRegion()); 6486 } 6487 } else { 6488 Diag(AStmt->getBeginLoc(), 6489 diag::err_omp_parallel_sections_not_compound_stmt); 6490 return StmtError(); 6491 } 6492 6493 setFunctionHasBranchProtectedScope(); 6494 6495 return OMPParallelSectionsDirective::Create( 6496 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 6497 } 6498 6499 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 6500 Stmt *AStmt, SourceLocation StartLoc, 6501 SourceLocation EndLoc) { 6502 if (!AStmt) 6503 return StmtError(); 6504 6505 auto *CS = cast<CapturedStmt>(AStmt); 6506 // 1.2.2 OpenMP Language Terminology 6507 // Structured block - An executable statement with a single entry at the 6508 // top and a single exit at the bottom. 6509 // The point of exit cannot be a branch out of the structured block. 6510 // longjmp() and throw() must not violate the entry/exit criteria. 6511 CS->getCapturedDecl()->setNothrow(); 6512 6513 setFunctionHasBranchProtectedScope(); 6514 6515 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6516 DSAStack->isCancelRegion()); 6517 } 6518 6519 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 6520 SourceLocation EndLoc) { 6521 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 6522 } 6523 6524 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 6525 SourceLocation EndLoc) { 6526 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 6527 } 6528 6529 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 6530 SourceLocation EndLoc) { 6531 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 6532 } 6533 6534 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 6535 Stmt *AStmt, 6536 SourceLocation StartLoc, 6537 SourceLocation EndLoc) { 6538 if (!AStmt) 6539 return StmtError(); 6540 6541 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6542 6543 setFunctionHasBranchProtectedScope(); 6544 6545 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 6546 AStmt, 6547 DSAStack->getTaskgroupReductionRef()); 6548 } 6549 6550 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 6551 SourceLocation StartLoc, 6552 SourceLocation EndLoc) { 6553 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 6554 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 6555 } 6556 6557 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 6558 Stmt *AStmt, 6559 SourceLocation StartLoc, 6560 SourceLocation EndLoc) { 6561 const OMPClause *DependFound = nullptr; 6562 const OMPClause *DependSourceClause = nullptr; 6563 const OMPClause *DependSinkClause = nullptr; 6564 bool ErrorFound = false; 6565 const OMPThreadsClause *TC = nullptr; 6566 const OMPSIMDClause *SC = nullptr; 6567 for (const OMPClause *C : Clauses) { 6568 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 6569 DependFound = C; 6570 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 6571 if (DependSourceClause) { 6572 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 6573 << getOpenMPDirectiveName(OMPD_ordered) 6574 << getOpenMPClauseName(OMPC_depend) << 2; 6575 ErrorFound = true; 6576 } else { 6577 DependSourceClause = C; 6578 } 6579 if (DependSinkClause) { 6580 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 6581 << 0; 6582 ErrorFound = true; 6583 } 6584 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 6585 if (DependSourceClause) { 6586 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 6587 << 1; 6588 ErrorFound = true; 6589 } 6590 DependSinkClause = C; 6591 } 6592 } else if (C->getClauseKind() == OMPC_threads) { 6593 TC = cast<OMPThreadsClause>(C); 6594 } else if (C->getClauseKind() == OMPC_simd) { 6595 SC = cast<OMPSIMDClause>(C); 6596 } 6597 } 6598 if (!ErrorFound && !SC && 6599 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 6600 // OpenMP [2.8.1,simd Construct, Restrictions] 6601 // An ordered construct with the simd clause is the only OpenMP construct 6602 // that can appear in the simd region. 6603 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 6604 ErrorFound = true; 6605 } else if (DependFound && (TC || SC)) { 6606 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 6607 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 6608 ErrorFound = true; 6609 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 6610 Diag(DependFound->getBeginLoc(), 6611 diag::err_omp_ordered_directive_without_param); 6612 ErrorFound = true; 6613 } else if (TC || Clauses.empty()) { 6614 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 6615 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 6616 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 6617 << (TC != nullptr); 6618 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 6619 ErrorFound = true; 6620 } 6621 } 6622 if ((!AStmt && !DependFound) || ErrorFound) 6623 return StmtError(); 6624 6625 if (AStmt) { 6626 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6627 6628 setFunctionHasBranchProtectedScope(); 6629 } 6630 6631 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6632 } 6633 6634 namespace { 6635 /// Helper class for checking expression in 'omp atomic [update]' 6636 /// construct. 6637 class OpenMPAtomicUpdateChecker { 6638 /// Error results for atomic update expressions. 6639 enum ExprAnalysisErrorCode { 6640 /// A statement is not an expression statement. 6641 NotAnExpression, 6642 /// Expression is not builtin binary or unary operation. 6643 NotABinaryOrUnaryExpression, 6644 /// Unary operation is not post-/pre- increment/decrement operation. 6645 NotAnUnaryIncDecExpression, 6646 /// An expression is not of scalar type. 6647 NotAScalarType, 6648 /// A binary operation is not an assignment operation. 6649 NotAnAssignmentOp, 6650 /// RHS part of the binary operation is not a binary expression. 6651 NotABinaryExpression, 6652 /// RHS part is not additive/multiplicative/shift/biwise binary 6653 /// expression. 6654 NotABinaryOperator, 6655 /// RHS binary operation does not have reference to the updated LHS 6656 /// part. 6657 NotAnUpdateExpression, 6658 /// No errors is found. 6659 NoError 6660 }; 6661 /// Reference to Sema. 6662 Sema &SemaRef; 6663 /// A location for note diagnostics (when error is found). 6664 SourceLocation NoteLoc; 6665 /// 'x' lvalue part of the source atomic expression. 6666 Expr *X; 6667 /// 'expr' rvalue part of the source atomic expression. 6668 Expr *E; 6669 /// Helper expression of the form 6670 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 6671 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 6672 Expr *UpdateExpr; 6673 /// Is 'x' a LHS in a RHS part of full update expression. It is 6674 /// important for non-associative operations. 6675 bool IsXLHSInRHSPart; 6676 BinaryOperatorKind Op; 6677 SourceLocation OpLoc; 6678 /// true if the source expression is a postfix unary operation, false 6679 /// if it is a prefix unary operation. 6680 bool IsPostfixUpdate; 6681 6682 public: 6683 OpenMPAtomicUpdateChecker(Sema &SemaRef) 6684 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 6685 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 6686 /// Check specified statement that it is suitable for 'atomic update' 6687 /// constructs and extract 'x', 'expr' and Operation from the original 6688 /// expression. If DiagId and NoteId == 0, then only check is performed 6689 /// without error notification. 6690 /// \param DiagId Diagnostic which should be emitted if error is found. 6691 /// \param NoteId Diagnostic note for the main error message. 6692 /// \return true if statement is not an update expression, false otherwise. 6693 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 6694 /// Return the 'x' lvalue part of the source atomic expression. 6695 Expr *getX() const { return X; } 6696 /// Return the 'expr' rvalue part of the source atomic expression. 6697 Expr *getExpr() const { return E; } 6698 /// Return the update expression used in calculation of the updated 6699 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 6700 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 6701 Expr *getUpdateExpr() const { return UpdateExpr; } 6702 /// Return true if 'x' is LHS in RHS part of full update expression, 6703 /// false otherwise. 6704 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 6705 6706 /// true if the source expression is a postfix unary operation, false 6707 /// if it is a prefix unary operation. 6708 bool isPostfixUpdate() const { return IsPostfixUpdate; } 6709 6710 private: 6711 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 6712 unsigned NoteId = 0); 6713 }; 6714 } // namespace 6715 6716 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 6717 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 6718 ExprAnalysisErrorCode ErrorFound = NoError; 6719 SourceLocation ErrorLoc, NoteLoc; 6720 SourceRange ErrorRange, NoteRange; 6721 // Allowed constructs are: 6722 // x = x binop expr; 6723 // x = expr binop x; 6724 if (AtomicBinOp->getOpcode() == BO_Assign) { 6725 X = AtomicBinOp->getLHS(); 6726 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 6727 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 6728 if (AtomicInnerBinOp->isMultiplicativeOp() || 6729 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 6730 AtomicInnerBinOp->isBitwiseOp()) { 6731 Op = AtomicInnerBinOp->getOpcode(); 6732 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 6733 Expr *LHS = AtomicInnerBinOp->getLHS(); 6734 Expr *RHS = AtomicInnerBinOp->getRHS(); 6735 llvm::FoldingSetNodeID XId, LHSId, RHSId; 6736 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 6737 /*Canonical=*/true); 6738 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 6739 /*Canonical=*/true); 6740 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 6741 /*Canonical=*/true); 6742 if (XId == LHSId) { 6743 E = RHS; 6744 IsXLHSInRHSPart = true; 6745 } else if (XId == RHSId) { 6746 E = LHS; 6747 IsXLHSInRHSPart = false; 6748 } else { 6749 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6750 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6751 NoteLoc = X->getExprLoc(); 6752 NoteRange = X->getSourceRange(); 6753 ErrorFound = NotAnUpdateExpression; 6754 } 6755 } else { 6756 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6757 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6758 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 6759 NoteRange = SourceRange(NoteLoc, NoteLoc); 6760 ErrorFound = NotABinaryOperator; 6761 } 6762 } else { 6763 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 6764 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 6765 ErrorFound = NotABinaryExpression; 6766 } 6767 } else { 6768 ErrorLoc = AtomicBinOp->getExprLoc(); 6769 ErrorRange = AtomicBinOp->getSourceRange(); 6770 NoteLoc = AtomicBinOp->getOperatorLoc(); 6771 NoteRange = SourceRange(NoteLoc, NoteLoc); 6772 ErrorFound = NotAnAssignmentOp; 6773 } 6774 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6775 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6776 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6777 return true; 6778 } 6779 if (SemaRef.CurContext->isDependentContext()) 6780 E = X = UpdateExpr = nullptr; 6781 return ErrorFound != NoError; 6782 } 6783 6784 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 6785 unsigned NoteId) { 6786 ExprAnalysisErrorCode ErrorFound = NoError; 6787 SourceLocation ErrorLoc, NoteLoc; 6788 SourceRange ErrorRange, NoteRange; 6789 // Allowed constructs are: 6790 // x++; 6791 // x--; 6792 // ++x; 6793 // --x; 6794 // x binop= expr; 6795 // x = x binop expr; 6796 // x = expr binop x; 6797 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 6798 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 6799 if (AtomicBody->getType()->isScalarType() || 6800 AtomicBody->isInstantiationDependent()) { 6801 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 6802 AtomicBody->IgnoreParenImpCasts())) { 6803 // Check for Compound Assignment Operation 6804 Op = BinaryOperator::getOpForCompoundAssignment( 6805 AtomicCompAssignOp->getOpcode()); 6806 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 6807 E = AtomicCompAssignOp->getRHS(); 6808 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 6809 IsXLHSInRHSPart = true; 6810 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 6811 AtomicBody->IgnoreParenImpCasts())) { 6812 // Check for Binary Operation 6813 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 6814 return true; 6815 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 6816 AtomicBody->IgnoreParenImpCasts())) { 6817 // Check for Unary Operation 6818 if (AtomicUnaryOp->isIncrementDecrementOp()) { 6819 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 6820 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 6821 OpLoc = AtomicUnaryOp->getOperatorLoc(); 6822 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 6823 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 6824 IsXLHSInRHSPart = true; 6825 } else { 6826 ErrorFound = NotAnUnaryIncDecExpression; 6827 ErrorLoc = AtomicUnaryOp->getExprLoc(); 6828 ErrorRange = AtomicUnaryOp->getSourceRange(); 6829 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 6830 NoteRange = SourceRange(NoteLoc, NoteLoc); 6831 } 6832 } else if (!AtomicBody->isInstantiationDependent()) { 6833 ErrorFound = NotABinaryOrUnaryExpression; 6834 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 6835 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 6836 } 6837 } else { 6838 ErrorFound = NotAScalarType; 6839 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 6840 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6841 } 6842 } else { 6843 ErrorFound = NotAnExpression; 6844 NoteLoc = ErrorLoc = S->getBeginLoc(); 6845 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6846 } 6847 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6848 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6849 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6850 return true; 6851 } 6852 if (SemaRef.CurContext->isDependentContext()) 6853 E = X = UpdateExpr = nullptr; 6854 if (ErrorFound == NoError && E && X) { 6855 // Build an update expression of form 'OpaqueValueExpr(x) binop 6856 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 6857 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 6858 auto *OVEX = new (SemaRef.getASTContext()) 6859 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 6860 auto *OVEExpr = new (SemaRef.getASTContext()) 6861 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 6862 ExprResult Update = 6863 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 6864 IsXLHSInRHSPart ? OVEExpr : OVEX); 6865 if (Update.isInvalid()) 6866 return true; 6867 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 6868 Sema::AA_Casting); 6869 if (Update.isInvalid()) 6870 return true; 6871 UpdateExpr = Update.get(); 6872 } 6873 return ErrorFound != NoError; 6874 } 6875 6876 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 6877 Stmt *AStmt, 6878 SourceLocation StartLoc, 6879 SourceLocation EndLoc) { 6880 if (!AStmt) 6881 return StmtError(); 6882 6883 auto *CS = cast<CapturedStmt>(AStmt); 6884 // 1.2.2 OpenMP Language Terminology 6885 // Structured block - An executable statement with a single entry at the 6886 // top and a single exit at the bottom. 6887 // The point of exit cannot be a branch out of the structured block. 6888 // longjmp() and throw() must not violate the entry/exit criteria. 6889 OpenMPClauseKind AtomicKind = OMPC_unknown; 6890 SourceLocation AtomicKindLoc; 6891 for (const OMPClause *C : Clauses) { 6892 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 6893 C->getClauseKind() == OMPC_update || 6894 C->getClauseKind() == OMPC_capture) { 6895 if (AtomicKind != OMPC_unknown) { 6896 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 6897 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 6898 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 6899 << getOpenMPClauseName(AtomicKind); 6900 } else { 6901 AtomicKind = C->getClauseKind(); 6902 AtomicKindLoc = C->getBeginLoc(); 6903 } 6904 } 6905 } 6906 6907 Stmt *Body = CS->getCapturedStmt(); 6908 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 6909 Body = EWC->getSubExpr(); 6910 6911 Expr *X = nullptr; 6912 Expr *V = nullptr; 6913 Expr *E = nullptr; 6914 Expr *UE = nullptr; 6915 bool IsXLHSInRHSPart = false; 6916 bool IsPostfixUpdate = false; 6917 // OpenMP [2.12.6, atomic Construct] 6918 // In the next expressions: 6919 // * x and v (as applicable) are both l-value expressions with scalar type. 6920 // * During the execution of an atomic region, multiple syntactic 6921 // occurrences of x must designate the same storage location. 6922 // * Neither of v and expr (as applicable) may access the storage location 6923 // designated by x. 6924 // * Neither of x and expr (as applicable) may access the storage location 6925 // designated by v. 6926 // * expr is an expression with scalar type. 6927 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 6928 // * binop, binop=, ++, and -- are not overloaded operators. 6929 // * The expression x binop expr must be numerically equivalent to x binop 6930 // (expr). This requirement is satisfied if the operators in expr have 6931 // precedence greater than binop, or by using parentheses around expr or 6932 // subexpressions of expr. 6933 // * The expression expr binop x must be numerically equivalent to (expr) 6934 // binop x. This requirement is satisfied if the operators in expr have 6935 // precedence equal to or greater than binop, or by using parentheses around 6936 // expr or subexpressions of expr. 6937 // * For forms that allow multiple occurrences of x, the number of times 6938 // that x is evaluated is unspecified. 6939 if (AtomicKind == OMPC_read) { 6940 enum { 6941 NotAnExpression, 6942 NotAnAssignmentOp, 6943 NotAScalarType, 6944 NotAnLValue, 6945 NoError 6946 } ErrorFound = NoError; 6947 SourceLocation ErrorLoc, NoteLoc; 6948 SourceRange ErrorRange, NoteRange; 6949 // If clause is read: 6950 // v = x; 6951 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6952 const auto *AtomicBinOp = 6953 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6954 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6955 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6956 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 6957 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6958 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 6959 if (!X->isLValue() || !V->isLValue()) { 6960 const Expr *NotLValueExpr = X->isLValue() ? V : X; 6961 ErrorFound = NotAnLValue; 6962 ErrorLoc = AtomicBinOp->getExprLoc(); 6963 ErrorRange = AtomicBinOp->getSourceRange(); 6964 NoteLoc = NotLValueExpr->getExprLoc(); 6965 NoteRange = NotLValueExpr->getSourceRange(); 6966 } 6967 } else if (!X->isInstantiationDependent() || 6968 !V->isInstantiationDependent()) { 6969 const Expr *NotScalarExpr = 6970 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6971 ? V 6972 : X; 6973 ErrorFound = NotAScalarType; 6974 ErrorLoc = AtomicBinOp->getExprLoc(); 6975 ErrorRange = AtomicBinOp->getSourceRange(); 6976 NoteLoc = NotScalarExpr->getExprLoc(); 6977 NoteRange = NotScalarExpr->getSourceRange(); 6978 } 6979 } else if (!AtomicBody->isInstantiationDependent()) { 6980 ErrorFound = NotAnAssignmentOp; 6981 ErrorLoc = AtomicBody->getExprLoc(); 6982 ErrorRange = AtomicBody->getSourceRange(); 6983 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6984 : AtomicBody->getExprLoc(); 6985 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6986 : AtomicBody->getSourceRange(); 6987 } 6988 } else { 6989 ErrorFound = NotAnExpression; 6990 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6991 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6992 } 6993 if (ErrorFound != NoError) { 6994 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 6995 << ErrorRange; 6996 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 6997 << NoteRange; 6998 return StmtError(); 6999 } 7000 if (CurContext->isDependentContext()) 7001 V = X = nullptr; 7002 } else if (AtomicKind == OMPC_write) { 7003 enum { 7004 NotAnExpression, 7005 NotAnAssignmentOp, 7006 NotAScalarType, 7007 NotAnLValue, 7008 NoError 7009 } ErrorFound = NoError; 7010 SourceLocation ErrorLoc, NoteLoc; 7011 SourceRange ErrorRange, NoteRange; 7012 // If clause is write: 7013 // x = expr; 7014 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7015 const auto *AtomicBinOp = 7016 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7017 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7018 X = AtomicBinOp->getLHS(); 7019 E = AtomicBinOp->getRHS(); 7020 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7021 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 7022 if (!X->isLValue()) { 7023 ErrorFound = NotAnLValue; 7024 ErrorLoc = AtomicBinOp->getExprLoc(); 7025 ErrorRange = AtomicBinOp->getSourceRange(); 7026 NoteLoc = X->getExprLoc(); 7027 NoteRange = X->getSourceRange(); 7028 } 7029 } else if (!X->isInstantiationDependent() || 7030 !E->isInstantiationDependent()) { 7031 const Expr *NotScalarExpr = 7032 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7033 ? E 7034 : X; 7035 ErrorFound = NotAScalarType; 7036 ErrorLoc = AtomicBinOp->getExprLoc(); 7037 ErrorRange = AtomicBinOp->getSourceRange(); 7038 NoteLoc = NotScalarExpr->getExprLoc(); 7039 NoteRange = NotScalarExpr->getSourceRange(); 7040 } 7041 } else if (!AtomicBody->isInstantiationDependent()) { 7042 ErrorFound = NotAnAssignmentOp; 7043 ErrorLoc = AtomicBody->getExprLoc(); 7044 ErrorRange = AtomicBody->getSourceRange(); 7045 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7046 : AtomicBody->getExprLoc(); 7047 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7048 : AtomicBody->getSourceRange(); 7049 } 7050 } else { 7051 ErrorFound = NotAnExpression; 7052 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7053 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7054 } 7055 if (ErrorFound != NoError) { 7056 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 7057 << ErrorRange; 7058 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7059 << NoteRange; 7060 return StmtError(); 7061 } 7062 if (CurContext->isDependentContext()) 7063 E = X = nullptr; 7064 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 7065 // If clause is update: 7066 // x++; 7067 // x--; 7068 // ++x; 7069 // --x; 7070 // x binop= expr; 7071 // x = x binop expr; 7072 // x = expr binop x; 7073 OpenMPAtomicUpdateChecker Checker(*this); 7074 if (Checker.checkStatement( 7075 Body, (AtomicKind == OMPC_update) 7076 ? diag::err_omp_atomic_update_not_expression_statement 7077 : diag::err_omp_atomic_not_expression_statement, 7078 diag::note_omp_atomic_update)) 7079 return StmtError(); 7080 if (!CurContext->isDependentContext()) { 7081 E = Checker.getExpr(); 7082 X = Checker.getX(); 7083 UE = Checker.getUpdateExpr(); 7084 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7085 } 7086 } else if (AtomicKind == OMPC_capture) { 7087 enum { 7088 NotAnAssignmentOp, 7089 NotACompoundStatement, 7090 NotTwoSubstatements, 7091 NotASpecificExpression, 7092 NoError 7093 } ErrorFound = NoError; 7094 SourceLocation ErrorLoc, NoteLoc; 7095 SourceRange ErrorRange, NoteRange; 7096 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7097 // If clause is a capture: 7098 // v = x++; 7099 // v = x--; 7100 // v = ++x; 7101 // v = --x; 7102 // v = x binop= expr; 7103 // v = x = x binop expr; 7104 // v = x = expr binop x; 7105 const auto *AtomicBinOp = 7106 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7107 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7108 V = AtomicBinOp->getLHS(); 7109 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7110 OpenMPAtomicUpdateChecker Checker(*this); 7111 if (Checker.checkStatement( 7112 Body, diag::err_omp_atomic_capture_not_expression_statement, 7113 diag::note_omp_atomic_update)) 7114 return StmtError(); 7115 E = Checker.getExpr(); 7116 X = Checker.getX(); 7117 UE = Checker.getUpdateExpr(); 7118 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7119 IsPostfixUpdate = Checker.isPostfixUpdate(); 7120 } else if (!AtomicBody->isInstantiationDependent()) { 7121 ErrorLoc = AtomicBody->getExprLoc(); 7122 ErrorRange = AtomicBody->getSourceRange(); 7123 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7124 : AtomicBody->getExprLoc(); 7125 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7126 : AtomicBody->getSourceRange(); 7127 ErrorFound = NotAnAssignmentOp; 7128 } 7129 if (ErrorFound != NoError) { 7130 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 7131 << ErrorRange; 7132 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7133 return StmtError(); 7134 } 7135 if (CurContext->isDependentContext()) 7136 UE = V = E = X = nullptr; 7137 } else { 7138 // If clause is a capture: 7139 // { v = x; x = expr; } 7140 // { v = x; x++; } 7141 // { v = x; x--; } 7142 // { v = x; ++x; } 7143 // { v = x; --x; } 7144 // { v = x; x binop= expr; } 7145 // { v = x; x = x binop expr; } 7146 // { v = x; x = expr binop x; } 7147 // { x++; v = x; } 7148 // { x--; v = x; } 7149 // { ++x; v = x; } 7150 // { --x; v = x; } 7151 // { x binop= expr; v = x; } 7152 // { x = x binop expr; v = x; } 7153 // { x = expr binop x; v = x; } 7154 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 7155 // Check that this is { expr1; expr2; } 7156 if (CS->size() == 2) { 7157 Stmt *First = CS->body_front(); 7158 Stmt *Second = CS->body_back(); 7159 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 7160 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 7161 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 7162 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 7163 // Need to find what subexpression is 'v' and what is 'x'. 7164 OpenMPAtomicUpdateChecker Checker(*this); 7165 bool IsUpdateExprFound = !Checker.checkStatement(Second); 7166 BinaryOperator *BinOp = nullptr; 7167 if (IsUpdateExprFound) { 7168 BinOp = dyn_cast<BinaryOperator>(First); 7169 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7170 } 7171 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7172 // { v = x; x++; } 7173 // { v = x; x--; } 7174 // { v = x; ++x; } 7175 // { v = x; --x; } 7176 // { v = x; x binop= expr; } 7177 // { v = x; x = x binop expr; } 7178 // { v = x; x = expr binop x; } 7179 // Check that the first expression has form v = x. 7180 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7181 llvm::FoldingSetNodeID XId, PossibleXId; 7182 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7183 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7184 IsUpdateExprFound = XId == PossibleXId; 7185 if (IsUpdateExprFound) { 7186 V = BinOp->getLHS(); 7187 X = Checker.getX(); 7188 E = Checker.getExpr(); 7189 UE = Checker.getUpdateExpr(); 7190 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7191 IsPostfixUpdate = true; 7192 } 7193 } 7194 if (!IsUpdateExprFound) { 7195 IsUpdateExprFound = !Checker.checkStatement(First); 7196 BinOp = nullptr; 7197 if (IsUpdateExprFound) { 7198 BinOp = dyn_cast<BinaryOperator>(Second); 7199 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7200 } 7201 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7202 // { x++; v = x; } 7203 // { x--; v = x; } 7204 // { ++x; v = x; } 7205 // { --x; v = x; } 7206 // { x binop= expr; v = x; } 7207 // { x = x binop expr; v = x; } 7208 // { x = expr binop x; v = x; } 7209 // Check that the second expression has form v = x. 7210 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7211 llvm::FoldingSetNodeID XId, PossibleXId; 7212 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7213 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7214 IsUpdateExprFound = XId == PossibleXId; 7215 if (IsUpdateExprFound) { 7216 V = BinOp->getLHS(); 7217 X = Checker.getX(); 7218 E = Checker.getExpr(); 7219 UE = Checker.getUpdateExpr(); 7220 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7221 IsPostfixUpdate = false; 7222 } 7223 } 7224 } 7225 if (!IsUpdateExprFound) { 7226 // { v = x; x = expr; } 7227 auto *FirstExpr = dyn_cast<Expr>(First); 7228 auto *SecondExpr = dyn_cast<Expr>(Second); 7229 if (!FirstExpr || !SecondExpr || 7230 !(FirstExpr->isInstantiationDependent() || 7231 SecondExpr->isInstantiationDependent())) { 7232 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 7233 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 7234 ErrorFound = NotAnAssignmentOp; 7235 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 7236 : First->getBeginLoc(); 7237 NoteRange = ErrorRange = FirstBinOp 7238 ? FirstBinOp->getSourceRange() 7239 : SourceRange(ErrorLoc, ErrorLoc); 7240 } else { 7241 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 7242 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 7243 ErrorFound = NotAnAssignmentOp; 7244 NoteLoc = ErrorLoc = SecondBinOp 7245 ? SecondBinOp->getOperatorLoc() 7246 : Second->getBeginLoc(); 7247 NoteRange = ErrorRange = 7248 SecondBinOp ? SecondBinOp->getSourceRange() 7249 : SourceRange(ErrorLoc, ErrorLoc); 7250 } else { 7251 Expr *PossibleXRHSInFirst = 7252 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 7253 Expr *PossibleXLHSInSecond = 7254 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 7255 llvm::FoldingSetNodeID X1Id, X2Id; 7256 PossibleXRHSInFirst->Profile(X1Id, Context, 7257 /*Canonical=*/true); 7258 PossibleXLHSInSecond->Profile(X2Id, Context, 7259 /*Canonical=*/true); 7260 IsUpdateExprFound = X1Id == X2Id; 7261 if (IsUpdateExprFound) { 7262 V = FirstBinOp->getLHS(); 7263 X = SecondBinOp->getLHS(); 7264 E = SecondBinOp->getRHS(); 7265 UE = nullptr; 7266 IsXLHSInRHSPart = false; 7267 IsPostfixUpdate = true; 7268 } else { 7269 ErrorFound = NotASpecificExpression; 7270 ErrorLoc = FirstBinOp->getExprLoc(); 7271 ErrorRange = FirstBinOp->getSourceRange(); 7272 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 7273 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 7274 } 7275 } 7276 } 7277 } 7278 } 7279 } else { 7280 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7281 NoteRange = ErrorRange = 7282 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7283 ErrorFound = NotTwoSubstatements; 7284 } 7285 } else { 7286 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7287 NoteRange = ErrorRange = 7288 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7289 ErrorFound = NotACompoundStatement; 7290 } 7291 if (ErrorFound != NoError) { 7292 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 7293 << ErrorRange; 7294 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7295 return StmtError(); 7296 } 7297 if (CurContext->isDependentContext()) 7298 UE = V = E = X = nullptr; 7299 } 7300 } 7301 7302 setFunctionHasBranchProtectedScope(); 7303 7304 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7305 X, V, E, UE, IsXLHSInRHSPart, 7306 IsPostfixUpdate); 7307 } 7308 7309 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 7310 Stmt *AStmt, 7311 SourceLocation StartLoc, 7312 SourceLocation EndLoc) { 7313 if (!AStmt) 7314 return StmtError(); 7315 7316 auto *CS = cast<CapturedStmt>(AStmt); 7317 // 1.2.2 OpenMP Language Terminology 7318 // Structured block - An executable statement with a single entry at the 7319 // top and a single exit at the bottom. 7320 // The point of exit cannot be a branch out of the structured block. 7321 // longjmp() and throw() must not violate the entry/exit criteria. 7322 CS->getCapturedDecl()->setNothrow(); 7323 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 7324 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7325 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7326 // 1.2.2 OpenMP Language Terminology 7327 // Structured block - An executable statement with a single entry at the 7328 // top and a single exit at the bottom. 7329 // The point of exit cannot be a branch out of the structured block. 7330 // longjmp() and throw() must not violate the entry/exit criteria. 7331 CS->getCapturedDecl()->setNothrow(); 7332 } 7333 7334 // OpenMP [2.16, Nesting of Regions] 7335 // If specified, a teams construct must be contained within a target 7336 // construct. That target construct must contain no statements or directives 7337 // outside of the teams construct. 7338 if (DSAStack->hasInnerTeamsRegion()) { 7339 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 7340 bool OMPTeamsFound = true; 7341 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 7342 auto I = CS->body_begin(); 7343 while (I != CS->body_end()) { 7344 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 7345 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 7346 OMPTeamsFound) { 7347 7348 OMPTeamsFound = false; 7349 break; 7350 } 7351 ++I; 7352 } 7353 assert(I != CS->body_end() && "Not found statement"); 7354 S = *I; 7355 } else { 7356 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 7357 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 7358 } 7359 if (!OMPTeamsFound) { 7360 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 7361 Diag(DSAStack->getInnerTeamsRegionLoc(), 7362 diag::note_omp_nested_teams_construct_here); 7363 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 7364 << isa<OMPExecutableDirective>(S); 7365 return StmtError(); 7366 } 7367 } 7368 7369 setFunctionHasBranchProtectedScope(); 7370 7371 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7372 } 7373 7374 StmtResult 7375 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 7376 Stmt *AStmt, SourceLocation StartLoc, 7377 SourceLocation EndLoc) { 7378 if (!AStmt) 7379 return StmtError(); 7380 7381 auto *CS = cast<CapturedStmt>(AStmt); 7382 // 1.2.2 OpenMP Language Terminology 7383 // Structured block - An executable statement with a single entry at the 7384 // top and a single exit at the bottom. 7385 // The point of exit cannot be a branch out of the structured block. 7386 // longjmp() and throw() must not violate the entry/exit criteria. 7387 CS->getCapturedDecl()->setNothrow(); 7388 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 7389 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7390 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7391 // 1.2.2 OpenMP Language Terminology 7392 // Structured block - An executable statement with a single entry at the 7393 // top and a single exit at the bottom. 7394 // The point of exit cannot be a branch out of the structured block. 7395 // longjmp() and throw() must not violate the entry/exit criteria. 7396 CS->getCapturedDecl()->setNothrow(); 7397 } 7398 7399 setFunctionHasBranchProtectedScope(); 7400 7401 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7402 AStmt); 7403 } 7404 7405 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 7406 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7407 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7408 if (!AStmt) 7409 return StmtError(); 7410 7411 auto *CS = cast<CapturedStmt>(AStmt); 7412 // 1.2.2 OpenMP Language Terminology 7413 // Structured block - An executable statement with a single entry at the 7414 // top and a single exit at the bottom. 7415 // The point of exit cannot be a branch out of the structured block. 7416 // longjmp() and throw() must not violate the entry/exit criteria. 7417 CS->getCapturedDecl()->setNothrow(); 7418 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 7419 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7420 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7421 // 1.2.2 OpenMP Language Terminology 7422 // Structured block - An executable statement with a single entry at the 7423 // top and a single exit at the bottom. 7424 // The point of exit cannot be a branch out of the structured block. 7425 // longjmp() and throw() must not violate the entry/exit criteria. 7426 CS->getCapturedDecl()->setNothrow(); 7427 } 7428 7429 OMPLoopDirective::HelperExprs B; 7430 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7431 // define the nested loops number. 7432 unsigned NestedLoopCount = 7433 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 7434 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7435 VarsWithImplicitDSA, B); 7436 if (NestedLoopCount == 0) 7437 return StmtError(); 7438 7439 assert((CurContext->isDependentContext() || B.builtAll()) && 7440 "omp target parallel for loop exprs were not built"); 7441 7442 if (!CurContext->isDependentContext()) { 7443 // Finalize the clauses that need pre-built expressions for CodeGen. 7444 for (OMPClause *C : Clauses) { 7445 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7446 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7447 B.NumIterations, *this, CurScope, 7448 DSAStack)) 7449 return StmtError(); 7450 } 7451 } 7452 7453 setFunctionHasBranchProtectedScope(); 7454 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 7455 NestedLoopCount, Clauses, AStmt, 7456 B, DSAStack->isCancelRegion()); 7457 } 7458 7459 /// Check for existence of a map clause in the list of clauses. 7460 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 7461 const OpenMPClauseKind K) { 7462 return llvm::any_of( 7463 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 7464 } 7465 7466 template <typename... Params> 7467 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 7468 const Params... ClauseTypes) { 7469 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 7470 } 7471 7472 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 7473 Stmt *AStmt, 7474 SourceLocation StartLoc, 7475 SourceLocation EndLoc) { 7476 if (!AStmt) 7477 return StmtError(); 7478 7479 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7480 7481 // OpenMP [2.10.1, Restrictions, p. 97] 7482 // At least one map clause must appear on the directive. 7483 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 7484 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7485 << "'map' or 'use_device_ptr'" 7486 << getOpenMPDirectiveName(OMPD_target_data); 7487 return StmtError(); 7488 } 7489 7490 setFunctionHasBranchProtectedScope(); 7491 7492 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7493 AStmt); 7494 } 7495 7496 StmtResult 7497 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 7498 SourceLocation StartLoc, 7499 SourceLocation EndLoc, Stmt *AStmt) { 7500 if (!AStmt) 7501 return StmtError(); 7502 7503 auto *CS = cast<CapturedStmt>(AStmt); 7504 // 1.2.2 OpenMP Language Terminology 7505 // Structured block - An executable statement with a single entry at the 7506 // top and a single exit at the bottom. 7507 // The point of exit cannot be a branch out of the structured block. 7508 // longjmp() and throw() must not violate the entry/exit criteria. 7509 CS->getCapturedDecl()->setNothrow(); 7510 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 7511 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7512 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7513 // 1.2.2 OpenMP Language Terminology 7514 // Structured block - An executable statement with a single entry at the 7515 // top and a single exit at the bottom. 7516 // The point of exit cannot be a branch out of the structured block. 7517 // longjmp() and throw() must not violate the entry/exit criteria. 7518 CS->getCapturedDecl()->setNothrow(); 7519 } 7520 7521 // OpenMP [2.10.2, Restrictions, p. 99] 7522 // At least one map clause must appear on the directive. 7523 if (!hasClauses(Clauses, OMPC_map)) { 7524 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7525 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 7526 return StmtError(); 7527 } 7528 7529 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7530 AStmt); 7531 } 7532 7533 StmtResult 7534 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 7535 SourceLocation StartLoc, 7536 SourceLocation EndLoc, Stmt *AStmt) { 7537 if (!AStmt) 7538 return StmtError(); 7539 7540 auto *CS = cast<CapturedStmt>(AStmt); 7541 // 1.2.2 OpenMP Language Terminology 7542 // Structured block - An executable statement with a single entry at the 7543 // top and a single exit at the bottom. 7544 // The point of exit cannot be a branch out of the structured block. 7545 // longjmp() and throw() must not violate the entry/exit criteria. 7546 CS->getCapturedDecl()->setNothrow(); 7547 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 7548 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7549 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7550 // 1.2.2 OpenMP Language Terminology 7551 // Structured block - An executable statement with a single entry at the 7552 // top and a single exit at the bottom. 7553 // The point of exit cannot be a branch out of the structured block. 7554 // longjmp() and throw() must not violate the entry/exit criteria. 7555 CS->getCapturedDecl()->setNothrow(); 7556 } 7557 7558 // OpenMP [2.10.3, Restrictions, p. 102] 7559 // At least one map clause must appear on the directive. 7560 if (!hasClauses(Clauses, OMPC_map)) { 7561 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7562 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 7563 return StmtError(); 7564 } 7565 7566 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7567 AStmt); 7568 } 7569 7570 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 7571 SourceLocation StartLoc, 7572 SourceLocation EndLoc, 7573 Stmt *AStmt) { 7574 if (!AStmt) 7575 return StmtError(); 7576 7577 auto *CS = cast<CapturedStmt>(AStmt); 7578 // 1.2.2 OpenMP Language Terminology 7579 // Structured block - An executable statement with a single entry at the 7580 // top and a single exit at the bottom. 7581 // The point of exit cannot be a branch out of the structured block. 7582 // longjmp() and throw() must not violate the entry/exit criteria. 7583 CS->getCapturedDecl()->setNothrow(); 7584 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 7585 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7586 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7587 // 1.2.2 OpenMP Language Terminology 7588 // Structured block - An executable statement with a single entry at the 7589 // top and a single exit at the bottom. 7590 // The point of exit cannot be a branch out of the structured block. 7591 // longjmp() and throw() must not violate the entry/exit criteria. 7592 CS->getCapturedDecl()->setNothrow(); 7593 } 7594 7595 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 7596 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 7597 return StmtError(); 7598 } 7599 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 7600 AStmt); 7601 } 7602 7603 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 7604 Stmt *AStmt, SourceLocation StartLoc, 7605 SourceLocation EndLoc) { 7606 if (!AStmt) 7607 return StmtError(); 7608 7609 auto *CS = cast<CapturedStmt>(AStmt); 7610 // 1.2.2 OpenMP Language Terminology 7611 // Structured block - An executable statement with a single entry at the 7612 // top and a single exit at the bottom. 7613 // The point of exit cannot be a branch out of the structured block. 7614 // longjmp() and throw() must not violate the entry/exit criteria. 7615 CS->getCapturedDecl()->setNothrow(); 7616 7617 setFunctionHasBranchProtectedScope(); 7618 7619 DSAStack->setParentTeamsRegionLoc(StartLoc); 7620 7621 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7622 } 7623 7624 StmtResult 7625 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 7626 SourceLocation EndLoc, 7627 OpenMPDirectiveKind CancelRegion) { 7628 if (DSAStack->isParentNowaitRegion()) { 7629 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 7630 return StmtError(); 7631 } 7632 if (DSAStack->isParentOrderedRegion()) { 7633 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 7634 return StmtError(); 7635 } 7636 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 7637 CancelRegion); 7638 } 7639 7640 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 7641 SourceLocation StartLoc, 7642 SourceLocation EndLoc, 7643 OpenMPDirectiveKind CancelRegion) { 7644 if (DSAStack->isParentNowaitRegion()) { 7645 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 7646 return StmtError(); 7647 } 7648 if (DSAStack->isParentOrderedRegion()) { 7649 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 7650 return StmtError(); 7651 } 7652 DSAStack->setParentCancelRegion(/*Cancel=*/true); 7653 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7654 CancelRegion); 7655 } 7656 7657 static bool checkGrainsizeNumTasksClauses(Sema &S, 7658 ArrayRef<OMPClause *> Clauses) { 7659 const OMPClause *PrevClause = nullptr; 7660 bool ErrorFound = false; 7661 for (const OMPClause *C : Clauses) { 7662 if (C->getClauseKind() == OMPC_grainsize || 7663 C->getClauseKind() == OMPC_num_tasks) { 7664 if (!PrevClause) 7665 PrevClause = C; 7666 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 7667 S.Diag(C->getBeginLoc(), 7668 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 7669 << getOpenMPClauseName(C->getClauseKind()) 7670 << getOpenMPClauseName(PrevClause->getClauseKind()); 7671 S.Diag(PrevClause->getBeginLoc(), 7672 diag::note_omp_previous_grainsize_num_tasks) 7673 << getOpenMPClauseName(PrevClause->getClauseKind()); 7674 ErrorFound = true; 7675 } 7676 } 7677 } 7678 return ErrorFound; 7679 } 7680 7681 static bool checkReductionClauseWithNogroup(Sema &S, 7682 ArrayRef<OMPClause *> Clauses) { 7683 const OMPClause *ReductionClause = nullptr; 7684 const OMPClause *NogroupClause = nullptr; 7685 for (const OMPClause *C : Clauses) { 7686 if (C->getClauseKind() == OMPC_reduction) { 7687 ReductionClause = C; 7688 if (NogroupClause) 7689 break; 7690 continue; 7691 } 7692 if (C->getClauseKind() == OMPC_nogroup) { 7693 NogroupClause = C; 7694 if (ReductionClause) 7695 break; 7696 continue; 7697 } 7698 } 7699 if (ReductionClause && NogroupClause) { 7700 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 7701 << SourceRange(NogroupClause->getBeginLoc(), 7702 NogroupClause->getEndLoc()); 7703 return true; 7704 } 7705 return false; 7706 } 7707 7708 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 7709 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7710 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7711 if (!AStmt) 7712 return StmtError(); 7713 7714 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7715 OMPLoopDirective::HelperExprs B; 7716 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7717 // define the nested loops number. 7718 unsigned NestedLoopCount = 7719 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 7720 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7721 VarsWithImplicitDSA, B); 7722 if (NestedLoopCount == 0) 7723 return StmtError(); 7724 7725 assert((CurContext->isDependentContext() || B.builtAll()) && 7726 "omp for loop exprs were not built"); 7727 7728 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7729 // The grainsize clause and num_tasks clause are mutually exclusive and may 7730 // not appear on the same taskloop directive. 7731 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7732 return StmtError(); 7733 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7734 // If a reduction clause is present on the taskloop directive, the nogroup 7735 // clause must not be specified. 7736 if (checkReductionClauseWithNogroup(*this, Clauses)) 7737 return StmtError(); 7738 7739 setFunctionHasBranchProtectedScope(); 7740 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 7741 NestedLoopCount, Clauses, AStmt, B); 7742 } 7743 7744 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 7745 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7746 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7747 if (!AStmt) 7748 return StmtError(); 7749 7750 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7751 OMPLoopDirective::HelperExprs B; 7752 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7753 // define the nested loops number. 7754 unsigned NestedLoopCount = 7755 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 7756 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7757 VarsWithImplicitDSA, B); 7758 if (NestedLoopCount == 0) 7759 return StmtError(); 7760 7761 assert((CurContext->isDependentContext() || B.builtAll()) && 7762 "omp for loop exprs were not built"); 7763 7764 if (!CurContext->isDependentContext()) { 7765 // Finalize the clauses that need pre-built expressions for CodeGen. 7766 for (OMPClause *C : Clauses) { 7767 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7768 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7769 B.NumIterations, *this, CurScope, 7770 DSAStack)) 7771 return StmtError(); 7772 } 7773 } 7774 7775 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7776 // The grainsize clause and num_tasks clause are mutually exclusive and may 7777 // not appear on the same taskloop directive. 7778 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7779 return StmtError(); 7780 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7781 // If a reduction clause is present on the taskloop directive, the nogroup 7782 // clause must not be specified. 7783 if (checkReductionClauseWithNogroup(*this, Clauses)) 7784 return StmtError(); 7785 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7786 return StmtError(); 7787 7788 setFunctionHasBranchProtectedScope(); 7789 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 7790 NestedLoopCount, Clauses, AStmt, B); 7791 } 7792 7793 StmtResult Sema::ActOnOpenMPDistributeDirective( 7794 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7795 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7796 if (!AStmt) 7797 return StmtError(); 7798 7799 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7800 OMPLoopDirective::HelperExprs B; 7801 // In presence of clause 'collapse' with number of loops, it will 7802 // define the nested loops number. 7803 unsigned NestedLoopCount = 7804 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 7805 nullptr /*ordered not a clause on distribute*/, AStmt, 7806 *this, *DSAStack, VarsWithImplicitDSA, B); 7807 if (NestedLoopCount == 0) 7808 return StmtError(); 7809 7810 assert((CurContext->isDependentContext() || B.builtAll()) && 7811 "omp for loop exprs were not built"); 7812 7813 setFunctionHasBranchProtectedScope(); 7814 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 7815 NestedLoopCount, Clauses, AStmt, B); 7816 } 7817 7818 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 7819 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7820 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7821 if (!AStmt) 7822 return StmtError(); 7823 7824 auto *CS = cast<CapturedStmt>(AStmt); 7825 // 1.2.2 OpenMP Language Terminology 7826 // Structured block - An executable statement with a single entry at the 7827 // top and a single exit at the bottom. 7828 // The point of exit cannot be a branch out of the structured block. 7829 // longjmp() and throw() must not violate the entry/exit criteria. 7830 CS->getCapturedDecl()->setNothrow(); 7831 for (int ThisCaptureLevel = 7832 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 7833 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7834 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7835 // 1.2.2 OpenMP Language Terminology 7836 // Structured block - An executable statement with a single entry at the 7837 // top and a single exit at the bottom. 7838 // The point of exit cannot be a branch out of the structured block. 7839 // longjmp() and throw() must not violate the entry/exit criteria. 7840 CS->getCapturedDecl()->setNothrow(); 7841 } 7842 7843 OMPLoopDirective::HelperExprs B; 7844 // In presence of clause 'collapse' with number of loops, it will 7845 // define the nested loops number. 7846 unsigned NestedLoopCount = checkOpenMPLoop( 7847 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 7848 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7849 VarsWithImplicitDSA, B); 7850 if (NestedLoopCount == 0) 7851 return StmtError(); 7852 7853 assert((CurContext->isDependentContext() || B.builtAll()) && 7854 "omp for loop exprs were not built"); 7855 7856 setFunctionHasBranchProtectedScope(); 7857 return OMPDistributeParallelForDirective::Create( 7858 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 7859 DSAStack->isCancelRegion()); 7860 } 7861 7862 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 7863 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7864 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7865 if (!AStmt) 7866 return StmtError(); 7867 7868 auto *CS = cast<CapturedStmt>(AStmt); 7869 // 1.2.2 OpenMP Language Terminology 7870 // Structured block - An executable statement with a single entry at the 7871 // top and a single exit at the bottom. 7872 // The point of exit cannot be a branch out of the structured block. 7873 // longjmp() and throw() must not violate the entry/exit criteria. 7874 CS->getCapturedDecl()->setNothrow(); 7875 for (int ThisCaptureLevel = 7876 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 7877 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7878 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7879 // 1.2.2 OpenMP Language Terminology 7880 // Structured block - An executable statement with a single entry at the 7881 // top and a single exit at the bottom. 7882 // The point of exit cannot be a branch out of the structured block. 7883 // longjmp() and throw() must not violate the entry/exit criteria. 7884 CS->getCapturedDecl()->setNothrow(); 7885 } 7886 7887 OMPLoopDirective::HelperExprs B; 7888 // In presence of clause 'collapse' with number of loops, it will 7889 // define the nested loops number. 7890 unsigned NestedLoopCount = checkOpenMPLoop( 7891 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 7892 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7893 VarsWithImplicitDSA, B); 7894 if (NestedLoopCount == 0) 7895 return StmtError(); 7896 7897 assert((CurContext->isDependentContext() || B.builtAll()) && 7898 "omp for loop exprs were not built"); 7899 7900 if (!CurContext->isDependentContext()) { 7901 // Finalize the clauses that need pre-built expressions for CodeGen. 7902 for (OMPClause *C : Clauses) { 7903 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7904 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7905 B.NumIterations, *this, CurScope, 7906 DSAStack)) 7907 return StmtError(); 7908 } 7909 } 7910 7911 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7912 return StmtError(); 7913 7914 setFunctionHasBranchProtectedScope(); 7915 return OMPDistributeParallelForSimdDirective::Create( 7916 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7917 } 7918 7919 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 7920 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7921 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7922 if (!AStmt) 7923 return StmtError(); 7924 7925 auto *CS = cast<CapturedStmt>(AStmt); 7926 // 1.2.2 OpenMP Language Terminology 7927 // Structured block - An executable statement with a single entry at the 7928 // top and a single exit at the bottom. 7929 // The point of exit cannot be a branch out of the structured block. 7930 // longjmp() and throw() must not violate the entry/exit criteria. 7931 CS->getCapturedDecl()->setNothrow(); 7932 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 7933 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7934 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7935 // 1.2.2 OpenMP Language Terminology 7936 // Structured block - An executable statement with a single entry at the 7937 // top and a single exit at the bottom. 7938 // The point of exit cannot be a branch out of the structured block. 7939 // longjmp() and throw() must not violate the entry/exit criteria. 7940 CS->getCapturedDecl()->setNothrow(); 7941 } 7942 7943 OMPLoopDirective::HelperExprs B; 7944 // In presence of clause 'collapse' with number of loops, it will 7945 // define the nested loops number. 7946 unsigned NestedLoopCount = 7947 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 7948 nullptr /*ordered not a clause on distribute*/, CS, *this, 7949 *DSAStack, VarsWithImplicitDSA, B); 7950 if (NestedLoopCount == 0) 7951 return StmtError(); 7952 7953 assert((CurContext->isDependentContext() || B.builtAll()) && 7954 "omp for loop exprs were not built"); 7955 7956 if (!CurContext->isDependentContext()) { 7957 // Finalize the clauses that need pre-built expressions for CodeGen. 7958 for (OMPClause *C : Clauses) { 7959 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7960 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7961 B.NumIterations, *this, CurScope, 7962 DSAStack)) 7963 return StmtError(); 7964 } 7965 } 7966 7967 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7968 return StmtError(); 7969 7970 setFunctionHasBranchProtectedScope(); 7971 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 7972 NestedLoopCount, Clauses, AStmt, B); 7973 } 7974 7975 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 7976 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7977 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7978 if (!AStmt) 7979 return StmtError(); 7980 7981 auto *CS = cast<CapturedStmt>(AStmt); 7982 // 1.2.2 OpenMP Language Terminology 7983 // Structured block - An executable statement with a single entry at the 7984 // top and a single exit at the bottom. 7985 // The point of exit cannot be a branch out of the structured block. 7986 // longjmp() and throw() must not violate the entry/exit criteria. 7987 CS->getCapturedDecl()->setNothrow(); 7988 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 7989 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7990 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7991 // 1.2.2 OpenMP Language Terminology 7992 // Structured block - An executable statement with a single entry at the 7993 // top and a single exit at the bottom. 7994 // The point of exit cannot be a branch out of the structured block. 7995 // longjmp() and throw() must not violate the entry/exit criteria. 7996 CS->getCapturedDecl()->setNothrow(); 7997 } 7998 7999 OMPLoopDirective::HelperExprs B; 8000 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8001 // define the nested loops number. 8002 unsigned NestedLoopCount = checkOpenMPLoop( 8003 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 8004 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8005 VarsWithImplicitDSA, B); 8006 if (NestedLoopCount == 0) 8007 return StmtError(); 8008 8009 assert((CurContext->isDependentContext() || B.builtAll()) && 8010 "omp target parallel for simd loop exprs were not built"); 8011 8012 if (!CurContext->isDependentContext()) { 8013 // Finalize the clauses that need pre-built expressions for CodeGen. 8014 for (OMPClause *C : Clauses) { 8015 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8016 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8017 B.NumIterations, *this, CurScope, 8018 DSAStack)) 8019 return StmtError(); 8020 } 8021 } 8022 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8023 return StmtError(); 8024 8025 setFunctionHasBranchProtectedScope(); 8026 return OMPTargetParallelForSimdDirective::Create( 8027 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8028 } 8029 8030 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 8031 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8032 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8033 if (!AStmt) 8034 return StmtError(); 8035 8036 auto *CS = cast<CapturedStmt>(AStmt); 8037 // 1.2.2 OpenMP Language Terminology 8038 // Structured block - An executable statement with a single entry at the 8039 // top and a single exit at the bottom. 8040 // The point of exit cannot be a branch out of the structured block. 8041 // longjmp() and throw() must not violate the entry/exit criteria. 8042 CS->getCapturedDecl()->setNothrow(); 8043 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 8044 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8045 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8046 // 1.2.2 OpenMP Language Terminology 8047 // Structured block - An executable statement with a single entry at the 8048 // top and a single exit at the bottom. 8049 // The point of exit cannot be a branch out of the structured block. 8050 // longjmp() and throw() must not violate the entry/exit criteria. 8051 CS->getCapturedDecl()->setNothrow(); 8052 } 8053 8054 OMPLoopDirective::HelperExprs B; 8055 // In presence of clause 'collapse' with number of loops, it will define the 8056 // nested loops number. 8057 unsigned NestedLoopCount = 8058 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 8059 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8060 VarsWithImplicitDSA, B); 8061 if (NestedLoopCount == 0) 8062 return StmtError(); 8063 8064 assert((CurContext->isDependentContext() || B.builtAll()) && 8065 "omp target simd loop exprs were not built"); 8066 8067 if (!CurContext->isDependentContext()) { 8068 // Finalize the clauses that need pre-built expressions for CodeGen. 8069 for (OMPClause *C : Clauses) { 8070 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8071 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8072 B.NumIterations, *this, CurScope, 8073 DSAStack)) 8074 return StmtError(); 8075 } 8076 } 8077 8078 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8079 return StmtError(); 8080 8081 setFunctionHasBranchProtectedScope(); 8082 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 8083 NestedLoopCount, Clauses, AStmt, B); 8084 } 8085 8086 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 8087 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8088 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8089 if (!AStmt) 8090 return StmtError(); 8091 8092 auto *CS = cast<CapturedStmt>(AStmt); 8093 // 1.2.2 OpenMP Language Terminology 8094 // Structured block - An executable statement with a single entry at the 8095 // top and a single exit at the bottom. 8096 // The point of exit cannot be a branch out of the structured block. 8097 // longjmp() and throw() must not violate the entry/exit criteria. 8098 CS->getCapturedDecl()->setNothrow(); 8099 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 8100 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8101 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8102 // 1.2.2 OpenMP Language Terminology 8103 // Structured block - An executable statement with a single entry at the 8104 // top and a single exit at the bottom. 8105 // The point of exit cannot be a branch out of the structured block. 8106 // longjmp() and throw() must not violate the entry/exit criteria. 8107 CS->getCapturedDecl()->setNothrow(); 8108 } 8109 8110 OMPLoopDirective::HelperExprs B; 8111 // In presence of clause 'collapse' with number of loops, it will 8112 // define the nested loops number. 8113 unsigned NestedLoopCount = 8114 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 8115 nullptr /*ordered not a clause on distribute*/, CS, *this, 8116 *DSAStack, VarsWithImplicitDSA, B); 8117 if (NestedLoopCount == 0) 8118 return StmtError(); 8119 8120 assert((CurContext->isDependentContext() || B.builtAll()) && 8121 "omp teams distribute loop exprs were not built"); 8122 8123 setFunctionHasBranchProtectedScope(); 8124 8125 DSAStack->setParentTeamsRegionLoc(StartLoc); 8126 8127 return OMPTeamsDistributeDirective::Create( 8128 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8129 } 8130 8131 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 8132 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8133 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8134 if (!AStmt) 8135 return StmtError(); 8136 8137 auto *CS = cast<CapturedStmt>(AStmt); 8138 // 1.2.2 OpenMP Language Terminology 8139 // Structured block - An executable statement with a single entry at the 8140 // top and a single exit at the bottom. 8141 // The point of exit cannot be a branch out of the structured block. 8142 // longjmp() and throw() must not violate the entry/exit criteria. 8143 CS->getCapturedDecl()->setNothrow(); 8144 for (int ThisCaptureLevel = 8145 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 8146 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8147 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8148 // 1.2.2 OpenMP Language Terminology 8149 // Structured block - An executable statement with a single entry at the 8150 // top and a single exit at the bottom. 8151 // The point of exit cannot be a branch out of the structured block. 8152 // longjmp() and throw() must not violate the entry/exit criteria. 8153 CS->getCapturedDecl()->setNothrow(); 8154 } 8155 8156 8157 OMPLoopDirective::HelperExprs B; 8158 // In presence of clause 'collapse' with number of loops, it will 8159 // define the nested loops number. 8160 unsigned NestedLoopCount = checkOpenMPLoop( 8161 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8162 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8163 VarsWithImplicitDSA, B); 8164 8165 if (NestedLoopCount == 0) 8166 return StmtError(); 8167 8168 assert((CurContext->isDependentContext() || B.builtAll()) && 8169 "omp teams distribute simd loop exprs were not built"); 8170 8171 if (!CurContext->isDependentContext()) { 8172 // Finalize the clauses that need pre-built expressions for CodeGen. 8173 for (OMPClause *C : Clauses) { 8174 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8175 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8176 B.NumIterations, *this, CurScope, 8177 DSAStack)) 8178 return StmtError(); 8179 } 8180 } 8181 8182 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8183 return StmtError(); 8184 8185 setFunctionHasBranchProtectedScope(); 8186 8187 DSAStack->setParentTeamsRegionLoc(StartLoc); 8188 8189 return OMPTeamsDistributeSimdDirective::Create( 8190 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8191 } 8192 8193 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 8194 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8195 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8196 if (!AStmt) 8197 return StmtError(); 8198 8199 auto *CS = cast<CapturedStmt>(AStmt); 8200 // 1.2.2 OpenMP Language Terminology 8201 // Structured block - An executable statement with a single entry at the 8202 // top and a single exit at the bottom. 8203 // The point of exit cannot be a branch out of the structured block. 8204 // longjmp() and throw() must not violate the entry/exit criteria. 8205 CS->getCapturedDecl()->setNothrow(); 8206 8207 for (int ThisCaptureLevel = 8208 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 8209 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8210 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8211 // 1.2.2 OpenMP Language Terminology 8212 // Structured block - An executable statement with a single entry at the 8213 // top and a single exit at the bottom. 8214 // The point of exit cannot be a branch out of the structured block. 8215 // longjmp() and throw() must not violate the entry/exit criteria. 8216 CS->getCapturedDecl()->setNothrow(); 8217 } 8218 8219 OMPLoopDirective::HelperExprs B; 8220 // In presence of clause 'collapse' with number of loops, it will 8221 // define the nested loops number. 8222 unsigned NestedLoopCount = checkOpenMPLoop( 8223 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8224 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8225 VarsWithImplicitDSA, B); 8226 8227 if (NestedLoopCount == 0) 8228 return StmtError(); 8229 8230 assert((CurContext->isDependentContext() || B.builtAll()) && 8231 "omp for loop exprs were not built"); 8232 8233 if (!CurContext->isDependentContext()) { 8234 // Finalize the clauses that need pre-built expressions for CodeGen. 8235 for (OMPClause *C : Clauses) { 8236 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8237 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8238 B.NumIterations, *this, CurScope, 8239 DSAStack)) 8240 return StmtError(); 8241 } 8242 } 8243 8244 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8245 return StmtError(); 8246 8247 setFunctionHasBranchProtectedScope(); 8248 8249 DSAStack->setParentTeamsRegionLoc(StartLoc); 8250 8251 return OMPTeamsDistributeParallelForSimdDirective::Create( 8252 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8253 } 8254 8255 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 8256 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8257 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8258 if (!AStmt) 8259 return StmtError(); 8260 8261 auto *CS = cast<CapturedStmt>(AStmt); 8262 // 1.2.2 OpenMP Language Terminology 8263 // Structured block - An executable statement with a single entry at the 8264 // top and a single exit at the bottom. 8265 // The point of exit cannot be a branch out of the structured block. 8266 // longjmp() and throw() must not violate the entry/exit criteria. 8267 CS->getCapturedDecl()->setNothrow(); 8268 8269 for (int ThisCaptureLevel = 8270 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 8271 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8272 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8273 // 1.2.2 OpenMP Language Terminology 8274 // Structured block - An executable statement with a single entry at the 8275 // top and a single exit at the bottom. 8276 // The point of exit cannot be a branch out of the structured block. 8277 // longjmp() and throw() must not violate the entry/exit criteria. 8278 CS->getCapturedDecl()->setNothrow(); 8279 } 8280 8281 OMPLoopDirective::HelperExprs B; 8282 // In presence of clause 'collapse' with number of loops, it will 8283 // define the nested loops number. 8284 unsigned NestedLoopCount = checkOpenMPLoop( 8285 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8286 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8287 VarsWithImplicitDSA, B); 8288 8289 if (NestedLoopCount == 0) 8290 return StmtError(); 8291 8292 assert((CurContext->isDependentContext() || B.builtAll()) && 8293 "omp for loop exprs were not built"); 8294 8295 setFunctionHasBranchProtectedScope(); 8296 8297 DSAStack->setParentTeamsRegionLoc(StartLoc); 8298 8299 return OMPTeamsDistributeParallelForDirective::Create( 8300 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8301 DSAStack->isCancelRegion()); 8302 } 8303 8304 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 8305 Stmt *AStmt, 8306 SourceLocation StartLoc, 8307 SourceLocation EndLoc) { 8308 if (!AStmt) 8309 return StmtError(); 8310 8311 auto *CS = cast<CapturedStmt>(AStmt); 8312 // 1.2.2 OpenMP Language Terminology 8313 // Structured block - An executable statement with a single entry at the 8314 // top and a single exit at the bottom. 8315 // The point of exit cannot be a branch out of the structured block. 8316 // longjmp() and throw() must not violate the entry/exit criteria. 8317 CS->getCapturedDecl()->setNothrow(); 8318 8319 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 8320 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8321 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8322 // 1.2.2 OpenMP Language Terminology 8323 // Structured block - An executable statement with a single entry at the 8324 // top and a single exit at the bottom. 8325 // The point of exit cannot be a branch out of the structured block. 8326 // longjmp() and throw() must not violate the entry/exit criteria. 8327 CS->getCapturedDecl()->setNothrow(); 8328 } 8329 setFunctionHasBranchProtectedScope(); 8330 8331 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 8332 AStmt); 8333 } 8334 8335 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 8336 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8337 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8338 if (!AStmt) 8339 return StmtError(); 8340 8341 auto *CS = cast<CapturedStmt>(AStmt); 8342 // 1.2.2 OpenMP Language Terminology 8343 // Structured block - An executable statement with a single entry at the 8344 // top and a single exit at the bottom. 8345 // The point of exit cannot be a branch out of the structured block. 8346 // longjmp() and throw() must not violate the entry/exit criteria. 8347 CS->getCapturedDecl()->setNothrow(); 8348 for (int ThisCaptureLevel = 8349 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 8350 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8351 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8352 // 1.2.2 OpenMP Language Terminology 8353 // Structured block - An executable statement with a single entry at the 8354 // top and a single exit at the bottom. 8355 // The point of exit cannot be a branch out of the structured block. 8356 // longjmp() and throw() must not violate the entry/exit criteria. 8357 CS->getCapturedDecl()->setNothrow(); 8358 } 8359 8360 OMPLoopDirective::HelperExprs B; 8361 // In presence of clause 'collapse' with number of loops, it will 8362 // define the nested loops number. 8363 unsigned NestedLoopCount = checkOpenMPLoop( 8364 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 8365 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8366 VarsWithImplicitDSA, B); 8367 if (NestedLoopCount == 0) 8368 return StmtError(); 8369 8370 assert((CurContext->isDependentContext() || B.builtAll()) && 8371 "omp target teams distribute loop exprs were not built"); 8372 8373 setFunctionHasBranchProtectedScope(); 8374 return OMPTargetTeamsDistributeDirective::Create( 8375 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8376 } 8377 8378 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 8379 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8380 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8381 if (!AStmt) 8382 return StmtError(); 8383 8384 auto *CS = cast<CapturedStmt>(AStmt); 8385 // 1.2.2 OpenMP Language Terminology 8386 // Structured block - An executable statement with a single entry at the 8387 // top and a single exit at the bottom. 8388 // The point of exit cannot be a branch out of the structured block. 8389 // longjmp() and throw() must not violate the entry/exit criteria. 8390 CS->getCapturedDecl()->setNothrow(); 8391 for (int ThisCaptureLevel = 8392 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 8393 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8394 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8395 // 1.2.2 OpenMP Language Terminology 8396 // Structured block - An executable statement with a single entry at the 8397 // top and a single exit at the bottom. 8398 // The point of exit cannot be a branch out of the structured block. 8399 // longjmp() and throw() must not violate the entry/exit criteria. 8400 CS->getCapturedDecl()->setNothrow(); 8401 } 8402 8403 OMPLoopDirective::HelperExprs B; 8404 // In presence of clause 'collapse' with number of loops, it will 8405 // define the nested loops number. 8406 unsigned NestedLoopCount = checkOpenMPLoop( 8407 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8408 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8409 VarsWithImplicitDSA, B); 8410 if (NestedLoopCount == 0) 8411 return StmtError(); 8412 8413 assert((CurContext->isDependentContext() || B.builtAll()) && 8414 "omp target teams distribute parallel for loop exprs were not built"); 8415 8416 if (!CurContext->isDependentContext()) { 8417 // Finalize the clauses that need pre-built expressions for CodeGen. 8418 for (OMPClause *C : Clauses) { 8419 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8420 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8421 B.NumIterations, *this, CurScope, 8422 DSAStack)) 8423 return StmtError(); 8424 } 8425 } 8426 8427 setFunctionHasBranchProtectedScope(); 8428 return OMPTargetTeamsDistributeParallelForDirective::Create( 8429 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8430 DSAStack->isCancelRegion()); 8431 } 8432 8433 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 8434 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8435 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8436 if (!AStmt) 8437 return StmtError(); 8438 8439 auto *CS = cast<CapturedStmt>(AStmt); 8440 // 1.2.2 OpenMP Language Terminology 8441 // Structured block - An executable statement with a single entry at the 8442 // top and a single exit at the bottom. 8443 // The point of exit cannot be a branch out of the structured block. 8444 // longjmp() and throw() must not violate the entry/exit criteria. 8445 CS->getCapturedDecl()->setNothrow(); 8446 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 8447 OMPD_target_teams_distribute_parallel_for_simd); 8448 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8449 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8450 // 1.2.2 OpenMP Language Terminology 8451 // Structured block - An executable statement with a single entry at the 8452 // top and a single exit at the bottom. 8453 // The point of exit cannot be a branch out of the structured block. 8454 // longjmp() and throw() must not violate the entry/exit criteria. 8455 CS->getCapturedDecl()->setNothrow(); 8456 } 8457 8458 OMPLoopDirective::HelperExprs B; 8459 // In presence of clause 'collapse' with number of loops, it will 8460 // define the nested loops number. 8461 unsigned NestedLoopCount = 8462 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 8463 getCollapseNumberExpr(Clauses), 8464 nullptr /*ordered not a clause on distribute*/, CS, *this, 8465 *DSAStack, VarsWithImplicitDSA, B); 8466 if (NestedLoopCount == 0) 8467 return StmtError(); 8468 8469 assert((CurContext->isDependentContext() || B.builtAll()) && 8470 "omp target teams distribute parallel for simd loop exprs were not " 8471 "built"); 8472 8473 if (!CurContext->isDependentContext()) { 8474 // Finalize the clauses that need pre-built expressions for CodeGen. 8475 for (OMPClause *C : Clauses) { 8476 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8477 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8478 B.NumIterations, *this, CurScope, 8479 DSAStack)) 8480 return StmtError(); 8481 } 8482 } 8483 8484 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8485 return StmtError(); 8486 8487 setFunctionHasBranchProtectedScope(); 8488 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 8489 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8490 } 8491 8492 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 8493 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8494 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8495 if (!AStmt) 8496 return StmtError(); 8497 8498 auto *CS = cast<CapturedStmt>(AStmt); 8499 // 1.2.2 OpenMP Language Terminology 8500 // Structured block - An executable statement with a single entry at the 8501 // top and a single exit at the bottom. 8502 // The point of exit cannot be a branch out of the structured block. 8503 // longjmp() and throw() must not violate the entry/exit criteria. 8504 CS->getCapturedDecl()->setNothrow(); 8505 for (int ThisCaptureLevel = 8506 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 8507 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8508 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8509 // 1.2.2 OpenMP Language Terminology 8510 // Structured block - An executable statement with a single entry at the 8511 // top and a single exit at the bottom. 8512 // The point of exit cannot be a branch out of the structured block. 8513 // longjmp() and throw() must not violate the entry/exit criteria. 8514 CS->getCapturedDecl()->setNothrow(); 8515 } 8516 8517 OMPLoopDirective::HelperExprs B; 8518 // In presence of clause 'collapse' with number of loops, it will 8519 // define the nested loops number. 8520 unsigned NestedLoopCount = checkOpenMPLoop( 8521 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8522 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8523 VarsWithImplicitDSA, B); 8524 if (NestedLoopCount == 0) 8525 return StmtError(); 8526 8527 assert((CurContext->isDependentContext() || B.builtAll()) && 8528 "omp target teams distribute simd loop exprs were not built"); 8529 8530 if (!CurContext->isDependentContext()) { 8531 // Finalize the clauses that need pre-built expressions for CodeGen. 8532 for (OMPClause *C : Clauses) { 8533 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8534 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8535 B.NumIterations, *this, CurScope, 8536 DSAStack)) 8537 return StmtError(); 8538 } 8539 } 8540 8541 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8542 return StmtError(); 8543 8544 setFunctionHasBranchProtectedScope(); 8545 return OMPTargetTeamsDistributeSimdDirective::Create( 8546 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8547 } 8548 8549 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 8550 SourceLocation StartLoc, 8551 SourceLocation LParenLoc, 8552 SourceLocation EndLoc) { 8553 OMPClause *Res = nullptr; 8554 switch (Kind) { 8555 case OMPC_final: 8556 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 8557 break; 8558 case OMPC_num_threads: 8559 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 8560 break; 8561 case OMPC_safelen: 8562 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 8563 break; 8564 case OMPC_simdlen: 8565 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 8566 break; 8567 case OMPC_allocator: 8568 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 8569 break; 8570 case OMPC_collapse: 8571 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 8572 break; 8573 case OMPC_ordered: 8574 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 8575 break; 8576 case OMPC_device: 8577 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 8578 break; 8579 case OMPC_num_teams: 8580 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 8581 break; 8582 case OMPC_thread_limit: 8583 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 8584 break; 8585 case OMPC_priority: 8586 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 8587 break; 8588 case OMPC_grainsize: 8589 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 8590 break; 8591 case OMPC_num_tasks: 8592 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 8593 break; 8594 case OMPC_hint: 8595 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 8596 break; 8597 case OMPC_if: 8598 case OMPC_default: 8599 case OMPC_proc_bind: 8600 case OMPC_schedule: 8601 case OMPC_private: 8602 case OMPC_firstprivate: 8603 case OMPC_lastprivate: 8604 case OMPC_shared: 8605 case OMPC_reduction: 8606 case OMPC_task_reduction: 8607 case OMPC_in_reduction: 8608 case OMPC_linear: 8609 case OMPC_aligned: 8610 case OMPC_copyin: 8611 case OMPC_copyprivate: 8612 case OMPC_nowait: 8613 case OMPC_untied: 8614 case OMPC_mergeable: 8615 case OMPC_threadprivate: 8616 case OMPC_allocate: 8617 case OMPC_flush: 8618 case OMPC_read: 8619 case OMPC_write: 8620 case OMPC_update: 8621 case OMPC_capture: 8622 case OMPC_seq_cst: 8623 case OMPC_depend: 8624 case OMPC_threads: 8625 case OMPC_simd: 8626 case OMPC_map: 8627 case OMPC_nogroup: 8628 case OMPC_dist_schedule: 8629 case OMPC_defaultmap: 8630 case OMPC_unknown: 8631 case OMPC_uniform: 8632 case OMPC_to: 8633 case OMPC_from: 8634 case OMPC_use_device_ptr: 8635 case OMPC_is_device_ptr: 8636 case OMPC_unified_address: 8637 case OMPC_unified_shared_memory: 8638 case OMPC_reverse_offload: 8639 case OMPC_dynamic_allocators: 8640 case OMPC_atomic_default_mem_order: 8641 llvm_unreachable("Clause is not allowed."); 8642 } 8643 return Res; 8644 } 8645 8646 // An OpenMP directive such as 'target parallel' has two captured regions: 8647 // for the 'target' and 'parallel' respectively. This function returns 8648 // the region in which to capture expressions associated with a clause. 8649 // A return value of OMPD_unknown signifies that the expression should not 8650 // be captured. 8651 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 8652 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 8653 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 8654 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 8655 switch (CKind) { 8656 case OMPC_if: 8657 switch (DKind) { 8658 case OMPD_target_parallel: 8659 case OMPD_target_parallel_for: 8660 case OMPD_target_parallel_for_simd: 8661 // If this clause applies to the nested 'parallel' region, capture within 8662 // the 'target' region, otherwise do not capture. 8663 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 8664 CaptureRegion = OMPD_target; 8665 break; 8666 case OMPD_target_teams_distribute_parallel_for: 8667 case OMPD_target_teams_distribute_parallel_for_simd: 8668 // If this clause applies to the nested 'parallel' region, capture within 8669 // the 'teams' region, otherwise do not capture. 8670 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 8671 CaptureRegion = OMPD_teams; 8672 break; 8673 case OMPD_teams_distribute_parallel_for: 8674 case OMPD_teams_distribute_parallel_for_simd: 8675 CaptureRegion = OMPD_teams; 8676 break; 8677 case OMPD_target_update: 8678 case OMPD_target_enter_data: 8679 case OMPD_target_exit_data: 8680 CaptureRegion = OMPD_task; 8681 break; 8682 case OMPD_cancel: 8683 case OMPD_parallel: 8684 case OMPD_parallel_sections: 8685 case OMPD_parallel_for: 8686 case OMPD_parallel_for_simd: 8687 case OMPD_target: 8688 case OMPD_target_simd: 8689 case OMPD_target_teams: 8690 case OMPD_target_teams_distribute: 8691 case OMPD_target_teams_distribute_simd: 8692 case OMPD_distribute_parallel_for: 8693 case OMPD_distribute_parallel_for_simd: 8694 case OMPD_task: 8695 case OMPD_taskloop: 8696 case OMPD_taskloop_simd: 8697 case OMPD_target_data: 8698 // Do not capture if-clause expressions. 8699 break; 8700 case OMPD_threadprivate: 8701 case OMPD_allocate: 8702 case OMPD_taskyield: 8703 case OMPD_barrier: 8704 case OMPD_taskwait: 8705 case OMPD_cancellation_point: 8706 case OMPD_flush: 8707 case OMPD_declare_reduction: 8708 case OMPD_declare_mapper: 8709 case OMPD_declare_simd: 8710 case OMPD_declare_target: 8711 case OMPD_end_declare_target: 8712 case OMPD_teams: 8713 case OMPD_simd: 8714 case OMPD_for: 8715 case OMPD_for_simd: 8716 case OMPD_sections: 8717 case OMPD_section: 8718 case OMPD_single: 8719 case OMPD_master: 8720 case OMPD_critical: 8721 case OMPD_taskgroup: 8722 case OMPD_distribute: 8723 case OMPD_ordered: 8724 case OMPD_atomic: 8725 case OMPD_distribute_simd: 8726 case OMPD_teams_distribute: 8727 case OMPD_teams_distribute_simd: 8728 case OMPD_requires: 8729 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 8730 case OMPD_unknown: 8731 llvm_unreachable("Unknown OpenMP directive"); 8732 } 8733 break; 8734 case OMPC_num_threads: 8735 switch (DKind) { 8736 case OMPD_target_parallel: 8737 case OMPD_target_parallel_for: 8738 case OMPD_target_parallel_for_simd: 8739 CaptureRegion = OMPD_target; 8740 break; 8741 case OMPD_teams_distribute_parallel_for: 8742 case OMPD_teams_distribute_parallel_for_simd: 8743 case OMPD_target_teams_distribute_parallel_for: 8744 case OMPD_target_teams_distribute_parallel_for_simd: 8745 CaptureRegion = OMPD_teams; 8746 break; 8747 case OMPD_parallel: 8748 case OMPD_parallel_sections: 8749 case OMPD_parallel_for: 8750 case OMPD_parallel_for_simd: 8751 case OMPD_distribute_parallel_for: 8752 case OMPD_distribute_parallel_for_simd: 8753 // Do not capture num_threads-clause expressions. 8754 break; 8755 case OMPD_target_data: 8756 case OMPD_target_enter_data: 8757 case OMPD_target_exit_data: 8758 case OMPD_target_update: 8759 case OMPD_target: 8760 case OMPD_target_simd: 8761 case OMPD_target_teams: 8762 case OMPD_target_teams_distribute: 8763 case OMPD_target_teams_distribute_simd: 8764 case OMPD_cancel: 8765 case OMPD_task: 8766 case OMPD_taskloop: 8767 case OMPD_taskloop_simd: 8768 case OMPD_threadprivate: 8769 case OMPD_allocate: 8770 case OMPD_taskyield: 8771 case OMPD_barrier: 8772 case OMPD_taskwait: 8773 case OMPD_cancellation_point: 8774 case OMPD_flush: 8775 case OMPD_declare_reduction: 8776 case OMPD_declare_mapper: 8777 case OMPD_declare_simd: 8778 case OMPD_declare_target: 8779 case OMPD_end_declare_target: 8780 case OMPD_teams: 8781 case OMPD_simd: 8782 case OMPD_for: 8783 case OMPD_for_simd: 8784 case OMPD_sections: 8785 case OMPD_section: 8786 case OMPD_single: 8787 case OMPD_master: 8788 case OMPD_critical: 8789 case OMPD_taskgroup: 8790 case OMPD_distribute: 8791 case OMPD_ordered: 8792 case OMPD_atomic: 8793 case OMPD_distribute_simd: 8794 case OMPD_teams_distribute: 8795 case OMPD_teams_distribute_simd: 8796 case OMPD_requires: 8797 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 8798 case OMPD_unknown: 8799 llvm_unreachable("Unknown OpenMP directive"); 8800 } 8801 break; 8802 case OMPC_num_teams: 8803 switch (DKind) { 8804 case OMPD_target_teams: 8805 case OMPD_target_teams_distribute: 8806 case OMPD_target_teams_distribute_simd: 8807 case OMPD_target_teams_distribute_parallel_for: 8808 case OMPD_target_teams_distribute_parallel_for_simd: 8809 CaptureRegion = OMPD_target; 8810 break; 8811 case OMPD_teams_distribute_parallel_for: 8812 case OMPD_teams_distribute_parallel_for_simd: 8813 case OMPD_teams: 8814 case OMPD_teams_distribute: 8815 case OMPD_teams_distribute_simd: 8816 // Do not capture num_teams-clause expressions. 8817 break; 8818 case OMPD_distribute_parallel_for: 8819 case OMPD_distribute_parallel_for_simd: 8820 case OMPD_task: 8821 case OMPD_taskloop: 8822 case OMPD_taskloop_simd: 8823 case OMPD_target_data: 8824 case OMPD_target_enter_data: 8825 case OMPD_target_exit_data: 8826 case OMPD_target_update: 8827 case OMPD_cancel: 8828 case OMPD_parallel: 8829 case OMPD_parallel_sections: 8830 case OMPD_parallel_for: 8831 case OMPD_parallel_for_simd: 8832 case OMPD_target: 8833 case OMPD_target_simd: 8834 case OMPD_target_parallel: 8835 case OMPD_target_parallel_for: 8836 case OMPD_target_parallel_for_simd: 8837 case OMPD_threadprivate: 8838 case OMPD_allocate: 8839 case OMPD_taskyield: 8840 case OMPD_barrier: 8841 case OMPD_taskwait: 8842 case OMPD_cancellation_point: 8843 case OMPD_flush: 8844 case OMPD_declare_reduction: 8845 case OMPD_declare_mapper: 8846 case OMPD_declare_simd: 8847 case OMPD_declare_target: 8848 case OMPD_end_declare_target: 8849 case OMPD_simd: 8850 case OMPD_for: 8851 case OMPD_for_simd: 8852 case OMPD_sections: 8853 case OMPD_section: 8854 case OMPD_single: 8855 case OMPD_master: 8856 case OMPD_critical: 8857 case OMPD_taskgroup: 8858 case OMPD_distribute: 8859 case OMPD_ordered: 8860 case OMPD_atomic: 8861 case OMPD_distribute_simd: 8862 case OMPD_requires: 8863 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 8864 case OMPD_unknown: 8865 llvm_unreachable("Unknown OpenMP directive"); 8866 } 8867 break; 8868 case OMPC_thread_limit: 8869 switch (DKind) { 8870 case OMPD_target_teams: 8871 case OMPD_target_teams_distribute: 8872 case OMPD_target_teams_distribute_simd: 8873 case OMPD_target_teams_distribute_parallel_for: 8874 case OMPD_target_teams_distribute_parallel_for_simd: 8875 CaptureRegion = OMPD_target; 8876 break; 8877 case OMPD_teams_distribute_parallel_for: 8878 case OMPD_teams_distribute_parallel_for_simd: 8879 case OMPD_teams: 8880 case OMPD_teams_distribute: 8881 case OMPD_teams_distribute_simd: 8882 // Do not capture thread_limit-clause expressions. 8883 break; 8884 case OMPD_distribute_parallel_for: 8885 case OMPD_distribute_parallel_for_simd: 8886 case OMPD_task: 8887 case OMPD_taskloop: 8888 case OMPD_taskloop_simd: 8889 case OMPD_target_data: 8890 case OMPD_target_enter_data: 8891 case OMPD_target_exit_data: 8892 case OMPD_target_update: 8893 case OMPD_cancel: 8894 case OMPD_parallel: 8895 case OMPD_parallel_sections: 8896 case OMPD_parallel_for: 8897 case OMPD_parallel_for_simd: 8898 case OMPD_target: 8899 case OMPD_target_simd: 8900 case OMPD_target_parallel: 8901 case OMPD_target_parallel_for: 8902 case OMPD_target_parallel_for_simd: 8903 case OMPD_threadprivate: 8904 case OMPD_allocate: 8905 case OMPD_taskyield: 8906 case OMPD_barrier: 8907 case OMPD_taskwait: 8908 case OMPD_cancellation_point: 8909 case OMPD_flush: 8910 case OMPD_declare_reduction: 8911 case OMPD_declare_mapper: 8912 case OMPD_declare_simd: 8913 case OMPD_declare_target: 8914 case OMPD_end_declare_target: 8915 case OMPD_simd: 8916 case OMPD_for: 8917 case OMPD_for_simd: 8918 case OMPD_sections: 8919 case OMPD_section: 8920 case OMPD_single: 8921 case OMPD_master: 8922 case OMPD_critical: 8923 case OMPD_taskgroup: 8924 case OMPD_distribute: 8925 case OMPD_ordered: 8926 case OMPD_atomic: 8927 case OMPD_distribute_simd: 8928 case OMPD_requires: 8929 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 8930 case OMPD_unknown: 8931 llvm_unreachable("Unknown OpenMP directive"); 8932 } 8933 break; 8934 case OMPC_schedule: 8935 switch (DKind) { 8936 case OMPD_parallel_for: 8937 case OMPD_parallel_for_simd: 8938 case OMPD_distribute_parallel_for: 8939 case OMPD_distribute_parallel_for_simd: 8940 case OMPD_teams_distribute_parallel_for: 8941 case OMPD_teams_distribute_parallel_for_simd: 8942 case OMPD_target_parallel_for: 8943 case OMPD_target_parallel_for_simd: 8944 case OMPD_target_teams_distribute_parallel_for: 8945 case OMPD_target_teams_distribute_parallel_for_simd: 8946 CaptureRegion = OMPD_parallel; 8947 break; 8948 case OMPD_for: 8949 case OMPD_for_simd: 8950 // Do not capture schedule-clause expressions. 8951 break; 8952 case OMPD_task: 8953 case OMPD_taskloop: 8954 case OMPD_taskloop_simd: 8955 case OMPD_target_data: 8956 case OMPD_target_enter_data: 8957 case OMPD_target_exit_data: 8958 case OMPD_target_update: 8959 case OMPD_teams: 8960 case OMPD_teams_distribute: 8961 case OMPD_teams_distribute_simd: 8962 case OMPD_target_teams_distribute: 8963 case OMPD_target_teams_distribute_simd: 8964 case OMPD_target: 8965 case OMPD_target_simd: 8966 case OMPD_target_parallel: 8967 case OMPD_cancel: 8968 case OMPD_parallel: 8969 case OMPD_parallel_sections: 8970 case OMPD_threadprivate: 8971 case OMPD_allocate: 8972 case OMPD_taskyield: 8973 case OMPD_barrier: 8974 case OMPD_taskwait: 8975 case OMPD_cancellation_point: 8976 case OMPD_flush: 8977 case OMPD_declare_reduction: 8978 case OMPD_declare_mapper: 8979 case OMPD_declare_simd: 8980 case OMPD_declare_target: 8981 case OMPD_end_declare_target: 8982 case OMPD_simd: 8983 case OMPD_sections: 8984 case OMPD_section: 8985 case OMPD_single: 8986 case OMPD_master: 8987 case OMPD_critical: 8988 case OMPD_taskgroup: 8989 case OMPD_distribute: 8990 case OMPD_ordered: 8991 case OMPD_atomic: 8992 case OMPD_distribute_simd: 8993 case OMPD_target_teams: 8994 case OMPD_requires: 8995 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 8996 case OMPD_unknown: 8997 llvm_unreachable("Unknown OpenMP directive"); 8998 } 8999 break; 9000 case OMPC_dist_schedule: 9001 switch (DKind) { 9002 case OMPD_teams_distribute_parallel_for: 9003 case OMPD_teams_distribute_parallel_for_simd: 9004 case OMPD_teams_distribute: 9005 case OMPD_teams_distribute_simd: 9006 case OMPD_target_teams_distribute_parallel_for: 9007 case OMPD_target_teams_distribute_parallel_for_simd: 9008 case OMPD_target_teams_distribute: 9009 case OMPD_target_teams_distribute_simd: 9010 CaptureRegion = OMPD_teams; 9011 break; 9012 case OMPD_distribute_parallel_for: 9013 case OMPD_distribute_parallel_for_simd: 9014 case OMPD_distribute: 9015 case OMPD_distribute_simd: 9016 // Do not capture thread_limit-clause expressions. 9017 break; 9018 case OMPD_parallel_for: 9019 case OMPD_parallel_for_simd: 9020 case OMPD_target_parallel_for_simd: 9021 case OMPD_target_parallel_for: 9022 case OMPD_task: 9023 case OMPD_taskloop: 9024 case OMPD_taskloop_simd: 9025 case OMPD_target_data: 9026 case OMPD_target_enter_data: 9027 case OMPD_target_exit_data: 9028 case OMPD_target_update: 9029 case OMPD_teams: 9030 case OMPD_target: 9031 case OMPD_target_simd: 9032 case OMPD_target_parallel: 9033 case OMPD_cancel: 9034 case OMPD_parallel: 9035 case OMPD_parallel_sections: 9036 case OMPD_threadprivate: 9037 case OMPD_allocate: 9038 case OMPD_taskyield: 9039 case OMPD_barrier: 9040 case OMPD_taskwait: 9041 case OMPD_cancellation_point: 9042 case OMPD_flush: 9043 case OMPD_declare_reduction: 9044 case OMPD_declare_mapper: 9045 case OMPD_declare_simd: 9046 case OMPD_declare_target: 9047 case OMPD_end_declare_target: 9048 case OMPD_simd: 9049 case OMPD_for: 9050 case OMPD_for_simd: 9051 case OMPD_sections: 9052 case OMPD_section: 9053 case OMPD_single: 9054 case OMPD_master: 9055 case OMPD_critical: 9056 case OMPD_taskgroup: 9057 case OMPD_ordered: 9058 case OMPD_atomic: 9059 case OMPD_target_teams: 9060 case OMPD_requires: 9061 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9062 case OMPD_unknown: 9063 llvm_unreachable("Unknown OpenMP directive"); 9064 } 9065 break; 9066 case OMPC_device: 9067 switch (DKind) { 9068 case OMPD_target_update: 9069 case OMPD_target_enter_data: 9070 case OMPD_target_exit_data: 9071 case OMPD_target: 9072 case OMPD_target_simd: 9073 case OMPD_target_teams: 9074 case OMPD_target_parallel: 9075 case OMPD_target_teams_distribute: 9076 case OMPD_target_teams_distribute_simd: 9077 case OMPD_target_parallel_for: 9078 case OMPD_target_parallel_for_simd: 9079 case OMPD_target_teams_distribute_parallel_for: 9080 case OMPD_target_teams_distribute_parallel_for_simd: 9081 CaptureRegion = OMPD_task; 9082 break; 9083 case OMPD_target_data: 9084 // Do not capture device-clause expressions. 9085 break; 9086 case OMPD_teams_distribute_parallel_for: 9087 case OMPD_teams_distribute_parallel_for_simd: 9088 case OMPD_teams: 9089 case OMPD_teams_distribute: 9090 case OMPD_teams_distribute_simd: 9091 case OMPD_distribute_parallel_for: 9092 case OMPD_distribute_parallel_for_simd: 9093 case OMPD_task: 9094 case OMPD_taskloop: 9095 case OMPD_taskloop_simd: 9096 case OMPD_cancel: 9097 case OMPD_parallel: 9098 case OMPD_parallel_sections: 9099 case OMPD_parallel_for: 9100 case OMPD_parallel_for_simd: 9101 case OMPD_threadprivate: 9102 case OMPD_allocate: 9103 case OMPD_taskyield: 9104 case OMPD_barrier: 9105 case OMPD_taskwait: 9106 case OMPD_cancellation_point: 9107 case OMPD_flush: 9108 case OMPD_declare_reduction: 9109 case OMPD_declare_mapper: 9110 case OMPD_declare_simd: 9111 case OMPD_declare_target: 9112 case OMPD_end_declare_target: 9113 case OMPD_simd: 9114 case OMPD_for: 9115 case OMPD_for_simd: 9116 case OMPD_sections: 9117 case OMPD_section: 9118 case OMPD_single: 9119 case OMPD_master: 9120 case OMPD_critical: 9121 case OMPD_taskgroup: 9122 case OMPD_distribute: 9123 case OMPD_ordered: 9124 case OMPD_atomic: 9125 case OMPD_distribute_simd: 9126 case OMPD_requires: 9127 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9128 case OMPD_unknown: 9129 llvm_unreachable("Unknown OpenMP directive"); 9130 } 9131 break; 9132 case OMPC_firstprivate: 9133 case OMPC_lastprivate: 9134 case OMPC_reduction: 9135 case OMPC_task_reduction: 9136 case OMPC_in_reduction: 9137 case OMPC_linear: 9138 case OMPC_default: 9139 case OMPC_proc_bind: 9140 case OMPC_final: 9141 case OMPC_safelen: 9142 case OMPC_simdlen: 9143 case OMPC_allocator: 9144 case OMPC_collapse: 9145 case OMPC_private: 9146 case OMPC_shared: 9147 case OMPC_aligned: 9148 case OMPC_copyin: 9149 case OMPC_copyprivate: 9150 case OMPC_ordered: 9151 case OMPC_nowait: 9152 case OMPC_untied: 9153 case OMPC_mergeable: 9154 case OMPC_threadprivate: 9155 case OMPC_allocate: 9156 case OMPC_flush: 9157 case OMPC_read: 9158 case OMPC_write: 9159 case OMPC_update: 9160 case OMPC_capture: 9161 case OMPC_seq_cst: 9162 case OMPC_depend: 9163 case OMPC_threads: 9164 case OMPC_simd: 9165 case OMPC_map: 9166 case OMPC_priority: 9167 case OMPC_grainsize: 9168 case OMPC_nogroup: 9169 case OMPC_num_tasks: 9170 case OMPC_hint: 9171 case OMPC_defaultmap: 9172 case OMPC_unknown: 9173 case OMPC_uniform: 9174 case OMPC_to: 9175 case OMPC_from: 9176 case OMPC_use_device_ptr: 9177 case OMPC_is_device_ptr: 9178 case OMPC_unified_address: 9179 case OMPC_unified_shared_memory: 9180 case OMPC_reverse_offload: 9181 case OMPC_dynamic_allocators: 9182 case OMPC_atomic_default_mem_order: 9183 llvm_unreachable("Unexpected OpenMP clause."); 9184 } 9185 return CaptureRegion; 9186 } 9187 9188 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 9189 Expr *Condition, SourceLocation StartLoc, 9190 SourceLocation LParenLoc, 9191 SourceLocation NameModifierLoc, 9192 SourceLocation ColonLoc, 9193 SourceLocation EndLoc) { 9194 Expr *ValExpr = Condition; 9195 Stmt *HelperValStmt = nullptr; 9196 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9197 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9198 !Condition->isInstantiationDependent() && 9199 !Condition->containsUnexpandedParameterPack()) { 9200 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9201 if (Val.isInvalid()) 9202 return nullptr; 9203 9204 ValExpr = Val.get(); 9205 9206 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9207 CaptureRegion = 9208 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 9209 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9210 ValExpr = MakeFullExpr(ValExpr).get(); 9211 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9212 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9213 HelperValStmt = buildPreInits(Context, Captures); 9214 } 9215 } 9216 9217 return new (Context) 9218 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 9219 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 9220 } 9221 9222 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 9223 SourceLocation StartLoc, 9224 SourceLocation LParenLoc, 9225 SourceLocation EndLoc) { 9226 Expr *ValExpr = Condition; 9227 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9228 !Condition->isInstantiationDependent() && 9229 !Condition->containsUnexpandedParameterPack()) { 9230 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9231 if (Val.isInvalid()) 9232 return nullptr; 9233 9234 ValExpr = MakeFullExpr(Val.get()).get(); 9235 } 9236 9237 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 9238 } 9239 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 9240 Expr *Op) { 9241 if (!Op) 9242 return ExprError(); 9243 9244 class IntConvertDiagnoser : public ICEConvertDiagnoser { 9245 public: 9246 IntConvertDiagnoser() 9247 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 9248 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 9249 QualType T) override { 9250 return S.Diag(Loc, diag::err_omp_not_integral) << T; 9251 } 9252 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 9253 QualType T) override { 9254 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 9255 } 9256 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 9257 QualType T, 9258 QualType ConvTy) override { 9259 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 9260 } 9261 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 9262 QualType ConvTy) override { 9263 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9264 << ConvTy->isEnumeralType() << ConvTy; 9265 } 9266 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 9267 QualType T) override { 9268 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 9269 } 9270 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 9271 QualType ConvTy) override { 9272 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9273 << ConvTy->isEnumeralType() << ConvTy; 9274 } 9275 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 9276 QualType) override { 9277 llvm_unreachable("conversion functions are permitted"); 9278 } 9279 } ConvertDiagnoser; 9280 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 9281 } 9282 9283 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 9284 OpenMPClauseKind CKind, 9285 bool StrictlyPositive) { 9286 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 9287 !ValExpr->isInstantiationDependent()) { 9288 SourceLocation Loc = ValExpr->getExprLoc(); 9289 ExprResult Value = 9290 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 9291 if (Value.isInvalid()) 9292 return false; 9293 9294 ValExpr = Value.get(); 9295 // The expression must evaluate to a non-negative integer value. 9296 llvm::APSInt Result; 9297 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 9298 Result.isSigned() && 9299 !((!StrictlyPositive && Result.isNonNegative()) || 9300 (StrictlyPositive && Result.isStrictlyPositive()))) { 9301 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 9302 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9303 << ValExpr->getSourceRange(); 9304 return false; 9305 } 9306 } 9307 return true; 9308 } 9309 9310 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 9311 SourceLocation StartLoc, 9312 SourceLocation LParenLoc, 9313 SourceLocation EndLoc) { 9314 Expr *ValExpr = NumThreads; 9315 Stmt *HelperValStmt = nullptr; 9316 9317 // OpenMP [2.5, Restrictions] 9318 // The num_threads expression must evaluate to a positive integer value. 9319 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 9320 /*StrictlyPositive=*/true)) 9321 return nullptr; 9322 9323 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9324 OpenMPDirectiveKind CaptureRegion = 9325 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 9326 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9327 ValExpr = MakeFullExpr(ValExpr).get(); 9328 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9329 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9330 HelperValStmt = buildPreInits(Context, Captures); 9331 } 9332 9333 return new (Context) OMPNumThreadsClause( 9334 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 9335 } 9336 9337 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 9338 OpenMPClauseKind CKind, 9339 bool StrictlyPositive) { 9340 if (!E) 9341 return ExprError(); 9342 if (E->isValueDependent() || E->isTypeDependent() || 9343 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 9344 return E; 9345 llvm::APSInt Result; 9346 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 9347 if (ICE.isInvalid()) 9348 return ExprError(); 9349 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 9350 (!StrictlyPositive && !Result.isNonNegative())) { 9351 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 9352 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9353 << E->getSourceRange(); 9354 return ExprError(); 9355 } 9356 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 9357 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 9358 << E->getSourceRange(); 9359 return ExprError(); 9360 } 9361 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 9362 DSAStack->setAssociatedLoops(Result.getExtValue()); 9363 else if (CKind == OMPC_ordered) 9364 DSAStack->setAssociatedLoops(Result.getExtValue()); 9365 return ICE; 9366 } 9367 9368 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 9369 SourceLocation LParenLoc, 9370 SourceLocation EndLoc) { 9371 // OpenMP [2.8.1, simd construct, Description] 9372 // The parameter of the safelen clause must be a constant 9373 // positive integer expression. 9374 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 9375 if (Safelen.isInvalid()) 9376 return nullptr; 9377 return new (Context) 9378 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 9379 } 9380 9381 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 9382 SourceLocation LParenLoc, 9383 SourceLocation EndLoc) { 9384 // OpenMP [2.8.1, simd construct, Description] 9385 // The parameter of the simdlen clause must be a constant 9386 // positive integer expression. 9387 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 9388 if (Simdlen.isInvalid()) 9389 return nullptr; 9390 return new (Context) 9391 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 9392 } 9393 9394 /// Tries to find omp_allocator_handle_t type. 9395 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 9396 DSAStackTy *Stack) { 9397 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 9398 if (!OMPAllocatorHandleT.isNull()) 9399 return true; 9400 // Build the predefined allocator expressions. 9401 bool ErrorFound = false; 9402 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 9403 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 9404 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 9405 StringRef Allocator = 9406 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 9407 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 9408 auto *VD = dyn_cast_or_null<ValueDecl>( 9409 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 9410 if (!VD) { 9411 ErrorFound = true; 9412 break; 9413 } 9414 QualType AllocatorType = 9415 VD->getType().getNonLValueExprType(S.getASTContext()); 9416 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 9417 if (!Res.isUsable()) { 9418 ErrorFound = true; 9419 break; 9420 } 9421 if (OMPAllocatorHandleT.isNull()) 9422 OMPAllocatorHandleT = AllocatorType; 9423 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 9424 ErrorFound = true; 9425 break; 9426 } 9427 Stack->setAllocator(AllocatorKind, Res.get()); 9428 } 9429 if (ErrorFound) { 9430 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 9431 return false; 9432 } 9433 OMPAllocatorHandleT.addConst(); 9434 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 9435 return true; 9436 } 9437 9438 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 9439 SourceLocation LParenLoc, 9440 SourceLocation EndLoc) { 9441 // OpenMP [2.11.3, allocate Directive, Description] 9442 // allocator is an expression of omp_allocator_handle_t type. 9443 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 9444 return nullptr; 9445 9446 ExprResult Allocator = DefaultLvalueConversion(A); 9447 if (Allocator.isInvalid()) 9448 return nullptr; 9449 Allocator = PerformImplicitConversion(Allocator.get(), 9450 DSAStack->getOMPAllocatorHandleT(), 9451 Sema::AA_Initializing, 9452 /*AllowExplicit=*/true); 9453 if (Allocator.isInvalid()) 9454 return nullptr; 9455 return new (Context) 9456 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 9457 } 9458 9459 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 9460 SourceLocation StartLoc, 9461 SourceLocation LParenLoc, 9462 SourceLocation EndLoc) { 9463 // OpenMP [2.7.1, loop construct, Description] 9464 // OpenMP [2.8.1, simd construct, Description] 9465 // OpenMP [2.9.6, distribute construct, Description] 9466 // The parameter of the collapse clause must be a constant 9467 // positive integer expression. 9468 ExprResult NumForLoopsResult = 9469 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 9470 if (NumForLoopsResult.isInvalid()) 9471 return nullptr; 9472 return new (Context) 9473 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 9474 } 9475 9476 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 9477 SourceLocation EndLoc, 9478 SourceLocation LParenLoc, 9479 Expr *NumForLoops) { 9480 // OpenMP [2.7.1, loop construct, Description] 9481 // OpenMP [2.8.1, simd construct, Description] 9482 // OpenMP [2.9.6, distribute construct, Description] 9483 // The parameter of the ordered clause must be a constant 9484 // positive integer expression if any. 9485 if (NumForLoops && LParenLoc.isValid()) { 9486 ExprResult NumForLoopsResult = 9487 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 9488 if (NumForLoopsResult.isInvalid()) 9489 return nullptr; 9490 NumForLoops = NumForLoopsResult.get(); 9491 } else { 9492 NumForLoops = nullptr; 9493 } 9494 auto *Clause = OMPOrderedClause::Create( 9495 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 9496 StartLoc, LParenLoc, EndLoc); 9497 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 9498 return Clause; 9499 } 9500 9501 OMPClause *Sema::ActOnOpenMPSimpleClause( 9502 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 9503 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 9504 OMPClause *Res = nullptr; 9505 switch (Kind) { 9506 case OMPC_default: 9507 Res = 9508 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 9509 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 9510 break; 9511 case OMPC_proc_bind: 9512 Res = ActOnOpenMPProcBindClause( 9513 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 9514 LParenLoc, EndLoc); 9515 break; 9516 case OMPC_atomic_default_mem_order: 9517 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 9518 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 9519 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 9520 break; 9521 case OMPC_if: 9522 case OMPC_final: 9523 case OMPC_num_threads: 9524 case OMPC_safelen: 9525 case OMPC_simdlen: 9526 case OMPC_allocator: 9527 case OMPC_collapse: 9528 case OMPC_schedule: 9529 case OMPC_private: 9530 case OMPC_firstprivate: 9531 case OMPC_lastprivate: 9532 case OMPC_shared: 9533 case OMPC_reduction: 9534 case OMPC_task_reduction: 9535 case OMPC_in_reduction: 9536 case OMPC_linear: 9537 case OMPC_aligned: 9538 case OMPC_copyin: 9539 case OMPC_copyprivate: 9540 case OMPC_ordered: 9541 case OMPC_nowait: 9542 case OMPC_untied: 9543 case OMPC_mergeable: 9544 case OMPC_threadprivate: 9545 case OMPC_allocate: 9546 case OMPC_flush: 9547 case OMPC_read: 9548 case OMPC_write: 9549 case OMPC_update: 9550 case OMPC_capture: 9551 case OMPC_seq_cst: 9552 case OMPC_depend: 9553 case OMPC_device: 9554 case OMPC_threads: 9555 case OMPC_simd: 9556 case OMPC_map: 9557 case OMPC_num_teams: 9558 case OMPC_thread_limit: 9559 case OMPC_priority: 9560 case OMPC_grainsize: 9561 case OMPC_nogroup: 9562 case OMPC_num_tasks: 9563 case OMPC_hint: 9564 case OMPC_dist_schedule: 9565 case OMPC_defaultmap: 9566 case OMPC_unknown: 9567 case OMPC_uniform: 9568 case OMPC_to: 9569 case OMPC_from: 9570 case OMPC_use_device_ptr: 9571 case OMPC_is_device_ptr: 9572 case OMPC_unified_address: 9573 case OMPC_unified_shared_memory: 9574 case OMPC_reverse_offload: 9575 case OMPC_dynamic_allocators: 9576 llvm_unreachable("Clause is not allowed."); 9577 } 9578 return Res; 9579 } 9580 9581 static std::string 9582 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 9583 ArrayRef<unsigned> Exclude = llvm::None) { 9584 SmallString<256> Buffer; 9585 llvm::raw_svector_ostream Out(Buffer); 9586 unsigned Bound = Last >= 2 ? Last - 2 : 0; 9587 unsigned Skipped = Exclude.size(); 9588 auto S = Exclude.begin(), E = Exclude.end(); 9589 for (unsigned I = First; I < Last; ++I) { 9590 if (std::find(S, E, I) != E) { 9591 --Skipped; 9592 continue; 9593 } 9594 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 9595 if (I == Bound - Skipped) 9596 Out << " or "; 9597 else if (I != Bound + 1 - Skipped) 9598 Out << ", "; 9599 } 9600 return Out.str(); 9601 } 9602 9603 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 9604 SourceLocation KindKwLoc, 9605 SourceLocation StartLoc, 9606 SourceLocation LParenLoc, 9607 SourceLocation EndLoc) { 9608 if (Kind == OMPC_DEFAULT_unknown) { 9609 static_assert(OMPC_DEFAULT_unknown > 0, 9610 "OMPC_DEFAULT_unknown not greater than 0"); 9611 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9612 << getListOfPossibleValues(OMPC_default, /*First=*/0, 9613 /*Last=*/OMPC_DEFAULT_unknown) 9614 << getOpenMPClauseName(OMPC_default); 9615 return nullptr; 9616 } 9617 switch (Kind) { 9618 case OMPC_DEFAULT_none: 9619 DSAStack->setDefaultDSANone(KindKwLoc); 9620 break; 9621 case OMPC_DEFAULT_shared: 9622 DSAStack->setDefaultDSAShared(KindKwLoc); 9623 break; 9624 case OMPC_DEFAULT_unknown: 9625 llvm_unreachable("Clause kind is not allowed."); 9626 break; 9627 } 9628 return new (Context) 9629 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 9630 } 9631 9632 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 9633 SourceLocation KindKwLoc, 9634 SourceLocation StartLoc, 9635 SourceLocation LParenLoc, 9636 SourceLocation EndLoc) { 9637 if (Kind == OMPC_PROC_BIND_unknown) { 9638 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9639 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 9640 /*Last=*/OMPC_PROC_BIND_unknown) 9641 << getOpenMPClauseName(OMPC_proc_bind); 9642 return nullptr; 9643 } 9644 return new (Context) 9645 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 9646 } 9647 9648 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 9649 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 9650 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 9651 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 9652 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9653 << getListOfPossibleValues( 9654 OMPC_atomic_default_mem_order, /*First=*/0, 9655 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 9656 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 9657 return nullptr; 9658 } 9659 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 9660 LParenLoc, EndLoc); 9661 } 9662 9663 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 9664 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 9665 SourceLocation StartLoc, SourceLocation LParenLoc, 9666 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 9667 SourceLocation EndLoc) { 9668 OMPClause *Res = nullptr; 9669 switch (Kind) { 9670 case OMPC_schedule: 9671 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 9672 assert(Argument.size() == NumberOfElements && 9673 ArgumentLoc.size() == NumberOfElements); 9674 Res = ActOnOpenMPScheduleClause( 9675 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 9676 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 9677 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 9678 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 9679 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 9680 break; 9681 case OMPC_if: 9682 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 9683 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 9684 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 9685 DelimLoc, EndLoc); 9686 break; 9687 case OMPC_dist_schedule: 9688 Res = ActOnOpenMPDistScheduleClause( 9689 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 9690 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 9691 break; 9692 case OMPC_defaultmap: 9693 enum { Modifier, DefaultmapKind }; 9694 Res = ActOnOpenMPDefaultmapClause( 9695 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 9696 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 9697 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 9698 EndLoc); 9699 break; 9700 case OMPC_final: 9701 case OMPC_num_threads: 9702 case OMPC_safelen: 9703 case OMPC_simdlen: 9704 case OMPC_allocator: 9705 case OMPC_collapse: 9706 case OMPC_default: 9707 case OMPC_proc_bind: 9708 case OMPC_private: 9709 case OMPC_firstprivate: 9710 case OMPC_lastprivate: 9711 case OMPC_shared: 9712 case OMPC_reduction: 9713 case OMPC_task_reduction: 9714 case OMPC_in_reduction: 9715 case OMPC_linear: 9716 case OMPC_aligned: 9717 case OMPC_copyin: 9718 case OMPC_copyprivate: 9719 case OMPC_ordered: 9720 case OMPC_nowait: 9721 case OMPC_untied: 9722 case OMPC_mergeable: 9723 case OMPC_threadprivate: 9724 case OMPC_allocate: 9725 case OMPC_flush: 9726 case OMPC_read: 9727 case OMPC_write: 9728 case OMPC_update: 9729 case OMPC_capture: 9730 case OMPC_seq_cst: 9731 case OMPC_depend: 9732 case OMPC_device: 9733 case OMPC_threads: 9734 case OMPC_simd: 9735 case OMPC_map: 9736 case OMPC_num_teams: 9737 case OMPC_thread_limit: 9738 case OMPC_priority: 9739 case OMPC_grainsize: 9740 case OMPC_nogroup: 9741 case OMPC_num_tasks: 9742 case OMPC_hint: 9743 case OMPC_unknown: 9744 case OMPC_uniform: 9745 case OMPC_to: 9746 case OMPC_from: 9747 case OMPC_use_device_ptr: 9748 case OMPC_is_device_ptr: 9749 case OMPC_unified_address: 9750 case OMPC_unified_shared_memory: 9751 case OMPC_reverse_offload: 9752 case OMPC_dynamic_allocators: 9753 case OMPC_atomic_default_mem_order: 9754 llvm_unreachable("Clause is not allowed."); 9755 } 9756 return Res; 9757 } 9758 9759 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 9760 OpenMPScheduleClauseModifier M2, 9761 SourceLocation M1Loc, SourceLocation M2Loc) { 9762 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 9763 SmallVector<unsigned, 2> Excluded; 9764 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 9765 Excluded.push_back(M2); 9766 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 9767 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 9768 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 9769 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 9770 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 9771 << getListOfPossibleValues(OMPC_schedule, 9772 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 9773 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 9774 Excluded) 9775 << getOpenMPClauseName(OMPC_schedule); 9776 return true; 9777 } 9778 return false; 9779 } 9780 9781 OMPClause *Sema::ActOnOpenMPScheduleClause( 9782 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 9783 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 9784 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 9785 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 9786 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 9787 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 9788 return nullptr; 9789 // OpenMP, 2.7.1, Loop Construct, Restrictions 9790 // Either the monotonic modifier or the nonmonotonic modifier can be specified 9791 // but not both. 9792 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 9793 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 9794 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 9795 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 9796 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 9797 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 9798 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 9799 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 9800 return nullptr; 9801 } 9802 if (Kind == OMPC_SCHEDULE_unknown) { 9803 std::string Values; 9804 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 9805 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 9806 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 9807 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 9808 Exclude); 9809 } else { 9810 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 9811 /*Last=*/OMPC_SCHEDULE_unknown); 9812 } 9813 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 9814 << Values << getOpenMPClauseName(OMPC_schedule); 9815 return nullptr; 9816 } 9817 // OpenMP, 2.7.1, Loop Construct, Restrictions 9818 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 9819 // schedule(guided). 9820 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 9821 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 9822 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 9823 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 9824 diag::err_omp_schedule_nonmonotonic_static); 9825 return nullptr; 9826 } 9827 Expr *ValExpr = ChunkSize; 9828 Stmt *HelperValStmt = nullptr; 9829 if (ChunkSize) { 9830 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 9831 !ChunkSize->isInstantiationDependent() && 9832 !ChunkSize->containsUnexpandedParameterPack()) { 9833 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 9834 ExprResult Val = 9835 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 9836 if (Val.isInvalid()) 9837 return nullptr; 9838 9839 ValExpr = Val.get(); 9840 9841 // OpenMP [2.7.1, Restrictions] 9842 // chunk_size must be a loop invariant integer expression with a positive 9843 // value. 9844 llvm::APSInt Result; 9845 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 9846 if (Result.isSigned() && !Result.isStrictlyPositive()) { 9847 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 9848 << "schedule" << 1 << ChunkSize->getSourceRange(); 9849 return nullptr; 9850 } 9851 } else if (getOpenMPCaptureRegionForClause( 9852 DSAStack->getCurrentDirective(), OMPC_schedule) != 9853 OMPD_unknown && 9854 !CurContext->isDependentContext()) { 9855 ValExpr = MakeFullExpr(ValExpr).get(); 9856 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9857 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9858 HelperValStmt = buildPreInits(Context, Captures); 9859 } 9860 } 9861 } 9862 9863 return new (Context) 9864 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 9865 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 9866 } 9867 9868 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 9869 SourceLocation StartLoc, 9870 SourceLocation EndLoc) { 9871 OMPClause *Res = nullptr; 9872 switch (Kind) { 9873 case OMPC_ordered: 9874 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 9875 break; 9876 case OMPC_nowait: 9877 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 9878 break; 9879 case OMPC_untied: 9880 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 9881 break; 9882 case OMPC_mergeable: 9883 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 9884 break; 9885 case OMPC_read: 9886 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 9887 break; 9888 case OMPC_write: 9889 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 9890 break; 9891 case OMPC_update: 9892 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 9893 break; 9894 case OMPC_capture: 9895 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 9896 break; 9897 case OMPC_seq_cst: 9898 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 9899 break; 9900 case OMPC_threads: 9901 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 9902 break; 9903 case OMPC_simd: 9904 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 9905 break; 9906 case OMPC_nogroup: 9907 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 9908 break; 9909 case OMPC_unified_address: 9910 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 9911 break; 9912 case OMPC_unified_shared_memory: 9913 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 9914 break; 9915 case OMPC_reverse_offload: 9916 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 9917 break; 9918 case OMPC_dynamic_allocators: 9919 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 9920 break; 9921 case OMPC_if: 9922 case OMPC_final: 9923 case OMPC_num_threads: 9924 case OMPC_safelen: 9925 case OMPC_simdlen: 9926 case OMPC_allocator: 9927 case OMPC_collapse: 9928 case OMPC_schedule: 9929 case OMPC_private: 9930 case OMPC_firstprivate: 9931 case OMPC_lastprivate: 9932 case OMPC_shared: 9933 case OMPC_reduction: 9934 case OMPC_task_reduction: 9935 case OMPC_in_reduction: 9936 case OMPC_linear: 9937 case OMPC_aligned: 9938 case OMPC_copyin: 9939 case OMPC_copyprivate: 9940 case OMPC_default: 9941 case OMPC_proc_bind: 9942 case OMPC_threadprivate: 9943 case OMPC_allocate: 9944 case OMPC_flush: 9945 case OMPC_depend: 9946 case OMPC_device: 9947 case OMPC_map: 9948 case OMPC_num_teams: 9949 case OMPC_thread_limit: 9950 case OMPC_priority: 9951 case OMPC_grainsize: 9952 case OMPC_num_tasks: 9953 case OMPC_hint: 9954 case OMPC_dist_schedule: 9955 case OMPC_defaultmap: 9956 case OMPC_unknown: 9957 case OMPC_uniform: 9958 case OMPC_to: 9959 case OMPC_from: 9960 case OMPC_use_device_ptr: 9961 case OMPC_is_device_ptr: 9962 case OMPC_atomic_default_mem_order: 9963 llvm_unreachable("Clause is not allowed."); 9964 } 9965 return Res; 9966 } 9967 9968 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 9969 SourceLocation EndLoc) { 9970 DSAStack->setNowaitRegion(); 9971 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 9972 } 9973 9974 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 9975 SourceLocation EndLoc) { 9976 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 9977 } 9978 9979 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 9980 SourceLocation EndLoc) { 9981 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 9982 } 9983 9984 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 9985 SourceLocation EndLoc) { 9986 return new (Context) OMPReadClause(StartLoc, EndLoc); 9987 } 9988 9989 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 9990 SourceLocation EndLoc) { 9991 return new (Context) OMPWriteClause(StartLoc, EndLoc); 9992 } 9993 9994 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 9995 SourceLocation EndLoc) { 9996 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 9997 } 9998 9999 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 10000 SourceLocation EndLoc) { 10001 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 10002 } 10003 10004 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 10005 SourceLocation EndLoc) { 10006 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 10007 } 10008 10009 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 10010 SourceLocation EndLoc) { 10011 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 10012 } 10013 10014 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 10015 SourceLocation EndLoc) { 10016 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 10017 } 10018 10019 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 10020 SourceLocation EndLoc) { 10021 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 10022 } 10023 10024 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 10025 SourceLocation EndLoc) { 10026 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 10027 } 10028 10029 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 10030 SourceLocation EndLoc) { 10031 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10032 } 10033 10034 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 10035 SourceLocation EndLoc) { 10036 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 10037 } 10038 10039 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 10040 SourceLocation EndLoc) { 10041 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 10042 } 10043 10044 OMPClause *Sema::ActOnOpenMPVarListClause( 10045 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 10046 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 10047 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 10048 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 10049 OpenMPLinearClauseKind LinKind, 10050 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 10051 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 10052 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 10053 SourceLocation StartLoc = Locs.StartLoc; 10054 SourceLocation LParenLoc = Locs.LParenLoc; 10055 SourceLocation EndLoc = Locs.EndLoc; 10056 OMPClause *Res = nullptr; 10057 switch (Kind) { 10058 case OMPC_private: 10059 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10060 break; 10061 case OMPC_firstprivate: 10062 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10063 break; 10064 case OMPC_lastprivate: 10065 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10066 break; 10067 case OMPC_shared: 10068 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 10069 break; 10070 case OMPC_reduction: 10071 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10072 EndLoc, ReductionOrMapperIdScopeSpec, 10073 ReductionOrMapperId); 10074 break; 10075 case OMPC_task_reduction: 10076 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10077 EndLoc, ReductionOrMapperIdScopeSpec, 10078 ReductionOrMapperId); 10079 break; 10080 case OMPC_in_reduction: 10081 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10082 EndLoc, ReductionOrMapperIdScopeSpec, 10083 ReductionOrMapperId); 10084 break; 10085 case OMPC_linear: 10086 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 10087 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 10088 break; 10089 case OMPC_aligned: 10090 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 10091 ColonLoc, EndLoc); 10092 break; 10093 case OMPC_copyin: 10094 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 10095 break; 10096 case OMPC_copyprivate: 10097 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10098 break; 10099 case OMPC_flush: 10100 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 10101 break; 10102 case OMPC_depend: 10103 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 10104 StartLoc, LParenLoc, EndLoc); 10105 break; 10106 case OMPC_map: 10107 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 10108 ReductionOrMapperIdScopeSpec, 10109 ReductionOrMapperId, MapType, IsMapTypeImplicit, 10110 DepLinMapLoc, ColonLoc, VarList, Locs); 10111 break; 10112 case OMPC_to: 10113 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 10114 ReductionOrMapperId, Locs); 10115 break; 10116 case OMPC_from: 10117 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 10118 ReductionOrMapperId, Locs); 10119 break; 10120 case OMPC_use_device_ptr: 10121 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 10122 break; 10123 case OMPC_is_device_ptr: 10124 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 10125 break; 10126 case OMPC_if: 10127 case OMPC_final: 10128 case OMPC_num_threads: 10129 case OMPC_safelen: 10130 case OMPC_simdlen: 10131 case OMPC_allocator: 10132 case OMPC_collapse: 10133 case OMPC_default: 10134 case OMPC_proc_bind: 10135 case OMPC_schedule: 10136 case OMPC_ordered: 10137 case OMPC_nowait: 10138 case OMPC_untied: 10139 case OMPC_mergeable: 10140 case OMPC_threadprivate: 10141 case OMPC_allocate: 10142 case OMPC_read: 10143 case OMPC_write: 10144 case OMPC_update: 10145 case OMPC_capture: 10146 case OMPC_seq_cst: 10147 case OMPC_device: 10148 case OMPC_threads: 10149 case OMPC_simd: 10150 case OMPC_num_teams: 10151 case OMPC_thread_limit: 10152 case OMPC_priority: 10153 case OMPC_grainsize: 10154 case OMPC_nogroup: 10155 case OMPC_num_tasks: 10156 case OMPC_hint: 10157 case OMPC_dist_schedule: 10158 case OMPC_defaultmap: 10159 case OMPC_unknown: 10160 case OMPC_uniform: 10161 case OMPC_unified_address: 10162 case OMPC_unified_shared_memory: 10163 case OMPC_reverse_offload: 10164 case OMPC_dynamic_allocators: 10165 case OMPC_atomic_default_mem_order: 10166 llvm_unreachable("Clause is not allowed."); 10167 } 10168 return Res; 10169 } 10170 10171 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 10172 ExprObjectKind OK, SourceLocation Loc) { 10173 ExprResult Res = BuildDeclRefExpr( 10174 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 10175 if (!Res.isUsable()) 10176 return ExprError(); 10177 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 10178 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 10179 if (!Res.isUsable()) 10180 return ExprError(); 10181 } 10182 if (VK != VK_LValue && Res.get()->isGLValue()) { 10183 Res = DefaultLvalueConversion(Res.get()); 10184 if (!Res.isUsable()) 10185 return ExprError(); 10186 } 10187 return Res; 10188 } 10189 10190 static std::pair<ValueDecl *, bool> 10191 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 10192 SourceRange &ERange, bool AllowArraySection = false) { 10193 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 10194 RefExpr->containsUnexpandedParameterPack()) 10195 return std::make_pair(nullptr, true); 10196 10197 // OpenMP [3.1, C/C++] 10198 // A list item is a variable name. 10199 // OpenMP [2.9.3.3, Restrictions, p.1] 10200 // A variable that is part of another variable (as an array or 10201 // structure element) cannot appear in a private clause. 10202 RefExpr = RefExpr->IgnoreParens(); 10203 enum { 10204 NoArrayExpr = -1, 10205 ArraySubscript = 0, 10206 OMPArraySection = 1 10207 } IsArrayExpr = NoArrayExpr; 10208 if (AllowArraySection) { 10209 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 10210 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 10211 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 10212 Base = TempASE->getBase()->IgnoreParenImpCasts(); 10213 RefExpr = Base; 10214 IsArrayExpr = ArraySubscript; 10215 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 10216 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 10217 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 10218 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 10219 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 10220 Base = TempASE->getBase()->IgnoreParenImpCasts(); 10221 RefExpr = Base; 10222 IsArrayExpr = OMPArraySection; 10223 } 10224 } 10225 ELoc = RefExpr->getExprLoc(); 10226 ERange = RefExpr->getSourceRange(); 10227 RefExpr = RefExpr->IgnoreParenImpCasts(); 10228 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 10229 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 10230 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 10231 (S.getCurrentThisType().isNull() || !ME || 10232 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 10233 !isa<FieldDecl>(ME->getMemberDecl()))) { 10234 if (IsArrayExpr != NoArrayExpr) { 10235 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 10236 << ERange; 10237 } else { 10238 S.Diag(ELoc, 10239 AllowArraySection 10240 ? diag::err_omp_expected_var_name_member_expr_or_array_item 10241 : diag::err_omp_expected_var_name_member_expr) 10242 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 10243 } 10244 return std::make_pair(nullptr, false); 10245 } 10246 return std::make_pair( 10247 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 10248 } 10249 10250 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 10251 SourceLocation StartLoc, 10252 SourceLocation LParenLoc, 10253 SourceLocation EndLoc) { 10254 SmallVector<Expr *, 8> Vars; 10255 SmallVector<Expr *, 8> PrivateCopies; 10256 for (Expr *RefExpr : VarList) { 10257 assert(RefExpr && "NULL expr in OpenMP private clause."); 10258 SourceLocation ELoc; 10259 SourceRange ERange; 10260 Expr *SimpleRefExpr = RefExpr; 10261 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10262 if (Res.second) { 10263 // It will be analyzed later. 10264 Vars.push_back(RefExpr); 10265 PrivateCopies.push_back(nullptr); 10266 } 10267 ValueDecl *D = Res.first; 10268 if (!D) 10269 continue; 10270 10271 QualType Type = D->getType(); 10272 auto *VD = dyn_cast<VarDecl>(D); 10273 10274 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10275 // A variable that appears in a private clause must not have an incomplete 10276 // type or a reference type. 10277 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 10278 continue; 10279 Type = Type.getNonReferenceType(); 10280 10281 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 10282 // A variable that is privatized must not have a const-qualified type 10283 // unless it is of class type with a mutable member. This restriction does 10284 // not apply to the firstprivate clause. 10285 // 10286 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 10287 // A variable that appears in a private clause must not have a 10288 // const-qualified type unless it is of class type with a mutable member. 10289 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 10290 continue; 10291 10292 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10293 // in a Construct] 10294 // Variables with the predetermined data-sharing attributes may not be 10295 // listed in data-sharing attributes clauses, except for the cases 10296 // listed below. For these exceptions only, listing a predetermined 10297 // variable in a data-sharing attribute clause is allowed and overrides 10298 // the variable's predetermined data-sharing attributes. 10299 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10300 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 10301 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10302 << getOpenMPClauseName(OMPC_private); 10303 reportOriginalDsa(*this, DSAStack, D, DVar); 10304 continue; 10305 } 10306 10307 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10308 // Variably modified types are not supported for tasks. 10309 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10310 isOpenMPTaskingDirective(CurrDir)) { 10311 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10312 << getOpenMPClauseName(OMPC_private) << Type 10313 << getOpenMPDirectiveName(CurrDir); 10314 bool IsDecl = 10315 !VD || 10316 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10317 Diag(D->getLocation(), 10318 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10319 << D; 10320 continue; 10321 } 10322 10323 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10324 // A list item cannot appear in both a map clause and a data-sharing 10325 // attribute clause on the same construct 10326 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10327 OpenMPClauseKind ConflictKind; 10328 if (DSAStack->checkMappableExprComponentListsForDecl( 10329 VD, /*CurrentRegionOnly=*/true, 10330 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 10331 OpenMPClauseKind WhereFoundClauseKind) -> bool { 10332 ConflictKind = WhereFoundClauseKind; 10333 return true; 10334 })) { 10335 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10336 << getOpenMPClauseName(OMPC_private) 10337 << getOpenMPClauseName(ConflictKind) 10338 << getOpenMPDirectiveName(CurrDir); 10339 reportOriginalDsa(*this, DSAStack, D, DVar); 10340 continue; 10341 } 10342 } 10343 10344 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 10345 // A variable of class type (or array thereof) that appears in a private 10346 // clause requires an accessible, unambiguous default constructor for the 10347 // class type. 10348 // Generate helper private variable and initialize it with the default 10349 // value. The address of the original variable is replaced by the address of 10350 // the new private variable in CodeGen. This new variable is not added to 10351 // IdResolver, so the code in the OpenMP region uses original variable for 10352 // proper diagnostics. 10353 Type = Type.getUnqualifiedType(); 10354 VarDecl *VDPrivate = 10355 buildVarDecl(*this, ELoc, Type, D->getName(), 10356 D->hasAttrs() ? &D->getAttrs() : nullptr, 10357 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10358 ActOnUninitializedDecl(VDPrivate); 10359 if (VDPrivate->isInvalidDecl()) 10360 continue; 10361 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10362 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 10363 10364 DeclRefExpr *Ref = nullptr; 10365 if (!VD && !CurContext->isDependentContext()) 10366 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10367 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 10368 Vars.push_back((VD || CurContext->isDependentContext()) 10369 ? RefExpr->IgnoreParens() 10370 : Ref); 10371 PrivateCopies.push_back(VDPrivateRefExpr); 10372 } 10373 10374 if (Vars.empty()) 10375 return nullptr; 10376 10377 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 10378 PrivateCopies); 10379 } 10380 10381 namespace { 10382 class DiagsUninitializedSeveretyRAII { 10383 private: 10384 DiagnosticsEngine &Diags; 10385 SourceLocation SavedLoc; 10386 bool IsIgnored = false; 10387 10388 public: 10389 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 10390 bool IsIgnored) 10391 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 10392 if (!IsIgnored) { 10393 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 10394 /*Map*/ diag::Severity::Ignored, Loc); 10395 } 10396 } 10397 ~DiagsUninitializedSeveretyRAII() { 10398 if (!IsIgnored) 10399 Diags.popMappings(SavedLoc); 10400 } 10401 }; 10402 } 10403 10404 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 10405 SourceLocation StartLoc, 10406 SourceLocation LParenLoc, 10407 SourceLocation EndLoc) { 10408 SmallVector<Expr *, 8> Vars; 10409 SmallVector<Expr *, 8> PrivateCopies; 10410 SmallVector<Expr *, 8> Inits; 10411 SmallVector<Decl *, 4> ExprCaptures; 10412 bool IsImplicitClause = 10413 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 10414 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 10415 10416 for (Expr *RefExpr : VarList) { 10417 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 10418 SourceLocation ELoc; 10419 SourceRange ERange; 10420 Expr *SimpleRefExpr = RefExpr; 10421 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10422 if (Res.second) { 10423 // It will be analyzed later. 10424 Vars.push_back(RefExpr); 10425 PrivateCopies.push_back(nullptr); 10426 Inits.push_back(nullptr); 10427 } 10428 ValueDecl *D = Res.first; 10429 if (!D) 10430 continue; 10431 10432 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 10433 QualType Type = D->getType(); 10434 auto *VD = dyn_cast<VarDecl>(D); 10435 10436 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10437 // A variable that appears in a private clause must not have an incomplete 10438 // type or a reference type. 10439 if (RequireCompleteType(ELoc, Type, 10440 diag::err_omp_firstprivate_incomplete_type)) 10441 continue; 10442 Type = Type.getNonReferenceType(); 10443 10444 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 10445 // A variable of class type (or array thereof) that appears in a private 10446 // clause requires an accessible, unambiguous copy constructor for the 10447 // class type. 10448 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 10449 10450 // If an implicit firstprivate variable found it was checked already. 10451 DSAStackTy::DSAVarData TopDVar; 10452 if (!IsImplicitClause) { 10453 DSAStackTy::DSAVarData DVar = 10454 DSAStack->getTopDSA(D, /*FromParent=*/false); 10455 TopDVar = DVar; 10456 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10457 bool IsConstant = ElemType.isConstant(Context); 10458 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 10459 // A list item that specifies a given variable may not appear in more 10460 // than one clause on the same directive, except that a variable may be 10461 // specified in both firstprivate and lastprivate clauses. 10462 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 10463 // A list item may appear in a firstprivate or lastprivate clause but not 10464 // both. 10465 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 10466 (isOpenMPDistributeDirective(CurrDir) || 10467 DVar.CKind != OMPC_lastprivate) && 10468 DVar.RefExpr) { 10469 Diag(ELoc, diag::err_omp_wrong_dsa) 10470 << getOpenMPClauseName(DVar.CKind) 10471 << getOpenMPClauseName(OMPC_firstprivate); 10472 reportOriginalDsa(*this, DSAStack, D, DVar); 10473 continue; 10474 } 10475 10476 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10477 // in a Construct] 10478 // Variables with the predetermined data-sharing attributes may not be 10479 // listed in data-sharing attributes clauses, except for the cases 10480 // listed below. For these exceptions only, listing a predetermined 10481 // variable in a data-sharing attribute clause is allowed and overrides 10482 // the variable's predetermined data-sharing attributes. 10483 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10484 // in a Construct, C/C++, p.2] 10485 // Variables with const-qualified type having no mutable member may be 10486 // listed in a firstprivate clause, even if they are static data members. 10487 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 10488 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 10489 Diag(ELoc, diag::err_omp_wrong_dsa) 10490 << getOpenMPClauseName(DVar.CKind) 10491 << getOpenMPClauseName(OMPC_firstprivate); 10492 reportOriginalDsa(*this, DSAStack, D, DVar); 10493 continue; 10494 } 10495 10496 // OpenMP [2.9.3.4, Restrictions, p.2] 10497 // A list item that is private within a parallel region must not appear 10498 // in a firstprivate clause on a worksharing construct if any of the 10499 // worksharing regions arising from the worksharing construct ever bind 10500 // to any of the parallel regions arising from the parallel construct. 10501 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 10502 // A list item that is private within a teams region must not appear in a 10503 // firstprivate clause on a distribute construct if any of the distribute 10504 // regions arising from the distribute construct ever bind to any of the 10505 // teams regions arising from the teams construct. 10506 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 10507 // A list item that appears in a reduction clause of a teams construct 10508 // must not appear in a firstprivate clause on a distribute construct if 10509 // any of the distribute regions arising from the distribute construct 10510 // ever bind to any of the teams regions arising from the teams construct. 10511 if ((isOpenMPWorksharingDirective(CurrDir) || 10512 isOpenMPDistributeDirective(CurrDir)) && 10513 !isOpenMPParallelDirective(CurrDir) && 10514 !isOpenMPTeamsDirective(CurrDir)) { 10515 DVar = DSAStack->getImplicitDSA(D, true); 10516 if (DVar.CKind != OMPC_shared && 10517 (isOpenMPParallelDirective(DVar.DKind) || 10518 isOpenMPTeamsDirective(DVar.DKind) || 10519 DVar.DKind == OMPD_unknown)) { 10520 Diag(ELoc, diag::err_omp_required_access) 10521 << getOpenMPClauseName(OMPC_firstprivate) 10522 << getOpenMPClauseName(OMPC_shared); 10523 reportOriginalDsa(*this, DSAStack, D, DVar); 10524 continue; 10525 } 10526 } 10527 // OpenMP [2.9.3.4, Restrictions, p.3] 10528 // A list item that appears in a reduction clause of a parallel construct 10529 // must not appear in a firstprivate clause on a worksharing or task 10530 // construct if any of the worksharing or task regions arising from the 10531 // worksharing or task construct ever bind to any of the parallel regions 10532 // arising from the parallel construct. 10533 // OpenMP [2.9.3.4, Restrictions, p.4] 10534 // A list item that appears in a reduction clause in worksharing 10535 // construct must not appear in a firstprivate clause in a task construct 10536 // encountered during execution of any of the worksharing regions arising 10537 // from the worksharing construct. 10538 if (isOpenMPTaskingDirective(CurrDir)) { 10539 DVar = DSAStack->hasInnermostDSA( 10540 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 10541 [](OpenMPDirectiveKind K) { 10542 return isOpenMPParallelDirective(K) || 10543 isOpenMPWorksharingDirective(K) || 10544 isOpenMPTeamsDirective(K); 10545 }, 10546 /*FromParent=*/true); 10547 if (DVar.CKind == OMPC_reduction && 10548 (isOpenMPParallelDirective(DVar.DKind) || 10549 isOpenMPWorksharingDirective(DVar.DKind) || 10550 isOpenMPTeamsDirective(DVar.DKind))) { 10551 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 10552 << getOpenMPDirectiveName(DVar.DKind); 10553 reportOriginalDsa(*this, DSAStack, D, DVar); 10554 continue; 10555 } 10556 } 10557 10558 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10559 // A list item cannot appear in both a map clause and a data-sharing 10560 // attribute clause on the same construct 10561 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10562 OpenMPClauseKind ConflictKind; 10563 if (DSAStack->checkMappableExprComponentListsForDecl( 10564 VD, /*CurrentRegionOnly=*/true, 10565 [&ConflictKind]( 10566 OMPClauseMappableExprCommon::MappableExprComponentListRef, 10567 OpenMPClauseKind WhereFoundClauseKind) { 10568 ConflictKind = WhereFoundClauseKind; 10569 return true; 10570 })) { 10571 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10572 << getOpenMPClauseName(OMPC_firstprivate) 10573 << getOpenMPClauseName(ConflictKind) 10574 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10575 reportOriginalDsa(*this, DSAStack, D, DVar); 10576 continue; 10577 } 10578 } 10579 } 10580 10581 // Variably modified types are not supported for tasks. 10582 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10583 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 10584 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10585 << getOpenMPClauseName(OMPC_firstprivate) << Type 10586 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10587 bool IsDecl = 10588 !VD || 10589 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10590 Diag(D->getLocation(), 10591 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10592 << D; 10593 continue; 10594 } 10595 10596 Type = Type.getUnqualifiedType(); 10597 VarDecl *VDPrivate = 10598 buildVarDecl(*this, ELoc, Type, D->getName(), 10599 D->hasAttrs() ? &D->getAttrs() : nullptr, 10600 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10601 // Generate helper private variable and initialize it with the value of the 10602 // original variable. The address of the original variable is replaced by 10603 // the address of the new private variable in the CodeGen. This new variable 10604 // is not added to IdResolver, so the code in the OpenMP region uses 10605 // original variable for proper diagnostics and variable capturing. 10606 Expr *VDInitRefExpr = nullptr; 10607 // For arrays generate initializer for single element and replace it by the 10608 // original array element in CodeGen. 10609 if (Type->isArrayType()) { 10610 VarDecl *VDInit = 10611 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 10612 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 10613 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 10614 ElemType = ElemType.getUnqualifiedType(); 10615 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 10616 ".firstprivate.temp"); 10617 InitializedEntity Entity = 10618 InitializedEntity::InitializeVariable(VDInitTemp); 10619 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 10620 10621 InitializationSequence InitSeq(*this, Entity, Kind, Init); 10622 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 10623 if (Result.isInvalid()) 10624 VDPrivate->setInvalidDecl(); 10625 else 10626 VDPrivate->setInit(Result.getAs<Expr>()); 10627 // Remove temp variable declaration. 10628 Context.Deallocate(VDInitTemp); 10629 } else { 10630 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 10631 ".firstprivate.temp"); 10632 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 10633 RefExpr->getExprLoc()); 10634 AddInitializerToDecl(VDPrivate, 10635 DefaultLvalueConversion(VDInitRefExpr).get(), 10636 /*DirectInit=*/false); 10637 } 10638 if (VDPrivate->isInvalidDecl()) { 10639 if (IsImplicitClause) { 10640 Diag(RefExpr->getExprLoc(), 10641 diag::note_omp_task_predetermined_firstprivate_here); 10642 } 10643 continue; 10644 } 10645 CurContext->addDecl(VDPrivate); 10646 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10647 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 10648 RefExpr->getExprLoc()); 10649 DeclRefExpr *Ref = nullptr; 10650 if (!VD && !CurContext->isDependentContext()) { 10651 if (TopDVar.CKind == OMPC_lastprivate) { 10652 Ref = TopDVar.PrivateCopy; 10653 } else { 10654 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10655 if (!isOpenMPCapturedDecl(D)) 10656 ExprCaptures.push_back(Ref->getDecl()); 10657 } 10658 } 10659 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 10660 Vars.push_back((VD || CurContext->isDependentContext()) 10661 ? RefExpr->IgnoreParens() 10662 : Ref); 10663 PrivateCopies.push_back(VDPrivateRefExpr); 10664 Inits.push_back(VDInitRefExpr); 10665 } 10666 10667 if (Vars.empty()) 10668 return nullptr; 10669 10670 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10671 Vars, PrivateCopies, Inits, 10672 buildPreInits(Context, ExprCaptures)); 10673 } 10674 10675 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 10676 SourceLocation StartLoc, 10677 SourceLocation LParenLoc, 10678 SourceLocation EndLoc) { 10679 SmallVector<Expr *, 8> Vars; 10680 SmallVector<Expr *, 8> SrcExprs; 10681 SmallVector<Expr *, 8> DstExprs; 10682 SmallVector<Expr *, 8> AssignmentOps; 10683 SmallVector<Decl *, 4> ExprCaptures; 10684 SmallVector<Expr *, 4> ExprPostUpdates; 10685 for (Expr *RefExpr : VarList) { 10686 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 10687 SourceLocation ELoc; 10688 SourceRange ERange; 10689 Expr *SimpleRefExpr = RefExpr; 10690 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10691 if (Res.second) { 10692 // It will be analyzed later. 10693 Vars.push_back(RefExpr); 10694 SrcExprs.push_back(nullptr); 10695 DstExprs.push_back(nullptr); 10696 AssignmentOps.push_back(nullptr); 10697 } 10698 ValueDecl *D = Res.first; 10699 if (!D) 10700 continue; 10701 10702 QualType Type = D->getType(); 10703 auto *VD = dyn_cast<VarDecl>(D); 10704 10705 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 10706 // A variable that appears in a lastprivate clause must not have an 10707 // incomplete type or a reference type. 10708 if (RequireCompleteType(ELoc, Type, 10709 diag::err_omp_lastprivate_incomplete_type)) 10710 continue; 10711 Type = Type.getNonReferenceType(); 10712 10713 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 10714 // A variable that is privatized must not have a const-qualified type 10715 // unless it is of class type with a mutable member. This restriction does 10716 // not apply to the firstprivate clause. 10717 // 10718 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 10719 // A variable that appears in a lastprivate clause must not have a 10720 // const-qualified type unless it is of class type with a mutable member. 10721 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 10722 continue; 10723 10724 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10725 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 10726 // in a Construct] 10727 // Variables with the predetermined data-sharing attributes may not be 10728 // listed in data-sharing attributes clauses, except for the cases 10729 // listed below. 10730 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 10731 // A list item may appear in a firstprivate or lastprivate clause but not 10732 // both. 10733 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10734 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 10735 (isOpenMPDistributeDirective(CurrDir) || 10736 DVar.CKind != OMPC_firstprivate) && 10737 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 10738 Diag(ELoc, diag::err_omp_wrong_dsa) 10739 << getOpenMPClauseName(DVar.CKind) 10740 << getOpenMPClauseName(OMPC_lastprivate); 10741 reportOriginalDsa(*this, DSAStack, D, DVar); 10742 continue; 10743 } 10744 10745 // OpenMP [2.14.3.5, Restrictions, p.2] 10746 // A list item that is private within a parallel region, or that appears in 10747 // the reduction clause of a parallel construct, must not appear in a 10748 // lastprivate clause on a worksharing construct if any of the corresponding 10749 // worksharing regions ever binds to any of the corresponding parallel 10750 // regions. 10751 DSAStackTy::DSAVarData TopDVar = DVar; 10752 if (isOpenMPWorksharingDirective(CurrDir) && 10753 !isOpenMPParallelDirective(CurrDir) && 10754 !isOpenMPTeamsDirective(CurrDir)) { 10755 DVar = DSAStack->getImplicitDSA(D, true); 10756 if (DVar.CKind != OMPC_shared) { 10757 Diag(ELoc, diag::err_omp_required_access) 10758 << getOpenMPClauseName(OMPC_lastprivate) 10759 << getOpenMPClauseName(OMPC_shared); 10760 reportOriginalDsa(*this, DSAStack, D, DVar); 10761 continue; 10762 } 10763 } 10764 10765 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 10766 // A variable of class type (or array thereof) that appears in a 10767 // lastprivate clause requires an accessible, unambiguous default 10768 // constructor for the class type, unless the list item is also specified 10769 // in a firstprivate clause. 10770 // A variable of class type (or array thereof) that appears in a 10771 // lastprivate clause requires an accessible, unambiguous copy assignment 10772 // operator for the class type. 10773 Type = Context.getBaseElementType(Type).getNonReferenceType(); 10774 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 10775 Type.getUnqualifiedType(), ".lastprivate.src", 10776 D->hasAttrs() ? &D->getAttrs() : nullptr); 10777 DeclRefExpr *PseudoSrcExpr = 10778 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 10779 VarDecl *DstVD = 10780 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 10781 D->hasAttrs() ? &D->getAttrs() : nullptr); 10782 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 10783 // For arrays generate assignment operation for single element and replace 10784 // it by the original array element in CodeGen. 10785 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 10786 PseudoDstExpr, PseudoSrcExpr); 10787 if (AssignmentOp.isInvalid()) 10788 continue; 10789 AssignmentOp = 10790 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 10791 if (AssignmentOp.isInvalid()) 10792 continue; 10793 10794 DeclRefExpr *Ref = nullptr; 10795 if (!VD && !CurContext->isDependentContext()) { 10796 if (TopDVar.CKind == OMPC_firstprivate) { 10797 Ref = TopDVar.PrivateCopy; 10798 } else { 10799 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10800 if (!isOpenMPCapturedDecl(D)) 10801 ExprCaptures.push_back(Ref->getDecl()); 10802 } 10803 if (TopDVar.CKind == OMPC_firstprivate || 10804 (!isOpenMPCapturedDecl(D) && 10805 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 10806 ExprResult RefRes = DefaultLvalueConversion(Ref); 10807 if (!RefRes.isUsable()) 10808 continue; 10809 ExprResult PostUpdateRes = 10810 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 10811 RefRes.get()); 10812 if (!PostUpdateRes.isUsable()) 10813 continue; 10814 ExprPostUpdates.push_back( 10815 IgnoredValueConversions(PostUpdateRes.get()).get()); 10816 } 10817 } 10818 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 10819 Vars.push_back((VD || CurContext->isDependentContext()) 10820 ? RefExpr->IgnoreParens() 10821 : Ref); 10822 SrcExprs.push_back(PseudoSrcExpr); 10823 DstExprs.push_back(PseudoDstExpr); 10824 AssignmentOps.push_back(AssignmentOp.get()); 10825 } 10826 10827 if (Vars.empty()) 10828 return nullptr; 10829 10830 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10831 Vars, SrcExprs, DstExprs, AssignmentOps, 10832 buildPreInits(Context, ExprCaptures), 10833 buildPostUpdate(*this, ExprPostUpdates)); 10834 } 10835 10836 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 10837 SourceLocation StartLoc, 10838 SourceLocation LParenLoc, 10839 SourceLocation EndLoc) { 10840 SmallVector<Expr *, 8> Vars; 10841 for (Expr *RefExpr : VarList) { 10842 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 10843 SourceLocation ELoc; 10844 SourceRange ERange; 10845 Expr *SimpleRefExpr = RefExpr; 10846 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10847 if (Res.second) { 10848 // It will be analyzed later. 10849 Vars.push_back(RefExpr); 10850 } 10851 ValueDecl *D = Res.first; 10852 if (!D) 10853 continue; 10854 10855 auto *VD = dyn_cast<VarDecl>(D); 10856 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10857 // in a Construct] 10858 // Variables with the predetermined data-sharing attributes may not be 10859 // listed in data-sharing attributes clauses, except for the cases 10860 // listed below. For these exceptions only, listing a predetermined 10861 // variable in a data-sharing attribute clause is allowed and overrides 10862 // the variable's predetermined data-sharing attributes. 10863 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10864 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 10865 DVar.RefExpr) { 10866 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10867 << getOpenMPClauseName(OMPC_shared); 10868 reportOriginalDsa(*this, DSAStack, D, DVar); 10869 continue; 10870 } 10871 10872 DeclRefExpr *Ref = nullptr; 10873 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 10874 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10875 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 10876 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 10877 ? RefExpr->IgnoreParens() 10878 : Ref); 10879 } 10880 10881 if (Vars.empty()) 10882 return nullptr; 10883 10884 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 10885 } 10886 10887 namespace { 10888 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 10889 DSAStackTy *Stack; 10890 10891 public: 10892 bool VisitDeclRefExpr(DeclRefExpr *E) { 10893 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 10894 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 10895 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 10896 return false; 10897 if (DVar.CKind != OMPC_unknown) 10898 return true; 10899 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 10900 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 10901 /*FromParent=*/true); 10902 return DVarPrivate.CKind != OMPC_unknown; 10903 } 10904 return false; 10905 } 10906 bool VisitStmt(Stmt *S) { 10907 for (Stmt *Child : S->children()) { 10908 if (Child && Visit(Child)) 10909 return true; 10910 } 10911 return false; 10912 } 10913 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 10914 }; 10915 } // namespace 10916 10917 namespace { 10918 // Transform MemberExpression for specified FieldDecl of current class to 10919 // DeclRefExpr to specified OMPCapturedExprDecl. 10920 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 10921 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 10922 ValueDecl *Field = nullptr; 10923 DeclRefExpr *CapturedExpr = nullptr; 10924 10925 public: 10926 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 10927 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 10928 10929 ExprResult TransformMemberExpr(MemberExpr *E) { 10930 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 10931 E->getMemberDecl() == Field) { 10932 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 10933 return CapturedExpr; 10934 } 10935 return BaseTransform::TransformMemberExpr(E); 10936 } 10937 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 10938 }; 10939 } // namespace 10940 10941 template <typename T, typename U> 10942 static T filterLookupForUDReductionAndMapper( 10943 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 10944 for (U &Set : Lookups) { 10945 for (auto *D : Set) { 10946 if (T Res = Gen(cast<ValueDecl>(D))) 10947 return Res; 10948 } 10949 } 10950 return T(); 10951 } 10952 10953 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 10954 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 10955 10956 for (auto RD : D->redecls()) { 10957 // Don't bother with extra checks if we already know this one isn't visible. 10958 if (RD == D) 10959 continue; 10960 10961 auto ND = cast<NamedDecl>(RD); 10962 if (LookupResult::isVisible(SemaRef, ND)) 10963 return ND; 10964 } 10965 10966 return nullptr; 10967 } 10968 10969 static void 10970 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 10971 SourceLocation Loc, QualType Ty, 10972 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 10973 // Find all of the associated namespaces and classes based on the 10974 // arguments we have. 10975 Sema::AssociatedNamespaceSet AssociatedNamespaces; 10976 Sema::AssociatedClassSet AssociatedClasses; 10977 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 10978 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 10979 AssociatedClasses); 10980 10981 // C++ [basic.lookup.argdep]p3: 10982 // Let X be the lookup set produced by unqualified lookup (3.4.1) 10983 // and let Y be the lookup set produced by argument dependent 10984 // lookup (defined as follows). If X contains [...] then Y is 10985 // empty. Otherwise Y is the set of declarations found in the 10986 // namespaces associated with the argument types as described 10987 // below. The set of declarations found by the lookup of the name 10988 // is the union of X and Y. 10989 // 10990 // Here, we compute Y and add its members to the overloaded 10991 // candidate set. 10992 for (auto *NS : AssociatedNamespaces) { 10993 // When considering an associated namespace, the lookup is the 10994 // same as the lookup performed when the associated namespace is 10995 // used as a qualifier (3.4.3.2) except that: 10996 // 10997 // -- Any using-directives in the associated namespace are 10998 // ignored. 10999 // 11000 // -- Any namespace-scope friend functions declared in 11001 // associated classes are visible within their respective 11002 // namespaces even if they are not visible during an ordinary 11003 // lookup (11.4). 11004 DeclContext::lookup_result R = NS->lookup(Id.getName()); 11005 for (auto *D : R) { 11006 auto *Underlying = D; 11007 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11008 Underlying = USD->getTargetDecl(); 11009 11010 if (!isa<OMPDeclareReductionDecl>(Underlying) && 11011 !isa<OMPDeclareMapperDecl>(Underlying)) 11012 continue; 11013 11014 if (!SemaRef.isVisible(D)) { 11015 D = findAcceptableDecl(SemaRef, D); 11016 if (!D) 11017 continue; 11018 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11019 Underlying = USD->getTargetDecl(); 11020 } 11021 Lookups.emplace_back(); 11022 Lookups.back().addDecl(Underlying); 11023 } 11024 } 11025 } 11026 11027 static ExprResult 11028 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 11029 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 11030 const DeclarationNameInfo &ReductionId, QualType Ty, 11031 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 11032 if (ReductionIdScopeSpec.isInvalid()) 11033 return ExprError(); 11034 SmallVector<UnresolvedSet<8>, 4> Lookups; 11035 if (S) { 11036 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11037 Lookup.suppressDiagnostics(); 11038 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 11039 NamedDecl *D = Lookup.getRepresentativeDecl(); 11040 do { 11041 S = S->getParent(); 11042 } while (S && !S->isDeclScope(D)); 11043 if (S) 11044 S = S->getParent(); 11045 Lookups.emplace_back(); 11046 Lookups.back().append(Lookup.begin(), Lookup.end()); 11047 Lookup.clear(); 11048 } 11049 } else if (auto *ULE = 11050 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 11051 Lookups.push_back(UnresolvedSet<8>()); 11052 Decl *PrevD = nullptr; 11053 for (NamedDecl *D : ULE->decls()) { 11054 if (D == PrevD) 11055 Lookups.push_back(UnresolvedSet<8>()); 11056 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 11057 Lookups.back().addDecl(DRD); 11058 PrevD = D; 11059 } 11060 } 11061 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 11062 Ty->isInstantiationDependentType() || 11063 Ty->containsUnexpandedParameterPack() || 11064 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 11065 return !D->isInvalidDecl() && 11066 (D->getType()->isDependentType() || 11067 D->getType()->isInstantiationDependentType() || 11068 D->getType()->containsUnexpandedParameterPack()); 11069 })) { 11070 UnresolvedSet<8> ResSet; 11071 for (const UnresolvedSet<8> &Set : Lookups) { 11072 if (Set.empty()) 11073 continue; 11074 ResSet.append(Set.begin(), Set.end()); 11075 // The last item marks the end of all declarations at the specified scope. 11076 ResSet.addDecl(Set[Set.size() - 1]); 11077 } 11078 return UnresolvedLookupExpr::Create( 11079 SemaRef.Context, /*NamingClass=*/nullptr, 11080 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 11081 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 11082 } 11083 // Lookup inside the classes. 11084 // C++ [over.match.oper]p3: 11085 // For a unary operator @ with an operand of a type whose 11086 // cv-unqualified version is T1, and for a binary operator @ with 11087 // a left operand of a type whose cv-unqualified version is T1 and 11088 // a right operand of a type whose cv-unqualified version is T2, 11089 // three sets of candidate functions, designated member 11090 // candidates, non-member candidates and built-in candidates, are 11091 // constructed as follows: 11092 // -- If T1 is a complete class type or a class currently being 11093 // defined, the set of member candidates is the result of the 11094 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 11095 // the set of member candidates is empty. 11096 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11097 Lookup.suppressDiagnostics(); 11098 if (const auto *TyRec = Ty->getAs<RecordType>()) { 11099 // Complete the type if it can be completed. 11100 // If the type is neither complete nor being defined, bail out now. 11101 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 11102 TyRec->getDecl()->getDefinition()) { 11103 Lookup.clear(); 11104 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 11105 if (Lookup.empty()) { 11106 Lookups.emplace_back(); 11107 Lookups.back().append(Lookup.begin(), Lookup.end()); 11108 } 11109 } 11110 } 11111 // Perform ADL. 11112 if (SemaRef.getLangOpts().CPlusPlus) { 11113 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 11114 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11115 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 11116 if (!D->isInvalidDecl() && 11117 SemaRef.Context.hasSameType(D->getType(), Ty)) 11118 return D; 11119 return nullptr; 11120 })) 11121 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 11122 VK_LValue, Loc); 11123 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11124 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 11125 if (!D->isInvalidDecl() && 11126 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 11127 !Ty.isMoreQualifiedThan(D->getType())) 11128 return D; 11129 return nullptr; 11130 })) { 11131 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 11132 /*DetectVirtual=*/false); 11133 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 11134 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 11135 VD->getType().getUnqualifiedType()))) { 11136 if (SemaRef.CheckBaseClassAccess( 11137 Loc, VD->getType(), Ty, Paths.front(), 11138 /*DiagID=*/0) != Sema::AR_inaccessible) { 11139 SemaRef.BuildBasePathArray(Paths, BasePath); 11140 return SemaRef.BuildDeclRefExpr( 11141 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 11142 } 11143 } 11144 } 11145 } 11146 } 11147 if (ReductionIdScopeSpec.isSet()) { 11148 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 11149 return ExprError(); 11150 } 11151 return ExprEmpty(); 11152 } 11153 11154 namespace { 11155 /// Data for the reduction-based clauses. 11156 struct ReductionData { 11157 /// List of original reduction items. 11158 SmallVector<Expr *, 8> Vars; 11159 /// List of private copies of the reduction items. 11160 SmallVector<Expr *, 8> Privates; 11161 /// LHS expressions for the reduction_op expressions. 11162 SmallVector<Expr *, 8> LHSs; 11163 /// RHS expressions for the reduction_op expressions. 11164 SmallVector<Expr *, 8> RHSs; 11165 /// Reduction operation expression. 11166 SmallVector<Expr *, 8> ReductionOps; 11167 /// Taskgroup descriptors for the corresponding reduction items in 11168 /// in_reduction clauses. 11169 SmallVector<Expr *, 8> TaskgroupDescriptors; 11170 /// List of captures for clause. 11171 SmallVector<Decl *, 4> ExprCaptures; 11172 /// List of postupdate expressions. 11173 SmallVector<Expr *, 4> ExprPostUpdates; 11174 ReductionData() = delete; 11175 /// Reserves required memory for the reduction data. 11176 ReductionData(unsigned Size) { 11177 Vars.reserve(Size); 11178 Privates.reserve(Size); 11179 LHSs.reserve(Size); 11180 RHSs.reserve(Size); 11181 ReductionOps.reserve(Size); 11182 TaskgroupDescriptors.reserve(Size); 11183 ExprCaptures.reserve(Size); 11184 ExprPostUpdates.reserve(Size); 11185 } 11186 /// Stores reduction item and reduction operation only (required for dependent 11187 /// reduction item). 11188 void push(Expr *Item, Expr *ReductionOp) { 11189 Vars.emplace_back(Item); 11190 Privates.emplace_back(nullptr); 11191 LHSs.emplace_back(nullptr); 11192 RHSs.emplace_back(nullptr); 11193 ReductionOps.emplace_back(ReductionOp); 11194 TaskgroupDescriptors.emplace_back(nullptr); 11195 } 11196 /// Stores reduction data. 11197 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 11198 Expr *TaskgroupDescriptor) { 11199 Vars.emplace_back(Item); 11200 Privates.emplace_back(Private); 11201 LHSs.emplace_back(LHS); 11202 RHSs.emplace_back(RHS); 11203 ReductionOps.emplace_back(ReductionOp); 11204 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 11205 } 11206 }; 11207 } // namespace 11208 11209 static bool checkOMPArraySectionConstantForReduction( 11210 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 11211 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 11212 const Expr *Length = OASE->getLength(); 11213 if (Length == nullptr) { 11214 // For array sections of the form [1:] or [:], we would need to analyze 11215 // the lower bound... 11216 if (OASE->getColonLoc().isValid()) 11217 return false; 11218 11219 // This is an array subscript which has implicit length 1! 11220 SingleElement = true; 11221 ArraySizes.push_back(llvm::APSInt::get(1)); 11222 } else { 11223 Expr::EvalResult Result; 11224 if (!Length->EvaluateAsInt(Result, Context)) 11225 return false; 11226 11227 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11228 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 11229 ArraySizes.push_back(ConstantLengthValue); 11230 } 11231 11232 // Get the base of this array section and walk up from there. 11233 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 11234 11235 // We require length = 1 for all array sections except the right-most to 11236 // guarantee that the memory region is contiguous and has no holes in it. 11237 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 11238 Length = TempOASE->getLength(); 11239 if (Length == nullptr) { 11240 // For array sections of the form [1:] or [:], we would need to analyze 11241 // the lower bound... 11242 if (OASE->getColonLoc().isValid()) 11243 return false; 11244 11245 // This is an array subscript which has implicit length 1! 11246 ArraySizes.push_back(llvm::APSInt::get(1)); 11247 } else { 11248 Expr::EvalResult Result; 11249 if (!Length->EvaluateAsInt(Result, Context)) 11250 return false; 11251 11252 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11253 if (ConstantLengthValue.getSExtValue() != 1) 11254 return false; 11255 11256 ArraySizes.push_back(ConstantLengthValue); 11257 } 11258 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 11259 } 11260 11261 // If we have a single element, we don't need to add the implicit lengths. 11262 if (!SingleElement) { 11263 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 11264 // Has implicit length 1! 11265 ArraySizes.push_back(llvm::APSInt::get(1)); 11266 Base = TempASE->getBase()->IgnoreParenImpCasts(); 11267 } 11268 } 11269 11270 // This array section can be privatized as a single value or as a constant 11271 // sized array. 11272 return true; 11273 } 11274 11275 static bool actOnOMPReductionKindClause( 11276 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 11277 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11278 SourceLocation ColonLoc, SourceLocation EndLoc, 11279 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11280 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 11281 DeclarationName DN = ReductionId.getName(); 11282 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 11283 BinaryOperatorKind BOK = BO_Comma; 11284 11285 ASTContext &Context = S.Context; 11286 // OpenMP [2.14.3.6, reduction clause] 11287 // C 11288 // reduction-identifier is either an identifier or one of the following 11289 // operators: +, -, *, &, |, ^, && and || 11290 // C++ 11291 // reduction-identifier is either an id-expression or one of the following 11292 // operators: +, -, *, &, |, ^, && and || 11293 switch (OOK) { 11294 case OO_Plus: 11295 case OO_Minus: 11296 BOK = BO_Add; 11297 break; 11298 case OO_Star: 11299 BOK = BO_Mul; 11300 break; 11301 case OO_Amp: 11302 BOK = BO_And; 11303 break; 11304 case OO_Pipe: 11305 BOK = BO_Or; 11306 break; 11307 case OO_Caret: 11308 BOK = BO_Xor; 11309 break; 11310 case OO_AmpAmp: 11311 BOK = BO_LAnd; 11312 break; 11313 case OO_PipePipe: 11314 BOK = BO_LOr; 11315 break; 11316 case OO_New: 11317 case OO_Delete: 11318 case OO_Array_New: 11319 case OO_Array_Delete: 11320 case OO_Slash: 11321 case OO_Percent: 11322 case OO_Tilde: 11323 case OO_Exclaim: 11324 case OO_Equal: 11325 case OO_Less: 11326 case OO_Greater: 11327 case OO_LessEqual: 11328 case OO_GreaterEqual: 11329 case OO_PlusEqual: 11330 case OO_MinusEqual: 11331 case OO_StarEqual: 11332 case OO_SlashEqual: 11333 case OO_PercentEqual: 11334 case OO_CaretEqual: 11335 case OO_AmpEqual: 11336 case OO_PipeEqual: 11337 case OO_LessLess: 11338 case OO_GreaterGreater: 11339 case OO_LessLessEqual: 11340 case OO_GreaterGreaterEqual: 11341 case OO_EqualEqual: 11342 case OO_ExclaimEqual: 11343 case OO_Spaceship: 11344 case OO_PlusPlus: 11345 case OO_MinusMinus: 11346 case OO_Comma: 11347 case OO_ArrowStar: 11348 case OO_Arrow: 11349 case OO_Call: 11350 case OO_Subscript: 11351 case OO_Conditional: 11352 case OO_Coawait: 11353 case NUM_OVERLOADED_OPERATORS: 11354 llvm_unreachable("Unexpected reduction identifier"); 11355 case OO_None: 11356 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 11357 if (II->isStr("max")) 11358 BOK = BO_GT; 11359 else if (II->isStr("min")) 11360 BOK = BO_LT; 11361 } 11362 break; 11363 } 11364 SourceRange ReductionIdRange; 11365 if (ReductionIdScopeSpec.isValid()) 11366 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 11367 else 11368 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 11369 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 11370 11371 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 11372 bool FirstIter = true; 11373 for (Expr *RefExpr : VarList) { 11374 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 11375 // OpenMP [2.1, C/C++] 11376 // A list item is a variable or array section, subject to the restrictions 11377 // specified in Section 2.4 on page 42 and in each of the sections 11378 // describing clauses and directives for which a list appears. 11379 // OpenMP [2.14.3.3, Restrictions, p.1] 11380 // A variable that is part of another variable (as an array or 11381 // structure element) cannot appear in a private clause. 11382 if (!FirstIter && IR != ER) 11383 ++IR; 11384 FirstIter = false; 11385 SourceLocation ELoc; 11386 SourceRange ERange; 11387 Expr *SimpleRefExpr = RefExpr; 11388 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 11389 /*AllowArraySection=*/true); 11390 if (Res.second) { 11391 // Try to find 'declare reduction' corresponding construct before using 11392 // builtin/overloaded operators. 11393 QualType Type = Context.DependentTy; 11394 CXXCastPath BasePath; 11395 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11396 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11397 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11398 Expr *ReductionOp = nullptr; 11399 if (S.CurContext->isDependentContext() && 11400 (DeclareReductionRef.isUnset() || 11401 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 11402 ReductionOp = DeclareReductionRef.get(); 11403 // It will be analyzed later. 11404 RD.push(RefExpr, ReductionOp); 11405 } 11406 ValueDecl *D = Res.first; 11407 if (!D) 11408 continue; 11409 11410 Expr *TaskgroupDescriptor = nullptr; 11411 QualType Type; 11412 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 11413 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 11414 if (ASE) { 11415 Type = ASE->getType().getNonReferenceType(); 11416 } else if (OASE) { 11417 QualType BaseType = 11418 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 11419 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 11420 Type = ATy->getElementType(); 11421 else 11422 Type = BaseType->getPointeeType(); 11423 Type = Type.getNonReferenceType(); 11424 } else { 11425 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 11426 } 11427 auto *VD = dyn_cast<VarDecl>(D); 11428 11429 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11430 // A variable that appears in a private clause must not have an incomplete 11431 // type or a reference type. 11432 if (S.RequireCompleteType(ELoc, D->getType(), 11433 diag::err_omp_reduction_incomplete_type)) 11434 continue; 11435 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11436 // A list item that appears in a reduction clause must not be 11437 // const-qualified. 11438 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 11439 /*AcceptIfMutable*/ false, ASE || OASE)) 11440 continue; 11441 11442 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 11443 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 11444 // If a list-item is a reference type then it must bind to the same object 11445 // for all threads of the team. 11446 if (!ASE && !OASE) { 11447 if (VD) { 11448 VarDecl *VDDef = VD->getDefinition(); 11449 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 11450 DSARefChecker Check(Stack); 11451 if (Check.Visit(VDDef->getInit())) { 11452 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 11453 << getOpenMPClauseName(ClauseKind) << ERange; 11454 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 11455 continue; 11456 } 11457 } 11458 } 11459 11460 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11461 // in a Construct] 11462 // Variables with the predetermined data-sharing attributes may not be 11463 // listed in data-sharing attributes clauses, except for the cases 11464 // listed below. For these exceptions only, listing a predetermined 11465 // variable in a data-sharing attribute clause is allowed and overrides 11466 // the variable's predetermined data-sharing attributes. 11467 // OpenMP [2.14.3.6, Restrictions, p.3] 11468 // Any number of reduction clauses can be specified on the directive, 11469 // but a list item can appear only once in the reduction clauses for that 11470 // directive. 11471 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 11472 if (DVar.CKind == OMPC_reduction) { 11473 S.Diag(ELoc, diag::err_omp_once_referenced) 11474 << getOpenMPClauseName(ClauseKind); 11475 if (DVar.RefExpr) 11476 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 11477 continue; 11478 } 11479 if (DVar.CKind != OMPC_unknown) { 11480 S.Diag(ELoc, diag::err_omp_wrong_dsa) 11481 << getOpenMPClauseName(DVar.CKind) 11482 << getOpenMPClauseName(OMPC_reduction); 11483 reportOriginalDsa(S, Stack, D, DVar); 11484 continue; 11485 } 11486 11487 // OpenMP [2.14.3.6, Restrictions, p.1] 11488 // A list item that appears in a reduction clause of a worksharing 11489 // construct must be shared in the parallel regions to which any of the 11490 // worksharing regions arising from the worksharing construct bind. 11491 if (isOpenMPWorksharingDirective(CurrDir) && 11492 !isOpenMPParallelDirective(CurrDir) && 11493 !isOpenMPTeamsDirective(CurrDir)) { 11494 DVar = Stack->getImplicitDSA(D, true); 11495 if (DVar.CKind != OMPC_shared) { 11496 S.Diag(ELoc, diag::err_omp_required_access) 11497 << getOpenMPClauseName(OMPC_reduction) 11498 << getOpenMPClauseName(OMPC_shared); 11499 reportOriginalDsa(S, Stack, D, DVar); 11500 continue; 11501 } 11502 } 11503 } 11504 11505 // Try to find 'declare reduction' corresponding construct before using 11506 // builtin/overloaded operators. 11507 CXXCastPath BasePath; 11508 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11509 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11510 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11511 if (DeclareReductionRef.isInvalid()) 11512 continue; 11513 if (S.CurContext->isDependentContext() && 11514 (DeclareReductionRef.isUnset() || 11515 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 11516 RD.push(RefExpr, DeclareReductionRef.get()); 11517 continue; 11518 } 11519 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 11520 // Not allowed reduction identifier is found. 11521 S.Diag(ReductionId.getBeginLoc(), 11522 diag::err_omp_unknown_reduction_identifier) 11523 << Type << ReductionIdRange; 11524 continue; 11525 } 11526 11527 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11528 // The type of a list item that appears in a reduction clause must be valid 11529 // for the reduction-identifier. For a max or min reduction in C, the type 11530 // of the list item must be an allowed arithmetic data type: char, int, 11531 // float, double, or _Bool, possibly modified with long, short, signed, or 11532 // unsigned. For a max or min reduction in C++, the type of the list item 11533 // must be an allowed arithmetic data type: char, wchar_t, int, float, 11534 // double, or bool, possibly modified with long, short, signed, or unsigned. 11535 if (DeclareReductionRef.isUnset()) { 11536 if ((BOK == BO_GT || BOK == BO_LT) && 11537 !(Type->isScalarType() || 11538 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 11539 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 11540 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 11541 if (!ASE && !OASE) { 11542 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11543 VarDecl::DeclarationOnly; 11544 S.Diag(D->getLocation(), 11545 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11546 << D; 11547 } 11548 continue; 11549 } 11550 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 11551 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 11552 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 11553 << getOpenMPClauseName(ClauseKind); 11554 if (!ASE && !OASE) { 11555 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11556 VarDecl::DeclarationOnly; 11557 S.Diag(D->getLocation(), 11558 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11559 << D; 11560 } 11561 continue; 11562 } 11563 } 11564 11565 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 11566 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 11567 D->hasAttrs() ? &D->getAttrs() : nullptr); 11568 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 11569 D->hasAttrs() ? &D->getAttrs() : nullptr); 11570 QualType PrivateTy = Type; 11571 11572 // Try if we can determine constant lengths for all array sections and avoid 11573 // the VLA. 11574 bool ConstantLengthOASE = false; 11575 if (OASE) { 11576 bool SingleElement; 11577 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 11578 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 11579 Context, OASE, SingleElement, ArraySizes); 11580 11581 // If we don't have a single element, we must emit a constant array type. 11582 if (ConstantLengthOASE && !SingleElement) { 11583 for (llvm::APSInt &Size : ArraySizes) 11584 PrivateTy = Context.getConstantArrayType( 11585 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 11586 } 11587 } 11588 11589 if ((OASE && !ConstantLengthOASE) || 11590 (!OASE && !ASE && 11591 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 11592 if (!Context.getTargetInfo().isVLASupported() && 11593 S.shouldDiagnoseTargetSupportFromOpenMP()) { 11594 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 11595 S.Diag(ELoc, diag::note_vla_unsupported); 11596 continue; 11597 } 11598 // For arrays/array sections only: 11599 // Create pseudo array type for private copy. The size for this array will 11600 // be generated during codegen. 11601 // For array subscripts or single variables Private Ty is the same as Type 11602 // (type of the variable or single array element). 11603 PrivateTy = Context.getVariableArrayType( 11604 Type, 11605 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 11606 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 11607 } else if (!ASE && !OASE && 11608 Context.getAsArrayType(D->getType().getNonReferenceType())) { 11609 PrivateTy = D->getType().getNonReferenceType(); 11610 } 11611 // Private copy. 11612 VarDecl *PrivateVD = 11613 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 11614 D->hasAttrs() ? &D->getAttrs() : nullptr, 11615 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11616 // Add initializer for private variable. 11617 Expr *Init = nullptr; 11618 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 11619 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 11620 if (DeclareReductionRef.isUsable()) { 11621 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 11622 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 11623 if (DRD->getInitializer()) { 11624 Init = DRDRef; 11625 RHSVD->setInit(DRDRef); 11626 RHSVD->setInitStyle(VarDecl::CallInit); 11627 } 11628 } else { 11629 switch (BOK) { 11630 case BO_Add: 11631 case BO_Xor: 11632 case BO_Or: 11633 case BO_LOr: 11634 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 11635 if (Type->isScalarType() || Type->isAnyComplexType()) 11636 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 11637 break; 11638 case BO_Mul: 11639 case BO_LAnd: 11640 if (Type->isScalarType() || Type->isAnyComplexType()) { 11641 // '*' and '&&' reduction ops - initializer is '1'. 11642 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 11643 } 11644 break; 11645 case BO_And: { 11646 // '&' reduction op - initializer is '~0'. 11647 QualType OrigType = Type; 11648 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 11649 Type = ComplexTy->getElementType(); 11650 if (Type->isRealFloatingType()) { 11651 llvm::APFloat InitValue = 11652 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 11653 /*isIEEE=*/true); 11654 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 11655 Type, ELoc); 11656 } else if (Type->isScalarType()) { 11657 uint64_t Size = Context.getTypeSize(Type); 11658 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 11659 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 11660 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 11661 } 11662 if (Init && OrigType->isAnyComplexType()) { 11663 // Init = 0xFFFF + 0xFFFFi; 11664 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 11665 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 11666 } 11667 Type = OrigType; 11668 break; 11669 } 11670 case BO_LT: 11671 case BO_GT: { 11672 // 'min' reduction op - initializer is 'Largest representable number in 11673 // the reduction list item type'. 11674 // 'max' reduction op - initializer is 'Least representable number in 11675 // the reduction list item type'. 11676 if (Type->isIntegerType() || Type->isPointerType()) { 11677 bool IsSigned = Type->hasSignedIntegerRepresentation(); 11678 uint64_t Size = Context.getTypeSize(Type); 11679 QualType IntTy = 11680 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 11681 llvm::APInt InitValue = 11682 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 11683 : llvm::APInt::getMinValue(Size) 11684 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 11685 : llvm::APInt::getMaxValue(Size); 11686 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 11687 if (Type->isPointerType()) { 11688 // Cast to pointer type. 11689 ExprResult CastExpr = S.BuildCStyleCastExpr( 11690 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 11691 if (CastExpr.isInvalid()) 11692 continue; 11693 Init = CastExpr.get(); 11694 } 11695 } else if (Type->isRealFloatingType()) { 11696 llvm::APFloat InitValue = llvm::APFloat::getLargest( 11697 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 11698 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 11699 Type, ELoc); 11700 } 11701 break; 11702 } 11703 case BO_PtrMemD: 11704 case BO_PtrMemI: 11705 case BO_MulAssign: 11706 case BO_Div: 11707 case BO_Rem: 11708 case BO_Sub: 11709 case BO_Shl: 11710 case BO_Shr: 11711 case BO_LE: 11712 case BO_GE: 11713 case BO_EQ: 11714 case BO_NE: 11715 case BO_Cmp: 11716 case BO_AndAssign: 11717 case BO_XorAssign: 11718 case BO_OrAssign: 11719 case BO_Assign: 11720 case BO_AddAssign: 11721 case BO_SubAssign: 11722 case BO_DivAssign: 11723 case BO_RemAssign: 11724 case BO_ShlAssign: 11725 case BO_ShrAssign: 11726 case BO_Comma: 11727 llvm_unreachable("Unexpected reduction operation"); 11728 } 11729 } 11730 if (Init && DeclareReductionRef.isUnset()) 11731 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 11732 else if (!Init) 11733 S.ActOnUninitializedDecl(RHSVD); 11734 if (RHSVD->isInvalidDecl()) 11735 continue; 11736 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 11737 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 11738 << Type << ReductionIdRange; 11739 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11740 VarDecl::DeclarationOnly; 11741 S.Diag(D->getLocation(), 11742 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11743 << D; 11744 continue; 11745 } 11746 // Store initializer for single element in private copy. Will be used during 11747 // codegen. 11748 PrivateVD->setInit(RHSVD->getInit()); 11749 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 11750 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 11751 ExprResult ReductionOp; 11752 if (DeclareReductionRef.isUsable()) { 11753 QualType RedTy = DeclareReductionRef.get()->getType(); 11754 QualType PtrRedTy = Context.getPointerType(RedTy); 11755 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 11756 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 11757 if (!BasePath.empty()) { 11758 LHS = S.DefaultLvalueConversion(LHS.get()); 11759 RHS = S.DefaultLvalueConversion(RHS.get()); 11760 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 11761 CK_UncheckedDerivedToBase, LHS.get(), 11762 &BasePath, LHS.get()->getValueKind()); 11763 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 11764 CK_UncheckedDerivedToBase, RHS.get(), 11765 &BasePath, RHS.get()->getValueKind()); 11766 } 11767 FunctionProtoType::ExtProtoInfo EPI; 11768 QualType Params[] = {PtrRedTy, PtrRedTy}; 11769 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 11770 auto *OVE = new (Context) OpaqueValueExpr( 11771 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 11772 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 11773 Expr *Args[] = {LHS.get(), RHS.get()}; 11774 ReductionOp = 11775 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 11776 } else { 11777 ReductionOp = S.BuildBinOp( 11778 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 11779 if (ReductionOp.isUsable()) { 11780 if (BOK != BO_LT && BOK != BO_GT) { 11781 ReductionOp = 11782 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 11783 BO_Assign, LHSDRE, ReductionOp.get()); 11784 } else { 11785 auto *ConditionalOp = new (Context) 11786 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 11787 Type, VK_LValue, OK_Ordinary); 11788 ReductionOp = 11789 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 11790 BO_Assign, LHSDRE, ConditionalOp); 11791 } 11792 if (ReductionOp.isUsable()) 11793 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 11794 /*DiscardedValue*/ false); 11795 } 11796 if (!ReductionOp.isUsable()) 11797 continue; 11798 } 11799 11800 // OpenMP [2.15.4.6, Restrictions, p.2] 11801 // A list item that appears in an in_reduction clause of a task construct 11802 // must appear in a task_reduction clause of a construct associated with a 11803 // taskgroup region that includes the participating task in its taskgroup 11804 // set. The construct associated with the innermost region that meets this 11805 // condition must specify the same reduction-identifier as the in_reduction 11806 // clause. 11807 if (ClauseKind == OMPC_in_reduction) { 11808 SourceRange ParentSR; 11809 BinaryOperatorKind ParentBOK; 11810 const Expr *ParentReductionOp; 11811 Expr *ParentBOKTD, *ParentReductionOpTD; 11812 DSAStackTy::DSAVarData ParentBOKDSA = 11813 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 11814 ParentBOKTD); 11815 DSAStackTy::DSAVarData ParentReductionOpDSA = 11816 Stack->getTopMostTaskgroupReductionData( 11817 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 11818 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 11819 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 11820 if (!IsParentBOK && !IsParentReductionOp) { 11821 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 11822 continue; 11823 } 11824 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 11825 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 11826 IsParentReductionOp) { 11827 bool EmitError = true; 11828 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 11829 llvm::FoldingSetNodeID RedId, ParentRedId; 11830 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 11831 DeclareReductionRef.get()->Profile(RedId, Context, 11832 /*Canonical=*/true); 11833 EmitError = RedId != ParentRedId; 11834 } 11835 if (EmitError) { 11836 S.Diag(ReductionId.getBeginLoc(), 11837 diag::err_omp_reduction_identifier_mismatch) 11838 << ReductionIdRange << RefExpr->getSourceRange(); 11839 S.Diag(ParentSR.getBegin(), 11840 diag::note_omp_previous_reduction_identifier) 11841 << ParentSR 11842 << (IsParentBOK ? ParentBOKDSA.RefExpr 11843 : ParentReductionOpDSA.RefExpr) 11844 ->getSourceRange(); 11845 continue; 11846 } 11847 } 11848 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 11849 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 11850 } 11851 11852 DeclRefExpr *Ref = nullptr; 11853 Expr *VarsExpr = RefExpr->IgnoreParens(); 11854 if (!VD && !S.CurContext->isDependentContext()) { 11855 if (ASE || OASE) { 11856 TransformExprToCaptures RebuildToCapture(S, D); 11857 VarsExpr = 11858 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 11859 Ref = RebuildToCapture.getCapturedExpr(); 11860 } else { 11861 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 11862 } 11863 if (!S.isOpenMPCapturedDecl(D)) { 11864 RD.ExprCaptures.emplace_back(Ref->getDecl()); 11865 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 11866 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 11867 if (!RefRes.isUsable()) 11868 continue; 11869 ExprResult PostUpdateRes = 11870 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11871 RefRes.get()); 11872 if (!PostUpdateRes.isUsable()) 11873 continue; 11874 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 11875 Stack->getCurrentDirective() == OMPD_taskgroup) { 11876 S.Diag(RefExpr->getExprLoc(), 11877 diag::err_omp_reduction_non_addressable_expression) 11878 << RefExpr->getSourceRange(); 11879 continue; 11880 } 11881 RD.ExprPostUpdates.emplace_back( 11882 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 11883 } 11884 } 11885 } 11886 // All reduction items are still marked as reduction (to do not increase 11887 // code base size). 11888 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 11889 if (CurrDir == OMPD_taskgroup) { 11890 if (DeclareReductionRef.isUsable()) 11891 Stack->addTaskgroupReductionData(D, ReductionIdRange, 11892 DeclareReductionRef.get()); 11893 else 11894 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 11895 } 11896 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 11897 TaskgroupDescriptor); 11898 } 11899 return RD.Vars.empty(); 11900 } 11901 11902 OMPClause *Sema::ActOnOpenMPReductionClause( 11903 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11904 SourceLocation ColonLoc, SourceLocation EndLoc, 11905 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11906 ArrayRef<Expr *> UnresolvedReductions) { 11907 ReductionData RD(VarList.size()); 11908 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 11909 StartLoc, LParenLoc, ColonLoc, EndLoc, 11910 ReductionIdScopeSpec, ReductionId, 11911 UnresolvedReductions, RD)) 11912 return nullptr; 11913 11914 return OMPReductionClause::Create( 11915 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11916 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11917 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 11918 buildPreInits(Context, RD.ExprCaptures), 11919 buildPostUpdate(*this, RD.ExprPostUpdates)); 11920 } 11921 11922 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 11923 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11924 SourceLocation ColonLoc, SourceLocation EndLoc, 11925 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11926 ArrayRef<Expr *> UnresolvedReductions) { 11927 ReductionData RD(VarList.size()); 11928 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 11929 StartLoc, LParenLoc, ColonLoc, EndLoc, 11930 ReductionIdScopeSpec, ReductionId, 11931 UnresolvedReductions, RD)) 11932 return nullptr; 11933 11934 return OMPTaskReductionClause::Create( 11935 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11936 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11937 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 11938 buildPreInits(Context, RD.ExprCaptures), 11939 buildPostUpdate(*this, RD.ExprPostUpdates)); 11940 } 11941 11942 OMPClause *Sema::ActOnOpenMPInReductionClause( 11943 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11944 SourceLocation ColonLoc, SourceLocation EndLoc, 11945 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11946 ArrayRef<Expr *> UnresolvedReductions) { 11947 ReductionData RD(VarList.size()); 11948 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 11949 StartLoc, LParenLoc, ColonLoc, EndLoc, 11950 ReductionIdScopeSpec, ReductionId, 11951 UnresolvedReductions, RD)) 11952 return nullptr; 11953 11954 return OMPInReductionClause::Create( 11955 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11956 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11957 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 11958 buildPreInits(Context, RD.ExprCaptures), 11959 buildPostUpdate(*this, RD.ExprPostUpdates)); 11960 } 11961 11962 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 11963 SourceLocation LinLoc) { 11964 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 11965 LinKind == OMPC_LINEAR_unknown) { 11966 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 11967 return true; 11968 } 11969 return false; 11970 } 11971 11972 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 11973 OpenMPLinearClauseKind LinKind, 11974 QualType Type) { 11975 const auto *VD = dyn_cast_or_null<VarDecl>(D); 11976 // A variable must not have an incomplete type or a reference type. 11977 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 11978 return true; 11979 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 11980 !Type->isReferenceType()) { 11981 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 11982 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 11983 return true; 11984 } 11985 Type = Type.getNonReferenceType(); 11986 11987 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11988 // A variable that is privatized must not have a const-qualified type 11989 // unless it is of class type with a mutable member. This restriction does 11990 // not apply to the firstprivate clause. 11991 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 11992 return true; 11993 11994 // A list item must be of integral or pointer type. 11995 Type = Type.getUnqualifiedType().getCanonicalType(); 11996 const auto *Ty = Type.getTypePtrOrNull(); 11997 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 11998 !Ty->isPointerType())) { 11999 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 12000 if (D) { 12001 bool IsDecl = 12002 !VD || 12003 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12004 Diag(D->getLocation(), 12005 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12006 << D; 12007 } 12008 return true; 12009 } 12010 return false; 12011 } 12012 12013 OMPClause *Sema::ActOnOpenMPLinearClause( 12014 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 12015 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 12016 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12017 SmallVector<Expr *, 8> Vars; 12018 SmallVector<Expr *, 8> Privates; 12019 SmallVector<Expr *, 8> Inits; 12020 SmallVector<Decl *, 4> ExprCaptures; 12021 SmallVector<Expr *, 4> ExprPostUpdates; 12022 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 12023 LinKind = OMPC_LINEAR_val; 12024 for (Expr *RefExpr : VarList) { 12025 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12026 SourceLocation ELoc; 12027 SourceRange ERange; 12028 Expr *SimpleRefExpr = RefExpr; 12029 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12030 if (Res.second) { 12031 // It will be analyzed later. 12032 Vars.push_back(RefExpr); 12033 Privates.push_back(nullptr); 12034 Inits.push_back(nullptr); 12035 } 12036 ValueDecl *D = Res.first; 12037 if (!D) 12038 continue; 12039 12040 QualType Type = D->getType(); 12041 auto *VD = dyn_cast<VarDecl>(D); 12042 12043 // OpenMP [2.14.3.7, linear clause] 12044 // A list-item cannot appear in more than one linear clause. 12045 // A list-item that appears in a linear clause cannot appear in any 12046 // other data-sharing attribute clause. 12047 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12048 if (DVar.RefExpr) { 12049 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12050 << getOpenMPClauseName(OMPC_linear); 12051 reportOriginalDsa(*this, DSAStack, D, DVar); 12052 continue; 12053 } 12054 12055 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 12056 continue; 12057 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12058 12059 // Build private copy of original var. 12060 VarDecl *Private = 12061 buildVarDecl(*this, ELoc, Type, D->getName(), 12062 D->hasAttrs() ? &D->getAttrs() : nullptr, 12063 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12064 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 12065 // Build var to save initial value. 12066 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 12067 Expr *InitExpr; 12068 DeclRefExpr *Ref = nullptr; 12069 if (!VD && !CurContext->isDependentContext()) { 12070 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12071 if (!isOpenMPCapturedDecl(D)) { 12072 ExprCaptures.push_back(Ref->getDecl()); 12073 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12074 ExprResult RefRes = DefaultLvalueConversion(Ref); 12075 if (!RefRes.isUsable()) 12076 continue; 12077 ExprResult PostUpdateRes = 12078 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 12079 SimpleRefExpr, RefRes.get()); 12080 if (!PostUpdateRes.isUsable()) 12081 continue; 12082 ExprPostUpdates.push_back( 12083 IgnoredValueConversions(PostUpdateRes.get()).get()); 12084 } 12085 } 12086 } 12087 if (LinKind == OMPC_LINEAR_uval) 12088 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 12089 else 12090 InitExpr = VD ? SimpleRefExpr : Ref; 12091 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 12092 /*DirectInit=*/false); 12093 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 12094 12095 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 12096 Vars.push_back((VD || CurContext->isDependentContext()) 12097 ? RefExpr->IgnoreParens() 12098 : Ref); 12099 Privates.push_back(PrivateRef); 12100 Inits.push_back(InitRef); 12101 } 12102 12103 if (Vars.empty()) 12104 return nullptr; 12105 12106 Expr *StepExpr = Step; 12107 Expr *CalcStepExpr = nullptr; 12108 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 12109 !Step->isInstantiationDependent() && 12110 !Step->containsUnexpandedParameterPack()) { 12111 SourceLocation StepLoc = Step->getBeginLoc(); 12112 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 12113 if (Val.isInvalid()) 12114 return nullptr; 12115 StepExpr = Val.get(); 12116 12117 // Build var to save the step value. 12118 VarDecl *SaveVar = 12119 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 12120 ExprResult SaveRef = 12121 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 12122 ExprResult CalcStep = 12123 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 12124 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 12125 12126 // Warn about zero linear step (it would be probably better specified as 12127 // making corresponding variables 'const'). 12128 llvm::APSInt Result; 12129 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 12130 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 12131 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 12132 << (Vars.size() > 1); 12133 if (!IsConstant && CalcStep.isUsable()) { 12134 // Calculate the step beforehand instead of doing this on each iteration. 12135 // (This is not used if the number of iterations may be kfold-ed). 12136 CalcStepExpr = CalcStep.get(); 12137 } 12138 } 12139 12140 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 12141 ColonLoc, EndLoc, Vars, Privates, Inits, 12142 StepExpr, CalcStepExpr, 12143 buildPreInits(Context, ExprCaptures), 12144 buildPostUpdate(*this, ExprPostUpdates)); 12145 } 12146 12147 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 12148 Expr *NumIterations, Sema &SemaRef, 12149 Scope *S, DSAStackTy *Stack) { 12150 // Walk the vars and build update/final expressions for the CodeGen. 12151 SmallVector<Expr *, 8> Updates; 12152 SmallVector<Expr *, 8> Finals; 12153 Expr *Step = Clause.getStep(); 12154 Expr *CalcStep = Clause.getCalcStep(); 12155 // OpenMP [2.14.3.7, linear clause] 12156 // If linear-step is not specified it is assumed to be 1. 12157 if (!Step) 12158 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 12159 else if (CalcStep) 12160 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 12161 bool HasErrors = false; 12162 auto CurInit = Clause.inits().begin(); 12163 auto CurPrivate = Clause.privates().begin(); 12164 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 12165 for (Expr *RefExpr : Clause.varlists()) { 12166 SourceLocation ELoc; 12167 SourceRange ERange; 12168 Expr *SimpleRefExpr = RefExpr; 12169 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 12170 ValueDecl *D = Res.first; 12171 if (Res.second || !D) { 12172 Updates.push_back(nullptr); 12173 Finals.push_back(nullptr); 12174 HasErrors = true; 12175 continue; 12176 } 12177 auto &&Info = Stack->isLoopControlVariable(D); 12178 // OpenMP [2.15.11, distribute simd Construct] 12179 // A list item may not appear in a linear clause, unless it is the loop 12180 // iteration variable. 12181 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 12182 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 12183 SemaRef.Diag(ELoc, 12184 diag::err_omp_linear_distribute_var_non_loop_iteration); 12185 Updates.push_back(nullptr); 12186 Finals.push_back(nullptr); 12187 HasErrors = true; 12188 continue; 12189 } 12190 Expr *InitExpr = *CurInit; 12191 12192 // Build privatized reference to the current linear var. 12193 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 12194 Expr *CapturedRef; 12195 if (LinKind == OMPC_LINEAR_uval) 12196 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 12197 else 12198 CapturedRef = 12199 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 12200 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 12201 /*RefersToCapture=*/true); 12202 12203 // Build update: Var = InitExpr + IV * Step 12204 ExprResult Update; 12205 if (!Info.first) 12206 Update = 12207 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 12208 InitExpr, IV, Step, /* Subtract */ false); 12209 else 12210 Update = *CurPrivate; 12211 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 12212 /*DiscardedValue*/ false); 12213 12214 // Build final: Var = InitExpr + NumIterations * Step 12215 ExprResult Final; 12216 if (!Info.first) 12217 Final = 12218 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 12219 InitExpr, NumIterations, Step, /*Subtract=*/false); 12220 else 12221 Final = *CurPrivate; 12222 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 12223 /*DiscardedValue*/ false); 12224 12225 if (!Update.isUsable() || !Final.isUsable()) { 12226 Updates.push_back(nullptr); 12227 Finals.push_back(nullptr); 12228 HasErrors = true; 12229 } else { 12230 Updates.push_back(Update.get()); 12231 Finals.push_back(Final.get()); 12232 } 12233 ++CurInit; 12234 ++CurPrivate; 12235 } 12236 Clause.setUpdates(Updates); 12237 Clause.setFinals(Finals); 12238 return HasErrors; 12239 } 12240 12241 OMPClause *Sema::ActOnOpenMPAlignedClause( 12242 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 12243 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12244 SmallVector<Expr *, 8> Vars; 12245 for (Expr *RefExpr : VarList) { 12246 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12247 SourceLocation ELoc; 12248 SourceRange ERange; 12249 Expr *SimpleRefExpr = RefExpr; 12250 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12251 if (Res.second) { 12252 // It will be analyzed later. 12253 Vars.push_back(RefExpr); 12254 } 12255 ValueDecl *D = Res.first; 12256 if (!D) 12257 continue; 12258 12259 QualType QType = D->getType(); 12260 auto *VD = dyn_cast<VarDecl>(D); 12261 12262 // OpenMP [2.8.1, simd construct, Restrictions] 12263 // The type of list items appearing in the aligned clause must be 12264 // array, pointer, reference to array, or reference to pointer. 12265 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12266 const Type *Ty = QType.getTypePtrOrNull(); 12267 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 12268 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 12269 << QType << getLangOpts().CPlusPlus << ERange; 12270 bool IsDecl = 12271 !VD || 12272 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12273 Diag(D->getLocation(), 12274 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12275 << D; 12276 continue; 12277 } 12278 12279 // OpenMP [2.8.1, simd construct, Restrictions] 12280 // A list-item cannot appear in more than one aligned clause. 12281 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 12282 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 12283 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 12284 << getOpenMPClauseName(OMPC_aligned); 12285 continue; 12286 } 12287 12288 DeclRefExpr *Ref = nullptr; 12289 if (!VD && isOpenMPCapturedDecl(D)) 12290 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12291 Vars.push_back(DefaultFunctionArrayConversion( 12292 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 12293 .get()); 12294 } 12295 12296 // OpenMP [2.8.1, simd construct, Description] 12297 // The parameter of the aligned clause, alignment, must be a constant 12298 // positive integer expression. 12299 // If no optional parameter is specified, implementation-defined default 12300 // alignments for SIMD instructions on the target platforms are assumed. 12301 if (Alignment != nullptr) { 12302 ExprResult AlignResult = 12303 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 12304 if (AlignResult.isInvalid()) 12305 return nullptr; 12306 Alignment = AlignResult.get(); 12307 } 12308 if (Vars.empty()) 12309 return nullptr; 12310 12311 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 12312 EndLoc, Vars, Alignment); 12313 } 12314 12315 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 12316 SourceLocation StartLoc, 12317 SourceLocation LParenLoc, 12318 SourceLocation EndLoc) { 12319 SmallVector<Expr *, 8> Vars; 12320 SmallVector<Expr *, 8> SrcExprs; 12321 SmallVector<Expr *, 8> DstExprs; 12322 SmallVector<Expr *, 8> AssignmentOps; 12323 for (Expr *RefExpr : VarList) { 12324 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 12325 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12326 // It will be analyzed later. 12327 Vars.push_back(RefExpr); 12328 SrcExprs.push_back(nullptr); 12329 DstExprs.push_back(nullptr); 12330 AssignmentOps.push_back(nullptr); 12331 continue; 12332 } 12333 12334 SourceLocation ELoc = RefExpr->getExprLoc(); 12335 // OpenMP [2.1, C/C++] 12336 // A list item is a variable name. 12337 // OpenMP [2.14.4.1, Restrictions, p.1] 12338 // A list item that appears in a copyin clause must be threadprivate. 12339 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 12340 if (!DE || !isa<VarDecl>(DE->getDecl())) { 12341 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 12342 << 0 << RefExpr->getSourceRange(); 12343 continue; 12344 } 12345 12346 Decl *D = DE->getDecl(); 12347 auto *VD = cast<VarDecl>(D); 12348 12349 QualType Type = VD->getType(); 12350 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 12351 // It will be analyzed later. 12352 Vars.push_back(DE); 12353 SrcExprs.push_back(nullptr); 12354 DstExprs.push_back(nullptr); 12355 AssignmentOps.push_back(nullptr); 12356 continue; 12357 } 12358 12359 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 12360 // A list item that appears in a copyin clause must be threadprivate. 12361 if (!DSAStack->isThreadPrivate(VD)) { 12362 Diag(ELoc, diag::err_omp_required_access) 12363 << getOpenMPClauseName(OMPC_copyin) 12364 << getOpenMPDirectiveName(OMPD_threadprivate); 12365 continue; 12366 } 12367 12368 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12369 // A variable of class type (or array thereof) that appears in a 12370 // copyin clause requires an accessible, unambiguous copy assignment 12371 // operator for the class type. 12372 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12373 VarDecl *SrcVD = 12374 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 12375 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12376 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 12377 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 12378 VarDecl *DstVD = 12379 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 12380 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12381 DeclRefExpr *PseudoDstExpr = 12382 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 12383 // For arrays generate assignment operation for single element and replace 12384 // it by the original array element in CodeGen. 12385 ExprResult AssignmentOp = 12386 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 12387 PseudoSrcExpr); 12388 if (AssignmentOp.isInvalid()) 12389 continue; 12390 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 12391 /*DiscardedValue*/ false); 12392 if (AssignmentOp.isInvalid()) 12393 continue; 12394 12395 DSAStack->addDSA(VD, DE, OMPC_copyin); 12396 Vars.push_back(DE); 12397 SrcExprs.push_back(PseudoSrcExpr); 12398 DstExprs.push_back(PseudoDstExpr); 12399 AssignmentOps.push_back(AssignmentOp.get()); 12400 } 12401 12402 if (Vars.empty()) 12403 return nullptr; 12404 12405 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12406 SrcExprs, DstExprs, AssignmentOps); 12407 } 12408 12409 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 12410 SourceLocation StartLoc, 12411 SourceLocation LParenLoc, 12412 SourceLocation EndLoc) { 12413 SmallVector<Expr *, 8> Vars; 12414 SmallVector<Expr *, 8> SrcExprs; 12415 SmallVector<Expr *, 8> DstExprs; 12416 SmallVector<Expr *, 8> AssignmentOps; 12417 for (Expr *RefExpr : VarList) { 12418 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12419 SourceLocation ELoc; 12420 SourceRange ERange; 12421 Expr *SimpleRefExpr = RefExpr; 12422 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12423 if (Res.second) { 12424 // It will be analyzed later. 12425 Vars.push_back(RefExpr); 12426 SrcExprs.push_back(nullptr); 12427 DstExprs.push_back(nullptr); 12428 AssignmentOps.push_back(nullptr); 12429 } 12430 ValueDecl *D = Res.first; 12431 if (!D) 12432 continue; 12433 12434 QualType Type = D->getType(); 12435 auto *VD = dyn_cast<VarDecl>(D); 12436 12437 // OpenMP [2.14.4.2, Restrictions, p.2] 12438 // A list item that appears in a copyprivate clause may not appear in a 12439 // private or firstprivate clause on the single construct. 12440 if (!VD || !DSAStack->isThreadPrivate(VD)) { 12441 DSAStackTy::DSAVarData DVar = 12442 DSAStack->getTopDSA(D, /*FromParent=*/false); 12443 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 12444 DVar.RefExpr) { 12445 Diag(ELoc, diag::err_omp_wrong_dsa) 12446 << getOpenMPClauseName(DVar.CKind) 12447 << getOpenMPClauseName(OMPC_copyprivate); 12448 reportOriginalDsa(*this, DSAStack, D, DVar); 12449 continue; 12450 } 12451 12452 // OpenMP [2.11.4.2, Restrictions, p.1] 12453 // All list items that appear in a copyprivate clause must be either 12454 // threadprivate or private in the enclosing context. 12455 if (DVar.CKind == OMPC_unknown) { 12456 DVar = DSAStack->getImplicitDSA(D, false); 12457 if (DVar.CKind == OMPC_shared) { 12458 Diag(ELoc, diag::err_omp_required_access) 12459 << getOpenMPClauseName(OMPC_copyprivate) 12460 << "threadprivate or private in the enclosing context"; 12461 reportOriginalDsa(*this, DSAStack, D, DVar); 12462 continue; 12463 } 12464 } 12465 } 12466 12467 // Variably modified types are not supported. 12468 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 12469 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12470 << getOpenMPClauseName(OMPC_copyprivate) << Type 12471 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12472 bool IsDecl = 12473 !VD || 12474 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12475 Diag(D->getLocation(), 12476 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12477 << D; 12478 continue; 12479 } 12480 12481 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12482 // A variable of class type (or array thereof) that appears in a 12483 // copyin clause requires an accessible, unambiguous copy assignment 12484 // operator for the class type. 12485 Type = Context.getBaseElementType(Type.getNonReferenceType()) 12486 .getUnqualifiedType(); 12487 VarDecl *SrcVD = 12488 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 12489 D->hasAttrs() ? &D->getAttrs() : nullptr); 12490 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 12491 VarDecl *DstVD = 12492 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 12493 D->hasAttrs() ? &D->getAttrs() : nullptr); 12494 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12495 ExprResult AssignmentOp = BuildBinOp( 12496 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 12497 if (AssignmentOp.isInvalid()) 12498 continue; 12499 AssignmentOp = 12500 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12501 if (AssignmentOp.isInvalid()) 12502 continue; 12503 12504 // No need to mark vars as copyprivate, they are already threadprivate or 12505 // implicitly private. 12506 assert(VD || isOpenMPCapturedDecl(D)); 12507 Vars.push_back( 12508 VD ? RefExpr->IgnoreParens() 12509 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 12510 SrcExprs.push_back(PseudoSrcExpr); 12511 DstExprs.push_back(PseudoDstExpr); 12512 AssignmentOps.push_back(AssignmentOp.get()); 12513 } 12514 12515 if (Vars.empty()) 12516 return nullptr; 12517 12518 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12519 Vars, SrcExprs, DstExprs, AssignmentOps); 12520 } 12521 12522 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 12523 SourceLocation StartLoc, 12524 SourceLocation LParenLoc, 12525 SourceLocation EndLoc) { 12526 if (VarList.empty()) 12527 return nullptr; 12528 12529 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 12530 } 12531 12532 OMPClause * 12533 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 12534 SourceLocation DepLoc, SourceLocation ColonLoc, 12535 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 12536 SourceLocation LParenLoc, SourceLocation EndLoc) { 12537 if (DSAStack->getCurrentDirective() == OMPD_ordered && 12538 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 12539 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 12540 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 12541 return nullptr; 12542 } 12543 if (DSAStack->getCurrentDirective() != OMPD_ordered && 12544 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 12545 DepKind == OMPC_DEPEND_sink)) { 12546 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 12547 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 12548 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12549 /*Last=*/OMPC_DEPEND_unknown, Except) 12550 << getOpenMPClauseName(OMPC_depend); 12551 return nullptr; 12552 } 12553 SmallVector<Expr *, 8> Vars; 12554 DSAStackTy::OperatorOffsetTy OpsOffs; 12555 llvm::APSInt DepCounter(/*BitWidth=*/32); 12556 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 12557 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 12558 if (const Expr *OrderedCountExpr = 12559 DSAStack->getParentOrderedRegionParam().first) { 12560 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 12561 TotalDepCount.setIsUnsigned(/*Val=*/true); 12562 } 12563 } 12564 for (Expr *RefExpr : VarList) { 12565 assert(RefExpr && "NULL expr in OpenMP shared clause."); 12566 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12567 // It will be analyzed later. 12568 Vars.push_back(RefExpr); 12569 continue; 12570 } 12571 12572 SourceLocation ELoc = RefExpr->getExprLoc(); 12573 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 12574 if (DepKind == OMPC_DEPEND_sink) { 12575 if (DSAStack->getParentOrderedRegionParam().first && 12576 DepCounter >= TotalDepCount) { 12577 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 12578 continue; 12579 } 12580 ++DepCounter; 12581 // OpenMP [2.13.9, Summary] 12582 // depend(dependence-type : vec), where dependence-type is: 12583 // 'sink' and where vec is the iteration vector, which has the form: 12584 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 12585 // where n is the value specified by the ordered clause in the loop 12586 // directive, xi denotes the loop iteration variable of the i-th nested 12587 // loop associated with the loop directive, and di is a constant 12588 // non-negative integer. 12589 if (CurContext->isDependentContext()) { 12590 // It will be analyzed later. 12591 Vars.push_back(RefExpr); 12592 continue; 12593 } 12594 SimpleExpr = SimpleExpr->IgnoreImplicit(); 12595 OverloadedOperatorKind OOK = OO_None; 12596 SourceLocation OOLoc; 12597 Expr *LHS = SimpleExpr; 12598 Expr *RHS = nullptr; 12599 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 12600 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 12601 OOLoc = BO->getOperatorLoc(); 12602 LHS = BO->getLHS()->IgnoreParenImpCasts(); 12603 RHS = BO->getRHS()->IgnoreParenImpCasts(); 12604 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 12605 OOK = OCE->getOperator(); 12606 OOLoc = OCE->getOperatorLoc(); 12607 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 12608 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 12609 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 12610 OOK = MCE->getMethodDecl() 12611 ->getNameInfo() 12612 .getName() 12613 .getCXXOverloadedOperator(); 12614 OOLoc = MCE->getCallee()->getExprLoc(); 12615 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 12616 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 12617 } 12618 SourceLocation ELoc; 12619 SourceRange ERange; 12620 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 12621 if (Res.second) { 12622 // It will be analyzed later. 12623 Vars.push_back(RefExpr); 12624 } 12625 ValueDecl *D = Res.first; 12626 if (!D) 12627 continue; 12628 12629 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 12630 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 12631 continue; 12632 } 12633 if (RHS) { 12634 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 12635 RHS, OMPC_depend, /*StrictlyPositive=*/false); 12636 if (RHSRes.isInvalid()) 12637 continue; 12638 } 12639 if (!CurContext->isDependentContext() && 12640 DSAStack->getParentOrderedRegionParam().first && 12641 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 12642 const ValueDecl *VD = 12643 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 12644 if (VD) 12645 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 12646 << 1 << VD; 12647 else 12648 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 12649 continue; 12650 } 12651 OpsOffs.emplace_back(RHS, OOK); 12652 } else { 12653 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 12654 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 12655 (ASE && 12656 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 12657 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 12658 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 12659 << RefExpr->getSourceRange(); 12660 continue; 12661 } 12662 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 12663 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 12664 ExprResult Res = 12665 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); 12666 getDiagnostics().setSuppressAllDiagnostics(Suppress); 12667 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 12668 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 12669 << RefExpr->getSourceRange(); 12670 continue; 12671 } 12672 } 12673 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 12674 } 12675 12676 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 12677 TotalDepCount > VarList.size() && 12678 DSAStack->getParentOrderedRegionParam().first && 12679 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 12680 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 12681 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 12682 } 12683 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 12684 Vars.empty()) 12685 return nullptr; 12686 12687 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12688 DepKind, DepLoc, ColonLoc, Vars, 12689 TotalDepCount.getZExtValue()); 12690 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 12691 DSAStack->isParentOrderedRegion()) 12692 DSAStack->addDoacrossDependClause(C, OpsOffs); 12693 return C; 12694 } 12695 12696 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 12697 SourceLocation LParenLoc, 12698 SourceLocation EndLoc) { 12699 Expr *ValExpr = Device; 12700 Stmt *HelperValStmt = nullptr; 12701 12702 // OpenMP [2.9.1, Restrictions] 12703 // The device expression must evaluate to a non-negative integer value. 12704 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 12705 /*StrictlyPositive=*/false)) 12706 return nullptr; 12707 12708 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12709 OpenMPDirectiveKind CaptureRegion = 12710 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 12711 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12712 ValExpr = MakeFullExpr(ValExpr).get(); 12713 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12714 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12715 HelperValStmt = buildPreInits(Context, Captures); 12716 } 12717 12718 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 12719 StartLoc, LParenLoc, EndLoc); 12720 } 12721 12722 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 12723 DSAStackTy *Stack, QualType QTy, 12724 bool FullCheck = true) { 12725 NamedDecl *ND; 12726 if (QTy->isIncompleteType(&ND)) { 12727 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 12728 return false; 12729 } 12730 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 12731 !QTy.isTrivialType(SemaRef.Context)) 12732 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 12733 return true; 12734 } 12735 12736 /// Return true if it can be proven that the provided array expression 12737 /// (array section or array subscript) does NOT specify the whole size of the 12738 /// array whose base type is \a BaseQTy. 12739 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 12740 const Expr *E, 12741 QualType BaseQTy) { 12742 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 12743 12744 // If this is an array subscript, it refers to the whole size if the size of 12745 // the dimension is constant and equals 1. Also, an array section assumes the 12746 // format of an array subscript if no colon is used. 12747 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 12748 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 12749 return ATy->getSize().getSExtValue() != 1; 12750 // Size can't be evaluated statically. 12751 return false; 12752 } 12753 12754 assert(OASE && "Expecting array section if not an array subscript."); 12755 const Expr *LowerBound = OASE->getLowerBound(); 12756 const Expr *Length = OASE->getLength(); 12757 12758 // If there is a lower bound that does not evaluates to zero, we are not 12759 // covering the whole dimension. 12760 if (LowerBound) { 12761 Expr::EvalResult Result; 12762 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 12763 return false; // Can't get the integer value as a constant. 12764 12765 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 12766 if (ConstLowerBound.getSExtValue()) 12767 return true; 12768 } 12769 12770 // If we don't have a length we covering the whole dimension. 12771 if (!Length) 12772 return false; 12773 12774 // If the base is a pointer, we don't have a way to get the size of the 12775 // pointee. 12776 if (BaseQTy->isPointerType()) 12777 return false; 12778 12779 // We can only check if the length is the same as the size of the dimension 12780 // if we have a constant array. 12781 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 12782 if (!CATy) 12783 return false; 12784 12785 Expr::EvalResult Result; 12786 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 12787 return false; // Can't get the integer value as a constant. 12788 12789 llvm::APSInt ConstLength = Result.Val.getInt(); 12790 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 12791 } 12792 12793 // Return true if it can be proven that the provided array expression (array 12794 // section or array subscript) does NOT specify a single element of the array 12795 // whose base type is \a BaseQTy. 12796 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 12797 const Expr *E, 12798 QualType BaseQTy) { 12799 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 12800 12801 // An array subscript always refer to a single element. Also, an array section 12802 // assumes the format of an array subscript if no colon is used. 12803 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 12804 return false; 12805 12806 assert(OASE && "Expecting array section if not an array subscript."); 12807 const Expr *Length = OASE->getLength(); 12808 12809 // If we don't have a length we have to check if the array has unitary size 12810 // for this dimension. Also, we should always expect a length if the base type 12811 // is pointer. 12812 if (!Length) { 12813 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 12814 return ATy->getSize().getSExtValue() != 1; 12815 // We cannot assume anything. 12816 return false; 12817 } 12818 12819 // Check if the length evaluates to 1. 12820 Expr::EvalResult Result; 12821 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 12822 return false; // Can't get the integer value as a constant. 12823 12824 llvm::APSInt ConstLength = Result.Val.getInt(); 12825 return ConstLength.getSExtValue() != 1; 12826 } 12827 12828 // Return the expression of the base of the mappable expression or null if it 12829 // cannot be determined and do all the necessary checks to see if the expression 12830 // is valid as a standalone mappable expression. In the process, record all the 12831 // components of the expression. 12832 static const Expr *checkMapClauseExpressionBase( 12833 Sema &SemaRef, Expr *E, 12834 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 12835 OpenMPClauseKind CKind, bool NoDiagnose) { 12836 SourceLocation ELoc = E->getExprLoc(); 12837 SourceRange ERange = E->getSourceRange(); 12838 12839 // The base of elements of list in a map clause have to be either: 12840 // - a reference to variable or field. 12841 // - a member expression. 12842 // - an array expression. 12843 // 12844 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 12845 // reference to 'r'. 12846 // 12847 // If we have: 12848 // 12849 // struct SS { 12850 // Bla S; 12851 // foo() { 12852 // #pragma omp target map (S.Arr[:12]); 12853 // } 12854 // } 12855 // 12856 // We want to retrieve the member expression 'this->S'; 12857 12858 const Expr *RelevantExpr = nullptr; 12859 12860 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 12861 // If a list item is an array section, it must specify contiguous storage. 12862 // 12863 // For this restriction it is sufficient that we make sure only references 12864 // to variables or fields and array expressions, and that no array sections 12865 // exist except in the rightmost expression (unless they cover the whole 12866 // dimension of the array). E.g. these would be invalid: 12867 // 12868 // r.ArrS[3:5].Arr[6:7] 12869 // 12870 // r.ArrS[3:5].x 12871 // 12872 // but these would be valid: 12873 // r.ArrS[3].Arr[6:7] 12874 // 12875 // r.ArrS[3].x 12876 12877 bool AllowUnitySizeArraySection = true; 12878 bool AllowWholeSizeArraySection = true; 12879 12880 while (!RelevantExpr) { 12881 E = E->IgnoreParenImpCasts(); 12882 12883 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 12884 if (!isa<VarDecl>(CurE->getDecl())) 12885 return nullptr; 12886 12887 RelevantExpr = CurE; 12888 12889 // If we got a reference to a declaration, we should not expect any array 12890 // section before that. 12891 AllowUnitySizeArraySection = false; 12892 AllowWholeSizeArraySection = false; 12893 12894 // Record the component. 12895 CurComponents.emplace_back(CurE, CurE->getDecl()); 12896 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 12897 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 12898 12899 if (isa<CXXThisExpr>(BaseE)) 12900 // We found a base expression: this->Val. 12901 RelevantExpr = CurE; 12902 else 12903 E = BaseE; 12904 12905 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 12906 if (!NoDiagnose) { 12907 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 12908 << CurE->getSourceRange(); 12909 return nullptr; 12910 } 12911 if (RelevantExpr) 12912 return nullptr; 12913 continue; 12914 } 12915 12916 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 12917 12918 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 12919 // A bit-field cannot appear in a map clause. 12920 // 12921 if (FD->isBitField()) { 12922 if (!NoDiagnose) { 12923 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 12924 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 12925 return nullptr; 12926 } 12927 if (RelevantExpr) 12928 return nullptr; 12929 continue; 12930 } 12931 12932 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12933 // If the type of a list item is a reference to a type T then the type 12934 // will be considered to be T for all purposes of this clause. 12935 QualType CurType = BaseE->getType().getNonReferenceType(); 12936 12937 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 12938 // A list item cannot be a variable that is a member of a structure with 12939 // a union type. 12940 // 12941 if (CurType->isUnionType()) { 12942 if (!NoDiagnose) { 12943 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 12944 << CurE->getSourceRange(); 12945 return nullptr; 12946 } 12947 continue; 12948 } 12949 12950 // If we got a member expression, we should not expect any array section 12951 // before that: 12952 // 12953 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 12954 // If a list item is an element of a structure, only the rightmost symbol 12955 // of the variable reference can be an array section. 12956 // 12957 AllowUnitySizeArraySection = false; 12958 AllowWholeSizeArraySection = false; 12959 12960 // Record the component. 12961 CurComponents.emplace_back(CurE, FD); 12962 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 12963 E = CurE->getBase()->IgnoreParenImpCasts(); 12964 12965 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 12966 if (!NoDiagnose) { 12967 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 12968 << 0 << CurE->getSourceRange(); 12969 return nullptr; 12970 } 12971 continue; 12972 } 12973 12974 // If we got an array subscript that express the whole dimension we 12975 // can have any array expressions before. If it only expressing part of 12976 // the dimension, we can only have unitary-size array expressions. 12977 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 12978 E->getType())) 12979 AllowWholeSizeArraySection = false; 12980 12981 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 12982 Expr::EvalResult Result; 12983 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 12984 if (!Result.Val.getInt().isNullValue()) { 12985 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 12986 diag::err_omp_invalid_map_this_expr); 12987 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 12988 diag::note_omp_invalid_subscript_on_this_ptr_map); 12989 } 12990 } 12991 RelevantExpr = TE; 12992 } 12993 12994 // Record the component - we don't have any declaration associated. 12995 CurComponents.emplace_back(CurE, nullptr); 12996 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 12997 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 12998 E = CurE->getBase()->IgnoreParenImpCasts(); 12999 13000 QualType CurType = 13001 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13002 13003 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13004 // If the type of a list item is a reference to a type T then the type 13005 // will be considered to be T for all purposes of this clause. 13006 if (CurType->isReferenceType()) 13007 CurType = CurType->getPointeeType(); 13008 13009 bool IsPointer = CurType->isAnyPointerType(); 13010 13011 if (!IsPointer && !CurType->isArrayType()) { 13012 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13013 << 0 << CurE->getSourceRange(); 13014 return nullptr; 13015 } 13016 13017 bool NotWhole = 13018 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 13019 bool NotUnity = 13020 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 13021 13022 if (AllowWholeSizeArraySection) { 13023 // Any array section is currently allowed. Allowing a whole size array 13024 // section implies allowing a unity array section as well. 13025 // 13026 // If this array section refers to the whole dimension we can still 13027 // accept other array sections before this one, except if the base is a 13028 // pointer. Otherwise, only unitary sections are accepted. 13029 if (NotWhole || IsPointer) 13030 AllowWholeSizeArraySection = false; 13031 } else if (AllowUnitySizeArraySection && NotUnity) { 13032 // A unity or whole array section is not allowed and that is not 13033 // compatible with the properties of the current array section. 13034 SemaRef.Diag( 13035 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 13036 << CurE->getSourceRange(); 13037 return nullptr; 13038 } 13039 13040 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13041 Expr::EvalResult ResultR; 13042 Expr::EvalResult ResultL; 13043 if (CurE->getLength()->EvaluateAsInt(ResultR, 13044 SemaRef.getASTContext())) { 13045 if (!ResultR.Val.getInt().isOneValue()) { 13046 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13047 diag::err_omp_invalid_map_this_expr); 13048 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13049 diag::note_omp_invalid_length_on_this_ptr_mapping); 13050 } 13051 } 13052 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 13053 ResultL, SemaRef.getASTContext())) { 13054 if (!ResultL.Val.getInt().isNullValue()) { 13055 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13056 diag::err_omp_invalid_map_this_expr); 13057 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13058 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 13059 } 13060 } 13061 RelevantExpr = TE; 13062 } 13063 13064 // Record the component - we don't have any declaration associated. 13065 CurComponents.emplace_back(CurE, nullptr); 13066 } else { 13067 if (!NoDiagnose) { 13068 // If nothing else worked, this is not a valid map clause expression. 13069 SemaRef.Diag( 13070 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 13071 << ERange; 13072 } 13073 return nullptr; 13074 } 13075 } 13076 13077 return RelevantExpr; 13078 } 13079 13080 // Return true if expression E associated with value VD has conflicts with other 13081 // map information. 13082 static bool checkMapConflicts( 13083 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 13084 bool CurrentRegionOnly, 13085 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 13086 OpenMPClauseKind CKind) { 13087 assert(VD && E); 13088 SourceLocation ELoc = E->getExprLoc(); 13089 SourceRange ERange = E->getSourceRange(); 13090 13091 // In order to easily check the conflicts we need to match each component of 13092 // the expression under test with the components of the expressions that are 13093 // already in the stack. 13094 13095 assert(!CurComponents.empty() && "Map clause expression with no components!"); 13096 assert(CurComponents.back().getAssociatedDeclaration() == VD && 13097 "Map clause expression with unexpected base!"); 13098 13099 // Variables to help detecting enclosing problems in data environment nests. 13100 bool IsEnclosedByDataEnvironmentExpr = false; 13101 const Expr *EnclosingExpr = nullptr; 13102 13103 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 13104 VD, CurrentRegionOnly, 13105 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 13106 ERange, CKind, &EnclosingExpr, 13107 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 13108 StackComponents, 13109 OpenMPClauseKind) { 13110 assert(!StackComponents.empty() && 13111 "Map clause expression with no components!"); 13112 assert(StackComponents.back().getAssociatedDeclaration() == VD && 13113 "Map clause expression with unexpected base!"); 13114 (void)VD; 13115 13116 // The whole expression in the stack. 13117 const Expr *RE = StackComponents.front().getAssociatedExpression(); 13118 13119 // Expressions must start from the same base. Here we detect at which 13120 // point both expressions diverge from each other and see if we can 13121 // detect if the memory referred to both expressions is contiguous and 13122 // do not overlap. 13123 auto CI = CurComponents.rbegin(); 13124 auto CE = CurComponents.rend(); 13125 auto SI = StackComponents.rbegin(); 13126 auto SE = StackComponents.rend(); 13127 for (; CI != CE && SI != SE; ++CI, ++SI) { 13128 13129 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 13130 // At most one list item can be an array item derived from a given 13131 // variable in map clauses of the same construct. 13132 if (CurrentRegionOnly && 13133 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 13134 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 13135 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 13136 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 13137 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 13138 diag::err_omp_multiple_array_items_in_map_clause) 13139 << CI->getAssociatedExpression()->getSourceRange(); 13140 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 13141 diag::note_used_here) 13142 << SI->getAssociatedExpression()->getSourceRange(); 13143 return true; 13144 } 13145 13146 // Do both expressions have the same kind? 13147 if (CI->getAssociatedExpression()->getStmtClass() != 13148 SI->getAssociatedExpression()->getStmtClass()) 13149 break; 13150 13151 // Are we dealing with different variables/fields? 13152 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 13153 break; 13154 } 13155 // Check if the extra components of the expressions in the enclosing 13156 // data environment are redundant for the current base declaration. 13157 // If they are, the maps completely overlap, which is legal. 13158 for (; SI != SE; ++SI) { 13159 QualType Type; 13160 if (const auto *ASE = 13161 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 13162 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 13163 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 13164 SI->getAssociatedExpression())) { 13165 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 13166 Type = 13167 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13168 } 13169 if (Type.isNull() || Type->isAnyPointerType() || 13170 checkArrayExpressionDoesNotReferToWholeSize( 13171 SemaRef, SI->getAssociatedExpression(), Type)) 13172 break; 13173 } 13174 13175 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13176 // List items of map clauses in the same construct must not share 13177 // original storage. 13178 // 13179 // If the expressions are exactly the same or one is a subset of the 13180 // other, it means they are sharing storage. 13181 if (CI == CE && SI == SE) { 13182 if (CurrentRegionOnly) { 13183 if (CKind == OMPC_map) { 13184 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13185 } else { 13186 assert(CKind == OMPC_to || CKind == OMPC_from); 13187 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13188 << ERange; 13189 } 13190 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13191 << RE->getSourceRange(); 13192 return true; 13193 } 13194 // If we find the same expression in the enclosing data environment, 13195 // that is legal. 13196 IsEnclosedByDataEnvironmentExpr = true; 13197 return false; 13198 } 13199 13200 QualType DerivedType = 13201 std::prev(CI)->getAssociatedDeclaration()->getType(); 13202 SourceLocation DerivedLoc = 13203 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 13204 13205 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13206 // If the type of a list item is a reference to a type T then the type 13207 // will be considered to be T for all purposes of this clause. 13208 DerivedType = DerivedType.getNonReferenceType(); 13209 13210 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 13211 // A variable for which the type is pointer and an array section 13212 // derived from that variable must not appear as list items of map 13213 // clauses of the same construct. 13214 // 13215 // Also, cover one of the cases in: 13216 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13217 // If any part of the original storage of a list item has corresponding 13218 // storage in the device data environment, all of the original storage 13219 // must have corresponding storage in the device data environment. 13220 // 13221 if (DerivedType->isAnyPointerType()) { 13222 if (CI == CE || SI == SE) { 13223 SemaRef.Diag( 13224 DerivedLoc, 13225 diag::err_omp_pointer_mapped_along_with_derived_section) 13226 << DerivedLoc; 13227 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13228 << RE->getSourceRange(); 13229 return true; 13230 } 13231 if (CI->getAssociatedExpression()->getStmtClass() != 13232 SI->getAssociatedExpression()->getStmtClass() || 13233 CI->getAssociatedDeclaration()->getCanonicalDecl() == 13234 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 13235 assert(CI != CE && SI != SE); 13236 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 13237 << DerivedLoc; 13238 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13239 << RE->getSourceRange(); 13240 return true; 13241 } 13242 } 13243 13244 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13245 // List items of map clauses in the same construct must not share 13246 // original storage. 13247 // 13248 // An expression is a subset of the other. 13249 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 13250 if (CKind == OMPC_map) { 13251 if (CI != CE || SI != SE) { 13252 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 13253 // a pointer. 13254 auto Begin = 13255 CI != CE ? CurComponents.begin() : StackComponents.begin(); 13256 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 13257 auto It = Begin; 13258 while (It != End && !It->getAssociatedDeclaration()) 13259 std::advance(It, 1); 13260 assert(It != End && 13261 "Expected at least one component with the declaration."); 13262 if (It != Begin && It->getAssociatedDeclaration() 13263 ->getType() 13264 .getCanonicalType() 13265 ->isAnyPointerType()) { 13266 IsEnclosedByDataEnvironmentExpr = false; 13267 EnclosingExpr = nullptr; 13268 return false; 13269 } 13270 } 13271 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13272 } else { 13273 assert(CKind == OMPC_to || CKind == OMPC_from); 13274 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13275 << ERange; 13276 } 13277 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13278 << RE->getSourceRange(); 13279 return true; 13280 } 13281 13282 // The current expression uses the same base as other expression in the 13283 // data environment but does not contain it completely. 13284 if (!CurrentRegionOnly && SI != SE) 13285 EnclosingExpr = RE; 13286 13287 // The current expression is a subset of the expression in the data 13288 // environment. 13289 IsEnclosedByDataEnvironmentExpr |= 13290 (!CurrentRegionOnly && CI != CE && SI == SE); 13291 13292 return false; 13293 }); 13294 13295 if (CurrentRegionOnly) 13296 return FoundError; 13297 13298 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13299 // If any part of the original storage of a list item has corresponding 13300 // storage in the device data environment, all of the original storage must 13301 // have corresponding storage in the device data environment. 13302 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 13303 // If a list item is an element of a structure, and a different element of 13304 // the structure has a corresponding list item in the device data environment 13305 // prior to a task encountering the construct associated with the map clause, 13306 // then the list item must also have a corresponding list item in the device 13307 // data environment prior to the task encountering the construct. 13308 // 13309 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 13310 SemaRef.Diag(ELoc, 13311 diag::err_omp_original_storage_is_shared_and_does_not_contain) 13312 << ERange; 13313 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 13314 << EnclosingExpr->getSourceRange(); 13315 return true; 13316 } 13317 13318 return FoundError; 13319 } 13320 13321 // Look up the user-defined mapper given the mapper name and mapped type, and 13322 // build a reference to it. 13323 ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 13324 CXXScopeSpec &MapperIdScopeSpec, 13325 const DeclarationNameInfo &MapperId, 13326 QualType Type, Expr *UnresolvedMapper) { 13327 if (MapperIdScopeSpec.isInvalid()) 13328 return ExprError(); 13329 // Find all user-defined mappers with the given MapperId. 13330 SmallVector<UnresolvedSet<8>, 4> Lookups; 13331 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 13332 Lookup.suppressDiagnostics(); 13333 if (S) { 13334 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 13335 NamedDecl *D = Lookup.getRepresentativeDecl(); 13336 while (S && !S->isDeclScope(D)) 13337 S = S->getParent(); 13338 if (S) 13339 S = S->getParent(); 13340 Lookups.emplace_back(); 13341 Lookups.back().append(Lookup.begin(), Lookup.end()); 13342 Lookup.clear(); 13343 } 13344 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 13345 // Extract the user-defined mappers with the given MapperId. 13346 Lookups.push_back(UnresolvedSet<8>()); 13347 for (NamedDecl *D : ULE->decls()) { 13348 auto *DMD = cast<OMPDeclareMapperDecl>(D); 13349 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 13350 Lookups.back().addDecl(DMD); 13351 } 13352 } 13353 // Defer the lookup for dependent types. The results will be passed through 13354 // UnresolvedMapper on instantiation. 13355 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 13356 Type->isInstantiationDependentType() || 13357 Type->containsUnexpandedParameterPack() || 13358 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13359 return !D->isInvalidDecl() && 13360 (D->getType()->isDependentType() || 13361 D->getType()->isInstantiationDependentType() || 13362 D->getType()->containsUnexpandedParameterPack()); 13363 })) { 13364 UnresolvedSet<8> URS; 13365 for (const UnresolvedSet<8> &Set : Lookups) { 13366 if (Set.empty()) 13367 continue; 13368 URS.append(Set.begin(), Set.end()); 13369 } 13370 return UnresolvedLookupExpr::Create( 13371 SemaRef.Context, /*NamingClass=*/nullptr, 13372 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 13373 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 13374 } 13375 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 13376 // The type must be of struct, union or class type in C and C++ 13377 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 13378 return ExprEmpty(); 13379 SourceLocation Loc = MapperId.getLoc(); 13380 // Perform argument dependent lookup. 13381 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 13382 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 13383 // Return the first user-defined mapper with the desired type. 13384 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13385 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 13386 if (!D->isInvalidDecl() && 13387 SemaRef.Context.hasSameType(D->getType(), Type)) 13388 return D; 13389 return nullptr; 13390 })) 13391 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13392 // Find the first user-defined mapper with a type derived from the desired 13393 // type. 13394 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13395 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 13396 if (!D->isInvalidDecl() && 13397 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 13398 !Type.isMoreQualifiedThan(D->getType())) 13399 return D; 13400 return nullptr; 13401 })) { 13402 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13403 /*DetectVirtual=*/false); 13404 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 13405 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13406 VD->getType().getUnqualifiedType()))) { 13407 if (SemaRef.CheckBaseClassAccess( 13408 Loc, VD->getType(), Type, Paths.front(), 13409 /*DiagID=*/0) != Sema::AR_inaccessible) { 13410 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13411 } 13412 } 13413 } 13414 } 13415 // Report error if a mapper is specified, but cannot be found. 13416 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 13417 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 13418 << Type << MapperId.getName(); 13419 return ExprError(); 13420 } 13421 return ExprEmpty(); 13422 } 13423 13424 namespace { 13425 // Utility struct that gathers all the related lists associated with a mappable 13426 // expression. 13427 struct MappableVarListInfo { 13428 // The list of expressions. 13429 ArrayRef<Expr *> VarList; 13430 // The list of processed expressions. 13431 SmallVector<Expr *, 16> ProcessedVarList; 13432 // The mappble components for each expression. 13433 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 13434 // The base declaration of the variable. 13435 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 13436 // The reference to the user-defined mapper associated with every expression. 13437 SmallVector<Expr *, 16> UDMapperList; 13438 13439 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 13440 // We have a list of components and base declarations for each entry in the 13441 // variable list. 13442 VarComponents.reserve(VarList.size()); 13443 VarBaseDeclarations.reserve(VarList.size()); 13444 } 13445 }; 13446 } 13447 13448 // Check the validity of the provided variable list for the provided clause kind 13449 // \a CKind. In the check process the valid expressions, mappable expression 13450 // components, variables, and user-defined mappers are extracted and used to 13451 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 13452 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 13453 // and \a MapperId are expected to be valid if the clause kind is 'map'. 13454 static void checkMappableExpressionList( 13455 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 13456 MappableVarListInfo &MVLI, SourceLocation StartLoc, 13457 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 13458 ArrayRef<Expr *> UnresolvedMappers, 13459 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 13460 bool IsMapTypeImplicit = false) { 13461 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 13462 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 13463 "Unexpected clause kind with mappable expressions!"); 13464 13465 // If the identifier of user-defined mapper is not specified, it is "default". 13466 // We do not change the actual name in this clause to distinguish whether a 13467 // mapper is specified explicitly, i.e., it is not explicitly specified when 13468 // MapperId.getName() is empty. 13469 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 13470 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 13471 MapperId.setName(DeclNames.getIdentifier( 13472 &SemaRef.getASTContext().Idents.get("default"))); 13473 } 13474 13475 // Iterators to find the current unresolved mapper expression. 13476 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 13477 bool UpdateUMIt = false; 13478 Expr *UnresolvedMapper = nullptr; 13479 13480 // Keep track of the mappable components and base declarations in this clause. 13481 // Each entry in the list is going to have a list of components associated. We 13482 // record each set of the components so that we can build the clause later on. 13483 // In the end we should have the same amount of declarations and component 13484 // lists. 13485 13486 for (Expr *RE : MVLI.VarList) { 13487 assert(RE && "Null expr in omp to/from/map clause"); 13488 SourceLocation ELoc = RE->getExprLoc(); 13489 13490 // Find the current unresolved mapper expression. 13491 if (UpdateUMIt && UMIt != UMEnd) { 13492 UMIt++; 13493 assert( 13494 UMIt != UMEnd && 13495 "Expect the size of UnresolvedMappers to match with that of VarList"); 13496 } 13497 UpdateUMIt = true; 13498 if (UMIt != UMEnd) 13499 UnresolvedMapper = *UMIt; 13500 13501 const Expr *VE = RE->IgnoreParenLValueCasts(); 13502 13503 if (VE->isValueDependent() || VE->isTypeDependent() || 13504 VE->isInstantiationDependent() || 13505 VE->containsUnexpandedParameterPack()) { 13506 // Try to find the associated user-defined mapper. 13507 ExprResult ER = buildUserDefinedMapperRef( 13508 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13509 VE->getType().getCanonicalType(), UnresolvedMapper); 13510 if (ER.isInvalid()) 13511 continue; 13512 MVLI.UDMapperList.push_back(ER.get()); 13513 // We can only analyze this information once the missing information is 13514 // resolved. 13515 MVLI.ProcessedVarList.push_back(RE); 13516 continue; 13517 } 13518 13519 Expr *SimpleExpr = RE->IgnoreParenCasts(); 13520 13521 if (!RE->IgnoreParenImpCasts()->isLValue()) { 13522 SemaRef.Diag(ELoc, 13523 diag::err_omp_expected_named_var_member_or_array_expression) 13524 << RE->getSourceRange(); 13525 continue; 13526 } 13527 13528 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 13529 ValueDecl *CurDeclaration = nullptr; 13530 13531 // Obtain the array or member expression bases if required. Also, fill the 13532 // components array with all the components identified in the process. 13533 const Expr *BE = checkMapClauseExpressionBase( 13534 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 13535 if (!BE) 13536 continue; 13537 13538 assert(!CurComponents.empty() && 13539 "Invalid mappable expression information."); 13540 13541 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 13542 // Add store "this" pointer to class in DSAStackTy for future checking 13543 DSAS->addMappedClassesQualTypes(TE->getType()); 13544 // Try to find the associated user-defined mapper. 13545 ExprResult ER = buildUserDefinedMapperRef( 13546 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13547 VE->getType().getCanonicalType(), UnresolvedMapper); 13548 if (ER.isInvalid()) 13549 continue; 13550 MVLI.UDMapperList.push_back(ER.get()); 13551 // Skip restriction checking for variable or field declarations 13552 MVLI.ProcessedVarList.push_back(RE); 13553 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13554 MVLI.VarComponents.back().append(CurComponents.begin(), 13555 CurComponents.end()); 13556 MVLI.VarBaseDeclarations.push_back(nullptr); 13557 continue; 13558 } 13559 13560 // For the following checks, we rely on the base declaration which is 13561 // expected to be associated with the last component. The declaration is 13562 // expected to be a variable or a field (if 'this' is being mapped). 13563 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 13564 assert(CurDeclaration && "Null decl on map clause."); 13565 assert( 13566 CurDeclaration->isCanonicalDecl() && 13567 "Expecting components to have associated only canonical declarations."); 13568 13569 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 13570 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 13571 13572 assert((VD || FD) && "Only variables or fields are expected here!"); 13573 (void)FD; 13574 13575 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 13576 // threadprivate variables cannot appear in a map clause. 13577 // OpenMP 4.5 [2.10.5, target update Construct] 13578 // threadprivate variables cannot appear in a from clause. 13579 if (VD && DSAS->isThreadPrivate(VD)) { 13580 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 13581 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 13582 << getOpenMPClauseName(CKind); 13583 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 13584 continue; 13585 } 13586 13587 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 13588 // A list item cannot appear in both a map clause and a data-sharing 13589 // attribute clause on the same construct. 13590 13591 // Check conflicts with other map clause expressions. We check the conflicts 13592 // with the current construct separately from the enclosing data 13593 // environment, because the restrictions are different. We only have to 13594 // check conflicts across regions for the map clauses. 13595 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 13596 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 13597 break; 13598 if (CKind == OMPC_map && 13599 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 13600 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 13601 break; 13602 13603 // OpenMP 4.5 [2.10.5, target update Construct] 13604 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13605 // If the type of a list item is a reference to a type T then the type will 13606 // be considered to be T for all purposes of this clause. 13607 auto I = llvm::find_if( 13608 CurComponents, 13609 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 13610 return MC.getAssociatedDeclaration(); 13611 }); 13612 assert(I != CurComponents.end() && "Null decl on map clause."); 13613 QualType Type = 13614 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 13615 13616 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 13617 // A list item in a to or from clause must have a mappable type. 13618 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 13619 // A list item must have a mappable type. 13620 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 13621 DSAS, Type)) 13622 continue; 13623 13624 if (CKind == OMPC_map) { 13625 // target enter data 13626 // OpenMP [2.10.2, Restrictions, p. 99] 13627 // A map-type must be specified in all map clauses and must be either 13628 // to or alloc. 13629 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 13630 if (DKind == OMPD_target_enter_data && 13631 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 13632 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 13633 << (IsMapTypeImplicit ? 1 : 0) 13634 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 13635 << getOpenMPDirectiveName(DKind); 13636 continue; 13637 } 13638 13639 // target exit_data 13640 // OpenMP [2.10.3, Restrictions, p. 102] 13641 // A map-type must be specified in all map clauses and must be either 13642 // from, release, or delete. 13643 if (DKind == OMPD_target_exit_data && 13644 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 13645 MapType == OMPC_MAP_delete)) { 13646 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 13647 << (IsMapTypeImplicit ? 1 : 0) 13648 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 13649 << getOpenMPDirectiveName(DKind); 13650 continue; 13651 } 13652 13653 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13654 // A list item cannot appear in both a map clause and a data-sharing 13655 // attribute clause on the same construct 13656 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 13657 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 13658 if (isOpenMPPrivate(DVar.CKind)) { 13659 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13660 << getOpenMPClauseName(DVar.CKind) 13661 << getOpenMPClauseName(OMPC_map) 13662 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 13663 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 13664 continue; 13665 } 13666 } 13667 } 13668 13669 // Try to find the associated user-defined mapper. 13670 ExprResult ER = buildUserDefinedMapperRef( 13671 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13672 Type.getCanonicalType(), UnresolvedMapper); 13673 if (ER.isInvalid()) 13674 continue; 13675 MVLI.UDMapperList.push_back(ER.get()); 13676 13677 // Save the current expression. 13678 MVLI.ProcessedVarList.push_back(RE); 13679 13680 // Store the components in the stack so that they can be used to check 13681 // against other clauses later on. 13682 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 13683 /*WhereFoundClauseKind=*/OMPC_map); 13684 13685 // Save the components and declaration to create the clause. For purposes of 13686 // the clause creation, any component list that has has base 'this' uses 13687 // null as base declaration. 13688 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13689 MVLI.VarComponents.back().append(CurComponents.begin(), 13690 CurComponents.end()); 13691 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 13692 : CurDeclaration); 13693 } 13694 } 13695 13696 OMPClause *Sema::ActOnOpenMPMapClause( 13697 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13698 ArrayRef<SourceLocation> MapTypeModifiersLoc, 13699 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 13700 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 13701 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 13702 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 13703 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 13704 OMPC_MAP_MODIFIER_unknown, 13705 OMPC_MAP_MODIFIER_unknown}; 13706 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 13707 13708 // Process map-type-modifiers, flag errors for duplicate modifiers. 13709 unsigned Count = 0; 13710 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 13711 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 13712 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 13713 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 13714 continue; 13715 } 13716 assert(Count < OMPMapClause::NumberOfModifiers && 13717 "Modifiers exceed the allowed number of map type modifiers"); 13718 Modifiers[Count] = MapTypeModifiers[I]; 13719 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 13720 ++Count; 13721 } 13722 13723 MappableVarListInfo MVLI(VarList); 13724 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 13725 MapperIdScopeSpec, MapperId, UnresolvedMappers, 13726 MapType, IsMapTypeImplicit); 13727 13728 // We need to produce a map clause even if we don't have variables so that 13729 // other diagnostics related with non-existing map clauses are accurate. 13730 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 13731 MVLI.VarBaseDeclarations, MVLI.VarComponents, 13732 MVLI.UDMapperList, Modifiers, ModifiersLoc, 13733 MapperIdScopeSpec.getWithLocInContext(Context), 13734 MapperId, MapType, IsMapTypeImplicit, MapLoc); 13735 } 13736 13737 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 13738 TypeResult ParsedType) { 13739 assert(ParsedType.isUsable()); 13740 13741 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 13742 if (ReductionType.isNull()) 13743 return QualType(); 13744 13745 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 13746 // A type name in a declare reduction directive cannot be a function type, an 13747 // array type, a reference type, or a type qualified with const, volatile or 13748 // restrict. 13749 if (ReductionType.hasQualifiers()) { 13750 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 13751 return QualType(); 13752 } 13753 13754 if (ReductionType->isFunctionType()) { 13755 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 13756 return QualType(); 13757 } 13758 if (ReductionType->isReferenceType()) { 13759 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 13760 return QualType(); 13761 } 13762 if (ReductionType->isArrayType()) { 13763 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 13764 return QualType(); 13765 } 13766 return ReductionType; 13767 } 13768 13769 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 13770 Scope *S, DeclContext *DC, DeclarationName Name, 13771 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 13772 AccessSpecifier AS, Decl *PrevDeclInScope) { 13773 SmallVector<Decl *, 8> Decls; 13774 Decls.reserve(ReductionTypes.size()); 13775 13776 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 13777 forRedeclarationInCurContext()); 13778 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 13779 // A reduction-identifier may not be re-declared in the current scope for the 13780 // same type or for a type that is compatible according to the base language 13781 // rules. 13782 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 13783 OMPDeclareReductionDecl *PrevDRD = nullptr; 13784 bool InCompoundScope = true; 13785 if (S != nullptr) { 13786 // Find previous declaration with the same name not referenced in other 13787 // declarations. 13788 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 13789 InCompoundScope = 13790 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 13791 LookupName(Lookup, S); 13792 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 13793 /*AllowInlineNamespace=*/false); 13794 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 13795 LookupResult::Filter Filter = Lookup.makeFilter(); 13796 while (Filter.hasNext()) { 13797 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 13798 if (InCompoundScope) { 13799 auto I = UsedAsPrevious.find(PrevDecl); 13800 if (I == UsedAsPrevious.end()) 13801 UsedAsPrevious[PrevDecl] = false; 13802 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 13803 UsedAsPrevious[D] = true; 13804 } 13805 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 13806 PrevDecl->getLocation(); 13807 } 13808 Filter.done(); 13809 if (InCompoundScope) { 13810 for (const auto &PrevData : UsedAsPrevious) { 13811 if (!PrevData.second) { 13812 PrevDRD = PrevData.first; 13813 break; 13814 } 13815 } 13816 } 13817 } else if (PrevDeclInScope != nullptr) { 13818 auto *PrevDRDInScope = PrevDRD = 13819 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 13820 do { 13821 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 13822 PrevDRDInScope->getLocation(); 13823 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 13824 } while (PrevDRDInScope != nullptr); 13825 } 13826 for (const auto &TyData : ReductionTypes) { 13827 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 13828 bool Invalid = false; 13829 if (I != PreviousRedeclTypes.end()) { 13830 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 13831 << TyData.first; 13832 Diag(I->second, diag::note_previous_definition); 13833 Invalid = true; 13834 } 13835 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 13836 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 13837 Name, TyData.first, PrevDRD); 13838 DC->addDecl(DRD); 13839 DRD->setAccess(AS); 13840 Decls.push_back(DRD); 13841 if (Invalid) 13842 DRD->setInvalidDecl(); 13843 else 13844 PrevDRD = DRD; 13845 } 13846 13847 return DeclGroupPtrTy::make( 13848 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 13849 } 13850 13851 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 13852 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13853 13854 // Enter new function scope. 13855 PushFunctionScope(); 13856 setFunctionHasBranchProtectedScope(); 13857 getCurFunction()->setHasOMPDeclareReductionCombiner(); 13858 13859 if (S != nullptr) 13860 PushDeclContext(S, DRD); 13861 else 13862 CurContext = DRD; 13863 13864 PushExpressionEvaluationContext( 13865 ExpressionEvaluationContext::PotentiallyEvaluated); 13866 13867 QualType ReductionType = DRD->getType(); 13868 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 13869 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 13870 // uses semantics of argument handles by value, but it should be passed by 13871 // reference. C lang does not support references, so pass all parameters as 13872 // pointers. 13873 // Create 'T omp_in;' variable. 13874 VarDecl *OmpInParm = 13875 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 13876 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 13877 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 13878 // uses semantics of argument handles by value, but it should be passed by 13879 // reference. C lang does not support references, so pass all parameters as 13880 // pointers. 13881 // Create 'T omp_out;' variable. 13882 VarDecl *OmpOutParm = 13883 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 13884 if (S != nullptr) { 13885 PushOnScopeChains(OmpInParm, S); 13886 PushOnScopeChains(OmpOutParm, S); 13887 } else { 13888 DRD->addDecl(OmpInParm); 13889 DRD->addDecl(OmpOutParm); 13890 } 13891 Expr *InE = 13892 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 13893 Expr *OutE = 13894 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 13895 DRD->setCombinerData(InE, OutE); 13896 } 13897 13898 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 13899 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13900 DiscardCleanupsInEvaluationContext(); 13901 PopExpressionEvaluationContext(); 13902 13903 PopDeclContext(); 13904 PopFunctionScopeInfo(); 13905 13906 if (Combiner != nullptr) 13907 DRD->setCombiner(Combiner); 13908 else 13909 DRD->setInvalidDecl(); 13910 } 13911 13912 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 13913 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13914 13915 // Enter new function scope. 13916 PushFunctionScope(); 13917 setFunctionHasBranchProtectedScope(); 13918 13919 if (S != nullptr) 13920 PushDeclContext(S, DRD); 13921 else 13922 CurContext = DRD; 13923 13924 PushExpressionEvaluationContext( 13925 ExpressionEvaluationContext::PotentiallyEvaluated); 13926 13927 QualType ReductionType = DRD->getType(); 13928 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 13929 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 13930 // uses semantics of argument handles by value, but it should be passed by 13931 // reference. C lang does not support references, so pass all parameters as 13932 // pointers. 13933 // Create 'T omp_priv;' variable. 13934 VarDecl *OmpPrivParm = 13935 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 13936 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 13937 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 13938 // uses semantics of argument handles by value, but it should be passed by 13939 // reference. C lang does not support references, so pass all parameters as 13940 // pointers. 13941 // Create 'T omp_orig;' variable. 13942 VarDecl *OmpOrigParm = 13943 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 13944 if (S != nullptr) { 13945 PushOnScopeChains(OmpPrivParm, S); 13946 PushOnScopeChains(OmpOrigParm, S); 13947 } else { 13948 DRD->addDecl(OmpPrivParm); 13949 DRD->addDecl(OmpOrigParm); 13950 } 13951 Expr *OrigE = 13952 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 13953 Expr *PrivE = 13954 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 13955 DRD->setInitializerData(OrigE, PrivE); 13956 return OmpPrivParm; 13957 } 13958 13959 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 13960 VarDecl *OmpPrivParm) { 13961 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13962 DiscardCleanupsInEvaluationContext(); 13963 PopExpressionEvaluationContext(); 13964 13965 PopDeclContext(); 13966 PopFunctionScopeInfo(); 13967 13968 if (Initializer != nullptr) { 13969 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 13970 } else if (OmpPrivParm->hasInit()) { 13971 DRD->setInitializer(OmpPrivParm->getInit(), 13972 OmpPrivParm->isDirectInit() 13973 ? OMPDeclareReductionDecl::DirectInit 13974 : OMPDeclareReductionDecl::CopyInit); 13975 } else { 13976 DRD->setInvalidDecl(); 13977 } 13978 } 13979 13980 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 13981 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 13982 for (Decl *D : DeclReductions.get()) { 13983 if (IsValid) { 13984 if (S) 13985 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 13986 /*AddToContext=*/false); 13987 } else { 13988 D->setInvalidDecl(); 13989 } 13990 } 13991 return DeclReductions; 13992 } 13993 13994 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 13995 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 13996 QualType T = TInfo->getType(); 13997 if (D.isInvalidType()) 13998 return true; 13999 14000 if (getLangOpts().CPlusPlus) { 14001 // Check that there are no default arguments (C++ only). 14002 CheckExtraCXXDefaultArguments(D); 14003 } 14004 14005 return CreateParsedType(T, TInfo); 14006 } 14007 14008 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 14009 TypeResult ParsedType) { 14010 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 14011 14012 QualType MapperType = GetTypeFromParser(ParsedType.get()); 14013 assert(!MapperType.isNull() && "Expect valid mapper type"); 14014 14015 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14016 // The type must be of struct, union or class type in C and C++ 14017 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 14018 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 14019 return QualType(); 14020 } 14021 return MapperType; 14022 } 14023 14024 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 14025 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 14026 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 14027 Decl *PrevDeclInScope) { 14028 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 14029 forRedeclarationInCurContext()); 14030 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14031 // A mapper-identifier may not be redeclared in the current scope for the 14032 // same type or for a type that is compatible according to the base language 14033 // rules. 14034 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14035 OMPDeclareMapperDecl *PrevDMD = nullptr; 14036 bool InCompoundScope = true; 14037 if (S != nullptr) { 14038 // Find previous declaration with the same name not referenced in other 14039 // declarations. 14040 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14041 InCompoundScope = 14042 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14043 LookupName(Lookup, S); 14044 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14045 /*AllowInlineNamespace=*/false); 14046 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 14047 LookupResult::Filter Filter = Lookup.makeFilter(); 14048 while (Filter.hasNext()) { 14049 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 14050 if (InCompoundScope) { 14051 auto I = UsedAsPrevious.find(PrevDecl); 14052 if (I == UsedAsPrevious.end()) 14053 UsedAsPrevious[PrevDecl] = false; 14054 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 14055 UsedAsPrevious[D] = true; 14056 } 14057 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14058 PrevDecl->getLocation(); 14059 } 14060 Filter.done(); 14061 if (InCompoundScope) { 14062 for (const auto &PrevData : UsedAsPrevious) { 14063 if (!PrevData.second) { 14064 PrevDMD = PrevData.first; 14065 break; 14066 } 14067 } 14068 } 14069 } else if (PrevDeclInScope) { 14070 auto *PrevDMDInScope = PrevDMD = 14071 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 14072 do { 14073 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 14074 PrevDMDInScope->getLocation(); 14075 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 14076 } while (PrevDMDInScope != nullptr); 14077 } 14078 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 14079 bool Invalid = false; 14080 if (I != PreviousRedeclTypes.end()) { 14081 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 14082 << MapperType << Name; 14083 Diag(I->second, diag::note_previous_definition); 14084 Invalid = true; 14085 } 14086 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 14087 MapperType, VN, PrevDMD); 14088 DC->addDecl(DMD); 14089 DMD->setAccess(AS); 14090 if (Invalid) 14091 DMD->setInvalidDecl(); 14092 14093 // Enter new function scope. 14094 PushFunctionScope(); 14095 setFunctionHasBranchProtectedScope(); 14096 14097 CurContext = DMD; 14098 14099 return DMD; 14100 } 14101 14102 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 14103 Scope *S, 14104 QualType MapperType, 14105 SourceLocation StartLoc, 14106 DeclarationName VN) { 14107 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 14108 if (S) 14109 PushOnScopeChains(VD, S); 14110 else 14111 DMD->addDecl(VD); 14112 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 14113 DMD->setMapperVarRef(MapperVarRefExpr); 14114 } 14115 14116 Sema::DeclGroupPtrTy 14117 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 14118 ArrayRef<OMPClause *> ClauseList) { 14119 PopDeclContext(); 14120 PopFunctionScopeInfo(); 14121 14122 if (D) { 14123 if (S) 14124 PushOnScopeChains(D, S, /*AddToContext=*/false); 14125 D->CreateClauses(Context, ClauseList); 14126 } 14127 14128 return DeclGroupPtrTy::make(DeclGroupRef(D)); 14129 } 14130 14131 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 14132 SourceLocation StartLoc, 14133 SourceLocation LParenLoc, 14134 SourceLocation EndLoc) { 14135 Expr *ValExpr = NumTeams; 14136 Stmt *HelperValStmt = nullptr; 14137 14138 // OpenMP [teams Constrcut, Restrictions] 14139 // The num_teams expression must evaluate to a positive integer value. 14140 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 14141 /*StrictlyPositive=*/true)) 14142 return nullptr; 14143 14144 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14145 OpenMPDirectiveKind CaptureRegion = 14146 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 14147 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14148 ValExpr = MakeFullExpr(ValExpr).get(); 14149 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14150 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14151 HelperValStmt = buildPreInits(Context, Captures); 14152 } 14153 14154 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 14155 StartLoc, LParenLoc, EndLoc); 14156 } 14157 14158 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 14159 SourceLocation StartLoc, 14160 SourceLocation LParenLoc, 14161 SourceLocation EndLoc) { 14162 Expr *ValExpr = ThreadLimit; 14163 Stmt *HelperValStmt = nullptr; 14164 14165 // OpenMP [teams Constrcut, Restrictions] 14166 // The thread_limit expression must evaluate to a positive integer value. 14167 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 14168 /*StrictlyPositive=*/true)) 14169 return nullptr; 14170 14171 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14172 OpenMPDirectiveKind CaptureRegion = 14173 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 14174 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14175 ValExpr = MakeFullExpr(ValExpr).get(); 14176 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14177 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14178 HelperValStmt = buildPreInits(Context, Captures); 14179 } 14180 14181 return new (Context) OMPThreadLimitClause( 14182 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 14183 } 14184 14185 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 14186 SourceLocation StartLoc, 14187 SourceLocation LParenLoc, 14188 SourceLocation EndLoc) { 14189 Expr *ValExpr = Priority; 14190 14191 // OpenMP [2.9.1, task Constrcut] 14192 // The priority-value is a non-negative numerical scalar expression. 14193 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 14194 /*StrictlyPositive=*/false)) 14195 return nullptr; 14196 14197 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14198 } 14199 14200 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 14201 SourceLocation StartLoc, 14202 SourceLocation LParenLoc, 14203 SourceLocation EndLoc) { 14204 Expr *ValExpr = Grainsize; 14205 14206 // OpenMP [2.9.2, taskloop Constrcut] 14207 // The parameter of the grainsize clause must be a positive integer 14208 // expression. 14209 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 14210 /*StrictlyPositive=*/true)) 14211 return nullptr; 14212 14213 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14214 } 14215 14216 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 14217 SourceLocation StartLoc, 14218 SourceLocation LParenLoc, 14219 SourceLocation EndLoc) { 14220 Expr *ValExpr = NumTasks; 14221 14222 // OpenMP [2.9.2, taskloop Constrcut] 14223 // The parameter of the num_tasks clause must be a positive integer 14224 // expression. 14225 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 14226 /*StrictlyPositive=*/true)) 14227 return nullptr; 14228 14229 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14230 } 14231 14232 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 14233 SourceLocation LParenLoc, 14234 SourceLocation EndLoc) { 14235 // OpenMP [2.13.2, critical construct, Description] 14236 // ... where hint-expression is an integer constant expression that evaluates 14237 // to a valid lock hint. 14238 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 14239 if (HintExpr.isInvalid()) 14240 return nullptr; 14241 return new (Context) 14242 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 14243 } 14244 14245 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 14246 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 14247 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 14248 SourceLocation EndLoc) { 14249 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 14250 std::string Values; 14251 Values += "'"; 14252 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 14253 Values += "'"; 14254 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 14255 << Values << getOpenMPClauseName(OMPC_dist_schedule); 14256 return nullptr; 14257 } 14258 Expr *ValExpr = ChunkSize; 14259 Stmt *HelperValStmt = nullptr; 14260 if (ChunkSize) { 14261 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 14262 !ChunkSize->isInstantiationDependent() && 14263 !ChunkSize->containsUnexpandedParameterPack()) { 14264 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 14265 ExprResult Val = 14266 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 14267 if (Val.isInvalid()) 14268 return nullptr; 14269 14270 ValExpr = Val.get(); 14271 14272 // OpenMP [2.7.1, Restrictions] 14273 // chunk_size must be a loop invariant integer expression with a positive 14274 // value. 14275 llvm::APSInt Result; 14276 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 14277 if (Result.isSigned() && !Result.isStrictlyPositive()) { 14278 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 14279 << "dist_schedule" << ChunkSize->getSourceRange(); 14280 return nullptr; 14281 } 14282 } else if (getOpenMPCaptureRegionForClause( 14283 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 14284 OMPD_unknown && 14285 !CurContext->isDependentContext()) { 14286 ValExpr = MakeFullExpr(ValExpr).get(); 14287 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14288 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14289 HelperValStmt = buildPreInits(Context, Captures); 14290 } 14291 } 14292 } 14293 14294 return new (Context) 14295 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 14296 Kind, ValExpr, HelperValStmt); 14297 } 14298 14299 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 14300 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 14301 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 14302 SourceLocation KindLoc, SourceLocation EndLoc) { 14303 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 14304 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 14305 std::string Value; 14306 SourceLocation Loc; 14307 Value += "'"; 14308 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 14309 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14310 OMPC_DEFAULTMAP_MODIFIER_tofrom); 14311 Loc = MLoc; 14312 } else { 14313 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14314 OMPC_DEFAULTMAP_scalar); 14315 Loc = KindLoc; 14316 } 14317 Value += "'"; 14318 Diag(Loc, diag::err_omp_unexpected_clause_value) 14319 << Value << getOpenMPClauseName(OMPC_defaultmap); 14320 return nullptr; 14321 } 14322 DSAStack->setDefaultDMAToFromScalar(StartLoc); 14323 14324 return new (Context) 14325 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 14326 } 14327 14328 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 14329 DeclContext *CurLexicalContext = getCurLexicalContext(); 14330 if (!CurLexicalContext->isFileContext() && 14331 !CurLexicalContext->isExternCContext() && 14332 !CurLexicalContext->isExternCXXContext() && 14333 !isa<CXXRecordDecl>(CurLexicalContext) && 14334 !isa<ClassTemplateDecl>(CurLexicalContext) && 14335 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 14336 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 14337 Diag(Loc, diag::err_omp_region_not_file_context); 14338 return false; 14339 } 14340 ++DeclareTargetNestingLevel; 14341 return true; 14342 } 14343 14344 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 14345 assert(DeclareTargetNestingLevel > 0 && 14346 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 14347 --DeclareTargetNestingLevel; 14348 } 14349 14350 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 14351 CXXScopeSpec &ScopeSpec, 14352 const DeclarationNameInfo &Id, 14353 OMPDeclareTargetDeclAttr::MapTypeTy MT, 14354 NamedDeclSetType &SameDirectiveDecls) { 14355 LookupResult Lookup(*this, Id, LookupOrdinaryName); 14356 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 14357 14358 if (Lookup.isAmbiguous()) 14359 return; 14360 Lookup.suppressDiagnostics(); 14361 14362 if (!Lookup.isSingleResult()) { 14363 if (TypoCorrection Corrected = 14364 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, 14365 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), 14366 CTK_ErrorRecovery)) { 14367 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 14368 << Id.getName()); 14369 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 14370 return; 14371 } 14372 14373 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 14374 return; 14375 } 14376 14377 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 14378 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 14379 isa<FunctionTemplateDecl>(ND)) { 14380 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 14381 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 14382 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14383 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 14384 cast<ValueDecl>(ND)); 14385 if (!Res) { 14386 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 14387 ND->addAttr(A); 14388 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14389 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 14390 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 14391 } else if (*Res != MT) { 14392 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 14393 << Id.getName(); 14394 } 14395 } else { 14396 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 14397 } 14398 } 14399 14400 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 14401 Sema &SemaRef, Decl *D) { 14402 if (!D || !isa<VarDecl>(D)) 14403 return; 14404 auto *VD = cast<VarDecl>(D); 14405 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 14406 return; 14407 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 14408 SemaRef.Diag(SL, diag::note_used_here) << SR; 14409 } 14410 14411 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 14412 Sema &SemaRef, DSAStackTy *Stack, 14413 ValueDecl *VD) { 14414 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 14415 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 14416 /*FullCheck=*/false); 14417 } 14418 14419 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 14420 SourceLocation IdLoc) { 14421 if (!D || D->isInvalidDecl()) 14422 return; 14423 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 14424 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 14425 if (auto *VD = dyn_cast<VarDecl>(D)) { 14426 // Only global variables can be marked as declare target. 14427 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 14428 !VD->isStaticDataMember()) 14429 return; 14430 // 2.10.6: threadprivate variable cannot appear in a declare target 14431 // directive. 14432 if (DSAStack->isThreadPrivate(VD)) { 14433 Diag(SL, diag::err_omp_threadprivate_in_target); 14434 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 14435 return; 14436 } 14437 } 14438 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 14439 D = FTD->getTemplatedDecl(); 14440 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 14441 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14442 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 14443 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 14444 assert(IdLoc.isValid() && "Source location is expected"); 14445 Diag(IdLoc, diag::err_omp_function_in_link_clause); 14446 Diag(FD->getLocation(), diag::note_defined_here) << FD; 14447 return; 14448 } 14449 } 14450 if (auto *VD = dyn_cast<ValueDecl>(D)) { 14451 // Problem if any with var declared with incomplete type will be reported 14452 // as normal, so no need to check it here. 14453 if ((E || !VD->getType()->isIncompleteType()) && 14454 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 14455 return; 14456 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 14457 // Checking declaration inside declare target region. 14458 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 14459 isa<FunctionTemplateDecl>(D)) { 14460 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 14461 Context, OMPDeclareTargetDeclAttr::MT_To); 14462 D->addAttr(A); 14463 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14464 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 14465 } 14466 return; 14467 } 14468 } 14469 if (!E) 14470 return; 14471 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 14472 } 14473 14474 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 14475 CXXScopeSpec &MapperIdScopeSpec, 14476 DeclarationNameInfo &MapperId, 14477 const OMPVarListLocTy &Locs, 14478 ArrayRef<Expr *> UnresolvedMappers) { 14479 MappableVarListInfo MVLI(VarList); 14480 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 14481 MapperIdScopeSpec, MapperId, UnresolvedMappers); 14482 if (MVLI.ProcessedVarList.empty()) 14483 return nullptr; 14484 14485 return OMPToClause::Create( 14486 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 14487 MVLI.VarComponents, MVLI.UDMapperList, 14488 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 14489 } 14490 14491 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 14492 CXXScopeSpec &MapperIdScopeSpec, 14493 DeclarationNameInfo &MapperId, 14494 const OMPVarListLocTy &Locs, 14495 ArrayRef<Expr *> UnresolvedMappers) { 14496 MappableVarListInfo MVLI(VarList); 14497 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 14498 MapperIdScopeSpec, MapperId, UnresolvedMappers); 14499 if (MVLI.ProcessedVarList.empty()) 14500 return nullptr; 14501 14502 return OMPFromClause::Create( 14503 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 14504 MVLI.VarComponents, MVLI.UDMapperList, 14505 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 14506 } 14507 14508 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 14509 const OMPVarListLocTy &Locs) { 14510 MappableVarListInfo MVLI(VarList); 14511 SmallVector<Expr *, 8> PrivateCopies; 14512 SmallVector<Expr *, 8> Inits; 14513 14514 for (Expr *RefExpr : VarList) { 14515 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 14516 SourceLocation ELoc; 14517 SourceRange ERange; 14518 Expr *SimpleRefExpr = RefExpr; 14519 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14520 if (Res.second) { 14521 // It will be analyzed later. 14522 MVLI.ProcessedVarList.push_back(RefExpr); 14523 PrivateCopies.push_back(nullptr); 14524 Inits.push_back(nullptr); 14525 } 14526 ValueDecl *D = Res.first; 14527 if (!D) 14528 continue; 14529 14530 QualType Type = D->getType(); 14531 Type = Type.getNonReferenceType().getUnqualifiedType(); 14532 14533 auto *VD = dyn_cast<VarDecl>(D); 14534 14535 // Item should be a pointer or reference to pointer. 14536 if (!Type->isPointerType()) { 14537 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 14538 << 0 << RefExpr->getSourceRange(); 14539 continue; 14540 } 14541 14542 // Build the private variable and the expression that refers to it. 14543 auto VDPrivate = 14544 buildVarDecl(*this, ELoc, Type, D->getName(), 14545 D->hasAttrs() ? &D->getAttrs() : nullptr, 14546 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14547 if (VDPrivate->isInvalidDecl()) 14548 continue; 14549 14550 CurContext->addDecl(VDPrivate); 14551 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 14552 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 14553 14554 // Add temporary variable to initialize the private copy of the pointer. 14555 VarDecl *VDInit = 14556 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 14557 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 14558 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 14559 AddInitializerToDecl(VDPrivate, 14560 DefaultLvalueConversion(VDInitRefExpr).get(), 14561 /*DirectInit=*/false); 14562 14563 // If required, build a capture to implement the privatization initialized 14564 // with the current list item value. 14565 DeclRefExpr *Ref = nullptr; 14566 if (!VD) 14567 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14568 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 14569 PrivateCopies.push_back(VDPrivateRefExpr); 14570 Inits.push_back(VDInitRefExpr); 14571 14572 // We need to add a data sharing attribute for this variable to make sure it 14573 // is correctly captured. A variable that shows up in a use_device_ptr has 14574 // similar properties of a first private variable. 14575 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 14576 14577 // Create a mappable component for the list item. List items in this clause 14578 // only need a component. 14579 MVLI.VarBaseDeclarations.push_back(D); 14580 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14581 MVLI.VarComponents.back().push_back( 14582 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 14583 } 14584 14585 if (MVLI.ProcessedVarList.empty()) 14586 return nullptr; 14587 14588 return OMPUseDevicePtrClause::Create( 14589 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 14590 MVLI.VarBaseDeclarations, MVLI.VarComponents); 14591 } 14592 14593 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 14594 const OMPVarListLocTy &Locs) { 14595 MappableVarListInfo MVLI(VarList); 14596 for (Expr *RefExpr : VarList) { 14597 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 14598 SourceLocation ELoc; 14599 SourceRange ERange; 14600 Expr *SimpleRefExpr = RefExpr; 14601 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14602 if (Res.second) { 14603 // It will be analyzed later. 14604 MVLI.ProcessedVarList.push_back(RefExpr); 14605 } 14606 ValueDecl *D = Res.first; 14607 if (!D) 14608 continue; 14609 14610 QualType Type = D->getType(); 14611 // item should be a pointer or array or reference to pointer or array 14612 if (!Type.getNonReferenceType()->isPointerType() && 14613 !Type.getNonReferenceType()->isArrayType()) { 14614 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 14615 << 0 << RefExpr->getSourceRange(); 14616 continue; 14617 } 14618 14619 // Check if the declaration in the clause does not show up in any data 14620 // sharing attribute. 14621 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14622 if (isOpenMPPrivate(DVar.CKind)) { 14623 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14624 << getOpenMPClauseName(DVar.CKind) 14625 << getOpenMPClauseName(OMPC_is_device_ptr) 14626 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14627 reportOriginalDsa(*this, DSAStack, D, DVar); 14628 continue; 14629 } 14630 14631 const Expr *ConflictExpr; 14632 if (DSAStack->checkMappableExprComponentListsForDecl( 14633 D, /*CurrentRegionOnly=*/true, 14634 [&ConflictExpr]( 14635 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 14636 OpenMPClauseKind) -> bool { 14637 ConflictExpr = R.front().getAssociatedExpression(); 14638 return true; 14639 })) { 14640 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 14641 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 14642 << ConflictExpr->getSourceRange(); 14643 continue; 14644 } 14645 14646 // Store the components in the stack so that they can be used to check 14647 // against other clauses later on. 14648 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 14649 DSAStack->addMappableExpressionComponents( 14650 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 14651 14652 // Record the expression we've just processed. 14653 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 14654 14655 // Create a mappable component for the list item. List items in this clause 14656 // only need a component. We use a null declaration to signal fields in 14657 // 'this'. 14658 assert((isa<DeclRefExpr>(SimpleRefExpr) || 14659 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 14660 "Unexpected device pointer expression!"); 14661 MVLI.VarBaseDeclarations.push_back( 14662 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 14663 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14664 MVLI.VarComponents.back().push_back(MC); 14665 } 14666 14667 if (MVLI.ProcessedVarList.empty()) 14668 return nullptr; 14669 14670 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 14671 MVLI.VarBaseDeclarations, 14672 MVLI.VarComponents); 14673 } 14674