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 if the defined 'requires' directive has specified type of clause. 426 template <typename ClauseType> 427 bool hasRequiresDeclWithClause() { 428 return llvm::any_of(RequiresDecls, [](const OMPRequiresDecl *D) { 429 return llvm::any_of(D->clauselists(), [](const OMPClause *C) { 430 return isa<ClauseType>(C); 431 }); 432 }); 433 } 434 435 /// Checks for a duplicate clause amongst previously declared requires 436 /// directives 437 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 438 bool IsDuplicate = false; 439 for (OMPClause *CNew : ClauseList) { 440 for (const OMPRequiresDecl *D : RequiresDecls) { 441 for (const OMPClause *CPrev : D->clauselists()) { 442 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 443 SemaRef.Diag(CNew->getBeginLoc(), 444 diag::err_omp_requires_clause_redeclaration) 445 << getOpenMPClauseName(CNew->getClauseKind()); 446 SemaRef.Diag(CPrev->getBeginLoc(), 447 diag::note_omp_requires_previous_clause) 448 << getOpenMPClauseName(CPrev->getClauseKind()); 449 IsDuplicate = true; 450 } 451 } 452 } 453 } 454 return IsDuplicate; 455 } 456 457 /// Set default data sharing attribute to none. 458 void setDefaultDSANone(SourceLocation Loc) { 459 assert(!isStackEmpty()); 460 Stack.back().first.back().DefaultAttr = DSA_none; 461 Stack.back().first.back().DefaultAttrLoc = Loc; 462 } 463 /// Set default data sharing attribute to shared. 464 void setDefaultDSAShared(SourceLocation Loc) { 465 assert(!isStackEmpty()); 466 Stack.back().first.back().DefaultAttr = DSA_shared; 467 Stack.back().first.back().DefaultAttrLoc = Loc; 468 } 469 /// Set default data mapping attribute to 'tofrom:scalar'. 470 void setDefaultDMAToFromScalar(SourceLocation Loc) { 471 assert(!isStackEmpty()); 472 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar; 473 Stack.back().first.back().DefaultMapAttrLoc = Loc; 474 } 475 476 DefaultDataSharingAttributes getDefaultDSA() const { 477 return isStackEmpty() ? DSA_unspecified 478 : Stack.back().first.back().DefaultAttr; 479 } 480 SourceLocation getDefaultDSALocation() const { 481 return isStackEmpty() ? SourceLocation() 482 : Stack.back().first.back().DefaultAttrLoc; 483 } 484 DefaultMapAttributes getDefaultDMA() const { 485 return isStackEmpty() ? DMA_unspecified 486 : Stack.back().first.back().DefaultMapAttr; 487 } 488 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 489 return Stack.back().first[Level].DefaultMapAttr; 490 } 491 SourceLocation getDefaultDMALocation() const { 492 return isStackEmpty() ? SourceLocation() 493 : Stack.back().first.back().DefaultMapAttrLoc; 494 } 495 496 /// Checks if the specified variable is a threadprivate. 497 bool isThreadPrivate(VarDecl *D) { 498 const DSAVarData DVar = getTopDSA(D, false); 499 return isOpenMPThreadPrivate(DVar.CKind); 500 } 501 502 /// Marks current region as ordered (it has an 'ordered' clause). 503 void setOrderedRegion(bool IsOrdered, const Expr *Param, 504 OMPOrderedClause *Clause) { 505 assert(!isStackEmpty()); 506 if (IsOrdered) 507 Stack.back().first.back().OrderedRegion.emplace(Param, Clause); 508 else 509 Stack.back().first.back().OrderedRegion.reset(); 510 } 511 /// Returns true, if region is ordered (has associated 'ordered' clause), 512 /// false - otherwise. 513 bool isOrderedRegion() const { 514 if (isStackEmpty()) 515 return false; 516 return Stack.back().first.rbegin()->OrderedRegion.hasValue(); 517 } 518 /// Returns optional parameter for the ordered region. 519 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 520 if (isStackEmpty() || 521 !Stack.back().first.rbegin()->OrderedRegion.hasValue()) 522 return std::make_pair(nullptr, nullptr); 523 return Stack.back().first.rbegin()->OrderedRegion.getValue(); 524 } 525 /// Returns true, if parent region is ordered (has associated 526 /// 'ordered' clause), false - otherwise. 527 bool isParentOrderedRegion() const { 528 if (isStackEmpty() || Stack.back().first.size() == 1) 529 return false; 530 return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue(); 531 } 532 /// Returns optional parameter for the ordered region. 533 std::pair<const Expr *, OMPOrderedClause *> 534 getParentOrderedRegionParam() const { 535 if (isStackEmpty() || Stack.back().first.size() == 1 || 536 !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue()) 537 return std::make_pair(nullptr, nullptr); 538 return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue(); 539 } 540 /// Marks current region as nowait (it has a 'nowait' clause). 541 void setNowaitRegion(bool IsNowait = true) { 542 assert(!isStackEmpty()); 543 Stack.back().first.back().NowaitRegion = IsNowait; 544 } 545 /// Returns true, if parent region is nowait (has associated 546 /// 'nowait' clause), false - otherwise. 547 bool isParentNowaitRegion() const { 548 if (isStackEmpty() || Stack.back().first.size() == 1) 549 return false; 550 return std::next(Stack.back().first.rbegin())->NowaitRegion; 551 } 552 /// Marks parent region as cancel region. 553 void setParentCancelRegion(bool Cancel = true) { 554 if (!isStackEmpty() && Stack.back().first.size() > 1) { 555 auto &StackElemRef = *std::next(Stack.back().first.rbegin()); 556 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel; 557 } 558 } 559 /// Return true if current region has inner cancel construct. 560 bool isCancelRegion() const { 561 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion; 562 } 563 564 /// Set collapse value for the region. 565 void setAssociatedLoops(unsigned Val) { 566 assert(!isStackEmpty()); 567 Stack.back().first.back().AssociatedLoops = Val; 568 } 569 /// Return collapse value for region. 570 unsigned getAssociatedLoops() const { 571 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops; 572 } 573 574 /// Marks current target region as one with closely nested teams 575 /// region. 576 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 577 if (!isStackEmpty() && Stack.back().first.size() > 1) { 578 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc = 579 TeamsRegionLoc; 580 } 581 } 582 /// Returns true, if current region has closely nested teams region. 583 bool hasInnerTeamsRegion() const { 584 return getInnerTeamsRegionLoc().isValid(); 585 } 586 /// Returns location of the nested teams region (if any). 587 SourceLocation getInnerTeamsRegionLoc() const { 588 return isStackEmpty() ? SourceLocation() 589 : Stack.back().first.back().InnerTeamsRegionLoc; 590 } 591 592 Scope *getCurScope() const { 593 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 594 } 595 SourceLocation getConstructLoc() const { 596 return isStackEmpty() ? SourceLocation() 597 : Stack.back().first.back().ConstructLoc; 598 } 599 600 /// Do the check specified in \a Check to all component lists and return true 601 /// if any issue is found. 602 bool checkMappableExprComponentListsForDecl( 603 const ValueDecl *VD, bool CurrentRegionOnly, 604 const llvm::function_ref< 605 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 606 OpenMPClauseKind)> 607 Check) const { 608 if (isStackEmpty()) 609 return false; 610 auto SI = Stack.back().first.rbegin(); 611 auto SE = Stack.back().first.rend(); 612 613 if (SI == SE) 614 return false; 615 616 if (CurrentRegionOnly) 617 SE = std::next(SI); 618 else 619 std::advance(SI, 1); 620 621 for (; SI != SE; ++SI) { 622 auto MI = SI->MappedExprComponents.find(VD); 623 if (MI != SI->MappedExprComponents.end()) 624 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 625 MI->second.Components) 626 if (Check(L, MI->second.Kind)) 627 return true; 628 } 629 return false; 630 } 631 632 /// Do the check specified in \a Check to all component lists at a given level 633 /// and return true if any issue is found. 634 bool checkMappableExprComponentListsForDeclAtLevel( 635 const ValueDecl *VD, unsigned Level, 636 const llvm::function_ref< 637 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 638 OpenMPClauseKind)> 639 Check) const { 640 if (isStackEmpty()) 641 return false; 642 643 auto StartI = Stack.back().first.begin(); 644 auto EndI = Stack.back().first.end(); 645 if (std::distance(StartI, EndI) <= (int)Level) 646 return false; 647 std::advance(StartI, Level); 648 649 auto MI = StartI->MappedExprComponents.find(VD); 650 if (MI != StartI->MappedExprComponents.end()) 651 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 652 MI->second.Components) 653 if (Check(L, MI->second.Kind)) 654 return true; 655 return false; 656 } 657 658 /// Create a new mappable expression component list associated with a given 659 /// declaration and initialize it with the provided list of components. 660 void addMappableExpressionComponents( 661 const ValueDecl *VD, 662 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 663 OpenMPClauseKind WhereFoundClauseKind) { 664 assert(!isStackEmpty() && 665 "Not expecting to retrieve components from a empty stack!"); 666 MappedExprComponentTy &MEC = 667 Stack.back().first.back().MappedExprComponents[VD]; 668 // Create new entry and append the new components there. 669 MEC.Components.resize(MEC.Components.size() + 1); 670 MEC.Components.back().append(Components.begin(), Components.end()); 671 MEC.Kind = WhereFoundClauseKind; 672 } 673 674 unsigned getNestingLevel() const { 675 assert(!isStackEmpty()); 676 return Stack.back().first.size() - 1; 677 } 678 void addDoacrossDependClause(OMPDependClause *C, 679 const OperatorOffsetTy &OpsOffs) { 680 assert(!isStackEmpty() && Stack.back().first.size() > 1); 681 SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 682 assert(isOpenMPWorksharingDirective(StackElem.Directive)); 683 StackElem.DoacrossDepends.try_emplace(C, OpsOffs); 684 } 685 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 686 getDoacrossDependClauses() const { 687 assert(!isStackEmpty()); 688 const SharingMapTy &StackElem = Stack.back().first.back(); 689 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 690 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 691 return llvm::make_range(Ref.begin(), Ref.end()); 692 } 693 return llvm::make_range(StackElem.DoacrossDepends.end(), 694 StackElem.DoacrossDepends.end()); 695 } 696 697 // Store types of classes which have been explicitly mapped 698 void addMappedClassesQualTypes(QualType QT) { 699 SharingMapTy &StackElem = Stack.back().first.back(); 700 StackElem.MappedClassesQualTypes.insert(QT); 701 } 702 703 // Return set of mapped classes types 704 bool isClassPreviouslyMapped(QualType QT) const { 705 const SharingMapTy &StackElem = Stack.back().first.back(); 706 return StackElem.MappedClassesQualTypes.count(QT) != 0; 707 } 708 709 /// Adds global declare target to the parent target region. 710 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 711 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 712 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 713 "Expected declare target link global."); 714 if (isStackEmpty()) 715 return; 716 auto It = Stack.back().first.rbegin(); 717 while (It != Stack.back().first.rend() && 718 !isOpenMPTargetExecutionDirective(It->Directive)) 719 ++It; 720 if (It != Stack.back().first.rend()) { 721 assert(isOpenMPTargetExecutionDirective(It->Directive) && 722 "Expected target executable directive."); 723 It->DeclareTargetLinkVarDecls.push_back(E); 724 } 725 } 726 727 /// Returns the list of globals with declare target link if current directive 728 /// is target. 729 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 730 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 731 "Expected target executable directive."); 732 return Stack.back().first.back().DeclareTargetLinkVarDecls; 733 } 734 }; 735 736 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 737 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 738 } 739 740 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 741 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || DKind == OMPD_unknown; 742 } 743 744 } // namespace 745 746 static const Expr *getExprAsWritten(const Expr *E) { 747 if (const auto *FE = dyn_cast<FullExpr>(E)) 748 E = FE->getSubExpr(); 749 750 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 751 E = MTE->GetTemporaryExpr(); 752 753 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 754 E = Binder->getSubExpr(); 755 756 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 757 E = ICE->getSubExprAsWritten(); 758 return E->IgnoreParens(); 759 } 760 761 static Expr *getExprAsWritten(Expr *E) { 762 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 763 } 764 765 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 766 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 767 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 768 D = ME->getMemberDecl(); 769 const auto *VD = dyn_cast<VarDecl>(D); 770 const auto *FD = dyn_cast<FieldDecl>(D); 771 if (VD != nullptr) { 772 VD = VD->getCanonicalDecl(); 773 D = VD; 774 } else { 775 assert(FD); 776 FD = FD->getCanonicalDecl(); 777 D = FD; 778 } 779 return D; 780 } 781 782 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 783 return const_cast<ValueDecl *>( 784 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 785 } 786 787 DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter, 788 ValueDecl *D) const { 789 D = getCanonicalDecl(D); 790 auto *VD = dyn_cast<VarDecl>(D); 791 const auto *FD = dyn_cast<FieldDecl>(D); 792 DSAVarData DVar; 793 if (isStackEmpty() || Iter == Stack.back().first.rend()) { 794 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 795 // in a region but not in construct] 796 // File-scope or namespace-scope variables referenced in called routines 797 // in the region are shared unless they appear in a threadprivate 798 // directive. 799 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 800 DVar.CKind = OMPC_shared; 801 802 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 803 // in a region but not in construct] 804 // Variables with static storage duration that are declared in called 805 // routines in the region are shared. 806 if (VD && VD->hasGlobalStorage()) 807 DVar.CKind = OMPC_shared; 808 809 // Non-static data members are shared by default. 810 if (FD) 811 DVar.CKind = OMPC_shared; 812 813 return DVar; 814 } 815 816 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 817 // in a Construct, C/C++, predetermined, p.1] 818 // Variables with automatic storage duration that are declared in a scope 819 // inside the construct are private. 820 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 821 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 822 DVar.CKind = OMPC_private; 823 return DVar; 824 } 825 826 DVar.DKind = Iter->Directive; 827 // Explicitly specified attributes and local variables with predetermined 828 // attributes. 829 if (Iter->SharingMap.count(D)) { 830 const DSAInfo &Data = Iter->SharingMap.lookup(D); 831 DVar.RefExpr = Data.RefExpr.getPointer(); 832 DVar.PrivateCopy = Data.PrivateCopy; 833 DVar.CKind = Data.Attributes; 834 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 835 return DVar; 836 } 837 838 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 839 // in a Construct, C/C++, implicitly determined, p.1] 840 // In a parallel or task construct, the data-sharing attributes of these 841 // variables are determined by the default clause, if present. 842 switch (Iter->DefaultAttr) { 843 case DSA_shared: 844 DVar.CKind = OMPC_shared; 845 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 846 return DVar; 847 case DSA_none: 848 return DVar; 849 case DSA_unspecified: 850 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 851 // in a Construct, implicitly determined, p.2] 852 // In a parallel construct, if no default clause is present, these 853 // variables are shared. 854 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 855 if (isOpenMPParallelDirective(DVar.DKind) || 856 isOpenMPTeamsDirective(DVar.DKind)) { 857 DVar.CKind = OMPC_shared; 858 return DVar; 859 } 860 861 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 862 // in a Construct, implicitly determined, p.4] 863 // In a task construct, if no default clause is present, a variable that in 864 // the enclosing context is determined to be shared by all implicit tasks 865 // bound to the current team is shared. 866 if (isOpenMPTaskingDirective(DVar.DKind)) { 867 DSAVarData DVarTemp; 868 iterator I = Iter, E = Stack.back().first.rend(); 869 do { 870 ++I; 871 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 872 // Referenced in a Construct, implicitly determined, p.6] 873 // In a task construct, if no default clause is present, a variable 874 // whose data-sharing attribute is not determined by the rules above is 875 // firstprivate. 876 DVarTemp = getDSA(I, D); 877 if (DVarTemp.CKind != OMPC_shared) { 878 DVar.RefExpr = nullptr; 879 DVar.CKind = OMPC_firstprivate; 880 return DVar; 881 } 882 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 883 DVar.CKind = 884 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 885 return DVar; 886 } 887 } 888 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 889 // in a Construct, implicitly determined, p.3] 890 // For constructs other than task, if no default clause is present, these 891 // variables inherit their data-sharing attributes from the enclosing 892 // context. 893 return getDSA(++Iter, D); 894 } 895 896 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 897 const Expr *NewDE) { 898 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 899 D = getCanonicalDecl(D); 900 SharingMapTy &StackElem = Stack.back().first.back(); 901 auto It = StackElem.AlignedMap.find(D); 902 if (It == StackElem.AlignedMap.end()) { 903 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 904 StackElem.AlignedMap[D] = NewDE; 905 return nullptr; 906 } 907 assert(It->second && "Unexpected nullptr expr in the aligned map"); 908 return It->second; 909 } 910 911 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 912 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 913 D = getCanonicalDecl(D); 914 SharingMapTy &StackElem = Stack.back().first.back(); 915 StackElem.LCVMap.try_emplace( 916 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 917 } 918 919 const DSAStackTy::LCDeclInfo 920 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 921 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 922 D = getCanonicalDecl(D); 923 const SharingMapTy &StackElem = Stack.back().first.back(); 924 auto It = StackElem.LCVMap.find(D); 925 if (It != StackElem.LCVMap.end()) 926 return It->second; 927 return {0, nullptr}; 928 } 929 930 const DSAStackTy::LCDeclInfo 931 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 932 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 933 "Data-sharing attributes stack is empty"); 934 D = getCanonicalDecl(D); 935 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 936 auto It = StackElem.LCVMap.find(D); 937 if (It != StackElem.LCVMap.end()) 938 return It->second; 939 return {0, nullptr}; 940 } 941 942 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 943 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 944 "Data-sharing attributes stack is empty"); 945 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 946 if (StackElem.LCVMap.size() < I) 947 return nullptr; 948 for (const auto &Pair : StackElem.LCVMap) 949 if (Pair.second.first == I) 950 return Pair.first; 951 return nullptr; 952 } 953 954 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 955 DeclRefExpr *PrivateCopy) { 956 D = getCanonicalDecl(D); 957 if (A == OMPC_threadprivate) { 958 DSAInfo &Data = Threadprivates[D]; 959 Data.Attributes = A; 960 Data.RefExpr.setPointer(E); 961 Data.PrivateCopy = nullptr; 962 } else { 963 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 964 DSAInfo &Data = Stack.back().first.back().SharingMap[D]; 965 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 966 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 967 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 968 (isLoopControlVariable(D).first && A == OMPC_private)); 969 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 970 Data.RefExpr.setInt(/*IntVal=*/true); 971 return; 972 } 973 const bool IsLastprivate = 974 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 975 Data.Attributes = A; 976 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 977 Data.PrivateCopy = PrivateCopy; 978 if (PrivateCopy) { 979 DSAInfo &Data = 980 Stack.back().first.back().SharingMap[PrivateCopy->getDecl()]; 981 Data.Attributes = A; 982 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 983 Data.PrivateCopy = nullptr; 984 } 985 } 986 } 987 988 /// Build a variable declaration for OpenMP loop iteration variable. 989 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 990 StringRef Name, const AttrVec *Attrs = nullptr, 991 DeclRefExpr *OrigRef = nullptr) { 992 DeclContext *DC = SemaRef.CurContext; 993 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 994 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 995 auto *Decl = 996 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 997 if (Attrs) { 998 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 999 I != E; ++I) 1000 Decl->addAttr(*I); 1001 } 1002 Decl->setImplicit(); 1003 if (OrigRef) { 1004 Decl->addAttr( 1005 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 1006 } 1007 return Decl; 1008 } 1009 1010 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 1011 SourceLocation Loc, 1012 bool RefersToCapture = false) { 1013 D->setReferenced(); 1014 D->markUsed(S.Context); 1015 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 1016 SourceLocation(), D, RefersToCapture, Loc, Ty, 1017 VK_LValue); 1018 } 1019 1020 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1021 BinaryOperatorKind BOK) { 1022 D = getCanonicalDecl(D); 1023 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1024 assert( 1025 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 1026 "Additional reduction info may be specified only for reduction items."); 1027 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 1028 assert(ReductionData.ReductionRange.isInvalid() && 1029 Stack.back().first.back().Directive == OMPD_taskgroup && 1030 "Additional reduction info may be specified only once for reduction " 1031 "items."); 1032 ReductionData.set(BOK, SR); 1033 Expr *&TaskgroupReductionRef = 1034 Stack.back().first.back().TaskgroupReductionRef; 1035 if (!TaskgroupReductionRef) { 1036 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1037 SemaRef.Context.VoidPtrTy, ".task_red."); 1038 TaskgroupReductionRef = 1039 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1040 } 1041 } 1042 1043 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1044 const Expr *ReductionRef) { 1045 D = getCanonicalDecl(D); 1046 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1047 assert( 1048 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 1049 "Additional reduction info may be specified only for reduction items."); 1050 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 1051 assert(ReductionData.ReductionRange.isInvalid() && 1052 Stack.back().first.back().Directive == OMPD_taskgroup && 1053 "Additional reduction info may be specified only once for reduction " 1054 "items."); 1055 ReductionData.set(ReductionRef, SR); 1056 Expr *&TaskgroupReductionRef = 1057 Stack.back().first.back().TaskgroupReductionRef; 1058 if (!TaskgroupReductionRef) { 1059 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1060 SemaRef.Context.VoidPtrTy, ".task_red."); 1061 TaskgroupReductionRef = 1062 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1063 } 1064 } 1065 1066 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1067 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1068 Expr *&TaskgroupDescriptor) const { 1069 D = getCanonicalDecl(D); 1070 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1071 if (Stack.back().first.empty()) 1072 return DSAVarData(); 1073 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 1074 E = Stack.back().first.rend(); 1075 I != E; std::advance(I, 1)) { 1076 const DSAInfo &Data = I->SharingMap.lookup(D); 1077 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1078 continue; 1079 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1080 if (!ReductionData.ReductionOp || 1081 ReductionData.ReductionOp.is<const Expr *>()) 1082 return DSAVarData(); 1083 SR = ReductionData.ReductionRange; 1084 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1085 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1086 "expression for the descriptor is not " 1087 "set."); 1088 TaskgroupDescriptor = I->TaskgroupReductionRef; 1089 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1090 Data.PrivateCopy, I->DefaultAttrLoc); 1091 } 1092 return DSAVarData(); 1093 } 1094 1095 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1096 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 1097 Expr *&TaskgroupDescriptor) const { 1098 D = getCanonicalDecl(D); 1099 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1100 if (Stack.back().first.empty()) 1101 return DSAVarData(); 1102 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 1103 E = Stack.back().first.rend(); 1104 I != E; std::advance(I, 1)) { 1105 const DSAInfo &Data = I->SharingMap.lookup(D); 1106 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1107 continue; 1108 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1109 if (!ReductionData.ReductionOp || 1110 !ReductionData.ReductionOp.is<const Expr *>()) 1111 return DSAVarData(); 1112 SR = ReductionData.ReductionRange; 1113 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 1114 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1115 "expression for the descriptor is not " 1116 "set."); 1117 TaskgroupDescriptor = I->TaskgroupReductionRef; 1118 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1119 Data.PrivateCopy, I->DefaultAttrLoc); 1120 } 1121 return DSAVarData(); 1122 } 1123 1124 bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const { 1125 D = D->getCanonicalDecl(); 1126 if (!isStackEmpty()) { 1127 iterator I = Iter, E = Stack.back().first.rend(); 1128 Scope *TopScope = nullptr; 1129 while (I != E && !isImplicitOrExplicitTaskingRegion(I->Directive) && 1130 !isOpenMPTargetExecutionDirective(I->Directive)) 1131 ++I; 1132 if (I == E) 1133 return false; 1134 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1135 Scope *CurScope = getCurScope(); 1136 while (CurScope != TopScope && !CurScope->isDeclScope(D)) 1137 CurScope = CurScope->getParent(); 1138 return CurScope != TopScope; 1139 } 1140 return false; 1141 } 1142 1143 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1144 bool AcceptIfMutable = true, 1145 bool *IsClassType = nullptr) { 1146 ASTContext &Context = SemaRef.getASTContext(); 1147 Type = Type.getNonReferenceType().getCanonicalType(); 1148 bool IsConstant = Type.isConstant(Context); 1149 Type = Context.getBaseElementType(Type); 1150 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1151 ? Type->getAsCXXRecordDecl() 1152 : nullptr; 1153 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1154 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1155 RD = CTD->getTemplatedDecl(); 1156 if (IsClassType) 1157 *IsClassType = RD; 1158 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1159 RD->hasDefinition() && RD->hasMutableFields()); 1160 } 1161 1162 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1163 QualType Type, OpenMPClauseKind CKind, 1164 SourceLocation ELoc, 1165 bool AcceptIfMutable = true, 1166 bool ListItemNotVar = false) { 1167 ASTContext &Context = SemaRef.getASTContext(); 1168 bool IsClassType; 1169 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1170 unsigned Diag = ListItemNotVar 1171 ? diag::err_omp_const_list_item 1172 : IsClassType ? diag::err_omp_const_not_mutable_variable 1173 : diag::err_omp_const_variable; 1174 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1175 if (!ListItemNotVar && D) { 1176 const VarDecl *VD = dyn_cast<VarDecl>(D); 1177 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1178 VarDecl::DeclarationOnly; 1179 SemaRef.Diag(D->getLocation(), 1180 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1181 << D; 1182 } 1183 return true; 1184 } 1185 return false; 1186 } 1187 1188 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1189 bool FromParent) { 1190 D = getCanonicalDecl(D); 1191 DSAVarData DVar; 1192 1193 auto *VD = dyn_cast<VarDecl>(D); 1194 auto TI = Threadprivates.find(D); 1195 if (TI != Threadprivates.end()) { 1196 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1197 DVar.CKind = OMPC_threadprivate; 1198 return DVar; 1199 } 1200 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1201 DVar.RefExpr = buildDeclRefExpr( 1202 SemaRef, VD, D->getType().getNonReferenceType(), 1203 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1204 DVar.CKind = OMPC_threadprivate; 1205 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1206 return DVar; 1207 } 1208 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1209 // in a Construct, C/C++, predetermined, p.1] 1210 // Variables appearing in threadprivate directives are threadprivate. 1211 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1212 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1213 SemaRef.getLangOpts().OpenMPUseTLS && 1214 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1215 (VD && VD->getStorageClass() == SC_Register && 1216 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1217 DVar.RefExpr = buildDeclRefExpr( 1218 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1219 DVar.CKind = OMPC_threadprivate; 1220 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1221 return DVar; 1222 } 1223 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1224 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1225 !isLoopControlVariable(D).first) { 1226 iterator IterTarget = 1227 std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(), 1228 [](const SharingMapTy &Data) { 1229 return isOpenMPTargetExecutionDirective(Data.Directive); 1230 }); 1231 if (IterTarget != Stack.back().first.rend()) { 1232 iterator ParentIterTarget = std::next(IterTarget, 1); 1233 for (iterator Iter = Stack.back().first.rbegin(); 1234 Iter != ParentIterTarget; std::advance(Iter, 1)) { 1235 if (isOpenMPLocal(VD, Iter)) { 1236 DVar.RefExpr = 1237 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1238 D->getLocation()); 1239 DVar.CKind = OMPC_threadprivate; 1240 return DVar; 1241 } 1242 } 1243 if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) { 1244 auto DSAIter = IterTarget->SharingMap.find(D); 1245 if (DSAIter != IterTarget->SharingMap.end() && 1246 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1247 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1248 DVar.CKind = OMPC_threadprivate; 1249 return DVar; 1250 } 1251 iterator End = Stack.back().first.rend(); 1252 if (!SemaRef.isOpenMPCapturedByRef( 1253 D, std::distance(ParentIterTarget, End))) { 1254 DVar.RefExpr = 1255 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1256 IterTarget->ConstructLoc); 1257 DVar.CKind = OMPC_threadprivate; 1258 return DVar; 1259 } 1260 } 1261 } 1262 } 1263 1264 if (isStackEmpty()) 1265 // Not in OpenMP execution region and top scope was already checked. 1266 return DVar; 1267 1268 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1269 // in a Construct, C/C++, predetermined, p.4] 1270 // Static data members are shared. 1271 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1272 // in a Construct, C/C++, predetermined, p.7] 1273 // Variables with static storage duration that are declared in a scope 1274 // inside the construct are shared. 1275 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1276 if (VD && VD->isStaticDataMember()) { 1277 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 1278 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1279 return DVar; 1280 1281 DVar.CKind = OMPC_shared; 1282 return DVar; 1283 } 1284 1285 // The predetermined shared attribute for const-qualified types having no 1286 // mutable members was removed after OpenMP 3.1. 1287 if (SemaRef.LangOpts.OpenMP <= 31) { 1288 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1289 // in a Construct, C/C++, predetermined, p.6] 1290 // Variables with const qualified type having no mutable member are 1291 // shared. 1292 if (isConstNotMutableType(SemaRef, D->getType())) { 1293 // Variables with const-qualified type having no mutable member may be 1294 // listed in a firstprivate clause, even if they are static data members. 1295 DSAVarData DVarTemp = hasInnermostDSA( 1296 D, 1297 [](OpenMPClauseKind C) { 1298 return C == OMPC_firstprivate || C == OMPC_shared; 1299 }, 1300 MatchesAlways, FromParent); 1301 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1302 return DVarTemp; 1303 1304 DVar.CKind = OMPC_shared; 1305 return DVar; 1306 } 1307 } 1308 1309 // Explicitly specified attributes and local variables with predetermined 1310 // attributes. 1311 iterator I = Stack.back().first.rbegin(); 1312 iterator EndI = Stack.back().first.rend(); 1313 if (FromParent && I != EndI) 1314 std::advance(I, 1); 1315 auto It = I->SharingMap.find(D); 1316 if (It != I->SharingMap.end()) { 1317 const DSAInfo &Data = It->getSecond(); 1318 DVar.RefExpr = Data.RefExpr.getPointer(); 1319 DVar.PrivateCopy = Data.PrivateCopy; 1320 DVar.CKind = Data.Attributes; 1321 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1322 DVar.DKind = I->Directive; 1323 } 1324 1325 return DVar; 1326 } 1327 1328 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1329 bool FromParent) const { 1330 if (isStackEmpty()) { 1331 iterator I; 1332 return getDSA(I, D); 1333 } 1334 D = getCanonicalDecl(D); 1335 iterator StartI = Stack.back().first.rbegin(); 1336 iterator EndI = Stack.back().first.rend(); 1337 if (FromParent && StartI != EndI) 1338 std::advance(StartI, 1); 1339 return getDSA(StartI, D); 1340 } 1341 1342 const DSAStackTy::DSAVarData 1343 DSAStackTy::hasDSA(ValueDecl *D, 1344 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1345 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1346 bool FromParent) const { 1347 if (isStackEmpty()) 1348 return {}; 1349 D = getCanonicalDecl(D); 1350 iterator I = Stack.back().first.rbegin(); 1351 iterator EndI = Stack.back().first.rend(); 1352 if (FromParent && I != EndI) 1353 std::advance(I, 1); 1354 for (; I != EndI; std::advance(I, 1)) { 1355 if (!DPred(I->Directive) && !isImplicitOrExplicitTaskingRegion(I->Directive)) 1356 continue; 1357 iterator NewI = I; 1358 DSAVarData DVar = getDSA(NewI, D); 1359 if (I == NewI && CPred(DVar.CKind)) 1360 return DVar; 1361 } 1362 return {}; 1363 } 1364 1365 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1366 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1367 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1368 bool FromParent) const { 1369 if (isStackEmpty()) 1370 return {}; 1371 D = getCanonicalDecl(D); 1372 iterator StartI = Stack.back().first.rbegin(); 1373 iterator EndI = Stack.back().first.rend(); 1374 if (FromParent && StartI != EndI) 1375 std::advance(StartI, 1); 1376 if (StartI == EndI || !DPred(StartI->Directive)) 1377 return {}; 1378 iterator NewI = StartI; 1379 DSAVarData DVar = getDSA(NewI, D); 1380 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1381 } 1382 1383 bool DSAStackTy::hasExplicitDSA( 1384 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1385 unsigned Level, bool NotLastprivate) const { 1386 if (isStackEmpty()) 1387 return false; 1388 D = getCanonicalDecl(D); 1389 auto StartI = Stack.back().first.begin(); 1390 auto EndI = Stack.back().first.end(); 1391 if (std::distance(StartI, EndI) <= (int)Level) 1392 return false; 1393 std::advance(StartI, Level); 1394 auto I = StartI->SharingMap.find(D); 1395 if ((I != StartI->SharingMap.end()) && 1396 I->getSecond().RefExpr.getPointer() && 1397 CPred(I->getSecond().Attributes) && 1398 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1399 return true; 1400 // Check predetermined rules for the loop control variables. 1401 auto LI = StartI->LCVMap.find(D); 1402 if (LI != StartI->LCVMap.end()) 1403 return CPred(OMPC_private); 1404 return false; 1405 } 1406 1407 bool DSAStackTy::hasExplicitDirective( 1408 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1409 unsigned Level) const { 1410 if (isStackEmpty()) 1411 return false; 1412 auto StartI = Stack.back().first.begin(); 1413 auto EndI = Stack.back().first.end(); 1414 if (std::distance(StartI, EndI) <= (int)Level) 1415 return false; 1416 std::advance(StartI, Level); 1417 return DPred(StartI->Directive); 1418 } 1419 1420 bool DSAStackTy::hasDirective( 1421 const llvm::function_ref<bool(OpenMPDirectiveKind, 1422 const DeclarationNameInfo &, SourceLocation)> 1423 DPred, 1424 bool FromParent) const { 1425 // We look only in the enclosing region. 1426 if (isStackEmpty()) 1427 return false; 1428 auto StartI = std::next(Stack.back().first.rbegin()); 1429 auto EndI = Stack.back().first.rend(); 1430 if (FromParent && StartI != EndI) 1431 StartI = std::next(StartI); 1432 for (auto I = StartI, EE = EndI; I != EE; ++I) { 1433 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1434 return true; 1435 } 1436 return false; 1437 } 1438 1439 void Sema::InitDataSharingAttributesStack() { 1440 VarDataSharingAttributesStack = new DSAStackTy(*this); 1441 } 1442 1443 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1444 1445 void Sema::pushOpenMPFunctionRegion() { 1446 DSAStack->pushFunction(); 1447 } 1448 1449 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1450 DSAStack->popFunction(OldFSI); 1451 } 1452 1453 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1454 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1455 "Expected OpenMP device compilation."); 1456 return !S.isInOpenMPTargetExecutionDirective() && 1457 !S.isInOpenMPDeclareTargetContext(); 1458 } 1459 1460 /// Do we know that we will eventually codegen the given function? 1461 static bool isKnownEmitted(Sema &S, FunctionDecl *FD) { 1462 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1463 "Expected OpenMP device compilation."); 1464 // Templates are emitted when they're instantiated. 1465 if (FD->isDependentContext()) 1466 return false; 1467 1468 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1469 FD->getCanonicalDecl())) 1470 return true; 1471 1472 // Otherwise, the function is known-emitted if it's in our set of 1473 // known-emitted functions. 1474 return S.DeviceKnownEmittedFns.count(FD) > 0; 1475 } 1476 1477 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1478 unsigned DiagID) { 1479 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1480 "Expected OpenMP device compilation."); 1481 return DeviceDiagBuilder((isOpenMPDeviceDelayedContext(*this) && 1482 !isKnownEmitted(*this, getCurFunctionDecl())) 1483 ? DeviceDiagBuilder::K_Deferred 1484 : DeviceDiagBuilder::K_Immediate, 1485 Loc, DiagID, getCurFunctionDecl(), *this); 1486 } 1487 1488 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) { 1489 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1490 "Expected OpenMP device compilation."); 1491 assert(Callee && "Callee may not be null."); 1492 FunctionDecl *Caller = getCurFunctionDecl(); 1493 1494 // If the caller is known-emitted, mark the callee as known-emitted. 1495 // Otherwise, mark the call in our call graph so we can traverse it later. 1496 if (!isOpenMPDeviceDelayedContext(*this) || 1497 (Caller && isKnownEmitted(*this, Caller))) 1498 markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted); 1499 else if (Caller) 1500 DeviceCallGraph[Caller].insert({Callee, Loc}); 1501 } 1502 1503 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1504 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1505 "OpenMP device compilation mode is expected."); 1506 QualType Ty = E->getType(); 1507 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1508 (Ty->isFloat128Type() && !Context.getTargetInfo().hasFloat128Type()) || 1509 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1510 !Context.getTargetInfo().hasInt128Type())) 1511 targetDiag(E->getExprLoc(), diag::err_type_unsupported) 1512 << Ty << E->getSourceRange(); 1513 } 1514 1515 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1516 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1517 1518 ASTContext &Ctx = getASTContext(); 1519 bool IsByRef = true; 1520 1521 // Find the directive that is associated with the provided scope. 1522 D = cast<ValueDecl>(D->getCanonicalDecl()); 1523 QualType Ty = D->getType(); 1524 1525 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1526 // This table summarizes how a given variable should be passed to the device 1527 // given its type and the clauses where it appears. This table is based on 1528 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1529 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1530 // 1531 // ========================================================================= 1532 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1533 // | |(tofrom:scalar)| | pvt | | | | 1534 // ========================================================================= 1535 // | scl | | | | - | | bycopy| 1536 // | scl | | - | x | - | - | bycopy| 1537 // | scl | | x | - | - | - | null | 1538 // | scl | x | | | - | | byref | 1539 // | scl | x | - | x | - | - | bycopy| 1540 // | scl | x | x | - | - | - | null | 1541 // | scl | | - | - | - | x | byref | 1542 // | scl | x | - | - | - | x | byref | 1543 // 1544 // | agg | n.a. | | | - | | byref | 1545 // | agg | n.a. | - | x | - | - | byref | 1546 // | agg | n.a. | x | - | - | - | null | 1547 // | agg | n.a. | - | - | - | x | byref | 1548 // | agg | n.a. | - | - | - | x[] | byref | 1549 // 1550 // | ptr | n.a. | | | - | | bycopy| 1551 // | ptr | n.a. | - | x | - | - | bycopy| 1552 // | ptr | n.a. | x | - | - | - | null | 1553 // | ptr | n.a. | - | - | - | x | byref | 1554 // | ptr | n.a. | - | - | - | x[] | bycopy| 1555 // | ptr | n.a. | - | - | x | | bycopy| 1556 // | ptr | n.a. | - | - | x | x | bycopy| 1557 // | ptr | n.a. | - | - | x | x[] | bycopy| 1558 // ========================================================================= 1559 // Legend: 1560 // scl - scalar 1561 // ptr - pointer 1562 // agg - aggregate 1563 // x - applies 1564 // - - invalid in this combination 1565 // [] - mapped with an array section 1566 // byref - should be mapped by reference 1567 // byval - should be mapped by value 1568 // null - initialize a local variable to null on the device 1569 // 1570 // Observations: 1571 // - All scalar declarations that show up in a map clause have to be passed 1572 // by reference, because they may have been mapped in the enclosing data 1573 // environment. 1574 // - If the scalar value does not fit the size of uintptr, it has to be 1575 // passed by reference, regardless the result in the table above. 1576 // - For pointers mapped by value that have either an implicit map or an 1577 // array section, the runtime library may pass the NULL value to the 1578 // device instead of the value passed to it by the compiler. 1579 1580 if (Ty->isReferenceType()) 1581 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1582 1583 // Locate map clauses and see if the variable being captured is referred to 1584 // in any of those clauses. Here we only care about variables, not fields, 1585 // because fields are part of aggregates. 1586 bool IsVariableUsedInMapClause = false; 1587 bool IsVariableAssociatedWithSection = false; 1588 1589 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1590 D, Level, 1591 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1592 OMPClauseMappableExprCommon::MappableExprComponentListRef 1593 MapExprComponents, 1594 OpenMPClauseKind WhereFoundClauseKind) { 1595 // Only the map clause information influences how a variable is 1596 // captured. E.g. is_device_ptr does not require changing the default 1597 // behavior. 1598 if (WhereFoundClauseKind != OMPC_map) 1599 return false; 1600 1601 auto EI = MapExprComponents.rbegin(); 1602 auto EE = MapExprComponents.rend(); 1603 1604 assert(EI != EE && "Invalid map expression!"); 1605 1606 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1607 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1608 1609 ++EI; 1610 if (EI == EE) 1611 return false; 1612 1613 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1614 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1615 isa<MemberExpr>(EI->getAssociatedExpression())) { 1616 IsVariableAssociatedWithSection = true; 1617 // There is nothing more we need to know about this variable. 1618 return true; 1619 } 1620 1621 // Keep looking for more map info. 1622 return false; 1623 }); 1624 1625 if (IsVariableUsedInMapClause) { 1626 // If variable is identified in a map clause it is always captured by 1627 // reference except if it is a pointer that is dereferenced somehow. 1628 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1629 } else { 1630 // By default, all the data that has a scalar type is mapped by copy 1631 // (except for reduction variables). 1632 IsByRef = 1633 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1634 !Ty->isAnyPointerType()) || 1635 !Ty->isScalarType() || 1636 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1637 DSAStack->hasExplicitDSA( 1638 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1639 } 1640 } 1641 1642 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1643 IsByRef = 1644 ((DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1645 !Ty->isAnyPointerType()) || 1646 !DSAStack->hasExplicitDSA( 1647 D, 1648 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1649 Level, /*NotLastprivate=*/true)) && 1650 // If the variable is artificial and must be captured by value - try to 1651 // capture by value. 1652 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1653 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1654 } 1655 1656 // When passing data by copy, we need to make sure it fits the uintptr size 1657 // and alignment, because the runtime library only deals with uintptr types. 1658 // If it does not fit the uintptr size, we need to pass the data by reference 1659 // instead. 1660 if (!IsByRef && 1661 (Ctx.getTypeSizeInChars(Ty) > 1662 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1663 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1664 IsByRef = true; 1665 } 1666 1667 return IsByRef; 1668 } 1669 1670 unsigned Sema::getOpenMPNestingLevel() const { 1671 assert(getLangOpts().OpenMP); 1672 return DSAStack->getNestingLevel(); 1673 } 1674 1675 bool Sema::isInOpenMPTargetExecutionDirective() const { 1676 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1677 !DSAStack->isClauseParsingMode()) || 1678 DSAStack->hasDirective( 1679 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1680 SourceLocation) -> bool { 1681 return isOpenMPTargetExecutionDirective(K); 1682 }, 1683 false); 1684 } 1685 1686 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) { 1687 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1688 D = getCanonicalDecl(D); 1689 1690 // If we are attempting to capture a global variable in a directive with 1691 // 'target' we return true so that this global is also mapped to the device. 1692 // 1693 auto *VD = dyn_cast<VarDecl>(D); 1694 if (VD && !VD->hasLocalStorage()) { 1695 if (isInOpenMPDeclareTargetContext() && 1696 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1697 // Try to mark variable as declare target if it is used in capturing 1698 // regions. 1699 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1700 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1701 return nullptr; 1702 } else if (isInOpenMPTargetExecutionDirective()) { 1703 // If the declaration is enclosed in a 'declare target' directive, 1704 // then it should not be captured. 1705 // 1706 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1707 return nullptr; 1708 return VD; 1709 } 1710 } 1711 // Capture variables captured by reference in lambdas for target-based 1712 // directives. 1713 if (VD && !DSAStack->isClauseParsingMode()) { 1714 if (const auto *RD = VD->getType() 1715 .getCanonicalType() 1716 .getNonReferenceType() 1717 ->getAsCXXRecordDecl()) { 1718 bool SavedForceCaptureByReferenceInTargetExecutable = 1719 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 1720 DSAStack->setForceCaptureByReferenceInTargetExecutable(/*V=*/true); 1721 if (RD->isLambda()) { 1722 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 1723 FieldDecl *ThisCapture; 1724 RD->getCaptureFields(Captures, ThisCapture); 1725 for (const LambdaCapture &LC : RD->captures()) { 1726 if (LC.getCaptureKind() == LCK_ByRef) { 1727 VarDecl *VD = LC.getCapturedVar(); 1728 DeclContext *VDC = VD->getDeclContext(); 1729 if (!VDC->Encloses(CurContext)) 1730 continue; 1731 DSAStackTy::DSAVarData DVarPrivate = 1732 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1733 // Do not capture already captured variables. 1734 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) && 1735 DVarPrivate.CKind == OMPC_unknown && 1736 !DSAStack->checkMappableExprComponentListsForDecl( 1737 D, /*CurrentRegionOnly=*/true, 1738 [](OMPClauseMappableExprCommon:: 1739 MappableExprComponentListRef, 1740 OpenMPClauseKind) { return true; })) 1741 MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar()); 1742 } else if (LC.getCaptureKind() == LCK_This) { 1743 QualType ThisTy = getCurrentThisType(); 1744 if (!ThisTy.isNull() && 1745 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 1746 CheckCXXThisCapture(LC.getLocation()); 1747 } 1748 } 1749 } 1750 DSAStack->setForceCaptureByReferenceInTargetExecutable( 1751 SavedForceCaptureByReferenceInTargetExecutable); 1752 } 1753 } 1754 1755 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1756 (!DSAStack->isClauseParsingMode() || 1757 DSAStack->getParentDirective() != OMPD_unknown)) { 1758 auto &&Info = DSAStack->isLoopControlVariable(D); 1759 if (Info.first || 1760 (VD && VD->hasLocalStorage() && 1761 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1762 (VD && DSAStack->isForceVarCapturing())) 1763 return VD ? VD : Info.second; 1764 DSAStackTy::DSAVarData DVarPrivate = 1765 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1766 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1767 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1768 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1769 [](OpenMPDirectiveKind) { return true; }, 1770 DSAStack->isClauseParsingMode()); 1771 if (DVarPrivate.CKind != OMPC_unknown) 1772 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1773 } 1774 return nullptr; 1775 } 1776 1777 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1778 unsigned Level) const { 1779 SmallVector<OpenMPDirectiveKind, 4> Regions; 1780 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1781 FunctionScopesIndex -= Regions.size(); 1782 } 1783 1784 void Sema::startOpenMPLoop() { 1785 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1786 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1787 DSAStack->loopInit(); 1788 } 1789 1790 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1791 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1792 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1793 if (DSAStack->getAssociatedLoops() > 0 && 1794 !DSAStack->isLoopStarted()) { 1795 DSAStack->resetPossibleLoopCounter(D); 1796 DSAStack->loopStart(); 1797 return true; 1798 } 1799 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 1800 DSAStack->isLoopControlVariable(D).first) && 1801 !DSAStack->hasExplicitDSA( 1802 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 1803 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 1804 return true; 1805 } 1806 return DSAStack->hasExplicitDSA( 1807 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1808 (DSAStack->isClauseParsingMode() && 1809 DSAStack->getClauseParsingMode() == OMPC_private) || 1810 // Consider taskgroup reduction descriptor variable a private to avoid 1811 // possible capture in the region. 1812 (DSAStack->hasExplicitDirective( 1813 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1814 Level) && 1815 DSAStack->isTaskgroupReductionRef(D, Level)); 1816 } 1817 1818 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1819 unsigned Level) { 1820 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1821 D = getCanonicalDecl(D); 1822 OpenMPClauseKind OMPC = OMPC_unknown; 1823 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1824 const unsigned NewLevel = I - 1; 1825 if (DSAStack->hasExplicitDSA(D, 1826 [&OMPC](const OpenMPClauseKind K) { 1827 if (isOpenMPPrivate(K)) { 1828 OMPC = K; 1829 return true; 1830 } 1831 return false; 1832 }, 1833 NewLevel)) 1834 break; 1835 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1836 D, NewLevel, 1837 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1838 OpenMPClauseKind) { return true; })) { 1839 OMPC = OMPC_map; 1840 break; 1841 } 1842 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1843 NewLevel)) { 1844 OMPC = OMPC_map; 1845 if (D->getType()->isScalarType() && 1846 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1847 DefaultMapAttributes::DMA_tofrom_scalar) 1848 OMPC = OMPC_firstprivate; 1849 break; 1850 } 1851 } 1852 if (OMPC != OMPC_unknown) 1853 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1854 } 1855 1856 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1857 unsigned Level) const { 1858 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1859 // Return true if the current level is no longer enclosed in a target region. 1860 1861 const auto *VD = dyn_cast<VarDecl>(D); 1862 return VD && !VD->hasLocalStorage() && 1863 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1864 Level); 1865 } 1866 1867 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1868 1869 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1870 const DeclarationNameInfo &DirName, 1871 Scope *CurScope, SourceLocation Loc) { 1872 DSAStack->push(DKind, DirName, CurScope, Loc); 1873 PushExpressionEvaluationContext( 1874 ExpressionEvaluationContext::PotentiallyEvaluated); 1875 } 1876 1877 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1878 DSAStack->setClauseParsingMode(K); 1879 } 1880 1881 void Sema::EndOpenMPClause() { 1882 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1883 } 1884 1885 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1886 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1887 // A variable of class type (or array thereof) that appears in a lastprivate 1888 // clause requires an accessible, unambiguous default constructor for the 1889 // class type, unless the list item is also specified in a firstprivate 1890 // clause. 1891 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1892 for (OMPClause *C : D->clauses()) { 1893 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1894 SmallVector<Expr *, 8> PrivateCopies; 1895 for (Expr *DE : Clause->varlists()) { 1896 if (DE->isValueDependent() || DE->isTypeDependent()) { 1897 PrivateCopies.push_back(nullptr); 1898 continue; 1899 } 1900 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1901 auto *VD = cast<VarDecl>(DRE->getDecl()); 1902 QualType Type = VD->getType().getNonReferenceType(); 1903 const DSAStackTy::DSAVarData DVar = 1904 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1905 if (DVar.CKind == OMPC_lastprivate) { 1906 // Generate helper private variable and initialize it with the 1907 // default value. The address of the original variable is replaced 1908 // by the address of the new private variable in CodeGen. This new 1909 // variable is not added to IdResolver, so the code in the OpenMP 1910 // region uses original variable for proper diagnostics. 1911 VarDecl *VDPrivate = buildVarDecl( 1912 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1913 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 1914 ActOnUninitializedDecl(VDPrivate); 1915 if (VDPrivate->isInvalidDecl()) 1916 continue; 1917 PrivateCopies.push_back(buildDeclRefExpr( 1918 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1919 } else { 1920 // The variable is also a firstprivate, so initialization sequence 1921 // for private copy is generated already. 1922 PrivateCopies.push_back(nullptr); 1923 } 1924 } 1925 // Set initializers to private copies if no errors were found. 1926 if (PrivateCopies.size() == Clause->varlist_size()) 1927 Clause->setPrivateCopies(PrivateCopies); 1928 } 1929 } 1930 } 1931 1932 DSAStack->pop(); 1933 DiscardCleanupsInEvaluationContext(); 1934 PopExpressionEvaluationContext(); 1935 } 1936 1937 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1938 Expr *NumIterations, Sema &SemaRef, 1939 Scope *S, DSAStackTy *Stack); 1940 1941 namespace { 1942 1943 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 1944 private: 1945 Sema &SemaRef; 1946 1947 public: 1948 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1949 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1950 NamedDecl *ND = Candidate.getCorrectionDecl(); 1951 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 1952 return VD->hasGlobalStorage() && 1953 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1954 SemaRef.getCurScope()); 1955 } 1956 return false; 1957 } 1958 }; 1959 1960 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 1961 private: 1962 Sema &SemaRef; 1963 1964 public: 1965 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 1966 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1967 NamedDecl *ND = Candidate.getCorrectionDecl(); 1968 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 1969 isa<FunctionDecl>(ND))) { 1970 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1971 SemaRef.getCurScope()); 1972 } 1973 return false; 1974 } 1975 }; 1976 1977 } // namespace 1978 1979 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 1980 CXXScopeSpec &ScopeSpec, 1981 const DeclarationNameInfo &Id, 1982 OpenMPDirectiveKind Kind) { 1983 LookupResult Lookup(*this, Id, LookupOrdinaryName); 1984 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 1985 1986 if (Lookup.isAmbiguous()) 1987 return ExprError(); 1988 1989 VarDecl *VD; 1990 if (!Lookup.isSingleResult()) { 1991 if (TypoCorrection Corrected = CorrectTypo( 1992 Id, LookupOrdinaryName, CurScope, nullptr, 1993 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 1994 diagnoseTypo(Corrected, 1995 PDiag(Lookup.empty() 1996 ? diag::err_undeclared_var_use_suggest 1997 : diag::err_omp_expected_var_arg_suggest) 1998 << Id.getName()); 1999 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 2000 } else { 2001 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 2002 : diag::err_omp_expected_var_arg) 2003 << Id.getName(); 2004 return ExprError(); 2005 } 2006 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 2007 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 2008 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 2009 return ExprError(); 2010 } 2011 Lookup.suppressDiagnostics(); 2012 2013 // OpenMP [2.9.2, Syntax, C/C++] 2014 // Variables must be file-scope, namespace-scope, or static block-scope. 2015 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 2016 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 2017 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 2018 bool IsDecl = 2019 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2020 Diag(VD->getLocation(), 2021 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2022 << VD; 2023 return ExprError(); 2024 } 2025 2026 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 2027 NamedDecl *ND = CanonicalVD; 2028 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2029 // A threadprivate directive for file-scope variables must appear outside 2030 // any definition or declaration. 2031 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2032 !getCurLexicalContext()->isTranslationUnit()) { 2033 Diag(Id.getLoc(), diag::err_omp_var_scope) 2034 << getOpenMPDirectiveName(Kind) << VD; 2035 bool IsDecl = 2036 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2037 Diag(VD->getLocation(), 2038 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2039 << VD; 2040 return ExprError(); 2041 } 2042 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2043 // A threadprivate directive for static class member variables must appear 2044 // in the class definition, in the same scope in which the member 2045 // variables are declared. 2046 if (CanonicalVD->isStaticDataMember() && 2047 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2048 Diag(Id.getLoc(), diag::err_omp_var_scope) 2049 << getOpenMPDirectiveName(Kind) << VD; 2050 bool IsDecl = 2051 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2052 Diag(VD->getLocation(), 2053 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2054 << VD; 2055 return ExprError(); 2056 } 2057 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2058 // A threadprivate directive for namespace-scope variables must appear 2059 // outside any definition or declaration other than the namespace 2060 // definition itself. 2061 if (CanonicalVD->getDeclContext()->isNamespace() && 2062 (!getCurLexicalContext()->isFileContext() || 2063 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2064 Diag(Id.getLoc(), diag::err_omp_var_scope) 2065 << getOpenMPDirectiveName(Kind) << VD; 2066 bool IsDecl = 2067 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2068 Diag(VD->getLocation(), 2069 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2070 << VD; 2071 return ExprError(); 2072 } 2073 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2074 // A threadprivate directive for static block-scope variables must appear 2075 // in the scope of the variable and not in a nested scope. 2076 if (CanonicalVD->isLocalVarDecl() && CurScope && 2077 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2078 Diag(Id.getLoc(), diag::err_omp_var_scope) 2079 << getOpenMPDirectiveName(Kind) << VD; 2080 bool IsDecl = 2081 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2082 Diag(VD->getLocation(), 2083 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2084 << VD; 2085 return ExprError(); 2086 } 2087 2088 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2089 // A threadprivate directive must lexically precede all references to any 2090 // of the variables in its list. 2091 if (Kind == OMPD_threadprivate && VD->isUsed() && 2092 !DSAStack->isThreadPrivate(VD)) { 2093 Diag(Id.getLoc(), diag::err_omp_var_used) 2094 << getOpenMPDirectiveName(Kind) << VD; 2095 return ExprError(); 2096 } 2097 2098 QualType ExprType = VD->getType().getNonReferenceType(); 2099 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2100 SourceLocation(), VD, 2101 /*RefersToEnclosingVariableOrCapture=*/false, 2102 Id.getLoc(), ExprType, VK_LValue); 2103 } 2104 2105 Sema::DeclGroupPtrTy 2106 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2107 ArrayRef<Expr *> VarList) { 2108 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2109 CurContext->addDecl(D); 2110 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2111 } 2112 return nullptr; 2113 } 2114 2115 namespace { 2116 class LocalVarRefChecker final 2117 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2118 Sema &SemaRef; 2119 2120 public: 2121 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2122 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2123 if (VD->hasLocalStorage()) { 2124 SemaRef.Diag(E->getBeginLoc(), 2125 diag::err_omp_local_var_in_threadprivate_init) 2126 << E->getSourceRange(); 2127 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2128 << VD << VD->getSourceRange(); 2129 return true; 2130 } 2131 } 2132 return false; 2133 } 2134 bool VisitStmt(const Stmt *S) { 2135 for (const Stmt *Child : S->children()) { 2136 if (Child && Visit(Child)) 2137 return true; 2138 } 2139 return false; 2140 } 2141 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2142 }; 2143 } // namespace 2144 2145 OMPThreadPrivateDecl * 2146 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2147 SmallVector<Expr *, 8> Vars; 2148 for (Expr *RefExpr : VarList) { 2149 auto *DE = cast<DeclRefExpr>(RefExpr); 2150 auto *VD = cast<VarDecl>(DE->getDecl()); 2151 SourceLocation ILoc = DE->getExprLoc(); 2152 2153 // Mark variable as used. 2154 VD->setReferenced(); 2155 VD->markUsed(Context); 2156 2157 QualType QType = VD->getType(); 2158 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2159 // It will be analyzed later. 2160 Vars.push_back(DE); 2161 continue; 2162 } 2163 2164 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2165 // A threadprivate variable must not have an incomplete type. 2166 if (RequireCompleteType(ILoc, VD->getType(), 2167 diag::err_omp_threadprivate_incomplete_type)) { 2168 continue; 2169 } 2170 2171 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2172 // A threadprivate variable must not have a reference type. 2173 if (VD->getType()->isReferenceType()) { 2174 Diag(ILoc, diag::err_omp_ref_type_arg) 2175 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2176 bool IsDecl = 2177 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2178 Diag(VD->getLocation(), 2179 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2180 << VD; 2181 continue; 2182 } 2183 2184 // Check if this is a TLS variable. If TLS is not being supported, produce 2185 // the corresponding diagnostic. 2186 if ((VD->getTLSKind() != VarDecl::TLS_None && 2187 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2188 getLangOpts().OpenMPUseTLS && 2189 getASTContext().getTargetInfo().isTLSSupported())) || 2190 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2191 !VD->isLocalVarDecl())) { 2192 Diag(ILoc, diag::err_omp_var_thread_local) 2193 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2194 bool IsDecl = 2195 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2196 Diag(VD->getLocation(), 2197 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2198 << VD; 2199 continue; 2200 } 2201 2202 // Check if initial value of threadprivate variable reference variable with 2203 // local storage (it is not supported by runtime). 2204 if (const Expr *Init = VD->getAnyInitializer()) { 2205 LocalVarRefChecker Checker(*this); 2206 if (Checker.Visit(Init)) 2207 continue; 2208 } 2209 2210 Vars.push_back(RefExpr); 2211 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2212 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2213 Context, SourceRange(Loc, Loc))); 2214 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2215 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2216 } 2217 OMPThreadPrivateDecl *D = nullptr; 2218 if (!Vars.empty()) { 2219 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2220 Vars); 2221 D->setAccess(AS_public); 2222 } 2223 return D; 2224 } 2225 2226 static OMPAllocateDeclAttr::AllocatorTypeTy 2227 getAllocatorKind(Sema &S, DSAStackTy *Stack, Expr *Allocator) { 2228 if (!Allocator) 2229 return OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2230 if (Allocator->isTypeDependent() || Allocator->isValueDependent() || 2231 Allocator->isInstantiationDependent() || 2232 Allocator->containsUnexpandedParameterPack()) 2233 return OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2234 auto AllocatorKindRes = OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; 2235 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 2236 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 2237 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 2238 Expr *DefAllocator = Stack->getAllocator(AllocatorKind); 2239 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2240 llvm::FoldingSetNodeID AEId, DAEId; 2241 AE->Profile(AEId, S.getASTContext(), /*Canonical=*/true); 2242 DefAllocator->Profile(DAEId, S.getASTContext(), /*Canonical=*/true); 2243 if (AEId == DAEId) { 2244 AllocatorKindRes = AllocatorKind; 2245 break; 2246 } 2247 } 2248 return AllocatorKindRes; 2249 } 2250 2251 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2252 SourceLocation Loc, ArrayRef<Expr *> VarList, 2253 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2254 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2255 Expr *Allocator = nullptr; 2256 if (Clauses.empty()) { 2257 // OpenMP 5.0, 2.11.3 allocate Directive, Restrictions. 2258 // allocate directives that appear in a target region must specify an 2259 // allocator clause unless a requires directive with the dynamic_allocators 2260 // clause is present in the same compilation unit. 2261 if (LangOpts.OpenMPIsDevice && 2262 !DSAStack->hasRequiresDeclWithClause<OMPDynamicAllocatorsClause>()) 2263 targetDiag(Loc, diag::err_expected_allocator_clause); 2264 } else { 2265 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2266 } 2267 OMPAllocateDeclAttr::AllocatorTypeTy AllocatorKind = 2268 getAllocatorKind(*this, DSAStack, Allocator); 2269 SmallVector<Expr *, 8> Vars; 2270 for (Expr *RefExpr : VarList) { 2271 auto *DE = cast<DeclRefExpr>(RefExpr); 2272 auto *VD = cast<VarDecl>(DE->getDecl()); 2273 2274 // Check if this is a TLS variable or global register. 2275 if (VD->getTLSKind() != VarDecl::TLS_None || 2276 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2277 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2278 !VD->isLocalVarDecl())) 2279 continue; 2280 // Do not apply for parameters. 2281 if (isa<ParmVarDecl>(VD)) 2282 continue; 2283 2284 // If the used several times in the allocate directive, the same allocator 2285 // must be used. 2286 if (VD->hasAttr<OMPAllocateDeclAttr>()) { 2287 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2288 Expr *PrevAllocator = A->getAllocator(); 2289 OMPAllocateDeclAttr::AllocatorTypeTy PrevAllocatorKind = 2290 getAllocatorKind(*this, DSAStack, PrevAllocator); 2291 bool AllocatorsMatch = AllocatorKind == PrevAllocatorKind; 2292 if (AllocatorsMatch && Allocator && PrevAllocator) { 2293 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2294 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2295 llvm::FoldingSetNodeID AEId, PAEId; 2296 AE->Profile(AEId, Context, /*Canonical=*/true); 2297 PAE->Profile(PAEId, Context, /*Canonical=*/true); 2298 AllocatorsMatch = AEId == PAEId; 2299 } 2300 if (!AllocatorsMatch) { 2301 SmallString<256> AllocatorBuffer; 2302 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2303 if (Allocator) 2304 Allocator->printPretty(AllocatorStream, nullptr, getPrintingPolicy()); 2305 SmallString<256> PrevAllocatorBuffer; 2306 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2307 if (PrevAllocator) 2308 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2309 getPrintingPolicy()); 2310 2311 SourceLocation AllocatorLoc = 2312 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2313 SourceRange AllocatorRange = 2314 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2315 SourceLocation PrevAllocatorLoc = 2316 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2317 SourceRange PrevAllocatorRange = 2318 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2319 Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2320 << (Allocator ? 1 : 0) << AllocatorStream.str() 2321 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2322 << AllocatorRange; 2323 Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2324 << PrevAllocatorRange; 2325 continue; 2326 } 2327 } 2328 2329 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2330 // If a list item has a static storage type, the allocator expression in the 2331 // allocator clause must be a constant expression that evaluates to one of 2332 // the predefined memory allocator values. 2333 if (Allocator && VD->hasGlobalStorage()) { 2334 if (AllocatorKind == OMPAllocateDeclAttr::OMPUserDefinedMemAlloc) { 2335 Diag(Allocator->getExprLoc(), 2336 diag::err_omp_expected_predefined_allocator) 2337 << Allocator->getSourceRange(); 2338 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2339 VarDecl::DeclarationOnly; 2340 Diag(VD->getLocation(), 2341 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2342 << VD; 2343 continue; 2344 } 2345 } 2346 2347 Vars.push_back(RefExpr); 2348 if ((!Allocator || (Allocator && !Allocator->isTypeDependent() && 2349 !Allocator->isValueDependent() && 2350 !Allocator->isInstantiationDependent() && 2351 !Allocator->containsUnexpandedParameterPack())) && 2352 !VD->hasAttr<OMPAllocateDeclAttr>()) { 2353 Attr *A = OMPAllocateDeclAttr::CreateImplicit( 2354 Context, AllocatorKind, Allocator, DE->getSourceRange()); 2355 VD->addAttr(A); 2356 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2357 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2358 } 2359 } 2360 if (Vars.empty()) 2361 return nullptr; 2362 if (!Owner) 2363 Owner = getCurLexicalContext(); 2364 OMPAllocateDecl *D = 2365 OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2366 D->setAccess(AS_public); 2367 Owner->addDecl(D); 2368 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2369 } 2370 2371 Sema::DeclGroupPtrTy 2372 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2373 ArrayRef<OMPClause *> ClauseList) { 2374 OMPRequiresDecl *D = nullptr; 2375 if (!CurContext->isFileContext()) { 2376 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2377 } else { 2378 D = CheckOMPRequiresDecl(Loc, ClauseList); 2379 if (D) { 2380 CurContext->addDecl(D); 2381 DSAStack->addRequiresDecl(D); 2382 } 2383 } 2384 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2385 } 2386 2387 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2388 ArrayRef<OMPClause *> ClauseList) { 2389 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2390 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2391 ClauseList); 2392 return nullptr; 2393 } 2394 2395 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2396 const ValueDecl *D, 2397 const DSAStackTy::DSAVarData &DVar, 2398 bool IsLoopIterVar = false) { 2399 if (DVar.RefExpr) { 2400 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2401 << getOpenMPClauseName(DVar.CKind); 2402 return; 2403 } 2404 enum { 2405 PDSA_StaticMemberShared, 2406 PDSA_StaticLocalVarShared, 2407 PDSA_LoopIterVarPrivate, 2408 PDSA_LoopIterVarLinear, 2409 PDSA_LoopIterVarLastprivate, 2410 PDSA_ConstVarShared, 2411 PDSA_GlobalVarShared, 2412 PDSA_TaskVarFirstprivate, 2413 PDSA_LocalVarPrivate, 2414 PDSA_Implicit 2415 } Reason = PDSA_Implicit; 2416 bool ReportHint = false; 2417 auto ReportLoc = D->getLocation(); 2418 auto *VD = dyn_cast<VarDecl>(D); 2419 if (IsLoopIterVar) { 2420 if (DVar.CKind == OMPC_private) 2421 Reason = PDSA_LoopIterVarPrivate; 2422 else if (DVar.CKind == OMPC_lastprivate) 2423 Reason = PDSA_LoopIterVarLastprivate; 2424 else 2425 Reason = PDSA_LoopIterVarLinear; 2426 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2427 DVar.CKind == OMPC_firstprivate) { 2428 Reason = PDSA_TaskVarFirstprivate; 2429 ReportLoc = DVar.ImplicitDSALoc; 2430 } else if (VD && VD->isStaticLocal()) 2431 Reason = PDSA_StaticLocalVarShared; 2432 else if (VD && VD->isStaticDataMember()) 2433 Reason = PDSA_StaticMemberShared; 2434 else if (VD && VD->isFileVarDecl()) 2435 Reason = PDSA_GlobalVarShared; 2436 else if (D->getType().isConstant(SemaRef.getASTContext())) 2437 Reason = PDSA_ConstVarShared; 2438 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2439 ReportHint = true; 2440 Reason = PDSA_LocalVarPrivate; 2441 } 2442 if (Reason != PDSA_Implicit) { 2443 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2444 << Reason << ReportHint 2445 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2446 } else if (DVar.ImplicitDSALoc.isValid()) { 2447 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2448 << getOpenMPClauseName(DVar.CKind); 2449 } 2450 } 2451 2452 namespace { 2453 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2454 DSAStackTy *Stack; 2455 Sema &SemaRef; 2456 bool ErrorFound = false; 2457 CapturedStmt *CS = nullptr; 2458 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2459 llvm::SmallVector<Expr *, 4> ImplicitMap; 2460 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2461 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2462 2463 void VisitSubCaptures(OMPExecutableDirective *S) { 2464 // Check implicitly captured variables. 2465 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2466 return; 2467 for (const CapturedStmt::Capture &Cap : 2468 S->getInnermostCapturedStmt()->captures()) { 2469 if (!Cap.capturesVariable()) 2470 continue; 2471 VarDecl *VD = Cap.getCapturedVar(); 2472 // Do not try to map the variable if it or its sub-component was mapped 2473 // already. 2474 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2475 Stack->checkMappableExprComponentListsForDecl( 2476 VD, /*CurrentRegionOnly=*/true, 2477 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2478 OpenMPClauseKind) { return true; })) 2479 continue; 2480 DeclRefExpr *DRE = buildDeclRefExpr( 2481 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 2482 Cap.getLocation(), /*RefersToCapture=*/true); 2483 Visit(DRE); 2484 } 2485 } 2486 2487 public: 2488 void VisitDeclRefExpr(DeclRefExpr *E) { 2489 if (E->isTypeDependent() || E->isValueDependent() || 2490 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2491 return; 2492 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2493 VD = VD->getCanonicalDecl(); 2494 // Skip internally declared variables. 2495 if (VD->hasLocalStorage() && !CS->capturesVariable(VD)) 2496 return; 2497 2498 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2499 // Check if the variable has explicit DSA set and stop analysis if it so. 2500 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2501 return; 2502 2503 // Skip internally declared static variables. 2504 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2505 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2506 if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) && 2507 (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2508 return; 2509 2510 SourceLocation ELoc = E->getExprLoc(); 2511 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2512 // The default(none) clause requires that each variable that is referenced 2513 // in the construct, and does not have a predetermined data-sharing 2514 // attribute, must have its data-sharing attribute explicitly determined 2515 // by being listed in a data-sharing attribute clause. 2516 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2517 isImplicitOrExplicitTaskingRegion(DKind) && 2518 VarsWithInheritedDSA.count(VD) == 0) { 2519 VarsWithInheritedDSA[VD] = E; 2520 return; 2521 } 2522 2523 if (isOpenMPTargetExecutionDirective(DKind) && 2524 !Stack->isLoopControlVariable(VD).first) { 2525 if (!Stack->checkMappableExprComponentListsForDecl( 2526 VD, /*CurrentRegionOnly=*/true, 2527 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2528 StackComponents, 2529 OpenMPClauseKind) { 2530 // Variable is used if it has been marked as an array, array 2531 // section or the variable iself. 2532 return StackComponents.size() == 1 || 2533 std::all_of( 2534 std::next(StackComponents.rbegin()), 2535 StackComponents.rend(), 2536 [](const OMPClauseMappableExprCommon:: 2537 MappableComponent &MC) { 2538 return MC.getAssociatedDeclaration() == 2539 nullptr && 2540 (isa<OMPArraySectionExpr>( 2541 MC.getAssociatedExpression()) || 2542 isa<ArraySubscriptExpr>( 2543 MC.getAssociatedExpression())); 2544 }); 2545 })) { 2546 bool IsFirstprivate = false; 2547 // By default lambdas are captured as firstprivates. 2548 if (const auto *RD = 2549 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2550 IsFirstprivate = RD->isLambda(); 2551 IsFirstprivate = 2552 IsFirstprivate || 2553 (VD->getType().getNonReferenceType()->isScalarType() && 2554 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2555 if (IsFirstprivate) 2556 ImplicitFirstprivate.emplace_back(E); 2557 else 2558 ImplicitMap.emplace_back(E); 2559 return; 2560 } 2561 } 2562 2563 // OpenMP [2.9.3.6, Restrictions, p.2] 2564 // A list item that appears in a reduction clause of the innermost 2565 // enclosing worksharing or parallel construct may not be accessed in an 2566 // explicit task. 2567 DVar = Stack->hasInnermostDSA( 2568 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2569 [](OpenMPDirectiveKind K) { 2570 return isOpenMPParallelDirective(K) || 2571 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2572 }, 2573 /*FromParent=*/true); 2574 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2575 ErrorFound = true; 2576 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2577 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2578 return; 2579 } 2580 2581 // Define implicit data-sharing attributes for task. 2582 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2583 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2584 !Stack->isLoopControlVariable(VD).first) { 2585 ImplicitFirstprivate.push_back(E); 2586 return; 2587 } 2588 2589 // Store implicitly used globals with declare target link for parent 2590 // target. 2591 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2592 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2593 Stack->addToParentTargetRegionLinkGlobals(E); 2594 return; 2595 } 2596 } 2597 } 2598 void VisitMemberExpr(MemberExpr *E) { 2599 if (E->isTypeDependent() || E->isValueDependent() || 2600 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2601 return; 2602 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2603 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2604 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2605 if (!FD) 2606 return; 2607 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2608 // Check if the variable has explicit DSA set and stop analysis if it 2609 // so. 2610 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2611 return; 2612 2613 if (isOpenMPTargetExecutionDirective(DKind) && 2614 !Stack->isLoopControlVariable(FD).first && 2615 !Stack->checkMappableExprComponentListsForDecl( 2616 FD, /*CurrentRegionOnly=*/true, 2617 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2618 StackComponents, 2619 OpenMPClauseKind) { 2620 return isa<CXXThisExpr>( 2621 cast<MemberExpr>( 2622 StackComponents.back().getAssociatedExpression()) 2623 ->getBase() 2624 ->IgnoreParens()); 2625 })) { 2626 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2627 // A bit-field cannot appear in a map clause. 2628 // 2629 if (FD->isBitField()) 2630 return; 2631 2632 // Check to see if the member expression is referencing a class that 2633 // has already been explicitly mapped 2634 if (Stack->isClassPreviouslyMapped(TE->getType())) 2635 return; 2636 2637 ImplicitMap.emplace_back(E); 2638 return; 2639 } 2640 2641 SourceLocation ELoc = E->getExprLoc(); 2642 // OpenMP [2.9.3.6, Restrictions, p.2] 2643 // A list item that appears in a reduction clause of the innermost 2644 // enclosing worksharing or parallel construct may not be accessed in 2645 // an explicit task. 2646 DVar = Stack->hasInnermostDSA( 2647 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2648 [](OpenMPDirectiveKind K) { 2649 return isOpenMPParallelDirective(K) || 2650 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2651 }, 2652 /*FromParent=*/true); 2653 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2654 ErrorFound = true; 2655 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2656 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2657 return; 2658 } 2659 2660 // Define implicit data-sharing attributes for task. 2661 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2662 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2663 !Stack->isLoopControlVariable(FD).first) { 2664 // Check if there is a captured expression for the current field in the 2665 // region. Do not mark it as firstprivate unless there is no captured 2666 // expression. 2667 // TODO: try to make it firstprivate. 2668 if (DVar.CKind != OMPC_unknown) 2669 ImplicitFirstprivate.push_back(E); 2670 } 2671 return; 2672 } 2673 if (isOpenMPTargetExecutionDirective(DKind)) { 2674 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2675 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2676 /*NoDiagnose=*/true)) 2677 return; 2678 const auto *VD = cast<ValueDecl>( 2679 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2680 if (!Stack->checkMappableExprComponentListsForDecl( 2681 VD, /*CurrentRegionOnly=*/true, 2682 [&CurComponents]( 2683 OMPClauseMappableExprCommon::MappableExprComponentListRef 2684 StackComponents, 2685 OpenMPClauseKind) { 2686 auto CCI = CurComponents.rbegin(); 2687 auto CCE = CurComponents.rend(); 2688 for (const auto &SC : llvm::reverse(StackComponents)) { 2689 // Do both expressions have the same kind? 2690 if (CCI->getAssociatedExpression()->getStmtClass() != 2691 SC.getAssociatedExpression()->getStmtClass()) 2692 if (!(isa<OMPArraySectionExpr>( 2693 SC.getAssociatedExpression()) && 2694 isa<ArraySubscriptExpr>( 2695 CCI->getAssociatedExpression()))) 2696 return false; 2697 2698 const Decl *CCD = CCI->getAssociatedDeclaration(); 2699 const Decl *SCD = SC.getAssociatedDeclaration(); 2700 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2701 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2702 if (SCD != CCD) 2703 return false; 2704 std::advance(CCI, 1); 2705 if (CCI == CCE) 2706 break; 2707 } 2708 return true; 2709 })) { 2710 Visit(E->getBase()); 2711 } 2712 } else { 2713 Visit(E->getBase()); 2714 } 2715 } 2716 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2717 for (OMPClause *C : S->clauses()) { 2718 // Skip analysis of arguments of implicitly defined firstprivate clause 2719 // for task|target directives. 2720 // Skip analysis of arguments of implicitly defined map clause for target 2721 // directives. 2722 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2723 C->isImplicit())) { 2724 for (Stmt *CC : C->children()) { 2725 if (CC) 2726 Visit(CC); 2727 } 2728 } 2729 } 2730 // Check implicitly captured variables. 2731 VisitSubCaptures(S); 2732 } 2733 void VisitStmt(Stmt *S) { 2734 for (Stmt *C : S->children()) { 2735 if (C) { 2736 // Check implicitly captured variables in the task-based directives to 2737 // check if they must be firstprivatized. 2738 Visit(C); 2739 } 2740 } 2741 } 2742 2743 bool isErrorFound() const { return ErrorFound; } 2744 ArrayRef<Expr *> getImplicitFirstprivate() const { 2745 return ImplicitFirstprivate; 2746 } 2747 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2748 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2749 return VarsWithInheritedDSA; 2750 } 2751 2752 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2753 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 2754 // Process declare target link variables for the target directives. 2755 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 2756 for (DeclRefExpr *E : Stack->getLinkGlobals()) 2757 Visit(E); 2758 } 2759 } 2760 }; 2761 } // namespace 2762 2763 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2764 switch (DKind) { 2765 case OMPD_parallel: 2766 case OMPD_parallel_for: 2767 case OMPD_parallel_for_simd: 2768 case OMPD_parallel_sections: 2769 case OMPD_teams: 2770 case OMPD_teams_distribute: 2771 case OMPD_teams_distribute_simd: { 2772 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2773 QualType KmpInt32PtrTy = 2774 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2775 Sema::CapturedParamNameType Params[] = { 2776 std::make_pair(".global_tid.", KmpInt32PtrTy), 2777 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2778 std::make_pair(StringRef(), QualType()) // __context with shared vars 2779 }; 2780 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2781 Params); 2782 break; 2783 } 2784 case OMPD_target_teams: 2785 case OMPD_target_parallel: 2786 case OMPD_target_parallel_for: 2787 case OMPD_target_parallel_for_simd: 2788 case OMPD_target_teams_distribute: 2789 case OMPD_target_teams_distribute_simd: { 2790 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2791 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2792 QualType KmpInt32PtrTy = 2793 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2794 QualType Args[] = {VoidPtrTy}; 2795 FunctionProtoType::ExtProtoInfo EPI; 2796 EPI.Variadic = true; 2797 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2798 Sema::CapturedParamNameType Params[] = { 2799 std::make_pair(".global_tid.", KmpInt32Ty), 2800 std::make_pair(".part_id.", KmpInt32PtrTy), 2801 std::make_pair(".privates.", VoidPtrTy), 2802 std::make_pair( 2803 ".copy_fn.", 2804 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2805 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2806 std::make_pair(StringRef(), QualType()) // __context with shared vars 2807 }; 2808 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2809 Params); 2810 // Mark this captured region as inlined, because we don't use outlined 2811 // function directly. 2812 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2813 AlwaysInlineAttr::CreateImplicit( 2814 Context, AlwaysInlineAttr::Keyword_forceinline)); 2815 Sema::CapturedParamNameType ParamsTarget[] = { 2816 std::make_pair(StringRef(), QualType()) // __context with shared vars 2817 }; 2818 // Start a captured region for 'target' with no implicit parameters. 2819 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2820 ParamsTarget); 2821 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2822 std::make_pair(".global_tid.", KmpInt32PtrTy), 2823 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2824 std::make_pair(StringRef(), QualType()) // __context with shared vars 2825 }; 2826 // Start a captured region for 'teams' or 'parallel'. Both regions have 2827 // the same implicit parameters. 2828 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2829 ParamsTeamsOrParallel); 2830 break; 2831 } 2832 case OMPD_target: 2833 case OMPD_target_simd: { 2834 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2835 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2836 QualType KmpInt32PtrTy = 2837 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2838 QualType Args[] = {VoidPtrTy}; 2839 FunctionProtoType::ExtProtoInfo EPI; 2840 EPI.Variadic = true; 2841 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2842 Sema::CapturedParamNameType Params[] = { 2843 std::make_pair(".global_tid.", KmpInt32Ty), 2844 std::make_pair(".part_id.", KmpInt32PtrTy), 2845 std::make_pair(".privates.", VoidPtrTy), 2846 std::make_pair( 2847 ".copy_fn.", 2848 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2849 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2850 std::make_pair(StringRef(), QualType()) // __context with shared vars 2851 }; 2852 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2853 Params); 2854 // Mark this captured region as inlined, because we don't use outlined 2855 // function directly. 2856 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2857 AlwaysInlineAttr::CreateImplicit( 2858 Context, AlwaysInlineAttr::Keyword_forceinline)); 2859 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2860 std::make_pair(StringRef(), QualType())); 2861 break; 2862 } 2863 case OMPD_simd: 2864 case OMPD_for: 2865 case OMPD_for_simd: 2866 case OMPD_sections: 2867 case OMPD_section: 2868 case OMPD_single: 2869 case OMPD_master: 2870 case OMPD_critical: 2871 case OMPD_taskgroup: 2872 case OMPD_distribute: 2873 case OMPD_distribute_simd: 2874 case OMPD_ordered: 2875 case OMPD_atomic: 2876 case OMPD_target_data: { 2877 Sema::CapturedParamNameType Params[] = { 2878 std::make_pair(StringRef(), QualType()) // __context with shared vars 2879 }; 2880 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2881 Params); 2882 break; 2883 } 2884 case OMPD_task: { 2885 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2886 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2887 QualType KmpInt32PtrTy = 2888 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2889 QualType Args[] = {VoidPtrTy}; 2890 FunctionProtoType::ExtProtoInfo EPI; 2891 EPI.Variadic = true; 2892 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2893 Sema::CapturedParamNameType Params[] = { 2894 std::make_pair(".global_tid.", KmpInt32Ty), 2895 std::make_pair(".part_id.", KmpInt32PtrTy), 2896 std::make_pair(".privates.", VoidPtrTy), 2897 std::make_pair( 2898 ".copy_fn.", 2899 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2900 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2901 std::make_pair(StringRef(), QualType()) // __context with shared vars 2902 }; 2903 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2904 Params); 2905 // Mark this captured region as inlined, because we don't use outlined 2906 // function directly. 2907 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2908 AlwaysInlineAttr::CreateImplicit( 2909 Context, AlwaysInlineAttr::Keyword_forceinline)); 2910 break; 2911 } 2912 case OMPD_taskloop: 2913 case OMPD_taskloop_simd: { 2914 QualType KmpInt32Ty = 2915 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 2916 .withConst(); 2917 QualType KmpUInt64Ty = 2918 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 2919 .withConst(); 2920 QualType KmpInt64Ty = 2921 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 2922 .withConst(); 2923 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2924 QualType KmpInt32PtrTy = 2925 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2926 QualType Args[] = {VoidPtrTy}; 2927 FunctionProtoType::ExtProtoInfo EPI; 2928 EPI.Variadic = true; 2929 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2930 Sema::CapturedParamNameType Params[] = { 2931 std::make_pair(".global_tid.", KmpInt32Ty), 2932 std::make_pair(".part_id.", KmpInt32PtrTy), 2933 std::make_pair(".privates.", VoidPtrTy), 2934 std::make_pair( 2935 ".copy_fn.", 2936 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2937 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2938 std::make_pair(".lb.", KmpUInt64Ty), 2939 std::make_pair(".ub.", KmpUInt64Ty), 2940 std::make_pair(".st.", KmpInt64Ty), 2941 std::make_pair(".liter.", KmpInt32Ty), 2942 std::make_pair(".reductions.", VoidPtrTy), 2943 std::make_pair(StringRef(), QualType()) // __context with shared vars 2944 }; 2945 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2946 Params); 2947 // Mark this captured region as inlined, because we don't use outlined 2948 // function directly. 2949 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2950 AlwaysInlineAttr::CreateImplicit( 2951 Context, AlwaysInlineAttr::Keyword_forceinline)); 2952 break; 2953 } 2954 case OMPD_distribute_parallel_for_simd: 2955 case OMPD_distribute_parallel_for: { 2956 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2957 QualType KmpInt32PtrTy = 2958 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2959 Sema::CapturedParamNameType Params[] = { 2960 std::make_pair(".global_tid.", KmpInt32PtrTy), 2961 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2962 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2963 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2964 std::make_pair(StringRef(), QualType()) // __context with shared vars 2965 }; 2966 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2967 Params); 2968 break; 2969 } 2970 case OMPD_target_teams_distribute_parallel_for: 2971 case OMPD_target_teams_distribute_parallel_for_simd: { 2972 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2973 QualType KmpInt32PtrTy = 2974 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2975 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2976 2977 QualType Args[] = {VoidPtrTy}; 2978 FunctionProtoType::ExtProtoInfo EPI; 2979 EPI.Variadic = true; 2980 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2981 Sema::CapturedParamNameType Params[] = { 2982 std::make_pair(".global_tid.", KmpInt32Ty), 2983 std::make_pair(".part_id.", KmpInt32PtrTy), 2984 std::make_pair(".privates.", VoidPtrTy), 2985 std::make_pair( 2986 ".copy_fn.", 2987 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2988 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2989 std::make_pair(StringRef(), QualType()) // __context with shared vars 2990 }; 2991 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2992 Params); 2993 // Mark this captured region as inlined, because we don't use outlined 2994 // function directly. 2995 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2996 AlwaysInlineAttr::CreateImplicit( 2997 Context, AlwaysInlineAttr::Keyword_forceinline)); 2998 Sema::CapturedParamNameType ParamsTarget[] = { 2999 std::make_pair(StringRef(), QualType()) // __context with shared vars 3000 }; 3001 // Start a captured region for 'target' with no implicit parameters. 3002 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3003 ParamsTarget); 3004 3005 Sema::CapturedParamNameType ParamsTeams[] = { 3006 std::make_pair(".global_tid.", KmpInt32PtrTy), 3007 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3008 std::make_pair(StringRef(), QualType()) // __context with shared vars 3009 }; 3010 // Start a captured region for 'target' with no implicit parameters. 3011 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3012 ParamsTeams); 3013 3014 Sema::CapturedParamNameType ParamsParallel[] = { 3015 std::make_pair(".global_tid.", KmpInt32PtrTy), 3016 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3017 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3018 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3019 std::make_pair(StringRef(), QualType()) // __context with shared vars 3020 }; 3021 // Start a captured region for 'teams' or 'parallel'. Both regions have 3022 // the same implicit parameters. 3023 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3024 ParamsParallel); 3025 break; 3026 } 3027 3028 case OMPD_teams_distribute_parallel_for: 3029 case OMPD_teams_distribute_parallel_for_simd: { 3030 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3031 QualType KmpInt32PtrTy = 3032 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3033 3034 Sema::CapturedParamNameType ParamsTeams[] = { 3035 std::make_pair(".global_tid.", KmpInt32PtrTy), 3036 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3037 std::make_pair(StringRef(), QualType()) // __context with shared vars 3038 }; 3039 // Start a captured region for 'target' with no implicit parameters. 3040 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3041 ParamsTeams); 3042 3043 Sema::CapturedParamNameType ParamsParallel[] = { 3044 std::make_pair(".global_tid.", KmpInt32PtrTy), 3045 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3046 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3047 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3048 std::make_pair(StringRef(), QualType()) // __context with shared vars 3049 }; 3050 // Start a captured region for 'teams' or 'parallel'. Both regions have 3051 // the same implicit parameters. 3052 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3053 ParamsParallel); 3054 break; 3055 } 3056 case OMPD_target_update: 3057 case OMPD_target_enter_data: 3058 case OMPD_target_exit_data: { 3059 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3060 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3061 QualType KmpInt32PtrTy = 3062 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3063 QualType Args[] = {VoidPtrTy}; 3064 FunctionProtoType::ExtProtoInfo EPI; 3065 EPI.Variadic = true; 3066 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3067 Sema::CapturedParamNameType Params[] = { 3068 std::make_pair(".global_tid.", KmpInt32Ty), 3069 std::make_pair(".part_id.", KmpInt32PtrTy), 3070 std::make_pair(".privates.", VoidPtrTy), 3071 std::make_pair( 3072 ".copy_fn.", 3073 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3074 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3075 std::make_pair(StringRef(), QualType()) // __context with shared vars 3076 }; 3077 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3078 Params); 3079 // Mark this captured region as inlined, because we don't use outlined 3080 // function directly. 3081 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3082 AlwaysInlineAttr::CreateImplicit( 3083 Context, AlwaysInlineAttr::Keyword_forceinline)); 3084 break; 3085 } 3086 case OMPD_threadprivate: 3087 case OMPD_allocate: 3088 case OMPD_taskyield: 3089 case OMPD_barrier: 3090 case OMPD_taskwait: 3091 case OMPD_cancellation_point: 3092 case OMPD_cancel: 3093 case OMPD_flush: 3094 case OMPD_declare_reduction: 3095 case OMPD_declare_mapper: 3096 case OMPD_declare_simd: 3097 case OMPD_declare_target: 3098 case OMPD_end_declare_target: 3099 case OMPD_requires: 3100 llvm_unreachable("OpenMP Directive is not allowed"); 3101 case OMPD_unknown: 3102 llvm_unreachable("Unknown OpenMP directive"); 3103 } 3104 } 3105 3106 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3107 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3108 getOpenMPCaptureRegions(CaptureRegions, DKind); 3109 return CaptureRegions.size(); 3110 } 3111 3112 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3113 Expr *CaptureExpr, bool WithInit, 3114 bool AsExpression) { 3115 assert(CaptureExpr); 3116 ASTContext &C = S.getASTContext(); 3117 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3118 QualType Ty = Init->getType(); 3119 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3120 if (S.getLangOpts().CPlusPlus) { 3121 Ty = C.getLValueReferenceType(Ty); 3122 } else { 3123 Ty = C.getPointerType(Ty); 3124 ExprResult Res = 3125 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3126 if (!Res.isUsable()) 3127 return nullptr; 3128 Init = Res.get(); 3129 } 3130 WithInit = true; 3131 } 3132 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3133 CaptureExpr->getBeginLoc()); 3134 if (!WithInit) 3135 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3136 S.CurContext->addHiddenDecl(CED); 3137 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3138 return CED; 3139 } 3140 3141 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3142 bool WithInit) { 3143 OMPCapturedExprDecl *CD; 3144 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3145 CD = cast<OMPCapturedExprDecl>(VD); 3146 else 3147 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3148 /*AsExpression=*/false); 3149 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3150 CaptureExpr->getExprLoc()); 3151 } 3152 3153 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3154 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3155 if (!Ref) { 3156 OMPCapturedExprDecl *CD = buildCaptureDecl( 3157 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3158 /*WithInit=*/true, /*AsExpression=*/true); 3159 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3160 CaptureExpr->getExprLoc()); 3161 } 3162 ExprResult Res = Ref; 3163 if (!S.getLangOpts().CPlusPlus && 3164 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3165 Ref->getType()->isPointerType()) { 3166 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3167 if (!Res.isUsable()) 3168 return ExprError(); 3169 } 3170 return S.DefaultLvalueConversion(Res.get()); 3171 } 3172 3173 namespace { 3174 // OpenMP directives parsed in this section are represented as a 3175 // CapturedStatement with an associated statement. If a syntax error 3176 // is detected during the parsing of the associated statement, the 3177 // compiler must abort processing and close the CapturedStatement. 3178 // 3179 // Combined directives such as 'target parallel' have more than one 3180 // nested CapturedStatements. This RAII ensures that we unwind out 3181 // of all the nested CapturedStatements when an error is found. 3182 class CaptureRegionUnwinderRAII { 3183 private: 3184 Sema &S; 3185 bool &ErrorFound; 3186 OpenMPDirectiveKind DKind = OMPD_unknown; 3187 3188 public: 3189 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3190 OpenMPDirectiveKind DKind) 3191 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3192 ~CaptureRegionUnwinderRAII() { 3193 if (ErrorFound) { 3194 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3195 while (--ThisCaptureLevel >= 0) 3196 S.ActOnCapturedRegionError(); 3197 } 3198 } 3199 }; 3200 } // namespace 3201 3202 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3203 ArrayRef<OMPClause *> Clauses) { 3204 bool ErrorFound = false; 3205 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3206 *this, ErrorFound, DSAStack->getCurrentDirective()); 3207 if (!S.isUsable()) { 3208 ErrorFound = true; 3209 return StmtError(); 3210 } 3211 3212 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3213 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3214 OMPOrderedClause *OC = nullptr; 3215 OMPScheduleClause *SC = nullptr; 3216 SmallVector<const OMPLinearClause *, 4> LCs; 3217 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3218 // This is required for proper codegen. 3219 for (OMPClause *Clause : Clauses) { 3220 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3221 Clause->getClauseKind() == OMPC_in_reduction) { 3222 // Capture taskgroup task_reduction descriptors inside the tasking regions 3223 // with the corresponding in_reduction items. 3224 auto *IRC = cast<OMPInReductionClause>(Clause); 3225 for (Expr *E : IRC->taskgroup_descriptors()) 3226 if (E) 3227 MarkDeclarationsReferencedInExpr(E); 3228 } 3229 if (isOpenMPPrivate(Clause->getClauseKind()) || 3230 Clause->getClauseKind() == OMPC_copyprivate || 3231 (getLangOpts().OpenMPUseTLS && 3232 getASTContext().getTargetInfo().isTLSSupported() && 3233 Clause->getClauseKind() == OMPC_copyin)) { 3234 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3235 // Mark all variables in private list clauses as used in inner region. 3236 for (Stmt *VarRef : Clause->children()) { 3237 if (auto *E = cast_or_null<Expr>(VarRef)) { 3238 MarkDeclarationsReferencedInExpr(E); 3239 } 3240 } 3241 DSAStack->setForceVarCapturing(/*V=*/false); 3242 } else if (CaptureRegions.size() > 1 || 3243 CaptureRegions.back() != OMPD_unknown) { 3244 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3245 PICs.push_back(C); 3246 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3247 if (Expr *E = C->getPostUpdateExpr()) 3248 MarkDeclarationsReferencedInExpr(E); 3249 } 3250 } 3251 if (Clause->getClauseKind() == OMPC_schedule) 3252 SC = cast<OMPScheduleClause>(Clause); 3253 else if (Clause->getClauseKind() == OMPC_ordered) 3254 OC = cast<OMPOrderedClause>(Clause); 3255 else if (Clause->getClauseKind() == OMPC_linear) 3256 LCs.push_back(cast<OMPLinearClause>(Clause)); 3257 } 3258 // OpenMP, 2.7.1 Loop Construct, Restrictions 3259 // The nonmonotonic modifier cannot be specified if an ordered clause is 3260 // specified. 3261 if (SC && 3262 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3263 SC->getSecondScheduleModifier() == 3264 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3265 OC) { 3266 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3267 ? SC->getFirstScheduleModifierLoc() 3268 : SC->getSecondScheduleModifierLoc(), 3269 diag::err_omp_schedule_nonmonotonic_ordered) 3270 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3271 ErrorFound = true; 3272 } 3273 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3274 for (const OMPLinearClause *C : LCs) { 3275 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3276 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3277 } 3278 ErrorFound = true; 3279 } 3280 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3281 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3282 OC->getNumForLoops()) { 3283 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3284 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3285 ErrorFound = true; 3286 } 3287 if (ErrorFound) { 3288 return StmtError(); 3289 } 3290 StmtResult SR = S; 3291 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3292 // Mark all variables in private list clauses as used in inner region. 3293 // Required for proper codegen of combined directives. 3294 // TODO: add processing for other clauses. 3295 if (ThisCaptureRegion != OMPD_unknown) { 3296 for (const clang::OMPClauseWithPreInit *C : PICs) { 3297 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3298 // Find the particular capture region for the clause if the 3299 // directive is a combined one with multiple capture regions. 3300 // If the directive is not a combined one, the capture region 3301 // associated with the clause is OMPD_unknown and is generated 3302 // only once. 3303 if (CaptureRegion == ThisCaptureRegion || 3304 CaptureRegion == OMPD_unknown) { 3305 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3306 for (Decl *D : DS->decls()) 3307 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3308 } 3309 } 3310 } 3311 } 3312 SR = ActOnCapturedRegionEnd(SR.get()); 3313 } 3314 return SR; 3315 } 3316 3317 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3318 OpenMPDirectiveKind CancelRegion, 3319 SourceLocation StartLoc) { 3320 // CancelRegion is only needed for cancel and cancellation_point. 3321 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3322 return false; 3323 3324 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3325 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3326 return false; 3327 3328 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3329 << getOpenMPDirectiveName(CancelRegion); 3330 return true; 3331 } 3332 3333 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3334 OpenMPDirectiveKind CurrentRegion, 3335 const DeclarationNameInfo &CurrentName, 3336 OpenMPDirectiveKind CancelRegion, 3337 SourceLocation StartLoc) { 3338 if (Stack->getCurScope()) { 3339 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3340 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3341 bool NestingProhibited = false; 3342 bool CloseNesting = true; 3343 bool OrphanSeen = false; 3344 enum { 3345 NoRecommend, 3346 ShouldBeInParallelRegion, 3347 ShouldBeInOrderedRegion, 3348 ShouldBeInTargetRegion, 3349 ShouldBeInTeamsRegion 3350 } Recommend = NoRecommend; 3351 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3352 // OpenMP [2.16, Nesting of Regions] 3353 // OpenMP constructs may not be nested inside a simd region. 3354 // OpenMP [2.8.1,simd Construct, Restrictions] 3355 // An ordered construct with the simd clause is the only OpenMP 3356 // construct that can appear in the simd region. 3357 // Allowing a SIMD construct nested in another SIMD construct is an 3358 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3359 // message. 3360 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3361 ? diag::err_omp_prohibited_region_simd 3362 : diag::warn_omp_nesting_simd); 3363 return CurrentRegion != OMPD_simd; 3364 } 3365 if (ParentRegion == OMPD_atomic) { 3366 // OpenMP [2.16, Nesting of Regions] 3367 // OpenMP constructs may not be nested inside an atomic region. 3368 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3369 return true; 3370 } 3371 if (CurrentRegion == OMPD_section) { 3372 // OpenMP [2.7.2, sections Construct, Restrictions] 3373 // Orphaned section directives are prohibited. That is, the section 3374 // directives must appear within the sections construct and must not be 3375 // encountered elsewhere in the sections region. 3376 if (ParentRegion != OMPD_sections && 3377 ParentRegion != OMPD_parallel_sections) { 3378 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3379 << (ParentRegion != OMPD_unknown) 3380 << getOpenMPDirectiveName(ParentRegion); 3381 return true; 3382 } 3383 return false; 3384 } 3385 // Allow some constructs (except teams and cancellation constructs) to be 3386 // orphaned (they could be used in functions, called from OpenMP regions 3387 // with the required preconditions). 3388 if (ParentRegion == OMPD_unknown && 3389 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3390 CurrentRegion != OMPD_cancellation_point && 3391 CurrentRegion != OMPD_cancel) 3392 return false; 3393 if (CurrentRegion == OMPD_cancellation_point || 3394 CurrentRegion == OMPD_cancel) { 3395 // OpenMP [2.16, Nesting of Regions] 3396 // A cancellation point construct for which construct-type-clause is 3397 // taskgroup must be nested inside a task construct. A cancellation 3398 // point construct for which construct-type-clause is not taskgroup must 3399 // be closely nested inside an OpenMP construct that matches the type 3400 // specified in construct-type-clause. 3401 // A cancel construct for which construct-type-clause is taskgroup must be 3402 // nested inside a task construct. A cancel construct for which 3403 // construct-type-clause is not taskgroup must be closely nested inside an 3404 // OpenMP construct that matches the type specified in 3405 // construct-type-clause. 3406 NestingProhibited = 3407 !((CancelRegion == OMPD_parallel && 3408 (ParentRegion == OMPD_parallel || 3409 ParentRegion == OMPD_target_parallel)) || 3410 (CancelRegion == OMPD_for && 3411 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3412 ParentRegion == OMPD_target_parallel_for || 3413 ParentRegion == OMPD_distribute_parallel_for || 3414 ParentRegion == OMPD_teams_distribute_parallel_for || 3415 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3416 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3417 (CancelRegion == OMPD_sections && 3418 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3419 ParentRegion == OMPD_parallel_sections))); 3420 OrphanSeen = ParentRegion == OMPD_unknown; 3421 } else if (CurrentRegion == OMPD_master) { 3422 // OpenMP [2.16, Nesting of Regions] 3423 // A master region may not be closely nested inside a worksharing, 3424 // atomic, or explicit task region. 3425 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3426 isOpenMPTaskingDirective(ParentRegion); 3427 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3428 // OpenMP [2.16, Nesting of Regions] 3429 // A critical region may not be nested (closely or otherwise) inside a 3430 // critical region with the same name. Note that this restriction is not 3431 // sufficient to prevent deadlock. 3432 SourceLocation PreviousCriticalLoc; 3433 bool DeadLock = Stack->hasDirective( 3434 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3435 const DeclarationNameInfo &DNI, 3436 SourceLocation Loc) { 3437 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3438 PreviousCriticalLoc = Loc; 3439 return true; 3440 } 3441 return false; 3442 }, 3443 false /* skip top directive */); 3444 if (DeadLock) { 3445 SemaRef.Diag(StartLoc, 3446 diag::err_omp_prohibited_region_critical_same_name) 3447 << CurrentName.getName(); 3448 if (PreviousCriticalLoc.isValid()) 3449 SemaRef.Diag(PreviousCriticalLoc, 3450 diag::note_omp_previous_critical_region); 3451 return true; 3452 } 3453 } else if (CurrentRegion == OMPD_barrier) { 3454 // OpenMP [2.16, Nesting of Regions] 3455 // A barrier region may not be closely nested inside a worksharing, 3456 // explicit task, critical, ordered, atomic, or master region. 3457 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3458 isOpenMPTaskingDirective(ParentRegion) || 3459 ParentRegion == OMPD_master || 3460 ParentRegion == OMPD_critical || 3461 ParentRegion == OMPD_ordered; 3462 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3463 !isOpenMPParallelDirective(CurrentRegion) && 3464 !isOpenMPTeamsDirective(CurrentRegion)) { 3465 // OpenMP [2.16, Nesting of Regions] 3466 // A worksharing region may not be closely nested inside a worksharing, 3467 // explicit task, critical, ordered, atomic, or master region. 3468 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3469 isOpenMPTaskingDirective(ParentRegion) || 3470 ParentRegion == OMPD_master || 3471 ParentRegion == OMPD_critical || 3472 ParentRegion == OMPD_ordered; 3473 Recommend = ShouldBeInParallelRegion; 3474 } else if (CurrentRegion == OMPD_ordered) { 3475 // OpenMP [2.16, Nesting of Regions] 3476 // An ordered region may not be closely nested inside a critical, 3477 // atomic, or explicit task region. 3478 // An ordered region must be closely nested inside a loop region (or 3479 // parallel loop region) with an ordered clause. 3480 // OpenMP [2.8.1,simd Construct, Restrictions] 3481 // An ordered construct with the simd clause is the only OpenMP construct 3482 // that can appear in the simd region. 3483 NestingProhibited = ParentRegion == OMPD_critical || 3484 isOpenMPTaskingDirective(ParentRegion) || 3485 !(isOpenMPSimdDirective(ParentRegion) || 3486 Stack->isParentOrderedRegion()); 3487 Recommend = ShouldBeInOrderedRegion; 3488 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3489 // OpenMP [2.16, Nesting of Regions] 3490 // If specified, a teams construct must be contained within a target 3491 // construct. 3492 NestingProhibited = ParentRegion != OMPD_target; 3493 OrphanSeen = ParentRegion == OMPD_unknown; 3494 Recommend = ShouldBeInTargetRegion; 3495 } 3496 if (!NestingProhibited && 3497 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3498 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3499 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3500 // OpenMP [2.16, Nesting of Regions] 3501 // distribute, parallel, parallel sections, parallel workshare, and the 3502 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3503 // constructs that can be closely nested in the teams region. 3504 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3505 !isOpenMPDistributeDirective(CurrentRegion); 3506 Recommend = ShouldBeInParallelRegion; 3507 } 3508 if (!NestingProhibited && 3509 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3510 // OpenMP 4.5 [2.17 Nesting of Regions] 3511 // The region associated with the distribute construct must be strictly 3512 // nested inside a teams region 3513 NestingProhibited = 3514 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3515 Recommend = ShouldBeInTeamsRegion; 3516 } 3517 if (!NestingProhibited && 3518 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3519 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3520 // OpenMP 4.5 [2.17 Nesting of Regions] 3521 // If a target, target update, target data, target enter data, or 3522 // target exit data construct is encountered during execution of a 3523 // target region, the behavior is unspecified. 3524 NestingProhibited = Stack->hasDirective( 3525 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3526 SourceLocation) { 3527 if (isOpenMPTargetExecutionDirective(K)) { 3528 OffendingRegion = K; 3529 return true; 3530 } 3531 return false; 3532 }, 3533 false /* don't skip top directive */); 3534 CloseNesting = false; 3535 } 3536 if (NestingProhibited) { 3537 if (OrphanSeen) { 3538 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3539 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3540 } else { 3541 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3542 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3543 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3544 } 3545 return true; 3546 } 3547 } 3548 return false; 3549 } 3550 3551 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3552 ArrayRef<OMPClause *> Clauses, 3553 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3554 bool ErrorFound = false; 3555 unsigned NamedModifiersNumber = 0; 3556 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3557 OMPD_unknown + 1); 3558 SmallVector<SourceLocation, 4> NameModifierLoc; 3559 for (const OMPClause *C : Clauses) { 3560 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3561 // At most one if clause without a directive-name-modifier can appear on 3562 // the directive. 3563 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3564 if (FoundNameModifiers[CurNM]) { 3565 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3566 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3567 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3568 ErrorFound = true; 3569 } else if (CurNM != OMPD_unknown) { 3570 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3571 ++NamedModifiersNumber; 3572 } 3573 FoundNameModifiers[CurNM] = IC; 3574 if (CurNM == OMPD_unknown) 3575 continue; 3576 // Check if the specified name modifier is allowed for the current 3577 // directive. 3578 // At most one if clause with the particular directive-name-modifier can 3579 // appear on the directive. 3580 bool MatchFound = false; 3581 for (auto NM : AllowedNameModifiers) { 3582 if (CurNM == NM) { 3583 MatchFound = true; 3584 break; 3585 } 3586 } 3587 if (!MatchFound) { 3588 S.Diag(IC->getNameModifierLoc(), 3589 diag::err_omp_wrong_if_directive_name_modifier) 3590 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3591 ErrorFound = true; 3592 } 3593 } 3594 } 3595 // If any if clause on the directive includes a directive-name-modifier then 3596 // all if clauses on the directive must include a directive-name-modifier. 3597 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3598 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3599 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3600 diag::err_omp_no_more_if_clause); 3601 } else { 3602 std::string Values; 3603 std::string Sep(", "); 3604 unsigned AllowedCnt = 0; 3605 unsigned TotalAllowedNum = 3606 AllowedNameModifiers.size() - NamedModifiersNumber; 3607 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3608 ++Cnt) { 3609 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3610 if (!FoundNameModifiers[NM]) { 3611 Values += "'"; 3612 Values += getOpenMPDirectiveName(NM); 3613 Values += "'"; 3614 if (AllowedCnt + 2 == TotalAllowedNum) 3615 Values += " or "; 3616 else if (AllowedCnt + 1 != TotalAllowedNum) 3617 Values += Sep; 3618 ++AllowedCnt; 3619 } 3620 } 3621 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3622 diag::err_omp_unnamed_if_clause) 3623 << (TotalAllowedNum > 1) << Values; 3624 } 3625 for (SourceLocation Loc : NameModifierLoc) { 3626 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3627 } 3628 ErrorFound = true; 3629 } 3630 return ErrorFound; 3631 } 3632 3633 StmtResult Sema::ActOnOpenMPExecutableDirective( 3634 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3635 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3636 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3637 StmtResult Res = StmtError(); 3638 // First check CancelRegion which is then used in checkNestingOfRegions. 3639 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 3640 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 3641 StartLoc)) 3642 return StmtError(); 3643 3644 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 3645 VarsWithInheritedDSAType VarsWithInheritedDSA; 3646 bool ErrorFound = false; 3647 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 3648 if (AStmt && !CurContext->isDependentContext()) { 3649 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3650 3651 // Check default data sharing attributes for referenced variables. 3652 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 3653 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 3654 Stmt *S = AStmt; 3655 while (--ThisCaptureLevel >= 0) 3656 S = cast<CapturedStmt>(S)->getCapturedStmt(); 3657 DSAChecker.Visit(S); 3658 if (DSAChecker.isErrorFound()) 3659 return StmtError(); 3660 // Generate list of implicitly defined firstprivate variables. 3661 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 3662 3663 SmallVector<Expr *, 4> ImplicitFirstprivates( 3664 DSAChecker.getImplicitFirstprivate().begin(), 3665 DSAChecker.getImplicitFirstprivate().end()); 3666 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 3667 DSAChecker.getImplicitMap().end()); 3668 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 3669 for (OMPClause *C : Clauses) { 3670 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 3671 for (Expr *E : IRC->taskgroup_descriptors()) 3672 if (E) 3673 ImplicitFirstprivates.emplace_back(E); 3674 } 3675 } 3676 if (!ImplicitFirstprivates.empty()) { 3677 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 3678 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 3679 SourceLocation())) { 3680 ClausesWithImplicit.push_back(Implicit); 3681 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 3682 ImplicitFirstprivates.size(); 3683 } else { 3684 ErrorFound = true; 3685 } 3686 } 3687 if (!ImplicitMaps.empty()) { 3688 CXXScopeSpec MapperIdScopeSpec; 3689 DeclarationNameInfo MapperId; 3690 if (OMPClause *Implicit = ActOnOpenMPMapClause( 3691 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 3692 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 3693 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 3694 ClausesWithImplicit.emplace_back(Implicit); 3695 ErrorFound |= 3696 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 3697 } else { 3698 ErrorFound = true; 3699 } 3700 } 3701 } 3702 3703 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 3704 switch (Kind) { 3705 case OMPD_parallel: 3706 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 3707 EndLoc); 3708 AllowedNameModifiers.push_back(OMPD_parallel); 3709 break; 3710 case OMPD_simd: 3711 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3712 VarsWithInheritedDSA); 3713 break; 3714 case OMPD_for: 3715 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3716 VarsWithInheritedDSA); 3717 break; 3718 case OMPD_for_simd: 3719 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3720 EndLoc, VarsWithInheritedDSA); 3721 break; 3722 case OMPD_sections: 3723 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 3724 EndLoc); 3725 break; 3726 case OMPD_section: 3727 assert(ClausesWithImplicit.empty() && 3728 "No clauses are allowed for 'omp section' directive"); 3729 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 3730 break; 3731 case OMPD_single: 3732 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 3733 EndLoc); 3734 break; 3735 case OMPD_master: 3736 assert(ClausesWithImplicit.empty() && 3737 "No clauses are allowed for 'omp master' directive"); 3738 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 3739 break; 3740 case OMPD_critical: 3741 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 3742 StartLoc, EndLoc); 3743 break; 3744 case OMPD_parallel_for: 3745 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 3746 EndLoc, VarsWithInheritedDSA); 3747 AllowedNameModifiers.push_back(OMPD_parallel); 3748 break; 3749 case OMPD_parallel_for_simd: 3750 Res = ActOnOpenMPParallelForSimdDirective( 3751 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3752 AllowedNameModifiers.push_back(OMPD_parallel); 3753 break; 3754 case OMPD_parallel_sections: 3755 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 3756 StartLoc, EndLoc); 3757 AllowedNameModifiers.push_back(OMPD_parallel); 3758 break; 3759 case OMPD_task: 3760 Res = 3761 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3762 AllowedNameModifiers.push_back(OMPD_task); 3763 break; 3764 case OMPD_taskyield: 3765 assert(ClausesWithImplicit.empty() && 3766 "No clauses are allowed for 'omp taskyield' directive"); 3767 assert(AStmt == nullptr && 3768 "No associated statement allowed for 'omp taskyield' directive"); 3769 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 3770 break; 3771 case OMPD_barrier: 3772 assert(ClausesWithImplicit.empty() && 3773 "No clauses are allowed for 'omp barrier' directive"); 3774 assert(AStmt == nullptr && 3775 "No associated statement allowed for 'omp barrier' directive"); 3776 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 3777 break; 3778 case OMPD_taskwait: 3779 assert(ClausesWithImplicit.empty() && 3780 "No clauses are allowed for 'omp taskwait' directive"); 3781 assert(AStmt == nullptr && 3782 "No associated statement allowed for 'omp taskwait' directive"); 3783 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 3784 break; 3785 case OMPD_taskgroup: 3786 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 3787 EndLoc); 3788 break; 3789 case OMPD_flush: 3790 assert(AStmt == nullptr && 3791 "No associated statement allowed for 'omp flush' directive"); 3792 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 3793 break; 3794 case OMPD_ordered: 3795 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 3796 EndLoc); 3797 break; 3798 case OMPD_atomic: 3799 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 3800 EndLoc); 3801 break; 3802 case OMPD_teams: 3803 Res = 3804 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3805 break; 3806 case OMPD_target: 3807 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 3808 EndLoc); 3809 AllowedNameModifiers.push_back(OMPD_target); 3810 break; 3811 case OMPD_target_parallel: 3812 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 3813 StartLoc, EndLoc); 3814 AllowedNameModifiers.push_back(OMPD_target); 3815 AllowedNameModifiers.push_back(OMPD_parallel); 3816 break; 3817 case OMPD_target_parallel_for: 3818 Res = ActOnOpenMPTargetParallelForDirective( 3819 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3820 AllowedNameModifiers.push_back(OMPD_target); 3821 AllowedNameModifiers.push_back(OMPD_parallel); 3822 break; 3823 case OMPD_cancellation_point: 3824 assert(ClausesWithImplicit.empty() && 3825 "No clauses are allowed for 'omp cancellation point' directive"); 3826 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 3827 "cancellation point' directive"); 3828 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 3829 break; 3830 case OMPD_cancel: 3831 assert(AStmt == nullptr && 3832 "No associated statement allowed for 'omp cancel' directive"); 3833 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 3834 CancelRegion); 3835 AllowedNameModifiers.push_back(OMPD_cancel); 3836 break; 3837 case OMPD_target_data: 3838 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 3839 EndLoc); 3840 AllowedNameModifiers.push_back(OMPD_target_data); 3841 break; 3842 case OMPD_target_enter_data: 3843 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 3844 EndLoc, AStmt); 3845 AllowedNameModifiers.push_back(OMPD_target_enter_data); 3846 break; 3847 case OMPD_target_exit_data: 3848 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 3849 EndLoc, AStmt); 3850 AllowedNameModifiers.push_back(OMPD_target_exit_data); 3851 break; 3852 case OMPD_taskloop: 3853 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 3854 EndLoc, VarsWithInheritedDSA); 3855 AllowedNameModifiers.push_back(OMPD_taskloop); 3856 break; 3857 case OMPD_taskloop_simd: 3858 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3859 EndLoc, VarsWithInheritedDSA); 3860 AllowedNameModifiers.push_back(OMPD_taskloop); 3861 break; 3862 case OMPD_distribute: 3863 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 3864 EndLoc, VarsWithInheritedDSA); 3865 break; 3866 case OMPD_target_update: 3867 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 3868 EndLoc, AStmt); 3869 AllowedNameModifiers.push_back(OMPD_target_update); 3870 break; 3871 case OMPD_distribute_parallel_for: 3872 Res = ActOnOpenMPDistributeParallelForDirective( 3873 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3874 AllowedNameModifiers.push_back(OMPD_parallel); 3875 break; 3876 case OMPD_distribute_parallel_for_simd: 3877 Res = ActOnOpenMPDistributeParallelForSimdDirective( 3878 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3879 AllowedNameModifiers.push_back(OMPD_parallel); 3880 break; 3881 case OMPD_distribute_simd: 3882 Res = ActOnOpenMPDistributeSimdDirective( 3883 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3884 break; 3885 case OMPD_target_parallel_for_simd: 3886 Res = ActOnOpenMPTargetParallelForSimdDirective( 3887 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3888 AllowedNameModifiers.push_back(OMPD_target); 3889 AllowedNameModifiers.push_back(OMPD_parallel); 3890 break; 3891 case OMPD_target_simd: 3892 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3893 EndLoc, VarsWithInheritedDSA); 3894 AllowedNameModifiers.push_back(OMPD_target); 3895 break; 3896 case OMPD_teams_distribute: 3897 Res = ActOnOpenMPTeamsDistributeDirective( 3898 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3899 break; 3900 case OMPD_teams_distribute_simd: 3901 Res = ActOnOpenMPTeamsDistributeSimdDirective( 3902 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3903 break; 3904 case OMPD_teams_distribute_parallel_for_simd: 3905 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 3906 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3907 AllowedNameModifiers.push_back(OMPD_parallel); 3908 break; 3909 case OMPD_teams_distribute_parallel_for: 3910 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 3911 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3912 AllowedNameModifiers.push_back(OMPD_parallel); 3913 break; 3914 case OMPD_target_teams: 3915 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 3916 EndLoc); 3917 AllowedNameModifiers.push_back(OMPD_target); 3918 break; 3919 case OMPD_target_teams_distribute: 3920 Res = ActOnOpenMPTargetTeamsDistributeDirective( 3921 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3922 AllowedNameModifiers.push_back(OMPD_target); 3923 break; 3924 case OMPD_target_teams_distribute_parallel_for: 3925 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 3926 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3927 AllowedNameModifiers.push_back(OMPD_target); 3928 AllowedNameModifiers.push_back(OMPD_parallel); 3929 break; 3930 case OMPD_target_teams_distribute_parallel_for_simd: 3931 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 3932 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3933 AllowedNameModifiers.push_back(OMPD_target); 3934 AllowedNameModifiers.push_back(OMPD_parallel); 3935 break; 3936 case OMPD_target_teams_distribute_simd: 3937 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 3938 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3939 AllowedNameModifiers.push_back(OMPD_target); 3940 break; 3941 case OMPD_declare_target: 3942 case OMPD_end_declare_target: 3943 case OMPD_threadprivate: 3944 case OMPD_allocate: 3945 case OMPD_declare_reduction: 3946 case OMPD_declare_mapper: 3947 case OMPD_declare_simd: 3948 case OMPD_requires: 3949 llvm_unreachable("OpenMP Directive is not allowed"); 3950 case OMPD_unknown: 3951 llvm_unreachable("Unknown OpenMP directive"); 3952 } 3953 3954 ErrorFound = Res.isInvalid() || ErrorFound; 3955 3956 for (const auto &P : VarsWithInheritedDSA) { 3957 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 3958 << P.first << P.second->getSourceRange(); 3959 } 3960 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 3961 3962 if (!AllowedNameModifiers.empty()) 3963 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 3964 ErrorFound; 3965 3966 if (ErrorFound) 3967 return StmtError(); 3968 3969 if (!(Res.getAs<OMPExecutableDirective>()->isStandaloneDirective())) { 3970 Res.getAs<OMPExecutableDirective>() 3971 ->getStructuredBlock() 3972 ->setIsOMPStructuredBlock(true); 3973 } 3974 3975 return Res; 3976 } 3977 3978 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 3979 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 3980 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 3981 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 3982 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 3983 assert(Aligneds.size() == Alignments.size()); 3984 assert(Linears.size() == LinModifiers.size()); 3985 assert(Linears.size() == Steps.size()); 3986 if (!DG || DG.get().isNull()) 3987 return DeclGroupPtrTy(); 3988 3989 if (!DG.get().isSingleDecl()) { 3990 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 3991 return DG; 3992 } 3993 Decl *ADecl = DG.get().getSingleDecl(); 3994 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 3995 ADecl = FTD->getTemplatedDecl(); 3996 3997 auto *FD = dyn_cast<FunctionDecl>(ADecl); 3998 if (!FD) { 3999 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 4000 return DeclGroupPtrTy(); 4001 } 4002 4003 // OpenMP [2.8.2, declare simd construct, Description] 4004 // The parameter of the simdlen clause must be a constant positive integer 4005 // expression. 4006 ExprResult SL; 4007 if (Simdlen) 4008 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 4009 // OpenMP [2.8.2, declare simd construct, Description] 4010 // The special this pointer can be used as if was one of the arguments to the 4011 // function in any of the linear, aligned, or uniform clauses. 4012 // The uniform clause declares one or more arguments to have an invariant 4013 // value for all concurrent invocations of the function in the execution of a 4014 // single SIMD loop. 4015 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 4016 const Expr *UniformedLinearThis = nullptr; 4017 for (const Expr *E : Uniforms) { 4018 E = E->IgnoreParenImpCasts(); 4019 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4020 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 4021 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4022 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4023 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 4024 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 4025 continue; 4026 } 4027 if (isa<CXXThisExpr>(E)) { 4028 UniformedLinearThis = E; 4029 continue; 4030 } 4031 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4032 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4033 } 4034 // OpenMP [2.8.2, declare simd construct, Description] 4035 // The aligned clause declares that the object to which each list item points 4036 // is aligned to the number of bytes expressed in the optional parameter of 4037 // the aligned clause. 4038 // The special this pointer can be used as if was one of the arguments to the 4039 // function in any of the linear, aligned, or uniform clauses. 4040 // The type of list items appearing in the aligned clause must be array, 4041 // pointer, reference to array, or reference to pointer. 4042 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 4043 const Expr *AlignedThis = nullptr; 4044 for (const Expr *E : Aligneds) { 4045 E = E->IgnoreParenImpCasts(); 4046 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4047 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4048 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4049 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4050 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4051 ->getCanonicalDecl() == CanonPVD) { 4052 // OpenMP [2.8.1, simd construct, Restrictions] 4053 // A list-item cannot appear in more than one aligned clause. 4054 if (AlignedArgs.count(CanonPVD) > 0) { 4055 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4056 << 1 << E->getSourceRange(); 4057 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4058 diag::note_omp_explicit_dsa) 4059 << getOpenMPClauseName(OMPC_aligned); 4060 continue; 4061 } 4062 AlignedArgs[CanonPVD] = E; 4063 QualType QTy = PVD->getType() 4064 .getNonReferenceType() 4065 .getUnqualifiedType() 4066 .getCanonicalType(); 4067 const Type *Ty = QTy.getTypePtrOrNull(); 4068 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4069 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4070 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4071 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4072 } 4073 continue; 4074 } 4075 } 4076 if (isa<CXXThisExpr>(E)) { 4077 if (AlignedThis) { 4078 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4079 << 2 << E->getSourceRange(); 4080 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4081 << getOpenMPClauseName(OMPC_aligned); 4082 } 4083 AlignedThis = E; 4084 continue; 4085 } 4086 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4087 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4088 } 4089 // The optional parameter of the aligned clause, alignment, must be a constant 4090 // positive integer expression. If no optional parameter is specified, 4091 // implementation-defined default alignments for SIMD instructions on the 4092 // target platforms are assumed. 4093 SmallVector<const Expr *, 4> NewAligns; 4094 for (Expr *E : Alignments) { 4095 ExprResult Align; 4096 if (E) 4097 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4098 NewAligns.push_back(Align.get()); 4099 } 4100 // OpenMP [2.8.2, declare simd construct, Description] 4101 // The linear clause declares one or more list items to be private to a SIMD 4102 // lane and to have a linear relationship with respect to the iteration space 4103 // of a loop. 4104 // The special this pointer can be used as if was one of the arguments to the 4105 // function in any of the linear, aligned, or uniform clauses. 4106 // When a linear-step expression is specified in a linear clause it must be 4107 // either a constant integer expression or an integer-typed parameter that is 4108 // specified in a uniform clause on the directive. 4109 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4110 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4111 auto MI = LinModifiers.begin(); 4112 for (const Expr *E : Linears) { 4113 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4114 ++MI; 4115 E = E->IgnoreParenImpCasts(); 4116 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4117 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4118 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4119 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4120 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4121 ->getCanonicalDecl() == CanonPVD) { 4122 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4123 // A list-item cannot appear in more than one linear clause. 4124 if (LinearArgs.count(CanonPVD) > 0) { 4125 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4126 << getOpenMPClauseName(OMPC_linear) 4127 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4128 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4129 diag::note_omp_explicit_dsa) 4130 << getOpenMPClauseName(OMPC_linear); 4131 continue; 4132 } 4133 // Each argument can appear in at most one uniform or linear clause. 4134 if (UniformedArgs.count(CanonPVD) > 0) { 4135 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4136 << getOpenMPClauseName(OMPC_linear) 4137 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4138 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4139 diag::note_omp_explicit_dsa) 4140 << getOpenMPClauseName(OMPC_uniform); 4141 continue; 4142 } 4143 LinearArgs[CanonPVD] = E; 4144 if (E->isValueDependent() || E->isTypeDependent() || 4145 E->isInstantiationDependent() || 4146 E->containsUnexpandedParameterPack()) 4147 continue; 4148 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4149 PVD->getOriginalType()); 4150 continue; 4151 } 4152 } 4153 if (isa<CXXThisExpr>(E)) { 4154 if (UniformedLinearThis) { 4155 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4156 << getOpenMPClauseName(OMPC_linear) 4157 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4158 << E->getSourceRange(); 4159 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4160 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4161 : OMPC_linear); 4162 continue; 4163 } 4164 UniformedLinearThis = E; 4165 if (E->isValueDependent() || E->isTypeDependent() || 4166 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4167 continue; 4168 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4169 E->getType()); 4170 continue; 4171 } 4172 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4173 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4174 } 4175 Expr *Step = nullptr; 4176 Expr *NewStep = nullptr; 4177 SmallVector<Expr *, 4> NewSteps; 4178 for (Expr *E : Steps) { 4179 // Skip the same step expression, it was checked already. 4180 if (Step == E || !E) { 4181 NewSteps.push_back(E ? NewStep : nullptr); 4182 continue; 4183 } 4184 Step = E; 4185 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4186 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4187 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4188 if (UniformedArgs.count(CanonPVD) == 0) { 4189 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4190 << Step->getSourceRange(); 4191 } else if (E->isValueDependent() || E->isTypeDependent() || 4192 E->isInstantiationDependent() || 4193 E->containsUnexpandedParameterPack() || 4194 CanonPVD->getType()->hasIntegerRepresentation()) { 4195 NewSteps.push_back(Step); 4196 } else { 4197 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4198 << Step->getSourceRange(); 4199 } 4200 continue; 4201 } 4202 NewStep = Step; 4203 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4204 !Step->isInstantiationDependent() && 4205 !Step->containsUnexpandedParameterPack()) { 4206 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4207 .get(); 4208 if (NewStep) 4209 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4210 } 4211 NewSteps.push_back(NewStep); 4212 } 4213 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4214 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4215 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4216 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4217 const_cast<Expr **>(Linears.data()), Linears.size(), 4218 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4219 NewSteps.data(), NewSteps.size(), SR); 4220 ADecl->addAttr(NewAttr); 4221 return ConvertDeclToDeclGroup(ADecl); 4222 } 4223 4224 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4225 Stmt *AStmt, 4226 SourceLocation StartLoc, 4227 SourceLocation EndLoc) { 4228 if (!AStmt) 4229 return StmtError(); 4230 4231 auto *CS = cast<CapturedStmt>(AStmt); 4232 // 1.2.2 OpenMP Language Terminology 4233 // Structured block - An executable statement with a single entry at the 4234 // top and a single exit at the bottom. 4235 // The point of exit cannot be a branch out of the structured block. 4236 // longjmp() and throw() must not violate the entry/exit criteria. 4237 CS->getCapturedDecl()->setNothrow(); 4238 4239 setFunctionHasBranchProtectedScope(); 4240 4241 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4242 DSAStack->isCancelRegion()); 4243 } 4244 4245 namespace { 4246 /// Helper class for checking canonical form of the OpenMP loops and 4247 /// extracting iteration space of each loop in the loop nest, that will be used 4248 /// for IR generation. 4249 class OpenMPIterationSpaceChecker { 4250 /// Reference to Sema. 4251 Sema &SemaRef; 4252 /// A location for diagnostics (when there is no some better location). 4253 SourceLocation DefaultLoc; 4254 /// A location for diagnostics (when increment is not compatible). 4255 SourceLocation ConditionLoc; 4256 /// A source location for referring to loop init later. 4257 SourceRange InitSrcRange; 4258 /// A source location for referring to condition later. 4259 SourceRange ConditionSrcRange; 4260 /// A source location for referring to increment later. 4261 SourceRange IncrementSrcRange; 4262 /// Loop variable. 4263 ValueDecl *LCDecl = nullptr; 4264 /// Reference to loop variable. 4265 Expr *LCRef = nullptr; 4266 /// Lower bound (initializer for the var). 4267 Expr *LB = nullptr; 4268 /// Upper bound. 4269 Expr *UB = nullptr; 4270 /// Loop step (increment). 4271 Expr *Step = nullptr; 4272 /// This flag is true when condition is one of: 4273 /// Var < UB 4274 /// Var <= UB 4275 /// UB > Var 4276 /// UB >= Var 4277 /// This will have no value when the condition is != 4278 llvm::Optional<bool> TestIsLessOp; 4279 /// This flag is true when condition is strict ( < or > ). 4280 bool TestIsStrictOp = false; 4281 /// This flag is true when step is subtracted on each iteration. 4282 bool SubtractStep = false; 4283 4284 public: 4285 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 4286 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 4287 /// Check init-expr for canonical loop form and save loop counter 4288 /// variable - #Var and its initialization value - #LB. 4289 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 4290 /// Check test-expr for canonical form, save upper-bound (#UB), flags 4291 /// for less/greater and for strict/non-strict comparison. 4292 bool checkAndSetCond(Expr *S); 4293 /// Check incr-expr for canonical loop form and return true if it 4294 /// does not conform, otherwise save loop step (#Step). 4295 bool checkAndSetInc(Expr *S); 4296 /// Return the loop counter variable. 4297 ValueDecl *getLoopDecl() const { return LCDecl; } 4298 /// Return the reference expression to loop counter variable. 4299 Expr *getLoopDeclRefExpr() const { return LCRef; } 4300 /// Source range of the loop init. 4301 SourceRange getInitSrcRange() const { return InitSrcRange; } 4302 /// Source range of the loop condition. 4303 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 4304 /// Source range of the loop increment. 4305 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 4306 /// True if the step should be subtracted. 4307 bool shouldSubtractStep() const { return SubtractStep; } 4308 /// True, if the compare operator is strict (<, > or !=). 4309 bool isStrictTestOp() const { return TestIsStrictOp; } 4310 /// Build the expression to calculate the number of iterations. 4311 Expr *buildNumIterations( 4312 Scope *S, const bool LimitedType, 4313 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4314 /// Build the precondition expression for the loops. 4315 Expr * 4316 buildPreCond(Scope *S, Expr *Cond, 4317 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4318 /// Build reference expression to the counter be used for codegen. 4319 DeclRefExpr * 4320 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4321 DSAStackTy &DSA) const; 4322 /// Build reference expression to the private counter be used for 4323 /// codegen. 4324 Expr *buildPrivateCounterVar() const; 4325 /// Build initialization of the counter be used for codegen. 4326 Expr *buildCounterInit() const; 4327 /// Build step of the counter be used for codegen. 4328 Expr *buildCounterStep() const; 4329 /// Build loop data with counter value for depend clauses in ordered 4330 /// directives. 4331 Expr * 4332 buildOrderedLoopData(Scope *S, Expr *Counter, 4333 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4334 SourceLocation Loc, Expr *Inc = nullptr, 4335 OverloadedOperatorKind OOK = OO_Amp); 4336 /// Return true if any expression is dependent. 4337 bool dependent() const; 4338 4339 private: 4340 /// Check the right-hand side of an assignment in the increment 4341 /// expression. 4342 bool checkAndSetIncRHS(Expr *RHS); 4343 /// Helper to set loop counter variable and its initializer. 4344 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); 4345 /// Helper to set upper bound. 4346 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 4347 SourceRange SR, SourceLocation SL); 4348 /// Helper to set loop increment. 4349 bool setStep(Expr *NewStep, bool Subtract); 4350 }; 4351 4352 bool OpenMPIterationSpaceChecker::dependent() const { 4353 if (!LCDecl) { 4354 assert(!LB && !UB && !Step); 4355 return false; 4356 } 4357 return LCDecl->getType()->isDependentType() || 4358 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 4359 (Step && Step->isValueDependent()); 4360 } 4361 4362 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 4363 Expr *NewLCRefExpr, 4364 Expr *NewLB) { 4365 // State consistency checking to ensure correct usage. 4366 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 4367 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4368 if (!NewLCDecl || !NewLB) 4369 return true; 4370 LCDecl = getCanonicalDecl(NewLCDecl); 4371 LCRef = NewLCRefExpr; 4372 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 4373 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4374 if ((Ctor->isCopyOrMoveConstructor() || 4375 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4376 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4377 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 4378 LB = NewLB; 4379 return false; 4380 } 4381 4382 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 4383 llvm::Optional<bool> LessOp, 4384 bool StrictOp, SourceRange SR, 4385 SourceLocation SL) { 4386 // State consistency checking to ensure correct usage. 4387 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 4388 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4389 if (!NewUB) 4390 return true; 4391 UB = NewUB; 4392 if (LessOp) 4393 TestIsLessOp = LessOp; 4394 TestIsStrictOp = StrictOp; 4395 ConditionSrcRange = SR; 4396 ConditionLoc = SL; 4397 return false; 4398 } 4399 4400 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 4401 // State consistency checking to ensure correct usage. 4402 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 4403 if (!NewStep) 4404 return true; 4405 if (!NewStep->isValueDependent()) { 4406 // Check that the step is integer expression. 4407 SourceLocation StepLoc = NewStep->getBeginLoc(); 4408 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 4409 StepLoc, getExprAsWritten(NewStep)); 4410 if (Val.isInvalid()) 4411 return true; 4412 NewStep = Val.get(); 4413 4414 // OpenMP [2.6, Canonical Loop Form, Restrictions] 4415 // If test-expr is of form var relational-op b and relational-op is < or 4416 // <= then incr-expr must cause var to increase on each iteration of the 4417 // loop. If test-expr is of form var relational-op b and relational-op is 4418 // > or >= then incr-expr must cause var to decrease on each iteration of 4419 // the loop. 4420 // If test-expr is of form b relational-op var and relational-op is < or 4421 // <= then incr-expr must cause var to decrease on each iteration of the 4422 // loop. If test-expr is of form b relational-op var and relational-op is 4423 // > or >= then incr-expr must cause var to increase on each iteration of 4424 // the loop. 4425 llvm::APSInt Result; 4426 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 4427 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 4428 bool IsConstNeg = 4429 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 4430 bool IsConstPos = 4431 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 4432 bool IsConstZero = IsConstant && !Result.getBoolValue(); 4433 4434 // != with increment is treated as <; != with decrement is treated as > 4435 if (!TestIsLessOp.hasValue()) 4436 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 4437 if (UB && (IsConstZero || 4438 (TestIsLessOp.getValue() ? 4439 (IsConstNeg || (IsUnsigned && Subtract)) : 4440 (IsConstPos || (IsUnsigned && !Subtract))))) { 4441 SemaRef.Diag(NewStep->getExprLoc(), 4442 diag::err_omp_loop_incr_not_compatible) 4443 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 4444 SemaRef.Diag(ConditionLoc, 4445 diag::note_omp_loop_cond_requres_compatible_incr) 4446 << TestIsLessOp.getValue() << ConditionSrcRange; 4447 return true; 4448 } 4449 if (TestIsLessOp.getValue() == Subtract) { 4450 NewStep = 4451 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 4452 .get(); 4453 Subtract = !Subtract; 4454 } 4455 } 4456 4457 Step = NewStep; 4458 SubtractStep = Subtract; 4459 return false; 4460 } 4461 4462 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 4463 // Check init-expr for canonical loop form and save loop counter 4464 // variable - #Var and its initialization value - #LB. 4465 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 4466 // var = lb 4467 // integer-type var = lb 4468 // random-access-iterator-type var = lb 4469 // pointer-type var = lb 4470 // 4471 if (!S) { 4472 if (EmitDiags) { 4473 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 4474 } 4475 return true; 4476 } 4477 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4478 if (!ExprTemp->cleanupsHaveSideEffects()) 4479 S = ExprTemp->getSubExpr(); 4480 4481 InitSrcRange = S->getSourceRange(); 4482 if (Expr *E = dyn_cast<Expr>(S)) 4483 S = E->IgnoreParens(); 4484 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4485 if (BO->getOpcode() == BO_Assign) { 4486 Expr *LHS = BO->getLHS()->IgnoreParens(); 4487 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4488 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4489 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4490 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4491 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); 4492 } 4493 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4494 if (ME->isArrow() && 4495 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4496 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4497 } 4498 } 4499 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 4500 if (DS->isSingleDecl()) { 4501 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 4502 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 4503 // Accept non-canonical init form here but emit ext. warning. 4504 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 4505 SemaRef.Diag(S->getBeginLoc(), 4506 diag::ext_omp_loop_not_canonical_init) 4507 << S->getSourceRange(); 4508 return setLCDeclAndLB( 4509 Var, 4510 buildDeclRefExpr(SemaRef, Var, 4511 Var->getType().getNonReferenceType(), 4512 DS->getBeginLoc()), 4513 Var->getInit()); 4514 } 4515 } 4516 } 4517 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4518 if (CE->getOperator() == OO_Equal) { 4519 Expr *LHS = CE->getArg(0); 4520 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4521 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4522 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4523 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4524 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); 4525 } 4526 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4527 if (ME->isArrow() && 4528 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4529 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4530 } 4531 } 4532 } 4533 4534 if (dependent() || SemaRef.CurContext->isDependentContext()) 4535 return false; 4536 if (EmitDiags) { 4537 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 4538 << S->getSourceRange(); 4539 } 4540 return true; 4541 } 4542 4543 /// Ignore parenthesizes, implicit casts, copy constructor and return the 4544 /// variable (which may be the loop variable) if possible. 4545 static const ValueDecl *getInitLCDecl(const Expr *E) { 4546 if (!E) 4547 return nullptr; 4548 E = getExprAsWritten(E); 4549 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 4550 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4551 if ((Ctor->isCopyOrMoveConstructor() || 4552 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4553 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4554 E = CE->getArg(0)->IgnoreParenImpCasts(); 4555 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 4556 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 4557 return getCanonicalDecl(VD); 4558 } 4559 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 4560 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4561 return getCanonicalDecl(ME->getMemberDecl()); 4562 return nullptr; 4563 } 4564 4565 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 4566 // Check test-expr for canonical form, save upper-bound UB, flags for 4567 // less/greater and for strict/non-strict comparison. 4568 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4569 // var relational-op b 4570 // b relational-op var 4571 // 4572 if (!S) { 4573 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 4574 return true; 4575 } 4576 S = getExprAsWritten(S); 4577 SourceLocation CondLoc = S->getBeginLoc(); 4578 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4579 if (BO->isRelationalOp()) { 4580 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4581 return setUB(BO->getRHS(), 4582 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 4583 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4584 BO->getSourceRange(), BO->getOperatorLoc()); 4585 if (getInitLCDecl(BO->getRHS()) == LCDecl) 4586 return setUB(BO->getLHS(), 4587 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 4588 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4589 BO->getSourceRange(), BO->getOperatorLoc()); 4590 } else if (BO->getOpcode() == BO_NE) 4591 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? 4592 BO->getRHS() : BO->getLHS(), 4593 /*LessOp=*/llvm::None, 4594 /*StrictOp=*/true, 4595 BO->getSourceRange(), BO->getOperatorLoc()); 4596 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4597 if (CE->getNumArgs() == 2) { 4598 auto Op = CE->getOperator(); 4599 switch (Op) { 4600 case OO_Greater: 4601 case OO_GreaterEqual: 4602 case OO_Less: 4603 case OO_LessEqual: 4604 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4605 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 4606 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4607 CE->getOperatorLoc()); 4608 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 4609 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 4610 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4611 CE->getOperatorLoc()); 4612 break; 4613 case OO_ExclaimEqual: 4614 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? 4615 CE->getArg(1) : CE->getArg(0), 4616 /*LessOp=*/llvm::None, 4617 /*StrictOp=*/true, 4618 CE->getSourceRange(), 4619 CE->getOperatorLoc()); 4620 break; 4621 default: 4622 break; 4623 } 4624 } 4625 } 4626 if (dependent() || SemaRef.CurContext->isDependentContext()) 4627 return false; 4628 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 4629 << S->getSourceRange() << LCDecl; 4630 return true; 4631 } 4632 4633 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 4634 // RHS of canonical loop form increment can be: 4635 // var + incr 4636 // incr + var 4637 // var - incr 4638 // 4639 RHS = RHS->IgnoreParenImpCasts(); 4640 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 4641 if (BO->isAdditiveOp()) { 4642 bool IsAdd = BO->getOpcode() == BO_Add; 4643 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4644 return setStep(BO->getRHS(), !IsAdd); 4645 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 4646 return setStep(BO->getLHS(), /*Subtract=*/false); 4647 } 4648 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 4649 bool IsAdd = CE->getOperator() == OO_Plus; 4650 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 4651 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4652 return setStep(CE->getArg(1), !IsAdd); 4653 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 4654 return setStep(CE->getArg(0), /*Subtract=*/false); 4655 } 4656 } 4657 if (dependent() || SemaRef.CurContext->isDependentContext()) 4658 return false; 4659 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 4660 << RHS->getSourceRange() << LCDecl; 4661 return true; 4662 } 4663 4664 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 4665 // Check incr-expr for canonical loop form and return true if it 4666 // does not conform. 4667 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4668 // ++var 4669 // var++ 4670 // --var 4671 // var-- 4672 // var += incr 4673 // var -= incr 4674 // var = var + incr 4675 // var = incr + var 4676 // var = var - incr 4677 // 4678 if (!S) { 4679 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 4680 return true; 4681 } 4682 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4683 if (!ExprTemp->cleanupsHaveSideEffects()) 4684 S = ExprTemp->getSubExpr(); 4685 4686 IncrementSrcRange = S->getSourceRange(); 4687 S = S->IgnoreParens(); 4688 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 4689 if (UO->isIncrementDecrementOp() && 4690 getInitLCDecl(UO->getSubExpr()) == LCDecl) 4691 return setStep(SemaRef 4692 .ActOnIntegerConstant(UO->getBeginLoc(), 4693 (UO->isDecrementOp() ? -1 : 1)) 4694 .get(), 4695 /*Subtract=*/false); 4696 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4697 switch (BO->getOpcode()) { 4698 case BO_AddAssign: 4699 case BO_SubAssign: 4700 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4701 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 4702 break; 4703 case BO_Assign: 4704 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4705 return checkAndSetIncRHS(BO->getRHS()); 4706 break; 4707 default: 4708 break; 4709 } 4710 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4711 switch (CE->getOperator()) { 4712 case OO_PlusPlus: 4713 case OO_MinusMinus: 4714 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4715 return setStep(SemaRef 4716 .ActOnIntegerConstant( 4717 CE->getBeginLoc(), 4718 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 4719 .get(), 4720 /*Subtract=*/false); 4721 break; 4722 case OO_PlusEqual: 4723 case OO_MinusEqual: 4724 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4725 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 4726 break; 4727 case OO_Equal: 4728 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4729 return checkAndSetIncRHS(CE->getArg(1)); 4730 break; 4731 default: 4732 break; 4733 } 4734 } 4735 if (dependent() || SemaRef.CurContext->isDependentContext()) 4736 return false; 4737 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 4738 << S->getSourceRange() << LCDecl; 4739 return true; 4740 } 4741 4742 static ExprResult 4743 tryBuildCapture(Sema &SemaRef, Expr *Capture, 4744 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4745 if (SemaRef.CurContext->isDependentContext()) 4746 return ExprResult(Capture); 4747 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 4748 return SemaRef.PerformImplicitConversion( 4749 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 4750 /*AllowExplicit=*/true); 4751 auto I = Captures.find(Capture); 4752 if (I != Captures.end()) 4753 return buildCapture(SemaRef, Capture, I->second); 4754 DeclRefExpr *Ref = nullptr; 4755 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 4756 Captures[Capture] = Ref; 4757 return Res; 4758 } 4759 4760 /// Build the expression to calculate the number of iterations. 4761 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 4762 Scope *S, const bool LimitedType, 4763 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 4764 ExprResult Diff; 4765 QualType VarType = LCDecl->getType().getNonReferenceType(); 4766 if (VarType->isIntegerType() || VarType->isPointerType() || 4767 SemaRef.getLangOpts().CPlusPlus) { 4768 // Upper - Lower 4769 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 4770 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 4771 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 4772 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 4773 if (!Upper || !Lower) 4774 return nullptr; 4775 4776 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4777 4778 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4779 // BuildBinOp already emitted error, this one is to point user to upper 4780 // and lower bound, and to tell what is passed to 'operator-'. 4781 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 4782 << Upper->getSourceRange() << Lower->getSourceRange(); 4783 return nullptr; 4784 } 4785 } 4786 4787 if (!Diff.isUsable()) 4788 return nullptr; 4789 4790 // Upper - Lower [- 1] 4791 if (TestIsStrictOp) 4792 Diff = SemaRef.BuildBinOp( 4793 S, DefaultLoc, BO_Sub, Diff.get(), 4794 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4795 if (!Diff.isUsable()) 4796 return nullptr; 4797 4798 // Upper - Lower [- 1] + Step 4799 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 4800 if (!NewStep.isUsable()) 4801 return nullptr; 4802 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 4803 if (!Diff.isUsable()) 4804 return nullptr; 4805 4806 // Parentheses (for dumping/debugging purposes only). 4807 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4808 if (!Diff.isUsable()) 4809 return nullptr; 4810 4811 // (Upper - Lower [- 1] + Step) / Step 4812 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4813 if (!Diff.isUsable()) 4814 return nullptr; 4815 4816 // OpenMP runtime requires 32-bit or 64-bit loop variables. 4817 QualType Type = Diff.get()->getType(); 4818 ASTContext &C = SemaRef.Context; 4819 bool UseVarType = VarType->hasIntegerRepresentation() && 4820 C.getTypeSize(Type) > C.getTypeSize(VarType); 4821 if (!Type->isIntegerType() || UseVarType) { 4822 unsigned NewSize = 4823 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 4824 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 4825 : Type->hasSignedIntegerRepresentation(); 4826 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 4827 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 4828 Diff = SemaRef.PerformImplicitConversion( 4829 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 4830 if (!Diff.isUsable()) 4831 return nullptr; 4832 } 4833 } 4834 if (LimitedType) { 4835 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 4836 if (NewSize != C.getTypeSize(Type)) { 4837 if (NewSize < C.getTypeSize(Type)) { 4838 assert(NewSize == 64 && "incorrect loop var size"); 4839 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 4840 << InitSrcRange << ConditionSrcRange; 4841 } 4842 QualType NewType = C.getIntTypeForBitwidth( 4843 NewSize, Type->hasSignedIntegerRepresentation() || 4844 C.getTypeSize(Type) < NewSize); 4845 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 4846 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 4847 Sema::AA_Converting, true); 4848 if (!Diff.isUsable()) 4849 return nullptr; 4850 } 4851 } 4852 } 4853 4854 return Diff.get(); 4855 } 4856 4857 Expr *OpenMPIterationSpaceChecker::buildPreCond( 4858 Scope *S, Expr *Cond, 4859 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 4860 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 4861 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4862 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4863 4864 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 4865 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 4866 if (!NewLB.isUsable() || !NewUB.isUsable()) 4867 return nullptr; 4868 4869 ExprResult CondExpr = 4870 SemaRef.BuildBinOp(S, DefaultLoc, 4871 TestIsLessOp.getValue() ? 4872 (TestIsStrictOp ? BO_LT : BO_LE) : 4873 (TestIsStrictOp ? BO_GT : BO_GE), 4874 NewLB.get(), NewUB.get()); 4875 if (CondExpr.isUsable()) { 4876 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 4877 SemaRef.Context.BoolTy)) 4878 CondExpr = SemaRef.PerformImplicitConversion( 4879 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 4880 /*AllowExplicit=*/true); 4881 } 4882 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4883 // Otherwise use original loop condition and evaluate it in runtime. 4884 return CondExpr.isUsable() ? CondExpr.get() : Cond; 4885 } 4886 4887 /// Build reference expression to the counter be used for codegen. 4888 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 4889 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4890 DSAStackTy &DSA) const { 4891 auto *VD = dyn_cast<VarDecl>(LCDecl); 4892 if (!VD) { 4893 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 4894 DeclRefExpr *Ref = buildDeclRefExpr( 4895 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 4896 const DSAStackTy::DSAVarData Data = 4897 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 4898 // If the loop control decl is explicitly marked as private, do not mark it 4899 // as captured again. 4900 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 4901 Captures.insert(std::make_pair(LCRef, Ref)); 4902 return Ref; 4903 } 4904 return cast<DeclRefExpr>(LCRef); 4905 } 4906 4907 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 4908 if (LCDecl && !LCDecl->isInvalidDecl()) { 4909 QualType Type = LCDecl->getType().getNonReferenceType(); 4910 VarDecl *PrivateVar = buildVarDecl( 4911 SemaRef, DefaultLoc, Type, LCDecl->getName(), 4912 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 4913 isa<VarDecl>(LCDecl) 4914 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 4915 : nullptr); 4916 if (PrivateVar->isInvalidDecl()) 4917 return nullptr; 4918 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 4919 } 4920 return nullptr; 4921 } 4922 4923 /// Build initialization of the counter to be used for codegen. 4924 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 4925 4926 /// Build step of the counter be used for codegen. 4927 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 4928 4929 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 4930 Scope *S, Expr *Counter, 4931 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 4932 Expr *Inc, OverloadedOperatorKind OOK) { 4933 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 4934 if (!Cnt) 4935 return nullptr; 4936 if (Inc) { 4937 assert((OOK == OO_Plus || OOK == OO_Minus) && 4938 "Expected only + or - operations for depend clauses."); 4939 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 4940 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 4941 if (!Cnt) 4942 return nullptr; 4943 } 4944 ExprResult Diff; 4945 QualType VarType = LCDecl->getType().getNonReferenceType(); 4946 if (VarType->isIntegerType() || VarType->isPointerType() || 4947 SemaRef.getLangOpts().CPlusPlus) { 4948 // Upper - Lower 4949 Expr *Upper = TestIsLessOp.getValue() 4950 ? Cnt 4951 : tryBuildCapture(SemaRef, UB, Captures).get(); 4952 Expr *Lower = TestIsLessOp.getValue() 4953 ? tryBuildCapture(SemaRef, LB, Captures).get() 4954 : Cnt; 4955 if (!Upper || !Lower) 4956 return nullptr; 4957 4958 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4959 4960 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4961 // BuildBinOp already emitted error, this one is to point user to upper 4962 // and lower bound, and to tell what is passed to 'operator-'. 4963 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 4964 << Upper->getSourceRange() << Lower->getSourceRange(); 4965 return nullptr; 4966 } 4967 } 4968 4969 if (!Diff.isUsable()) 4970 return nullptr; 4971 4972 // Parentheses (for dumping/debugging purposes only). 4973 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4974 if (!Diff.isUsable()) 4975 return nullptr; 4976 4977 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 4978 if (!NewStep.isUsable()) 4979 return nullptr; 4980 // (Upper - Lower) / Step 4981 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4982 if (!Diff.isUsable()) 4983 return nullptr; 4984 4985 return Diff.get(); 4986 } 4987 4988 /// Iteration space of a single for loop. 4989 struct LoopIterationSpace final { 4990 /// True if the condition operator is the strict compare operator (<, > or 4991 /// !=). 4992 bool IsStrictCompare = false; 4993 /// Condition of the loop. 4994 Expr *PreCond = nullptr; 4995 /// This expression calculates the number of iterations in the loop. 4996 /// It is always possible to calculate it before starting the loop. 4997 Expr *NumIterations = nullptr; 4998 /// The loop counter variable. 4999 Expr *CounterVar = nullptr; 5000 /// Private loop counter variable. 5001 Expr *PrivateCounterVar = nullptr; 5002 /// This is initializer for the initial value of #CounterVar. 5003 Expr *CounterInit = nullptr; 5004 /// This is step for the #CounterVar used to generate its update: 5005 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 5006 Expr *CounterStep = nullptr; 5007 /// Should step be subtracted? 5008 bool Subtract = false; 5009 /// Source range of the loop init. 5010 SourceRange InitSrcRange; 5011 /// Source range of the loop condition. 5012 SourceRange CondSrcRange; 5013 /// Source range of the loop increment. 5014 SourceRange IncSrcRange; 5015 }; 5016 5017 } // namespace 5018 5019 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 5020 assert(getLangOpts().OpenMP && "OpenMP is not active."); 5021 assert(Init && "Expected loop in canonical form."); 5022 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 5023 if (AssociatedLoops > 0 && 5024 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 5025 DSAStack->loopStart(); 5026 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 5027 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 5028 if (ValueDecl *D = ISC.getLoopDecl()) { 5029 auto *VD = dyn_cast<VarDecl>(D); 5030 if (!VD) { 5031 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 5032 VD = Private; 5033 } else { 5034 DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 5035 /*WithInit=*/false); 5036 VD = cast<VarDecl>(Ref->getDecl()); 5037 } 5038 } 5039 DSAStack->addLoopControlVariable(D, VD); 5040 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 5041 if (LD != D->getCanonicalDecl()) { 5042 DSAStack->resetPossibleLoopCounter(); 5043 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 5044 MarkDeclarationsReferencedInExpr( 5045 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 5046 Var->getType().getNonLValueExprType(Context), 5047 ForLoc, /*RefersToCapture=*/true)); 5048 } 5049 } 5050 } 5051 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 5052 } 5053 } 5054 5055 /// Called on a for stmt to check and extract its iteration space 5056 /// for further processing (such as collapsing). 5057 static bool checkOpenMPIterationSpace( 5058 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 5059 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 5060 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 5061 Expr *OrderedLoopCountExpr, 5062 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5063 LoopIterationSpace &ResultIterSpace, 5064 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5065 // OpenMP [2.6, Canonical Loop Form] 5066 // for (init-expr; test-expr; incr-expr) structured-block 5067 auto *For = dyn_cast_or_null<ForStmt>(S); 5068 if (!For) { 5069 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 5070 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 5071 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 5072 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 5073 if (TotalNestedLoopCount > 1) { 5074 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 5075 SemaRef.Diag(DSA.getConstructLoc(), 5076 diag::note_omp_collapse_ordered_expr) 5077 << 2 << CollapseLoopCountExpr->getSourceRange() 5078 << OrderedLoopCountExpr->getSourceRange(); 5079 else if (CollapseLoopCountExpr) 5080 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5081 diag::note_omp_collapse_ordered_expr) 5082 << 0 << CollapseLoopCountExpr->getSourceRange(); 5083 else 5084 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5085 diag::note_omp_collapse_ordered_expr) 5086 << 1 << OrderedLoopCountExpr->getSourceRange(); 5087 } 5088 return true; 5089 } 5090 assert(For->getBody()); 5091 5092 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 5093 5094 // Check init. 5095 Stmt *Init = For->getInit(); 5096 if (ISC.checkAndSetInit(Init)) 5097 return true; 5098 5099 bool HasErrors = false; 5100 5101 // Check loop variable's type. 5102 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 5103 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 5104 5105 // OpenMP [2.6, Canonical Loop Form] 5106 // Var is one of the following: 5107 // A variable of signed or unsigned integer type. 5108 // For C++, a variable of a random access iterator type. 5109 // For C, a variable of a pointer type. 5110 QualType VarType = LCDecl->getType().getNonReferenceType(); 5111 if (!VarType->isDependentType() && !VarType->isIntegerType() && 5112 !VarType->isPointerType() && 5113 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 5114 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 5115 << SemaRef.getLangOpts().CPlusPlus; 5116 HasErrors = true; 5117 } 5118 5119 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 5120 // a Construct 5121 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5122 // parallel for construct is (are) private. 5123 // The loop iteration variable in the associated for-loop of a simd 5124 // construct with just one associated for-loop is linear with a 5125 // constant-linear-step that is the increment of the associated for-loop. 5126 // Exclude loop var from the list of variables with implicitly defined data 5127 // sharing attributes. 5128 VarsWithImplicitDSA.erase(LCDecl); 5129 5130 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 5131 // in a Construct, C/C++]. 5132 // The loop iteration variable in the associated for-loop of a simd 5133 // construct with just one associated for-loop may be listed in a linear 5134 // clause with a constant-linear-step that is the increment of the 5135 // associated for-loop. 5136 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5137 // parallel for construct may be listed in a private or lastprivate clause. 5138 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 5139 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 5140 // declared in the loop and it is predetermined as a private. 5141 OpenMPClauseKind PredeterminedCKind = 5142 isOpenMPSimdDirective(DKind) 5143 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 5144 : OMPC_private; 5145 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5146 DVar.CKind != PredeterminedCKind) || 5147 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 5148 isOpenMPDistributeDirective(DKind)) && 5149 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5150 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 5151 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 5152 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 5153 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 5154 << getOpenMPClauseName(PredeterminedCKind); 5155 if (DVar.RefExpr == nullptr) 5156 DVar.CKind = PredeterminedCKind; 5157 reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 5158 HasErrors = true; 5159 } else if (LoopDeclRefExpr != nullptr) { 5160 // Make the loop iteration variable private (for worksharing constructs), 5161 // linear (for simd directives with the only one associated loop) or 5162 // lastprivate (for simd directives with several collapsed or ordered 5163 // loops). 5164 if (DVar.CKind == OMPC_unknown) 5165 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 5166 } 5167 5168 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 5169 5170 // Check test-expr. 5171 HasErrors |= ISC.checkAndSetCond(For->getCond()); 5172 5173 // Check incr-expr. 5174 HasErrors |= ISC.checkAndSetInc(For->getInc()); 5175 } 5176 5177 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 5178 return HasErrors; 5179 5180 // Build the loop's iteration space representation. 5181 ResultIterSpace.PreCond = 5182 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 5183 ResultIterSpace.NumIterations = ISC.buildNumIterations( 5184 DSA.getCurScope(), 5185 (isOpenMPWorksharingDirective(DKind) || 5186 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 5187 Captures); 5188 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA); 5189 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar(); 5190 ResultIterSpace.CounterInit = ISC.buildCounterInit(); 5191 ResultIterSpace.CounterStep = ISC.buildCounterStep(); 5192 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange(); 5193 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange(); 5194 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange(); 5195 ResultIterSpace.Subtract = ISC.shouldSubtractStep(); 5196 ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp(); 5197 5198 HasErrors |= (ResultIterSpace.PreCond == nullptr || 5199 ResultIterSpace.NumIterations == nullptr || 5200 ResultIterSpace.CounterVar == nullptr || 5201 ResultIterSpace.PrivateCounterVar == nullptr || 5202 ResultIterSpace.CounterInit == nullptr || 5203 ResultIterSpace.CounterStep == nullptr); 5204 if (!HasErrors && DSA.isOrderedRegion()) { 5205 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 5206 if (CurrentNestedLoopCount < 5207 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 5208 DSA.getOrderedRegionParam().second->setLoopNumIterations( 5209 CurrentNestedLoopCount, ResultIterSpace.NumIterations); 5210 DSA.getOrderedRegionParam().second->setLoopCounter( 5211 CurrentNestedLoopCount, ResultIterSpace.CounterVar); 5212 } 5213 } 5214 for (auto &Pair : DSA.getDoacrossDependClauses()) { 5215 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 5216 // Erroneous case - clause has some problems. 5217 continue; 5218 } 5219 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 5220 Pair.second.size() <= CurrentNestedLoopCount) { 5221 // Erroneous case - clause has some problems. 5222 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 5223 continue; 5224 } 5225 Expr *CntValue; 5226 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 5227 CntValue = ISC.buildOrderedLoopData( 5228 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5229 Pair.first->getDependencyLoc()); 5230 else 5231 CntValue = ISC.buildOrderedLoopData( 5232 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5233 Pair.first->getDependencyLoc(), 5234 Pair.second[CurrentNestedLoopCount].first, 5235 Pair.second[CurrentNestedLoopCount].second); 5236 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 5237 } 5238 } 5239 5240 return HasErrors; 5241 } 5242 5243 /// Build 'VarRef = Start. 5244 static ExprResult 5245 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5246 ExprResult Start, 5247 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5248 // Build 'VarRef = Start. 5249 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 5250 if (!NewStart.isUsable()) 5251 return ExprError(); 5252 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 5253 VarRef.get()->getType())) { 5254 NewStart = SemaRef.PerformImplicitConversion( 5255 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 5256 /*AllowExplicit=*/true); 5257 if (!NewStart.isUsable()) 5258 return ExprError(); 5259 } 5260 5261 ExprResult Init = 5262 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5263 return Init; 5264 } 5265 5266 /// Build 'VarRef = Start + Iter * Step'. 5267 static ExprResult buildCounterUpdate( 5268 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5269 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 5270 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 5271 // Add parentheses (for debugging purposes only). 5272 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 5273 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 5274 !Step.isUsable()) 5275 return ExprError(); 5276 5277 ExprResult NewStep = Step; 5278 if (Captures) 5279 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 5280 if (NewStep.isInvalid()) 5281 return ExprError(); 5282 ExprResult Update = 5283 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 5284 if (!Update.isUsable()) 5285 return ExprError(); 5286 5287 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 5288 // 'VarRef = Start (+|-) Iter * Step'. 5289 ExprResult NewStart = Start; 5290 if (Captures) 5291 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 5292 if (NewStart.isInvalid()) 5293 return ExprError(); 5294 5295 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 5296 ExprResult SavedUpdate = Update; 5297 ExprResult UpdateVal; 5298 if (VarRef.get()->getType()->isOverloadableType() || 5299 NewStart.get()->getType()->isOverloadableType() || 5300 Update.get()->getType()->isOverloadableType()) { 5301 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5302 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5303 Update = 5304 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5305 if (Update.isUsable()) { 5306 UpdateVal = 5307 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 5308 VarRef.get(), SavedUpdate.get()); 5309 if (UpdateVal.isUsable()) { 5310 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 5311 UpdateVal.get()); 5312 } 5313 } 5314 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5315 } 5316 5317 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 5318 if (!Update.isUsable() || !UpdateVal.isUsable()) { 5319 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 5320 NewStart.get(), SavedUpdate.get()); 5321 if (!Update.isUsable()) 5322 return ExprError(); 5323 5324 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 5325 VarRef.get()->getType())) { 5326 Update = SemaRef.PerformImplicitConversion( 5327 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 5328 if (!Update.isUsable()) 5329 return ExprError(); 5330 } 5331 5332 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 5333 } 5334 return Update; 5335 } 5336 5337 /// Convert integer expression \a E to make it have at least \a Bits 5338 /// bits. 5339 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 5340 if (E == nullptr) 5341 return ExprError(); 5342 ASTContext &C = SemaRef.Context; 5343 QualType OldType = E->getType(); 5344 unsigned HasBits = C.getTypeSize(OldType); 5345 if (HasBits >= Bits) 5346 return ExprResult(E); 5347 // OK to convert to signed, because new type has more bits than old. 5348 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 5349 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 5350 true); 5351 } 5352 5353 /// Check if the given expression \a E is a constant integer that fits 5354 /// into \a Bits bits. 5355 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 5356 if (E == nullptr) 5357 return false; 5358 llvm::APSInt Result; 5359 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 5360 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 5361 return false; 5362 } 5363 5364 /// Build preinits statement for the given declarations. 5365 static Stmt *buildPreInits(ASTContext &Context, 5366 MutableArrayRef<Decl *> PreInits) { 5367 if (!PreInits.empty()) { 5368 return new (Context) DeclStmt( 5369 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 5370 SourceLocation(), SourceLocation()); 5371 } 5372 return nullptr; 5373 } 5374 5375 /// Build preinits statement for the given declarations. 5376 static Stmt * 5377 buildPreInits(ASTContext &Context, 5378 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5379 if (!Captures.empty()) { 5380 SmallVector<Decl *, 16> PreInits; 5381 for (const auto &Pair : Captures) 5382 PreInits.push_back(Pair.second->getDecl()); 5383 return buildPreInits(Context, PreInits); 5384 } 5385 return nullptr; 5386 } 5387 5388 /// Build postupdate expression for the given list of postupdates expressions. 5389 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 5390 Expr *PostUpdate = nullptr; 5391 if (!PostUpdates.empty()) { 5392 for (Expr *E : PostUpdates) { 5393 Expr *ConvE = S.BuildCStyleCastExpr( 5394 E->getExprLoc(), 5395 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 5396 E->getExprLoc(), E) 5397 .get(); 5398 PostUpdate = PostUpdate 5399 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 5400 PostUpdate, ConvE) 5401 .get() 5402 : ConvE; 5403 } 5404 } 5405 return PostUpdate; 5406 } 5407 5408 /// Called on a for stmt to check itself and nested loops (if any). 5409 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 5410 /// number of collapsed loops otherwise. 5411 static unsigned 5412 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 5413 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 5414 DSAStackTy &DSA, 5415 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5416 OMPLoopDirective::HelperExprs &Built) { 5417 unsigned NestedLoopCount = 1; 5418 if (CollapseLoopCountExpr) { 5419 // Found 'collapse' clause - calculate collapse number. 5420 Expr::EvalResult Result; 5421 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 5422 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 5423 } 5424 unsigned OrderedLoopCount = 1; 5425 if (OrderedLoopCountExpr) { 5426 // Found 'ordered' clause - calculate collapse number. 5427 Expr::EvalResult EVResult; 5428 if (OrderedLoopCountExpr->EvaluateAsInt(EVResult, SemaRef.getASTContext())) { 5429 llvm::APSInt Result = EVResult.Val.getInt(); 5430 if (Result.getLimitedValue() < NestedLoopCount) { 5431 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5432 diag::err_omp_wrong_ordered_loop_count) 5433 << OrderedLoopCountExpr->getSourceRange(); 5434 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5435 diag::note_collapse_loop_count) 5436 << CollapseLoopCountExpr->getSourceRange(); 5437 } 5438 OrderedLoopCount = Result.getLimitedValue(); 5439 } 5440 } 5441 // This is helper routine for loop directives (e.g., 'for', 'simd', 5442 // 'for simd', etc.). 5443 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 5444 SmallVector<LoopIterationSpace, 4> IterSpaces( 5445 std::max(OrderedLoopCount, NestedLoopCount)); 5446 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 5447 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 5448 if (checkOpenMPIterationSpace( 5449 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 5450 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 5451 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 5452 Captures)) 5453 return 0; 5454 // Move on to the next nested for loop, or to the loop body. 5455 // OpenMP [2.8.1, simd construct, Restrictions] 5456 // All loops associated with the construct must be perfectly nested; that 5457 // is, there must be no intervening code nor any OpenMP directive between 5458 // any two loops. 5459 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 5460 } 5461 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 5462 if (checkOpenMPIterationSpace( 5463 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 5464 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 5465 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 5466 Captures)) 5467 return 0; 5468 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 5469 // Handle initialization of captured loop iterator variables. 5470 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 5471 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 5472 Captures[DRE] = DRE; 5473 } 5474 } 5475 // Move on to the next nested for loop, or to the loop body. 5476 // OpenMP [2.8.1, simd construct, Restrictions] 5477 // All loops associated with the construct must be perfectly nested; that 5478 // is, there must be no intervening code nor any OpenMP directive between 5479 // any two loops. 5480 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 5481 } 5482 5483 Built.clear(/* size */ NestedLoopCount); 5484 5485 if (SemaRef.CurContext->isDependentContext()) 5486 return NestedLoopCount; 5487 5488 // An example of what is generated for the following code: 5489 // 5490 // #pragma omp simd collapse(2) ordered(2) 5491 // for (i = 0; i < NI; ++i) 5492 // for (k = 0; k < NK; ++k) 5493 // for (j = J0; j < NJ; j+=2) { 5494 // <loop body> 5495 // } 5496 // 5497 // We generate the code below. 5498 // Note: the loop body may be outlined in CodeGen. 5499 // Note: some counters may be C++ classes, operator- is used to find number of 5500 // iterations and operator+= to calculate counter value. 5501 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 5502 // or i64 is currently supported). 5503 // 5504 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 5505 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 5506 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 5507 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 5508 // // similar updates for vars in clauses (e.g. 'linear') 5509 // <loop body (using local i and j)> 5510 // } 5511 // i = NI; // assign final values of counters 5512 // j = NJ; 5513 // 5514 5515 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 5516 // the iteration counts of the collapsed for loops. 5517 // Precondition tests if there is at least one iteration (all conditions are 5518 // true). 5519 auto PreCond = ExprResult(IterSpaces[0].PreCond); 5520 Expr *N0 = IterSpaces[0].NumIterations; 5521 ExprResult LastIteration32 = 5522 widenIterationCount(/*Bits=*/32, 5523 SemaRef 5524 .PerformImplicitConversion( 5525 N0->IgnoreImpCasts(), N0->getType(), 5526 Sema::AA_Converting, /*AllowExplicit=*/true) 5527 .get(), 5528 SemaRef); 5529 ExprResult LastIteration64 = widenIterationCount( 5530 /*Bits=*/64, 5531 SemaRef 5532 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 5533 Sema::AA_Converting, 5534 /*AllowExplicit=*/true) 5535 .get(), 5536 SemaRef); 5537 5538 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 5539 return NestedLoopCount; 5540 5541 ASTContext &C = SemaRef.Context; 5542 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 5543 5544 Scope *CurScope = DSA.getCurScope(); 5545 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 5546 if (PreCond.isUsable()) { 5547 PreCond = 5548 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 5549 PreCond.get(), IterSpaces[Cnt].PreCond); 5550 } 5551 Expr *N = IterSpaces[Cnt].NumIterations; 5552 SourceLocation Loc = N->getExprLoc(); 5553 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 5554 if (LastIteration32.isUsable()) 5555 LastIteration32 = SemaRef.BuildBinOp( 5556 CurScope, Loc, BO_Mul, LastIteration32.get(), 5557 SemaRef 5558 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5559 Sema::AA_Converting, 5560 /*AllowExplicit=*/true) 5561 .get()); 5562 if (LastIteration64.isUsable()) 5563 LastIteration64 = SemaRef.BuildBinOp( 5564 CurScope, Loc, BO_Mul, LastIteration64.get(), 5565 SemaRef 5566 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5567 Sema::AA_Converting, 5568 /*AllowExplicit=*/true) 5569 .get()); 5570 } 5571 5572 // Choose either the 32-bit or 64-bit version. 5573 ExprResult LastIteration = LastIteration64; 5574 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 5575 (LastIteration32.isUsable() && 5576 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 5577 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 5578 fitsInto( 5579 /*Bits=*/32, 5580 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 5581 LastIteration64.get(), SemaRef)))) 5582 LastIteration = LastIteration32; 5583 QualType VType = LastIteration.get()->getType(); 5584 QualType RealVType = VType; 5585 QualType StrideVType = VType; 5586 if (isOpenMPTaskLoopDirective(DKind)) { 5587 VType = 5588 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 5589 StrideVType = 5590 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 5591 } 5592 5593 if (!LastIteration.isUsable()) 5594 return 0; 5595 5596 // Save the number of iterations. 5597 ExprResult NumIterations = LastIteration; 5598 { 5599 LastIteration = SemaRef.BuildBinOp( 5600 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 5601 LastIteration.get(), 5602 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5603 if (!LastIteration.isUsable()) 5604 return 0; 5605 } 5606 5607 // Calculate the last iteration number beforehand instead of doing this on 5608 // each iteration. Do not do this if the number of iterations may be kfold-ed. 5609 llvm::APSInt Result; 5610 bool IsConstant = 5611 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 5612 ExprResult CalcLastIteration; 5613 if (!IsConstant) { 5614 ExprResult SaveRef = 5615 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 5616 LastIteration = SaveRef; 5617 5618 // Prepare SaveRef + 1. 5619 NumIterations = SemaRef.BuildBinOp( 5620 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 5621 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5622 if (!NumIterations.isUsable()) 5623 return 0; 5624 } 5625 5626 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 5627 5628 // Build variables passed into runtime, necessary for worksharing directives. 5629 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 5630 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5631 isOpenMPDistributeDirective(DKind)) { 5632 // Lower bound variable, initialized with zero. 5633 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 5634 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 5635 SemaRef.AddInitializerToDecl(LBDecl, 5636 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5637 /*DirectInit*/ false); 5638 5639 // Upper bound variable, initialized with last iteration number. 5640 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 5641 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 5642 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 5643 /*DirectInit*/ false); 5644 5645 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 5646 // This will be used to implement clause 'lastprivate'. 5647 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 5648 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 5649 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 5650 SemaRef.AddInitializerToDecl(ILDecl, 5651 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5652 /*DirectInit*/ false); 5653 5654 // Stride variable returned by runtime (we initialize it to 1 by default). 5655 VarDecl *STDecl = 5656 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 5657 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 5658 SemaRef.AddInitializerToDecl(STDecl, 5659 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 5660 /*DirectInit*/ false); 5661 5662 // Build expression: UB = min(UB, LastIteration) 5663 // It is necessary for CodeGen of directives with static scheduling. 5664 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 5665 UB.get(), LastIteration.get()); 5666 ExprResult CondOp = SemaRef.ActOnConditionalOp( 5667 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 5668 LastIteration.get(), UB.get()); 5669 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 5670 CondOp.get()); 5671 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 5672 5673 // If we have a combined directive that combines 'distribute', 'for' or 5674 // 'simd' we need to be able to access the bounds of the schedule of the 5675 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 5676 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 5677 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5678 // Lower bound variable, initialized with zero. 5679 VarDecl *CombLBDecl = 5680 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 5681 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 5682 SemaRef.AddInitializerToDecl( 5683 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5684 /*DirectInit*/ false); 5685 5686 // Upper bound variable, initialized with last iteration number. 5687 VarDecl *CombUBDecl = 5688 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 5689 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 5690 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 5691 /*DirectInit*/ false); 5692 5693 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 5694 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 5695 ExprResult CombCondOp = 5696 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 5697 LastIteration.get(), CombUB.get()); 5698 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 5699 CombCondOp.get()); 5700 CombEUB = 5701 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 5702 5703 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 5704 // We expect to have at least 2 more parameters than the 'parallel' 5705 // directive does - the lower and upper bounds of the previous schedule. 5706 assert(CD->getNumParams() >= 4 && 5707 "Unexpected number of parameters in loop combined directive"); 5708 5709 // Set the proper type for the bounds given what we learned from the 5710 // enclosed loops. 5711 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 5712 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 5713 5714 // Previous lower and upper bounds are obtained from the region 5715 // parameters. 5716 PrevLB = 5717 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 5718 PrevUB = 5719 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 5720 } 5721 } 5722 5723 // Build the iteration variable and its initialization before loop. 5724 ExprResult IV; 5725 ExprResult Init, CombInit; 5726 { 5727 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 5728 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 5729 Expr *RHS = 5730 (isOpenMPWorksharingDirective(DKind) || 5731 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5732 ? LB.get() 5733 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 5734 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 5735 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 5736 5737 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5738 Expr *CombRHS = 5739 (isOpenMPWorksharingDirective(DKind) || 5740 isOpenMPTaskLoopDirective(DKind) || 5741 isOpenMPDistributeDirective(DKind)) 5742 ? CombLB.get() 5743 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 5744 CombInit = 5745 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 5746 CombInit = 5747 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 5748 } 5749 } 5750 5751 bool UseStrictCompare = 5752 RealVType->hasUnsignedIntegerRepresentation() && 5753 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 5754 return LIS.IsStrictCompare; 5755 }); 5756 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 5757 // unsigned IV)) for worksharing loops. 5758 SourceLocation CondLoc = AStmt->getBeginLoc(); 5759 Expr *BoundUB = UB.get(); 5760 if (UseStrictCompare) { 5761 BoundUB = 5762 SemaRef 5763 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 5764 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 5765 .get(); 5766 BoundUB = 5767 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 5768 } 5769 ExprResult Cond = 5770 (isOpenMPWorksharingDirective(DKind) || 5771 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5772 ? SemaRef.BuildBinOp(CurScope, CondLoc, 5773 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 5774 BoundUB) 5775 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 5776 NumIterations.get()); 5777 ExprResult CombDistCond; 5778 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5779 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 5780 NumIterations.get()); 5781 } 5782 5783 ExprResult CombCond; 5784 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5785 Expr *BoundCombUB = CombUB.get(); 5786 if (UseStrictCompare) { 5787 BoundCombUB = 5788 SemaRef 5789 .BuildBinOp( 5790 CurScope, CondLoc, BO_Add, BoundCombUB, 5791 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 5792 .get(); 5793 BoundCombUB = 5794 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 5795 .get(); 5796 } 5797 CombCond = 5798 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 5799 IV.get(), BoundCombUB); 5800 } 5801 // Loop increment (IV = IV + 1) 5802 SourceLocation IncLoc = AStmt->getBeginLoc(); 5803 ExprResult Inc = 5804 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 5805 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 5806 if (!Inc.isUsable()) 5807 return 0; 5808 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 5809 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 5810 if (!Inc.isUsable()) 5811 return 0; 5812 5813 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 5814 // Used for directives with static scheduling. 5815 // In combined construct, add combined version that use CombLB and CombUB 5816 // base variables for the update 5817 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 5818 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5819 isOpenMPDistributeDirective(DKind)) { 5820 // LB + ST 5821 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 5822 if (!NextLB.isUsable()) 5823 return 0; 5824 // LB = LB + ST 5825 NextLB = 5826 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 5827 NextLB = 5828 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 5829 if (!NextLB.isUsable()) 5830 return 0; 5831 // UB + ST 5832 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 5833 if (!NextUB.isUsable()) 5834 return 0; 5835 // UB = UB + ST 5836 NextUB = 5837 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 5838 NextUB = 5839 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 5840 if (!NextUB.isUsable()) 5841 return 0; 5842 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5843 CombNextLB = 5844 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 5845 if (!NextLB.isUsable()) 5846 return 0; 5847 // LB = LB + ST 5848 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 5849 CombNextLB.get()); 5850 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 5851 /*DiscardedValue*/ false); 5852 if (!CombNextLB.isUsable()) 5853 return 0; 5854 // UB + ST 5855 CombNextUB = 5856 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 5857 if (!CombNextUB.isUsable()) 5858 return 0; 5859 // UB = UB + ST 5860 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 5861 CombNextUB.get()); 5862 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 5863 /*DiscardedValue*/ false); 5864 if (!CombNextUB.isUsable()) 5865 return 0; 5866 } 5867 } 5868 5869 // Create increment expression for distribute loop when combined in a same 5870 // directive with for as IV = IV + ST; ensure upper bound expression based 5871 // on PrevUB instead of NumIterations - used to implement 'for' when found 5872 // in combination with 'distribute', like in 'distribute parallel for' 5873 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 5874 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 5875 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5876 DistCond = SemaRef.BuildBinOp( 5877 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 5878 assert(DistCond.isUsable() && "distribute cond expr was not built"); 5879 5880 DistInc = 5881 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 5882 assert(DistInc.isUsable() && "distribute inc expr was not built"); 5883 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 5884 DistInc.get()); 5885 DistInc = 5886 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 5887 assert(DistInc.isUsable() && "distribute inc expr was not built"); 5888 5889 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 5890 // construct 5891 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 5892 ExprResult IsUBGreater = 5893 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 5894 ExprResult CondOp = SemaRef.ActOnConditionalOp( 5895 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 5896 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 5897 CondOp.get()); 5898 PrevEUB = 5899 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 5900 5901 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 5902 // parallel for is in combination with a distribute directive with 5903 // schedule(static, 1) 5904 Expr *BoundPrevUB = PrevUB.get(); 5905 if (UseStrictCompare) { 5906 BoundPrevUB = 5907 SemaRef 5908 .BuildBinOp( 5909 CurScope, CondLoc, BO_Add, BoundPrevUB, 5910 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 5911 .get(); 5912 BoundPrevUB = 5913 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 5914 .get(); 5915 } 5916 ParForInDistCond = 5917 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 5918 IV.get(), BoundPrevUB); 5919 } 5920 5921 // Build updates and final values of the loop counters. 5922 bool HasErrors = false; 5923 Built.Counters.resize(NestedLoopCount); 5924 Built.Inits.resize(NestedLoopCount); 5925 Built.Updates.resize(NestedLoopCount); 5926 Built.Finals.resize(NestedLoopCount); 5927 { 5928 // We implement the following algorithm for obtaining the 5929 // original loop iteration variable values based on the 5930 // value of the collapsed loop iteration variable IV. 5931 // 5932 // Let n+1 be the number of collapsed loops in the nest. 5933 // Iteration variables (I0, I1, .... In) 5934 // Iteration counts (N0, N1, ... Nn) 5935 // 5936 // Acc = IV; 5937 // 5938 // To compute Ik for loop k, 0 <= k <= n, generate: 5939 // Prod = N(k+1) * N(k+2) * ... * Nn; 5940 // Ik = Acc / Prod; 5941 // Acc -= Ik * Prod; 5942 // 5943 ExprResult Acc = IV; 5944 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 5945 LoopIterationSpace &IS = IterSpaces[Cnt]; 5946 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 5947 ExprResult Iter; 5948 5949 // Compute prod 5950 ExprResult Prod = 5951 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 5952 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 5953 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 5954 IterSpaces[K].NumIterations); 5955 5956 // Iter = Acc / Prod 5957 // If there is at least one more inner loop to avoid 5958 // multiplication by 1. 5959 if (Cnt + 1 < NestedLoopCount) 5960 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 5961 Acc.get(), Prod.get()); 5962 else 5963 Iter = Acc; 5964 if (!Iter.isUsable()) { 5965 HasErrors = true; 5966 break; 5967 } 5968 5969 // Update Acc: 5970 // Acc -= Iter * Prod 5971 // Check if there is at least one more inner loop to avoid 5972 // multiplication by 1. 5973 if (Cnt + 1 < NestedLoopCount) 5974 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 5975 Iter.get(), Prod.get()); 5976 else 5977 Prod = Iter; 5978 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 5979 Acc.get(), Prod.get()); 5980 5981 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 5982 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 5983 DeclRefExpr *CounterVar = buildDeclRefExpr( 5984 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 5985 /*RefersToCapture=*/true); 5986 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 5987 IS.CounterInit, Captures); 5988 if (!Init.isUsable()) { 5989 HasErrors = true; 5990 break; 5991 } 5992 ExprResult Update = buildCounterUpdate( 5993 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 5994 IS.CounterStep, IS.Subtract, &Captures); 5995 if (!Update.isUsable()) { 5996 HasErrors = true; 5997 break; 5998 } 5999 6000 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 6001 ExprResult Final = buildCounterUpdate( 6002 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 6003 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 6004 if (!Final.isUsable()) { 6005 HasErrors = true; 6006 break; 6007 } 6008 6009 if (!Update.isUsable() || !Final.isUsable()) { 6010 HasErrors = true; 6011 break; 6012 } 6013 // Save results 6014 Built.Counters[Cnt] = IS.CounterVar; 6015 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 6016 Built.Inits[Cnt] = Init.get(); 6017 Built.Updates[Cnt] = Update.get(); 6018 Built.Finals[Cnt] = Final.get(); 6019 } 6020 } 6021 6022 if (HasErrors) 6023 return 0; 6024 6025 // Save results 6026 Built.IterationVarRef = IV.get(); 6027 Built.LastIteration = LastIteration.get(); 6028 Built.NumIterations = NumIterations.get(); 6029 Built.CalcLastIteration = SemaRef 6030 .ActOnFinishFullExpr(CalcLastIteration.get(), 6031 /*DiscardedValue*/ false) 6032 .get(); 6033 Built.PreCond = PreCond.get(); 6034 Built.PreInits = buildPreInits(C, Captures); 6035 Built.Cond = Cond.get(); 6036 Built.Init = Init.get(); 6037 Built.Inc = Inc.get(); 6038 Built.LB = LB.get(); 6039 Built.UB = UB.get(); 6040 Built.IL = IL.get(); 6041 Built.ST = ST.get(); 6042 Built.EUB = EUB.get(); 6043 Built.NLB = NextLB.get(); 6044 Built.NUB = NextUB.get(); 6045 Built.PrevLB = PrevLB.get(); 6046 Built.PrevUB = PrevUB.get(); 6047 Built.DistInc = DistInc.get(); 6048 Built.PrevEUB = PrevEUB.get(); 6049 Built.DistCombinedFields.LB = CombLB.get(); 6050 Built.DistCombinedFields.UB = CombUB.get(); 6051 Built.DistCombinedFields.EUB = CombEUB.get(); 6052 Built.DistCombinedFields.Init = CombInit.get(); 6053 Built.DistCombinedFields.Cond = CombCond.get(); 6054 Built.DistCombinedFields.NLB = CombNextLB.get(); 6055 Built.DistCombinedFields.NUB = CombNextUB.get(); 6056 Built.DistCombinedFields.DistCond = CombDistCond.get(); 6057 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 6058 6059 return NestedLoopCount; 6060 } 6061 6062 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 6063 auto CollapseClauses = 6064 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 6065 if (CollapseClauses.begin() != CollapseClauses.end()) 6066 return (*CollapseClauses.begin())->getNumForLoops(); 6067 return nullptr; 6068 } 6069 6070 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 6071 auto OrderedClauses = 6072 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 6073 if (OrderedClauses.begin() != OrderedClauses.end()) 6074 return (*OrderedClauses.begin())->getNumForLoops(); 6075 return nullptr; 6076 } 6077 6078 static bool checkSimdlenSafelenSpecified(Sema &S, 6079 const ArrayRef<OMPClause *> Clauses) { 6080 const OMPSafelenClause *Safelen = nullptr; 6081 const OMPSimdlenClause *Simdlen = nullptr; 6082 6083 for (const OMPClause *Clause : Clauses) { 6084 if (Clause->getClauseKind() == OMPC_safelen) 6085 Safelen = cast<OMPSafelenClause>(Clause); 6086 else if (Clause->getClauseKind() == OMPC_simdlen) 6087 Simdlen = cast<OMPSimdlenClause>(Clause); 6088 if (Safelen && Simdlen) 6089 break; 6090 } 6091 6092 if (Simdlen && Safelen) { 6093 const Expr *SimdlenLength = Simdlen->getSimdlen(); 6094 const Expr *SafelenLength = Safelen->getSafelen(); 6095 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 6096 SimdlenLength->isInstantiationDependent() || 6097 SimdlenLength->containsUnexpandedParameterPack()) 6098 return false; 6099 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 6100 SafelenLength->isInstantiationDependent() || 6101 SafelenLength->containsUnexpandedParameterPack()) 6102 return false; 6103 Expr::EvalResult SimdlenResult, SafelenResult; 6104 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 6105 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 6106 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 6107 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 6108 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 6109 // If both simdlen and safelen clauses are specified, the value of the 6110 // simdlen parameter must be less than or equal to the value of the safelen 6111 // parameter. 6112 if (SimdlenRes > SafelenRes) { 6113 S.Diag(SimdlenLength->getExprLoc(), 6114 diag::err_omp_wrong_simdlen_safelen_values) 6115 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 6116 return true; 6117 } 6118 } 6119 return false; 6120 } 6121 6122 StmtResult 6123 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6124 SourceLocation StartLoc, SourceLocation EndLoc, 6125 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6126 if (!AStmt) 6127 return StmtError(); 6128 6129 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6130 OMPLoopDirective::HelperExprs B; 6131 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6132 // define the nested loops number. 6133 unsigned NestedLoopCount = checkOpenMPLoop( 6134 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6135 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6136 if (NestedLoopCount == 0) 6137 return StmtError(); 6138 6139 assert((CurContext->isDependentContext() || B.builtAll()) && 6140 "omp simd loop exprs were not built"); 6141 6142 if (!CurContext->isDependentContext()) { 6143 // Finalize the clauses that need pre-built expressions for CodeGen. 6144 for (OMPClause *C : Clauses) { 6145 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6146 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6147 B.NumIterations, *this, CurScope, 6148 DSAStack)) 6149 return StmtError(); 6150 } 6151 } 6152 6153 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6154 return StmtError(); 6155 6156 setFunctionHasBranchProtectedScope(); 6157 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6158 Clauses, AStmt, B); 6159 } 6160 6161 StmtResult 6162 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6163 SourceLocation StartLoc, SourceLocation EndLoc, 6164 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6165 if (!AStmt) 6166 return StmtError(); 6167 6168 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6169 OMPLoopDirective::HelperExprs B; 6170 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6171 // define the nested loops number. 6172 unsigned NestedLoopCount = checkOpenMPLoop( 6173 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6174 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6175 if (NestedLoopCount == 0) 6176 return StmtError(); 6177 6178 assert((CurContext->isDependentContext() || B.builtAll()) && 6179 "omp for loop exprs were not built"); 6180 6181 if (!CurContext->isDependentContext()) { 6182 // Finalize the clauses that need pre-built expressions for CodeGen. 6183 for (OMPClause *C : Clauses) { 6184 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6185 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6186 B.NumIterations, *this, CurScope, 6187 DSAStack)) 6188 return StmtError(); 6189 } 6190 } 6191 6192 setFunctionHasBranchProtectedScope(); 6193 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6194 Clauses, AStmt, B, DSAStack->isCancelRegion()); 6195 } 6196 6197 StmtResult Sema::ActOnOpenMPForSimdDirective( 6198 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6199 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6200 if (!AStmt) 6201 return StmtError(); 6202 6203 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6204 OMPLoopDirective::HelperExprs B; 6205 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6206 // define the nested loops number. 6207 unsigned NestedLoopCount = 6208 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 6209 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6210 VarsWithImplicitDSA, B); 6211 if (NestedLoopCount == 0) 6212 return StmtError(); 6213 6214 assert((CurContext->isDependentContext() || B.builtAll()) && 6215 "omp for simd loop exprs were not built"); 6216 6217 if (!CurContext->isDependentContext()) { 6218 // Finalize the clauses that need pre-built expressions for CodeGen. 6219 for (OMPClause *C : Clauses) { 6220 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6221 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6222 B.NumIterations, *this, CurScope, 6223 DSAStack)) 6224 return StmtError(); 6225 } 6226 } 6227 6228 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6229 return StmtError(); 6230 6231 setFunctionHasBranchProtectedScope(); 6232 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6233 Clauses, AStmt, B); 6234 } 6235 6236 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 6237 Stmt *AStmt, 6238 SourceLocation StartLoc, 6239 SourceLocation EndLoc) { 6240 if (!AStmt) 6241 return StmtError(); 6242 6243 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6244 auto BaseStmt = AStmt; 6245 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6246 BaseStmt = CS->getCapturedStmt(); 6247 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6248 auto S = C->children(); 6249 if (S.begin() == S.end()) 6250 return StmtError(); 6251 // All associated statements must be '#pragma omp section' except for 6252 // the first one. 6253 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6254 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6255 if (SectionStmt) 6256 Diag(SectionStmt->getBeginLoc(), 6257 diag::err_omp_sections_substmt_not_section); 6258 return StmtError(); 6259 } 6260 cast<OMPSectionDirective>(SectionStmt) 6261 ->setHasCancel(DSAStack->isCancelRegion()); 6262 } 6263 } else { 6264 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 6265 return StmtError(); 6266 } 6267 6268 setFunctionHasBranchProtectedScope(); 6269 6270 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6271 DSAStack->isCancelRegion()); 6272 } 6273 6274 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 6275 SourceLocation StartLoc, 6276 SourceLocation EndLoc) { 6277 if (!AStmt) 6278 return StmtError(); 6279 6280 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6281 6282 setFunctionHasBranchProtectedScope(); 6283 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 6284 6285 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 6286 DSAStack->isCancelRegion()); 6287 } 6288 6289 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 6290 Stmt *AStmt, 6291 SourceLocation StartLoc, 6292 SourceLocation EndLoc) { 6293 if (!AStmt) 6294 return StmtError(); 6295 6296 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6297 6298 setFunctionHasBranchProtectedScope(); 6299 6300 // OpenMP [2.7.3, single Construct, Restrictions] 6301 // The copyprivate clause must not be used with the nowait clause. 6302 const OMPClause *Nowait = nullptr; 6303 const OMPClause *Copyprivate = nullptr; 6304 for (const OMPClause *Clause : Clauses) { 6305 if (Clause->getClauseKind() == OMPC_nowait) 6306 Nowait = Clause; 6307 else if (Clause->getClauseKind() == OMPC_copyprivate) 6308 Copyprivate = Clause; 6309 if (Copyprivate && Nowait) { 6310 Diag(Copyprivate->getBeginLoc(), 6311 diag::err_omp_single_copyprivate_with_nowait); 6312 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 6313 return StmtError(); 6314 } 6315 } 6316 6317 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6318 } 6319 6320 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 6321 SourceLocation StartLoc, 6322 SourceLocation EndLoc) { 6323 if (!AStmt) 6324 return StmtError(); 6325 6326 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6327 6328 setFunctionHasBranchProtectedScope(); 6329 6330 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 6331 } 6332 6333 StmtResult Sema::ActOnOpenMPCriticalDirective( 6334 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 6335 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 6336 if (!AStmt) 6337 return StmtError(); 6338 6339 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6340 6341 bool ErrorFound = false; 6342 llvm::APSInt Hint; 6343 SourceLocation HintLoc; 6344 bool DependentHint = false; 6345 for (const OMPClause *C : Clauses) { 6346 if (C->getClauseKind() == OMPC_hint) { 6347 if (!DirName.getName()) { 6348 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 6349 ErrorFound = true; 6350 } 6351 Expr *E = cast<OMPHintClause>(C)->getHint(); 6352 if (E->isTypeDependent() || E->isValueDependent() || 6353 E->isInstantiationDependent()) { 6354 DependentHint = true; 6355 } else { 6356 Hint = E->EvaluateKnownConstInt(Context); 6357 HintLoc = C->getBeginLoc(); 6358 } 6359 } 6360 } 6361 if (ErrorFound) 6362 return StmtError(); 6363 const auto Pair = DSAStack->getCriticalWithHint(DirName); 6364 if (Pair.first && DirName.getName() && !DependentHint) { 6365 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 6366 Diag(StartLoc, diag::err_omp_critical_with_hint); 6367 if (HintLoc.isValid()) 6368 Diag(HintLoc, diag::note_omp_critical_hint_here) 6369 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 6370 else 6371 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 6372 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 6373 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 6374 << 1 6375 << C->getHint()->EvaluateKnownConstInt(Context).toString( 6376 /*Radix=*/10, /*Signed=*/false); 6377 } else { 6378 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 6379 } 6380 } 6381 } 6382 6383 setFunctionHasBranchProtectedScope(); 6384 6385 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 6386 Clauses, AStmt); 6387 if (!Pair.first && DirName.getName() && !DependentHint) 6388 DSAStack->addCriticalWithHint(Dir, Hint); 6389 return Dir; 6390 } 6391 6392 StmtResult Sema::ActOnOpenMPParallelForDirective( 6393 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6394 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6395 if (!AStmt) 6396 return StmtError(); 6397 6398 auto *CS = cast<CapturedStmt>(AStmt); 6399 // 1.2.2 OpenMP Language Terminology 6400 // Structured block - An executable statement with a single entry at the 6401 // top and a single exit at the bottom. 6402 // The point of exit cannot be a branch out of the structured block. 6403 // longjmp() and throw() must not violate the entry/exit criteria. 6404 CS->getCapturedDecl()->setNothrow(); 6405 6406 OMPLoopDirective::HelperExprs B; 6407 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6408 // define the nested loops number. 6409 unsigned NestedLoopCount = 6410 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 6411 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6412 VarsWithImplicitDSA, B); 6413 if (NestedLoopCount == 0) 6414 return StmtError(); 6415 6416 assert((CurContext->isDependentContext() || B.builtAll()) && 6417 "omp parallel for loop exprs were not built"); 6418 6419 if (!CurContext->isDependentContext()) { 6420 // Finalize the clauses that need pre-built expressions for CodeGen. 6421 for (OMPClause *C : Clauses) { 6422 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6423 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6424 B.NumIterations, *this, CurScope, 6425 DSAStack)) 6426 return StmtError(); 6427 } 6428 } 6429 6430 setFunctionHasBranchProtectedScope(); 6431 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 6432 NestedLoopCount, Clauses, AStmt, B, 6433 DSAStack->isCancelRegion()); 6434 } 6435 6436 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 6437 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6438 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6439 if (!AStmt) 6440 return StmtError(); 6441 6442 auto *CS = cast<CapturedStmt>(AStmt); 6443 // 1.2.2 OpenMP Language Terminology 6444 // Structured block - An executable statement with a single entry at the 6445 // top and a single exit at the bottom. 6446 // The point of exit cannot be a branch out of the structured block. 6447 // longjmp() and throw() must not violate the entry/exit criteria. 6448 CS->getCapturedDecl()->setNothrow(); 6449 6450 OMPLoopDirective::HelperExprs B; 6451 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6452 // define the nested loops number. 6453 unsigned NestedLoopCount = 6454 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 6455 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6456 VarsWithImplicitDSA, B); 6457 if (NestedLoopCount == 0) 6458 return StmtError(); 6459 6460 if (!CurContext->isDependentContext()) { 6461 // Finalize the clauses that need pre-built expressions for CodeGen. 6462 for (OMPClause *C : Clauses) { 6463 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6464 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6465 B.NumIterations, *this, CurScope, 6466 DSAStack)) 6467 return StmtError(); 6468 } 6469 } 6470 6471 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6472 return StmtError(); 6473 6474 setFunctionHasBranchProtectedScope(); 6475 return OMPParallelForSimdDirective::Create( 6476 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6477 } 6478 6479 StmtResult 6480 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 6481 Stmt *AStmt, SourceLocation StartLoc, 6482 SourceLocation EndLoc) { 6483 if (!AStmt) 6484 return StmtError(); 6485 6486 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6487 auto BaseStmt = AStmt; 6488 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6489 BaseStmt = CS->getCapturedStmt(); 6490 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6491 auto S = C->children(); 6492 if (S.begin() == S.end()) 6493 return StmtError(); 6494 // All associated statements must be '#pragma omp section' except for 6495 // the first one. 6496 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6497 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6498 if (SectionStmt) 6499 Diag(SectionStmt->getBeginLoc(), 6500 diag::err_omp_parallel_sections_substmt_not_section); 6501 return StmtError(); 6502 } 6503 cast<OMPSectionDirective>(SectionStmt) 6504 ->setHasCancel(DSAStack->isCancelRegion()); 6505 } 6506 } else { 6507 Diag(AStmt->getBeginLoc(), 6508 diag::err_omp_parallel_sections_not_compound_stmt); 6509 return StmtError(); 6510 } 6511 6512 setFunctionHasBranchProtectedScope(); 6513 6514 return OMPParallelSectionsDirective::Create( 6515 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 6516 } 6517 6518 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 6519 Stmt *AStmt, SourceLocation StartLoc, 6520 SourceLocation EndLoc) { 6521 if (!AStmt) 6522 return StmtError(); 6523 6524 auto *CS = cast<CapturedStmt>(AStmt); 6525 // 1.2.2 OpenMP Language Terminology 6526 // Structured block - An executable statement with a single entry at the 6527 // top and a single exit at the bottom. 6528 // The point of exit cannot be a branch out of the structured block. 6529 // longjmp() and throw() must not violate the entry/exit criteria. 6530 CS->getCapturedDecl()->setNothrow(); 6531 6532 setFunctionHasBranchProtectedScope(); 6533 6534 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6535 DSAStack->isCancelRegion()); 6536 } 6537 6538 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 6539 SourceLocation EndLoc) { 6540 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 6541 } 6542 6543 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 6544 SourceLocation EndLoc) { 6545 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 6546 } 6547 6548 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 6549 SourceLocation EndLoc) { 6550 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 6551 } 6552 6553 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 6554 Stmt *AStmt, 6555 SourceLocation StartLoc, 6556 SourceLocation EndLoc) { 6557 if (!AStmt) 6558 return StmtError(); 6559 6560 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6561 6562 setFunctionHasBranchProtectedScope(); 6563 6564 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 6565 AStmt, 6566 DSAStack->getTaskgroupReductionRef()); 6567 } 6568 6569 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 6570 SourceLocation StartLoc, 6571 SourceLocation EndLoc) { 6572 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 6573 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 6574 } 6575 6576 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 6577 Stmt *AStmt, 6578 SourceLocation StartLoc, 6579 SourceLocation EndLoc) { 6580 const OMPClause *DependFound = nullptr; 6581 const OMPClause *DependSourceClause = nullptr; 6582 const OMPClause *DependSinkClause = nullptr; 6583 bool ErrorFound = false; 6584 const OMPThreadsClause *TC = nullptr; 6585 const OMPSIMDClause *SC = nullptr; 6586 for (const OMPClause *C : Clauses) { 6587 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 6588 DependFound = C; 6589 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 6590 if (DependSourceClause) { 6591 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 6592 << getOpenMPDirectiveName(OMPD_ordered) 6593 << getOpenMPClauseName(OMPC_depend) << 2; 6594 ErrorFound = true; 6595 } else { 6596 DependSourceClause = C; 6597 } 6598 if (DependSinkClause) { 6599 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 6600 << 0; 6601 ErrorFound = true; 6602 } 6603 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 6604 if (DependSourceClause) { 6605 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 6606 << 1; 6607 ErrorFound = true; 6608 } 6609 DependSinkClause = C; 6610 } 6611 } else if (C->getClauseKind() == OMPC_threads) { 6612 TC = cast<OMPThreadsClause>(C); 6613 } else if (C->getClauseKind() == OMPC_simd) { 6614 SC = cast<OMPSIMDClause>(C); 6615 } 6616 } 6617 if (!ErrorFound && !SC && 6618 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 6619 // OpenMP [2.8.1,simd Construct, Restrictions] 6620 // An ordered construct with the simd clause is the only OpenMP construct 6621 // that can appear in the simd region. 6622 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 6623 ErrorFound = true; 6624 } else if (DependFound && (TC || SC)) { 6625 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 6626 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 6627 ErrorFound = true; 6628 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 6629 Diag(DependFound->getBeginLoc(), 6630 diag::err_omp_ordered_directive_without_param); 6631 ErrorFound = true; 6632 } else if (TC || Clauses.empty()) { 6633 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 6634 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 6635 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 6636 << (TC != nullptr); 6637 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 6638 ErrorFound = true; 6639 } 6640 } 6641 if ((!AStmt && !DependFound) || ErrorFound) 6642 return StmtError(); 6643 6644 if (AStmt) { 6645 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6646 6647 setFunctionHasBranchProtectedScope(); 6648 } 6649 6650 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6651 } 6652 6653 namespace { 6654 /// Helper class for checking expression in 'omp atomic [update]' 6655 /// construct. 6656 class OpenMPAtomicUpdateChecker { 6657 /// Error results for atomic update expressions. 6658 enum ExprAnalysisErrorCode { 6659 /// A statement is not an expression statement. 6660 NotAnExpression, 6661 /// Expression is not builtin binary or unary operation. 6662 NotABinaryOrUnaryExpression, 6663 /// Unary operation is not post-/pre- increment/decrement operation. 6664 NotAnUnaryIncDecExpression, 6665 /// An expression is not of scalar type. 6666 NotAScalarType, 6667 /// A binary operation is not an assignment operation. 6668 NotAnAssignmentOp, 6669 /// RHS part of the binary operation is not a binary expression. 6670 NotABinaryExpression, 6671 /// RHS part is not additive/multiplicative/shift/biwise binary 6672 /// expression. 6673 NotABinaryOperator, 6674 /// RHS binary operation does not have reference to the updated LHS 6675 /// part. 6676 NotAnUpdateExpression, 6677 /// No errors is found. 6678 NoError 6679 }; 6680 /// Reference to Sema. 6681 Sema &SemaRef; 6682 /// A location for note diagnostics (when error is found). 6683 SourceLocation NoteLoc; 6684 /// 'x' lvalue part of the source atomic expression. 6685 Expr *X; 6686 /// 'expr' rvalue part of the source atomic expression. 6687 Expr *E; 6688 /// Helper expression of the form 6689 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 6690 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 6691 Expr *UpdateExpr; 6692 /// Is 'x' a LHS in a RHS part of full update expression. It is 6693 /// important for non-associative operations. 6694 bool IsXLHSInRHSPart; 6695 BinaryOperatorKind Op; 6696 SourceLocation OpLoc; 6697 /// true if the source expression is a postfix unary operation, false 6698 /// if it is a prefix unary operation. 6699 bool IsPostfixUpdate; 6700 6701 public: 6702 OpenMPAtomicUpdateChecker(Sema &SemaRef) 6703 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 6704 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 6705 /// Check specified statement that it is suitable for 'atomic update' 6706 /// constructs and extract 'x', 'expr' and Operation from the original 6707 /// expression. If DiagId and NoteId == 0, then only check is performed 6708 /// without error notification. 6709 /// \param DiagId Diagnostic which should be emitted if error is found. 6710 /// \param NoteId Diagnostic note for the main error message. 6711 /// \return true if statement is not an update expression, false otherwise. 6712 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 6713 /// Return the 'x' lvalue part of the source atomic expression. 6714 Expr *getX() const { return X; } 6715 /// Return the 'expr' rvalue part of the source atomic expression. 6716 Expr *getExpr() const { return E; } 6717 /// Return the update expression used in calculation of the updated 6718 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 6719 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 6720 Expr *getUpdateExpr() const { return UpdateExpr; } 6721 /// Return true if 'x' is LHS in RHS part of full update expression, 6722 /// false otherwise. 6723 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 6724 6725 /// true if the source expression is a postfix unary operation, false 6726 /// if it is a prefix unary operation. 6727 bool isPostfixUpdate() const { return IsPostfixUpdate; } 6728 6729 private: 6730 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 6731 unsigned NoteId = 0); 6732 }; 6733 } // namespace 6734 6735 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 6736 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 6737 ExprAnalysisErrorCode ErrorFound = NoError; 6738 SourceLocation ErrorLoc, NoteLoc; 6739 SourceRange ErrorRange, NoteRange; 6740 // Allowed constructs are: 6741 // x = x binop expr; 6742 // x = expr binop x; 6743 if (AtomicBinOp->getOpcode() == BO_Assign) { 6744 X = AtomicBinOp->getLHS(); 6745 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 6746 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 6747 if (AtomicInnerBinOp->isMultiplicativeOp() || 6748 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 6749 AtomicInnerBinOp->isBitwiseOp()) { 6750 Op = AtomicInnerBinOp->getOpcode(); 6751 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 6752 Expr *LHS = AtomicInnerBinOp->getLHS(); 6753 Expr *RHS = AtomicInnerBinOp->getRHS(); 6754 llvm::FoldingSetNodeID XId, LHSId, RHSId; 6755 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 6756 /*Canonical=*/true); 6757 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 6758 /*Canonical=*/true); 6759 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 6760 /*Canonical=*/true); 6761 if (XId == LHSId) { 6762 E = RHS; 6763 IsXLHSInRHSPart = true; 6764 } else if (XId == RHSId) { 6765 E = LHS; 6766 IsXLHSInRHSPart = false; 6767 } else { 6768 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6769 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6770 NoteLoc = X->getExprLoc(); 6771 NoteRange = X->getSourceRange(); 6772 ErrorFound = NotAnUpdateExpression; 6773 } 6774 } else { 6775 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6776 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6777 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 6778 NoteRange = SourceRange(NoteLoc, NoteLoc); 6779 ErrorFound = NotABinaryOperator; 6780 } 6781 } else { 6782 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 6783 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 6784 ErrorFound = NotABinaryExpression; 6785 } 6786 } else { 6787 ErrorLoc = AtomicBinOp->getExprLoc(); 6788 ErrorRange = AtomicBinOp->getSourceRange(); 6789 NoteLoc = AtomicBinOp->getOperatorLoc(); 6790 NoteRange = SourceRange(NoteLoc, NoteLoc); 6791 ErrorFound = NotAnAssignmentOp; 6792 } 6793 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6794 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6795 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6796 return true; 6797 } 6798 if (SemaRef.CurContext->isDependentContext()) 6799 E = X = UpdateExpr = nullptr; 6800 return ErrorFound != NoError; 6801 } 6802 6803 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 6804 unsigned NoteId) { 6805 ExprAnalysisErrorCode ErrorFound = NoError; 6806 SourceLocation ErrorLoc, NoteLoc; 6807 SourceRange ErrorRange, NoteRange; 6808 // Allowed constructs are: 6809 // x++; 6810 // x--; 6811 // ++x; 6812 // --x; 6813 // x binop= expr; 6814 // x = x binop expr; 6815 // x = expr binop x; 6816 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 6817 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 6818 if (AtomicBody->getType()->isScalarType() || 6819 AtomicBody->isInstantiationDependent()) { 6820 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 6821 AtomicBody->IgnoreParenImpCasts())) { 6822 // Check for Compound Assignment Operation 6823 Op = BinaryOperator::getOpForCompoundAssignment( 6824 AtomicCompAssignOp->getOpcode()); 6825 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 6826 E = AtomicCompAssignOp->getRHS(); 6827 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 6828 IsXLHSInRHSPart = true; 6829 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 6830 AtomicBody->IgnoreParenImpCasts())) { 6831 // Check for Binary Operation 6832 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 6833 return true; 6834 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 6835 AtomicBody->IgnoreParenImpCasts())) { 6836 // Check for Unary Operation 6837 if (AtomicUnaryOp->isIncrementDecrementOp()) { 6838 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 6839 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 6840 OpLoc = AtomicUnaryOp->getOperatorLoc(); 6841 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 6842 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 6843 IsXLHSInRHSPart = true; 6844 } else { 6845 ErrorFound = NotAnUnaryIncDecExpression; 6846 ErrorLoc = AtomicUnaryOp->getExprLoc(); 6847 ErrorRange = AtomicUnaryOp->getSourceRange(); 6848 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 6849 NoteRange = SourceRange(NoteLoc, NoteLoc); 6850 } 6851 } else if (!AtomicBody->isInstantiationDependent()) { 6852 ErrorFound = NotABinaryOrUnaryExpression; 6853 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 6854 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 6855 } 6856 } else { 6857 ErrorFound = NotAScalarType; 6858 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 6859 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6860 } 6861 } else { 6862 ErrorFound = NotAnExpression; 6863 NoteLoc = ErrorLoc = S->getBeginLoc(); 6864 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6865 } 6866 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6867 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6868 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6869 return true; 6870 } 6871 if (SemaRef.CurContext->isDependentContext()) 6872 E = X = UpdateExpr = nullptr; 6873 if (ErrorFound == NoError && E && X) { 6874 // Build an update expression of form 'OpaqueValueExpr(x) binop 6875 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 6876 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 6877 auto *OVEX = new (SemaRef.getASTContext()) 6878 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 6879 auto *OVEExpr = new (SemaRef.getASTContext()) 6880 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 6881 ExprResult Update = 6882 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 6883 IsXLHSInRHSPart ? OVEExpr : OVEX); 6884 if (Update.isInvalid()) 6885 return true; 6886 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 6887 Sema::AA_Casting); 6888 if (Update.isInvalid()) 6889 return true; 6890 UpdateExpr = Update.get(); 6891 } 6892 return ErrorFound != NoError; 6893 } 6894 6895 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 6896 Stmt *AStmt, 6897 SourceLocation StartLoc, 6898 SourceLocation EndLoc) { 6899 if (!AStmt) 6900 return StmtError(); 6901 6902 auto *CS = cast<CapturedStmt>(AStmt); 6903 // 1.2.2 OpenMP Language Terminology 6904 // Structured block - An executable statement with a single entry at the 6905 // top and a single exit at the bottom. 6906 // The point of exit cannot be a branch out of the structured block. 6907 // longjmp() and throw() must not violate the entry/exit criteria. 6908 OpenMPClauseKind AtomicKind = OMPC_unknown; 6909 SourceLocation AtomicKindLoc; 6910 for (const OMPClause *C : Clauses) { 6911 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 6912 C->getClauseKind() == OMPC_update || 6913 C->getClauseKind() == OMPC_capture) { 6914 if (AtomicKind != OMPC_unknown) { 6915 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 6916 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 6917 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 6918 << getOpenMPClauseName(AtomicKind); 6919 } else { 6920 AtomicKind = C->getClauseKind(); 6921 AtomicKindLoc = C->getBeginLoc(); 6922 } 6923 } 6924 } 6925 6926 Stmt *Body = CS->getCapturedStmt(); 6927 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 6928 Body = EWC->getSubExpr(); 6929 6930 Expr *X = nullptr; 6931 Expr *V = nullptr; 6932 Expr *E = nullptr; 6933 Expr *UE = nullptr; 6934 bool IsXLHSInRHSPart = false; 6935 bool IsPostfixUpdate = false; 6936 // OpenMP [2.12.6, atomic Construct] 6937 // In the next expressions: 6938 // * x and v (as applicable) are both l-value expressions with scalar type. 6939 // * During the execution of an atomic region, multiple syntactic 6940 // occurrences of x must designate the same storage location. 6941 // * Neither of v and expr (as applicable) may access the storage location 6942 // designated by x. 6943 // * Neither of x and expr (as applicable) may access the storage location 6944 // designated by v. 6945 // * expr is an expression with scalar type. 6946 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 6947 // * binop, binop=, ++, and -- are not overloaded operators. 6948 // * The expression x binop expr must be numerically equivalent to x binop 6949 // (expr). This requirement is satisfied if the operators in expr have 6950 // precedence greater than binop, or by using parentheses around expr or 6951 // subexpressions of expr. 6952 // * The expression expr binop x must be numerically equivalent to (expr) 6953 // binop x. This requirement is satisfied if the operators in expr have 6954 // precedence equal to or greater than binop, or by using parentheses around 6955 // expr or subexpressions of expr. 6956 // * For forms that allow multiple occurrences of x, the number of times 6957 // that x is evaluated is unspecified. 6958 if (AtomicKind == OMPC_read) { 6959 enum { 6960 NotAnExpression, 6961 NotAnAssignmentOp, 6962 NotAScalarType, 6963 NotAnLValue, 6964 NoError 6965 } ErrorFound = NoError; 6966 SourceLocation ErrorLoc, NoteLoc; 6967 SourceRange ErrorRange, NoteRange; 6968 // If clause is read: 6969 // v = x; 6970 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6971 const auto *AtomicBinOp = 6972 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6973 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6974 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6975 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 6976 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6977 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 6978 if (!X->isLValue() || !V->isLValue()) { 6979 const Expr *NotLValueExpr = X->isLValue() ? V : X; 6980 ErrorFound = NotAnLValue; 6981 ErrorLoc = AtomicBinOp->getExprLoc(); 6982 ErrorRange = AtomicBinOp->getSourceRange(); 6983 NoteLoc = NotLValueExpr->getExprLoc(); 6984 NoteRange = NotLValueExpr->getSourceRange(); 6985 } 6986 } else if (!X->isInstantiationDependent() || 6987 !V->isInstantiationDependent()) { 6988 const Expr *NotScalarExpr = 6989 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6990 ? V 6991 : X; 6992 ErrorFound = NotAScalarType; 6993 ErrorLoc = AtomicBinOp->getExprLoc(); 6994 ErrorRange = AtomicBinOp->getSourceRange(); 6995 NoteLoc = NotScalarExpr->getExprLoc(); 6996 NoteRange = NotScalarExpr->getSourceRange(); 6997 } 6998 } else if (!AtomicBody->isInstantiationDependent()) { 6999 ErrorFound = NotAnAssignmentOp; 7000 ErrorLoc = AtomicBody->getExprLoc(); 7001 ErrorRange = AtomicBody->getSourceRange(); 7002 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7003 : AtomicBody->getExprLoc(); 7004 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7005 : AtomicBody->getSourceRange(); 7006 } 7007 } else { 7008 ErrorFound = NotAnExpression; 7009 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7010 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7011 } 7012 if (ErrorFound != NoError) { 7013 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 7014 << ErrorRange; 7015 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7016 << NoteRange; 7017 return StmtError(); 7018 } 7019 if (CurContext->isDependentContext()) 7020 V = X = nullptr; 7021 } else if (AtomicKind == OMPC_write) { 7022 enum { 7023 NotAnExpression, 7024 NotAnAssignmentOp, 7025 NotAScalarType, 7026 NotAnLValue, 7027 NoError 7028 } ErrorFound = NoError; 7029 SourceLocation ErrorLoc, NoteLoc; 7030 SourceRange ErrorRange, NoteRange; 7031 // If clause is write: 7032 // x = expr; 7033 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7034 const auto *AtomicBinOp = 7035 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7036 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7037 X = AtomicBinOp->getLHS(); 7038 E = AtomicBinOp->getRHS(); 7039 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 7040 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 7041 if (!X->isLValue()) { 7042 ErrorFound = NotAnLValue; 7043 ErrorLoc = AtomicBinOp->getExprLoc(); 7044 ErrorRange = AtomicBinOp->getSourceRange(); 7045 NoteLoc = X->getExprLoc(); 7046 NoteRange = X->getSourceRange(); 7047 } 7048 } else if (!X->isInstantiationDependent() || 7049 !E->isInstantiationDependent()) { 7050 const Expr *NotScalarExpr = 7051 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7052 ? E 7053 : X; 7054 ErrorFound = NotAScalarType; 7055 ErrorLoc = AtomicBinOp->getExprLoc(); 7056 ErrorRange = AtomicBinOp->getSourceRange(); 7057 NoteLoc = NotScalarExpr->getExprLoc(); 7058 NoteRange = NotScalarExpr->getSourceRange(); 7059 } 7060 } else if (!AtomicBody->isInstantiationDependent()) { 7061 ErrorFound = NotAnAssignmentOp; 7062 ErrorLoc = AtomicBody->getExprLoc(); 7063 ErrorRange = AtomicBody->getSourceRange(); 7064 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7065 : AtomicBody->getExprLoc(); 7066 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7067 : AtomicBody->getSourceRange(); 7068 } 7069 } else { 7070 ErrorFound = NotAnExpression; 7071 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7072 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7073 } 7074 if (ErrorFound != NoError) { 7075 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 7076 << ErrorRange; 7077 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7078 << NoteRange; 7079 return StmtError(); 7080 } 7081 if (CurContext->isDependentContext()) 7082 E = X = nullptr; 7083 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 7084 // If clause is update: 7085 // x++; 7086 // x--; 7087 // ++x; 7088 // --x; 7089 // x binop= expr; 7090 // x = x binop expr; 7091 // x = expr binop x; 7092 OpenMPAtomicUpdateChecker Checker(*this); 7093 if (Checker.checkStatement( 7094 Body, (AtomicKind == OMPC_update) 7095 ? diag::err_omp_atomic_update_not_expression_statement 7096 : diag::err_omp_atomic_not_expression_statement, 7097 diag::note_omp_atomic_update)) 7098 return StmtError(); 7099 if (!CurContext->isDependentContext()) { 7100 E = Checker.getExpr(); 7101 X = Checker.getX(); 7102 UE = Checker.getUpdateExpr(); 7103 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7104 } 7105 } else if (AtomicKind == OMPC_capture) { 7106 enum { 7107 NotAnAssignmentOp, 7108 NotACompoundStatement, 7109 NotTwoSubstatements, 7110 NotASpecificExpression, 7111 NoError 7112 } ErrorFound = NoError; 7113 SourceLocation ErrorLoc, NoteLoc; 7114 SourceRange ErrorRange, NoteRange; 7115 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7116 // If clause is a capture: 7117 // v = x++; 7118 // v = x--; 7119 // v = ++x; 7120 // v = --x; 7121 // v = x binop= expr; 7122 // v = x = x binop expr; 7123 // v = x = expr binop x; 7124 const auto *AtomicBinOp = 7125 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7126 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7127 V = AtomicBinOp->getLHS(); 7128 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7129 OpenMPAtomicUpdateChecker Checker(*this); 7130 if (Checker.checkStatement( 7131 Body, diag::err_omp_atomic_capture_not_expression_statement, 7132 diag::note_omp_atomic_update)) 7133 return StmtError(); 7134 E = Checker.getExpr(); 7135 X = Checker.getX(); 7136 UE = Checker.getUpdateExpr(); 7137 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7138 IsPostfixUpdate = Checker.isPostfixUpdate(); 7139 } else if (!AtomicBody->isInstantiationDependent()) { 7140 ErrorLoc = AtomicBody->getExprLoc(); 7141 ErrorRange = AtomicBody->getSourceRange(); 7142 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7143 : AtomicBody->getExprLoc(); 7144 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7145 : AtomicBody->getSourceRange(); 7146 ErrorFound = NotAnAssignmentOp; 7147 } 7148 if (ErrorFound != NoError) { 7149 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 7150 << ErrorRange; 7151 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7152 return StmtError(); 7153 } 7154 if (CurContext->isDependentContext()) 7155 UE = V = E = X = nullptr; 7156 } else { 7157 // If clause is a capture: 7158 // { v = x; x = expr; } 7159 // { v = x; x++; } 7160 // { v = x; x--; } 7161 // { v = x; ++x; } 7162 // { v = x; --x; } 7163 // { v = x; x binop= expr; } 7164 // { v = x; x = x binop expr; } 7165 // { v = x; x = expr binop x; } 7166 // { x++; v = x; } 7167 // { x--; v = x; } 7168 // { ++x; v = x; } 7169 // { --x; v = x; } 7170 // { x binop= expr; v = x; } 7171 // { x = x binop expr; v = x; } 7172 // { x = expr binop x; v = x; } 7173 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 7174 // Check that this is { expr1; expr2; } 7175 if (CS->size() == 2) { 7176 Stmt *First = CS->body_front(); 7177 Stmt *Second = CS->body_back(); 7178 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 7179 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 7180 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 7181 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 7182 // Need to find what subexpression is 'v' and what is 'x'. 7183 OpenMPAtomicUpdateChecker Checker(*this); 7184 bool IsUpdateExprFound = !Checker.checkStatement(Second); 7185 BinaryOperator *BinOp = nullptr; 7186 if (IsUpdateExprFound) { 7187 BinOp = dyn_cast<BinaryOperator>(First); 7188 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7189 } 7190 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7191 // { v = x; x++; } 7192 // { v = x; x--; } 7193 // { v = x; ++x; } 7194 // { v = x; --x; } 7195 // { v = x; x binop= expr; } 7196 // { v = x; x = x binop expr; } 7197 // { v = x; x = expr binop x; } 7198 // Check that the first expression has form v = x. 7199 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7200 llvm::FoldingSetNodeID XId, PossibleXId; 7201 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7202 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7203 IsUpdateExprFound = XId == PossibleXId; 7204 if (IsUpdateExprFound) { 7205 V = BinOp->getLHS(); 7206 X = Checker.getX(); 7207 E = Checker.getExpr(); 7208 UE = Checker.getUpdateExpr(); 7209 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7210 IsPostfixUpdate = true; 7211 } 7212 } 7213 if (!IsUpdateExprFound) { 7214 IsUpdateExprFound = !Checker.checkStatement(First); 7215 BinOp = nullptr; 7216 if (IsUpdateExprFound) { 7217 BinOp = dyn_cast<BinaryOperator>(Second); 7218 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7219 } 7220 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7221 // { x++; v = x; } 7222 // { x--; v = x; } 7223 // { ++x; v = x; } 7224 // { --x; v = x; } 7225 // { x binop= expr; v = x; } 7226 // { x = x binop expr; v = x; } 7227 // { x = expr binop x; v = x; } 7228 // Check that the second expression has form v = x. 7229 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7230 llvm::FoldingSetNodeID XId, PossibleXId; 7231 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7232 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7233 IsUpdateExprFound = XId == PossibleXId; 7234 if (IsUpdateExprFound) { 7235 V = BinOp->getLHS(); 7236 X = Checker.getX(); 7237 E = Checker.getExpr(); 7238 UE = Checker.getUpdateExpr(); 7239 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7240 IsPostfixUpdate = false; 7241 } 7242 } 7243 } 7244 if (!IsUpdateExprFound) { 7245 // { v = x; x = expr; } 7246 auto *FirstExpr = dyn_cast<Expr>(First); 7247 auto *SecondExpr = dyn_cast<Expr>(Second); 7248 if (!FirstExpr || !SecondExpr || 7249 !(FirstExpr->isInstantiationDependent() || 7250 SecondExpr->isInstantiationDependent())) { 7251 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 7252 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 7253 ErrorFound = NotAnAssignmentOp; 7254 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 7255 : First->getBeginLoc(); 7256 NoteRange = ErrorRange = FirstBinOp 7257 ? FirstBinOp->getSourceRange() 7258 : SourceRange(ErrorLoc, ErrorLoc); 7259 } else { 7260 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 7261 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 7262 ErrorFound = NotAnAssignmentOp; 7263 NoteLoc = ErrorLoc = SecondBinOp 7264 ? SecondBinOp->getOperatorLoc() 7265 : Second->getBeginLoc(); 7266 NoteRange = ErrorRange = 7267 SecondBinOp ? SecondBinOp->getSourceRange() 7268 : SourceRange(ErrorLoc, ErrorLoc); 7269 } else { 7270 Expr *PossibleXRHSInFirst = 7271 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 7272 Expr *PossibleXLHSInSecond = 7273 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 7274 llvm::FoldingSetNodeID X1Id, X2Id; 7275 PossibleXRHSInFirst->Profile(X1Id, Context, 7276 /*Canonical=*/true); 7277 PossibleXLHSInSecond->Profile(X2Id, Context, 7278 /*Canonical=*/true); 7279 IsUpdateExprFound = X1Id == X2Id; 7280 if (IsUpdateExprFound) { 7281 V = FirstBinOp->getLHS(); 7282 X = SecondBinOp->getLHS(); 7283 E = SecondBinOp->getRHS(); 7284 UE = nullptr; 7285 IsXLHSInRHSPart = false; 7286 IsPostfixUpdate = true; 7287 } else { 7288 ErrorFound = NotASpecificExpression; 7289 ErrorLoc = FirstBinOp->getExprLoc(); 7290 ErrorRange = FirstBinOp->getSourceRange(); 7291 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 7292 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 7293 } 7294 } 7295 } 7296 } 7297 } 7298 } else { 7299 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7300 NoteRange = ErrorRange = 7301 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7302 ErrorFound = NotTwoSubstatements; 7303 } 7304 } else { 7305 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7306 NoteRange = ErrorRange = 7307 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7308 ErrorFound = NotACompoundStatement; 7309 } 7310 if (ErrorFound != NoError) { 7311 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 7312 << ErrorRange; 7313 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7314 return StmtError(); 7315 } 7316 if (CurContext->isDependentContext()) 7317 UE = V = E = X = nullptr; 7318 } 7319 } 7320 7321 setFunctionHasBranchProtectedScope(); 7322 7323 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7324 X, V, E, UE, IsXLHSInRHSPart, 7325 IsPostfixUpdate); 7326 } 7327 7328 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 7329 Stmt *AStmt, 7330 SourceLocation StartLoc, 7331 SourceLocation EndLoc) { 7332 if (!AStmt) 7333 return StmtError(); 7334 7335 auto *CS = cast<CapturedStmt>(AStmt); 7336 // 1.2.2 OpenMP Language Terminology 7337 // Structured block - An executable statement with a single entry at the 7338 // top and a single exit at the bottom. 7339 // The point of exit cannot be a branch out of the structured block. 7340 // longjmp() and throw() must not violate the entry/exit criteria. 7341 CS->getCapturedDecl()->setNothrow(); 7342 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 7343 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7344 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7345 // 1.2.2 OpenMP Language Terminology 7346 // Structured block - An executable statement with a single entry at the 7347 // top and a single exit at the bottom. 7348 // The point of exit cannot be a branch out of the structured block. 7349 // longjmp() and throw() must not violate the entry/exit criteria. 7350 CS->getCapturedDecl()->setNothrow(); 7351 } 7352 7353 // OpenMP [2.16, Nesting of Regions] 7354 // If specified, a teams construct must be contained within a target 7355 // construct. That target construct must contain no statements or directives 7356 // outside of the teams construct. 7357 if (DSAStack->hasInnerTeamsRegion()) { 7358 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 7359 bool OMPTeamsFound = true; 7360 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 7361 auto I = CS->body_begin(); 7362 while (I != CS->body_end()) { 7363 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 7364 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 7365 OMPTeamsFound) { 7366 7367 OMPTeamsFound = false; 7368 break; 7369 } 7370 ++I; 7371 } 7372 assert(I != CS->body_end() && "Not found statement"); 7373 S = *I; 7374 } else { 7375 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 7376 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 7377 } 7378 if (!OMPTeamsFound) { 7379 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 7380 Diag(DSAStack->getInnerTeamsRegionLoc(), 7381 diag::note_omp_nested_teams_construct_here); 7382 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 7383 << isa<OMPExecutableDirective>(S); 7384 return StmtError(); 7385 } 7386 } 7387 7388 setFunctionHasBranchProtectedScope(); 7389 7390 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7391 } 7392 7393 StmtResult 7394 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 7395 Stmt *AStmt, SourceLocation StartLoc, 7396 SourceLocation EndLoc) { 7397 if (!AStmt) 7398 return StmtError(); 7399 7400 auto *CS = cast<CapturedStmt>(AStmt); 7401 // 1.2.2 OpenMP Language Terminology 7402 // Structured block - An executable statement with a single entry at the 7403 // top and a single exit at the bottom. 7404 // The point of exit cannot be a branch out of the structured block. 7405 // longjmp() and throw() must not violate the entry/exit criteria. 7406 CS->getCapturedDecl()->setNothrow(); 7407 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 7408 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7409 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7410 // 1.2.2 OpenMP Language Terminology 7411 // Structured block - An executable statement with a single entry at the 7412 // top and a single exit at the bottom. 7413 // The point of exit cannot be a branch out of the structured block. 7414 // longjmp() and throw() must not violate the entry/exit criteria. 7415 CS->getCapturedDecl()->setNothrow(); 7416 } 7417 7418 setFunctionHasBranchProtectedScope(); 7419 7420 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7421 AStmt); 7422 } 7423 7424 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 7425 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7426 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7427 if (!AStmt) 7428 return StmtError(); 7429 7430 auto *CS = cast<CapturedStmt>(AStmt); 7431 // 1.2.2 OpenMP Language Terminology 7432 // Structured block - An executable statement with a single entry at the 7433 // top and a single exit at the bottom. 7434 // The point of exit cannot be a branch out of the structured block. 7435 // longjmp() and throw() must not violate the entry/exit criteria. 7436 CS->getCapturedDecl()->setNothrow(); 7437 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 7438 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7439 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7440 // 1.2.2 OpenMP Language Terminology 7441 // Structured block - An executable statement with a single entry at the 7442 // top and a single exit at the bottom. 7443 // The point of exit cannot be a branch out of the structured block. 7444 // longjmp() and throw() must not violate the entry/exit criteria. 7445 CS->getCapturedDecl()->setNothrow(); 7446 } 7447 7448 OMPLoopDirective::HelperExprs B; 7449 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7450 // define the nested loops number. 7451 unsigned NestedLoopCount = 7452 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 7453 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7454 VarsWithImplicitDSA, B); 7455 if (NestedLoopCount == 0) 7456 return StmtError(); 7457 7458 assert((CurContext->isDependentContext() || B.builtAll()) && 7459 "omp target parallel for loop exprs were not built"); 7460 7461 if (!CurContext->isDependentContext()) { 7462 // Finalize the clauses that need pre-built expressions for CodeGen. 7463 for (OMPClause *C : Clauses) { 7464 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7465 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7466 B.NumIterations, *this, CurScope, 7467 DSAStack)) 7468 return StmtError(); 7469 } 7470 } 7471 7472 setFunctionHasBranchProtectedScope(); 7473 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 7474 NestedLoopCount, Clauses, AStmt, 7475 B, DSAStack->isCancelRegion()); 7476 } 7477 7478 /// Check for existence of a map clause in the list of clauses. 7479 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 7480 const OpenMPClauseKind K) { 7481 return llvm::any_of( 7482 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 7483 } 7484 7485 template <typename... Params> 7486 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 7487 const Params... ClauseTypes) { 7488 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 7489 } 7490 7491 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 7492 Stmt *AStmt, 7493 SourceLocation StartLoc, 7494 SourceLocation EndLoc) { 7495 if (!AStmt) 7496 return StmtError(); 7497 7498 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7499 7500 // OpenMP [2.10.1, Restrictions, p. 97] 7501 // At least one map clause must appear on the directive. 7502 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 7503 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7504 << "'map' or 'use_device_ptr'" 7505 << getOpenMPDirectiveName(OMPD_target_data); 7506 return StmtError(); 7507 } 7508 7509 setFunctionHasBranchProtectedScope(); 7510 7511 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7512 AStmt); 7513 } 7514 7515 StmtResult 7516 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 7517 SourceLocation StartLoc, 7518 SourceLocation EndLoc, Stmt *AStmt) { 7519 if (!AStmt) 7520 return StmtError(); 7521 7522 auto *CS = cast<CapturedStmt>(AStmt); 7523 // 1.2.2 OpenMP Language Terminology 7524 // Structured block - An executable statement with a single entry at the 7525 // top and a single exit at the bottom. 7526 // The point of exit cannot be a branch out of the structured block. 7527 // longjmp() and throw() must not violate the entry/exit criteria. 7528 CS->getCapturedDecl()->setNothrow(); 7529 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 7530 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7531 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7532 // 1.2.2 OpenMP Language Terminology 7533 // Structured block - An executable statement with a single entry at the 7534 // top and a single exit at the bottom. 7535 // The point of exit cannot be a branch out of the structured block. 7536 // longjmp() and throw() must not violate the entry/exit criteria. 7537 CS->getCapturedDecl()->setNothrow(); 7538 } 7539 7540 // OpenMP [2.10.2, Restrictions, p. 99] 7541 // At least one map clause must appear on the directive. 7542 if (!hasClauses(Clauses, OMPC_map)) { 7543 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7544 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 7545 return StmtError(); 7546 } 7547 7548 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7549 AStmt); 7550 } 7551 7552 StmtResult 7553 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 7554 SourceLocation StartLoc, 7555 SourceLocation EndLoc, Stmt *AStmt) { 7556 if (!AStmt) 7557 return StmtError(); 7558 7559 auto *CS = cast<CapturedStmt>(AStmt); 7560 // 1.2.2 OpenMP Language Terminology 7561 // Structured block - An executable statement with a single entry at the 7562 // top and a single exit at the bottom. 7563 // The point of exit cannot be a branch out of the structured block. 7564 // longjmp() and throw() must not violate the entry/exit criteria. 7565 CS->getCapturedDecl()->setNothrow(); 7566 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 7567 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7568 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7569 // 1.2.2 OpenMP Language Terminology 7570 // Structured block - An executable statement with a single entry at the 7571 // top and a single exit at the bottom. 7572 // The point of exit cannot be a branch out of the structured block. 7573 // longjmp() and throw() must not violate the entry/exit criteria. 7574 CS->getCapturedDecl()->setNothrow(); 7575 } 7576 7577 // OpenMP [2.10.3, Restrictions, p. 102] 7578 // At least one map clause must appear on the directive. 7579 if (!hasClauses(Clauses, OMPC_map)) { 7580 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7581 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 7582 return StmtError(); 7583 } 7584 7585 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7586 AStmt); 7587 } 7588 7589 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 7590 SourceLocation StartLoc, 7591 SourceLocation EndLoc, 7592 Stmt *AStmt) { 7593 if (!AStmt) 7594 return StmtError(); 7595 7596 auto *CS = cast<CapturedStmt>(AStmt); 7597 // 1.2.2 OpenMP Language Terminology 7598 // Structured block - An executable statement with a single entry at the 7599 // top and a single exit at the bottom. 7600 // The point of exit cannot be a branch out of the structured block. 7601 // longjmp() and throw() must not violate the entry/exit criteria. 7602 CS->getCapturedDecl()->setNothrow(); 7603 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 7604 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7605 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7606 // 1.2.2 OpenMP Language Terminology 7607 // Structured block - An executable statement with a single entry at the 7608 // top and a single exit at the bottom. 7609 // The point of exit cannot be a branch out of the structured block. 7610 // longjmp() and throw() must not violate the entry/exit criteria. 7611 CS->getCapturedDecl()->setNothrow(); 7612 } 7613 7614 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 7615 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 7616 return StmtError(); 7617 } 7618 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 7619 AStmt); 7620 } 7621 7622 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 7623 Stmt *AStmt, SourceLocation StartLoc, 7624 SourceLocation EndLoc) { 7625 if (!AStmt) 7626 return StmtError(); 7627 7628 auto *CS = cast<CapturedStmt>(AStmt); 7629 // 1.2.2 OpenMP Language Terminology 7630 // Structured block - An executable statement with a single entry at the 7631 // top and a single exit at the bottom. 7632 // The point of exit cannot be a branch out of the structured block. 7633 // longjmp() and throw() must not violate the entry/exit criteria. 7634 CS->getCapturedDecl()->setNothrow(); 7635 7636 setFunctionHasBranchProtectedScope(); 7637 7638 DSAStack->setParentTeamsRegionLoc(StartLoc); 7639 7640 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7641 } 7642 7643 StmtResult 7644 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 7645 SourceLocation EndLoc, 7646 OpenMPDirectiveKind CancelRegion) { 7647 if (DSAStack->isParentNowaitRegion()) { 7648 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 7649 return StmtError(); 7650 } 7651 if (DSAStack->isParentOrderedRegion()) { 7652 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 7653 return StmtError(); 7654 } 7655 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 7656 CancelRegion); 7657 } 7658 7659 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 7660 SourceLocation StartLoc, 7661 SourceLocation EndLoc, 7662 OpenMPDirectiveKind CancelRegion) { 7663 if (DSAStack->isParentNowaitRegion()) { 7664 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 7665 return StmtError(); 7666 } 7667 if (DSAStack->isParentOrderedRegion()) { 7668 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 7669 return StmtError(); 7670 } 7671 DSAStack->setParentCancelRegion(/*Cancel=*/true); 7672 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7673 CancelRegion); 7674 } 7675 7676 static bool checkGrainsizeNumTasksClauses(Sema &S, 7677 ArrayRef<OMPClause *> Clauses) { 7678 const OMPClause *PrevClause = nullptr; 7679 bool ErrorFound = false; 7680 for (const OMPClause *C : Clauses) { 7681 if (C->getClauseKind() == OMPC_grainsize || 7682 C->getClauseKind() == OMPC_num_tasks) { 7683 if (!PrevClause) 7684 PrevClause = C; 7685 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 7686 S.Diag(C->getBeginLoc(), 7687 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 7688 << getOpenMPClauseName(C->getClauseKind()) 7689 << getOpenMPClauseName(PrevClause->getClauseKind()); 7690 S.Diag(PrevClause->getBeginLoc(), 7691 diag::note_omp_previous_grainsize_num_tasks) 7692 << getOpenMPClauseName(PrevClause->getClauseKind()); 7693 ErrorFound = true; 7694 } 7695 } 7696 } 7697 return ErrorFound; 7698 } 7699 7700 static bool checkReductionClauseWithNogroup(Sema &S, 7701 ArrayRef<OMPClause *> Clauses) { 7702 const OMPClause *ReductionClause = nullptr; 7703 const OMPClause *NogroupClause = nullptr; 7704 for (const OMPClause *C : Clauses) { 7705 if (C->getClauseKind() == OMPC_reduction) { 7706 ReductionClause = C; 7707 if (NogroupClause) 7708 break; 7709 continue; 7710 } 7711 if (C->getClauseKind() == OMPC_nogroup) { 7712 NogroupClause = C; 7713 if (ReductionClause) 7714 break; 7715 continue; 7716 } 7717 } 7718 if (ReductionClause && NogroupClause) { 7719 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 7720 << SourceRange(NogroupClause->getBeginLoc(), 7721 NogroupClause->getEndLoc()); 7722 return true; 7723 } 7724 return false; 7725 } 7726 7727 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 7728 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7729 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7730 if (!AStmt) 7731 return StmtError(); 7732 7733 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7734 OMPLoopDirective::HelperExprs B; 7735 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7736 // define the nested loops number. 7737 unsigned NestedLoopCount = 7738 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 7739 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7740 VarsWithImplicitDSA, B); 7741 if (NestedLoopCount == 0) 7742 return StmtError(); 7743 7744 assert((CurContext->isDependentContext() || B.builtAll()) && 7745 "omp for loop exprs were not built"); 7746 7747 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7748 // The grainsize clause and num_tasks clause are mutually exclusive and may 7749 // not appear on the same taskloop directive. 7750 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7751 return StmtError(); 7752 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7753 // If a reduction clause is present on the taskloop directive, the nogroup 7754 // clause must not be specified. 7755 if (checkReductionClauseWithNogroup(*this, Clauses)) 7756 return StmtError(); 7757 7758 setFunctionHasBranchProtectedScope(); 7759 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 7760 NestedLoopCount, Clauses, AStmt, B); 7761 } 7762 7763 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 7764 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7765 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7766 if (!AStmt) 7767 return StmtError(); 7768 7769 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7770 OMPLoopDirective::HelperExprs B; 7771 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7772 // define the nested loops number. 7773 unsigned NestedLoopCount = 7774 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 7775 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7776 VarsWithImplicitDSA, B); 7777 if (NestedLoopCount == 0) 7778 return StmtError(); 7779 7780 assert((CurContext->isDependentContext() || B.builtAll()) && 7781 "omp for loop exprs were not built"); 7782 7783 if (!CurContext->isDependentContext()) { 7784 // Finalize the clauses that need pre-built expressions for CodeGen. 7785 for (OMPClause *C : Clauses) { 7786 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7787 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7788 B.NumIterations, *this, CurScope, 7789 DSAStack)) 7790 return StmtError(); 7791 } 7792 } 7793 7794 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7795 // The grainsize clause and num_tasks clause are mutually exclusive and may 7796 // not appear on the same taskloop directive. 7797 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7798 return StmtError(); 7799 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7800 // If a reduction clause is present on the taskloop directive, the nogroup 7801 // clause must not be specified. 7802 if (checkReductionClauseWithNogroup(*this, Clauses)) 7803 return StmtError(); 7804 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7805 return StmtError(); 7806 7807 setFunctionHasBranchProtectedScope(); 7808 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 7809 NestedLoopCount, Clauses, AStmt, B); 7810 } 7811 7812 StmtResult Sema::ActOnOpenMPDistributeDirective( 7813 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7814 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7815 if (!AStmt) 7816 return StmtError(); 7817 7818 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7819 OMPLoopDirective::HelperExprs B; 7820 // In presence of clause 'collapse' with number of loops, it will 7821 // define the nested loops number. 7822 unsigned NestedLoopCount = 7823 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 7824 nullptr /*ordered not a clause on distribute*/, AStmt, 7825 *this, *DSAStack, VarsWithImplicitDSA, B); 7826 if (NestedLoopCount == 0) 7827 return StmtError(); 7828 7829 assert((CurContext->isDependentContext() || B.builtAll()) && 7830 "omp for loop exprs were not built"); 7831 7832 setFunctionHasBranchProtectedScope(); 7833 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 7834 NestedLoopCount, Clauses, AStmt, B); 7835 } 7836 7837 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 7838 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7839 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7840 if (!AStmt) 7841 return StmtError(); 7842 7843 auto *CS = cast<CapturedStmt>(AStmt); 7844 // 1.2.2 OpenMP Language Terminology 7845 // Structured block - An executable statement with a single entry at the 7846 // top and a single exit at the bottom. 7847 // The point of exit cannot be a branch out of the structured block. 7848 // longjmp() and throw() must not violate the entry/exit criteria. 7849 CS->getCapturedDecl()->setNothrow(); 7850 for (int ThisCaptureLevel = 7851 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 7852 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7853 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7854 // 1.2.2 OpenMP Language Terminology 7855 // Structured block - An executable statement with a single entry at the 7856 // top and a single exit at the bottom. 7857 // The point of exit cannot be a branch out of the structured block. 7858 // longjmp() and throw() must not violate the entry/exit criteria. 7859 CS->getCapturedDecl()->setNothrow(); 7860 } 7861 7862 OMPLoopDirective::HelperExprs B; 7863 // In presence of clause 'collapse' with number of loops, it will 7864 // define the nested loops number. 7865 unsigned NestedLoopCount = checkOpenMPLoop( 7866 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 7867 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7868 VarsWithImplicitDSA, B); 7869 if (NestedLoopCount == 0) 7870 return StmtError(); 7871 7872 assert((CurContext->isDependentContext() || B.builtAll()) && 7873 "omp for loop exprs were not built"); 7874 7875 setFunctionHasBranchProtectedScope(); 7876 return OMPDistributeParallelForDirective::Create( 7877 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 7878 DSAStack->isCancelRegion()); 7879 } 7880 7881 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 7882 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7883 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7884 if (!AStmt) 7885 return StmtError(); 7886 7887 auto *CS = cast<CapturedStmt>(AStmt); 7888 // 1.2.2 OpenMP Language Terminology 7889 // Structured block - An executable statement with a single entry at the 7890 // top and a single exit at the bottom. 7891 // The point of exit cannot be a branch out of the structured block. 7892 // longjmp() and throw() must not violate the entry/exit criteria. 7893 CS->getCapturedDecl()->setNothrow(); 7894 for (int ThisCaptureLevel = 7895 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 7896 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7897 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7898 // 1.2.2 OpenMP Language Terminology 7899 // Structured block - An executable statement with a single entry at the 7900 // top and a single exit at the bottom. 7901 // The point of exit cannot be a branch out of the structured block. 7902 // longjmp() and throw() must not violate the entry/exit criteria. 7903 CS->getCapturedDecl()->setNothrow(); 7904 } 7905 7906 OMPLoopDirective::HelperExprs B; 7907 // In presence of clause 'collapse' with number of loops, it will 7908 // define the nested loops number. 7909 unsigned NestedLoopCount = checkOpenMPLoop( 7910 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 7911 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7912 VarsWithImplicitDSA, B); 7913 if (NestedLoopCount == 0) 7914 return StmtError(); 7915 7916 assert((CurContext->isDependentContext() || B.builtAll()) && 7917 "omp for loop exprs were not built"); 7918 7919 if (!CurContext->isDependentContext()) { 7920 // Finalize the clauses that need pre-built expressions for CodeGen. 7921 for (OMPClause *C : Clauses) { 7922 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7923 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7924 B.NumIterations, *this, CurScope, 7925 DSAStack)) 7926 return StmtError(); 7927 } 7928 } 7929 7930 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7931 return StmtError(); 7932 7933 setFunctionHasBranchProtectedScope(); 7934 return OMPDistributeParallelForSimdDirective::Create( 7935 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7936 } 7937 7938 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 7939 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7940 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7941 if (!AStmt) 7942 return StmtError(); 7943 7944 auto *CS = cast<CapturedStmt>(AStmt); 7945 // 1.2.2 OpenMP Language Terminology 7946 // Structured block - An executable statement with a single entry at the 7947 // top and a single exit at the bottom. 7948 // The point of exit cannot be a branch out of the structured block. 7949 // longjmp() and throw() must not violate the entry/exit criteria. 7950 CS->getCapturedDecl()->setNothrow(); 7951 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 7952 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7953 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7954 // 1.2.2 OpenMP Language Terminology 7955 // Structured block - An executable statement with a single entry at the 7956 // top and a single exit at the bottom. 7957 // The point of exit cannot be a branch out of the structured block. 7958 // longjmp() and throw() must not violate the entry/exit criteria. 7959 CS->getCapturedDecl()->setNothrow(); 7960 } 7961 7962 OMPLoopDirective::HelperExprs B; 7963 // In presence of clause 'collapse' with number of loops, it will 7964 // define the nested loops number. 7965 unsigned NestedLoopCount = 7966 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 7967 nullptr /*ordered not a clause on distribute*/, CS, *this, 7968 *DSAStack, VarsWithImplicitDSA, B); 7969 if (NestedLoopCount == 0) 7970 return StmtError(); 7971 7972 assert((CurContext->isDependentContext() || B.builtAll()) && 7973 "omp for loop exprs were not built"); 7974 7975 if (!CurContext->isDependentContext()) { 7976 // Finalize the clauses that need pre-built expressions for CodeGen. 7977 for (OMPClause *C : Clauses) { 7978 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7979 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7980 B.NumIterations, *this, CurScope, 7981 DSAStack)) 7982 return StmtError(); 7983 } 7984 } 7985 7986 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7987 return StmtError(); 7988 7989 setFunctionHasBranchProtectedScope(); 7990 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 7991 NestedLoopCount, Clauses, AStmt, B); 7992 } 7993 7994 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 7995 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7996 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7997 if (!AStmt) 7998 return StmtError(); 7999 8000 auto *CS = cast<CapturedStmt>(AStmt); 8001 // 1.2.2 OpenMP Language Terminology 8002 // Structured block - An executable statement with a single entry at the 8003 // top and a single exit at the bottom. 8004 // The point of exit cannot be a branch out of the structured block. 8005 // longjmp() and throw() must not violate the entry/exit criteria. 8006 CS->getCapturedDecl()->setNothrow(); 8007 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 8008 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8009 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8010 // 1.2.2 OpenMP Language Terminology 8011 // Structured block - An executable statement with a single entry at the 8012 // top and a single exit at the bottom. 8013 // The point of exit cannot be a branch out of the structured block. 8014 // longjmp() and throw() must not violate the entry/exit criteria. 8015 CS->getCapturedDecl()->setNothrow(); 8016 } 8017 8018 OMPLoopDirective::HelperExprs B; 8019 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 8020 // define the nested loops number. 8021 unsigned NestedLoopCount = checkOpenMPLoop( 8022 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 8023 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8024 VarsWithImplicitDSA, B); 8025 if (NestedLoopCount == 0) 8026 return StmtError(); 8027 8028 assert((CurContext->isDependentContext() || B.builtAll()) && 8029 "omp target parallel for simd loop exprs were not built"); 8030 8031 if (!CurContext->isDependentContext()) { 8032 // Finalize the clauses that need pre-built expressions for CodeGen. 8033 for (OMPClause *C : Clauses) { 8034 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8035 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8036 B.NumIterations, *this, CurScope, 8037 DSAStack)) 8038 return StmtError(); 8039 } 8040 } 8041 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8042 return StmtError(); 8043 8044 setFunctionHasBranchProtectedScope(); 8045 return OMPTargetParallelForSimdDirective::Create( 8046 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8047 } 8048 8049 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 8050 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8051 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8052 if (!AStmt) 8053 return StmtError(); 8054 8055 auto *CS = cast<CapturedStmt>(AStmt); 8056 // 1.2.2 OpenMP Language Terminology 8057 // Structured block - An executable statement with a single entry at the 8058 // top and a single exit at the bottom. 8059 // The point of exit cannot be a branch out of the structured block. 8060 // longjmp() and throw() must not violate the entry/exit criteria. 8061 CS->getCapturedDecl()->setNothrow(); 8062 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 8063 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8064 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8065 // 1.2.2 OpenMP Language Terminology 8066 // Structured block - An executable statement with a single entry at the 8067 // top and a single exit at the bottom. 8068 // The point of exit cannot be a branch out of the structured block. 8069 // longjmp() and throw() must not violate the entry/exit criteria. 8070 CS->getCapturedDecl()->setNothrow(); 8071 } 8072 8073 OMPLoopDirective::HelperExprs B; 8074 // In presence of clause 'collapse' with number of loops, it will define the 8075 // nested loops number. 8076 unsigned NestedLoopCount = 8077 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 8078 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8079 VarsWithImplicitDSA, B); 8080 if (NestedLoopCount == 0) 8081 return StmtError(); 8082 8083 assert((CurContext->isDependentContext() || B.builtAll()) && 8084 "omp target simd loop exprs were not built"); 8085 8086 if (!CurContext->isDependentContext()) { 8087 // Finalize the clauses that need pre-built expressions for CodeGen. 8088 for (OMPClause *C : Clauses) { 8089 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8090 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8091 B.NumIterations, *this, CurScope, 8092 DSAStack)) 8093 return StmtError(); 8094 } 8095 } 8096 8097 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8098 return StmtError(); 8099 8100 setFunctionHasBranchProtectedScope(); 8101 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 8102 NestedLoopCount, Clauses, AStmt, B); 8103 } 8104 8105 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 8106 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8107 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8108 if (!AStmt) 8109 return StmtError(); 8110 8111 auto *CS = cast<CapturedStmt>(AStmt); 8112 // 1.2.2 OpenMP Language Terminology 8113 // Structured block - An executable statement with a single entry at the 8114 // top and a single exit at the bottom. 8115 // The point of exit cannot be a branch out of the structured block. 8116 // longjmp() and throw() must not violate the entry/exit criteria. 8117 CS->getCapturedDecl()->setNothrow(); 8118 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 8119 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8120 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8121 // 1.2.2 OpenMP Language Terminology 8122 // Structured block - An executable statement with a single entry at the 8123 // top and a single exit at the bottom. 8124 // The point of exit cannot be a branch out of the structured block. 8125 // longjmp() and throw() must not violate the entry/exit criteria. 8126 CS->getCapturedDecl()->setNothrow(); 8127 } 8128 8129 OMPLoopDirective::HelperExprs B; 8130 // In presence of clause 'collapse' with number of loops, it will 8131 // define the nested loops number. 8132 unsigned NestedLoopCount = 8133 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 8134 nullptr /*ordered not a clause on distribute*/, CS, *this, 8135 *DSAStack, VarsWithImplicitDSA, B); 8136 if (NestedLoopCount == 0) 8137 return StmtError(); 8138 8139 assert((CurContext->isDependentContext() || B.builtAll()) && 8140 "omp teams distribute loop exprs were not built"); 8141 8142 setFunctionHasBranchProtectedScope(); 8143 8144 DSAStack->setParentTeamsRegionLoc(StartLoc); 8145 8146 return OMPTeamsDistributeDirective::Create( 8147 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8148 } 8149 8150 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 8151 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8152 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8153 if (!AStmt) 8154 return StmtError(); 8155 8156 auto *CS = cast<CapturedStmt>(AStmt); 8157 // 1.2.2 OpenMP Language Terminology 8158 // Structured block - An executable statement with a single entry at the 8159 // top and a single exit at the bottom. 8160 // The point of exit cannot be a branch out of the structured block. 8161 // longjmp() and throw() must not violate the entry/exit criteria. 8162 CS->getCapturedDecl()->setNothrow(); 8163 for (int ThisCaptureLevel = 8164 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 8165 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8166 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8167 // 1.2.2 OpenMP Language Terminology 8168 // Structured block - An executable statement with a single entry at the 8169 // top and a single exit at the bottom. 8170 // The point of exit cannot be a branch out of the structured block. 8171 // longjmp() and throw() must not violate the entry/exit criteria. 8172 CS->getCapturedDecl()->setNothrow(); 8173 } 8174 8175 8176 OMPLoopDirective::HelperExprs B; 8177 // In presence of clause 'collapse' with number of loops, it will 8178 // define the nested loops number. 8179 unsigned NestedLoopCount = checkOpenMPLoop( 8180 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8181 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8182 VarsWithImplicitDSA, B); 8183 8184 if (NestedLoopCount == 0) 8185 return StmtError(); 8186 8187 assert((CurContext->isDependentContext() || B.builtAll()) && 8188 "omp teams distribute simd loop exprs were not built"); 8189 8190 if (!CurContext->isDependentContext()) { 8191 // Finalize the clauses that need pre-built expressions for CodeGen. 8192 for (OMPClause *C : Clauses) { 8193 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8194 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8195 B.NumIterations, *this, CurScope, 8196 DSAStack)) 8197 return StmtError(); 8198 } 8199 } 8200 8201 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8202 return StmtError(); 8203 8204 setFunctionHasBranchProtectedScope(); 8205 8206 DSAStack->setParentTeamsRegionLoc(StartLoc); 8207 8208 return OMPTeamsDistributeSimdDirective::Create( 8209 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8210 } 8211 8212 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 8213 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8214 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8215 if (!AStmt) 8216 return StmtError(); 8217 8218 auto *CS = cast<CapturedStmt>(AStmt); 8219 // 1.2.2 OpenMP Language Terminology 8220 // Structured block - An executable statement with a single entry at the 8221 // top and a single exit at the bottom. 8222 // The point of exit cannot be a branch out of the structured block. 8223 // longjmp() and throw() must not violate the entry/exit criteria. 8224 CS->getCapturedDecl()->setNothrow(); 8225 8226 for (int ThisCaptureLevel = 8227 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 8228 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8229 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8230 // 1.2.2 OpenMP Language Terminology 8231 // Structured block - An executable statement with a single entry at the 8232 // top and a single exit at the bottom. 8233 // The point of exit cannot be a branch out of the structured block. 8234 // longjmp() and throw() must not violate the entry/exit criteria. 8235 CS->getCapturedDecl()->setNothrow(); 8236 } 8237 8238 OMPLoopDirective::HelperExprs B; 8239 // In presence of clause 'collapse' with number of loops, it will 8240 // define the nested loops number. 8241 unsigned NestedLoopCount = checkOpenMPLoop( 8242 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8243 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8244 VarsWithImplicitDSA, B); 8245 8246 if (NestedLoopCount == 0) 8247 return StmtError(); 8248 8249 assert((CurContext->isDependentContext() || B.builtAll()) && 8250 "omp for loop exprs were not built"); 8251 8252 if (!CurContext->isDependentContext()) { 8253 // Finalize the clauses that need pre-built expressions for CodeGen. 8254 for (OMPClause *C : Clauses) { 8255 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8256 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8257 B.NumIterations, *this, CurScope, 8258 DSAStack)) 8259 return StmtError(); 8260 } 8261 } 8262 8263 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8264 return StmtError(); 8265 8266 setFunctionHasBranchProtectedScope(); 8267 8268 DSAStack->setParentTeamsRegionLoc(StartLoc); 8269 8270 return OMPTeamsDistributeParallelForSimdDirective::Create( 8271 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8272 } 8273 8274 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 8275 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8276 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8277 if (!AStmt) 8278 return StmtError(); 8279 8280 auto *CS = cast<CapturedStmt>(AStmt); 8281 // 1.2.2 OpenMP Language Terminology 8282 // Structured block - An executable statement with a single entry at the 8283 // top and a single exit at the bottom. 8284 // The point of exit cannot be a branch out of the structured block. 8285 // longjmp() and throw() must not violate the entry/exit criteria. 8286 CS->getCapturedDecl()->setNothrow(); 8287 8288 for (int ThisCaptureLevel = 8289 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 8290 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8291 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8292 // 1.2.2 OpenMP Language Terminology 8293 // Structured block - An executable statement with a single entry at the 8294 // top and a single exit at the bottom. 8295 // The point of exit cannot be a branch out of the structured block. 8296 // longjmp() and throw() must not violate the entry/exit criteria. 8297 CS->getCapturedDecl()->setNothrow(); 8298 } 8299 8300 OMPLoopDirective::HelperExprs B; 8301 // In presence of clause 'collapse' with number of loops, it will 8302 // define the nested loops number. 8303 unsigned NestedLoopCount = checkOpenMPLoop( 8304 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8305 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8306 VarsWithImplicitDSA, B); 8307 8308 if (NestedLoopCount == 0) 8309 return StmtError(); 8310 8311 assert((CurContext->isDependentContext() || B.builtAll()) && 8312 "omp for loop exprs were not built"); 8313 8314 setFunctionHasBranchProtectedScope(); 8315 8316 DSAStack->setParentTeamsRegionLoc(StartLoc); 8317 8318 return OMPTeamsDistributeParallelForDirective::Create( 8319 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8320 DSAStack->isCancelRegion()); 8321 } 8322 8323 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 8324 Stmt *AStmt, 8325 SourceLocation StartLoc, 8326 SourceLocation EndLoc) { 8327 if (!AStmt) 8328 return StmtError(); 8329 8330 auto *CS = cast<CapturedStmt>(AStmt); 8331 // 1.2.2 OpenMP Language Terminology 8332 // Structured block - An executable statement with a single entry at the 8333 // top and a single exit at the bottom. 8334 // The point of exit cannot be a branch out of the structured block. 8335 // longjmp() and throw() must not violate the entry/exit criteria. 8336 CS->getCapturedDecl()->setNothrow(); 8337 8338 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 8339 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8340 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8341 // 1.2.2 OpenMP Language Terminology 8342 // Structured block - An executable statement with a single entry at the 8343 // top and a single exit at the bottom. 8344 // The point of exit cannot be a branch out of the structured block. 8345 // longjmp() and throw() must not violate the entry/exit criteria. 8346 CS->getCapturedDecl()->setNothrow(); 8347 } 8348 setFunctionHasBranchProtectedScope(); 8349 8350 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 8351 AStmt); 8352 } 8353 8354 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 8355 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8356 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8357 if (!AStmt) 8358 return StmtError(); 8359 8360 auto *CS = cast<CapturedStmt>(AStmt); 8361 // 1.2.2 OpenMP Language Terminology 8362 // Structured block - An executable statement with a single entry at the 8363 // top and a single exit at the bottom. 8364 // The point of exit cannot be a branch out of the structured block. 8365 // longjmp() and throw() must not violate the entry/exit criteria. 8366 CS->getCapturedDecl()->setNothrow(); 8367 for (int ThisCaptureLevel = 8368 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 8369 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8370 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8371 // 1.2.2 OpenMP Language Terminology 8372 // Structured block - An executable statement with a single entry at the 8373 // top and a single exit at the bottom. 8374 // The point of exit cannot be a branch out of the structured block. 8375 // longjmp() and throw() must not violate the entry/exit criteria. 8376 CS->getCapturedDecl()->setNothrow(); 8377 } 8378 8379 OMPLoopDirective::HelperExprs B; 8380 // In presence of clause 'collapse' with number of loops, it will 8381 // define the nested loops number. 8382 unsigned NestedLoopCount = checkOpenMPLoop( 8383 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 8384 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8385 VarsWithImplicitDSA, B); 8386 if (NestedLoopCount == 0) 8387 return StmtError(); 8388 8389 assert((CurContext->isDependentContext() || B.builtAll()) && 8390 "omp target teams distribute loop exprs were not built"); 8391 8392 setFunctionHasBranchProtectedScope(); 8393 return OMPTargetTeamsDistributeDirective::Create( 8394 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8395 } 8396 8397 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 8398 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8399 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8400 if (!AStmt) 8401 return StmtError(); 8402 8403 auto *CS = cast<CapturedStmt>(AStmt); 8404 // 1.2.2 OpenMP Language Terminology 8405 // Structured block - An executable statement with a single entry at the 8406 // top and a single exit at the bottom. 8407 // The point of exit cannot be a branch out of the structured block. 8408 // longjmp() and throw() must not violate the entry/exit criteria. 8409 CS->getCapturedDecl()->setNothrow(); 8410 for (int ThisCaptureLevel = 8411 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 8412 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8413 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8414 // 1.2.2 OpenMP Language Terminology 8415 // Structured block - An executable statement with a single entry at the 8416 // top and a single exit at the bottom. 8417 // The point of exit cannot be a branch out of the structured block. 8418 // longjmp() and throw() must not violate the entry/exit criteria. 8419 CS->getCapturedDecl()->setNothrow(); 8420 } 8421 8422 OMPLoopDirective::HelperExprs B; 8423 // In presence of clause 'collapse' with number of loops, it will 8424 // define the nested loops number. 8425 unsigned NestedLoopCount = checkOpenMPLoop( 8426 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8427 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8428 VarsWithImplicitDSA, B); 8429 if (NestedLoopCount == 0) 8430 return StmtError(); 8431 8432 assert((CurContext->isDependentContext() || B.builtAll()) && 8433 "omp target teams distribute parallel for loop exprs were not built"); 8434 8435 if (!CurContext->isDependentContext()) { 8436 // Finalize the clauses that need pre-built expressions for CodeGen. 8437 for (OMPClause *C : Clauses) { 8438 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8439 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8440 B.NumIterations, *this, CurScope, 8441 DSAStack)) 8442 return StmtError(); 8443 } 8444 } 8445 8446 setFunctionHasBranchProtectedScope(); 8447 return OMPTargetTeamsDistributeParallelForDirective::Create( 8448 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8449 DSAStack->isCancelRegion()); 8450 } 8451 8452 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 8453 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8454 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8455 if (!AStmt) 8456 return StmtError(); 8457 8458 auto *CS = cast<CapturedStmt>(AStmt); 8459 // 1.2.2 OpenMP Language Terminology 8460 // Structured block - An executable statement with a single entry at the 8461 // top and a single exit at the bottom. 8462 // The point of exit cannot be a branch out of the structured block. 8463 // longjmp() and throw() must not violate the entry/exit criteria. 8464 CS->getCapturedDecl()->setNothrow(); 8465 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 8466 OMPD_target_teams_distribute_parallel_for_simd); 8467 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8468 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8469 // 1.2.2 OpenMP Language Terminology 8470 // Structured block - An executable statement with a single entry at the 8471 // top and a single exit at the bottom. 8472 // The point of exit cannot be a branch out of the structured block. 8473 // longjmp() and throw() must not violate the entry/exit criteria. 8474 CS->getCapturedDecl()->setNothrow(); 8475 } 8476 8477 OMPLoopDirective::HelperExprs B; 8478 // In presence of clause 'collapse' with number of loops, it will 8479 // define the nested loops number. 8480 unsigned NestedLoopCount = 8481 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 8482 getCollapseNumberExpr(Clauses), 8483 nullptr /*ordered not a clause on distribute*/, CS, *this, 8484 *DSAStack, VarsWithImplicitDSA, B); 8485 if (NestedLoopCount == 0) 8486 return StmtError(); 8487 8488 assert((CurContext->isDependentContext() || B.builtAll()) && 8489 "omp target teams distribute parallel for simd loop exprs were not " 8490 "built"); 8491 8492 if (!CurContext->isDependentContext()) { 8493 // Finalize the clauses that need pre-built expressions for CodeGen. 8494 for (OMPClause *C : Clauses) { 8495 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8496 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8497 B.NumIterations, *this, CurScope, 8498 DSAStack)) 8499 return StmtError(); 8500 } 8501 } 8502 8503 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8504 return StmtError(); 8505 8506 setFunctionHasBranchProtectedScope(); 8507 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 8508 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8509 } 8510 8511 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 8512 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8513 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8514 if (!AStmt) 8515 return StmtError(); 8516 8517 auto *CS = cast<CapturedStmt>(AStmt); 8518 // 1.2.2 OpenMP Language Terminology 8519 // Structured block - An executable statement with a single entry at the 8520 // top and a single exit at the bottom. 8521 // The point of exit cannot be a branch out of the structured block. 8522 // longjmp() and throw() must not violate the entry/exit criteria. 8523 CS->getCapturedDecl()->setNothrow(); 8524 for (int ThisCaptureLevel = 8525 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 8526 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8527 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8528 // 1.2.2 OpenMP Language Terminology 8529 // Structured block - An executable statement with a single entry at the 8530 // top and a single exit at the bottom. 8531 // The point of exit cannot be a branch out of the structured block. 8532 // longjmp() and throw() must not violate the entry/exit criteria. 8533 CS->getCapturedDecl()->setNothrow(); 8534 } 8535 8536 OMPLoopDirective::HelperExprs B; 8537 // In presence of clause 'collapse' with number of loops, it will 8538 // define the nested loops number. 8539 unsigned NestedLoopCount = checkOpenMPLoop( 8540 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8541 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8542 VarsWithImplicitDSA, B); 8543 if (NestedLoopCount == 0) 8544 return StmtError(); 8545 8546 assert((CurContext->isDependentContext() || B.builtAll()) && 8547 "omp target teams distribute simd loop exprs were not built"); 8548 8549 if (!CurContext->isDependentContext()) { 8550 // Finalize the clauses that need pre-built expressions for CodeGen. 8551 for (OMPClause *C : Clauses) { 8552 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8553 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8554 B.NumIterations, *this, CurScope, 8555 DSAStack)) 8556 return StmtError(); 8557 } 8558 } 8559 8560 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8561 return StmtError(); 8562 8563 setFunctionHasBranchProtectedScope(); 8564 return OMPTargetTeamsDistributeSimdDirective::Create( 8565 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8566 } 8567 8568 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 8569 SourceLocation StartLoc, 8570 SourceLocation LParenLoc, 8571 SourceLocation EndLoc) { 8572 OMPClause *Res = nullptr; 8573 switch (Kind) { 8574 case OMPC_final: 8575 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 8576 break; 8577 case OMPC_num_threads: 8578 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 8579 break; 8580 case OMPC_safelen: 8581 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 8582 break; 8583 case OMPC_simdlen: 8584 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 8585 break; 8586 case OMPC_allocator: 8587 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 8588 break; 8589 case OMPC_collapse: 8590 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 8591 break; 8592 case OMPC_ordered: 8593 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 8594 break; 8595 case OMPC_device: 8596 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 8597 break; 8598 case OMPC_num_teams: 8599 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 8600 break; 8601 case OMPC_thread_limit: 8602 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 8603 break; 8604 case OMPC_priority: 8605 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 8606 break; 8607 case OMPC_grainsize: 8608 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 8609 break; 8610 case OMPC_num_tasks: 8611 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 8612 break; 8613 case OMPC_hint: 8614 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 8615 break; 8616 case OMPC_if: 8617 case OMPC_default: 8618 case OMPC_proc_bind: 8619 case OMPC_schedule: 8620 case OMPC_private: 8621 case OMPC_firstprivate: 8622 case OMPC_lastprivate: 8623 case OMPC_shared: 8624 case OMPC_reduction: 8625 case OMPC_task_reduction: 8626 case OMPC_in_reduction: 8627 case OMPC_linear: 8628 case OMPC_aligned: 8629 case OMPC_copyin: 8630 case OMPC_copyprivate: 8631 case OMPC_nowait: 8632 case OMPC_untied: 8633 case OMPC_mergeable: 8634 case OMPC_threadprivate: 8635 case OMPC_allocate: 8636 case OMPC_flush: 8637 case OMPC_read: 8638 case OMPC_write: 8639 case OMPC_update: 8640 case OMPC_capture: 8641 case OMPC_seq_cst: 8642 case OMPC_depend: 8643 case OMPC_threads: 8644 case OMPC_simd: 8645 case OMPC_map: 8646 case OMPC_nogroup: 8647 case OMPC_dist_schedule: 8648 case OMPC_defaultmap: 8649 case OMPC_unknown: 8650 case OMPC_uniform: 8651 case OMPC_to: 8652 case OMPC_from: 8653 case OMPC_use_device_ptr: 8654 case OMPC_is_device_ptr: 8655 case OMPC_unified_address: 8656 case OMPC_unified_shared_memory: 8657 case OMPC_reverse_offload: 8658 case OMPC_dynamic_allocators: 8659 case OMPC_atomic_default_mem_order: 8660 llvm_unreachable("Clause is not allowed."); 8661 } 8662 return Res; 8663 } 8664 8665 // An OpenMP directive such as 'target parallel' has two captured regions: 8666 // for the 'target' and 'parallel' respectively. This function returns 8667 // the region in which to capture expressions associated with a clause. 8668 // A return value of OMPD_unknown signifies that the expression should not 8669 // be captured. 8670 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 8671 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 8672 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 8673 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 8674 switch (CKind) { 8675 case OMPC_if: 8676 switch (DKind) { 8677 case OMPD_target_parallel: 8678 case OMPD_target_parallel_for: 8679 case OMPD_target_parallel_for_simd: 8680 // If this clause applies to the nested 'parallel' region, capture within 8681 // the 'target' region, otherwise do not capture. 8682 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 8683 CaptureRegion = OMPD_target; 8684 break; 8685 case OMPD_target_teams_distribute_parallel_for: 8686 case OMPD_target_teams_distribute_parallel_for_simd: 8687 // If this clause applies to the nested 'parallel' region, capture within 8688 // the 'teams' region, otherwise do not capture. 8689 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 8690 CaptureRegion = OMPD_teams; 8691 break; 8692 case OMPD_teams_distribute_parallel_for: 8693 case OMPD_teams_distribute_parallel_for_simd: 8694 CaptureRegion = OMPD_teams; 8695 break; 8696 case OMPD_target_update: 8697 case OMPD_target_enter_data: 8698 case OMPD_target_exit_data: 8699 CaptureRegion = OMPD_task; 8700 break; 8701 case OMPD_cancel: 8702 case OMPD_parallel: 8703 case OMPD_parallel_sections: 8704 case OMPD_parallel_for: 8705 case OMPD_parallel_for_simd: 8706 case OMPD_target: 8707 case OMPD_target_simd: 8708 case OMPD_target_teams: 8709 case OMPD_target_teams_distribute: 8710 case OMPD_target_teams_distribute_simd: 8711 case OMPD_distribute_parallel_for: 8712 case OMPD_distribute_parallel_for_simd: 8713 case OMPD_task: 8714 case OMPD_taskloop: 8715 case OMPD_taskloop_simd: 8716 case OMPD_target_data: 8717 // Do not capture if-clause expressions. 8718 break; 8719 case OMPD_threadprivate: 8720 case OMPD_allocate: 8721 case OMPD_taskyield: 8722 case OMPD_barrier: 8723 case OMPD_taskwait: 8724 case OMPD_cancellation_point: 8725 case OMPD_flush: 8726 case OMPD_declare_reduction: 8727 case OMPD_declare_mapper: 8728 case OMPD_declare_simd: 8729 case OMPD_declare_target: 8730 case OMPD_end_declare_target: 8731 case OMPD_teams: 8732 case OMPD_simd: 8733 case OMPD_for: 8734 case OMPD_for_simd: 8735 case OMPD_sections: 8736 case OMPD_section: 8737 case OMPD_single: 8738 case OMPD_master: 8739 case OMPD_critical: 8740 case OMPD_taskgroup: 8741 case OMPD_distribute: 8742 case OMPD_ordered: 8743 case OMPD_atomic: 8744 case OMPD_distribute_simd: 8745 case OMPD_teams_distribute: 8746 case OMPD_teams_distribute_simd: 8747 case OMPD_requires: 8748 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 8749 case OMPD_unknown: 8750 llvm_unreachable("Unknown OpenMP directive"); 8751 } 8752 break; 8753 case OMPC_num_threads: 8754 switch (DKind) { 8755 case OMPD_target_parallel: 8756 case OMPD_target_parallel_for: 8757 case OMPD_target_parallel_for_simd: 8758 CaptureRegion = OMPD_target; 8759 break; 8760 case OMPD_teams_distribute_parallel_for: 8761 case OMPD_teams_distribute_parallel_for_simd: 8762 case OMPD_target_teams_distribute_parallel_for: 8763 case OMPD_target_teams_distribute_parallel_for_simd: 8764 CaptureRegion = OMPD_teams; 8765 break; 8766 case OMPD_parallel: 8767 case OMPD_parallel_sections: 8768 case OMPD_parallel_for: 8769 case OMPD_parallel_for_simd: 8770 case OMPD_distribute_parallel_for: 8771 case OMPD_distribute_parallel_for_simd: 8772 // Do not capture num_threads-clause expressions. 8773 break; 8774 case OMPD_target_data: 8775 case OMPD_target_enter_data: 8776 case OMPD_target_exit_data: 8777 case OMPD_target_update: 8778 case OMPD_target: 8779 case OMPD_target_simd: 8780 case OMPD_target_teams: 8781 case OMPD_target_teams_distribute: 8782 case OMPD_target_teams_distribute_simd: 8783 case OMPD_cancel: 8784 case OMPD_task: 8785 case OMPD_taskloop: 8786 case OMPD_taskloop_simd: 8787 case OMPD_threadprivate: 8788 case OMPD_allocate: 8789 case OMPD_taskyield: 8790 case OMPD_barrier: 8791 case OMPD_taskwait: 8792 case OMPD_cancellation_point: 8793 case OMPD_flush: 8794 case OMPD_declare_reduction: 8795 case OMPD_declare_mapper: 8796 case OMPD_declare_simd: 8797 case OMPD_declare_target: 8798 case OMPD_end_declare_target: 8799 case OMPD_teams: 8800 case OMPD_simd: 8801 case OMPD_for: 8802 case OMPD_for_simd: 8803 case OMPD_sections: 8804 case OMPD_section: 8805 case OMPD_single: 8806 case OMPD_master: 8807 case OMPD_critical: 8808 case OMPD_taskgroup: 8809 case OMPD_distribute: 8810 case OMPD_ordered: 8811 case OMPD_atomic: 8812 case OMPD_distribute_simd: 8813 case OMPD_teams_distribute: 8814 case OMPD_teams_distribute_simd: 8815 case OMPD_requires: 8816 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 8817 case OMPD_unknown: 8818 llvm_unreachable("Unknown OpenMP directive"); 8819 } 8820 break; 8821 case OMPC_num_teams: 8822 switch (DKind) { 8823 case OMPD_target_teams: 8824 case OMPD_target_teams_distribute: 8825 case OMPD_target_teams_distribute_simd: 8826 case OMPD_target_teams_distribute_parallel_for: 8827 case OMPD_target_teams_distribute_parallel_for_simd: 8828 CaptureRegion = OMPD_target; 8829 break; 8830 case OMPD_teams_distribute_parallel_for: 8831 case OMPD_teams_distribute_parallel_for_simd: 8832 case OMPD_teams: 8833 case OMPD_teams_distribute: 8834 case OMPD_teams_distribute_simd: 8835 // Do not capture num_teams-clause expressions. 8836 break; 8837 case OMPD_distribute_parallel_for: 8838 case OMPD_distribute_parallel_for_simd: 8839 case OMPD_task: 8840 case OMPD_taskloop: 8841 case OMPD_taskloop_simd: 8842 case OMPD_target_data: 8843 case OMPD_target_enter_data: 8844 case OMPD_target_exit_data: 8845 case OMPD_target_update: 8846 case OMPD_cancel: 8847 case OMPD_parallel: 8848 case OMPD_parallel_sections: 8849 case OMPD_parallel_for: 8850 case OMPD_parallel_for_simd: 8851 case OMPD_target: 8852 case OMPD_target_simd: 8853 case OMPD_target_parallel: 8854 case OMPD_target_parallel_for: 8855 case OMPD_target_parallel_for_simd: 8856 case OMPD_threadprivate: 8857 case OMPD_allocate: 8858 case OMPD_taskyield: 8859 case OMPD_barrier: 8860 case OMPD_taskwait: 8861 case OMPD_cancellation_point: 8862 case OMPD_flush: 8863 case OMPD_declare_reduction: 8864 case OMPD_declare_mapper: 8865 case OMPD_declare_simd: 8866 case OMPD_declare_target: 8867 case OMPD_end_declare_target: 8868 case OMPD_simd: 8869 case OMPD_for: 8870 case OMPD_for_simd: 8871 case OMPD_sections: 8872 case OMPD_section: 8873 case OMPD_single: 8874 case OMPD_master: 8875 case OMPD_critical: 8876 case OMPD_taskgroup: 8877 case OMPD_distribute: 8878 case OMPD_ordered: 8879 case OMPD_atomic: 8880 case OMPD_distribute_simd: 8881 case OMPD_requires: 8882 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 8883 case OMPD_unknown: 8884 llvm_unreachable("Unknown OpenMP directive"); 8885 } 8886 break; 8887 case OMPC_thread_limit: 8888 switch (DKind) { 8889 case OMPD_target_teams: 8890 case OMPD_target_teams_distribute: 8891 case OMPD_target_teams_distribute_simd: 8892 case OMPD_target_teams_distribute_parallel_for: 8893 case OMPD_target_teams_distribute_parallel_for_simd: 8894 CaptureRegion = OMPD_target; 8895 break; 8896 case OMPD_teams_distribute_parallel_for: 8897 case OMPD_teams_distribute_parallel_for_simd: 8898 case OMPD_teams: 8899 case OMPD_teams_distribute: 8900 case OMPD_teams_distribute_simd: 8901 // Do not capture thread_limit-clause expressions. 8902 break; 8903 case OMPD_distribute_parallel_for: 8904 case OMPD_distribute_parallel_for_simd: 8905 case OMPD_task: 8906 case OMPD_taskloop: 8907 case OMPD_taskloop_simd: 8908 case OMPD_target_data: 8909 case OMPD_target_enter_data: 8910 case OMPD_target_exit_data: 8911 case OMPD_target_update: 8912 case OMPD_cancel: 8913 case OMPD_parallel: 8914 case OMPD_parallel_sections: 8915 case OMPD_parallel_for: 8916 case OMPD_parallel_for_simd: 8917 case OMPD_target: 8918 case OMPD_target_simd: 8919 case OMPD_target_parallel: 8920 case OMPD_target_parallel_for: 8921 case OMPD_target_parallel_for_simd: 8922 case OMPD_threadprivate: 8923 case OMPD_allocate: 8924 case OMPD_taskyield: 8925 case OMPD_barrier: 8926 case OMPD_taskwait: 8927 case OMPD_cancellation_point: 8928 case OMPD_flush: 8929 case OMPD_declare_reduction: 8930 case OMPD_declare_mapper: 8931 case OMPD_declare_simd: 8932 case OMPD_declare_target: 8933 case OMPD_end_declare_target: 8934 case OMPD_simd: 8935 case OMPD_for: 8936 case OMPD_for_simd: 8937 case OMPD_sections: 8938 case OMPD_section: 8939 case OMPD_single: 8940 case OMPD_master: 8941 case OMPD_critical: 8942 case OMPD_taskgroup: 8943 case OMPD_distribute: 8944 case OMPD_ordered: 8945 case OMPD_atomic: 8946 case OMPD_distribute_simd: 8947 case OMPD_requires: 8948 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 8949 case OMPD_unknown: 8950 llvm_unreachable("Unknown OpenMP directive"); 8951 } 8952 break; 8953 case OMPC_schedule: 8954 switch (DKind) { 8955 case OMPD_parallel_for: 8956 case OMPD_parallel_for_simd: 8957 case OMPD_distribute_parallel_for: 8958 case OMPD_distribute_parallel_for_simd: 8959 case OMPD_teams_distribute_parallel_for: 8960 case OMPD_teams_distribute_parallel_for_simd: 8961 case OMPD_target_parallel_for: 8962 case OMPD_target_parallel_for_simd: 8963 case OMPD_target_teams_distribute_parallel_for: 8964 case OMPD_target_teams_distribute_parallel_for_simd: 8965 CaptureRegion = OMPD_parallel; 8966 break; 8967 case OMPD_for: 8968 case OMPD_for_simd: 8969 // Do not capture schedule-clause expressions. 8970 break; 8971 case OMPD_task: 8972 case OMPD_taskloop: 8973 case OMPD_taskloop_simd: 8974 case OMPD_target_data: 8975 case OMPD_target_enter_data: 8976 case OMPD_target_exit_data: 8977 case OMPD_target_update: 8978 case OMPD_teams: 8979 case OMPD_teams_distribute: 8980 case OMPD_teams_distribute_simd: 8981 case OMPD_target_teams_distribute: 8982 case OMPD_target_teams_distribute_simd: 8983 case OMPD_target: 8984 case OMPD_target_simd: 8985 case OMPD_target_parallel: 8986 case OMPD_cancel: 8987 case OMPD_parallel: 8988 case OMPD_parallel_sections: 8989 case OMPD_threadprivate: 8990 case OMPD_allocate: 8991 case OMPD_taskyield: 8992 case OMPD_barrier: 8993 case OMPD_taskwait: 8994 case OMPD_cancellation_point: 8995 case OMPD_flush: 8996 case OMPD_declare_reduction: 8997 case OMPD_declare_mapper: 8998 case OMPD_declare_simd: 8999 case OMPD_declare_target: 9000 case OMPD_end_declare_target: 9001 case OMPD_simd: 9002 case OMPD_sections: 9003 case OMPD_section: 9004 case OMPD_single: 9005 case OMPD_master: 9006 case OMPD_critical: 9007 case OMPD_taskgroup: 9008 case OMPD_distribute: 9009 case OMPD_ordered: 9010 case OMPD_atomic: 9011 case OMPD_distribute_simd: 9012 case OMPD_target_teams: 9013 case OMPD_requires: 9014 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9015 case OMPD_unknown: 9016 llvm_unreachable("Unknown OpenMP directive"); 9017 } 9018 break; 9019 case OMPC_dist_schedule: 9020 switch (DKind) { 9021 case OMPD_teams_distribute_parallel_for: 9022 case OMPD_teams_distribute_parallel_for_simd: 9023 case OMPD_teams_distribute: 9024 case OMPD_teams_distribute_simd: 9025 case OMPD_target_teams_distribute_parallel_for: 9026 case OMPD_target_teams_distribute_parallel_for_simd: 9027 case OMPD_target_teams_distribute: 9028 case OMPD_target_teams_distribute_simd: 9029 CaptureRegion = OMPD_teams; 9030 break; 9031 case OMPD_distribute_parallel_for: 9032 case OMPD_distribute_parallel_for_simd: 9033 case OMPD_distribute: 9034 case OMPD_distribute_simd: 9035 // Do not capture thread_limit-clause expressions. 9036 break; 9037 case OMPD_parallel_for: 9038 case OMPD_parallel_for_simd: 9039 case OMPD_target_parallel_for_simd: 9040 case OMPD_target_parallel_for: 9041 case OMPD_task: 9042 case OMPD_taskloop: 9043 case OMPD_taskloop_simd: 9044 case OMPD_target_data: 9045 case OMPD_target_enter_data: 9046 case OMPD_target_exit_data: 9047 case OMPD_target_update: 9048 case OMPD_teams: 9049 case OMPD_target: 9050 case OMPD_target_simd: 9051 case OMPD_target_parallel: 9052 case OMPD_cancel: 9053 case OMPD_parallel: 9054 case OMPD_parallel_sections: 9055 case OMPD_threadprivate: 9056 case OMPD_allocate: 9057 case OMPD_taskyield: 9058 case OMPD_barrier: 9059 case OMPD_taskwait: 9060 case OMPD_cancellation_point: 9061 case OMPD_flush: 9062 case OMPD_declare_reduction: 9063 case OMPD_declare_mapper: 9064 case OMPD_declare_simd: 9065 case OMPD_declare_target: 9066 case OMPD_end_declare_target: 9067 case OMPD_simd: 9068 case OMPD_for: 9069 case OMPD_for_simd: 9070 case OMPD_sections: 9071 case OMPD_section: 9072 case OMPD_single: 9073 case OMPD_master: 9074 case OMPD_critical: 9075 case OMPD_taskgroup: 9076 case OMPD_ordered: 9077 case OMPD_atomic: 9078 case OMPD_target_teams: 9079 case OMPD_requires: 9080 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9081 case OMPD_unknown: 9082 llvm_unreachable("Unknown OpenMP directive"); 9083 } 9084 break; 9085 case OMPC_device: 9086 switch (DKind) { 9087 case OMPD_target_update: 9088 case OMPD_target_enter_data: 9089 case OMPD_target_exit_data: 9090 case OMPD_target: 9091 case OMPD_target_simd: 9092 case OMPD_target_teams: 9093 case OMPD_target_parallel: 9094 case OMPD_target_teams_distribute: 9095 case OMPD_target_teams_distribute_simd: 9096 case OMPD_target_parallel_for: 9097 case OMPD_target_parallel_for_simd: 9098 case OMPD_target_teams_distribute_parallel_for: 9099 case OMPD_target_teams_distribute_parallel_for_simd: 9100 CaptureRegion = OMPD_task; 9101 break; 9102 case OMPD_target_data: 9103 // Do not capture device-clause expressions. 9104 break; 9105 case OMPD_teams_distribute_parallel_for: 9106 case OMPD_teams_distribute_parallel_for_simd: 9107 case OMPD_teams: 9108 case OMPD_teams_distribute: 9109 case OMPD_teams_distribute_simd: 9110 case OMPD_distribute_parallel_for: 9111 case OMPD_distribute_parallel_for_simd: 9112 case OMPD_task: 9113 case OMPD_taskloop: 9114 case OMPD_taskloop_simd: 9115 case OMPD_cancel: 9116 case OMPD_parallel: 9117 case OMPD_parallel_sections: 9118 case OMPD_parallel_for: 9119 case OMPD_parallel_for_simd: 9120 case OMPD_threadprivate: 9121 case OMPD_allocate: 9122 case OMPD_taskyield: 9123 case OMPD_barrier: 9124 case OMPD_taskwait: 9125 case OMPD_cancellation_point: 9126 case OMPD_flush: 9127 case OMPD_declare_reduction: 9128 case OMPD_declare_mapper: 9129 case OMPD_declare_simd: 9130 case OMPD_declare_target: 9131 case OMPD_end_declare_target: 9132 case OMPD_simd: 9133 case OMPD_for: 9134 case OMPD_for_simd: 9135 case OMPD_sections: 9136 case OMPD_section: 9137 case OMPD_single: 9138 case OMPD_master: 9139 case OMPD_critical: 9140 case OMPD_taskgroup: 9141 case OMPD_distribute: 9142 case OMPD_ordered: 9143 case OMPD_atomic: 9144 case OMPD_distribute_simd: 9145 case OMPD_requires: 9146 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9147 case OMPD_unknown: 9148 llvm_unreachable("Unknown OpenMP directive"); 9149 } 9150 break; 9151 case OMPC_firstprivate: 9152 case OMPC_lastprivate: 9153 case OMPC_reduction: 9154 case OMPC_task_reduction: 9155 case OMPC_in_reduction: 9156 case OMPC_linear: 9157 case OMPC_default: 9158 case OMPC_proc_bind: 9159 case OMPC_final: 9160 case OMPC_safelen: 9161 case OMPC_simdlen: 9162 case OMPC_allocator: 9163 case OMPC_collapse: 9164 case OMPC_private: 9165 case OMPC_shared: 9166 case OMPC_aligned: 9167 case OMPC_copyin: 9168 case OMPC_copyprivate: 9169 case OMPC_ordered: 9170 case OMPC_nowait: 9171 case OMPC_untied: 9172 case OMPC_mergeable: 9173 case OMPC_threadprivate: 9174 case OMPC_allocate: 9175 case OMPC_flush: 9176 case OMPC_read: 9177 case OMPC_write: 9178 case OMPC_update: 9179 case OMPC_capture: 9180 case OMPC_seq_cst: 9181 case OMPC_depend: 9182 case OMPC_threads: 9183 case OMPC_simd: 9184 case OMPC_map: 9185 case OMPC_priority: 9186 case OMPC_grainsize: 9187 case OMPC_nogroup: 9188 case OMPC_num_tasks: 9189 case OMPC_hint: 9190 case OMPC_defaultmap: 9191 case OMPC_unknown: 9192 case OMPC_uniform: 9193 case OMPC_to: 9194 case OMPC_from: 9195 case OMPC_use_device_ptr: 9196 case OMPC_is_device_ptr: 9197 case OMPC_unified_address: 9198 case OMPC_unified_shared_memory: 9199 case OMPC_reverse_offload: 9200 case OMPC_dynamic_allocators: 9201 case OMPC_atomic_default_mem_order: 9202 llvm_unreachable("Unexpected OpenMP clause."); 9203 } 9204 return CaptureRegion; 9205 } 9206 9207 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 9208 Expr *Condition, SourceLocation StartLoc, 9209 SourceLocation LParenLoc, 9210 SourceLocation NameModifierLoc, 9211 SourceLocation ColonLoc, 9212 SourceLocation EndLoc) { 9213 Expr *ValExpr = Condition; 9214 Stmt *HelperValStmt = nullptr; 9215 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9216 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9217 !Condition->isInstantiationDependent() && 9218 !Condition->containsUnexpandedParameterPack()) { 9219 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9220 if (Val.isInvalid()) 9221 return nullptr; 9222 9223 ValExpr = Val.get(); 9224 9225 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9226 CaptureRegion = 9227 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 9228 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9229 ValExpr = MakeFullExpr(ValExpr).get(); 9230 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9231 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9232 HelperValStmt = buildPreInits(Context, Captures); 9233 } 9234 } 9235 9236 return new (Context) 9237 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 9238 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 9239 } 9240 9241 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 9242 SourceLocation StartLoc, 9243 SourceLocation LParenLoc, 9244 SourceLocation EndLoc) { 9245 Expr *ValExpr = Condition; 9246 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9247 !Condition->isInstantiationDependent() && 9248 !Condition->containsUnexpandedParameterPack()) { 9249 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9250 if (Val.isInvalid()) 9251 return nullptr; 9252 9253 ValExpr = MakeFullExpr(Val.get()).get(); 9254 } 9255 9256 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 9257 } 9258 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 9259 Expr *Op) { 9260 if (!Op) 9261 return ExprError(); 9262 9263 class IntConvertDiagnoser : public ICEConvertDiagnoser { 9264 public: 9265 IntConvertDiagnoser() 9266 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 9267 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 9268 QualType T) override { 9269 return S.Diag(Loc, diag::err_omp_not_integral) << T; 9270 } 9271 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 9272 QualType T) override { 9273 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 9274 } 9275 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 9276 QualType T, 9277 QualType ConvTy) override { 9278 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 9279 } 9280 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 9281 QualType ConvTy) override { 9282 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9283 << ConvTy->isEnumeralType() << ConvTy; 9284 } 9285 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 9286 QualType T) override { 9287 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 9288 } 9289 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 9290 QualType ConvTy) override { 9291 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9292 << ConvTy->isEnumeralType() << ConvTy; 9293 } 9294 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 9295 QualType) override { 9296 llvm_unreachable("conversion functions are permitted"); 9297 } 9298 } ConvertDiagnoser; 9299 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 9300 } 9301 9302 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 9303 OpenMPClauseKind CKind, 9304 bool StrictlyPositive) { 9305 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 9306 !ValExpr->isInstantiationDependent()) { 9307 SourceLocation Loc = ValExpr->getExprLoc(); 9308 ExprResult Value = 9309 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 9310 if (Value.isInvalid()) 9311 return false; 9312 9313 ValExpr = Value.get(); 9314 // The expression must evaluate to a non-negative integer value. 9315 llvm::APSInt Result; 9316 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 9317 Result.isSigned() && 9318 !((!StrictlyPositive && Result.isNonNegative()) || 9319 (StrictlyPositive && Result.isStrictlyPositive()))) { 9320 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 9321 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9322 << ValExpr->getSourceRange(); 9323 return false; 9324 } 9325 } 9326 return true; 9327 } 9328 9329 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 9330 SourceLocation StartLoc, 9331 SourceLocation LParenLoc, 9332 SourceLocation EndLoc) { 9333 Expr *ValExpr = NumThreads; 9334 Stmt *HelperValStmt = nullptr; 9335 9336 // OpenMP [2.5, Restrictions] 9337 // The num_threads expression must evaluate to a positive integer value. 9338 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 9339 /*StrictlyPositive=*/true)) 9340 return nullptr; 9341 9342 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9343 OpenMPDirectiveKind CaptureRegion = 9344 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 9345 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9346 ValExpr = MakeFullExpr(ValExpr).get(); 9347 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9348 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9349 HelperValStmt = buildPreInits(Context, Captures); 9350 } 9351 9352 return new (Context) OMPNumThreadsClause( 9353 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 9354 } 9355 9356 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 9357 OpenMPClauseKind CKind, 9358 bool StrictlyPositive) { 9359 if (!E) 9360 return ExprError(); 9361 if (E->isValueDependent() || E->isTypeDependent() || 9362 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 9363 return E; 9364 llvm::APSInt Result; 9365 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 9366 if (ICE.isInvalid()) 9367 return ExprError(); 9368 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 9369 (!StrictlyPositive && !Result.isNonNegative())) { 9370 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 9371 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9372 << E->getSourceRange(); 9373 return ExprError(); 9374 } 9375 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 9376 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 9377 << E->getSourceRange(); 9378 return ExprError(); 9379 } 9380 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 9381 DSAStack->setAssociatedLoops(Result.getExtValue()); 9382 else if (CKind == OMPC_ordered) 9383 DSAStack->setAssociatedLoops(Result.getExtValue()); 9384 return ICE; 9385 } 9386 9387 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 9388 SourceLocation LParenLoc, 9389 SourceLocation EndLoc) { 9390 // OpenMP [2.8.1, simd construct, Description] 9391 // The parameter of the safelen clause must be a constant 9392 // positive integer expression. 9393 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 9394 if (Safelen.isInvalid()) 9395 return nullptr; 9396 return new (Context) 9397 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 9398 } 9399 9400 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 9401 SourceLocation LParenLoc, 9402 SourceLocation EndLoc) { 9403 // OpenMP [2.8.1, simd construct, Description] 9404 // The parameter of the simdlen clause must be a constant 9405 // positive integer expression. 9406 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 9407 if (Simdlen.isInvalid()) 9408 return nullptr; 9409 return new (Context) 9410 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 9411 } 9412 9413 /// Tries to find omp_allocator_handle_t type. 9414 static bool findOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 9415 DSAStackTy *Stack) { 9416 QualType OMPAllocatorHandleT = Stack->getOMPAllocatorHandleT(); 9417 if (!OMPAllocatorHandleT.isNull()) 9418 return true; 9419 // Build the predefined allocator expressions. 9420 bool ErrorFound = false; 9421 for (int I = OMPAllocateDeclAttr::OMPDefaultMemAlloc; 9422 I < OMPAllocateDeclAttr::OMPUserDefinedMemAlloc; ++I) { 9423 auto AllocatorKind = static_cast<OMPAllocateDeclAttr::AllocatorTypeTy>(I); 9424 StringRef Allocator = 9425 OMPAllocateDeclAttr::ConvertAllocatorTypeTyToStr(AllocatorKind); 9426 DeclarationName AllocatorName = &S.getASTContext().Idents.get(Allocator); 9427 auto *VD = dyn_cast_or_null<ValueDecl>( 9428 S.LookupSingleName(S.TUScope, AllocatorName, Loc, Sema::LookupAnyName)); 9429 if (!VD) { 9430 ErrorFound = true; 9431 break; 9432 } 9433 QualType AllocatorType = 9434 VD->getType().getNonLValueExprType(S.getASTContext()); 9435 ExprResult Res = S.BuildDeclRefExpr(VD, AllocatorType, VK_LValue, Loc); 9436 if (!Res.isUsable()) { 9437 ErrorFound = true; 9438 break; 9439 } 9440 if (OMPAllocatorHandleT.isNull()) 9441 OMPAllocatorHandleT = AllocatorType; 9442 if (!S.getASTContext().hasSameType(OMPAllocatorHandleT, AllocatorType)) { 9443 ErrorFound = true; 9444 break; 9445 } 9446 Stack->setAllocator(AllocatorKind, Res.get()); 9447 } 9448 if (ErrorFound) { 9449 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 9450 return false; 9451 } 9452 OMPAllocatorHandleT.addConst(); 9453 Stack->setOMPAllocatorHandleT(OMPAllocatorHandleT); 9454 return true; 9455 } 9456 9457 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 9458 SourceLocation LParenLoc, 9459 SourceLocation EndLoc) { 9460 // OpenMP [2.11.3, allocate Directive, Description] 9461 // allocator is an expression of omp_allocator_handle_t type. 9462 if (!findOMPAllocatorHandleT(*this, A->getExprLoc(), DSAStack)) 9463 return nullptr; 9464 9465 ExprResult Allocator = DefaultLvalueConversion(A); 9466 if (Allocator.isInvalid()) 9467 return nullptr; 9468 Allocator = PerformImplicitConversion(Allocator.get(), 9469 DSAStack->getOMPAllocatorHandleT(), 9470 Sema::AA_Initializing, 9471 /*AllowExplicit=*/true); 9472 if (Allocator.isInvalid()) 9473 return nullptr; 9474 return new (Context) 9475 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 9476 } 9477 9478 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 9479 SourceLocation StartLoc, 9480 SourceLocation LParenLoc, 9481 SourceLocation EndLoc) { 9482 // OpenMP [2.7.1, loop construct, Description] 9483 // OpenMP [2.8.1, simd construct, Description] 9484 // OpenMP [2.9.6, distribute construct, Description] 9485 // The parameter of the collapse clause must be a constant 9486 // positive integer expression. 9487 ExprResult NumForLoopsResult = 9488 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 9489 if (NumForLoopsResult.isInvalid()) 9490 return nullptr; 9491 return new (Context) 9492 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 9493 } 9494 9495 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 9496 SourceLocation EndLoc, 9497 SourceLocation LParenLoc, 9498 Expr *NumForLoops) { 9499 // OpenMP [2.7.1, loop construct, Description] 9500 // OpenMP [2.8.1, simd construct, Description] 9501 // OpenMP [2.9.6, distribute construct, Description] 9502 // The parameter of the ordered clause must be a constant 9503 // positive integer expression if any. 9504 if (NumForLoops && LParenLoc.isValid()) { 9505 ExprResult NumForLoopsResult = 9506 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 9507 if (NumForLoopsResult.isInvalid()) 9508 return nullptr; 9509 NumForLoops = NumForLoopsResult.get(); 9510 } else { 9511 NumForLoops = nullptr; 9512 } 9513 auto *Clause = OMPOrderedClause::Create( 9514 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 9515 StartLoc, LParenLoc, EndLoc); 9516 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 9517 return Clause; 9518 } 9519 9520 OMPClause *Sema::ActOnOpenMPSimpleClause( 9521 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 9522 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 9523 OMPClause *Res = nullptr; 9524 switch (Kind) { 9525 case OMPC_default: 9526 Res = 9527 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 9528 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 9529 break; 9530 case OMPC_proc_bind: 9531 Res = ActOnOpenMPProcBindClause( 9532 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 9533 LParenLoc, EndLoc); 9534 break; 9535 case OMPC_atomic_default_mem_order: 9536 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 9537 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 9538 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 9539 break; 9540 case OMPC_if: 9541 case OMPC_final: 9542 case OMPC_num_threads: 9543 case OMPC_safelen: 9544 case OMPC_simdlen: 9545 case OMPC_allocator: 9546 case OMPC_collapse: 9547 case OMPC_schedule: 9548 case OMPC_private: 9549 case OMPC_firstprivate: 9550 case OMPC_lastprivate: 9551 case OMPC_shared: 9552 case OMPC_reduction: 9553 case OMPC_task_reduction: 9554 case OMPC_in_reduction: 9555 case OMPC_linear: 9556 case OMPC_aligned: 9557 case OMPC_copyin: 9558 case OMPC_copyprivate: 9559 case OMPC_ordered: 9560 case OMPC_nowait: 9561 case OMPC_untied: 9562 case OMPC_mergeable: 9563 case OMPC_threadprivate: 9564 case OMPC_allocate: 9565 case OMPC_flush: 9566 case OMPC_read: 9567 case OMPC_write: 9568 case OMPC_update: 9569 case OMPC_capture: 9570 case OMPC_seq_cst: 9571 case OMPC_depend: 9572 case OMPC_device: 9573 case OMPC_threads: 9574 case OMPC_simd: 9575 case OMPC_map: 9576 case OMPC_num_teams: 9577 case OMPC_thread_limit: 9578 case OMPC_priority: 9579 case OMPC_grainsize: 9580 case OMPC_nogroup: 9581 case OMPC_num_tasks: 9582 case OMPC_hint: 9583 case OMPC_dist_schedule: 9584 case OMPC_defaultmap: 9585 case OMPC_unknown: 9586 case OMPC_uniform: 9587 case OMPC_to: 9588 case OMPC_from: 9589 case OMPC_use_device_ptr: 9590 case OMPC_is_device_ptr: 9591 case OMPC_unified_address: 9592 case OMPC_unified_shared_memory: 9593 case OMPC_reverse_offload: 9594 case OMPC_dynamic_allocators: 9595 llvm_unreachable("Clause is not allowed."); 9596 } 9597 return Res; 9598 } 9599 9600 static std::string 9601 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 9602 ArrayRef<unsigned> Exclude = llvm::None) { 9603 SmallString<256> Buffer; 9604 llvm::raw_svector_ostream Out(Buffer); 9605 unsigned Bound = Last >= 2 ? Last - 2 : 0; 9606 unsigned Skipped = Exclude.size(); 9607 auto S = Exclude.begin(), E = Exclude.end(); 9608 for (unsigned I = First; I < Last; ++I) { 9609 if (std::find(S, E, I) != E) { 9610 --Skipped; 9611 continue; 9612 } 9613 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 9614 if (I == Bound - Skipped) 9615 Out << " or "; 9616 else if (I != Bound + 1 - Skipped) 9617 Out << ", "; 9618 } 9619 return Out.str(); 9620 } 9621 9622 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 9623 SourceLocation KindKwLoc, 9624 SourceLocation StartLoc, 9625 SourceLocation LParenLoc, 9626 SourceLocation EndLoc) { 9627 if (Kind == OMPC_DEFAULT_unknown) { 9628 static_assert(OMPC_DEFAULT_unknown > 0, 9629 "OMPC_DEFAULT_unknown not greater than 0"); 9630 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9631 << getListOfPossibleValues(OMPC_default, /*First=*/0, 9632 /*Last=*/OMPC_DEFAULT_unknown) 9633 << getOpenMPClauseName(OMPC_default); 9634 return nullptr; 9635 } 9636 switch (Kind) { 9637 case OMPC_DEFAULT_none: 9638 DSAStack->setDefaultDSANone(KindKwLoc); 9639 break; 9640 case OMPC_DEFAULT_shared: 9641 DSAStack->setDefaultDSAShared(KindKwLoc); 9642 break; 9643 case OMPC_DEFAULT_unknown: 9644 llvm_unreachable("Clause kind is not allowed."); 9645 break; 9646 } 9647 return new (Context) 9648 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 9649 } 9650 9651 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 9652 SourceLocation KindKwLoc, 9653 SourceLocation StartLoc, 9654 SourceLocation LParenLoc, 9655 SourceLocation EndLoc) { 9656 if (Kind == OMPC_PROC_BIND_unknown) { 9657 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9658 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 9659 /*Last=*/OMPC_PROC_BIND_unknown) 9660 << getOpenMPClauseName(OMPC_proc_bind); 9661 return nullptr; 9662 } 9663 return new (Context) 9664 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 9665 } 9666 9667 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 9668 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 9669 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 9670 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 9671 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9672 << getListOfPossibleValues( 9673 OMPC_atomic_default_mem_order, /*First=*/0, 9674 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 9675 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 9676 return nullptr; 9677 } 9678 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 9679 LParenLoc, EndLoc); 9680 } 9681 9682 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 9683 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 9684 SourceLocation StartLoc, SourceLocation LParenLoc, 9685 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 9686 SourceLocation EndLoc) { 9687 OMPClause *Res = nullptr; 9688 switch (Kind) { 9689 case OMPC_schedule: 9690 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 9691 assert(Argument.size() == NumberOfElements && 9692 ArgumentLoc.size() == NumberOfElements); 9693 Res = ActOnOpenMPScheduleClause( 9694 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 9695 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 9696 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 9697 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 9698 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 9699 break; 9700 case OMPC_if: 9701 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 9702 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 9703 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 9704 DelimLoc, EndLoc); 9705 break; 9706 case OMPC_dist_schedule: 9707 Res = ActOnOpenMPDistScheduleClause( 9708 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 9709 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 9710 break; 9711 case OMPC_defaultmap: 9712 enum { Modifier, DefaultmapKind }; 9713 Res = ActOnOpenMPDefaultmapClause( 9714 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 9715 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 9716 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 9717 EndLoc); 9718 break; 9719 case OMPC_final: 9720 case OMPC_num_threads: 9721 case OMPC_safelen: 9722 case OMPC_simdlen: 9723 case OMPC_allocator: 9724 case OMPC_collapse: 9725 case OMPC_default: 9726 case OMPC_proc_bind: 9727 case OMPC_private: 9728 case OMPC_firstprivate: 9729 case OMPC_lastprivate: 9730 case OMPC_shared: 9731 case OMPC_reduction: 9732 case OMPC_task_reduction: 9733 case OMPC_in_reduction: 9734 case OMPC_linear: 9735 case OMPC_aligned: 9736 case OMPC_copyin: 9737 case OMPC_copyprivate: 9738 case OMPC_ordered: 9739 case OMPC_nowait: 9740 case OMPC_untied: 9741 case OMPC_mergeable: 9742 case OMPC_threadprivate: 9743 case OMPC_allocate: 9744 case OMPC_flush: 9745 case OMPC_read: 9746 case OMPC_write: 9747 case OMPC_update: 9748 case OMPC_capture: 9749 case OMPC_seq_cst: 9750 case OMPC_depend: 9751 case OMPC_device: 9752 case OMPC_threads: 9753 case OMPC_simd: 9754 case OMPC_map: 9755 case OMPC_num_teams: 9756 case OMPC_thread_limit: 9757 case OMPC_priority: 9758 case OMPC_grainsize: 9759 case OMPC_nogroup: 9760 case OMPC_num_tasks: 9761 case OMPC_hint: 9762 case OMPC_unknown: 9763 case OMPC_uniform: 9764 case OMPC_to: 9765 case OMPC_from: 9766 case OMPC_use_device_ptr: 9767 case OMPC_is_device_ptr: 9768 case OMPC_unified_address: 9769 case OMPC_unified_shared_memory: 9770 case OMPC_reverse_offload: 9771 case OMPC_dynamic_allocators: 9772 case OMPC_atomic_default_mem_order: 9773 llvm_unreachable("Clause is not allowed."); 9774 } 9775 return Res; 9776 } 9777 9778 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 9779 OpenMPScheduleClauseModifier M2, 9780 SourceLocation M1Loc, SourceLocation M2Loc) { 9781 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 9782 SmallVector<unsigned, 2> Excluded; 9783 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 9784 Excluded.push_back(M2); 9785 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 9786 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 9787 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 9788 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 9789 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 9790 << getListOfPossibleValues(OMPC_schedule, 9791 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 9792 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 9793 Excluded) 9794 << getOpenMPClauseName(OMPC_schedule); 9795 return true; 9796 } 9797 return false; 9798 } 9799 9800 OMPClause *Sema::ActOnOpenMPScheduleClause( 9801 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 9802 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 9803 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 9804 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 9805 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 9806 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 9807 return nullptr; 9808 // OpenMP, 2.7.1, Loop Construct, Restrictions 9809 // Either the monotonic modifier or the nonmonotonic modifier can be specified 9810 // but not both. 9811 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 9812 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 9813 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 9814 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 9815 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 9816 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 9817 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 9818 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 9819 return nullptr; 9820 } 9821 if (Kind == OMPC_SCHEDULE_unknown) { 9822 std::string Values; 9823 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 9824 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 9825 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 9826 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 9827 Exclude); 9828 } else { 9829 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 9830 /*Last=*/OMPC_SCHEDULE_unknown); 9831 } 9832 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 9833 << Values << getOpenMPClauseName(OMPC_schedule); 9834 return nullptr; 9835 } 9836 // OpenMP, 2.7.1, Loop Construct, Restrictions 9837 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 9838 // schedule(guided). 9839 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 9840 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 9841 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 9842 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 9843 diag::err_omp_schedule_nonmonotonic_static); 9844 return nullptr; 9845 } 9846 Expr *ValExpr = ChunkSize; 9847 Stmt *HelperValStmt = nullptr; 9848 if (ChunkSize) { 9849 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 9850 !ChunkSize->isInstantiationDependent() && 9851 !ChunkSize->containsUnexpandedParameterPack()) { 9852 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 9853 ExprResult Val = 9854 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 9855 if (Val.isInvalid()) 9856 return nullptr; 9857 9858 ValExpr = Val.get(); 9859 9860 // OpenMP [2.7.1, Restrictions] 9861 // chunk_size must be a loop invariant integer expression with a positive 9862 // value. 9863 llvm::APSInt Result; 9864 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 9865 if (Result.isSigned() && !Result.isStrictlyPositive()) { 9866 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 9867 << "schedule" << 1 << ChunkSize->getSourceRange(); 9868 return nullptr; 9869 } 9870 } else if (getOpenMPCaptureRegionForClause( 9871 DSAStack->getCurrentDirective(), OMPC_schedule) != 9872 OMPD_unknown && 9873 !CurContext->isDependentContext()) { 9874 ValExpr = MakeFullExpr(ValExpr).get(); 9875 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9876 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9877 HelperValStmt = buildPreInits(Context, Captures); 9878 } 9879 } 9880 } 9881 9882 return new (Context) 9883 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 9884 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 9885 } 9886 9887 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 9888 SourceLocation StartLoc, 9889 SourceLocation EndLoc) { 9890 OMPClause *Res = nullptr; 9891 switch (Kind) { 9892 case OMPC_ordered: 9893 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 9894 break; 9895 case OMPC_nowait: 9896 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 9897 break; 9898 case OMPC_untied: 9899 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 9900 break; 9901 case OMPC_mergeable: 9902 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 9903 break; 9904 case OMPC_read: 9905 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 9906 break; 9907 case OMPC_write: 9908 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 9909 break; 9910 case OMPC_update: 9911 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 9912 break; 9913 case OMPC_capture: 9914 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 9915 break; 9916 case OMPC_seq_cst: 9917 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 9918 break; 9919 case OMPC_threads: 9920 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 9921 break; 9922 case OMPC_simd: 9923 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 9924 break; 9925 case OMPC_nogroup: 9926 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 9927 break; 9928 case OMPC_unified_address: 9929 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 9930 break; 9931 case OMPC_unified_shared_memory: 9932 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 9933 break; 9934 case OMPC_reverse_offload: 9935 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 9936 break; 9937 case OMPC_dynamic_allocators: 9938 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 9939 break; 9940 case OMPC_if: 9941 case OMPC_final: 9942 case OMPC_num_threads: 9943 case OMPC_safelen: 9944 case OMPC_simdlen: 9945 case OMPC_allocator: 9946 case OMPC_collapse: 9947 case OMPC_schedule: 9948 case OMPC_private: 9949 case OMPC_firstprivate: 9950 case OMPC_lastprivate: 9951 case OMPC_shared: 9952 case OMPC_reduction: 9953 case OMPC_task_reduction: 9954 case OMPC_in_reduction: 9955 case OMPC_linear: 9956 case OMPC_aligned: 9957 case OMPC_copyin: 9958 case OMPC_copyprivate: 9959 case OMPC_default: 9960 case OMPC_proc_bind: 9961 case OMPC_threadprivate: 9962 case OMPC_allocate: 9963 case OMPC_flush: 9964 case OMPC_depend: 9965 case OMPC_device: 9966 case OMPC_map: 9967 case OMPC_num_teams: 9968 case OMPC_thread_limit: 9969 case OMPC_priority: 9970 case OMPC_grainsize: 9971 case OMPC_num_tasks: 9972 case OMPC_hint: 9973 case OMPC_dist_schedule: 9974 case OMPC_defaultmap: 9975 case OMPC_unknown: 9976 case OMPC_uniform: 9977 case OMPC_to: 9978 case OMPC_from: 9979 case OMPC_use_device_ptr: 9980 case OMPC_is_device_ptr: 9981 case OMPC_atomic_default_mem_order: 9982 llvm_unreachable("Clause is not allowed."); 9983 } 9984 return Res; 9985 } 9986 9987 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 9988 SourceLocation EndLoc) { 9989 DSAStack->setNowaitRegion(); 9990 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 9991 } 9992 9993 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 9994 SourceLocation EndLoc) { 9995 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 9996 } 9997 9998 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 9999 SourceLocation EndLoc) { 10000 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 10001 } 10002 10003 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 10004 SourceLocation EndLoc) { 10005 return new (Context) OMPReadClause(StartLoc, EndLoc); 10006 } 10007 10008 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 10009 SourceLocation EndLoc) { 10010 return new (Context) OMPWriteClause(StartLoc, EndLoc); 10011 } 10012 10013 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 10014 SourceLocation EndLoc) { 10015 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 10016 } 10017 10018 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 10019 SourceLocation EndLoc) { 10020 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 10021 } 10022 10023 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 10024 SourceLocation EndLoc) { 10025 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 10026 } 10027 10028 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 10029 SourceLocation EndLoc) { 10030 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 10031 } 10032 10033 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 10034 SourceLocation EndLoc) { 10035 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 10036 } 10037 10038 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 10039 SourceLocation EndLoc) { 10040 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 10041 } 10042 10043 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 10044 SourceLocation EndLoc) { 10045 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 10046 } 10047 10048 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 10049 SourceLocation EndLoc) { 10050 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 10051 } 10052 10053 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 10054 SourceLocation EndLoc) { 10055 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 10056 } 10057 10058 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 10059 SourceLocation EndLoc) { 10060 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 10061 } 10062 10063 OMPClause *Sema::ActOnOpenMPVarListClause( 10064 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 10065 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 10066 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 10067 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 10068 OpenMPLinearClauseKind LinKind, 10069 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 10070 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 10071 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 10072 SourceLocation StartLoc = Locs.StartLoc; 10073 SourceLocation LParenLoc = Locs.LParenLoc; 10074 SourceLocation EndLoc = Locs.EndLoc; 10075 OMPClause *Res = nullptr; 10076 switch (Kind) { 10077 case OMPC_private: 10078 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10079 break; 10080 case OMPC_firstprivate: 10081 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10082 break; 10083 case OMPC_lastprivate: 10084 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10085 break; 10086 case OMPC_shared: 10087 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 10088 break; 10089 case OMPC_reduction: 10090 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10091 EndLoc, ReductionOrMapperIdScopeSpec, 10092 ReductionOrMapperId); 10093 break; 10094 case OMPC_task_reduction: 10095 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10096 EndLoc, ReductionOrMapperIdScopeSpec, 10097 ReductionOrMapperId); 10098 break; 10099 case OMPC_in_reduction: 10100 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10101 EndLoc, ReductionOrMapperIdScopeSpec, 10102 ReductionOrMapperId); 10103 break; 10104 case OMPC_linear: 10105 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 10106 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 10107 break; 10108 case OMPC_aligned: 10109 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 10110 ColonLoc, EndLoc); 10111 break; 10112 case OMPC_copyin: 10113 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 10114 break; 10115 case OMPC_copyprivate: 10116 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10117 break; 10118 case OMPC_flush: 10119 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 10120 break; 10121 case OMPC_depend: 10122 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 10123 StartLoc, LParenLoc, EndLoc); 10124 break; 10125 case OMPC_map: 10126 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 10127 ReductionOrMapperIdScopeSpec, 10128 ReductionOrMapperId, MapType, IsMapTypeImplicit, 10129 DepLinMapLoc, ColonLoc, VarList, Locs); 10130 break; 10131 case OMPC_to: 10132 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 10133 ReductionOrMapperId, Locs); 10134 break; 10135 case OMPC_from: 10136 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 10137 ReductionOrMapperId, Locs); 10138 break; 10139 case OMPC_use_device_ptr: 10140 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 10141 break; 10142 case OMPC_is_device_ptr: 10143 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 10144 break; 10145 case OMPC_if: 10146 case OMPC_final: 10147 case OMPC_num_threads: 10148 case OMPC_safelen: 10149 case OMPC_simdlen: 10150 case OMPC_allocator: 10151 case OMPC_collapse: 10152 case OMPC_default: 10153 case OMPC_proc_bind: 10154 case OMPC_schedule: 10155 case OMPC_ordered: 10156 case OMPC_nowait: 10157 case OMPC_untied: 10158 case OMPC_mergeable: 10159 case OMPC_threadprivate: 10160 case OMPC_allocate: 10161 case OMPC_read: 10162 case OMPC_write: 10163 case OMPC_update: 10164 case OMPC_capture: 10165 case OMPC_seq_cst: 10166 case OMPC_device: 10167 case OMPC_threads: 10168 case OMPC_simd: 10169 case OMPC_num_teams: 10170 case OMPC_thread_limit: 10171 case OMPC_priority: 10172 case OMPC_grainsize: 10173 case OMPC_nogroup: 10174 case OMPC_num_tasks: 10175 case OMPC_hint: 10176 case OMPC_dist_schedule: 10177 case OMPC_defaultmap: 10178 case OMPC_unknown: 10179 case OMPC_uniform: 10180 case OMPC_unified_address: 10181 case OMPC_unified_shared_memory: 10182 case OMPC_reverse_offload: 10183 case OMPC_dynamic_allocators: 10184 case OMPC_atomic_default_mem_order: 10185 llvm_unreachable("Clause is not allowed."); 10186 } 10187 return Res; 10188 } 10189 10190 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 10191 ExprObjectKind OK, SourceLocation Loc) { 10192 ExprResult Res = BuildDeclRefExpr( 10193 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 10194 if (!Res.isUsable()) 10195 return ExprError(); 10196 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 10197 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 10198 if (!Res.isUsable()) 10199 return ExprError(); 10200 } 10201 if (VK != VK_LValue && Res.get()->isGLValue()) { 10202 Res = DefaultLvalueConversion(Res.get()); 10203 if (!Res.isUsable()) 10204 return ExprError(); 10205 } 10206 return Res; 10207 } 10208 10209 static std::pair<ValueDecl *, bool> 10210 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 10211 SourceRange &ERange, bool AllowArraySection = false) { 10212 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 10213 RefExpr->containsUnexpandedParameterPack()) 10214 return std::make_pair(nullptr, true); 10215 10216 // OpenMP [3.1, C/C++] 10217 // A list item is a variable name. 10218 // OpenMP [2.9.3.3, Restrictions, p.1] 10219 // A variable that is part of another variable (as an array or 10220 // structure element) cannot appear in a private clause. 10221 RefExpr = RefExpr->IgnoreParens(); 10222 enum { 10223 NoArrayExpr = -1, 10224 ArraySubscript = 0, 10225 OMPArraySection = 1 10226 } IsArrayExpr = NoArrayExpr; 10227 if (AllowArraySection) { 10228 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 10229 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 10230 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 10231 Base = TempASE->getBase()->IgnoreParenImpCasts(); 10232 RefExpr = Base; 10233 IsArrayExpr = ArraySubscript; 10234 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 10235 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 10236 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 10237 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 10238 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 10239 Base = TempASE->getBase()->IgnoreParenImpCasts(); 10240 RefExpr = Base; 10241 IsArrayExpr = OMPArraySection; 10242 } 10243 } 10244 ELoc = RefExpr->getExprLoc(); 10245 ERange = RefExpr->getSourceRange(); 10246 RefExpr = RefExpr->IgnoreParenImpCasts(); 10247 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 10248 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 10249 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 10250 (S.getCurrentThisType().isNull() || !ME || 10251 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 10252 !isa<FieldDecl>(ME->getMemberDecl()))) { 10253 if (IsArrayExpr != NoArrayExpr) { 10254 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 10255 << ERange; 10256 } else { 10257 S.Diag(ELoc, 10258 AllowArraySection 10259 ? diag::err_omp_expected_var_name_member_expr_or_array_item 10260 : diag::err_omp_expected_var_name_member_expr) 10261 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 10262 } 10263 return std::make_pair(nullptr, false); 10264 } 10265 return std::make_pair( 10266 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 10267 } 10268 10269 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 10270 SourceLocation StartLoc, 10271 SourceLocation LParenLoc, 10272 SourceLocation EndLoc) { 10273 SmallVector<Expr *, 8> Vars; 10274 SmallVector<Expr *, 8> PrivateCopies; 10275 for (Expr *RefExpr : VarList) { 10276 assert(RefExpr && "NULL expr in OpenMP private clause."); 10277 SourceLocation ELoc; 10278 SourceRange ERange; 10279 Expr *SimpleRefExpr = RefExpr; 10280 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10281 if (Res.second) { 10282 // It will be analyzed later. 10283 Vars.push_back(RefExpr); 10284 PrivateCopies.push_back(nullptr); 10285 } 10286 ValueDecl *D = Res.first; 10287 if (!D) 10288 continue; 10289 10290 QualType Type = D->getType(); 10291 auto *VD = dyn_cast<VarDecl>(D); 10292 10293 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10294 // A variable that appears in a private clause must not have an incomplete 10295 // type or a reference type. 10296 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 10297 continue; 10298 Type = Type.getNonReferenceType(); 10299 10300 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 10301 // A variable that is privatized must not have a const-qualified type 10302 // unless it is of class type with a mutable member. This restriction does 10303 // not apply to the firstprivate clause. 10304 // 10305 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 10306 // A variable that appears in a private clause must not have a 10307 // const-qualified type unless it is of class type with a mutable member. 10308 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 10309 continue; 10310 10311 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10312 // in a Construct] 10313 // Variables with the predetermined data-sharing attributes may not be 10314 // listed in data-sharing attributes clauses, except for the cases 10315 // listed below. For these exceptions only, listing a predetermined 10316 // variable in a data-sharing attribute clause is allowed and overrides 10317 // the variable's predetermined data-sharing attributes. 10318 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10319 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 10320 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10321 << getOpenMPClauseName(OMPC_private); 10322 reportOriginalDsa(*this, DSAStack, D, DVar); 10323 continue; 10324 } 10325 10326 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10327 // Variably modified types are not supported for tasks. 10328 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10329 isOpenMPTaskingDirective(CurrDir)) { 10330 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10331 << getOpenMPClauseName(OMPC_private) << Type 10332 << getOpenMPDirectiveName(CurrDir); 10333 bool IsDecl = 10334 !VD || 10335 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10336 Diag(D->getLocation(), 10337 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10338 << D; 10339 continue; 10340 } 10341 10342 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10343 // A list item cannot appear in both a map clause and a data-sharing 10344 // attribute clause on the same construct 10345 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10346 OpenMPClauseKind ConflictKind; 10347 if (DSAStack->checkMappableExprComponentListsForDecl( 10348 VD, /*CurrentRegionOnly=*/true, 10349 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 10350 OpenMPClauseKind WhereFoundClauseKind) -> bool { 10351 ConflictKind = WhereFoundClauseKind; 10352 return true; 10353 })) { 10354 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10355 << getOpenMPClauseName(OMPC_private) 10356 << getOpenMPClauseName(ConflictKind) 10357 << getOpenMPDirectiveName(CurrDir); 10358 reportOriginalDsa(*this, DSAStack, D, DVar); 10359 continue; 10360 } 10361 } 10362 10363 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 10364 // A variable of class type (or array thereof) that appears in a private 10365 // clause requires an accessible, unambiguous default constructor for the 10366 // class type. 10367 // Generate helper private variable and initialize it with the default 10368 // value. The address of the original variable is replaced by the address of 10369 // the new private variable in CodeGen. This new variable is not added to 10370 // IdResolver, so the code in the OpenMP region uses original variable for 10371 // proper diagnostics. 10372 Type = Type.getUnqualifiedType(); 10373 VarDecl *VDPrivate = 10374 buildVarDecl(*this, ELoc, Type, D->getName(), 10375 D->hasAttrs() ? &D->getAttrs() : nullptr, 10376 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10377 ActOnUninitializedDecl(VDPrivate); 10378 if (VDPrivate->isInvalidDecl()) 10379 continue; 10380 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10381 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 10382 10383 DeclRefExpr *Ref = nullptr; 10384 if (!VD && !CurContext->isDependentContext()) 10385 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10386 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 10387 Vars.push_back((VD || CurContext->isDependentContext()) 10388 ? RefExpr->IgnoreParens() 10389 : Ref); 10390 PrivateCopies.push_back(VDPrivateRefExpr); 10391 } 10392 10393 if (Vars.empty()) 10394 return nullptr; 10395 10396 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 10397 PrivateCopies); 10398 } 10399 10400 namespace { 10401 class DiagsUninitializedSeveretyRAII { 10402 private: 10403 DiagnosticsEngine &Diags; 10404 SourceLocation SavedLoc; 10405 bool IsIgnored = false; 10406 10407 public: 10408 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 10409 bool IsIgnored) 10410 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 10411 if (!IsIgnored) { 10412 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 10413 /*Map*/ diag::Severity::Ignored, Loc); 10414 } 10415 } 10416 ~DiagsUninitializedSeveretyRAII() { 10417 if (!IsIgnored) 10418 Diags.popMappings(SavedLoc); 10419 } 10420 }; 10421 } 10422 10423 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 10424 SourceLocation StartLoc, 10425 SourceLocation LParenLoc, 10426 SourceLocation EndLoc) { 10427 SmallVector<Expr *, 8> Vars; 10428 SmallVector<Expr *, 8> PrivateCopies; 10429 SmallVector<Expr *, 8> Inits; 10430 SmallVector<Decl *, 4> ExprCaptures; 10431 bool IsImplicitClause = 10432 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 10433 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 10434 10435 for (Expr *RefExpr : VarList) { 10436 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 10437 SourceLocation ELoc; 10438 SourceRange ERange; 10439 Expr *SimpleRefExpr = RefExpr; 10440 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10441 if (Res.second) { 10442 // It will be analyzed later. 10443 Vars.push_back(RefExpr); 10444 PrivateCopies.push_back(nullptr); 10445 Inits.push_back(nullptr); 10446 } 10447 ValueDecl *D = Res.first; 10448 if (!D) 10449 continue; 10450 10451 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 10452 QualType Type = D->getType(); 10453 auto *VD = dyn_cast<VarDecl>(D); 10454 10455 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10456 // A variable that appears in a private clause must not have an incomplete 10457 // type or a reference type. 10458 if (RequireCompleteType(ELoc, Type, 10459 diag::err_omp_firstprivate_incomplete_type)) 10460 continue; 10461 Type = Type.getNonReferenceType(); 10462 10463 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 10464 // A variable of class type (or array thereof) that appears in a private 10465 // clause requires an accessible, unambiguous copy constructor for the 10466 // class type. 10467 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 10468 10469 // If an implicit firstprivate variable found it was checked already. 10470 DSAStackTy::DSAVarData TopDVar; 10471 if (!IsImplicitClause) { 10472 DSAStackTy::DSAVarData DVar = 10473 DSAStack->getTopDSA(D, /*FromParent=*/false); 10474 TopDVar = DVar; 10475 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10476 bool IsConstant = ElemType.isConstant(Context); 10477 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 10478 // A list item that specifies a given variable may not appear in more 10479 // than one clause on the same directive, except that a variable may be 10480 // specified in both firstprivate and lastprivate clauses. 10481 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 10482 // A list item may appear in a firstprivate or lastprivate clause but not 10483 // both. 10484 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 10485 (isOpenMPDistributeDirective(CurrDir) || 10486 DVar.CKind != OMPC_lastprivate) && 10487 DVar.RefExpr) { 10488 Diag(ELoc, diag::err_omp_wrong_dsa) 10489 << getOpenMPClauseName(DVar.CKind) 10490 << getOpenMPClauseName(OMPC_firstprivate); 10491 reportOriginalDsa(*this, DSAStack, D, DVar); 10492 continue; 10493 } 10494 10495 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10496 // in a Construct] 10497 // Variables with the predetermined data-sharing attributes may not be 10498 // listed in data-sharing attributes clauses, except for the cases 10499 // listed below. For these exceptions only, listing a predetermined 10500 // variable in a data-sharing attribute clause is allowed and overrides 10501 // the variable's predetermined data-sharing attributes. 10502 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10503 // in a Construct, C/C++, p.2] 10504 // Variables with const-qualified type having no mutable member may be 10505 // listed in a firstprivate clause, even if they are static data members. 10506 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 10507 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 10508 Diag(ELoc, diag::err_omp_wrong_dsa) 10509 << getOpenMPClauseName(DVar.CKind) 10510 << getOpenMPClauseName(OMPC_firstprivate); 10511 reportOriginalDsa(*this, DSAStack, D, DVar); 10512 continue; 10513 } 10514 10515 // OpenMP [2.9.3.4, Restrictions, p.2] 10516 // A list item that is private within a parallel region must not appear 10517 // in a firstprivate clause on a worksharing construct if any of the 10518 // worksharing regions arising from the worksharing construct ever bind 10519 // to any of the parallel regions arising from the parallel construct. 10520 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 10521 // A list item that is private within a teams region must not appear in a 10522 // firstprivate clause on a distribute construct if any of the distribute 10523 // regions arising from the distribute construct ever bind to any of the 10524 // teams regions arising from the teams construct. 10525 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 10526 // A list item that appears in a reduction clause of a teams construct 10527 // must not appear in a firstprivate clause on a distribute construct if 10528 // any of the distribute regions arising from the distribute construct 10529 // ever bind to any of the teams regions arising from the teams construct. 10530 if ((isOpenMPWorksharingDirective(CurrDir) || 10531 isOpenMPDistributeDirective(CurrDir)) && 10532 !isOpenMPParallelDirective(CurrDir) && 10533 !isOpenMPTeamsDirective(CurrDir)) { 10534 DVar = DSAStack->getImplicitDSA(D, true); 10535 if (DVar.CKind != OMPC_shared && 10536 (isOpenMPParallelDirective(DVar.DKind) || 10537 isOpenMPTeamsDirective(DVar.DKind) || 10538 DVar.DKind == OMPD_unknown)) { 10539 Diag(ELoc, diag::err_omp_required_access) 10540 << getOpenMPClauseName(OMPC_firstprivate) 10541 << getOpenMPClauseName(OMPC_shared); 10542 reportOriginalDsa(*this, DSAStack, D, DVar); 10543 continue; 10544 } 10545 } 10546 // OpenMP [2.9.3.4, Restrictions, p.3] 10547 // A list item that appears in a reduction clause of a parallel construct 10548 // must not appear in a firstprivate clause on a worksharing or task 10549 // construct if any of the worksharing or task regions arising from the 10550 // worksharing or task construct ever bind to any of the parallel regions 10551 // arising from the parallel construct. 10552 // OpenMP [2.9.3.4, Restrictions, p.4] 10553 // A list item that appears in a reduction clause in worksharing 10554 // construct must not appear in a firstprivate clause in a task construct 10555 // encountered during execution of any of the worksharing regions arising 10556 // from the worksharing construct. 10557 if (isOpenMPTaskingDirective(CurrDir)) { 10558 DVar = DSAStack->hasInnermostDSA( 10559 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 10560 [](OpenMPDirectiveKind K) { 10561 return isOpenMPParallelDirective(K) || 10562 isOpenMPWorksharingDirective(K) || 10563 isOpenMPTeamsDirective(K); 10564 }, 10565 /*FromParent=*/true); 10566 if (DVar.CKind == OMPC_reduction && 10567 (isOpenMPParallelDirective(DVar.DKind) || 10568 isOpenMPWorksharingDirective(DVar.DKind) || 10569 isOpenMPTeamsDirective(DVar.DKind))) { 10570 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 10571 << getOpenMPDirectiveName(DVar.DKind); 10572 reportOriginalDsa(*this, DSAStack, D, DVar); 10573 continue; 10574 } 10575 } 10576 10577 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10578 // A list item cannot appear in both a map clause and a data-sharing 10579 // attribute clause on the same construct 10580 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10581 OpenMPClauseKind ConflictKind; 10582 if (DSAStack->checkMappableExprComponentListsForDecl( 10583 VD, /*CurrentRegionOnly=*/true, 10584 [&ConflictKind]( 10585 OMPClauseMappableExprCommon::MappableExprComponentListRef, 10586 OpenMPClauseKind WhereFoundClauseKind) { 10587 ConflictKind = WhereFoundClauseKind; 10588 return true; 10589 })) { 10590 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10591 << getOpenMPClauseName(OMPC_firstprivate) 10592 << getOpenMPClauseName(ConflictKind) 10593 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10594 reportOriginalDsa(*this, DSAStack, D, DVar); 10595 continue; 10596 } 10597 } 10598 } 10599 10600 // Variably modified types are not supported for tasks. 10601 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10602 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 10603 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10604 << getOpenMPClauseName(OMPC_firstprivate) << Type 10605 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10606 bool IsDecl = 10607 !VD || 10608 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10609 Diag(D->getLocation(), 10610 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10611 << D; 10612 continue; 10613 } 10614 10615 Type = Type.getUnqualifiedType(); 10616 VarDecl *VDPrivate = 10617 buildVarDecl(*this, ELoc, Type, D->getName(), 10618 D->hasAttrs() ? &D->getAttrs() : nullptr, 10619 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10620 // Generate helper private variable and initialize it with the value of the 10621 // original variable. The address of the original variable is replaced by 10622 // the address of the new private variable in the CodeGen. This new variable 10623 // is not added to IdResolver, so the code in the OpenMP region uses 10624 // original variable for proper diagnostics and variable capturing. 10625 Expr *VDInitRefExpr = nullptr; 10626 // For arrays generate initializer for single element and replace it by the 10627 // original array element in CodeGen. 10628 if (Type->isArrayType()) { 10629 VarDecl *VDInit = 10630 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 10631 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 10632 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 10633 ElemType = ElemType.getUnqualifiedType(); 10634 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 10635 ".firstprivate.temp"); 10636 InitializedEntity Entity = 10637 InitializedEntity::InitializeVariable(VDInitTemp); 10638 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 10639 10640 InitializationSequence InitSeq(*this, Entity, Kind, Init); 10641 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 10642 if (Result.isInvalid()) 10643 VDPrivate->setInvalidDecl(); 10644 else 10645 VDPrivate->setInit(Result.getAs<Expr>()); 10646 // Remove temp variable declaration. 10647 Context.Deallocate(VDInitTemp); 10648 } else { 10649 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 10650 ".firstprivate.temp"); 10651 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 10652 RefExpr->getExprLoc()); 10653 AddInitializerToDecl(VDPrivate, 10654 DefaultLvalueConversion(VDInitRefExpr).get(), 10655 /*DirectInit=*/false); 10656 } 10657 if (VDPrivate->isInvalidDecl()) { 10658 if (IsImplicitClause) { 10659 Diag(RefExpr->getExprLoc(), 10660 diag::note_omp_task_predetermined_firstprivate_here); 10661 } 10662 continue; 10663 } 10664 CurContext->addDecl(VDPrivate); 10665 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10666 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 10667 RefExpr->getExprLoc()); 10668 DeclRefExpr *Ref = nullptr; 10669 if (!VD && !CurContext->isDependentContext()) { 10670 if (TopDVar.CKind == OMPC_lastprivate) { 10671 Ref = TopDVar.PrivateCopy; 10672 } else { 10673 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10674 if (!isOpenMPCapturedDecl(D)) 10675 ExprCaptures.push_back(Ref->getDecl()); 10676 } 10677 } 10678 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 10679 Vars.push_back((VD || CurContext->isDependentContext()) 10680 ? RefExpr->IgnoreParens() 10681 : Ref); 10682 PrivateCopies.push_back(VDPrivateRefExpr); 10683 Inits.push_back(VDInitRefExpr); 10684 } 10685 10686 if (Vars.empty()) 10687 return nullptr; 10688 10689 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10690 Vars, PrivateCopies, Inits, 10691 buildPreInits(Context, ExprCaptures)); 10692 } 10693 10694 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 10695 SourceLocation StartLoc, 10696 SourceLocation LParenLoc, 10697 SourceLocation EndLoc) { 10698 SmallVector<Expr *, 8> Vars; 10699 SmallVector<Expr *, 8> SrcExprs; 10700 SmallVector<Expr *, 8> DstExprs; 10701 SmallVector<Expr *, 8> AssignmentOps; 10702 SmallVector<Decl *, 4> ExprCaptures; 10703 SmallVector<Expr *, 4> ExprPostUpdates; 10704 for (Expr *RefExpr : VarList) { 10705 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 10706 SourceLocation ELoc; 10707 SourceRange ERange; 10708 Expr *SimpleRefExpr = RefExpr; 10709 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10710 if (Res.second) { 10711 // It will be analyzed later. 10712 Vars.push_back(RefExpr); 10713 SrcExprs.push_back(nullptr); 10714 DstExprs.push_back(nullptr); 10715 AssignmentOps.push_back(nullptr); 10716 } 10717 ValueDecl *D = Res.first; 10718 if (!D) 10719 continue; 10720 10721 QualType Type = D->getType(); 10722 auto *VD = dyn_cast<VarDecl>(D); 10723 10724 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 10725 // A variable that appears in a lastprivate clause must not have an 10726 // incomplete type or a reference type. 10727 if (RequireCompleteType(ELoc, Type, 10728 diag::err_omp_lastprivate_incomplete_type)) 10729 continue; 10730 Type = Type.getNonReferenceType(); 10731 10732 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 10733 // A variable that is privatized must not have a const-qualified type 10734 // unless it is of class type with a mutable member. This restriction does 10735 // not apply to the firstprivate clause. 10736 // 10737 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 10738 // A variable that appears in a lastprivate clause must not have a 10739 // const-qualified type unless it is of class type with a mutable member. 10740 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 10741 continue; 10742 10743 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10744 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 10745 // in a Construct] 10746 // Variables with the predetermined data-sharing attributes may not be 10747 // listed in data-sharing attributes clauses, except for the cases 10748 // listed below. 10749 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 10750 // A list item may appear in a firstprivate or lastprivate clause but not 10751 // both. 10752 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10753 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 10754 (isOpenMPDistributeDirective(CurrDir) || 10755 DVar.CKind != OMPC_firstprivate) && 10756 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 10757 Diag(ELoc, diag::err_omp_wrong_dsa) 10758 << getOpenMPClauseName(DVar.CKind) 10759 << getOpenMPClauseName(OMPC_lastprivate); 10760 reportOriginalDsa(*this, DSAStack, D, DVar); 10761 continue; 10762 } 10763 10764 // OpenMP [2.14.3.5, Restrictions, p.2] 10765 // A list item that is private within a parallel region, or that appears in 10766 // the reduction clause of a parallel construct, must not appear in a 10767 // lastprivate clause on a worksharing construct if any of the corresponding 10768 // worksharing regions ever binds to any of the corresponding parallel 10769 // regions. 10770 DSAStackTy::DSAVarData TopDVar = DVar; 10771 if (isOpenMPWorksharingDirective(CurrDir) && 10772 !isOpenMPParallelDirective(CurrDir) && 10773 !isOpenMPTeamsDirective(CurrDir)) { 10774 DVar = DSAStack->getImplicitDSA(D, true); 10775 if (DVar.CKind != OMPC_shared) { 10776 Diag(ELoc, diag::err_omp_required_access) 10777 << getOpenMPClauseName(OMPC_lastprivate) 10778 << getOpenMPClauseName(OMPC_shared); 10779 reportOriginalDsa(*this, DSAStack, D, DVar); 10780 continue; 10781 } 10782 } 10783 10784 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 10785 // A variable of class type (or array thereof) that appears in a 10786 // lastprivate clause requires an accessible, unambiguous default 10787 // constructor for the class type, unless the list item is also specified 10788 // in a firstprivate clause. 10789 // A variable of class type (or array thereof) that appears in a 10790 // lastprivate clause requires an accessible, unambiguous copy assignment 10791 // operator for the class type. 10792 Type = Context.getBaseElementType(Type).getNonReferenceType(); 10793 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 10794 Type.getUnqualifiedType(), ".lastprivate.src", 10795 D->hasAttrs() ? &D->getAttrs() : nullptr); 10796 DeclRefExpr *PseudoSrcExpr = 10797 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 10798 VarDecl *DstVD = 10799 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 10800 D->hasAttrs() ? &D->getAttrs() : nullptr); 10801 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 10802 // For arrays generate assignment operation for single element and replace 10803 // it by the original array element in CodeGen. 10804 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 10805 PseudoDstExpr, PseudoSrcExpr); 10806 if (AssignmentOp.isInvalid()) 10807 continue; 10808 AssignmentOp = 10809 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 10810 if (AssignmentOp.isInvalid()) 10811 continue; 10812 10813 DeclRefExpr *Ref = nullptr; 10814 if (!VD && !CurContext->isDependentContext()) { 10815 if (TopDVar.CKind == OMPC_firstprivate) { 10816 Ref = TopDVar.PrivateCopy; 10817 } else { 10818 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10819 if (!isOpenMPCapturedDecl(D)) 10820 ExprCaptures.push_back(Ref->getDecl()); 10821 } 10822 if (TopDVar.CKind == OMPC_firstprivate || 10823 (!isOpenMPCapturedDecl(D) && 10824 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 10825 ExprResult RefRes = DefaultLvalueConversion(Ref); 10826 if (!RefRes.isUsable()) 10827 continue; 10828 ExprResult PostUpdateRes = 10829 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 10830 RefRes.get()); 10831 if (!PostUpdateRes.isUsable()) 10832 continue; 10833 ExprPostUpdates.push_back( 10834 IgnoredValueConversions(PostUpdateRes.get()).get()); 10835 } 10836 } 10837 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 10838 Vars.push_back((VD || CurContext->isDependentContext()) 10839 ? RefExpr->IgnoreParens() 10840 : Ref); 10841 SrcExprs.push_back(PseudoSrcExpr); 10842 DstExprs.push_back(PseudoDstExpr); 10843 AssignmentOps.push_back(AssignmentOp.get()); 10844 } 10845 10846 if (Vars.empty()) 10847 return nullptr; 10848 10849 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10850 Vars, SrcExprs, DstExprs, AssignmentOps, 10851 buildPreInits(Context, ExprCaptures), 10852 buildPostUpdate(*this, ExprPostUpdates)); 10853 } 10854 10855 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 10856 SourceLocation StartLoc, 10857 SourceLocation LParenLoc, 10858 SourceLocation EndLoc) { 10859 SmallVector<Expr *, 8> Vars; 10860 for (Expr *RefExpr : VarList) { 10861 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 10862 SourceLocation ELoc; 10863 SourceRange ERange; 10864 Expr *SimpleRefExpr = RefExpr; 10865 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10866 if (Res.second) { 10867 // It will be analyzed later. 10868 Vars.push_back(RefExpr); 10869 } 10870 ValueDecl *D = Res.first; 10871 if (!D) 10872 continue; 10873 10874 auto *VD = dyn_cast<VarDecl>(D); 10875 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10876 // in a Construct] 10877 // Variables with the predetermined data-sharing attributes may not be 10878 // listed in data-sharing attributes clauses, except for the cases 10879 // listed below. For these exceptions only, listing a predetermined 10880 // variable in a data-sharing attribute clause is allowed and overrides 10881 // the variable's predetermined data-sharing attributes. 10882 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10883 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 10884 DVar.RefExpr) { 10885 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10886 << getOpenMPClauseName(OMPC_shared); 10887 reportOriginalDsa(*this, DSAStack, D, DVar); 10888 continue; 10889 } 10890 10891 DeclRefExpr *Ref = nullptr; 10892 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 10893 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10894 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 10895 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 10896 ? RefExpr->IgnoreParens() 10897 : Ref); 10898 } 10899 10900 if (Vars.empty()) 10901 return nullptr; 10902 10903 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 10904 } 10905 10906 namespace { 10907 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 10908 DSAStackTy *Stack; 10909 10910 public: 10911 bool VisitDeclRefExpr(DeclRefExpr *E) { 10912 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 10913 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 10914 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 10915 return false; 10916 if (DVar.CKind != OMPC_unknown) 10917 return true; 10918 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 10919 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 10920 /*FromParent=*/true); 10921 return DVarPrivate.CKind != OMPC_unknown; 10922 } 10923 return false; 10924 } 10925 bool VisitStmt(Stmt *S) { 10926 for (Stmt *Child : S->children()) { 10927 if (Child && Visit(Child)) 10928 return true; 10929 } 10930 return false; 10931 } 10932 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 10933 }; 10934 } // namespace 10935 10936 namespace { 10937 // Transform MemberExpression for specified FieldDecl of current class to 10938 // DeclRefExpr to specified OMPCapturedExprDecl. 10939 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 10940 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 10941 ValueDecl *Field = nullptr; 10942 DeclRefExpr *CapturedExpr = nullptr; 10943 10944 public: 10945 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 10946 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 10947 10948 ExprResult TransformMemberExpr(MemberExpr *E) { 10949 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 10950 E->getMemberDecl() == Field) { 10951 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 10952 return CapturedExpr; 10953 } 10954 return BaseTransform::TransformMemberExpr(E); 10955 } 10956 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 10957 }; 10958 } // namespace 10959 10960 template <typename T, typename U> 10961 static T filterLookupForUDReductionAndMapper( 10962 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 10963 for (U &Set : Lookups) { 10964 for (auto *D : Set) { 10965 if (T Res = Gen(cast<ValueDecl>(D))) 10966 return Res; 10967 } 10968 } 10969 return T(); 10970 } 10971 10972 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 10973 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 10974 10975 for (auto RD : D->redecls()) { 10976 // Don't bother with extra checks if we already know this one isn't visible. 10977 if (RD == D) 10978 continue; 10979 10980 auto ND = cast<NamedDecl>(RD); 10981 if (LookupResult::isVisible(SemaRef, ND)) 10982 return ND; 10983 } 10984 10985 return nullptr; 10986 } 10987 10988 static void 10989 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 10990 SourceLocation Loc, QualType Ty, 10991 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 10992 // Find all of the associated namespaces and classes based on the 10993 // arguments we have. 10994 Sema::AssociatedNamespaceSet AssociatedNamespaces; 10995 Sema::AssociatedClassSet AssociatedClasses; 10996 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 10997 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 10998 AssociatedClasses); 10999 11000 // C++ [basic.lookup.argdep]p3: 11001 // Let X be the lookup set produced by unqualified lookup (3.4.1) 11002 // and let Y be the lookup set produced by argument dependent 11003 // lookup (defined as follows). If X contains [...] then Y is 11004 // empty. Otherwise Y is the set of declarations found in the 11005 // namespaces associated with the argument types as described 11006 // below. The set of declarations found by the lookup of the name 11007 // is the union of X and Y. 11008 // 11009 // Here, we compute Y and add its members to the overloaded 11010 // candidate set. 11011 for (auto *NS : AssociatedNamespaces) { 11012 // When considering an associated namespace, the lookup is the 11013 // same as the lookup performed when the associated namespace is 11014 // used as a qualifier (3.4.3.2) except that: 11015 // 11016 // -- Any using-directives in the associated namespace are 11017 // ignored. 11018 // 11019 // -- Any namespace-scope friend functions declared in 11020 // associated classes are visible within their respective 11021 // namespaces even if they are not visible during an ordinary 11022 // lookup (11.4). 11023 DeclContext::lookup_result R = NS->lookup(Id.getName()); 11024 for (auto *D : R) { 11025 auto *Underlying = D; 11026 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11027 Underlying = USD->getTargetDecl(); 11028 11029 if (!isa<OMPDeclareReductionDecl>(Underlying) && 11030 !isa<OMPDeclareMapperDecl>(Underlying)) 11031 continue; 11032 11033 if (!SemaRef.isVisible(D)) { 11034 D = findAcceptableDecl(SemaRef, D); 11035 if (!D) 11036 continue; 11037 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 11038 Underlying = USD->getTargetDecl(); 11039 } 11040 Lookups.emplace_back(); 11041 Lookups.back().addDecl(Underlying); 11042 } 11043 } 11044 } 11045 11046 static ExprResult 11047 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 11048 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 11049 const DeclarationNameInfo &ReductionId, QualType Ty, 11050 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 11051 if (ReductionIdScopeSpec.isInvalid()) 11052 return ExprError(); 11053 SmallVector<UnresolvedSet<8>, 4> Lookups; 11054 if (S) { 11055 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11056 Lookup.suppressDiagnostics(); 11057 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 11058 NamedDecl *D = Lookup.getRepresentativeDecl(); 11059 do { 11060 S = S->getParent(); 11061 } while (S && !S->isDeclScope(D)); 11062 if (S) 11063 S = S->getParent(); 11064 Lookups.emplace_back(); 11065 Lookups.back().append(Lookup.begin(), Lookup.end()); 11066 Lookup.clear(); 11067 } 11068 } else if (auto *ULE = 11069 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 11070 Lookups.push_back(UnresolvedSet<8>()); 11071 Decl *PrevD = nullptr; 11072 for (NamedDecl *D : ULE->decls()) { 11073 if (D == PrevD) 11074 Lookups.push_back(UnresolvedSet<8>()); 11075 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 11076 Lookups.back().addDecl(DRD); 11077 PrevD = D; 11078 } 11079 } 11080 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 11081 Ty->isInstantiationDependentType() || 11082 Ty->containsUnexpandedParameterPack() || 11083 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 11084 return !D->isInvalidDecl() && 11085 (D->getType()->isDependentType() || 11086 D->getType()->isInstantiationDependentType() || 11087 D->getType()->containsUnexpandedParameterPack()); 11088 })) { 11089 UnresolvedSet<8> ResSet; 11090 for (const UnresolvedSet<8> &Set : Lookups) { 11091 if (Set.empty()) 11092 continue; 11093 ResSet.append(Set.begin(), Set.end()); 11094 // The last item marks the end of all declarations at the specified scope. 11095 ResSet.addDecl(Set[Set.size() - 1]); 11096 } 11097 return UnresolvedLookupExpr::Create( 11098 SemaRef.Context, /*NamingClass=*/nullptr, 11099 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 11100 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 11101 } 11102 // Lookup inside the classes. 11103 // C++ [over.match.oper]p3: 11104 // For a unary operator @ with an operand of a type whose 11105 // cv-unqualified version is T1, and for a binary operator @ with 11106 // a left operand of a type whose cv-unqualified version is T1 and 11107 // a right operand of a type whose cv-unqualified version is T2, 11108 // three sets of candidate functions, designated member 11109 // candidates, non-member candidates and built-in candidates, are 11110 // constructed as follows: 11111 // -- If T1 is a complete class type or a class currently being 11112 // defined, the set of member candidates is the result of the 11113 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 11114 // the set of member candidates is empty. 11115 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11116 Lookup.suppressDiagnostics(); 11117 if (const auto *TyRec = Ty->getAs<RecordType>()) { 11118 // Complete the type if it can be completed. 11119 // If the type is neither complete nor being defined, bail out now. 11120 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 11121 TyRec->getDecl()->getDefinition()) { 11122 Lookup.clear(); 11123 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 11124 if (Lookup.empty()) { 11125 Lookups.emplace_back(); 11126 Lookups.back().append(Lookup.begin(), Lookup.end()); 11127 } 11128 } 11129 } 11130 // Perform ADL. 11131 if (SemaRef.getLangOpts().CPlusPlus) { 11132 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 11133 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11134 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 11135 if (!D->isInvalidDecl() && 11136 SemaRef.Context.hasSameType(D->getType(), Ty)) 11137 return D; 11138 return nullptr; 11139 })) 11140 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 11141 VK_LValue, Loc); 11142 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11143 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 11144 if (!D->isInvalidDecl() && 11145 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 11146 !Ty.isMoreQualifiedThan(D->getType())) 11147 return D; 11148 return nullptr; 11149 })) { 11150 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 11151 /*DetectVirtual=*/false); 11152 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 11153 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 11154 VD->getType().getUnqualifiedType()))) { 11155 if (SemaRef.CheckBaseClassAccess( 11156 Loc, VD->getType(), Ty, Paths.front(), 11157 /*DiagID=*/0) != Sema::AR_inaccessible) { 11158 SemaRef.BuildBasePathArray(Paths, BasePath); 11159 return SemaRef.BuildDeclRefExpr( 11160 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 11161 } 11162 } 11163 } 11164 } 11165 } 11166 if (ReductionIdScopeSpec.isSet()) { 11167 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 11168 return ExprError(); 11169 } 11170 return ExprEmpty(); 11171 } 11172 11173 namespace { 11174 /// Data for the reduction-based clauses. 11175 struct ReductionData { 11176 /// List of original reduction items. 11177 SmallVector<Expr *, 8> Vars; 11178 /// List of private copies of the reduction items. 11179 SmallVector<Expr *, 8> Privates; 11180 /// LHS expressions for the reduction_op expressions. 11181 SmallVector<Expr *, 8> LHSs; 11182 /// RHS expressions for the reduction_op expressions. 11183 SmallVector<Expr *, 8> RHSs; 11184 /// Reduction operation expression. 11185 SmallVector<Expr *, 8> ReductionOps; 11186 /// Taskgroup descriptors for the corresponding reduction items in 11187 /// in_reduction clauses. 11188 SmallVector<Expr *, 8> TaskgroupDescriptors; 11189 /// List of captures for clause. 11190 SmallVector<Decl *, 4> ExprCaptures; 11191 /// List of postupdate expressions. 11192 SmallVector<Expr *, 4> ExprPostUpdates; 11193 ReductionData() = delete; 11194 /// Reserves required memory for the reduction data. 11195 ReductionData(unsigned Size) { 11196 Vars.reserve(Size); 11197 Privates.reserve(Size); 11198 LHSs.reserve(Size); 11199 RHSs.reserve(Size); 11200 ReductionOps.reserve(Size); 11201 TaskgroupDescriptors.reserve(Size); 11202 ExprCaptures.reserve(Size); 11203 ExprPostUpdates.reserve(Size); 11204 } 11205 /// Stores reduction item and reduction operation only (required for dependent 11206 /// reduction item). 11207 void push(Expr *Item, Expr *ReductionOp) { 11208 Vars.emplace_back(Item); 11209 Privates.emplace_back(nullptr); 11210 LHSs.emplace_back(nullptr); 11211 RHSs.emplace_back(nullptr); 11212 ReductionOps.emplace_back(ReductionOp); 11213 TaskgroupDescriptors.emplace_back(nullptr); 11214 } 11215 /// Stores reduction data. 11216 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 11217 Expr *TaskgroupDescriptor) { 11218 Vars.emplace_back(Item); 11219 Privates.emplace_back(Private); 11220 LHSs.emplace_back(LHS); 11221 RHSs.emplace_back(RHS); 11222 ReductionOps.emplace_back(ReductionOp); 11223 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 11224 } 11225 }; 11226 } // namespace 11227 11228 static bool checkOMPArraySectionConstantForReduction( 11229 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 11230 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 11231 const Expr *Length = OASE->getLength(); 11232 if (Length == nullptr) { 11233 // For array sections of the form [1:] or [:], we would need to analyze 11234 // the lower bound... 11235 if (OASE->getColonLoc().isValid()) 11236 return false; 11237 11238 // This is an array subscript which has implicit length 1! 11239 SingleElement = true; 11240 ArraySizes.push_back(llvm::APSInt::get(1)); 11241 } else { 11242 Expr::EvalResult Result; 11243 if (!Length->EvaluateAsInt(Result, Context)) 11244 return false; 11245 11246 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11247 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 11248 ArraySizes.push_back(ConstantLengthValue); 11249 } 11250 11251 // Get the base of this array section and walk up from there. 11252 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 11253 11254 // We require length = 1 for all array sections except the right-most to 11255 // guarantee that the memory region is contiguous and has no holes in it. 11256 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 11257 Length = TempOASE->getLength(); 11258 if (Length == nullptr) { 11259 // For array sections of the form [1:] or [:], we would need to analyze 11260 // the lower bound... 11261 if (OASE->getColonLoc().isValid()) 11262 return false; 11263 11264 // This is an array subscript which has implicit length 1! 11265 ArraySizes.push_back(llvm::APSInt::get(1)); 11266 } else { 11267 Expr::EvalResult Result; 11268 if (!Length->EvaluateAsInt(Result, Context)) 11269 return false; 11270 11271 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11272 if (ConstantLengthValue.getSExtValue() != 1) 11273 return false; 11274 11275 ArraySizes.push_back(ConstantLengthValue); 11276 } 11277 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 11278 } 11279 11280 // If we have a single element, we don't need to add the implicit lengths. 11281 if (!SingleElement) { 11282 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 11283 // Has implicit length 1! 11284 ArraySizes.push_back(llvm::APSInt::get(1)); 11285 Base = TempASE->getBase()->IgnoreParenImpCasts(); 11286 } 11287 } 11288 11289 // This array section can be privatized as a single value or as a constant 11290 // sized array. 11291 return true; 11292 } 11293 11294 static bool actOnOMPReductionKindClause( 11295 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 11296 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11297 SourceLocation ColonLoc, SourceLocation EndLoc, 11298 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11299 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 11300 DeclarationName DN = ReductionId.getName(); 11301 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 11302 BinaryOperatorKind BOK = BO_Comma; 11303 11304 ASTContext &Context = S.Context; 11305 // OpenMP [2.14.3.6, reduction clause] 11306 // C 11307 // reduction-identifier is either an identifier or one of the following 11308 // operators: +, -, *, &, |, ^, && and || 11309 // C++ 11310 // reduction-identifier is either an id-expression or one of the following 11311 // operators: +, -, *, &, |, ^, && and || 11312 switch (OOK) { 11313 case OO_Plus: 11314 case OO_Minus: 11315 BOK = BO_Add; 11316 break; 11317 case OO_Star: 11318 BOK = BO_Mul; 11319 break; 11320 case OO_Amp: 11321 BOK = BO_And; 11322 break; 11323 case OO_Pipe: 11324 BOK = BO_Or; 11325 break; 11326 case OO_Caret: 11327 BOK = BO_Xor; 11328 break; 11329 case OO_AmpAmp: 11330 BOK = BO_LAnd; 11331 break; 11332 case OO_PipePipe: 11333 BOK = BO_LOr; 11334 break; 11335 case OO_New: 11336 case OO_Delete: 11337 case OO_Array_New: 11338 case OO_Array_Delete: 11339 case OO_Slash: 11340 case OO_Percent: 11341 case OO_Tilde: 11342 case OO_Exclaim: 11343 case OO_Equal: 11344 case OO_Less: 11345 case OO_Greater: 11346 case OO_LessEqual: 11347 case OO_GreaterEqual: 11348 case OO_PlusEqual: 11349 case OO_MinusEqual: 11350 case OO_StarEqual: 11351 case OO_SlashEqual: 11352 case OO_PercentEqual: 11353 case OO_CaretEqual: 11354 case OO_AmpEqual: 11355 case OO_PipeEqual: 11356 case OO_LessLess: 11357 case OO_GreaterGreater: 11358 case OO_LessLessEqual: 11359 case OO_GreaterGreaterEqual: 11360 case OO_EqualEqual: 11361 case OO_ExclaimEqual: 11362 case OO_Spaceship: 11363 case OO_PlusPlus: 11364 case OO_MinusMinus: 11365 case OO_Comma: 11366 case OO_ArrowStar: 11367 case OO_Arrow: 11368 case OO_Call: 11369 case OO_Subscript: 11370 case OO_Conditional: 11371 case OO_Coawait: 11372 case NUM_OVERLOADED_OPERATORS: 11373 llvm_unreachable("Unexpected reduction identifier"); 11374 case OO_None: 11375 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 11376 if (II->isStr("max")) 11377 BOK = BO_GT; 11378 else if (II->isStr("min")) 11379 BOK = BO_LT; 11380 } 11381 break; 11382 } 11383 SourceRange ReductionIdRange; 11384 if (ReductionIdScopeSpec.isValid()) 11385 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 11386 else 11387 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 11388 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 11389 11390 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 11391 bool FirstIter = true; 11392 for (Expr *RefExpr : VarList) { 11393 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 11394 // OpenMP [2.1, C/C++] 11395 // A list item is a variable or array section, subject to the restrictions 11396 // specified in Section 2.4 on page 42 and in each of the sections 11397 // describing clauses and directives for which a list appears. 11398 // OpenMP [2.14.3.3, Restrictions, p.1] 11399 // A variable that is part of another variable (as an array or 11400 // structure element) cannot appear in a private clause. 11401 if (!FirstIter && IR != ER) 11402 ++IR; 11403 FirstIter = false; 11404 SourceLocation ELoc; 11405 SourceRange ERange; 11406 Expr *SimpleRefExpr = RefExpr; 11407 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 11408 /*AllowArraySection=*/true); 11409 if (Res.second) { 11410 // Try to find 'declare reduction' corresponding construct before using 11411 // builtin/overloaded operators. 11412 QualType Type = Context.DependentTy; 11413 CXXCastPath BasePath; 11414 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11415 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11416 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11417 Expr *ReductionOp = nullptr; 11418 if (S.CurContext->isDependentContext() && 11419 (DeclareReductionRef.isUnset() || 11420 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 11421 ReductionOp = DeclareReductionRef.get(); 11422 // It will be analyzed later. 11423 RD.push(RefExpr, ReductionOp); 11424 } 11425 ValueDecl *D = Res.first; 11426 if (!D) 11427 continue; 11428 11429 Expr *TaskgroupDescriptor = nullptr; 11430 QualType Type; 11431 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 11432 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 11433 if (ASE) { 11434 Type = ASE->getType().getNonReferenceType(); 11435 } else if (OASE) { 11436 QualType BaseType = 11437 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 11438 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 11439 Type = ATy->getElementType(); 11440 else 11441 Type = BaseType->getPointeeType(); 11442 Type = Type.getNonReferenceType(); 11443 } else { 11444 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 11445 } 11446 auto *VD = dyn_cast<VarDecl>(D); 11447 11448 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11449 // A variable that appears in a private clause must not have an incomplete 11450 // type or a reference type. 11451 if (S.RequireCompleteType(ELoc, D->getType(), 11452 diag::err_omp_reduction_incomplete_type)) 11453 continue; 11454 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11455 // A list item that appears in a reduction clause must not be 11456 // const-qualified. 11457 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 11458 /*AcceptIfMutable*/ false, ASE || OASE)) 11459 continue; 11460 11461 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 11462 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 11463 // If a list-item is a reference type then it must bind to the same object 11464 // for all threads of the team. 11465 if (!ASE && !OASE) { 11466 if (VD) { 11467 VarDecl *VDDef = VD->getDefinition(); 11468 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 11469 DSARefChecker Check(Stack); 11470 if (Check.Visit(VDDef->getInit())) { 11471 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 11472 << getOpenMPClauseName(ClauseKind) << ERange; 11473 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 11474 continue; 11475 } 11476 } 11477 } 11478 11479 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11480 // in a Construct] 11481 // Variables with the predetermined data-sharing attributes may not be 11482 // listed in data-sharing attributes clauses, except for the cases 11483 // listed below. For these exceptions only, listing a predetermined 11484 // variable in a data-sharing attribute clause is allowed and overrides 11485 // the variable's predetermined data-sharing attributes. 11486 // OpenMP [2.14.3.6, Restrictions, p.3] 11487 // Any number of reduction clauses can be specified on the directive, 11488 // but a list item can appear only once in the reduction clauses for that 11489 // directive. 11490 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 11491 if (DVar.CKind == OMPC_reduction) { 11492 S.Diag(ELoc, diag::err_omp_once_referenced) 11493 << getOpenMPClauseName(ClauseKind); 11494 if (DVar.RefExpr) 11495 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 11496 continue; 11497 } 11498 if (DVar.CKind != OMPC_unknown) { 11499 S.Diag(ELoc, diag::err_omp_wrong_dsa) 11500 << getOpenMPClauseName(DVar.CKind) 11501 << getOpenMPClauseName(OMPC_reduction); 11502 reportOriginalDsa(S, Stack, D, DVar); 11503 continue; 11504 } 11505 11506 // OpenMP [2.14.3.6, Restrictions, p.1] 11507 // A list item that appears in a reduction clause of a worksharing 11508 // construct must be shared in the parallel regions to which any of the 11509 // worksharing regions arising from the worksharing construct bind. 11510 if (isOpenMPWorksharingDirective(CurrDir) && 11511 !isOpenMPParallelDirective(CurrDir) && 11512 !isOpenMPTeamsDirective(CurrDir)) { 11513 DVar = Stack->getImplicitDSA(D, true); 11514 if (DVar.CKind != OMPC_shared) { 11515 S.Diag(ELoc, diag::err_omp_required_access) 11516 << getOpenMPClauseName(OMPC_reduction) 11517 << getOpenMPClauseName(OMPC_shared); 11518 reportOriginalDsa(S, Stack, D, DVar); 11519 continue; 11520 } 11521 } 11522 } 11523 11524 // Try to find 'declare reduction' corresponding construct before using 11525 // builtin/overloaded operators. 11526 CXXCastPath BasePath; 11527 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11528 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11529 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11530 if (DeclareReductionRef.isInvalid()) 11531 continue; 11532 if (S.CurContext->isDependentContext() && 11533 (DeclareReductionRef.isUnset() || 11534 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 11535 RD.push(RefExpr, DeclareReductionRef.get()); 11536 continue; 11537 } 11538 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 11539 // Not allowed reduction identifier is found. 11540 S.Diag(ReductionId.getBeginLoc(), 11541 diag::err_omp_unknown_reduction_identifier) 11542 << Type << ReductionIdRange; 11543 continue; 11544 } 11545 11546 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11547 // The type of a list item that appears in a reduction clause must be valid 11548 // for the reduction-identifier. For a max or min reduction in C, the type 11549 // of the list item must be an allowed arithmetic data type: char, int, 11550 // float, double, or _Bool, possibly modified with long, short, signed, or 11551 // unsigned. For a max or min reduction in C++, the type of the list item 11552 // must be an allowed arithmetic data type: char, wchar_t, int, float, 11553 // double, or bool, possibly modified with long, short, signed, or unsigned. 11554 if (DeclareReductionRef.isUnset()) { 11555 if ((BOK == BO_GT || BOK == BO_LT) && 11556 !(Type->isScalarType() || 11557 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 11558 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 11559 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 11560 if (!ASE && !OASE) { 11561 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11562 VarDecl::DeclarationOnly; 11563 S.Diag(D->getLocation(), 11564 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11565 << D; 11566 } 11567 continue; 11568 } 11569 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 11570 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 11571 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 11572 << getOpenMPClauseName(ClauseKind); 11573 if (!ASE && !OASE) { 11574 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11575 VarDecl::DeclarationOnly; 11576 S.Diag(D->getLocation(), 11577 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11578 << D; 11579 } 11580 continue; 11581 } 11582 } 11583 11584 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 11585 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 11586 D->hasAttrs() ? &D->getAttrs() : nullptr); 11587 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 11588 D->hasAttrs() ? &D->getAttrs() : nullptr); 11589 QualType PrivateTy = Type; 11590 11591 // Try if we can determine constant lengths for all array sections and avoid 11592 // the VLA. 11593 bool ConstantLengthOASE = false; 11594 if (OASE) { 11595 bool SingleElement; 11596 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 11597 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 11598 Context, OASE, SingleElement, ArraySizes); 11599 11600 // If we don't have a single element, we must emit a constant array type. 11601 if (ConstantLengthOASE && !SingleElement) { 11602 for (llvm::APSInt &Size : ArraySizes) 11603 PrivateTy = Context.getConstantArrayType( 11604 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 11605 } 11606 } 11607 11608 if ((OASE && !ConstantLengthOASE) || 11609 (!OASE && !ASE && 11610 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 11611 if (!Context.getTargetInfo().isVLASupported() && 11612 S.shouldDiagnoseTargetSupportFromOpenMP()) { 11613 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 11614 S.Diag(ELoc, diag::note_vla_unsupported); 11615 continue; 11616 } 11617 // For arrays/array sections only: 11618 // Create pseudo array type for private copy. The size for this array will 11619 // be generated during codegen. 11620 // For array subscripts or single variables Private Ty is the same as Type 11621 // (type of the variable or single array element). 11622 PrivateTy = Context.getVariableArrayType( 11623 Type, 11624 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 11625 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 11626 } else if (!ASE && !OASE && 11627 Context.getAsArrayType(D->getType().getNonReferenceType())) { 11628 PrivateTy = D->getType().getNonReferenceType(); 11629 } 11630 // Private copy. 11631 VarDecl *PrivateVD = 11632 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 11633 D->hasAttrs() ? &D->getAttrs() : nullptr, 11634 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11635 // Add initializer for private variable. 11636 Expr *Init = nullptr; 11637 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 11638 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 11639 if (DeclareReductionRef.isUsable()) { 11640 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 11641 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 11642 if (DRD->getInitializer()) { 11643 Init = DRDRef; 11644 RHSVD->setInit(DRDRef); 11645 RHSVD->setInitStyle(VarDecl::CallInit); 11646 } 11647 } else { 11648 switch (BOK) { 11649 case BO_Add: 11650 case BO_Xor: 11651 case BO_Or: 11652 case BO_LOr: 11653 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 11654 if (Type->isScalarType() || Type->isAnyComplexType()) 11655 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 11656 break; 11657 case BO_Mul: 11658 case BO_LAnd: 11659 if (Type->isScalarType() || Type->isAnyComplexType()) { 11660 // '*' and '&&' reduction ops - initializer is '1'. 11661 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 11662 } 11663 break; 11664 case BO_And: { 11665 // '&' reduction op - initializer is '~0'. 11666 QualType OrigType = Type; 11667 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 11668 Type = ComplexTy->getElementType(); 11669 if (Type->isRealFloatingType()) { 11670 llvm::APFloat InitValue = 11671 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 11672 /*isIEEE=*/true); 11673 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 11674 Type, ELoc); 11675 } else if (Type->isScalarType()) { 11676 uint64_t Size = Context.getTypeSize(Type); 11677 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 11678 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 11679 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 11680 } 11681 if (Init && OrigType->isAnyComplexType()) { 11682 // Init = 0xFFFF + 0xFFFFi; 11683 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 11684 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 11685 } 11686 Type = OrigType; 11687 break; 11688 } 11689 case BO_LT: 11690 case BO_GT: { 11691 // 'min' reduction op - initializer is 'Largest representable number in 11692 // the reduction list item type'. 11693 // 'max' reduction op - initializer is 'Least representable number in 11694 // the reduction list item type'. 11695 if (Type->isIntegerType() || Type->isPointerType()) { 11696 bool IsSigned = Type->hasSignedIntegerRepresentation(); 11697 uint64_t Size = Context.getTypeSize(Type); 11698 QualType IntTy = 11699 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 11700 llvm::APInt InitValue = 11701 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 11702 : llvm::APInt::getMinValue(Size) 11703 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 11704 : llvm::APInt::getMaxValue(Size); 11705 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 11706 if (Type->isPointerType()) { 11707 // Cast to pointer type. 11708 ExprResult CastExpr = S.BuildCStyleCastExpr( 11709 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 11710 if (CastExpr.isInvalid()) 11711 continue; 11712 Init = CastExpr.get(); 11713 } 11714 } else if (Type->isRealFloatingType()) { 11715 llvm::APFloat InitValue = llvm::APFloat::getLargest( 11716 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 11717 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 11718 Type, ELoc); 11719 } 11720 break; 11721 } 11722 case BO_PtrMemD: 11723 case BO_PtrMemI: 11724 case BO_MulAssign: 11725 case BO_Div: 11726 case BO_Rem: 11727 case BO_Sub: 11728 case BO_Shl: 11729 case BO_Shr: 11730 case BO_LE: 11731 case BO_GE: 11732 case BO_EQ: 11733 case BO_NE: 11734 case BO_Cmp: 11735 case BO_AndAssign: 11736 case BO_XorAssign: 11737 case BO_OrAssign: 11738 case BO_Assign: 11739 case BO_AddAssign: 11740 case BO_SubAssign: 11741 case BO_DivAssign: 11742 case BO_RemAssign: 11743 case BO_ShlAssign: 11744 case BO_ShrAssign: 11745 case BO_Comma: 11746 llvm_unreachable("Unexpected reduction operation"); 11747 } 11748 } 11749 if (Init && DeclareReductionRef.isUnset()) 11750 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 11751 else if (!Init) 11752 S.ActOnUninitializedDecl(RHSVD); 11753 if (RHSVD->isInvalidDecl()) 11754 continue; 11755 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 11756 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 11757 << Type << ReductionIdRange; 11758 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11759 VarDecl::DeclarationOnly; 11760 S.Diag(D->getLocation(), 11761 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11762 << D; 11763 continue; 11764 } 11765 // Store initializer for single element in private copy. Will be used during 11766 // codegen. 11767 PrivateVD->setInit(RHSVD->getInit()); 11768 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 11769 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 11770 ExprResult ReductionOp; 11771 if (DeclareReductionRef.isUsable()) { 11772 QualType RedTy = DeclareReductionRef.get()->getType(); 11773 QualType PtrRedTy = Context.getPointerType(RedTy); 11774 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 11775 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 11776 if (!BasePath.empty()) { 11777 LHS = S.DefaultLvalueConversion(LHS.get()); 11778 RHS = S.DefaultLvalueConversion(RHS.get()); 11779 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 11780 CK_UncheckedDerivedToBase, LHS.get(), 11781 &BasePath, LHS.get()->getValueKind()); 11782 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 11783 CK_UncheckedDerivedToBase, RHS.get(), 11784 &BasePath, RHS.get()->getValueKind()); 11785 } 11786 FunctionProtoType::ExtProtoInfo EPI; 11787 QualType Params[] = {PtrRedTy, PtrRedTy}; 11788 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 11789 auto *OVE = new (Context) OpaqueValueExpr( 11790 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 11791 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 11792 Expr *Args[] = {LHS.get(), RHS.get()}; 11793 ReductionOp = 11794 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 11795 } else { 11796 ReductionOp = S.BuildBinOp( 11797 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 11798 if (ReductionOp.isUsable()) { 11799 if (BOK != BO_LT && BOK != BO_GT) { 11800 ReductionOp = 11801 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 11802 BO_Assign, LHSDRE, ReductionOp.get()); 11803 } else { 11804 auto *ConditionalOp = new (Context) 11805 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 11806 Type, VK_LValue, OK_Ordinary); 11807 ReductionOp = 11808 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 11809 BO_Assign, LHSDRE, ConditionalOp); 11810 } 11811 if (ReductionOp.isUsable()) 11812 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 11813 /*DiscardedValue*/ false); 11814 } 11815 if (!ReductionOp.isUsable()) 11816 continue; 11817 } 11818 11819 // OpenMP [2.15.4.6, Restrictions, p.2] 11820 // A list item that appears in an in_reduction clause of a task construct 11821 // must appear in a task_reduction clause of a construct associated with a 11822 // taskgroup region that includes the participating task in its taskgroup 11823 // set. The construct associated with the innermost region that meets this 11824 // condition must specify the same reduction-identifier as the in_reduction 11825 // clause. 11826 if (ClauseKind == OMPC_in_reduction) { 11827 SourceRange ParentSR; 11828 BinaryOperatorKind ParentBOK; 11829 const Expr *ParentReductionOp; 11830 Expr *ParentBOKTD, *ParentReductionOpTD; 11831 DSAStackTy::DSAVarData ParentBOKDSA = 11832 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 11833 ParentBOKTD); 11834 DSAStackTy::DSAVarData ParentReductionOpDSA = 11835 Stack->getTopMostTaskgroupReductionData( 11836 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 11837 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 11838 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 11839 if (!IsParentBOK && !IsParentReductionOp) { 11840 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 11841 continue; 11842 } 11843 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 11844 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 11845 IsParentReductionOp) { 11846 bool EmitError = true; 11847 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 11848 llvm::FoldingSetNodeID RedId, ParentRedId; 11849 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 11850 DeclareReductionRef.get()->Profile(RedId, Context, 11851 /*Canonical=*/true); 11852 EmitError = RedId != ParentRedId; 11853 } 11854 if (EmitError) { 11855 S.Diag(ReductionId.getBeginLoc(), 11856 diag::err_omp_reduction_identifier_mismatch) 11857 << ReductionIdRange << RefExpr->getSourceRange(); 11858 S.Diag(ParentSR.getBegin(), 11859 diag::note_omp_previous_reduction_identifier) 11860 << ParentSR 11861 << (IsParentBOK ? ParentBOKDSA.RefExpr 11862 : ParentReductionOpDSA.RefExpr) 11863 ->getSourceRange(); 11864 continue; 11865 } 11866 } 11867 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 11868 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 11869 } 11870 11871 DeclRefExpr *Ref = nullptr; 11872 Expr *VarsExpr = RefExpr->IgnoreParens(); 11873 if (!VD && !S.CurContext->isDependentContext()) { 11874 if (ASE || OASE) { 11875 TransformExprToCaptures RebuildToCapture(S, D); 11876 VarsExpr = 11877 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 11878 Ref = RebuildToCapture.getCapturedExpr(); 11879 } else { 11880 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 11881 } 11882 if (!S.isOpenMPCapturedDecl(D)) { 11883 RD.ExprCaptures.emplace_back(Ref->getDecl()); 11884 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 11885 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 11886 if (!RefRes.isUsable()) 11887 continue; 11888 ExprResult PostUpdateRes = 11889 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11890 RefRes.get()); 11891 if (!PostUpdateRes.isUsable()) 11892 continue; 11893 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 11894 Stack->getCurrentDirective() == OMPD_taskgroup) { 11895 S.Diag(RefExpr->getExprLoc(), 11896 diag::err_omp_reduction_non_addressable_expression) 11897 << RefExpr->getSourceRange(); 11898 continue; 11899 } 11900 RD.ExprPostUpdates.emplace_back( 11901 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 11902 } 11903 } 11904 } 11905 // All reduction items are still marked as reduction (to do not increase 11906 // code base size). 11907 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 11908 if (CurrDir == OMPD_taskgroup) { 11909 if (DeclareReductionRef.isUsable()) 11910 Stack->addTaskgroupReductionData(D, ReductionIdRange, 11911 DeclareReductionRef.get()); 11912 else 11913 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 11914 } 11915 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 11916 TaskgroupDescriptor); 11917 } 11918 return RD.Vars.empty(); 11919 } 11920 11921 OMPClause *Sema::ActOnOpenMPReductionClause( 11922 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11923 SourceLocation ColonLoc, SourceLocation EndLoc, 11924 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11925 ArrayRef<Expr *> UnresolvedReductions) { 11926 ReductionData RD(VarList.size()); 11927 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 11928 StartLoc, LParenLoc, ColonLoc, EndLoc, 11929 ReductionIdScopeSpec, ReductionId, 11930 UnresolvedReductions, RD)) 11931 return nullptr; 11932 11933 return OMPReductionClause::Create( 11934 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11935 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11936 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 11937 buildPreInits(Context, RD.ExprCaptures), 11938 buildPostUpdate(*this, RD.ExprPostUpdates)); 11939 } 11940 11941 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 11942 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11943 SourceLocation ColonLoc, SourceLocation EndLoc, 11944 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11945 ArrayRef<Expr *> UnresolvedReductions) { 11946 ReductionData RD(VarList.size()); 11947 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 11948 StartLoc, LParenLoc, ColonLoc, EndLoc, 11949 ReductionIdScopeSpec, ReductionId, 11950 UnresolvedReductions, RD)) 11951 return nullptr; 11952 11953 return OMPTaskReductionClause::Create( 11954 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11955 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11956 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 11957 buildPreInits(Context, RD.ExprCaptures), 11958 buildPostUpdate(*this, RD.ExprPostUpdates)); 11959 } 11960 11961 OMPClause *Sema::ActOnOpenMPInReductionClause( 11962 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11963 SourceLocation ColonLoc, SourceLocation EndLoc, 11964 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11965 ArrayRef<Expr *> UnresolvedReductions) { 11966 ReductionData RD(VarList.size()); 11967 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 11968 StartLoc, LParenLoc, ColonLoc, EndLoc, 11969 ReductionIdScopeSpec, ReductionId, 11970 UnresolvedReductions, RD)) 11971 return nullptr; 11972 11973 return OMPInReductionClause::Create( 11974 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11975 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11976 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 11977 buildPreInits(Context, RD.ExprCaptures), 11978 buildPostUpdate(*this, RD.ExprPostUpdates)); 11979 } 11980 11981 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 11982 SourceLocation LinLoc) { 11983 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 11984 LinKind == OMPC_LINEAR_unknown) { 11985 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 11986 return true; 11987 } 11988 return false; 11989 } 11990 11991 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 11992 OpenMPLinearClauseKind LinKind, 11993 QualType Type) { 11994 const auto *VD = dyn_cast_or_null<VarDecl>(D); 11995 // A variable must not have an incomplete type or a reference type. 11996 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 11997 return true; 11998 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 11999 !Type->isReferenceType()) { 12000 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 12001 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 12002 return true; 12003 } 12004 Type = Type.getNonReferenceType(); 12005 12006 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 12007 // A variable that is privatized must not have a const-qualified type 12008 // unless it is of class type with a mutable member. This restriction does 12009 // not apply to the firstprivate clause. 12010 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 12011 return true; 12012 12013 // A list item must be of integral or pointer type. 12014 Type = Type.getUnqualifiedType().getCanonicalType(); 12015 const auto *Ty = Type.getTypePtrOrNull(); 12016 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 12017 !Ty->isPointerType())) { 12018 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 12019 if (D) { 12020 bool IsDecl = 12021 !VD || 12022 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12023 Diag(D->getLocation(), 12024 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12025 << D; 12026 } 12027 return true; 12028 } 12029 return false; 12030 } 12031 12032 OMPClause *Sema::ActOnOpenMPLinearClause( 12033 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 12034 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 12035 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12036 SmallVector<Expr *, 8> Vars; 12037 SmallVector<Expr *, 8> Privates; 12038 SmallVector<Expr *, 8> Inits; 12039 SmallVector<Decl *, 4> ExprCaptures; 12040 SmallVector<Expr *, 4> ExprPostUpdates; 12041 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 12042 LinKind = OMPC_LINEAR_val; 12043 for (Expr *RefExpr : VarList) { 12044 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12045 SourceLocation ELoc; 12046 SourceRange ERange; 12047 Expr *SimpleRefExpr = RefExpr; 12048 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12049 if (Res.second) { 12050 // It will be analyzed later. 12051 Vars.push_back(RefExpr); 12052 Privates.push_back(nullptr); 12053 Inits.push_back(nullptr); 12054 } 12055 ValueDecl *D = Res.first; 12056 if (!D) 12057 continue; 12058 12059 QualType Type = D->getType(); 12060 auto *VD = dyn_cast<VarDecl>(D); 12061 12062 // OpenMP [2.14.3.7, linear clause] 12063 // A list-item cannot appear in more than one linear clause. 12064 // A list-item that appears in a linear clause cannot appear in any 12065 // other data-sharing attribute clause. 12066 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 12067 if (DVar.RefExpr) { 12068 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 12069 << getOpenMPClauseName(OMPC_linear); 12070 reportOriginalDsa(*this, DSAStack, D, DVar); 12071 continue; 12072 } 12073 12074 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 12075 continue; 12076 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12077 12078 // Build private copy of original var. 12079 VarDecl *Private = 12080 buildVarDecl(*this, ELoc, Type, D->getName(), 12081 D->hasAttrs() ? &D->getAttrs() : nullptr, 12082 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12083 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 12084 // Build var to save initial value. 12085 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 12086 Expr *InitExpr; 12087 DeclRefExpr *Ref = nullptr; 12088 if (!VD && !CurContext->isDependentContext()) { 12089 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12090 if (!isOpenMPCapturedDecl(D)) { 12091 ExprCaptures.push_back(Ref->getDecl()); 12092 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12093 ExprResult RefRes = DefaultLvalueConversion(Ref); 12094 if (!RefRes.isUsable()) 12095 continue; 12096 ExprResult PostUpdateRes = 12097 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 12098 SimpleRefExpr, RefRes.get()); 12099 if (!PostUpdateRes.isUsable()) 12100 continue; 12101 ExprPostUpdates.push_back( 12102 IgnoredValueConversions(PostUpdateRes.get()).get()); 12103 } 12104 } 12105 } 12106 if (LinKind == OMPC_LINEAR_uval) 12107 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 12108 else 12109 InitExpr = VD ? SimpleRefExpr : Ref; 12110 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 12111 /*DirectInit=*/false); 12112 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 12113 12114 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 12115 Vars.push_back((VD || CurContext->isDependentContext()) 12116 ? RefExpr->IgnoreParens() 12117 : Ref); 12118 Privates.push_back(PrivateRef); 12119 Inits.push_back(InitRef); 12120 } 12121 12122 if (Vars.empty()) 12123 return nullptr; 12124 12125 Expr *StepExpr = Step; 12126 Expr *CalcStepExpr = nullptr; 12127 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 12128 !Step->isInstantiationDependent() && 12129 !Step->containsUnexpandedParameterPack()) { 12130 SourceLocation StepLoc = Step->getBeginLoc(); 12131 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 12132 if (Val.isInvalid()) 12133 return nullptr; 12134 StepExpr = Val.get(); 12135 12136 // Build var to save the step value. 12137 VarDecl *SaveVar = 12138 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 12139 ExprResult SaveRef = 12140 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 12141 ExprResult CalcStep = 12142 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 12143 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 12144 12145 // Warn about zero linear step (it would be probably better specified as 12146 // making corresponding variables 'const'). 12147 llvm::APSInt Result; 12148 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 12149 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 12150 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 12151 << (Vars.size() > 1); 12152 if (!IsConstant && CalcStep.isUsable()) { 12153 // Calculate the step beforehand instead of doing this on each iteration. 12154 // (This is not used if the number of iterations may be kfold-ed). 12155 CalcStepExpr = CalcStep.get(); 12156 } 12157 } 12158 12159 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 12160 ColonLoc, EndLoc, Vars, Privates, Inits, 12161 StepExpr, CalcStepExpr, 12162 buildPreInits(Context, ExprCaptures), 12163 buildPostUpdate(*this, ExprPostUpdates)); 12164 } 12165 12166 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 12167 Expr *NumIterations, Sema &SemaRef, 12168 Scope *S, DSAStackTy *Stack) { 12169 // Walk the vars and build update/final expressions for the CodeGen. 12170 SmallVector<Expr *, 8> Updates; 12171 SmallVector<Expr *, 8> Finals; 12172 Expr *Step = Clause.getStep(); 12173 Expr *CalcStep = Clause.getCalcStep(); 12174 // OpenMP [2.14.3.7, linear clause] 12175 // If linear-step is not specified it is assumed to be 1. 12176 if (!Step) 12177 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 12178 else if (CalcStep) 12179 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 12180 bool HasErrors = false; 12181 auto CurInit = Clause.inits().begin(); 12182 auto CurPrivate = Clause.privates().begin(); 12183 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 12184 for (Expr *RefExpr : Clause.varlists()) { 12185 SourceLocation ELoc; 12186 SourceRange ERange; 12187 Expr *SimpleRefExpr = RefExpr; 12188 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 12189 ValueDecl *D = Res.first; 12190 if (Res.second || !D) { 12191 Updates.push_back(nullptr); 12192 Finals.push_back(nullptr); 12193 HasErrors = true; 12194 continue; 12195 } 12196 auto &&Info = Stack->isLoopControlVariable(D); 12197 // OpenMP [2.15.11, distribute simd Construct] 12198 // A list item may not appear in a linear clause, unless it is the loop 12199 // iteration variable. 12200 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 12201 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 12202 SemaRef.Diag(ELoc, 12203 diag::err_omp_linear_distribute_var_non_loop_iteration); 12204 Updates.push_back(nullptr); 12205 Finals.push_back(nullptr); 12206 HasErrors = true; 12207 continue; 12208 } 12209 Expr *InitExpr = *CurInit; 12210 12211 // Build privatized reference to the current linear var. 12212 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 12213 Expr *CapturedRef; 12214 if (LinKind == OMPC_LINEAR_uval) 12215 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 12216 else 12217 CapturedRef = 12218 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 12219 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 12220 /*RefersToCapture=*/true); 12221 12222 // Build update: Var = InitExpr + IV * Step 12223 ExprResult Update; 12224 if (!Info.first) 12225 Update = 12226 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 12227 InitExpr, IV, Step, /* Subtract */ false); 12228 else 12229 Update = *CurPrivate; 12230 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 12231 /*DiscardedValue*/ false); 12232 12233 // Build final: Var = InitExpr + NumIterations * Step 12234 ExprResult Final; 12235 if (!Info.first) 12236 Final = 12237 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 12238 InitExpr, NumIterations, Step, /*Subtract=*/false); 12239 else 12240 Final = *CurPrivate; 12241 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 12242 /*DiscardedValue*/ false); 12243 12244 if (!Update.isUsable() || !Final.isUsable()) { 12245 Updates.push_back(nullptr); 12246 Finals.push_back(nullptr); 12247 HasErrors = true; 12248 } else { 12249 Updates.push_back(Update.get()); 12250 Finals.push_back(Final.get()); 12251 } 12252 ++CurInit; 12253 ++CurPrivate; 12254 } 12255 Clause.setUpdates(Updates); 12256 Clause.setFinals(Finals); 12257 return HasErrors; 12258 } 12259 12260 OMPClause *Sema::ActOnOpenMPAlignedClause( 12261 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 12262 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12263 SmallVector<Expr *, 8> Vars; 12264 for (Expr *RefExpr : VarList) { 12265 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12266 SourceLocation ELoc; 12267 SourceRange ERange; 12268 Expr *SimpleRefExpr = RefExpr; 12269 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12270 if (Res.second) { 12271 // It will be analyzed later. 12272 Vars.push_back(RefExpr); 12273 } 12274 ValueDecl *D = Res.first; 12275 if (!D) 12276 continue; 12277 12278 QualType QType = D->getType(); 12279 auto *VD = dyn_cast<VarDecl>(D); 12280 12281 // OpenMP [2.8.1, simd construct, Restrictions] 12282 // The type of list items appearing in the aligned clause must be 12283 // array, pointer, reference to array, or reference to pointer. 12284 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12285 const Type *Ty = QType.getTypePtrOrNull(); 12286 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 12287 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 12288 << QType << getLangOpts().CPlusPlus << ERange; 12289 bool IsDecl = 12290 !VD || 12291 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12292 Diag(D->getLocation(), 12293 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12294 << D; 12295 continue; 12296 } 12297 12298 // OpenMP [2.8.1, simd construct, Restrictions] 12299 // A list-item cannot appear in more than one aligned clause. 12300 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 12301 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 12302 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 12303 << getOpenMPClauseName(OMPC_aligned); 12304 continue; 12305 } 12306 12307 DeclRefExpr *Ref = nullptr; 12308 if (!VD && isOpenMPCapturedDecl(D)) 12309 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12310 Vars.push_back(DefaultFunctionArrayConversion( 12311 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 12312 .get()); 12313 } 12314 12315 // OpenMP [2.8.1, simd construct, Description] 12316 // The parameter of the aligned clause, alignment, must be a constant 12317 // positive integer expression. 12318 // If no optional parameter is specified, implementation-defined default 12319 // alignments for SIMD instructions on the target platforms are assumed. 12320 if (Alignment != nullptr) { 12321 ExprResult AlignResult = 12322 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 12323 if (AlignResult.isInvalid()) 12324 return nullptr; 12325 Alignment = AlignResult.get(); 12326 } 12327 if (Vars.empty()) 12328 return nullptr; 12329 12330 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 12331 EndLoc, Vars, Alignment); 12332 } 12333 12334 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 12335 SourceLocation StartLoc, 12336 SourceLocation LParenLoc, 12337 SourceLocation EndLoc) { 12338 SmallVector<Expr *, 8> Vars; 12339 SmallVector<Expr *, 8> SrcExprs; 12340 SmallVector<Expr *, 8> DstExprs; 12341 SmallVector<Expr *, 8> AssignmentOps; 12342 for (Expr *RefExpr : VarList) { 12343 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 12344 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12345 // It will be analyzed later. 12346 Vars.push_back(RefExpr); 12347 SrcExprs.push_back(nullptr); 12348 DstExprs.push_back(nullptr); 12349 AssignmentOps.push_back(nullptr); 12350 continue; 12351 } 12352 12353 SourceLocation ELoc = RefExpr->getExprLoc(); 12354 // OpenMP [2.1, C/C++] 12355 // A list item is a variable name. 12356 // OpenMP [2.14.4.1, Restrictions, p.1] 12357 // A list item that appears in a copyin clause must be threadprivate. 12358 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 12359 if (!DE || !isa<VarDecl>(DE->getDecl())) { 12360 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 12361 << 0 << RefExpr->getSourceRange(); 12362 continue; 12363 } 12364 12365 Decl *D = DE->getDecl(); 12366 auto *VD = cast<VarDecl>(D); 12367 12368 QualType Type = VD->getType(); 12369 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 12370 // It will be analyzed later. 12371 Vars.push_back(DE); 12372 SrcExprs.push_back(nullptr); 12373 DstExprs.push_back(nullptr); 12374 AssignmentOps.push_back(nullptr); 12375 continue; 12376 } 12377 12378 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 12379 // A list item that appears in a copyin clause must be threadprivate. 12380 if (!DSAStack->isThreadPrivate(VD)) { 12381 Diag(ELoc, diag::err_omp_required_access) 12382 << getOpenMPClauseName(OMPC_copyin) 12383 << getOpenMPDirectiveName(OMPD_threadprivate); 12384 continue; 12385 } 12386 12387 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12388 // A variable of class type (or array thereof) that appears in a 12389 // copyin clause requires an accessible, unambiguous copy assignment 12390 // operator for the class type. 12391 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12392 VarDecl *SrcVD = 12393 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 12394 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12395 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 12396 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 12397 VarDecl *DstVD = 12398 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 12399 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12400 DeclRefExpr *PseudoDstExpr = 12401 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 12402 // For arrays generate assignment operation for single element and replace 12403 // it by the original array element in CodeGen. 12404 ExprResult AssignmentOp = 12405 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 12406 PseudoSrcExpr); 12407 if (AssignmentOp.isInvalid()) 12408 continue; 12409 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 12410 /*DiscardedValue*/ false); 12411 if (AssignmentOp.isInvalid()) 12412 continue; 12413 12414 DSAStack->addDSA(VD, DE, OMPC_copyin); 12415 Vars.push_back(DE); 12416 SrcExprs.push_back(PseudoSrcExpr); 12417 DstExprs.push_back(PseudoDstExpr); 12418 AssignmentOps.push_back(AssignmentOp.get()); 12419 } 12420 12421 if (Vars.empty()) 12422 return nullptr; 12423 12424 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12425 SrcExprs, DstExprs, AssignmentOps); 12426 } 12427 12428 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 12429 SourceLocation StartLoc, 12430 SourceLocation LParenLoc, 12431 SourceLocation EndLoc) { 12432 SmallVector<Expr *, 8> Vars; 12433 SmallVector<Expr *, 8> SrcExprs; 12434 SmallVector<Expr *, 8> DstExprs; 12435 SmallVector<Expr *, 8> AssignmentOps; 12436 for (Expr *RefExpr : VarList) { 12437 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12438 SourceLocation ELoc; 12439 SourceRange ERange; 12440 Expr *SimpleRefExpr = RefExpr; 12441 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12442 if (Res.second) { 12443 // It will be analyzed later. 12444 Vars.push_back(RefExpr); 12445 SrcExprs.push_back(nullptr); 12446 DstExprs.push_back(nullptr); 12447 AssignmentOps.push_back(nullptr); 12448 } 12449 ValueDecl *D = Res.first; 12450 if (!D) 12451 continue; 12452 12453 QualType Type = D->getType(); 12454 auto *VD = dyn_cast<VarDecl>(D); 12455 12456 // OpenMP [2.14.4.2, Restrictions, p.2] 12457 // A list item that appears in a copyprivate clause may not appear in a 12458 // private or firstprivate clause on the single construct. 12459 if (!VD || !DSAStack->isThreadPrivate(VD)) { 12460 DSAStackTy::DSAVarData DVar = 12461 DSAStack->getTopDSA(D, /*FromParent=*/false); 12462 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 12463 DVar.RefExpr) { 12464 Diag(ELoc, diag::err_omp_wrong_dsa) 12465 << getOpenMPClauseName(DVar.CKind) 12466 << getOpenMPClauseName(OMPC_copyprivate); 12467 reportOriginalDsa(*this, DSAStack, D, DVar); 12468 continue; 12469 } 12470 12471 // OpenMP [2.11.4.2, Restrictions, p.1] 12472 // All list items that appear in a copyprivate clause must be either 12473 // threadprivate or private in the enclosing context. 12474 if (DVar.CKind == OMPC_unknown) { 12475 DVar = DSAStack->getImplicitDSA(D, false); 12476 if (DVar.CKind == OMPC_shared) { 12477 Diag(ELoc, diag::err_omp_required_access) 12478 << getOpenMPClauseName(OMPC_copyprivate) 12479 << "threadprivate or private in the enclosing context"; 12480 reportOriginalDsa(*this, DSAStack, D, DVar); 12481 continue; 12482 } 12483 } 12484 } 12485 12486 // Variably modified types are not supported. 12487 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 12488 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12489 << getOpenMPClauseName(OMPC_copyprivate) << Type 12490 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12491 bool IsDecl = 12492 !VD || 12493 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12494 Diag(D->getLocation(), 12495 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12496 << D; 12497 continue; 12498 } 12499 12500 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12501 // A variable of class type (or array thereof) that appears in a 12502 // copyin clause requires an accessible, unambiguous copy assignment 12503 // operator for the class type. 12504 Type = Context.getBaseElementType(Type.getNonReferenceType()) 12505 .getUnqualifiedType(); 12506 VarDecl *SrcVD = 12507 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 12508 D->hasAttrs() ? &D->getAttrs() : nullptr); 12509 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 12510 VarDecl *DstVD = 12511 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 12512 D->hasAttrs() ? &D->getAttrs() : nullptr); 12513 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12514 ExprResult AssignmentOp = BuildBinOp( 12515 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 12516 if (AssignmentOp.isInvalid()) 12517 continue; 12518 AssignmentOp = 12519 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12520 if (AssignmentOp.isInvalid()) 12521 continue; 12522 12523 // No need to mark vars as copyprivate, they are already threadprivate or 12524 // implicitly private. 12525 assert(VD || isOpenMPCapturedDecl(D)); 12526 Vars.push_back( 12527 VD ? RefExpr->IgnoreParens() 12528 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 12529 SrcExprs.push_back(PseudoSrcExpr); 12530 DstExprs.push_back(PseudoDstExpr); 12531 AssignmentOps.push_back(AssignmentOp.get()); 12532 } 12533 12534 if (Vars.empty()) 12535 return nullptr; 12536 12537 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12538 Vars, SrcExprs, DstExprs, AssignmentOps); 12539 } 12540 12541 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 12542 SourceLocation StartLoc, 12543 SourceLocation LParenLoc, 12544 SourceLocation EndLoc) { 12545 if (VarList.empty()) 12546 return nullptr; 12547 12548 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 12549 } 12550 12551 OMPClause * 12552 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 12553 SourceLocation DepLoc, SourceLocation ColonLoc, 12554 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 12555 SourceLocation LParenLoc, SourceLocation EndLoc) { 12556 if (DSAStack->getCurrentDirective() == OMPD_ordered && 12557 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 12558 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 12559 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 12560 return nullptr; 12561 } 12562 if (DSAStack->getCurrentDirective() != OMPD_ordered && 12563 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 12564 DepKind == OMPC_DEPEND_sink)) { 12565 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 12566 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 12567 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12568 /*Last=*/OMPC_DEPEND_unknown, Except) 12569 << getOpenMPClauseName(OMPC_depend); 12570 return nullptr; 12571 } 12572 SmallVector<Expr *, 8> Vars; 12573 DSAStackTy::OperatorOffsetTy OpsOffs; 12574 llvm::APSInt DepCounter(/*BitWidth=*/32); 12575 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 12576 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 12577 if (const Expr *OrderedCountExpr = 12578 DSAStack->getParentOrderedRegionParam().first) { 12579 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 12580 TotalDepCount.setIsUnsigned(/*Val=*/true); 12581 } 12582 } 12583 for (Expr *RefExpr : VarList) { 12584 assert(RefExpr && "NULL expr in OpenMP shared clause."); 12585 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12586 // It will be analyzed later. 12587 Vars.push_back(RefExpr); 12588 continue; 12589 } 12590 12591 SourceLocation ELoc = RefExpr->getExprLoc(); 12592 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 12593 if (DepKind == OMPC_DEPEND_sink) { 12594 if (DSAStack->getParentOrderedRegionParam().first && 12595 DepCounter >= TotalDepCount) { 12596 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 12597 continue; 12598 } 12599 ++DepCounter; 12600 // OpenMP [2.13.9, Summary] 12601 // depend(dependence-type : vec), where dependence-type is: 12602 // 'sink' and where vec is the iteration vector, which has the form: 12603 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 12604 // where n is the value specified by the ordered clause in the loop 12605 // directive, xi denotes the loop iteration variable of the i-th nested 12606 // loop associated with the loop directive, and di is a constant 12607 // non-negative integer. 12608 if (CurContext->isDependentContext()) { 12609 // It will be analyzed later. 12610 Vars.push_back(RefExpr); 12611 continue; 12612 } 12613 SimpleExpr = SimpleExpr->IgnoreImplicit(); 12614 OverloadedOperatorKind OOK = OO_None; 12615 SourceLocation OOLoc; 12616 Expr *LHS = SimpleExpr; 12617 Expr *RHS = nullptr; 12618 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 12619 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 12620 OOLoc = BO->getOperatorLoc(); 12621 LHS = BO->getLHS()->IgnoreParenImpCasts(); 12622 RHS = BO->getRHS()->IgnoreParenImpCasts(); 12623 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 12624 OOK = OCE->getOperator(); 12625 OOLoc = OCE->getOperatorLoc(); 12626 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 12627 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 12628 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 12629 OOK = MCE->getMethodDecl() 12630 ->getNameInfo() 12631 .getName() 12632 .getCXXOverloadedOperator(); 12633 OOLoc = MCE->getCallee()->getExprLoc(); 12634 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 12635 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 12636 } 12637 SourceLocation ELoc; 12638 SourceRange ERange; 12639 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 12640 if (Res.second) { 12641 // It will be analyzed later. 12642 Vars.push_back(RefExpr); 12643 } 12644 ValueDecl *D = Res.first; 12645 if (!D) 12646 continue; 12647 12648 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 12649 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 12650 continue; 12651 } 12652 if (RHS) { 12653 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 12654 RHS, OMPC_depend, /*StrictlyPositive=*/false); 12655 if (RHSRes.isInvalid()) 12656 continue; 12657 } 12658 if (!CurContext->isDependentContext() && 12659 DSAStack->getParentOrderedRegionParam().first && 12660 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 12661 const ValueDecl *VD = 12662 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 12663 if (VD) 12664 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 12665 << 1 << VD; 12666 else 12667 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 12668 continue; 12669 } 12670 OpsOffs.emplace_back(RHS, OOK); 12671 } else { 12672 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 12673 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 12674 (ASE && 12675 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 12676 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 12677 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 12678 << RefExpr->getSourceRange(); 12679 continue; 12680 } 12681 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 12682 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 12683 ExprResult Res = 12684 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); 12685 getDiagnostics().setSuppressAllDiagnostics(Suppress); 12686 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 12687 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 12688 << RefExpr->getSourceRange(); 12689 continue; 12690 } 12691 } 12692 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 12693 } 12694 12695 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 12696 TotalDepCount > VarList.size() && 12697 DSAStack->getParentOrderedRegionParam().first && 12698 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 12699 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 12700 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 12701 } 12702 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 12703 Vars.empty()) 12704 return nullptr; 12705 12706 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12707 DepKind, DepLoc, ColonLoc, Vars, 12708 TotalDepCount.getZExtValue()); 12709 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 12710 DSAStack->isParentOrderedRegion()) 12711 DSAStack->addDoacrossDependClause(C, OpsOffs); 12712 return C; 12713 } 12714 12715 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 12716 SourceLocation LParenLoc, 12717 SourceLocation EndLoc) { 12718 Expr *ValExpr = Device; 12719 Stmt *HelperValStmt = nullptr; 12720 12721 // OpenMP [2.9.1, Restrictions] 12722 // The device expression must evaluate to a non-negative integer value. 12723 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 12724 /*StrictlyPositive=*/false)) 12725 return nullptr; 12726 12727 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12728 OpenMPDirectiveKind CaptureRegion = 12729 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 12730 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12731 ValExpr = MakeFullExpr(ValExpr).get(); 12732 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12733 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12734 HelperValStmt = buildPreInits(Context, Captures); 12735 } 12736 12737 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 12738 StartLoc, LParenLoc, EndLoc); 12739 } 12740 12741 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 12742 DSAStackTy *Stack, QualType QTy, 12743 bool FullCheck = true) { 12744 NamedDecl *ND; 12745 if (QTy->isIncompleteType(&ND)) { 12746 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 12747 return false; 12748 } 12749 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 12750 !QTy.isTrivialType(SemaRef.Context)) 12751 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 12752 return true; 12753 } 12754 12755 /// Return true if it can be proven that the provided array expression 12756 /// (array section or array subscript) does NOT specify the whole size of the 12757 /// array whose base type is \a BaseQTy. 12758 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 12759 const Expr *E, 12760 QualType BaseQTy) { 12761 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 12762 12763 // If this is an array subscript, it refers to the whole size if the size of 12764 // the dimension is constant and equals 1. Also, an array section assumes the 12765 // format of an array subscript if no colon is used. 12766 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 12767 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 12768 return ATy->getSize().getSExtValue() != 1; 12769 // Size can't be evaluated statically. 12770 return false; 12771 } 12772 12773 assert(OASE && "Expecting array section if not an array subscript."); 12774 const Expr *LowerBound = OASE->getLowerBound(); 12775 const Expr *Length = OASE->getLength(); 12776 12777 // If there is a lower bound that does not evaluates to zero, we are not 12778 // covering the whole dimension. 12779 if (LowerBound) { 12780 Expr::EvalResult Result; 12781 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 12782 return false; // Can't get the integer value as a constant. 12783 12784 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 12785 if (ConstLowerBound.getSExtValue()) 12786 return true; 12787 } 12788 12789 // If we don't have a length we covering the whole dimension. 12790 if (!Length) 12791 return false; 12792 12793 // If the base is a pointer, we don't have a way to get the size of the 12794 // pointee. 12795 if (BaseQTy->isPointerType()) 12796 return false; 12797 12798 // We can only check if the length is the same as the size of the dimension 12799 // if we have a constant array. 12800 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 12801 if (!CATy) 12802 return false; 12803 12804 Expr::EvalResult Result; 12805 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 12806 return false; // Can't get the integer value as a constant. 12807 12808 llvm::APSInt ConstLength = Result.Val.getInt(); 12809 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 12810 } 12811 12812 // Return true if it can be proven that the provided array expression (array 12813 // section or array subscript) does NOT specify a single element of the array 12814 // whose base type is \a BaseQTy. 12815 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 12816 const Expr *E, 12817 QualType BaseQTy) { 12818 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 12819 12820 // An array subscript always refer to a single element. Also, an array section 12821 // assumes the format of an array subscript if no colon is used. 12822 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 12823 return false; 12824 12825 assert(OASE && "Expecting array section if not an array subscript."); 12826 const Expr *Length = OASE->getLength(); 12827 12828 // If we don't have a length we have to check if the array has unitary size 12829 // for this dimension. Also, we should always expect a length if the base type 12830 // is pointer. 12831 if (!Length) { 12832 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 12833 return ATy->getSize().getSExtValue() != 1; 12834 // We cannot assume anything. 12835 return false; 12836 } 12837 12838 // Check if the length evaluates to 1. 12839 Expr::EvalResult Result; 12840 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 12841 return false; // Can't get the integer value as a constant. 12842 12843 llvm::APSInt ConstLength = Result.Val.getInt(); 12844 return ConstLength.getSExtValue() != 1; 12845 } 12846 12847 // Return the expression of the base of the mappable expression or null if it 12848 // cannot be determined and do all the necessary checks to see if the expression 12849 // is valid as a standalone mappable expression. In the process, record all the 12850 // components of the expression. 12851 static const Expr *checkMapClauseExpressionBase( 12852 Sema &SemaRef, Expr *E, 12853 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 12854 OpenMPClauseKind CKind, bool NoDiagnose) { 12855 SourceLocation ELoc = E->getExprLoc(); 12856 SourceRange ERange = E->getSourceRange(); 12857 12858 // The base of elements of list in a map clause have to be either: 12859 // - a reference to variable or field. 12860 // - a member expression. 12861 // - an array expression. 12862 // 12863 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 12864 // reference to 'r'. 12865 // 12866 // If we have: 12867 // 12868 // struct SS { 12869 // Bla S; 12870 // foo() { 12871 // #pragma omp target map (S.Arr[:12]); 12872 // } 12873 // } 12874 // 12875 // We want to retrieve the member expression 'this->S'; 12876 12877 const Expr *RelevantExpr = nullptr; 12878 12879 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 12880 // If a list item is an array section, it must specify contiguous storage. 12881 // 12882 // For this restriction it is sufficient that we make sure only references 12883 // to variables or fields and array expressions, and that no array sections 12884 // exist except in the rightmost expression (unless they cover the whole 12885 // dimension of the array). E.g. these would be invalid: 12886 // 12887 // r.ArrS[3:5].Arr[6:7] 12888 // 12889 // r.ArrS[3:5].x 12890 // 12891 // but these would be valid: 12892 // r.ArrS[3].Arr[6:7] 12893 // 12894 // r.ArrS[3].x 12895 12896 bool AllowUnitySizeArraySection = true; 12897 bool AllowWholeSizeArraySection = true; 12898 12899 while (!RelevantExpr) { 12900 E = E->IgnoreParenImpCasts(); 12901 12902 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 12903 if (!isa<VarDecl>(CurE->getDecl())) 12904 return nullptr; 12905 12906 RelevantExpr = CurE; 12907 12908 // If we got a reference to a declaration, we should not expect any array 12909 // section before that. 12910 AllowUnitySizeArraySection = false; 12911 AllowWholeSizeArraySection = false; 12912 12913 // Record the component. 12914 CurComponents.emplace_back(CurE, CurE->getDecl()); 12915 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 12916 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 12917 12918 if (isa<CXXThisExpr>(BaseE)) 12919 // We found a base expression: this->Val. 12920 RelevantExpr = CurE; 12921 else 12922 E = BaseE; 12923 12924 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 12925 if (!NoDiagnose) { 12926 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 12927 << CurE->getSourceRange(); 12928 return nullptr; 12929 } 12930 if (RelevantExpr) 12931 return nullptr; 12932 continue; 12933 } 12934 12935 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 12936 12937 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 12938 // A bit-field cannot appear in a map clause. 12939 // 12940 if (FD->isBitField()) { 12941 if (!NoDiagnose) { 12942 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 12943 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 12944 return nullptr; 12945 } 12946 if (RelevantExpr) 12947 return nullptr; 12948 continue; 12949 } 12950 12951 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12952 // If the type of a list item is a reference to a type T then the type 12953 // will be considered to be T for all purposes of this clause. 12954 QualType CurType = BaseE->getType().getNonReferenceType(); 12955 12956 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 12957 // A list item cannot be a variable that is a member of a structure with 12958 // a union type. 12959 // 12960 if (CurType->isUnionType()) { 12961 if (!NoDiagnose) { 12962 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 12963 << CurE->getSourceRange(); 12964 return nullptr; 12965 } 12966 continue; 12967 } 12968 12969 // If we got a member expression, we should not expect any array section 12970 // before that: 12971 // 12972 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 12973 // If a list item is an element of a structure, only the rightmost symbol 12974 // of the variable reference can be an array section. 12975 // 12976 AllowUnitySizeArraySection = false; 12977 AllowWholeSizeArraySection = false; 12978 12979 // Record the component. 12980 CurComponents.emplace_back(CurE, FD); 12981 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 12982 E = CurE->getBase()->IgnoreParenImpCasts(); 12983 12984 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 12985 if (!NoDiagnose) { 12986 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 12987 << 0 << CurE->getSourceRange(); 12988 return nullptr; 12989 } 12990 continue; 12991 } 12992 12993 // If we got an array subscript that express the whole dimension we 12994 // can have any array expressions before. If it only expressing part of 12995 // the dimension, we can only have unitary-size array expressions. 12996 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 12997 E->getType())) 12998 AllowWholeSizeArraySection = false; 12999 13000 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13001 Expr::EvalResult Result; 13002 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 13003 if (!Result.Val.getInt().isNullValue()) { 13004 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13005 diag::err_omp_invalid_map_this_expr); 13006 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 13007 diag::note_omp_invalid_subscript_on_this_ptr_map); 13008 } 13009 } 13010 RelevantExpr = TE; 13011 } 13012 13013 // Record the component - we don't have any declaration associated. 13014 CurComponents.emplace_back(CurE, nullptr); 13015 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 13016 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 13017 E = CurE->getBase()->IgnoreParenImpCasts(); 13018 13019 QualType CurType = 13020 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13021 13022 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13023 // If the type of a list item is a reference to a type T then the type 13024 // will be considered to be T for all purposes of this clause. 13025 if (CurType->isReferenceType()) 13026 CurType = CurType->getPointeeType(); 13027 13028 bool IsPointer = CurType->isAnyPointerType(); 13029 13030 if (!IsPointer && !CurType->isArrayType()) { 13031 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 13032 << 0 << CurE->getSourceRange(); 13033 return nullptr; 13034 } 13035 13036 bool NotWhole = 13037 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 13038 bool NotUnity = 13039 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 13040 13041 if (AllowWholeSizeArraySection) { 13042 // Any array section is currently allowed. Allowing a whole size array 13043 // section implies allowing a unity array section as well. 13044 // 13045 // If this array section refers to the whole dimension we can still 13046 // accept other array sections before this one, except if the base is a 13047 // pointer. Otherwise, only unitary sections are accepted. 13048 if (NotWhole || IsPointer) 13049 AllowWholeSizeArraySection = false; 13050 } else if (AllowUnitySizeArraySection && NotUnity) { 13051 // A unity or whole array section is not allowed and that is not 13052 // compatible with the properties of the current array section. 13053 SemaRef.Diag( 13054 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 13055 << CurE->getSourceRange(); 13056 return nullptr; 13057 } 13058 13059 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 13060 Expr::EvalResult ResultR; 13061 Expr::EvalResult ResultL; 13062 if (CurE->getLength()->EvaluateAsInt(ResultR, 13063 SemaRef.getASTContext())) { 13064 if (!ResultR.Val.getInt().isOneValue()) { 13065 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13066 diag::err_omp_invalid_map_this_expr); 13067 SemaRef.Diag(CurE->getLength()->getExprLoc(), 13068 diag::note_omp_invalid_length_on_this_ptr_mapping); 13069 } 13070 } 13071 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 13072 ResultL, SemaRef.getASTContext())) { 13073 if (!ResultL.Val.getInt().isNullValue()) { 13074 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13075 diag::err_omp_invalid_map_this_expr); 13076 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13077 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 13078 } 13079 } 13080 RelevantExpr = TE; 13081 } 13082 13083 // Record the component - we don't have any declaration associated. 13084 CurComponents.emplace_back(CurE, nullptr); 13085 } else { 13086 if (!NoDiagnose) { 13087 // If nothing else worked, this is not a valid map clause expression. 13088 SemaRef.Diag( 13089 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 13090 << ERange; 13091 } 13092 return nullptr; 13093 } 13094 } 13095 13096 return RelevantExpr; 13097 } 13098 13099 // Return true if expression E associated with value VD has conflicts with other 13100 // map information. 13101 static bool checkMapConflicts( 13102 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 13103 bool CurrentRegionOnly, 13104 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 13105 OpenMPClauseKind CKind) { 13106 assert(VD && E); 13107 SourceLocation ELoc = E->getExprLoc(); 13108 SourceRange ERange = E->getSourceRange(); 13109 13110 // In order to easily check the conflicts we need to match each component of 13111 // the expression under test with the components of the expressions that are 13112 // already in the stack. 13113 13114 assert(!CurComponents.empty() && "Map clause expression with no components!"); 13115 assert(CurComponents.back().getAssociatedDeclaration() == VD && 13116 "Map clause expression with unexpected base!"); 13117 13118 // Variables to help detecting enclosing problems in data environment nests. 13119 bool IsEnclosedByDataEnvironmentExpr = false; 13120 const Expr *EnclosingExpr = nullptr; 13121 13122 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 13123 VD, CurrentRegionOnly, 13124 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 13125 ERange, CKind, &EnclosingExpr, 13126 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 13127 StackComponents, 13128 OpenMPClauseKind) { 13129 assert(!StackComponents.empty() && 13130 "Map clause expression with no components!"); 13131 assert(StackComponents.back().getAssociatedDeclaration() == VD && 13132 "Map clause expression with unexpected base!"); 13133 (void)VD; 13134 13135 // The whole expression in the stack. 13136 const Expr *RE = StackComponents.front().getAssociatedExpression(); 13137 13138 // Expressions must start from the same base. Here we detect at which 13139 // point both expressions diverge from each other and see if we can 13140 // detect if the memory referred to both expressions is contiguous and 13141 // do not overlap. 13142 auto CI = CurComponents.rbegin(); 13143 auto CE = CurComponents.rend(); 13144 auto SI = StackComponents.rbegin(); 13145 auto SE = StackComponents.rend(); 13146 for (; CI != CE && SI != SE; ++CI, ++SI) { 13147 13148 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 13149 // At most one list item can be an array item derived from a given 13150 // variable in map clauses of the same construct. 13151 if (CurrentRegionOnly && 13152 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 13153 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 13154 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 13155 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 13156 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 13157 diag::err_omp_multiple_array_items_in_map_clause) 13158 << CI->getAssociatedExpression()->getSourceRange(); 13159 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 13160 diag::note_used_here) 13161 << SI->getAssociatedExpression()->getSourceRange(); 13162 return true; 13163 } 13164 13165 // Do both expressions have the same kind? 13166 if (CI->getAssociatedExpression()->getStmtClass() != 13167 SI->getAssociatedExpression()->getStmtClass()) 13168 break; 13169 13170 // Are we dealing with different variables/fields? 13171 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 13172 break; 13173 } 13174 // Check if the extra components of the expressions in the enclosing 13175 // data environment are redundant for the current base declaration. 13176 // If they are, the maps completely overlap, which is legal. 13177 for (; SI != SE; ++SI) { 13178 QualType Type; 13179 if (const auto *ASE = 13180 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 13181 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 13182 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 13183 SI->getAssociatedExpression())) { 13184 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 13185 Type = 13186 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13187 } 13188 if (Type.isNull() || Type->isAnyPointerType() || 13189 checkArrayExpressionDoesNotReferToWholeSize( 13190 SemaRef, SI->getAssociatedExpression(), Type)) 13191 break; 13192 } 13193 13194 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13195 // List items of map clauses in the same construct must not share 13196 // original storage. 13197 // 13198 // If the expressions are exactly the same or one is a subset of the 13199 // other, it means they are sharing storage. 13200 if (CI == CE && SI == SE) { 13201 if (CurrentRegionOnly) { 13202 if (CKind == OMPC_map) { 13203 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13204 } else { 13205 assert(CKind == OMPC_to || CKind == OMPC_from); 13206 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13207 << ERange; 13208 } 13209 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13210 << RE->getSourceRange(); 13211 return true; 13212 } 13213 // If we find the same expression in the enclosing data environment, 13214 // that is legal. 13215 IsEnclosedByDataEnvironmentExpr = true; 13216 return false; 13217 } 13218 13219 QualType DerivedType = 13220 std::prev(CI)->getAssociatedDeclaration()->getType(); 13221 SourceLocation DerivedLoc = 13222 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 13223 13224 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13225 // If the type of a list item is a reference to a type T then the type 13226 // will be considered to be T for all purposes of this clause. 13227 DerivedType = DerivedType.getNonReferenceType(); 13228 13229 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 13230 // A variable for which the type is pointer and an array section 13231 // derived from that variable must not appear as list items of map 13232 // clauses of the same construct. 13233 // 13234 // Also, cover one of the cases in: 13235 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13236 // If any part of the original storage of a list item has corresponding 13237 // storage in the device data environment, all of the original storage 13238 // must have corresponding storage in the device data environment. 13239 // 13240 if (DerivedType->isAnyPointerType()) { 13241 if (CI == CE || SI == SE) { 13242 SemaRef.Diag( 13243 DerivedLoc, 13244 diag::err_omp_pointer_mapped_along_with_derived_section) 13245 << DerivedLoc; 13246 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13247 << RE->getSourceRange(); 13248 return true; 13249 } 13250 if (CI->getAssociatedExpression()->getStmtClass() != 13251 SI->getAssociatedExpression()->getStmtClass() || 13252 CI->getAssociatedDeclaration()->getCanonicalDecl() == 13253 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 13254 assert(CI != CE && SI != SE); 13255 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 13256 << DerivedLoc; 13257 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13258 << RE->getSourceRange(); 13259 return true; 13260 } 13261 } 13262 13263 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13264 // List items of map clauses in the same construct must not share 13265 // original storage. 13266 // 13267 // An expression is a subset of the other. 13268 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 13269 if (CKind == OMPC_map) { 13270 if (CI != CE || SI != SE) { 13271 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 13272 // a pointer. 13273 auto Begin = 13274 CI != CE ? CurComponents.begin() : StackComponents.begin(); 13275 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 13276 auto It = Begin; 13277 while (It != End && !It->getAssociatedDeclaration()) 13278 std::advance(It, 1); 13279 assert(It != End && 13280 "Expected at least one component with the declaration."); 13281 if (It != Begin && It->getAssociatedDeclaration() 13282 ->getType() 13283 .getCanonicalType() 13284 ->isAnyPointerType()) { 13285 IsEnclosedByDataEnvironmentExpr = false; 13286 EnclosingExpr = nullptr; 13287 return false; 13288 } 13289 } 13290 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13291 } else { 13292 assert(CKind == OMPC_to || CKind == OMPC_from); 13293 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13294 << ERange; 13295 } 13296 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13297 << RE->getSourceRange(); 13298 return true; 13299 } 13300 13301 // The current expression uses the same base as other expression in the 13302 // data environment but does not contain it completely. 13303 if (!CurrentRegionOnly && SI != SE) 13304 EnclosingExpr = RE; 13305 13306 // The current expression is a subset of the expression in the data 13307 // environment. 13308 IsEnclosedByDataEnvironmentExpr |= 13309 (!CurrentRegionOnly && CI != CE && SI == SE); 13310 13311 return false; 13312 }); 13313 13314 if (CurrentRegionOnly) 13315 return FoundError; 13316 13317 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13318 // If any part of the original storage of a list item has corresponding 13319 // storage in the device data environment, all of the original storage must 13320 // have corresponding storage in the device data environment. 13321 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 13322 // If a list item is an element of a structure, and a different element of 13323 // the structure has a corresponding list item in the device data environment 13324 // prior to a task encountering the construct associated with the map clause, 13325 // then the list item must also have a corresponding list item in the device 13326 // data environment prior to the task encountering the construct. 13327 // 13328 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 13329 SemaRef.Diag(ELoc, 13330 diag::err_omp_original_storage_is_shared_and_does_not_contain) 13331 << ERange; 13332 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 13333 << EnclosingExpr->getSourceRange(); 13334 return true; 13335 } 13336 13337 return FoundError; 13338 } 13339 13340 // Look up the user-defined mapper given the mapper name and mapped type, and 13341 // build a reference to it. 13342 ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 13343 CXXScopeSpec &MapperIdScopeSpec, 13344 const DeclarationNameInfo &MapperId, 13345 QualType Type, Expr *UnresolvedMapper) { 13346 if (MapperIdScopeSpec.isInvalid()) 13347 return ExprError(); 13348 // Find all user-defined mappers with the given MapperId. 13349 SmallVector<UnresolvedSet<8>, 4> Lookups; 13350 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 13351 Lookup.suppressDiagnostics(); 13352 if (S) { 13353 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 13354 NamedDecl *D = Lookup.getRepresentativeDecl(); 13355 while (S && !S->isDeclScope(D)) 13356 S = S->getParent(); 13357 if (S) 13358 S = S->getParent(); 13359 Lookups.emplace_back(); 13360 Lookups.back().append(Lookup.begin(), Lookup.end()); 13361 Lookup.clear(); 13362 } 13363 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 13364 // Extract the user-defined mappers with the given MapperId. 13365 Lookups.push_back(UnresolvedSet<8>()); 13366 for (NamedDecl *D : ULE->decls()) { 13367 auto *DMD = cast<OMPDeclareMapperDecl>(D); 13368 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 13369 Lookups.back().addDecl(DMD); 13370 } 13371 } 13372 // Defer the lookup for dependent types. The results will be passed through 13373 // UnresolvedMapper on instantiation. 13374 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 13375 Type->isInstantiationDependentType() || 13376 Type->containsUnexpandedParameterPack() || 13377 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13378 return !D->isInvalidDecl() && 13379 (D->getType()->isDependentType() || 13380 D->getType()->isInstantiationDependentType() || 13381 D->getType()->containsUnexpandedParameterPack()); 13382 })) { 13383 UnresolvedSet<8> URS; 13384 for (const UnresolvedSet<8> &Set : Lookups) { 13385 if (Set.empty()) 13386 continue; 13387 URS.append(Set.begin(), Set.end()); 13388 } 13389 return UnresolvedLookupExpr::Create( 13390 SemaRef.Context, /*NamingClass=*/nullptr, 13391 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 13392 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 13393 } 13394 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 13395 // The type must be of struct, union or class type in C and C++ 13396 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 13397 return ExprEmpty(); 13398 SourceLocation Loc = MapperId.getLoc(); 13399 // Perform argument dependent lookup. 13400 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 13401 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 13402 // Return the first user-defined mapper with the desired type. 13403 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13404 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 13405 if (!D->isInvalidDecl() && 13406 SemaRef.Context.hasSameType(D->getType(), Type)) 13407 return D; 13408 return nullptr; 13409 })) 13410 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13411 // Find the first user-defined mapper with a type derived from the desired 13412 // type. 13413 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13414 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 13415 if (!D->isInvalidDecl() && 13416 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 13417 !Type.isMoreQualifiedThan(D->getType())) 13418 return D; 13419 return nullptr; 13420 })) { 13421 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13422 /*DetectVirtual=*/false); 13423 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 13424 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13425 VD->getType().getUnqualifiedType()))) { 13426 if (SemaRef.CheckBaseClassAccess( 13427 Loc, VD->getType(), Type, Paths.front(), 13428 /*DiagID=*/0) != Sema::AR_inaccessible) { 13429 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13430 } 13431 } 13432 } 13433 } 13434 // Report error if a mapper is specified, but cannot be found. 13435 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 13436 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 13437 << Type << MapperId.getName(); 13438 return ExprError(); 13439 } 13440 return ExprEmpty(); 13441 } 13442 13443 namespace { 13444 // Utility struct that gathers all the related lists associated with a mappable 13445 // expression. 13446 struct MappableVarListInfo { 13447 // The list of expressions. 13448 ArrayRef<Expr *> VarList; 13449 // The list of processed expressions. 13450 SmallVector<Expr *, 16> ProcessedVarList; 13451 // The mappble components for each expression. 13452 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 13453 // The base declaration of the variable. 13454 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 13455 // The reference to the user-defined mapper associated with every expression. 13456 SmallVector<Expr *, 16> UDMapperList; 13457 13458 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 13459 // We have a list of components and base declarations for each entry in the 13460 // variable list. 13461 VarComponents.reserve(VarList.size()); 13462 VarBaseDeclarations.reserve(VarList.size()); 13463 } 13464 }; 13465 } 13466 13467 // Check the validity of the provided variable list for the provided clause kind 13468 // \a CKind. In the check process the valid expressions, mappable expression 13469 // components, variables, and user-defined mappers are extracted and used to 13470 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 13471 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 13472 // and \a MapperId are expected to be valid if the clause kind is 'map'. 13473 static void checkMappableExpressionList( 13474 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 13475 MappableVarListInfo &MVLI, SourceLocation StartLoc, 13476 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 13477 ArrayRef<Expr *> UnresolvedMappers, 13478 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 13479 bool IsMapTypeImplicit = false) { 13480 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 13481 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 13482 "Unexpected clause kind with mappable expressions!"); 13483 13484 // If the identifier of user-defined mapper is not specified, it is "default". 13485 // We do not change the actual name in this clause to distinguish whether a 13486 // mapper is specified explicitly, i.e., it is not explicitly specified when 13487 // MapperId.getName() is empty. 13488 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 13489 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 13490 MapperId.setName(DeclNames.getIdentifier( 13491 &SemaRef.getASTContext().Idents.get("default"))); 13492 } 13493 13494 // Iterators to find the current unresolved mapper expression. 13495 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 13496 bool UpdateUMIt = false; 13497 Expr *UnresolvedMapper = nullptr; 13498 13499 // Keep track of the mappable components and base declarations in this clause. 13500 // Each entry in the list is going to have a list of components associated. We 13501 // record each set of the components so that we can build the clause later on. 13502 // In the end we should have the same amount of declarations and component 13503 // lists. 13504 13505 for (Expr *RE : MVLI.VarList) { 13506 assert(RE && "Null expr in omp to/from/map clause"); 13507 SourceLocation ELoc = RE->getExprLoc(); 13508 13509 // Find the current unresolved mapper expression. 13510 if (UpdateUMIt && UMIt != UMEnd) { 13511 UMIt++; 13512 assert( 13513 UMIt != UMEnd && 13514 "Expect the size of UnresolvedMappers to match with that of VarList"); 13515 } 13516 UpdateUMIt = true; 13517 if (UMIt != UMEnd) 13518 UnresolvedMapper = *UMIt; 13519 13520 const Expr *VE = RE->IgnoreParenLValueCasts(); 13521 13522 if (VE->isValueDependent() || VE->isTypeDependent() || 13523 VE->isInstantiationDependent() || 13524 VE->containsUnexpandedParameterPack()) { 13525 // Try to find the associated user-defined mapper. 13526 ExprResult ER = buildUserDefinedMapperRef( 13527 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13528 VE->getType().getCanonicalType(), UnresolvedMapper); 13529 if (ER.isInvalid()) 13530 continue; 13531 MVLI.UDMapperList.push_back(ER.get()); 13532 // We can only analyze this information once the missing information is 13533 // resolved. 13534 MVLI.ProcessedVarList.push_back(RE); 13535 continue; 13536 } 13537 13538 Expr *SimpleExpr = RE->IgnoreParenCasts(); 13539 13540 if (!RE->IgnoreParenImpCasts()->isLValue()) { 13541 SemaRef.Diag(ELoc, 13542 diag::err_omp_expected_named_var_member_or_array_expression) 13543 << RE->getSourceRange(); 13544 continue; 13545 } 13546 13547 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 13548 ValueDecl *CurDeclaration = nullptr; 13549 13550 // Obtain the array or member expression bases if required. Also, fill the 13551 // components array with all the components identified in the process. 13552 const Expr *BE = checkMapClauseExpressionBase( 13553 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 13554 if (!BE) 13555 continue; 13556 13557 assert(!CurComponents.empty() && 13558 "Invalid mappable expression information."); 13559 13560 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 13561 // Add store "this" pointer to class in DSAStackTy for future checking 13562 DSAS->addMappedClassesQualTypes(TE->getType()); 13563 // Try to find the associated user-defined mapper. 13564 ExprResult ER = buildUserDefinedMapperRef( 13565 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13566 VE->getType().getCanonicalType(), UnresolvedMapper); 13567 if (ER.isInvalid()) 13568 continue; 13569 MVLI.UDMapperList.push_back(ER.get()); 13570 // Skip restriction checking for variable or field declarations 13571 MVLI.ProcessedVarList.push_back(RE); 13572 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13573 MVLI.VarComponents.back().append(CurComponents.begin(), 13574 CurComponents.end()); 13575 MVLI.VarBaseDeclarations.push_back(nullptr); 13576 continue; 13577 } 13578 13579 // For the following checks, we rely on the base declaration which is 13580 // expected to be associated with the last component. The declaration is 13581 // expected to be a variable or a field (if 'this' is being mapped). 13582 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 13583 assert(CurDeclaration && "Null decl on map clause."); 13584 assert( 13585 CurDeclaration->isCanonicalDecl() && 13586 "Expecting components to have associated only canonical declarations."); 13587 13588 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 13589 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 13590 13591 assert((VD || FD) && "Only variables or fields are expected here!"); 13592 (void)FD; 13593 13594 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 13595 // threadprivate variables cannot appear in a map clause. 13596 // OpenMP 4.5 [2.10.5, target update Construct] 13597 // threadprivate variables cannot appear in a from clause. 13598 if (VD && DSAS->isThreadPrivate(VD)) { 13599 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 13600 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 13601 << getOpenMPClauseName(CKind); 13602 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 13603 continue; 13604 } 13605 13606 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 13607 // A list item cannot appear in both a map clause and a data-sharing 13608 // attribute clause on the same construct. 13609 13610 // Check conflicts with other map clause expressions. We check the conflicts 13611 // with the current construct separately from the enclosing data 13612 // environment, because the restrictions are different. We only have to 13613 // check conflicts across regions for the map clauses. 13614 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 13615 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 13616 break; 13617 if (CKind == OMPC_map && 13618 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 13619 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 13620 break; 13621 13622 // OpenMP 4.5 [2.10.5, target update Construct] 13623 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13624 // If the type of a list item is a reference to a type T then the type will 13625 // be considered to be T for all purposes of this clause. 13626 auto I = llvm::find_if( 13627 CurComponents, 13628 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 13629 return MC.getAssociatedDeclaration(); 13630 }); 13631 assert(I != CurComponents.end() && "Null decl on map clause."); 13632 QualType Type = 13633 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 13634 13635 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 13636 // A list item in a to or from clause must have a mappable type. 13637 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 13638 // A list item must have a mappable type. 13639 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 13640 DSAS, Type)) 13641 continue; 13642 13643 if (CKind == OMPC_map) { 13644 // target enter data 13645 // OpenMP [2.10.2, Restrictions, p. 99] 13646 // A map-type must be specified in all map clauses and must be either 13647 // to or alloc. 13648 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 13649 if (DKind == OMPD_target_enter_data && 13650 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 13651 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 13652 << (IsMapTypeImplicit ? 1 : 0) 13653 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 13654 << getOpenMPDirectiveName(DKind); 13655 continue; 13656 } 13657 13658 // target exit_data 13659 // OpenMP [2.10.3, Restrictions, p. 102] 13660 // A map-type must be specified in all map clauses and must be either 13661 // from, release, or delete. 13662 if (DKind == OMPD_target_exit_data && 13663 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 13664 MapType == OMPC_MAP_delete)) { 13665 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 13666 << (IsMapTypeImplicit ? 1 : 0) 13667 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 13668 << getOpenMPDirectiveName(DKind); 13669 continue; 13670 } 13671 13672 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13673 // A list item cannot appear in both a map clause and a data-sharing 13674 // attribute clause on the same construct 13675 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 13676 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 13677 if (isOpenMPPrivate(DVar.CKind)) { 13678 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13679 << getOpenMPClauseName(DVar.CKind) 13680 << getOpenMPClauseName(OMPC_map) 13681 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 13682 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 13683 continue; 13684 } 13685 } 13686 } 13687 13688 // Try to find the associated user-defined mapper. 13689 ExprResult ER = buildUserDefinedMapperRef( 13690 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13691 Type.getCanonicalType(), UnresolvedMapper); 13692 if (ER.isInvalid()) 13693 continue; 13694 MVLI.UDMapperList.push_back(ER.get()); 13695 13696 // Save the current expression. 13697 MVLI.ProcessedVarList.push_back(RE); 13698 13699 // Store the components in the stack so that they can be used to check 13700 // against other clauses later on. 13701 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 13702 /*WhereFoundClauseKind=*/OMPC_map); 13703 13704 // Save the components and declaration to create the clause. For purposes of 13705 // the clause creation, any component list that has has base 'this' uses 13706 // null as base declaration. 13707 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13708 MVLI.VarComponents.back().append(CurComponents.begin(), 13709 CurComponents.end()); 13710 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 13711 : CurDeclaration); 13712 } 13713 } 13714 13715 OMPClause *Sema::ActOnOpenMPMapClause( 13716 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13717 ArrayRef<SourceLocation> MapTypeModifiersLoc, 13718 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 13719 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 13720 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 13721 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 13722 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 13723 OMPC_MAP_MODIFIER_unknown, 13724 OMPC_MAP_MODIFIER_unknown}; 13725 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 13726 13727 // Process map-type-modifiers, flag errors for duplicate modifiers. 13728 unsigned Count = 0; 13729 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 13730 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 13731 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 13732 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 13733 continue; 13734 } 13735 assert(Count < OMPMapClause::NumberOfModifiers && 13736 "Modifiers exceed the allowed number of map type modifiers"); 13737 Modifiers[Count] = MapTypeModifiers[I]; 13738 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 13739 ++Count; 13740 } 13741 13742 MappableVarListInfo MVLI(VarList); 13743 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 13744 MapperIdScopeSpec, MapperId, UnresolvedMappers, 13745 MapType, IsMapTypeImplicit); 13746 13747 // We need to produce a map clause even if we don't have variables so that 13748 // other diagnostics related with non-existing map clauses are accurate. 13749 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 13750 MVLI.VarBaseDeclarations, MVLI.VarComponents, 13751 MVLI.UDMapperList, Modifiers, ModifiersLoc, 13752 MapperIdScopeSpec.getWithLocInContext(Context), 13753 MapperId, MapType, IsMapTypeImplicit, MapLoc); 13754 } 13755 13756 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 13757 TypeResult ParsedType) { 13758 assert(ParsedType.isUsable()); 13759 13760 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 13761 if (ReductionType.isNull()) 13762 return QualType(); 13763 13764 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 13765 // A type name in a declare reduction directive cannot be a function type, an 13766 // array type, a reference type, or a type qualified with const, volatile or 13767 // restrict. 13768 if (ReductionType.hasQualifiers()) { 13769 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 13770 return QualType(); 13771 } 13772 13773 if (ReductionType->isFunctionType()) { 13774 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 13775 return QualType(); 13776 } 13777 if (ReductionType->isReferenceType()) { 13778 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 13779 return QualType(); 13780 } 13781 if (ReductionType->isArrayType()) { 13782 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 13783 return QualType(); 13784 } 13785 return ReductionType; 13786 } 13787 13788 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 13789 Scope *S, DeclContext *DC, DeclarationName Name, 13790 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 13791 AccessSpecifier AS, Decl *PrevDeclInScope) { 13792 SmallVector<Decl *, 8> Decls; 13793 Decls.reserve(ReductionTypes.size()); 13794 13795 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 13796 forRedeclarationInCurContext()); 13797 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 13798 // A reduction-identifier may not be re-declared in the current scope for the 13799 // same type or for a type that is compatible according to the base language 13800 // rules. 13801 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 13802 OMPDeclareReductionDecl *PrevDRD = nullptr; 13803 bool InCompoundScope = true; 13804 if (S != nullptr) { 13805 // Find previous declaration with the same name not referenced in other 13806 // declarations. 13807 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 13808 InCompoundScope = 13809 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 13810 LookupName(Lookup, S); 13811 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 13812 /*AllowInlineNamespace=*/false); 13813 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 13814 LookupResult::Filter Filter = Lookup.makeFilter(); 13815 while (Filter.hasNext()) { 13816 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 13817 if (InCompoundScope) { 13818 auto I = UsedAsPrevious.find(PrevDecl); 13819 if (I == UsedAsPrevious.end()) 13820 UsedAsPrevious[PrevDecl] = false; 13821 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 13822 UsedAsPrevious[D] = true; 13823 } 13824 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 13825 PrevDecl->getLocation(); 13826 } 13827 Filter.done(); 13828 if (InCompoundScope) { 13829 for (const auto &PrevData : UsedAsPrevious) { 13830 if (!PrevData.second) { 13831 PrevDRD = PrevData.first; 13832 break; 13833 } 13834 } 13835 } 13836 } else if (PrevDeclInScope != nullptr) { 13837 auto *PrevDRDInScope = PrevDRD = 13838 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 13839 do { 13840 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 13841 PrevDRDInScope->getLocation(); 13842 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 13843 } while (PrevDRDInScope != nullptr); 13844 } 13845 for (const auto &TyData : ReductionTypes) { 13846 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 13847 bool Invalid = false; 13848 if (I != PreviousRedeclTypes.end()) { 13849 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 13850 << TyData.first; 13851 Diag(I->second, diag::note_previous_definition); 13852 Invalid = true; 13853 } 13854 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 13855 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 13856 Name, TyData.first, PrevDRD); 13857 DC->addDecl(DRD); 13858 DRD->setAccess(AS); 13859 Decls.push_back(DRD); 13860 if (Invalid) 13861 DRD->setInvalidDecl(); 13862 else 13863 PrevDRD = DRD; 13864 } 13865 13866 return DeclGroupPtrTy::make( 13867 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 13868 } 13869 13870 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 13871 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13872 13873 // Enter new function scope. 13874 PushFunctionScope(); 13875 setFunctionHasBranchProtectedScope(); 13876 getCurFunction()->setHasOMPDeclareReductionCombiner(); 13877 13878 if (S != nullptr) 13879 PushDeclContext(S, DRD); 13880 else 13881 CurContext = DRD; 13882 13883 PushExpressionEvaluationContext( 13884 ExpressionEvaluationContext::PotentiallyEvaluated); 13885 13886 QualType ReductionType = DRD->getType(); 13887 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 13888 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 13889 // uses semantics of argument handles by value, but it should be passed by 13890 // reference. C lang does not support references, so pass all parameters as 13891 // pointers. 13892 // Create 'T omp_in;' variable. 13893 VarDecl *OmpInParm = 13894 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 13895 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 13896 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 13897 // uses semantics of argument handles by value, but it should be passed by 13898 // reference. C lang does not support references, so pass all parameters as 13899 // pointers. 13900 // Create 'T omp_out;' variable. 13901 VarDecl *OmpOutParm = 13902 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 13903 if (S != nullptr) { 13904 PushOnScopeChains(OmpInParm, S); 13905 PushOnScopeChains(OmpOutParm, S); 13906 } else { 13907 DRD->addDecl(OmpInParm); 13908 DRD->addDecl(OmpOutParm); 13909 } 13910 Expr *InE = 13911 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 13912 Expr *OutE = 13913 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 13914 DRD->setCombinerData(InE, OutE); 13915 } 13916 13917 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 13918 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13919 DiscardCleanupsInEvaluationContext(); 13920 PopExpressionEvaluationContext(); 13921 13922 PopDeclContext(); 13923 PopFunctionScopeInfo(); 13924 13925 if (Combiner != nullptr) 13926 DRD->setCombiner(Combiner); 13927 else 13928 DRD->setInvalidDecl(); 13929 } 13930 13931 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 13932 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13933 13934 // Enter new function scope. 13935 PushFunctionScope(); 13936 setFunctionHasBranchProtectedScope(); 13937 13938 if (S != nullptr) 13939 PushDeclContext(S, DRD); 13940 else 13941 CurContext = DRD; 13942 13943 PushExpressionEvaluationContext( 13944 ExpressionEvaluationContext::PotentiallyEvaluated); 13945 13946 QualType ReductionType = DRD->getType(); 13947 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 13948 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 13949 // uses semantics of argument handles by value, but it should be passed by 13950 // reference. C lang does not support references, so pass all parameters as 13951 // pointers. 13952 // Create 'T omp_priv;' variable. 13953 VarDecl *OmpPrivParm = 13954 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 13955 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 13956 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 13957 // uses semantics of argument handles by value, but it should be passed by 13958 // reference. C lang does not support references, so pass all parameters as 13959 // pointers. 13960 // Create 'T omp_orig;' variable. 13961 VarDecl *OmpOrigParm = 13962 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 13963 if (S != nullptr) { 13964 PushOnScopeChains(OmpPrivParm, S); 13965 PushOnScopeChains(OmpOrigParm, S); 13966 } else { 13967 DRD->addDecl(OmpPrivParm); 13968 DRD->addDecl(OmpOrigParm); 13969 } 13970 Expr *OrigE = 13971 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 13972 Expr *PrivE = 13973 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 13974 DRD->setInitializerData(OrigE, PrivE); 13975 return OmpPrivParm; 13976 } 13977 13978 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 13979 VarDecl *OmpPrivParm) { 13980 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13981 DiscardCleanupsInEvaluationContext(); 13982 PopExpressionEvaluationContext(); 13983 13984 PopDeclContext(); 13985 PopFunctionScopeInfo(); 13986 13987 if (Initializer != nullptr) { 13988 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 13989 } else if (OmpPrivParm->hasInit()) { 13990 DRD->setInitializer(OmpPrivParm->getInit(), 13991 OmpPrivParm->isDirectInit() 13992 ? OMPDeclareReductionDecl::DirectInit 13993 : OMPDeclareReductionDecl::CopyInit); 13994 } else { 13995 DRD->setInvalidDecl(); 13996 } 13997 } 13998 13999 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 14000 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 14001 for (Decl *D : DeclReductions.get()) { 14002 if (IsValid) { 14003 if (S) 14004 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 14005 /*AddToContext=*/false); 14006 } else { 14007 D->setInvalidDecl(); 14008 } 14009 } 14010 return DeclReductions; 14011 } 14012 14013 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 14014 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 14015 QualType T = TInfo->getType(); 14016 if (D.isInvalidType()) 14017 return true; 14018 14019 if (getLangOpts().CPlusPlus) { 14020 // Check that there are no default arguments (C++ only). 14021 CheckExtraCXXDefaultArguments(D); 14022 } 14023 14024 return CreateParsedType(T, TInfo); 14025 } 14026 14027 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 14028 TypeResult ParsedType) { 14029 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 14030 14031 QualType MapperType = GetTypeFromParser(ParsedType.get()); 14032 assert(!MapperType.isNull() && "Expect valid mapper type"); 14033 14034 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14035 // The type must be of struct, union or class type in C and C++ 14036 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 14037 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 14038 return QualType(); 14039 } 14040 return MapperType; 14041 } 14042 14043 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 14044 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 14045 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 14046 Decl *PrevDeclInScope) { 14047 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 14048 forRedeclarationInCurContext()); 14049 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 14050 // A mapper-identifier may not be redeclared in the current scope for the 14051 // same type or for a type that is compatible according to the base language 14052 // rules. 14053 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 14054 OMPDeclareMapperDecl *PrevDMD = nullptr; 14055 bool InCompoundScope = true; 14056 if (S != nullptr) { 14057 // Find previous declaration with the same name not referenced in other 14058 // declarations. 14059 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 14060 InCompoundScope = 14061 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 14062 LookupName(Lookup, S); 14063 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 14064 /*AllowInlineNamespace=*/false); 14065 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 14066 LookupResult::Filter Filter = Lookup.makeFilter(); 14067 while (Filter.hasNext()) { 14068 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 14069 if (InCompoundScope) { 14070 auto I = UsedAsPrevious.find(PrevDecl); 14071 if (I == UsedAsPrevious.end()) 14072 UsedAsPrevious[PrevDecl] = false; 14073 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 14074 UsedAsPrevious[D] = true; 14075 } 14076 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14077 PrevDecl->getLocation(); 14078 } 14079 Filter.done(); 14080 if (InCompoundScope) { 14081 for (const auto &PrevData : UsedAsPrevious) { 14082 if (!PrevData.second) { 14083 PrevDMD = PrevData.first; 14084 break; 14085 } 14086 } 14087 } 14088 } else if (PrevDeclInScope) { 14089 auto *PrevDMDInScope = PrevDMD = 14090 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 14091 do { 14092 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 14093 PrevDMDInScope->getLocation(); 14094 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 14095 } while (PrevDMDInScope != nullptr); 14096 } 14097 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 14098 bool Invalid = false; 14099 if (I != PreviousRedeclTypes.end()) { 14100 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 14101 << MapperType << Name; 14102 Diag(I->second, diag::note_previous_definition); 14103 Invalid = true; 14104 } 14105 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 14106 MapperType, VN, PrevDMD); 14107 DC->addDecl(DMD); 14108 DMD->setAccess(AS); 14109 if (Invalid) 14110 DMD->setInvalidDecl(); 14111 14112 // Enter new function scope. 14113 PushFunctionScope(); 14114 setFunctionHasBranchProtectedScope(); 14115 14116 CurContext = DMD; 14117 14118 return DMD; 14119 } 14120 14121 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 14122 Scope *S, 14123 QualType MapperType, 14124 SourceLocation StartLoc, 14125 DeclarationName VN) { 14126 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 14127 if (S) 14128 PushOnScopeChains(VD, S); 14129 else 14130 DMD->addDecl(VD); 14131 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 14132 DMD->setMapperVarRef(MapperVarRefExpr); 14133 } 14134 14135 Sema::DeclGroupPtrTy 14136 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 14137 ArrayRef<OMPClause *> ClauseList) { 14138 PopDeclContext(); 14139 PopFunctionScopeInfo(); 14140 14141 if (D) { 14142 if (S) 14143 PushOnScopeChains(D, S, /*AddToContext=*/false); 14144 D->CreateClauses(Context, ClauseList); 14145 } 14146 14147 return DeclGroupPtrTy::make(DeclGroupRef(D)); 14148 } 14149 14150 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 14151 SourceLocation StartLoc, 14152 SourceLocation LParenLoc, 14153 SourceLocation EndLoc) { 14154 Expr *ValExpr = NumTeams; 14155 Stmt *HelperValStmt = nullptr; 14156 14157 // OpenMP [teams Constrcut, Restrictions] 14158 // The num_teams expression must evaluate to a positive integer value. 14159 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 14160 /*StrictlyPositive=*/true)) 14161 return nullptr; 14162 14163 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14164 OpenMPDirectiveKind CaptureRegion = 14165 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 14166 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14167 ValExpr = MakeFullExpr(ValExpr).get(); 14168 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14169 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14170 HelperValStmt = buildPreInits(Context, Captures); 14171 } 14172 14173 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 14174 StartLoc, LParenLoc, EndLoc); 14175 } 14176 14177 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 14178 SourceLocation StartLoc, 14179 SourceLocation LParenLoc, 14180 SourceLocation EndLoc) { 14181 Expr *ValExpr = ThreadLimit; 14182 Stmt *HelperValStmt = nullptr; 14183 14184 // OpenMP [teams Constrcut, Restrictions] 14185 // The thread_limit expression must evaluate to a positive integer value. 14186 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 14187 /*StrictlyPositive=*/true)) 14188 return nullptr; 14189 14190 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14191 OpenMPDirectiveKind CaptureRegion = 14192 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 14193 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14194 ValExpr = MakeFullExpr(ValExpr).get(); 14195 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14196 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14197 HelperValStmt = buildPreInits(Context, Captures); 14198 } 14199 14200 return new (Context) OMPThreadLimitClause( 14201 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 14202 } 14203 14204 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 14205 SourceLocation StartLoc, 14206 SourceLocation LParenLoc, 14207 SourceLocation EndLoc) { 14208 Expr *ValExpr = Priority; 14209 14210 // OpenMP [2.9.1, task Constrcut] 14211 // The priority-value is a non-negative numerical scalar expression. 14212 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 14213 /*StrictlyPositive=*/false)) 14214 return nullptr; 14215 14216 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14217 } 14218 14219 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 14220 SourceLocation StartLoc, 14221 SourceLocation LParenLoc, 14222 SourceLocation EndLoc) { 14223 Expr *ValExpr = Grainsize; 14224 14225 // OpenMP [2.9.2, taskloop Constrcut] 14226 // The parameter of the grainsize clause must be a positive integer 14227 // expression. 14228 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 14229 /*StrictlyPositive=*/true)) 14230 return nullptr; 14231 14232 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14233 } 14234 14235 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 14236 SourceLocation StartLoc, 14237 SourceLocation LParenLoc, 14238 SourceLocation EndLoc) { 14239 Expr *ValExpr = NumTasks; 14240 14241 // OpenMP [2.9.2, taskloop Constrcut] 14242 // The parameter of the num_tasks clause must be a positive integer 14243 // expression. 14244 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 14245 /*StrictlyPositive=*/true)) 14246 return nullptr; 14247 14248 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14249 } 14250 14251 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 14252 SourceLocation LParenLoc, 14253 SourceLocation EndLoc) { 14254 // OpenMP [2.13.2, critical construct, Description] 14255 // ... where hint-expression is an integer constant expression that evaluates 14256 // to a valid lock hint. 14257 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 14258 if (HintExpr.isInvalid()) 14259 return nullptr; 14260 return new (Context) 14261 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 14262 } 14263 14264 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 14265 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 14266 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 14267 SourceLocation EndLoc) { 14268 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 14269 std::string Values; 14270 Values += "'"; 14271 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 14272 Values += "'"; 14273 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 14274 << Values << getOpenMPClauseName(OMPC_dist_schedule); 14275 return nullptr; 14276 } 14277 Expr *ValExpr = ChunkSize; 14278 Stmt *HelperValStmt = nullptr; 14279 if (ChunkSize) { 14280 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 14281 !ChunkSize->isInstantiationDependent() && 14282 !ChunkSize->containsUnexpandedParameterPack()) { 14283 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 14284 ExprResult Val = 14285 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 14286 if (Val.isInvalid()) 14287 return nullptr; 14288 14289 ValExpr = Val.get(); 14290 14291 // OpenMP [2.7.1, Restrictions] 14292 // chunk_size must be a loop invariant integer expression with a positive 14293 // value. 14294 llvm::APSInt Result; 14295 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 14296 if (Result.isSigned() && !Result.isStrictlyPositive()) { 14297 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 14298 << "dist_schedule" << ChunkSize->getSourceRange(); 14299 return nullptr; 14300 } 14301 } else if (getOpenMPCaptureRegionForClause( 14302 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 14303 OMPD_unknown && 14304 !CurContext->isDependentContext()) { 14305 ValExpr = MakeFullExpr(ValExpr).get(); 14306 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14307 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14308 HelperValStmt = buildPreInits(Context, Captures); 14309 } 14310 } 14311 } 14312 14313 return new (Context) 14314 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 14315 Kind, ValExpr, HelperValStmt); 14316 } 14317 14318 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 14319 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 14320 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 14321 SourceLocation KindLoc, SourceLocation EndLoc) { 14322 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 14323 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 14324 std::string Value; 14325 SourceLocation Loc; 14326 Value += "'"; 14327 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 14328 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14329 OMPC_DEFAULTMAP_MODIFIER_tofrom); 14330 Loc = MLoc; 14331 } else { 14332 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14333 OMPC_DEFAULTMAP_scalar); 14334 Loc = KindLoc; 14335 } 14336 Value += "'"; 14337 Diag(Loc, diag::err_omp_unexpected_clause_value) 14338 << Value << getOpenMPClauseName(OMPC_defaultmap); 14339 return nullptr; 14340 } 14341 DSAStack->setDefaultDMAToFromScalar(StartLoc); 14342 14343 return new (Context) 14344 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 14345 } 14346 14347 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 14348 DeclContext *CurLexicalContext = getCurLexicalContext(); 14349 if (!CurLexicalContext->isFileContext() && 14350 !CurLexicalContext->isExternCContext() && 14351 !CurLexicalContext->isExternCXXContext() && 14352 !isa<CXXRecordDecl>(CurLexicalContext) && 14353 !isa<ClassTemplateDecl>(CurLexicalContext) && 14354 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 14355 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 14356 Diag(Loc, diag::err_omp_region_not_file_context); 14357 return false; 14358 } 14359 ++DeclareTargetNestingLevel; 14360 return true; 14361 } 14362 14363 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 14364 assert(DeclareTargetNestingLevel > 0 && 14365 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 14366 --DeclareTargetNestingLevel; 14367 } 14368 14369 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 14370 CXXScopeSpec &ScopeSpec, 14371 const DeclarationNameInfo &Id, 14372 OMPDeclareTargetDeclAttr::MapTypeTy MT, 14373 NamedDeclSetType &SameDirectiveDecls) { 14374 LookupResult Lookup(*this, Id, LookupOrdinaryName); 14375 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 14376 14377 if (Lookup.isAmbiguous()) 14378 return; 14379 Lookup.suppressDiagnostics(); 14380 14381 if (!Lookup.isSingleResult()) { 14382 if (TypoCorrection Corrected = 14383 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, 14384 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), 14385 CTK_ErrorRecovery)) { 14386 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 14387 << Id.getName()); 14388 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 14389 return; 14390 } 14391 14392 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 14393 return; 14394 } 14395 14396 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 14397 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 14398 isa<FunctionTemplateDecl>(ND)) { 14399 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 14400 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 14401 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14402 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 14403 cast<ValueDecl>(ND)); 14404 if (!Res) { 14405 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 14406 ND->addAttr(A); 14407 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14408 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 14409 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 14410 } else if (*Res != MT) { 14411 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 14412 << Id.getName(); 14413 } 14414 } else { 14415 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 14416 } 14417 } 14418 14419 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 14420 Sema &SemaRef, Decl *D) { 14421 if (!D || !isa<VarDecl>(D)) 14422 return; 14423 auto *VD = cast<VarDecl>(D); 14424 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 14425 return; 14426 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 14427 SemaRef.Diag(SL, diag::note_used_here) << SR; 14428 } 14429 14430 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 14431 Sema &SemaRef, DSAStackTy *Stack, 14432 ValueDecl *VD) { 14433 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 14434 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 14435 /*FullCheck=*/false); 14436 } 14437 14438 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 14439 SourceLocation IdLoc) { 14440 if (!D || D->isInvalidDecl()) 14441 return; 14442 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 14443 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 14444 if (auto *VD = dyn_cast<VarDecl>(D)) { 14445 // Only global variables can be marked as declare target. 14446 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 14447 !VD->isStaticDataMember()) 14448 return; 14449 // 2.10.6: threadprivate variable cannot appear in a declare target 14450 // directive. 14451 if (DSAStack->isThreadPrivate(VD)) { 14452 Diag(SL, diag::err_omp_threadprivate_in_target); 14453 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 14454 return; 14455 } 14456 } 14457 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 14458 D = FTD->getTemplatedDecl(); 14459 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 14460 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14461 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 14462 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 14463 assert(IdLoc.isValid() && "Source location is expected"); 14464 Diag(IdLoc, diag::err_omp_function_in_link_clause); 14465 Diag(FD->getLocation(), diag::note_defined_here) << FD; 14466 return; 14467 } 14468 } 14469 if (auto *VD = dyn_cast<ValueDecl>(D)) { 14470 // Problem if any with var declared with incomplete type will be reported 14471 // as normal, so no need to check it here. 14472 if ((E || !VD->getType()->isIncompleteType()) && 14473 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 14474 return; 14475 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 14476 // Checking declaration inside declare target region. 14477 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 14478 isa<FunctionTemplateDecl>(D)) { 14479 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 14480 Context, OMPDeclareTargetDeclAttr::MT_To); 14481 D->addAttr(A); 14482 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14483 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 14484 } 14485 return; 14486 } 14487 } 14488 if (!E) 14489 return; 14490 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 14491 } 14492 14493 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 14494 CXXScopeSpec &MapperIdScopeSpec, 14495 DeclarationNameInfo &MapperId, 14496 const OMPVarListLocTy &Locs, 14497 ArrayRef<Expr *> UnresolvedMappers) { 14498 MappableVarListInfo MVLI(VarList); 14499 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 14500 MapperIdScopeSpec, MapperId, UnresolvedMappers); 14501 if (MVLI.ProcessedVarList.empty()) 14502 return nullptr; 14503 14504 return OMPToClause::Create( 14505 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 14506 MVLI.VarComponents, MVLI.UDMapperList, 14507 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 14508 } 14509 14510 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 14511 CXXScopeSpec &MapperIdScopeSpec, 14512 DeclarationNameInfo &MapperId, 14513 const OMPVarListLocTy &Locs, 14514 ArrayRef<Expr *> UnresolvedMappers) { 14515 MappableVarListInfo MVLI(VarList); 14516 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 14517 MapperIdScopeSpec, MapperId, UnresolvedMappers); 14518 if (MVLI.ProcessedVarList.empty()) 14519 return nullptr; 14520 14521 return OMPFromClause::Create( 14522 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 14523 MVLI.VarComponents, MVLI.UDMapperList, 14524 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 14525 } 14526 14527 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 14528 const OMPVarListLocTy &Locs) { 14529 MappableVarListInfo MVLI(VarList); 14530 SmallVector<Expr *, 8> PrivateCopies; 14531 SmallVector<Expr *, 8> Inits; 14532 14533 for (Expr *RefExpr : VarList) { 14534 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 14535 SourceLocation ELoc; 14536 SourceRange ERange; 14537 Expr *SimpleRefExpr = RefExpr; 14538 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14539 if (Res.second) { 14540 // It will be analyzed later. 14541 MVLI.ProcessedVarList.push_back(RefExpr); 14542 PrivateCopies.push_back(nullptr); 14543 Inits.push_back(nullptr); 14544 } 14545 ValueDecl *D = Res.first; 14546 if (!D) 14547 continue; 14548 14549 QualType Type = D->getType(); 14550 Type = Type.getNonReferenceType().getUnqualifiedType(); 14551 14552 auto *VD = dyn_cast<VarDecl>(D); 14553 14554 // Item should be a pointer or reference to pointer. 14555 if (!Type->isPointerType()) { 14556 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 14557 << 0 << RefExpr->getSourceRange(); 14558 continue; 14559 } 14560 14561 // Build the private variable and the expression that refers to it. 14562 auto VDPrivate = 14563 buildVarDecl(*this, ELoc, Type, D->getName(), 14564 D->hasAttrs() ? &D->getAttrs() : nullptr, 14565 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14566 if (VDPrivate->isInvalidDecl()) 14567 continue; 14568 14569 CurContext->addDecl(VDPrivate); 14570 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 14571 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 14572 14573 // Add temporary variable to initialize the private copy of the pointer. 14574 VarDecl *VDInit = 14575 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 14576 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 14577 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 14578 AddInitializerToDecl(VDPrivate, 14579 DefaultLvalueConversion(VDInitRefExpr).get(), 14580 /*DirectInit=*/false); 14581 14582 // If required, build a capture to implement the privatization initialized 14583 // with the current list item value. 14584 DeclRefExpr *Ref = nullptr; 14585 if (!VD) 14586 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14587 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 14588 PrivateCopies.push_back(VDPrivateRefExpr); 14589 Inits.push_back(VDInitRefExpr); 14590 14591 // We need to add a data sharing attribute for this variable to make sure it 14592 // is correctly captured. A variable that shows up in a use_device_ptr has 14593 // similar properties of a first private variable. 14594 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 14595 14596 // Create a mappable component for the list item. List items in this clause 14597 // only need a component. 14598 MVLI.VarBaseDeclarations.push_back(D); 14599 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14600 MVLI.VarComponents.back().push_back( 14601 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 14602 } 14603 14604 if (MVLI.ProcessedVarList.empty()) 14605 return nullptr; 14606 14607 return OMPUseDevicePtrClause::Create( 14608 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 14609 MVLI.VarBaseDeclarations, MVLI.VarComponents); 14610 } 14611 14612 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 14613 const OMPVarListLocTy &Locs) { 14614 MappableVarListInfo MVLI(VarList); 14615 for (Expr *RefExpr : VarList) { 14616 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 14617 SourceLocation ELoc; 14618 SourceRange ERange; 14619 Expr *SimpleRefExpr = RefExpr; 14620 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14621 if (Res.second) { 14622 // It will be analyzed later. 14623 MVLI.ProcessedVarList.push_back(RefExpr); 14624 } 14625 ValueDecl *D = Res.first; 14626 if (!D) 14627 continue; 14628 14629 QualType Type = D->getType(); 14630 // item should be a pointer or array or reference to pointer or array 14631 if (!Type.getNonReferenceType()->isPointerType() && 14632 !Type.getNonReferenceType()->isArrayType()) { 14633 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 14634 << 0 << RefExpr->getSourceRange(); 14635 continue; 14636 } 14637 14638 // Check if the declaration in the clause does not show up in any data 14639 // sharing attribute. 14640 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14641 if (isOpenMPPrivate(DVar.CKind)) { 14642 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14643 << getOpenMPClauseName(DVar.CKind) 14644 << getOpenMPClauseName(OMPC_is_device_ptr) 14645 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14646 reportOriginalDsa(*this, DSAStack, D, DVar); 14647 continue; 14648 } 14649 14650 const Expr *ConflictExpr; 14651 if (DSAStack->checkMappableExprComponentListsForDecl( 14652 D, /*CurrentRegionOnly=*/true, 14653 [&ConflictExpr]( 14654 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 14655 OpenMPClauseKind) -> bool { 14656 ConflictExpr = R.front().getAssociatedExpression(); 14657 return true; 14658 })) { 14659 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 14660 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 14661 << ConflictExpr->getSourceRange(); 14662 continue; 14663 } 14664 14665 // Store the components in the stack so that they can be used to check 14666 // against other clauses later on. 14667 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 14668 DSAStack->addMappableExpressionComponents( 14669 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 14670 14671 // Record the expression we've just processed. 14672 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 14673 14674 // Create a mappable component for the list item. List items in this clause 14675 // only need a component. We use a null declaration to signal fields in 14676 // 'this'. 14677 assert((isa<DeclRefExpr>(SimpleRefExpr) || 14678 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 14679 "Unexpected device pointer expression!"); 14680 MVLI.VarBaseDeclarations.push_back( 14681 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 14682 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14683 MVLI.VarComponents.back().push_back(MC); 14684 } 14685 14686 if (MVLI.ProcessedVarList.empty()) 14687 return nullptr; 14688 14689 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 14690 MVLI.VarBaseDeclarations, 14691 MVLI.VarComponents); 14692 } 14693