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 192 public: 193 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 194 195 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 196 OpenMPClauseKind getClauseParsingMode() const { 197 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 198 return ClauseKindMode; 199 } 200 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 201 202 bool isForceVarCapturing() const { return ForceCapturing; } 203 void setForceVarCapturing(bool V) { ForceCapturing = V; } 204 205 void setForceCaptureByReferenceInTargetExecutable(bool V) { 206 ForceCaptureByReferenceInTargetExecutable = V; 207 } 208 bool isForceCaptureByReferenceInTargetExecutable() const { 209 return ForceCaptureByReferenceInTargetExecutable; 210 } 211 212 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 213 Scope *CurScope, SourceLocation Loc) { 214 if (Stack.empty() || 215 Stack.back().second != CurrentNonCapturingFunctionScope) 216 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 217 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 218 Stack.back().first.back().DefaultAttrLoc = Loc; 219 } 220 221 void pop() { 222 assert(!Stack.back().first.empty() && 223 "Data-sharing attributes stack is empty!"); 224 Stack.back().first.pop_back(); 225 } 226 227 /// Marks that we're started loop parsing. 228 void loopInit() { 229 assert(isOpenMPLoopDirective(getCurrentDirective()) && 230 "Expected loop-based directive."); 231 Stack.back().first.back().LoopStart = true; 232 } 233 /// Start capturing of the variables in the loop context. 234 void loopStart() { 235 assert(isOpenMPLoopDirective(getCurrentDirective()) && 236 "Expected loop-based directive."); 237 Stack.back().first.back().LoopStart = false; 238 } 239 /// true, if variables are captured, false otherwise. 240 bool isLoopStarted() const { 241 assert(isOpenMPLoopDirective(getCurrentDirective()) && 242 "Expected loop-based directive."); 243 return !Stack.back().first.back().LoopStart; 244 } 245 /// Marks (or clears) declaration as possibly loop counter. 246 void resetPossibleLoopCounter(const Decl *D = nullptr) { 247 Stack.back().first.back().PossiblyLoopCounter = 248 D ? D->getCanonicalDecl() : D; 249 } 250 /// Gets the possible loop counter decl. 251 const Decl *getPossiblyLoopCunter() const { 252 return Stack.back().first.back().PossiblyLoopCounter; 253 } 254 /// Start new OpenMP region stack in new non-capturing function. 255 void pushFunction() { 256 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 257 assert(!isa<CapturingScopeInfo>(CurFnScope)); 258 CurrentNonCapturingFunctionScope = CurFnScope; 259 } 260 /// Pop region stack for non-capturing function. 261 void popFunction(const FunctionScopeInfo *OldFSI) { 262 if (!Stack.empty() && Stack.back().second == OldFSI) { 263 assert(Stack.back().first.empty()); 264 Stack.pop_back(); 265 } 266 CurrentNonCapturingFunctionScope = nullptr; 267 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 268 if (!isa<CapturingScopeInfo>(FSI)) { 269 CurrentNonCapturingFunctionScope = FSI; 270 break; 271 } 272 } 273 } 274 275 void addCriticalWithHint(const OMPCriticalDirective *D, llvm::APSInt Hint) { 276 Criticals.try_emplace(D->getDirectiveName().getAsString(), D, Hint); 277 } 278 const std::pair<const OMPCriticalDirective *, llvm::APSInt> 279 getCriticalWithHint(const DeclarationNameInfo &Name) const { 280 auto I = Criticals.find(Name.getAsString()); 281 if (I != Criticals.end()) 282 return I->second; 283 return std::make_pair(nullptr, llvm::APSInt()); 284 } 285 /// If 'aligned' declaration for given variable \a D was not seen yet, 286 /// add it and return NULL; otherwise return previous occurrence's expression 287 /// for diagnostics. 288 const Expr *addUniqueAligned(const ValueDecl *D, const Expr *NewDE); 289 290 /// Register specified variable as loop control variable. 291 void addLoopControlVariable(const ValueDecl *D, VarDecl *Capture); 292 /// Check if the specified variable is a loop control variable for 293 /// current region. 294 /// \return The index of the loop control variable in the list of associated 295 /// for-loops (from outer to inner). 296 const LCDeclInfo isLoopControlVariable(const ValueDecl *D) const; 297 /// Check if the specified variable is a loop control variable for 298 /// parent region. 299 /// \return The index of the loop control variable in the list of associated 300 /// for-loops (from outer to inner). 301 const LCDeclInfo isParentLoopControlVariable(const ValueDecl *D) const; 302 /// Get the loop control variable for the I-th loop (or nullptr) in 303 /// parent directive. 304 const ValueDecl *getParentLoopControlVariable(unsigned I) const; 305 306 /// Adds explicit data sharing attribute to the specified declaration. 307 void addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 308 DeclRefExpr *PrivateCopy = nullptr); 309 310 /// Adds additional information for the reduction items with the reduction id 311 /// represented as an operator. 312 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 313 BinaryOperatorKind BOK); 314 /// Adds additional information for the reduction items with the reduction id 315 /// represented as reduction identifier. 316 void addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 317 const Expr *ReductionRef); 318 /// Returns the location and reduction operation from the innermost parent 319 /// region for the given \p D. 320 const DSAVarData 321 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 322 BinaryOperatorKind &BOK, 323 Expr *&TaskgroupDescriptor) const; 324 /// Returns the location and reduction operation from the innermost parent 325 /// region for the given \p D. 326 const DSAVarData 327 getTopMostTaskgroupReductionData(const ValueDecl *D, SourceRange &SR, 328 const Expr *&ReductionRef, 329 Expr *&TaskgroupDescriptor) const; 330 /// Return reduction reference expression for the current taskgroup. 331 Expr *getTaskgroupReductionRef() const { 332 assert(Stack.back().first.back().Directive == OMPD_taskgroup && 333 "taskgroup reference expression requested for non taskgroup " 334 "directive."); 335 return Stack.back().first.back().TaskgroupReductionRef; 336 } 337 /// Checks if the given \p VD declaration is actually a taskgroup reduction 338 /// descriptor variable at the \p Level of OpenMP regions. 339 bool isTaskgroupReductionRef(const ValueDecl *VD, unsigned Level) const { 340 return Stack.back().first[Level].TaskgroupReductionRef && 341 cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef) 342 ->getDecl() == VD; 343 } 344 345 /// Returns data sharing attributes from top of the stack for the 346 /// specified declaration. 347 const DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 348 /// Returns data-sharing attributes for the specified declaration. 349 const DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent) const; 350 /// Checks if the specified variables has data-sharing attributes which 351 /// match specified \a CPred predicate in any directive which matches \a DPred 352 /// predicate. 353 const DSAVarData 354 hasDSA(ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 355 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 356 bool FromParent) const; 357 /// Checks if the specified variables has data-sharing attributes which 358 /// match specified \a CPred predicate in any innermost directive which 359 /// matches \a DPred predicate. 360 const DSAVarData 361 hasInnermostDSA(ValueDecl *D, 362 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 363 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 364 bool FromParent) const; 365 /// Checks if the specified variables has explicit data-sharing 366 /// attributes which match specified \a CPred predicate at the specified 367 /// OpenMP region. 368 bool hasExplicitDSA(const ValueDecl *D, 369 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 370 unsigned Level, bool NotLastprivate = false) const; 371 372 /// Returns true if the directive at level \Level matches in the 373 /// specified \a DPred predicate. 374 bool hasExplicitDirective( 375 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 376 unsigned Level) const; 377 378 /// Finds a directive which matches specified \a DPred predicate. 379 bool hasDirective( 380 const llvm::function_ref<bool( 381 OpenMPDirectiveKind, const DeclarationNameInfo &, SourceLocation)> 382 DPred, 383 bool FromParent) const; 384 385 /// Returns currently analyzed directive. 386 OpenMPDirectiveKind getCurrentDirective() const { 387 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive; 388 } 389 /// Returns directive kind at specified level. 390 OpenMPDirectiveKind getDirective(unsigned Level) const { 391 assert(!isStackEmpty() && "No directive at specified level."); 392 return Stack.back().first[Level].Directive; 393 } 394 /// Returns parent directive. 395 OpenMPDirectiveKind getParentDirective() const { 396 if (isStackEmpty() || Stack.back().first.size() == 1) 397 return OMPD_unknown; 398 return std::next(Stack.back().first.rbegin())->Directive; 399 } 400 401 /// Add requires decl to internal vector 402 void addRequiresDecl(OMPRequiresDecl *RD) { 403 RequiresDecls.push_back(RD); 404 } 405 406 /// Checks for a duplicate clause amongst previously declared requires 407 /// directives 408 bool hasDuplicateRequiresClause(ArrayRef<OMPClause *> ClauseList) const { 409 bool IsDuplicate = false; 410 for (OMPClause *CNew : ClauseList) { 411 for (const OMPRequiresDecl *D : RequiresDecls) { 412 for (const OMPClause *CPrev : D->clauselists()) { 413 if (CNew->getClauseKind() == CPrev->getClauseKind()) { 414 SemaRef.Diag(CNew->getBeginLoc(), 415 diag::err_omp_requires_clause_redeclaration) 416 << getOpenMPClauseName(CNew->getClauseKind()); 417 SemaRef.Diag(CPrev->getBeginLoc(), 418 diag::note_omp_requires_previous_clause) 419 << getOpenMPClauseName(CPrev->getClauseKind()); 420 IsDuplicate = true; 421 } 422 } 423 } 424 } 425 return IsDuplicate; 426 } 427 428 /// Set default data sharing attribute to none. 429 void setDefaultDSANone(SourceLocation Loc) { 430 assert(!isStackEmpty()); 431 Stack.back().first.back().DefaultAttr = DSA_none; 432 Stack.back().first.back().DefaultAttrLoc = Loc; 433 } 434 /// Set default data sharing attribute to shared. 435 void setDefaultDSAShared(SourceLocation Loc) { 436 assert(!isStackEmpty()); 437 Stack.back().first.back().DefaultAttr = DSA_shared; 438 Stack.back().first.back().DefaultAttrLoc = Loc; 439 } 440 /// Set default data mapping attribute to 'tofrom:scalar'. 441 void setDefaultDMAToFromScalar(SourceLocation Loc) { 442 assert(!isStackEmpty()); 443 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar; 444 Stack.back().first.back().DefaultMapAttrLoc = Loc; 445 } 446 447 DefaultDataSharingAttributes getDefaultDSA() const { 448 return isStackEmpty() ? DSA_unspecified 449 : Stack.back().first.back().DefaultAttr; 450 } 451 SourceLocation getDefaultDSALocation() const { 452 return isStackEmpty() ? SourceLocation() 453 : Stack.back().first.back().DefaultAttrLoc; 454 } 455 DefaultMapAttributes getDefaultDMA() const { 456 return isStackEmpty() ? DMA_unspecified 457 : Stack.back().first.back().DefaultMapAttr; 458 } 459 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 460 return Stack.back().first[Level].DefaultMapAttr; 461 } 462 SourceLocation getDefaultDMALocation() const { 463 return isStackEmpty() ? SourceLocation() 464 : Stack.back().first.back().DefaultMapAttrLoc; 465 } 466 467 /// Checks if the specified variable is a threadprivate. 468 bool isThreadPrivate(VarDecl *D) { 469 const DSAVarData DVar = getTopDSA(D, false); 470 return isOpenMPThreadPrivate(DVar.CKind); 471 } 472 473 /// Marks current region as ordered (it has an 'ordered' clause). 474 void setOrderedRegion(bool IsOrdered, const Expr *Param, 475 OMPOrderedClause *Clause) { 476 assert(!isStackEmpty()); 477 if (IsOrdered) 478 Stack.back().first.back().OrderedRegion.emplace(Param, Clause); 479 else 480 Stack.back().first.back().OrderedRegion.reset(); 481 } 482 /// Returns true, if region is ordered (has associated 'ordered' clause), 483 /// false - otherwise. 484 bool isOrderedRegion() const { 485 if (isStackEmpty()) 486 return false; 487 return Stack.back().first.rbegin()->OrderedRegion.hasValue(); 488 } 489 /// Returns optional parameter for the ordered region. 490 std::pair<const Expr *, OMPOrderedClause *> getOrderedRegionParam() const { 491 if (isStackEmpty() || 492 !Stack.back().first.rbegin()->OrderedRegion.hasValue()) 493 return std::make_pair(nullptr, nullptr); 494 return Stack.back().first.rbegin()->OrderedRegion.getValue(); 495 } 496 /// Returns true, if parent region is ordered (has associated 497 /// 'ordered' clause), false - otherwise. 498 bool isParentOrderedRegion() const { 499 if (isStackEmpty() || Stack.back().first.size() == 1) 500 return false; 501 return std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue(); 502 } 503 /// Returns optional parameter for the ordered region. 504 std::pair<const Expr *, OMPOrderedClause *> 505 getParentOrderedRegionParam() const { 506 if (isStackEmpty() || Stack.back().first.size() == 1 || 507 !std::next(Stack.back().first.rbegin())->OrderedRegion.hasValue()) 508 return std::make_pair(nullptr, nullptr); 509 return std::next(Stack.back().first.rbegin())->OrderedRegion.getValue(); 510 } 511 /// Marks current region as nowait (it has a 'nowait' clause). 512 void setNowaitRegion(bool IsNowait = true) { 513 assert(!isStackEmpty()); 514 Stack.back().first.back().NowaitRegion = IsNowait; 515 } 516 /// Returns true, if parent region is nowait (has associated 517 /// 'nowait' clause), false - otherwise. 518 bool isParentNowaitRegion() const { 519 if (isStackEmpty() || Stack.back().first.size() == 1) 520 return false; 521 return std::next(Stack.back().first.rbegin())->NowaitRegion; 522 } 523 /// Marks parent region as cancel region. 524 void setParentCancelRegion(bool Cancel = true) { 525 if (!isStackEmpty() && Stack.back().first.size() > 1) { 526 auto &StackElemRef = *std::next(Stack.back().first.rbegin()); 527 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel; 528 } 529 } 530 /// Return true if current region has inner cancel construct. 531 bool isCancelRegion() const { 532 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion; 533 } 534 535 /// Set collapse value for the region. 536 void setAssociatedLoops(unsigned Val) { 537 assert(!isStackEmpty()); 538 Stack.back().first.back().AssociatedLoops = Val; 539 } 540 /// Return collapse value for region. 541 unsigned getAssociatedLoops() const { 542 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops; 543 } 544 545 /// Marks current target region as one with closely nested teams 546 /// region. 547 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 548 if (!isStackEmpty() && Stack.back().first.size() > 1) { 549 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc = 550 TeamsRegionLoc; 551 } 552 } 553 /// Returns true, if current region has closely nested teams region. 554 bool hasInnerTeamsRegion() const { 555 return getInnerTeamsRegionLoc().isValid(); 556 } 557 /// Returns location of the nested teams region (if any). 558 SourceLocation getInnerTeamsRegionLoc() const { 559 return isStackEmpty() ? SourceLocation() 560 : Stack.back().first.back().InnerTeamsRegionLoc; 561 } 562 563 Scope *getCurScope() const { 564 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 565 } 566 SourceLocation getConstructLoc() const { 567 return isStackEmpty() ? SourceLocation() 568 : Stack.back().first.back().ConstructLoc; 569 } 570 571 /// Do the check specified in \a Check to all component lists and return true 572 /// if any issue is found. 573 bool checkMappableExprComponentListsForDecl( 574 const ValueDecl *VD, bool CurrentRegionOnly, 575 const llvm::function_ref< 576 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 577 OpenMPClauseKind)> 578 Check) const { 579 if (isStackEmpty()) 580 return false; 581 auto SI = Stack.back().first.rbegin(); 582 auto SE = Stack.back().first.rend(); 583 584 if (SI == SE) 585 return false; 586 587 if (CurrentRegionOnly) 588 SE = std::next(SI); 589 else 590 std::advance(SI, 1); 591 592 for (; SI != SE; ++SI) { 593 auto MI = SI->MappedExprComponents.find(VD); 594 if (MI != SI->MappedExprComponents.end()) 595 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 596 MI->second.Components) 597 if (Check(L, MI->second.Kind)) 598 return true; 599 } 600 return false; 601 } 602 603 /// Do the check specified in \a Check to all component lists at a given level 604 /// and return true if any issue is found. 605 bool checkMappableExprComponentListsForDeclAtLevel( 606 const ValueDecl *VD, unsigned Level, 607 const llvm::function_ref< 608 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 609 OpenMPClauseKind)> 610 Check) const { 611 if (isStackEmpty()) 612 return false; 613 614 auto StartI = Stack.back().first.begin(); 615 auto EndI = Stack.back().first.end(); 616 if (std::distance(StartI, EndI) <= (int)Level) 617 return false; 618 std::advance(StartI, Level); 619 620 auto MI = StartI->MappedExprComponents.find(VD); 621 if (MI != StartI->MappedExprComponents.end()) 622 for (OMPClauseMappableExprCommon::MappableExprComponentListRef L : 623 MI->second.Components) 624 if (Check(L, MI->second.Kind)) 625 return true; 626 return false; 627 } 628 629 /// Create a new mappable expression component list associated with a given 630 /// declaration and initialize it with the provided list of components. 631 void addMappableExpressionComponents( 632 const ValueDecl *VD, 633 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 634 OpenMPClauseKind WhereFoundClauseKind) { 635 assert(!isStackEmpty() && 636 "Not expecting to retrieve components from a empty stack!"); 637 MappedExprComponentTy &MEC = 638 Stack.back().first.back().MappedExprComponents[VD]; 639 // Create new entry and append the new components there. 640 MEC.Components.resize(MEC.Components.size() + 1); 641 MEC.Components.back().append(Components.begin(), Components.end()); 642 MEC.Kind = WhereFoundClauseKind; 643 } 644 645 unsigned getNestingLevel() const { 646 assert(!isStackEmpty()); 647 return Stack.back().first.size() - 1; 648 } 649 void addDoacrossDependClause(OMPDependClause *C, 650 const OperatorOffsetTy &OpsOffs) { 651 assert(!isStackEmpty() && Stack.back().first.size() > 1); 652 SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 653 assert(isOpenMPWorksharingDirective(StackElem.Directive)); 654 StackElem.DoacrossDepends.try_emplace(C, OpsOffs); 655 } 656 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 657 getDoacrossDependClauses() const { 658 assert(!isStackEmpty()); 659 const SharingMapTy &StackElem = Stack.back().first.back(); 660 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 661 const DoacrossDependMapTy &Ref = StackElem.DoacrossDepends; 662 return llvm::make_range(Ref.begin(), Ref.end()); 663 } 664 return llvm::make_range(StackElem.DoacrossDepends.end(), 665 StackElem.DoacrossDepends.end()); 666 } 667 668 // Store types of classes which have been explicitly mapped 669 void addMappedClassesQualTypes(QualType QT) { 670 SharingMapTy &StackElem = Stack.back().first.back(); 671 StackElem.MappedClassesQualTypes.insert(QT); 672 } 673 674 // Return set of mapped classes types 675 bool isClassPreviouslyMapped(QualType QT) const { 676 const SharingMapTy &StackElem = Stack.back().first.back(); 677 return StackElem.MappedClassesQualTypes.count(QT) != 0; 678 } 679 680 /// Adds global declare target to the parent target region. 681 void addToParentTargetRegionLinkGlobals(DeclRefExpr *E) { 682 assert(*OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 683 E->getDecl()) == OMPDeclareTargetDeclAttr::MT_Link && 684 "Expected declare target link global."); 685 if (isStackEmpty()) 686 return; 687 auto It = Stack.back().first.rbegin(); 688 while (It != Stack.back().first.rend() && 689 !isOpenMPTargetExecutionDirective(It->Directive)) 690 ++It; 691 if (It != Stack.back().first.rend()) { 692 assert(isOpenMPTargetExecutionDirective(It->Directive) && 693 "Expected target executable directive."); 694 It->DeclareTargetLinkVarDecls.push_back(E); 695 } 696 } 697 698 /// Returns the list of globals with declare target link if current directive 699 /// is target. 700 ArrayRef<DeclRefExpr *> getLinkGlobals() const { 701 assert(isOpenMPTargetExecutionDirective(getCurrentDirective()) && 702 "Expected target executable directive."); 703 return Stack.back().first.back().DeclareTargetLinkVarDecls; 704 } 705 }; 706 707 bool isImplicitTaskingRegion(OpenMPDirectiveKind DKind) { 708 return isOpenMPParallelDirective(DKind) || isOpenMPTeamsDirective(DKind); 709 } 710 711 bool isImplicitOrExplicitTaskingRegion(OpenMPDirectiveKind DKind) { 712 return isImplicitTaskingRegion(DKind) || isOpenMPTaskingDirective(DKind) || DKind == OMPD_unknown; 713 } 714 715 } // namespace 716 717 static const Expr *getExprAsWritten(const Expr *E) { 718 if (const auto *FE = dyn_cast<FullExpr>(E)) 719 E = FE->getSubExpr(); 720 721 if (const auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 722 E = MTE->GetTemporaryExpr(); 723 724 while (const auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 725 E = Binder->getSubExpr(); 726 727 if (const auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 728 E = ICE->getSubExprAsWritten(); 729 return E->IgnoreParens(); 730 } 731 732 static Expr *getExprAsWritten(Expr *E) { 733 return const_cast<Expr *>(getExprAsWritten(const_cast<const Expr *>(E))); 734 } 735 736 static const ValueDecl *getCanonicalDecl(const ValueDecl *D) { 737 if (const auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 738 if (const auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 739 D = ME->getMemberDecl(); 740 const auto *VD = dyn_cast<VarDecl>(D); 741 const auto *FD = dyn_cast<FieldDecl>(D); 742 if (VD != nullptr) { 743 VD = VD->getCanonicalDecl(); 744 D = VD; 745 } else { 746 assert(FD); 747 FD = FD->getCanonicalDecl(); 748 D = FD; 749 } 750 return D; 751 } 752 753 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 754 return const_cast<ValueDecl *>( 755 getCanonicalDecl(const_cast<const ValueDecl *>(D))); 756 } 757 758 DSAStackTy::DSAVarData DSAStackTy::getDSA(iterator &Iter, 759 ValueDecl *D) const { 760 D = getCanonicalDecl(D); 761 auto *VD = dyn_cast<VarDecl>(D); 762 const auto *FD = dyn_cast<FieldDecl>(D); 763 DSAVarData DVar; 764 if (isStackEmpty() || Iter == Stack.back().first.rend()) { 765 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 766 // in a region but not in construct] 767 // File-scope or namespace-scope variables referenced in called routines 768 // in the region are shared unless they appear in a threadprivate 769 // directive. 770 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(VD)) 771 DVar.CKind = OMPC_shared; 772 773 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 774 // in a region but not in construct] 775 // Variables with static storage duration that are declared in called 776 // routines in the region are shared. 777 if (VD && VD->hasGlobalStorage()) 778 DVar.CKind = OMPC_shared; 779 780 // Non-static data members are shared by default. 781 if (FD) 782 DVar.CKind = OMPC_shared; 783 784 return DVar; 785 } 786 787 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 788 // in a Construct, C/C++, predetermined, p.1] 789 // Variables with automatic storage duration that are declared in a scope 790 // inside the construct are private. 791 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 792 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 793 DVar.CKind = OMPC_private; 794 return DVar; 795 } 796 797 DVar.DKind = Iter->Directive; 798 // Explicitly specified attributes and local variables with predetermined 799 // attributes. 800 if (Iter->SharingMap.count(D)) { 801 const DSAInfo &Data = Iter->SharingMap.lookup(D); 802 DVar.RefExpr = Data.RefExpr.getPointer(); 803 DVar.PrivateCopy = Data.PrivateCopy; 804 DVar.CKind = Data.Attributes; 805 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 806 return DVar; 807 } 808 809 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 810 // in a Construct, C/C++, implicitly determined, p.1] 811 // In a parallel or task construct, the data-sharing attributes of these 812 // variables are determined by the default clause, if present. 813 switch (Iter->DefaultAttr) { 814 case DSA_shared: 815 DVar.CKind = OMPC_shared; 816 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 817 return DVar; 818 case DSA_none: 819 return DVar; 820 case DSA_unspecified: 821 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 822 // in a Construct, implicitly determined, p.2] 823 // In a parallel construct, if no default clause is present, these 824 // variables are shared. 825 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 826 if (isOpenMPParallelDirective(DVar.DKind) || 827 isOpenMPTeamsDirective(DVar.DKind)) { 828 DVar.CKind = OMPC_shared; 829 return DVar; 830 } 831 832 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 833 // in a Construct, implicitly determined, p.4] 834 // In a task construct, if no default clause is present, a variable that in 835 // the enclosing context is determined to be shared by all implicit tasks 836 // bound to the current team is shared. 837 if (isOpenMPTaskingDirective(DVar.DKind)) { 838 DSAVarData DVarTemp; 839 iterator I = Iter, E = Stack.back().first.rend(); 840 do { 841 ++I; 842 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 843 // Referenced in a Construct, implicitly determined, p.6] 844 // In a task construct, if no default clause is present, a variable 845 // whose data-sharing attribute is not determined by the rules above is 846 // firstprivate. 847 DVarTemp = getDSA(I, D); 848 if (DVarTemp.CKind != OMPC_shared) { 849 DVar.RefExpr = nullptr; 850 DVar.CKind = OMPC_firstprivate; 851 return DVar; 852 } 853 } while (I != E && !isImplicitTaskingRegion(I->Directive)); 854 DVar.CKind = 855 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 856 return DVar; 857 } 858 } 859 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 860 // in a Construct, implicitly determined, p.3] 861 // For constructs other than task, if no default clause is present, these 862 // variables inherit their data-sharing attributes from the enclosing 863 // context. 864 return getDSA(++Iter, D); 865 } 866 867 const Expr *DSAStackTy::addUniqueAligned(const ValueDecl *D, 868 const Expr *NewDE) { 869 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 870 D = getCanonicalDecl(D); 871 SharingMapTy &StackElem = Stack.back().first.back(); 872 auto It = StackElem.AlignedMap.find(D); 873 if (It == StackElem.AlignedMap.end()) { 874 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 875 StackElem.AlignedMap[D] = NewDE; 876 return nullptr; 877 } 878 assert(It->second && "Unexpected nullptr expr in the aligned map"); 879 return It->second; 880 } 881 882 void DSAStackTy::addLoopControlVariable(const ValueDecl *D, VarDecl *Capture) { 883 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 884 D = getCanonicalDecl(D); 885 SharingMapTy &StackElem = Stack.back().first.back(); 886 StackElem.LCVMap.try_emplace( 887 D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)); 888 } 889 890 const DSAStackTy::LCDeclInfo 891 DSAStackTy::isLoopControlVariable(const ValueDecl *D) const { 892 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 893 D = getCanonicalDecl(D); 894 const SharingMapTy &StackElem = Stack.back().first.back(); 895 auto It = StackElem.LCVMap.find(D); 896 if (It != StackElem.LCVMap.end()) 897 return It->second; 898 return {0, nullptr}; 899 } 900 901 const DSAStackTy::LCDeclInfo 902 DSAStackTy::isParentLoopControlVariable(const ValueDecl *D) const { 903 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 904 "Data-sharing attributes stack is empty"); 905 D = getCanonicalDecl(D); 906 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 907 auto It = StackElem.LCVMap.find(D); 908 if (It != StackElem.LCVMap.end()) 909 return It->second; 910 return {0, nullptr}; 911 } 912 913 const ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) const { 914 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 915 "Data-sharing attributes stack is empty"); 916 const SharingMapTy &StackElem = *std::next(Stack.back().first.rbegin()); 917 if (StackElem.LCVMap.size() < I) 918 return nullptr; 919 for (const auto &Pair : StackElem.LCVMap) 920 if (Pair.second.first == I) 921 return Pair.first; 922 return nullptr; 923 } 924 925 void DSAStackTy::addDSA(const ValueDecl *D, const Expr *E, OpenMPClauseKind A, 926 DeclRefExpr *PrivateCopy) { 927 D = getCanonicalDecl(D); 928 if (A == OMPC_threadprivate) { 929 DSAInfo &Data = Threadprivates[D]; 930 Data.Attributes = A; 931 Data.RefExpr.setPointer(E); 932 Data.PrivateCopy = nullptr; 933 } else { 934 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 935 DSAInfo &Data = Stack.back().first.back().SharingMap[D]; 936 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 937 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 938 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 939 (isLoopControlVariable(D).first && A == OMPC_private)); 940 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 941 Data.RefExpr.setInt(/*IntVal=*/true); 942 return; 943 } 944 const bool IsLastprivate = 945 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 946 Data.Attributes = A; 947 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 948 Data.PrivateCopy = PrivateCopy; 949 if (PrivateCopy) { 950 DSAInfo &Data = 951 Stack.back().first.back().SharingMap[PrivateCopy->getDecl()]; 952 Data.Attributes = A; 953 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 954 Data.PrivateCopy = nullptr; 955 } 956 } 957 } 958 959 /// Build a variable declaration for OpenMP loop iteration variable. 960 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 961 StringRef Name, const AttrVec *Attrs = nullptr, 962 DeclRefExpr *OrigRef = nullptr) { 963 DeclContext *DC = SemaRef.CurContext; 964 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 965 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 966 auto *Decl = 967 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 968 if (Attrs) { 969 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 970 I != E; ++I) 971 Decl->addAttr(*I); 972 } 973 Decl->setImplicit(); 974 if (OrigRef) { 975 Decl->addAttr( 976 OMPReferencedVarAttr::CreateImplicit(SemaRef.Context, OrigRef)); 977 } 978 return Decl; 979 } 980 981 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 982 SourceLocation Loc, 983 bool RefersToCapture = false) { 984 D->setReferenced(); 985 D->markUsed(S.Context); 986 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 987 SourceLocation(), D, RefersToCapture, Loc, Ty, 988 VK_LValue); 989 } 990 991 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 992 BinaryOperatorKind BOK) { 993 D = getCanonicalDecl(D); 994 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 995 assert( 996 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 997 "Additional reduction info may be specified only for reduction items."); 998 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 999 assert(ReductionData.ReductionRange.isInvalid() && 1000 Stack.back().first.back().Directive == OMPD_taskgroup && 1001 "Additional reduction info may be specified only once for reduction " 1002 "items."); 1003 ReductionData.set(BOK, SR); 1004 Expr *&TaskgroupReductionRef = 1005 Stack.back().first.back().TaskgroupReductionRef; 1006 if (!TaskgroupReductionRef) { 1007 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1008 SemaRef.Context.VoidPtrTy, ".task_red."); 1009 TaskgroupReductionRef = 1010 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1011 } 1012 } 1013 1014 void DSAStackTy::addTaskgroupReductionData(const ValueDecl *D, SourceRange SR, 1015 const Expr *ReductionRef) { 1016 D = getCanonicalDecl(D); 1017 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 1018 assert( 1019 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 1020 "Additional reduction info may be specified only for reduction items."); 1021 ReductionData &ReductionData = Stack.back().first.back().ReductionMap[D]; 1022 assert(ReductionData.ReductionRange.isInvalid() && 1023 Stack.back().first.back().Directive == OMPD_taskgroup && 1024 "Additional reduction info may be specified only once for reduction " 1025 "items."); 1026 ReductionData.set(ReductionRef, SR); 1027 Expr *&TaskgroupReductionRef = 1028 Stack.back().first.back().TaskgroupReductionRef; 1029 if (!TaskgroupReductionRef) { 1030 VarDecl *VD = buildVarDecl(SemaRef, SR.getBegin(), 1031 SemaRef.Context.VoidPtrTy, ".task_red."); 1032 TaskgroupReductionRef = 1033 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 1034 } 1035 } 1036 1037 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1038 const ValueDecl *D, SourceRange &SR, BinaryOperatorKind &BOK, 1039 Expr *&TaskgroupDescriptor) const { 1040 D = getCanonicalDecl(D); 1041 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 1042 if (Stack.back().first.empty()) 1043 return DSAVarData(); 1044 for (iterator I = std::next(Stack.back().first.rbegin(), 1), 1045 E = Stack.back().first.rend(); 1046 I != E; std::advance(I, 1)) { 1047 const DSAInfo &Data = I->SharingMap.lookup(D); 1048 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 1049 continue; 1050 const ReductionData &ReductionData = I->ReductionMap.lookup(D); 1051 if (!ReductionData.ReductionOp || 1052 ReductionData.ReductionOp.is<const Expr *>()) 1053 return DSAVarData(); 1054 SR = ReductionData.ReductionRange; 1055 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 1056 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 1057 "expression for the descriptor is not " 1058 "set."); 1059 TaskgroupDescriptor = I->TaskgroupReductionRef; 1060 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 1061 Data.PrivateCopy, I->DefaultAttrLoc); 1062 } 1063 return DSAVarData(); 1064 } 1065 1066 const DSAStackTy::DSAVarData DSAStackTy::getTopMostTaskgroupReductionData( 1067 const ValueDecl *D, SourceRange &SR, const Expr *&ReductionRef, 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 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 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 bool DSAStackTy::isOpenMPLocal(VarDecl *D, iterator Iter) const { 1096 D = D->getCanonicalDecl(); 1097 if (!isStackEmpty()) { 1098 iterator I = Iter, E = Stack.back().first.rend(); 1099 Scope *TopScope = nullptr; 1100 while (I != E && !isImplicitOrExplicitTaskingRegion(I->Directive) && 1101 !isOpenMPTargetExecutionDirective(I->Directive)) 1102 ++I; 1103 if (I == E) 1104 return false; 1105 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 1106 Scope *CurScope = getCurScope(); 1107 while (CurScope != TopScope && !CurScope->isDeclScope(D)) 1108 CurScope = CurScope->getParent(); 1109 return CurScope != TopScope; 1110 } 1111 return false; 1112 } 1113 1114 static bool isConstNotMutableType(Sema &SemaRef, QualType Type, 1115 bool AcceptIfMutable = true, 1116 bool *IsClassType = nullptr) { 1117 ASTContext &Context = SemaRef.getASTContext(); 1118 Type = Type.getNonReferenceType().getCanonicalType(); 1119 bool IsConstant = Type.isConstant(Context); 1120 Type = Context.getBaseElementType(Type); 1121 const CXXRecordDecl *RD = AcceptIfMutable && SemaRef.getLangOpts().CPlusPlus 1122 ? Type->getAsCXXRecordDecl() 1123 : nullptr; 1124 if (const auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1125 if (const ClassTemplateDecl *CTD = CTSD->getSpecializedTemplate()) 1126 RD = CTD->getTemplatedDecl(); 1127 if (IsClassType) 1128 *IsClassType = RD; 1129 return IsConstant && !(SemaRef.getLangOpts().CPlusPlus && RD && 1130 RD->hasDefinition() && RD->hasMutableFields()); 1131 } 1132 1133 static bool rejectConstNotMutableType(Sema &SemaRef, const ValueDecl *D, 1134 QualType Type, OpenMPClauseKind CKind, 1135 SourceLocation ELoc, 1136 bool AcceptIfMutable = true, 1137 bool ListItemNotVar = false) { 1138 ASTContext &Context = SemaRef.getASTContext(); 1139 bool IsClassType; 1140 if (isConstNotMutableType(SemaRef, Type, AcceptIfMutable, &IsClassType)) { 1141 unsigned Diag = ListItemNotVar 1142 ? diag::err_omp_const_list_item 1143 : IsClassType ? diag::err_omp_const_not_mutable_variable 1144 : diag::err_omp_const_variable; 1145 SemaRef.Diag(ELoc, Diag) << getOpenMPClauseName(CKind); 1146 if (!ListItemNotVar && D) { 1147 const VarDecl *VD = dyn_cast<VarDecl>(D); 1148 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 1149 VarDecl::DeclarationOnly; 1150 SemaRef.Diag(D->getLocation(), 1151 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1152 << D; 1153 } 1154 return true; 1155 } 1156 return false; 1157 } 1158 1159 const DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, 1160 bool FromParent) { 1161 D = getCanonicalDecl(D); 1162 DSAVarData DVar; 1163 1164 auto *VD = dyn_cast<VarDecl>(D); 1165 auto TI = Threadprivates.find(D); 1166 if (TI != Threadprivates.end()) { 1167 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 1168 DVar.CKind = OMPC_threadprivate; 1169 return DVar; 1170 } 1171 if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 1172 DVar.RefExpr = buildDeclRefExpr( 1173 SemaRef, VD, D->getType().getNonReferenceType(), 1174 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 1175 DVar.CKind = OMPC_threadprivate; 1176 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1177 return DVar; 1178 } 1179 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1180 // in a Construct, C/C++, predetermined, p.1] 1181 // Variables appearing in threadprivate directives are threadprivate. 1182 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 1183 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1184 SemaRef.getLangOpts().OpenMPUseTLS && 1185 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 1186 (VD && VD->getStorageClass() == SC_Register && 1187 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 1188 DVar.RefExpr = buildDeclRefExpr( 1189 SemaRef, VD, D->getType().getNonReferenceType(), D->getLocation()); 1190 DVar.CKind = OMPC_threadprivate; 1191 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 1192 return DVar; 1193 } 1194 if (SemaRef.getLangOpts().OpenMPCUDAMode && VD && 1195 VD->isLocalVarDeclOrParm() && !isStackEmpty() && 1196 !isLoopControlVariable(D).first) { 1197 iterator IterTarget = 1198 std::find_if(Stack.back().first.rbegin(), Stack.back().first.rend(), 1199 [](const SharingMapTy &Data) { 1200 return isOpenMPTargetExecutionDirective(Data.Directive); 1201 }); 1202 if (IterTarget != Stack.back().first.rend()) { 1203 iterator ParentIterTarget = std::next(IterTarget, 1); 1204 for (iterator Iter = Stack.back().first.rbegin(); 1205 Iter != ParentIterTarget; std::advance(Iter, 1)) { 1206 if (isOpenMPLocal(VD, Iter)) { 1207 DVar.RefExpr = 1208 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1209 D->getLocation()); 1210 DVar.CKind = OMPC_threadprivate; 1211 return DVar; 1212 } 1213 } 1214 if (!isClauseParsingMode() || IterTarget != Stack.back().first.rbegin()) { 1215 auto DSAIter = IterTarget->SharingMap.find(D); 1216 if (DSAIter != IterTarget->SharingMap.end() && 1217 isOpenMPPrivate(DSAIter->getSecond().Attributes)) { 1218 DVar.RefExpr = DSAIter->getSecond().RefExpr.getPointer(); 1219 DVar.CKind = OMPC_threadprivate; 1220 return DVar; 1221 } 1222 iterator End = Stack.back().first.rend(); 1223 if (!SemaRef.isOpenMPCapturedByRef( 1224 D, std::distance(ParentIterTarget, End))) { 1225 DVar.RefExpr = 1226 buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 1227 IterTarget->ConstructLoc); 1228 DVar.CKind = OMPC_threadprivate; 1229 return DVar; 1230 } 1231 } 1232 } 1233 } 1234 1235 if (isStackEmpty()) 1236 // Not in OpenMP execution region and top scope was already checked. 1237 return DVar; 1238 1239 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1240 // in a Construct, C/C++, predetermined, p.4] 1241 // Static data members are shared. 1242 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1243 // in a Construct, C/C++, predetermined, p.7] 1244 // Variables with static storage duration that are declared in a scope 1245 // inside the construct are shared. 1246 auto &&MatchesAlways = [](OpenMPDirectiveKind) { return true; }; 1247 if (VD && VD->isStaticDataMember()) { 1248 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 1249 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1250 return DVar; 1251 1252 DVar.CKind = OMPC_shared; 1253 return DVar; 1254 } 1255 1256 // The predetermined shared attribute for const-qualified types having no 1257 // mutable members was removed after OpenMP 3.1. 1258 if (SemaRef.LangOpts.OpenMP <= 31) { 1259 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1260 // in a Construct, C/C++, predetermined, p.6] 1261 // Variables with const qualified type having no mutable member are 1262 // shared. 1263 if (isConstNotMutableType(SemaRef, D->getType())) { 1264 // Variables with const-qualified type having no mutable member may be 1265 // listed in a firstprivate clause, even if they are static data members. 1266 DSAVarData DVarTemp = hasInnermostDSA( 1267 D, 1268 [](OpenMPClauseKind C) { 1269 return C == OMPC_firstprivate || C == OMPC_shared; 1270 }, 1271 MatchesAlways, FromParent); 1272 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1273 return DVarTemp; 1274 1275 DVar.CKind = OMPC_shared; 1276 return DVar; 1277 } 1278 } 1279 1280 // Explicitly specified attributes and local variables with predetermined 1281 // attributes. 1282 iterator I = Stack.back().first.rbegin(); 1283 iterator EndI = Stack.back().first.rend(); 1284 if (FromParent && I != EndI) 1285 std::advance(I, 1); 1286 auto It = I->SharingMap.find(D); 1287 if (It != I->SharingMap.end()) { 1288 const DSAInfo &Data = It->getSecond(); 1289 DVar.RefExpr = Data.RefExpr.getPointer(); 1290 DVar.PrivateCopy = Data.PrivateCopy; 1291 DVar.CKind = Data.Attributes; 1292 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1293 DVar.DKind = I->Directive; 1294 } 1295 1296 return DVar; 1297 } 1298 1299 const DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1300 bool FromParent) const { 1301 if (isStackEmpty()) { 1302 iterator I; 1303 return getDSA(I, D); 1304 } 1305 D = getCanonicalDecl(D); 1306 iterator StartI = Stack.back().first.rbegin(); 1307 iterator EndI = Stack.back().first.rend(); 1308 if (FromParent && StartI != EndI) 1309 std::advance(StartI, 1); 1310 return getDSA(StartI, D); 1311 } 1312 1313 const DSAStackTy::DSAVarData 1314 DSAStackTy::hasDSA(ValueDecl *D, 1315 const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1316 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1317 bool FromParent) const { 1318 if (isStackEmpty()) 1319 return {}; 1320 D = getCanonicalDecl(D); 1321 iterator I = Stack.back().first.rbegin(); 1322 iterator EndI = Stack.back().first.rend(); 1323 if (FromParent && I != EndI) 1324 std::advance(I, 1); 1325 for (; I != EndI; std::advance(I, 1)) { 1326 if (!DPred(I->Directive) && !isImplicitOrExplicitTaskingRegion(I->Directive)) 1327 continue; 1328 iterator NewI = I; 1329 DSAVarData DVar = getDSA(NewI, D); 1330 if (I == NewI && CPred(DVar.CKind)) 1331 return DVar; 1332 } 1333 return {}; 1334 } 1335 1336 const DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1337 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1338 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1339 bool FromParent) const { 1340 if (isStackEmpty()) 1341 return {}; 1342 D = getCanonicalDecl(D); 1343 iterator StartI = Stack.back().first.rbegin(); 1344 iterator EndI = Stack.back().first.rend(); 1345 if (FromParent && StartI != EndI) 1346 std::advance(StartI, 1); 1347 if (StartI == EndI || !DPred(StartI->Directive)) 1348 return {}; 1349 iterator NewI = StartI; 1350 DSAVarData DVar = getDSA(NewI, D); 1351 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1352 } 1353 1354 bool DSAStackTy::hasExplicitDSA( 1355 const ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> CPred, 1356 unsigned Level, bool NotLastprivate) const { 1357 if (isStackEmpty()) 1358 return false; 1359 D = getCanonicalDecl(D); 1360 auto StartI = Stack.back().first.begin(); 1361 auto EndI = Stack.back().first.end(); 1362 if (std::distance(StartI, EndI) <= (int)Level) 1363 return false; 1364 std::advance(StartI, Level); 1365 auto I = StartI->SharingMap.find(D); 1366 if ((I != StartI->SharingMap.end()) && 1367 I->getSecond().RefExpr.getPointer() && 1368 CPred(I->getSecond().Attributes) && 1369 (!NotLastprivate || !I->getSecond().RefExpr.getInt())) 1370 return true; 1371 // Check predetermined rules for the loop control variables. 1372 auto LI = StartI->LCVMap.find(D); 1373 if (LI != StartI->LCVMap.end()) 1374 return CPred(OMPC_private); 1375 return false; 1376 } 1377 1378 bool DSAStackTy::hasExplicitDirective( 1379 const llvm::function_ref<bool(OpenMPDirectiveKind)> DPred, 1380 unsigned Level) const { 1381 if (isStackEmpty()) 1382 return false; 1383 auto StartI = Stack.back().first.begin(); 1384 auto EndI = Stack.back().first.end(); 1385 if (std::distance(StartI, EndI) <= (int)Level) 1386 return false; 1387 std::advance(StartI, Level); 1388 return DPred(StartI->Directive); 1389 } 1390 1391 bool DSAStackTy::hasDirective( 1392 const llvm::function_ref<bool(OpenMPDirectiveKind, 1393 const DeclarationNameInfo &, SourceLocation)> 1394 DPred, 1395 bool FromParent) const { 1396 // We look only in the enclosing region. 1397 if (isStackEmpty()) 1398 return false; 1399 auto StartI = std::next(Stack.back().first.rbegin()); 1400 auto EndI = Stack.back().first.rend(); 1401 if (FromParent && StartI != EndI) 1402 StartI = std::next(StartI); 1403 for (auto I = StartI, EE = EndI; I != EE; ++I) { 1404 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1405 return true; 1406 } 1407 return false; 1408 } 1409 1410 void Sema::InitDataSharingAttributesStack() { 1411 VarDataSharingAttributesStack = new DSAStackTy(*this); 1412 } 1413 1414 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1415 1416 void Sema::pushOpenMPFunctionRegion() { 1417 DSAStack->pushFunction(); 1418 } 1419 1420 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1421 DSAStack->popFunction(OldFSI); 1422 } 1423 1424 static bool isOpenMPDeviceDelayedContext(Sema &S) { 1425 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1426 "Expected OpenMP device compilation."); 1427 return !S.isInOpenMPTargetExecutionDirective() && 1428 !S.isInOpenMPDeclareTargetContext(); 1429 } 1430 1431 /// Do we know that we will eventually codegen the given function? 1432 static bool isKnownEmitted(Sema &S, FunctionDecl *FD) { 1433 assert(S.LangOpts.OpenMP && S.LangOpts.OpenMPIsDevice && 1434 "Expected OpenMP device compilation."); 1435 // Templates are emitted when they're instantiated. 1436 if (FD->isDependentContext()) 1437 return false; 1438 1439 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 1440 FD->getCanonicalDecl())) 1441 return true; 1442 1443 // Otherwise, the function is known-emitted if it's in our set of 1444 // known-emitted functions. 1445 return S.DeviceKnownEmittedFns.count(FD) > 0; 1446 } 1447 1448 Sema::DeviceDiagBuilder Sema::diagIfOpenMPDeviceCode(SourceLocation Loc, 1449 unsigned DiagID) { 1450 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1451 "Expected OpenMP device compilation."); 1452 return DeviceDiagBuilder((isOpenMPDeviceDelayedContext(*this) && 1453 !isKnownEmitted(*this, getCurFunctionDecl())) 1454 ? DeviceDiagBuilder::K_Deferred 1455 : DeviceDiagBuilder::K_Immediate, 1456 Loc, DiagID, getCurFunctionDecl(), *this); 1457 } 1458 1459 void Sema::checkOpenMPDeviceFunction(SourceLocation Loc, FunctionDecl *Callee) { 1460 assert(LangOpts.OpenMP && LangOpts.OpenMPIsDevice && 1461 "Expected OpenMP device compilation."); 1462 assert(Callee && "Callee may not be null."); 1463 FunctionDecl *Caller = getCurFunctionDecl(); 1464 1465 // If the caller is known-emitted, mark the callee as known-emitted. 1466 // Otherwise, mark the call in our call graph so we can traverse it later. 1467 if (!isOpenMPDeviceDelayedContext(*this) || 1468 (Caller && isKnownEmitted(*this, Caller))) 1469 markKnownEmitted(*this, Caller, Callee, Loc, isKnownEmitted); 1470 else if (Caller) 1471 DeviceCallGraph[Caller].insert({Callee, Loc}); 1472 } 1473 1474 void Sema::checkOpenMPDeviceExpr(const Expr *E) { 1475 assert(getLangOpts().OpenMP && getLangOpts().OpenMPIsDevice && 1476 "OpenMP device compilation mode is expected."); 1477 QualType Ty = E->getType(); 1478 if ((Ty->isFloat16Type() && !Context.getTargetInfo().hasFloat16Type()) || 1479 (Ty->isFloat128Type() && !Context.getTargetInfo().hasFloat128Type()) || 1480 (Ty->isIntegerType() && Context.getTypeSize(Ty) == 128 && 1481 !Context.getTargetInfo().hasInt128Type())) 1482 targetDiag(E->getExprLoc(), diag::err_type_unsupported) 1483 << Ty << E->getSourceRange(); 1484 } 1485 1486 bool Sema::isOpenMPCapturedByRef(const ValueDecl *D, unsigned Level) const { 1487 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1488 1489 ASTContext &Ctx = getASTContext(); 1490 bool IsByRef = true; 1491 1492 // Find the directive that is associated with the provided scope. 1493 D = cast<ValueDecl>(D->getCanonicalDecl()); 1494 QualType Ty = D->getType(); 1495 1496 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1497 // This table summarizes how a given variable should be passed to the device 1498 // given its type and the clauses where it appears. This table is based on 1499 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1500 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1501 // 1502 // ========================================================================= 1503 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1504 // | |(tofrom:scalar)| | pvt | | | | 1505 // ========================================================================= 1506 // | scl | | | | - | | bycopy| 1507 // | scl | | - | x | - | - | bycopy| 1508 // | scl | | x | - | - | - | null | 1509 // | scl | x | | | - | | byref | 1510 // | scl | x | - | x | - | - | bycopy| 1511 // | scl | x | x | - | - | - | null | 1512 // | scl | | - | - | - | x | byref | 1513 // | scl | x | - | - | - | x | byref | 1514 // 1515 // | agg | n.a. | | | - | | byref | 1516 // | agg | n.a. | - | x | - | - | byref | 1517 // | agg | n.a. | x | - | - | - | null | 1518 // | agg | n.a. | - | - | - | x | byref | 1519 // | agg | n.a. | - | - | - | x[] | byref | 1520 // 1521 // | ptr | n.a. | | | - | | bycopy| 1522 // | ptr | n.a. | - | x | - | - | bycopy| 1523 // | ptr | n.a. | x | - | - | - | null | 1524 // | ptr | n.a. | - | - | - | x | byref | 1525 // | ptr | n.a. | - | - | - | x[] | bycopy| 1526 // | ptr | n.a. | - | - | x | | bycopy| 1527 // | ptr | n.a. | - | - | x | x | bycopy| 1528 // | ptr | n.a. | - | - | x | x[] | bycopy| 1529 // ========================================================================= 1530 // Legend: 1531 // scl - scalar 1532 // ptr - pointer 1533 // agg - aggregate 1534 // x - applies 1535 // - - invalid in this combination 1536 // [] - mapped with an array section 1537 // byref - should be mapped by reference 1538 // byval - should be mapped by value 1539 // null - initialize a local variable to null on the device 1540 // 1541 // Observations: 1542 // - All scalar declarations that show up in a map clause have to be passed 1543 // by reference, because they may have been mapped in the enclosing data 1544 // environment. 1545 // - If the scalar value does not fit the size of uintptr, it has to be 1546 // passed by reference, regardless the result in the table above. 1547 // - For pointers mapped by value that have either an implicit map or an 1548 // array section, the runtime library may pass the NULL value to the 1549 // device instead of the value passed to it by the compiler. 1550 1551 if (Ty->isReferenceType()) 1552 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1553 1554 // Locate map clauses and see if the variable being captured is referred to 1555 // in any of those clauses. Here we only care about variables, not fields, 1556 // because fields are part of aggregates. 1557 bool IsVariableUsedInMapClause = false; 1558 bool IsVariableAssociatedWithSection = false; 1559 1560 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1561 D, Level, 1562 [&IsVariableUsedInMapClause, &IsVariableAssociatedWithSection, D]( 1563 OMPClauseMappableExprCommon::MappableExprComponentListRef 1564 MapExprComponents, 1565 OpenMPClauseKind WhereFoundClauseKind) { 1566 // Only the map clause information influences how a variable is 1567 // captured. E.g. is_device_ptr does not require changing the default 1568 // behavior. 1569 if (WhereFoundClauseKind != OMPC_map) 1570 return false; 1571 1572 auto EI = MapExprComponents.rbegin(); 1573 auto EE = MapExprComponents.rend(); 1574 1575 assert(EI != EE && "Invalid map expression!"); 1576 1577 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1578 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1579 1580 ++EI; 1581 if (EI == EE) 1582 return false; 1583 1584 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1585 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1586 isa<MemberExpr>(EI->getAssociatedExpression())) { 1587 IsVariableAssociatedWithSection = true; 1588 // There is nothing more we need to know about this variable. 1589 return true; 1590 } 1591 1592 // Keep looking for more map info. 1593 return false; 1594 }); 1595 1596 if (IsVariableUsedInMapClause) { 1597 // If variable is identified in a map clause it is always captured by 1598 // reference except if it is a pointer that is dereferenced somehow. 1599 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1600 } else { 1601 // By default, all the data that has a scalar type is mapped by copy 1602 // (except for reduction variables). 1603 IsByRef = 1604 (DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1605 !Ty->isAnyPointerType()) || 1606 !Ty->isScalarType() || 1607 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1608 DSAStack->hasExplicitDSA( 1609 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1610 } 1611 } 1612 1613 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1614 IsByRef = 1615 ((DSAStack->isForceCaptureByReferenceInTargetExecutable() && 1616 !Ty->isAnyPointerType()) || 1617 !DSAStack->hasExplicitDSA( 1618 D, 1619 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1620 Level, /*NotLastprivate=*/true)) && 1621 // If the variable is artificial and must be captured by value - try to 1622 // capture by value. 1623 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1624 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1625 } 1626 1627 // When passing data by copy, we need to make sure it fits the uintptr size 1628 // and alignment, because the runtime library only deals with uintptr types. 1629 // If it does not fit the uintptr size, we need to pass the data by reference 1630 // instead. 1631 if (!IsByRef && 1632 (Ctx.getTypeSizeInChars(Ty) > 1633 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1634 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1635 IsByRef = true; 1636 } 1637 1638 return IsByRef; 1639 } 1640 1641 unsigned Sema::getOpenMPNestingLevel() const { 1642 assert(getLangOpts().OpenMP); 1643 return DSAStack->getNestingLevel(); 1644 } 1645 1646 bool Sema::isInOpenMPTargetExecutionDirective() const { 1647 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1648 !DSAStack->isClauseParsingMode()) || 1649 DSAStack->hasDirective( 1650 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1651 SourceLocation) -> bool { 1652 return isOpenMPTargetExecutionDirective(K); 1653 }, 1654 false); 1655 } 1656 1657 VarDecl *Sema::isOpenMPCapturedDecl(ValueDecl *D) { 1658 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1659 D = getCanonicalDecl(D); 1660 1661 // If we are attempting to capture a global variable in a directive with 1662 // 'target' we return true so that this global is also mapped to the device. 1663 // 1664 auto *VD = dyn_cast<VarDecl>(D); 1665 if (VD && !VD->hasLocalStorage()) { 1666 if (isInOpenMPDeclareTargetContext() && 1667 (getCurCapturedRegion() || getCurBlock() || getCurLambda())) { 1668 // Try to mark variable as declare target if it is used in capturing 1669 // regions. 1670 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1671 checkDeclIsAllowedInOpenMPTarget(nullptr, VD); 1672 return nullptr; 1673 } else if (isInOpenMPTargetExecutionDirective()) { 1674 // If the declaration is enclosed in a 'declare target' directive, 1675 // then it should not be captured. 1676 // 1677 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 1678 return nullptr; 1679 return VD; 1680 } 1681 } 1682 // Capture variables captured by reference in lambdas for target-based 1683 // directives. 1684 if (VD && !DSAStack->isClauseParsingMode()) { 1685 if (const auto *RD = VD->getType() 1686 .getCanonicalType() 1687 .getNonReferenceType() 1688 ->getAsCXXRecordDecl()) { 1689 bool SavedForceCaptureByReferenceInTargetExecutable = 1690 DSAStack->isForceCaptureByReferenceInTargetExecutable(); 1691 DSAStack->setForceCaptureByReferenceInTargetExecutable(/*V=*/true); 1692 if (RD->isLambda()) { 1693 llvm::DenseMap<const VarDecl *, FieldDecl *> Captures; 1694 FieldDecl *ThisCapture; 1695 RD->getCaptureFields(Captures, ThisCapture); 1696 for (const LambdaCapture &LC : RD->captures()) { 1697 if (LC.getCaptureKind() == LCK_ByRef) { 1698 VarDecl *VD = LC.getCapturedVar(); 1699 DeclContext *VDC = VD->getDeclContext(); 1700 if (!VDC->Encloses(CurContext)) 1701 continue; 1702 DSAStackTy::DSAVarData DVarPrivate = 1703 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1704 // Do not capture already captured variables. 1705 if (!OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD) && 1706 DVarPrivate.CKind == OMPC_unknown && 1707 !DSAStack->checkMappableExprComponentListsForDecl( 1708 D, /*CurrentRegionOnly=*/true, 1709 [](OMPClauseMappableExprCommon:: 1710 MappableExprComponentListRef, 1711 OpenMPClauseKind) { return true; })) 1712 MarkVariableReferenced(LC.getLocation(), LC.getCapturedVar()); 1713 } else if (LC.getCaptureKind() == LCK_This) { 1714 QualType ThisTy = getCurrentThisType(); 1715 if (!ThisTy.isNull() && 1716 Context.typesAreCompatible(ThisTy, ThisCapture->getType())) 1717 CheckCXXThisCapture(LC.getLocation()); 1718 } 1719 } 1720 } 1721 DSAStack->setForceCaptureByReferenceInTargetExecutable( 1722 SavedForceCaptureByReferenceInTargetExecutable); 1723 } 1724 } 1725 1726 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1727 (!DSAStack->isClauseParsingMode() || 1728 DSAStack->getParentDirective() != OMPD_unknown)) { 1729 auto &&Info = DSAStack->isLoopControlVariable(D); 1730 if (Info.first || 1731 (VD && VD->hasLocalStorage() && 1732 isImplicitOrExplicitTaskingRegion(DSAStack->getCurrentDirective())) || 1733 (VD && DSAStack->isForceVarCapturing())) 1734 return VD ? VD : Info.second; 1735 DSAStackTy::DSAVarData DVarPrivate = 1736 DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1737 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1738 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1739 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, 1740 [](OpenMPDirectiveKind) { return true; }, 1741 DSAStack->isClauseParsingMode()); 1742 if (DVarPrivate.CKind != OMPC_unknown) 1743 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1744 } 1745 return nullptr; 1746 } 1747 1748 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1749 unsigned Level) const { 1750 SmallVector<OpenMPDirectiveKind, 4> Regions; 1751 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1752 FunctionScopesIndex -= Regions.size(); 1753 } 1754 1755 void Sema::startOpenMPLoop() { 1756 assert(LangOpts.OpenMP && "OpenMP must be enabled."); 1757 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) 1758 DSAStack->loopInit(); 1759 } 1760 1761 bool Sema::isOpenMPPrivateDecl(const ValueDecl *D, unsigned Level) const { 1762 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1763 if (isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 1764 if (DSAStack->getAssociatedLoops() > 0 && 1765 !DSAStack->isLoopStarted()) { 1766 DSAStack->resetPossibleLoopCounter(D); 1767 DSAStack->loopStart(); 1768 return true; 1769 } 1770 if ((DSAStack->getPossiblyLoopCunter() == D->getCanonicalDecl() || 1771 DSAStack->isLoopControlVariable(D).first) && 1772 !DSAStack->hasExplicitDSA( 1773 D, [](OpenMPClauseKind K) { return K != OMPC_private; }, Level) && 1774 !isOpenMPSimdDirective(DSAStack->getCurrentDirective())) 1775 return true; 1776 } 1777 return DSAStack->hasExplicitDSA( 1778 D, [](OpenMPClauseKind K) { return K == OMPC_private; }, Level) || 1779 (DSAStack->isClauseParsingMode() && 1780 DSAStack->getClauseParsingMode() == OMPC_private) || 1781 // Consider taskgroup reduction descriptor variable a private to avoid 1782 // possible capture in the region. 1783 (DSAStack->hasExplicitDirective( 1784 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1785 Level) && 1786 DSAStack->isTaskgroupReductionRef(D, Level)); 1787 } 1788 1789 void Sema::setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, 1790 unsigned Level) { 1791 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1792 D = getCanonicalDecl(D); 1793 OpenMPClauseKind OMPC = OMPC_unknown; 1794 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1795 const unsigned NewLevel = I - 1; 1796 if (DSAStack->hasExplicitDSA(D, 1797 [&OMPC](const OpenMPClauseKind K) { 1798 if (isOpenMPPrivate(K)) { 1799 OMPC = K; 1800 return true; 1801 } 1802 return false; 1803 }, 1804 NewLevel)) 1805 break; 1806 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1807 D, NewLevel, 1808 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1809 OpenMPClauseKind) { return true; })) { 1810 OMPC = OMPC_map; 1811 break; 1812 } 1813 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1814 NewLevel)) { 1815 OMPC = OMPC_map; 1816 if (D->getType()->isScalarType() && 1817 DSAStack->getDefaultDMAAtLevel(NewLevel) != 1818 DefaultMapAttributes::DMA_tofrom_scalar) 1819 OMPC = OMPC_firstprivate; 1820 break; 1821 } 1822 } 1823 if (OMPC != OMPC_unknown) 1824 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1825 } 1826 1827 bool Sema::isOpenMPTargetCapturedDecl(const ValueDecl *D, 1828 unsigned Level) const { 1829 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1830 // Return true if the current level is no longer enclosed in a target region. 1831 1832 const auto *VD = dyn_cast<VarDecl>(D); 1833 return VD && !VD->hasLocalStorage() && 1834 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1835 Level); 1836 } 1837 1838 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1839 1840 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1841 const DeclarationNameInfo &DirName, 1842 Scope *CurScope, SourceLocation Loc) { 1843 DSAStack->push(DKind, DirName, CurScope, Loc); 1844 PushExpressionEvaluationContext( 1845 ExpressionEvaluationContext::PotentiallyEvaluated); 1846 } 1847 1848 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1849 DSAStack->setClauseParsingMode(K); 1850 } 1851 1852 void Sema::EndOpenMPClause() { 1853 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1854 } 1855 1856 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1857 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1858 // A variable of class type (or array thereof) that appears in a lastprivate 1859 // clause requires an accessible, unambiguous default constructor for the 1860 // class type, unless the list item is also specified in a firstprivate 1861 // clause. 1862 if (const auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1863 for (OMPClause *C : D->clauses()) { 1864 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1865 SmallVector<Expr *, 8> PrivateCopies; 1866 for (Expr *DE : Clause->varlists()) { 1867 if (DE->isValueDependent() || DE->isTypeDependent()) { 1868 PrivateCopies.push_back(nullptr); 1869 continue; 1870 } 1871 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1872 auto *VD = cast<VarDecl>(DRE->getDecl()); 1873 QualType Type = VD->getType().getNonReferenceType(); 1874 const DSAStackTy::DSAVarData DVar = 1875 DSAStack->getTopDSA(VD, /*FromParent=*/false); 1876 if (DVar.CKind == OMPC_lastprivate) { 1877 // Generate helper private variable and initialize it with the 1878 // default value. The address of the original variable is replaced 1879 // by the address of the new private variable in CodeGen. This new 1880 // variable is not added to IdResolver, so the code in the OpenMP 1881 // region uses original variable for proper diagnostics. 1882 VarDecl *VDPrivate = buildVarDecl( 1883 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1884 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr, DRE); 1885 ActOnUninitializedDecl(VDPrivate); 1886 if (VDPrivate->isInvalidDecl()) 1887 continue; 1888 PrivateCopies.push_back(buildDeclRefExpr( 1889 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1890 } else { 1891 // The variable is also a firstprivate, so initialization sequence 1892 // for private copy is generated already. 1893 PrivateCopies.push_back(nullptr); 1894 } 1895 } 1896 // Set initializers to private copies if no errors were found. 1897 if (PrivateCopies.size() == Clause->varlist_size()) 1898 Clause->setPrivateCopies(PrivateCopies); 1899 } 1900 } 1901 } 1902 1903 DSAStack->pop(); 1904 DiscardCleanupsInEvaluationContext(); 1905 PopExpressionEvaluationContext(); 1906 } 1907 1908 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1909 Expr *NumIterations, Sema &SemaRef, 1910 Scope *S, DSAStackTy *Stack); 1911 1912 namespace { 1913 1914 class VarDeclFilterCCC final : public CorrectionCandidateCallback { 1915 private: 1916 Sema &SemaRef; 1917 1918 public: 1919 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1920 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1921 NamedDecl *ND = Candidate.getCorrectionDecl(); 1922 if (const auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 1923 return VD->hasGlobalStorage() && 1924 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1925 SemaRef.getCurScope()); 1926 } 1927 return false; 1928 } 1929 }; 1930 1931 class VarOrFuncDeclFilterCCC final : public CorrectionCandidateCallback { 1932 private: 1933 Sema &SemaRef; 1934 1935 public: 1936 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 1937 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1938 NamedDecl *ND = Candidate.getCorrectionDecl(); 1939 if (ND && ((isa<VarDecl>(ND) && ND->getKind() == Decl::Var) || 1940 isa<FunctionDecl>(ND))) { 1941 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1942 SemaRef.getCurScope()); 1943 } 1944 return false; 1945 } 1946 }; 1947 1948 } // namespace 1949 1950 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 1951 CXXScopeSpec &ScopeSpec, 1952 const DeclarationNameInfo &Id, 1953 OpenMPDirectiveKind Kind) { 1954 LookupResult Lookup(*this, Id, LookupOrdinaryName); 1955 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 1956 1957 if (Lookup.isAmbiguous()) 1958 return ExprError(); 1959 1960 VarDecl *VD; 1961 if (!Lookup.isSingleResult()) { 1962 if (TypoCorrection Corrected = CorrectTypo( 1963 Id, LookupOrdinaryName, CurScope, nullptr, 1964 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 1965 diagnoseTypo(Corrected, 1966 PDiag(Lookup.empty() 1967 ? diag::err_undeclared_var_use_suggest 1968 : diag::err_omp_expected_var_arg_suggest) 1969 << Id.getName()); 1970 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 1971 } else { 1972 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 1973 : diag::err_omp_expected_var_arg) 1974 << Id.getName(); 1975 return ExprError(); 1976 } 1977 } else if (!(VD = Lookup.getAsSingle<VarDecl>())) { 1978 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 1979 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 1980 return ExprError(); 1981 } 1982 Lookup.suppressDiagnostics(); 1983 1984 // OpenMP [2.9.2, Syntax, C/C++] 1985 // Variables must be file-scope, namespace-scope, or static block-scope. 1986 if (Kind == OMPD_threadprivate && !VD->hasGlobalStorage()) { 1987 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 1988 << getOpenMPDirectiveName(Kind) << !VD->isStaticLocal(); 1989 bool IsDecl = 1990 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1991 Diag(VD->getLocation(), 1992 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1993 << VD; 1994 return ExprError(); 1995 } 1996 1997 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 1998 NamedDecl *ND = CanonicalVD; 1999 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 2000 // A threadprivate directive for file-scope variables must appear outside 2001 // any definition or declaration. 2002 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 2003 !getCurLexicalContext()->isTranslationUnit()) { 2004 Diag(Id.getLoc(), diag::err_omp_var_scope) 2005 << getOpenMPDirectiveName(Kind) << VD; 2006 bool IsDecl = 2007 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2008 Diag(VD->getLocation(), 2009 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2010 << VD; 2011 return ExprError(); 2012 } 2013 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 2014 // A threadprivate directive for static class member variables must appear 2015 // in the class definition, in the same scope in which the member 2016 // variables are declared. 2017 if (CanonicalVD->isStaticDataMember() && 2018 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 2019 Diag(Id.getLoc(), diag::err_omp_var_scope) 2020 << getOpenMPDirectiveName(Kind) << VD; 2021 bool IsDecl = 2022 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2023 Diag(VD->getLocation(), 2024 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2025 << VD; 2026 return ExprError(); 2027 } 2028 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 2029 // A threadprivate directive for namespace-scope variables must appear 2030 // outside any definition or declaration other than the namespace 2031 // definition itself. 2032 if (CanonicalVD->getDeclContext()->isNamespace() && 2033 (!getCurLexicalContext()->isFileContext() || 2034 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 2035 Diag(Id.getLoc(), diag::err_omp_var_scope) 2036 << getOpenMPDirectiveName(Kind) << VD; 2037 bool IsDecl = 2038 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2039 Diag(VD->getLocation(), 2040 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2041 << VD; 2042 return ExprError(); 2043 } 2044 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 2045 // A threadprivate directive for static block-scope variables must appear 2046 // in the scope of the variable and not in a nested scope. 2047 if (CanonicalVD->isLocalVarDecl() && CurScope && 2048 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 2049 Diag(Id.getLoc(), diag::err_omp_var_scope) 2050 << getOpenMPDirectiveName(Kind) << VD; 2051 bool IsDecl = 2052 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2053 Diag(VD->getLocation(), 2054 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2055 << VD; 2056 return ExprError(); 2057 } 2058 2059 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 2060 // A threadprivate directive must lexically precede all references to any 2061 // of the variables in its list. 2062 if (Kind == OMPD_threadprivate && VD->isUsed() && 2063 !DSAStack->isThreadPrivate(VD)) { 2064 Diag(Id.getLoc(), diag::err_omp_var_used) 2065 << getOpenMPDirectiveName(Kind) << VD; 2066 return ExprError(); 2067 } 2068 2069 QualType ExprType = VD->getType().getNonReferenceType(); 2070 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 2071 SourceLocation(), VD, 2072 /*RefersToEnclosingVariableOrCapture=*/false, 2073 Id.getLoc(), ExprType, VK_LValue); 2074 } 2075 2076 Sema::DeclGroupPtrTy 2077 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 2078 ArrayRef<Expr *> VarList) { 2079 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 2080 CurContext->addDecl(D); 2081 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2082 } 2083 return nullptr; 2084 } 2085 2086 namespace { 2087 class LocalVarRefChecker final 2088 : public ConstStmtVisitor<LocalVarRefChecker, bool> { 2089 Sema &SemaRef; 2090 2091 public: 2092 bool VisitDeclRefExpr(const DeclRefExpr *E) { 2093 if (const auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2094 if (VD->hasLocalStorage()) { 2095 SemaRef.Diag(E->getBeginLoc(), 2096 diag::err_omp_local_var_in_threadprivate_init) 2097 << E->getSourceRange(); 2098 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 2099 << VD << VD->getSourceRange(); 2100 return true; 2101 } 2102 } 2103 return false; 2104 } 2105 bool VisitStmt(const Stmt *S) { 2106 for (const Stmt *Child : S->children()) { 2107 if (Child && Visit(Child)) 2108 return true; 2109 } 2110 return false; 2111 } 2112 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 2113 }; 2114 } // namespace 2115 2116 OMPThreadPrivateDecl * 2117 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 2118 SmallVector<Expr *, 8> Vars; 2119 for (Expr *RefExpr : VarList) { 2120 auto *DE = cast<DeclRefExpr>(RefExpr); 2121 auto *VD = cast<VarDecl>(DE->getDecl()); 2122 SourceLocation ILoc = DE->getExprLoc(); 2123 2124 // Mark variable as used. 2125 VD->setReferenced(); 2126 VD->markUsed(Context); 2127 2128 QualType QType = VD->getType(); 2129 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 2130 // It will be analyzed later. 2131 Vars.push_back(DE); 2132 continue; 2133 } 2134 2135 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2136 // A threadprivate variable must not have an incomplete type. 2137 if (RequireCompleteType(ILoc, VD->getType(), 2138 diag::err_omp_threadprivate_incomplete_type)) { 2139 continue; 2140 } 2141 2142 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 2143 // A threadprivate variable must not have a reference type. 2144 if (VD->getType()->isReferenceType()) { 2145 Diag(ILoc, diag::err_omp_ref_type_arg) 2146 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 2147 bool IsDecl = 2148 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2149 Diag(VD->getLocation(), 2150 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2151 << VD; 2152 continue; 2153 } 2154 2155 // Check if this is a TLS variable. If TLS is not being supported, produce 2156 // the corresponding diagnostic. 2157 if ((VD->getTLSKind() != VarDecl::TLS_None && 2158 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 2159 getLangOpts().OpenMPUseTLS && 2160 getASTContext().getTargetInfo().isTLSSupported())) || 2161 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2162 !VD->isLocalVarDecl())) { 2163 Diag(ILoc, diag::err_omp_var_thread_local) 2164 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 2165 bool IsDecl = 2166 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 2167 Diag(VD->getLocation(), 2168 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2169 << VD; 2170 continue; 2171 } 2172 2173 // Check if initial value of threadprivate variable reference variable with 2174 // local storage (it is not supported by runtime). 2175 if (const Expr *Init = VD->getAnyInitializer()) { 2176 LocalVarRefChecker Checker(*this); 2177 if (Checker.Visit(Init)) 2178 continue; 2179 } 2180 2181 Vars.push_back(RefExpr); 2182 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 2183 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 2184 Context, SourceRange(Loc, Loc))); 2185 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2186 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 2187 } 2188 OMPThreadPrivateDecl *D = nullptr; 2189 if (!Vars.empty()) { 2190 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 2191 Vars); 2192 D->setAccess(AS_public); 2193 } 2194 return D; 2195 } 2196 2197 Sema::DeclGroupPtrTy Sema::ActOnOpenMPAllocateDirective( 2198 SourceLocation Loc, ArrayRef<Expr *> VarList, 2199 ArrayRef<OMPClause *> Clauses, DeclContext *Owner) { 2200 assert(Clauses.size() <= 1 && "Expected at most one clause."); 2201 Expr *Allocator = nullptr; 2202 if (!Clauses.empty()) 2203 Allocator = cast<OMPAllocatorClause>(Clauses.back())->getAllocator(); 2204 SmallVector<Expr *, 8> Vars; 2205 for (Expr *RefExpr : VarList) { 2206 auto *DE = cast<DeclRefExpr>(RefExpr); 2207 auto *VD = cast<VarDecl>(DE->getDecl()); 2208 2209 // Check if this is a TLS variable or global register. 2210 if (VD->getTLSKind() != VarDecl::TLS_None || 2211 VD->hasAttr<OMPThreadPrivateDeclAttr>() || 2212 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 2213 !VD->isLocalVarDecl())) 2214 continue; 2215 // Do not apply for parameters. 2216 if (isa<ParmVarDecl>(VD)) 2217 continue; 2218 2219 // If the used several times in the allocate directive, the same allocator 2220 // must be used. 2221 if (VD->hasAttr<OMPAllocateDeclAttr>()) { 2222 const auto *A = VD->getAttr<OMPAllocateDeclAttr>(); 2223 const Expr *PrevAllocator = A->getAllocator(); 2224 bool AllocatorsMatch = false; 2225 if (Allocator && PrevAllocator) { 2226 const Expr *AE = Allocator->IgnoreParenImpCasts(); 2227 const Expr *PAE = PrevAllocator->IgnoreParenImpCasts(); 2228 llvm::FoldingSetNodeID AEId, PAEId; 2229 AE->Profile(AEId, Context, /*Canonical=*/true); 2230 PAE->Profile(PAEId, Context, /*Canonical=*/true); 2231 AllocatorsMatch = AEId == PAEId; 2232 } else if (!Allocator && !PrevAllocator) { 2233 AllocatorsMatch = true; 2234 } else { 2235 const Expr *AE = Allocator ? Allocator : PrevAllocator; 2236 // In this case the specified allocator must be the default one. 2237 AE = AE->IgnoreParenImpCasts(); 2238 if (const auto *DRE = dyn_cast<DeclRefExpr>(AE)) { 2239 DeclarationName DN = DRE->getDecl()->getDeclName(); 2240 AllocatorsMatch = 2241 DN.isIdentifier() && 2242 DN.getAsIdentifierInfo()->isStr("omp_default_mem_alloc"); 2243 } 2244 } 2245 if (!AllocatorsMatch) { 2246 SmallString<256> AllocatorBuffer; 2247 llvm::raw_svector_ostream AllocatorStream(AllocatorBuffer); 2248 if (Allocator) 2249 Allocator->printPretty(AllocatorStream, nullptr, getPrintingPolicy()); 2250 SmallString<256> PrevAllocatorBuffer; 2251 llvm::raw_svector_ostream PrevAllocatorStream(PrevAllocatorBuffer); 2252 if (PrevAllocator) 2253 PrevAllocator->printPretty(PrevAllocatorStream, nullptr, 2254 getPrintingPolicy()); 2255 2256 SourceLocation AllocatorLoc = 2257 Allocator ? Allocator->getExprLoc() : RefExpr->getExprLoc(); 2258 SourceRange AllocatorRange = 2259 Allocator ? Allocator->getSourceRange() : RefExpr->getSourceRange(); 2260 SourceLocation PrevAllocatorLoc = 2261 PrevAllocator ? PrevAllocator->getExprLoc() : A->getLocation(); 2262 SourceRange PrevAllocatorRange = 2263 PrevAllocator ? PrevAllocator->getSourceRange() : A->getRange(); 2264 Diag(AllocatorLoc, diag::warn_omp_used_different_allocator) 2265 << (Allocator ? 1 : 0) << AllocatorStream.str() 2266 << (PrevAllocator ? 1 : 0) << PrevAllocatorStream.str() 2267 << AllocatorRange; 2268 Diag(PrevAllocatorLoc, diag::note_omp_previous_allocator) 2269 << PrevAllocatorRange; 2270 continue; 2271 } 2272 } 2273 2274 // OpenMP, 2.11.3 allocate Directive, Restrictions, C / C++ 2275 // If a list item has a static storage type, the allocator expression in the 2276 // allocator clause must be a constant expression that evaluates to one of 2277 // the predefined memory allocator values. 2278 if (Allocator && VD->hasGlobalStorage()) { 2279 bool IsPredefinedAllocator = false; 2280 if (const auto *DRE = 2281 dyn_cast<DeclRefExpr>(Allocator->IgnoreParenImpCasts())) { 2282 if (DRE->getType().isConstant(getASTContext())) { 2283 DeclarationName DN = DRE->getDecl()->getDeclName(); 2284 if (DN.isIdentifier()) { 2285 StringRef PredefinedAllocators[] = { 2286 "omp_default_mem_alloc", "omp_large_cap_mem_alloc", 2287 "omp_const_mem_alloc", "omp_high_bw_mem_alloc", 2288 "omp_low_lat_mem_alloc", "omp_cgroup_mem_alloc", 2289 "omp_pteam_mem_alloc", "omp_thread_mem_alloc", 2290 }; 2291 IsPredefinedAllocator = 2292 llvm::any_of(PredefinedAllocators, [&DN](StringRef S) { 2293 return DN.getAsIdentifierInfo()->isStr(S); 2294 }); 2295 } 2296 } 2297 } 2298 if (!IsPredefinedAllocator) { 2299 Diag(Allocator->getExprLoc(), 2300 diag::err_omp_expected_predefined_allocator) 2301 << Allocator->getSourceRange(); 2302 bool IsDecl = VD->isThisDeclarationADefinition(Context) == 2303 VarDecl::DeclarationOnly; 2304 Diag(VD->getLocation(), 2305 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 2306 << VD; 2307 continue; 2308 } 2309 } 2310 2311 Vars.push_back(RefExpr); 2312 if ((!Allocator || (Allocator && !Allocator->isTypeDependent() && 2313 !Allocator->isValueDependent() && 2314 !Allocator->isInstantiationDependent() && 2315 !Allocator->containsUnexpandedParameterPack())) && 2316 !VD->hasAttr<OMPAllocateDeclAttr>()) { 2317 Attr *A = OMPAllocateDeclAttr::CreateImplicit(Context, Allocator, 2318 DE->getSourceRange()); 2319 VD->addAttr(A); 2320 if (ASTMutationListener *ML = Context.getASTMutationListener()) 2321 ML->DeclarationMarkedOpenMPAllocate(VD, A); 2322 } 2323 } 2324 if (Vars.empty()) 2325 return nullptr; 2326 if (!Owner) 2327 Owner = getCurLexicalContext(); 2328 OMPAllocateDecl *D = 2329 OMPAllocateDecl::Create(Context, Owner, Loc, Vars, Clauses); 2330 D->setAccess(AS_public); 2331 Owner->addDecl(D); 2332 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2333 } 2334 2335 Sema::DeclGroupPtrTy 2336 Sema::ActOnOpenMPRequiresDirective(SourceLocation Loc, 2337 ArrayRef<OMPClause *> ClauseList) { 2338 OMPRequiresDecl *D = nullptr; 2339 if (!CurContext->isFileContext()) { 2340 Diag(Loc, diag::err_omp_invalid_scope) << "requires"; 2341 } else { 2342 D = CheckOMPRequiresDecl(Loc, ClauseList); 2343 if (D) { 2344 CurContext->addDecl(D); 2345 DSAStack->addRequiresDecl(D); 2346 } 2347 } 2348 return DeclGroupPtrTy::make(DeclGroupRef(D)); 2349 } 2350 2351 OMPRequiresDecl *Sema::CheckOMPRequiresDecl(SourceLocation Loc, 2352 ArrayRef<OMPClause *> ClauseList) { 2353 if (!DSAStack->hasDuplicateRequiresClause(ClauseList)) 2354 return OMPRequiresDecl::Create(Context, getCurLexicalContext(), Loc, 2355 ClauseList); 2356 return nullptr; 2357 } 2358 2359 static void reportOriginalDsa(Sema &SemaRef, const DSAStackTy *Stack, 2360 const ValueDecl *D, 2361 const DSAStackTy::DSAVarData &DVar, 2362 bool IsLoopIterVar = false) { 2363 if (DVar.RefExpr) { 2364 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 2365 << getOpenMPClauseName(DVar.CKind); 2366 return; 2367 } 2368 enum { 2369 PDSA_StaticMemberShared, 2370 PDSA_StaticLocalVarShared, 2371 PDSA_LoopIterVarPrivate, 2372 PDSA_LoopIterVarLinear, 2373 PDSA_LoopIterVarLastprivate, 2374 PDSA_ConstVarShared, 2375 PDSA_GlobalVarShared, 2376 PDSA_TaskVarFirstprivate, 2377 PDSA_LocalVarPrivate, 2378 PDSA_Implicit 2379 } Reason = PDSA_Implicit; 2380 bool ReportHint = false; 2381 auto ReportLoc = D->getLocation(); 2382 auto *VD = dyn_cast<VarDecl>(D); 2383 if (IsLoopIterVar) { 2384 if (DVar.CKind == OMPC_private) 2385 Reason = PDSA_LoopIterVarPrivate; 2386 else if (DVar.CKind == OMPC_lastprivate) 2387 Reason = PDSA_LoopIterVarLastprivate; 2388 else 2389 Reason = PDSA_LoopIterVarLinear; 2390 } else if (isOpenMPTaskingDirective(DVar.DKind) && 2391 DVar.CKind == OMPC_firstprivate) { 2392 Reason = PDSA_TaskVarFirstprivate; 2393 ReportLoc = DVar.ImplicitDSALoc; 2394 } else if (VD && VD->isStaticLocal()) 2395 Reason = PDSA_StaticLocalVarShared; 2396 else if (VD && VD->isStaticDataMember()) 2397 Reason = PDSA_StaticMemberShared; 2398 else if (VD && VD->isFileVarDecl()) 2399 Reason = PDSA_GlobalVarShared; 2400 else if (D->getType().isConstant(SemaRef.getASTContext())) 2401 Reason = PDSA_ConstVarShared; 2402 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 2403 ReportHint = true; 2404 Reason = PDSA_LocalVarPrivate; 2405 } 2406 if (Reason != PDSA_Implicit) { 2407 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 2408 << Reason << ReportHint 2409 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 2410 } else if (DVar.ImplicitDSALoc.isValid()) { 2411 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 2412 << getOpenMPClauseName(DVar.CKind); 2413 } 2414 } 2415 2416 namespace { 2417 class DSAAttrChecker final : public StmtVisitor<DSAAttrChecker, void> { 2418 DSAStackTy *Stack; 2419 Sema &SemaRef; 2420 bool ErrorFound = false; 2421 CapturedStmt *CS = nullptr; 2422 llvm::SmallVector<Expr *, 4> ImplicitFirstprivate; 2423 llvm::SmallVector<Expr *, 4> ImplicitMap; 2424 Sema::VarsWithInheritedDSAType VarsWithInheritedDSA; 2425 llvm::SmallDenseSet<const ValueDecl *, 4> ImplicitDeclarations; 2426 2427 void VisitSubCaptures(OMPExecutableDirective *S) { 2428 // Check implicitly captured variables. 2429 if (!S->hasAssociatedStmt() || !S->getAssociatedStmt()) 2430 return; 2431 for (const CapturedStmt::Capture &Cap : 2432 S->getInnermostCapturedStmt()->captures()) { 2433 if (!Cap.capturesVariable()) 2434 continue; 2435 VarDecl *VD = Cap.getCapturedVar(); 2436 // Do not try to map the variable if it or its sub-component was mapped 2437 // already. 2438 if (isOpenMPTargetExecutionDirective(Stack->getCurrentDirective()) && 2439 Stack->checkMappableExprComponentListsForDecl( 2440 VD, /*CurrentRegionOnly=*/true, 2441 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 2442 OpenMPClauseKind) { return true; })) 2443 continue; 2444 DeclRefExpr *DRE = buildDeclRefExpr( 2445 SemaRef, VD, VD->getType().getNonLValueExprType(SemaRef.Context), 2446 Cap.getLocation(), /*RefersToCapture=*/true); 2447 Visit(DRE); 2448 } 2449 } 2450 2451 public: 2452 void VisitDeclRefExpr(DeclRefExpr *E) { 2453 if (E->isTypeDependent() || E->isValueDependent() || 2454 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2455 return; 2456 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 2457 VD = VD->getCanonicalDecl(); 2458 // Skip internally declared variables. 2459 if (VD->hasLocalStorage() && !CS->capturesVariable(VD)) 2460 return; 2461 2462 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 2463 // Check if the variable has explicit DSA set and stop analysis if it so. 2464 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 2465 return; 2466 2467 // Skip internally declared static variables. 2468 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 2469 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD); 2470 if (VD->hasGlobalStorage() && !CS->capturesVariable(VD) && 2471 (!Res || *Res != OMPDeclareTargetDeclAttr::MT_Link)) 2472 return; 2473 2474 SourceLocation ELoc = E->getExprLoc(); 2475 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2476 // The default(none) clause requires that each variable that is referenced 2477 // in the construct, and does not have a predetermined data-sharing 2478 // attribute, must have its data-sharing attribute explicitly determined 2479 // by being listed in a data-sharing attribute clause. 2480 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 2481 isImplicitOrExplicitTaskingRegion(DKind) && 2482 VarsWithInheritedDSA.count(VD) == 0) { 2483 VarsWithInheritedDSA[VD] = E; 2484 return; 2485 } 2486 2487 if (isOpenMPTargetExecutionDirective(DKind) && 2488 !Stack->isLoopControlVariable(VD).first) { 2489 if (!Stack->checkMappableExprComponentListsForDecl( 2490 VD, /*CurrentRegionOnly=*/true, 2491 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2492 StackComponents, 2493 OpenMPClauseKind) { 2494 // Variable is used if it has been marked as an array, array 2495 // section or the variable iself. 2496 return StackComponents.size() == 1 || 2497 std::all_of( 2498 std::next(StackComponents.rbegin()), 2499 StackComponents.rend(), 2500 [](const OMPClauseMappableExprCommon:: 2501 MappableComponent &MC) { 2502 return MC.getAssociatedDeclaration() == 2503 nullptr && 2504 (isa<OMPArraySectionExpr>( 2505 MC.getAssociatedExpression()) || 2506 isa<ArraySubscriptExpr>( 2507 MC.getAssociatedExpression())); 2508 }); 2509 })) { 2510 bool IsFirstprivate = false; 2511 // By default lambdas are captured as firstprivates. 2512 if (const auto *RD = 2513 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 2514 IsFirstprivate = RD->isLambda(); 2515 IsFirstprivate = 2516 IsFirstprivate || 2517 (VD->getType().getNonReferenceType()->isScalarType() && 2518 Stack->getDefaultDMA() != DMA_tofrom_scalar && !Res); 2519 if (IsFirstprivate) 2520 ImplicitFirstprivate.emplace_back(E); 2521 else 2522 ImplicitMap.emplace_back(E); 2523 return; 2524 } 2525 } 2526 2527 // OpenMP [2.9.3.6, Restrictions, p.2] 2528 // A list item that appears in a reduction clause of the innermost 2529 // enclosing worksharing or parallel construct may not be accessed in an 2530 // explicit task. 2531 DVar = Stack->hasInnermostDSA( 2532 VD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2533 [](OpenMPDirectiveKind K) { 2534 return isOpenMPParallelDirective(K) || 2535 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2536 }, 2537 /*FromParent=*/true); 2538 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2539 ErrorFound = true; 2540 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2541 reportOriginalDsa(SemaRef, Stack, VD, DVar); 2542 return; 2543 } 2544 2545 // Define implicit data-sharing attributes for task. 2546 DVar = Stack->getImplicitDSA(VD, /*FromParent=*/false); 2547 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2548 !Stack->isLoopControlVariable(VD).first) { 2549 ImplicitFirstprivate.push_back(E); 2550 return; 2551 } 2552 2553 // Store implicitly used globals with declare target link for parent 2554 // target. 2555 if (!isOpenMPTargetExecutionDirective(DKind) && Res && 2556 *Res == OMPDeclareTargetDeclAttr::MT_Link) { 2557 Stack->addToParentTargetRegionLinkGlobals(E); 2558 return; 2559 } 2560 } 2561 } 2562 void VisitMemberExpr(MemberExpr *E) { 2563 if (E->isTypeDependent() || E->isValueDependent() || 2564 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 2565 return; 2566 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 2567 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 2568 if (auto *TE = dyn_cast<CXXThisExpr>(E->getBase()->IgnoreParens())) { 2569 if (!FD) 2570 return; 2571 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(FD, /*FromParent=*/false); 2572 // Check if the variable has explicit DSA set and stop analysis if it 2573 // so. 2574 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 2575 return; 2576 2577 if (isOpenMPTargetExecutionDirective(DKind) && 2578 !Stack->isLoopControlVariable(FD).first && 2579 !Stack->checkMappableExprComponentListsForDecl( 2580 FD, /*CurrentRegionOnly=*/true, 2581 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 2582 StackComponents, 2583 OpenMPClauseKind) { 2584 return isa<CXXThisExpr>( 2585 cast<MemberExpr>( 2586 StackComponents.back().getAssociatedExpression()) 2587 ->getBase() 2588 ->IgnoreParens()); 2589 })) { 2590 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 2591 // A bit-field cannot appear in a map clause. 2592 // 2593 if (FD->isBitField()) 2594 return; 2595 2596 // Check to see if the member expression is referencing a class that 2597 // has already been explicitly mapped 2598 if (Stack->isClassPreviouslyMapped(TE->getType())) 2599 return; 2600 2601 ImplicitMap.emplace_back(E); 2602 return; 2603 } 2604 2605 SourceLocation ELoc = E->getExprLoc(); 2606 // OpenMP [2.9.3.6, Restrictions, p.2] 2607 // A list item that appears in a reduction clause of the innermost 2608 // enclosing worksharing or parallel construct may not be accessed in 2609 // an explicit task. 2610 DVar = Stack->hasInnermostDSA( 2611 FD, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 2612 [](OpenMPDirectiveKind K) { 2613 return isOpenMPParallelDirective(K) || 2614 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2615 }, 2616 /*FromParent=*/true); 2617 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2618 ErrorFound = true; 2619 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2620 reportOriginalDsa(SemaRef, Stack, FD, DVar); 2621 return; 2622 } 2623 2624 // Define implicit data-sharing attributes for task. 2625 DVar = Stack->getImplicitDSA(FD, /*FromParent=*/false); 2626 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2627 !Stack->isLoopControlVariable(FD).first) { 2628 // Check if there is a captured expression for the current field in the 2629 // region. Do not mark it as firstprivate unless there is no captured 2630 // expression. 2631 // TODO: try to make it firstprivate. 2632 if (DVar.CKind != OMPC_unknown) 2633 ImplicitFirstprivate.push_back(E); 2634 } 2635 return; 2636 } 2637 if (isOpenMPTargetExecutionDirective(DKind)) { 2638 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2639 if (!checkMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2640 /*NoDiagnose=*/true)) 2641 return; 2642 const auto *VD = cast<ValueDecl>( 2643 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2644 if (!Stack->checkMappableExprComponentListsForDecl( 2645 VD, /*CurrentRegionOnly=*/true, 2646 [&CurComponents]( 2647 OMPClauseMappableExprCommon::MappableExprComponentListRef 2648 StackComponents, 2649 OpenMPClauseKind) { 2650 auto CCI = CurComponents.rbegin(); 2651 auto CCE = CurComponents.rend(); 2652 for (const auto &SC : llvm::reverse(StackComponents)) { 2653 // Do both expressions have the same kind? 2654 if (CCI->getAssociatedExpression()->getStmtClass() != 2655 SC.getAssociatedExpression()->getStmtClass()) 2656 if (!(isa<OMPArraySectionExpr>( 2657 SC.getAssociatedExpression()) && 2658 isa<ArraySubscriptExpr>( 2659 CCI->getAssociatedExpression()))) 2660 return false; 2661 2662 const Decl *CCD = CCI->getAssociatedDeclaration(); 2663 const Decl *SCD = SC.getAssociatedDeclaration(); 2664 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2665 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2666 if (SCD != CCD) 2667 return false; 2668 std::advance(CCI, 1); 2669 if (CCI == CCE) 2670 break; 2671 } 2672 return true; 2673 })) { 2674 Visit(E->getBase()); 2675 } 2676 } else { 2677 Visit(E->getBase()); 2678 } 2679 } 2680 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2681 for (OMPClause *C : S->clauses()) { 2682 // Skip analysis of arguments of implicitly defined firstprivate clause 2683 // for task|target directives. 2684 // Skip analysis of arguments of implicitly defined map clause for target 2685 // directives. 2686 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2687 C->isImplicit())) { 2688 for (Stmt *CC : C->children()) { 2689 if (CC) 2690 Visit(CC); 2691 } 2692 } 2693 } 2694 // Check implicitly captured variables. 2695 VisitSubCaptures(S); 2696 } 2697 void VisitStmt(Stmt *S) { 2698 for (Stmt *C : S->children()) { 2699 if (C) { 2700 // Check implicitly captured variables in the task-based directives to 2701 // check if they must be firstprivatized. 2702 Visit(C); 2703 } 2704 } 2705 } 2706 2707 bool isErrorFound() const { return ErrorFound; } 2708 ArrayRef<Expr *> getImplicitFirstprivate() const { 2709 return ImplicitFirstprivate; 2710 } 2711 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2712 const Sema::VarsWithInheritedDSAType &getVarsWithInheritedDSA() const { 2713 return VarsWithInheritedDSA; 2714 } 2715 2716 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2717 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) { 2718 // Process declare target link variables for the target directives. 2719 if (isOpenMPTargetExecutionDirective(S->getCurrentDirective())) { 2720 for (DeclRefExpr *E : Stack->getLinkGlobals()) 2721 Visit(E); 2722 } 2723 } 2724 }; 2725 } // namespace 2726 2727 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2728 switch (DKind) { 2729 case OMPD_parallel: 2730 case OMPD_parallel_for: 2731 case OMPD_parallel_for_simd: 2732 case OMPD_parallel_sections: 2733 case OMPD_teams: 2734 case OMPD_teams_distribute: 2735 case OMPD_teams_distribute_simd: { 2736 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2737 QualType KmpInt32PtrTy = 2738 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2739 Sema::CapturedParamNameType Params[] = { 2740 std::make_pair(".global_tid.", KmpInt32PtrTy), 2741 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2742 std::make_pair(StringRef(), QualType()) // __context with shared vars 2743 }; 2744 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2745 Params); 2746 break; 2747 } 2748 case OMPD_target_teams: 2749 case OMPD_target_parallel: 2750 case OMPD_target_parallel_for: 2751 case OMPD_target_parallel_for_simd: 2752 case OMPD_target_teams_distribute: 2753 case OMPD_target_teams_distribute_simd: { 2754 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2755 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2756 QualType KmpInt32PtrTy = 2757 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2758 QualType Args[] = {VoidPtrTy}; 2759 FunctionProtoType::ExtProtoInfo EPI; 2760 EPI.Variadic = true; 2761 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2762 Sema::CapturedParamNameType Params[] = { 2763 std::make_pair(".global_tid.", KmpInt32Ty), 2764 std::make_pair(".part_id.", KmpInt32PtrTy), 2765 std::make_pair(".privates.", VoidPtrTy), 2766 std::make_pair( 2767 ".copy_fn.", 2768 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2769 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2770 std::make_pair(StringRef(), QualType()) // __context with shared vars 2771 }; 2772 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2773 Params); 2774 // Mark this captured region as inlined, because we don't use outlined 2775 // function directly. 2776 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2777 AlwaysInlineAttr::CreateImplicit( 2778 Context, AlwaysInlineAttr::Keyword_forceinline)); 2779 Sema::CapturedParamNameType ParamsTarget[] = { 2780 std::make_pair(StringRef(), QualType()) // __context with shared vars 2781 }; 2782 // Start a captured region for 'target' with no implicit parameters. 2783 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2784 ParamsTarget); 2785 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2786 std::make_pair(".global_tid.", KmpInt32PtrTy), 2787 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2788 std::make_pair(StringRef(), QualType()) // __context with shared vars 2789 }; 2790 // Start a captured region for 'teams' or 'parallel'. Both regions have 2791 // the same implicit parameters. 2792 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2793 ParamsTeamsOrParallel); 2794 break; 2795 } 2796 case OMPD_target: 2797 case OMPD_target_simd: { 2798 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2799 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2800 QualType KmpInt32PtrTy = 2801 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2802 QualType Args[] = {VoidPtrTy}; 2803 FunctionProtoType::ExtProtoInfo EPI; 2804 EPI.Variadic = true; 2805 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2806 Sema::CapturedParamNameType Params[] = { 2807 std::make_pair(".global_tid.", KmpInt32Ty), 2808 std::make_pair(".part_id.", KmpInt32PtrTy), 2809 std::make_pair(".privates.", VoidPtrTy), 2810 std::make_pair( 2811 ".copy_fn.", 2812 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2813 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2814 std::make_pair(StringRef(), QualType()) // __context with shared vars 2815 }; 2816 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2817 Params); 2818 // Mark this captured region as inlined, because we don't use outlined 2819 // function directly. 2820 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2821 AlwaysInlineAttr::CreateImplicit( 2822 Context, AlwaysInlineAttr::Keyword_forceinline)); 2823 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2824 std::make_pair(StringRef(), QualType())); 2825 break; 2826 } 2827 case OMPD_simd: 2828 case OMPD_for: 2829 case OMPD_for_simd: 2830 case OMPD_sections: 2831 case OMPD_section: 2832 case OMPD_single: 2833 case OMPD_master: 2834 case OMPD_critical: 2835 case OMPD_taskgroup: 2836 case OMPD_distribute: 2837 case OMPD_distribute_simd: 2838 case OMPD_ordered: 2839 case OMPD_atomic: 2840 case OMPD_target_data: { 2841 Sema::CapturedParamNameType Params[] = { 2842 std::make_pair(StringRef(), QualType()) // __context with shared vars 2843 }; 2844 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2845 Params); 2846 break; 2847 } 2848 case OMPD_task: { 2849 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2850 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2851 QualType KmpInt32PtrTy = 2852 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2853 QualType Args[] = {VoidPtrTy}; 2854 FunctionProtoType::ExtProtoInfo EPI; 2855 EPI.Variadic = true; 2856 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2857 Sema::CapturedParamNameType Params[] = { 2858 std::make_pair(".global_tid.", KmpInt32Ty), 2859 std::make_pair(".part_id.", KmpInt32PtrTy), 2860 std::make_pair(".privates.", VoidPtrTy), 2861 std::make_pair( 2862 ".copy_fn.", 2863 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2864 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2865 std::make_pair(StringRef(), QualType()) // __context with shared vars 2866 }; 2867 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2868 Params); 2869 // Mark this captured region as inlined, because we don't use outlined 2870 // function directly. 2871 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2872 AlwaysInlineAttr::CreateImplicit( 2873 Context, AlwaysInlineAttr::Keyword_forceinline)); 2874 break; 2875 } 2876 case OMPD_taskloop: 2877 case OMPD_taskloop_simd: { 2878 QualType KmpInt32Ty = 2879 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1) 2880 .withConst(); 2881 QualType KmpUInt64Ty = 2882 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0) 2883 .withConst(); 2884 QualType KmpInt64Ty = 2885 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1) 2886 .withConst(); 2887 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2888 QualType KmpInt32PtrTy = 2889 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2890 QualType Args[] = {VoidPtrTy}; 2891 FunctionProtoType::ExtProtoInfo EPI; 2892 EPI.Variadic = true; 2893 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2894 Sema::CapturedParamNameType Params[] = { 2895 std::make_pair(".global_tid.", KmpInt32Ty), 2896 std::make_pair(".part_id.", KmpInt32PtrTy), 2897 std::make_pair(".privates.", VoidPtrTy), 2898 std::make_pair( 2899 ".copy_fn.", 2900 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2901 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2902 std::make_pair(".lb.", KmpUInt64Ty), 2903 std::make_pair(".ub.", KmpUInt64Ty), 2904 std::make_pair(".st.", KmpInt64Ty), 2905 std::make_pair(".liter.", KmpInt32Ty), 2906 std::make_pair(".reductions.", VoidPtrTy), 2907 std::make_pair(StringRef(), QualType()) // __context with shared vars 2908 }; 2909 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2910 Params); 2911 // Mark this captured region as inlined, because we don't use outlined 2912 // function directly. 2913 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2914 AlwaysInlineAttr::CreateImplicit( 2915 Context, AlwaysInlineAttr::Keyword_forceinline)); 2916 break; 2917 } 2918 case OMPD_distribute_parallel_for_simd: 2919 case OMPD_distribute_parallel_for: { 2920 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2921 QualType KmpInt32PtrTy = 2922 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2923 Sema::CapturedParamNameType Params[] = { 2924 std::make_pair(".global_tid.", KmpInt32PtrTy), 2925 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2926 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2927 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2928 std::make_pair(StringRef(), QualType()) // __context with shared vars 2929 }; 2930 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2931 Params); 2932 break; 2933 } 2934 case OMPD_target_teams_distribute_parallel_for: 2935 case OMPD_target_teams_distribute_parallel_for_simd: { 2936 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2937 QualType KmpInt32PtrTy = 2938 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2939 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 2940 2941 QualType Args[] = {VoidPtrTy}; 2942 FunctionProtoType::ExtProtoInfo EPI; 2943 EPI.Variadic = true; 2944 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2945 Sema::CapturedParamNameType Params[] = { 2946 std::make_pair(".global_tid.", KmpInt32Ty), 2947 std::make_pair(".part_id.", KmpInt32PtrTy), 2948 std::make_pair(".privates.", VoidPtrTy), 2949 std::make_pair( 2950 ".copy_fn.", 2951 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2952 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2953 std::make_pair(StringRef(), QualType()) // __context with shared vars 2954 }; 2955 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2956 Params); 2957 // Mark this captured region as inlined, because we don't use outlined 2958 // function directly. 2959 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2960 AlwaysInlineAttr::CreateImplicit( 2961 Context, AlwaysInlineAttr::Keyword_forceinline)); 2962 Sema::CapturedParamNameType ParamsTarget[] = { 2963 std::make_pair(StringRef(), QualType()) // __context with shared vars 2964 }; 2965 // Start a captured region for 'target' with no implicit parameters. 2966 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2967 ParamsTarget); 2968 2969 Sema::CapturedParamNameType ParamsTeams[] = { 2970 std::make_pair(".global_tid.", KmpInt32PtrTy), 2971 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2972 std::make_pair(StringRef(), QualType()) // __context with shared vars 2973 }; 2974 // Start a captured region for 'target' with no implicit parameters. 2975 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2976 ParamsTeams); 2977 2978 Sema::CapturedParamNameType ParamsParallel[] = { 2979 std::make_pair(".global_tid.", KmpInt32PtrTy), 2980 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2981 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 2982 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 2983 std::make_pair(StringRef(), QualType()) // __context with shared vars 2984 }; 2985 // Start a captured region for 'teams' or 'parallel'. Both regions have 2986 // the same implicit parameters. 2987 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2988 ParamsParallel); 2989 break; 2990 } 2991 2992 case OMPD_teams_distribute_parallel_for: 2993 case OMPD_teams_distribute_parallel_for_simd: { 2994 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 2995 QualType KmpInt32PtrTy = 2996 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2997 2998 Sema::CapturedParamNameType ParamsTeams[] = { 2999 std::make_pair(".global_tid.", KmpInt32PtrTy), 3000 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3001 std::make_pair(StringRef(), QualType()) // __context with shared vars 3002 }; 3003 // Start a captured region for 'target' with no implicit parameters. 3004 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3005 ParamsTeams); 3006 3007 Sema::CapturedParamNameType ParamsParallel[] = { 3008 std::make_pair(".global_tid.", KmpInt32PtrTy), 3009 std::make_pair(".bound_tid.", KmpInt32PtrTy), 3010 std::make_pair(".previous.lb.", Context.getSizeType().withConst()), 3011 std::make_pair(".previous.ub.", Context.getSizeType().withConst()), 3012 std::make_pair(StringRef(), QualType()) // __context with shared vars 3013 }; 3014 // Start a captured region for 'teams' or 'parallel'. Both regions have 3015 // the same implicit parameters. 3016 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3017 ParamsParallel); 3018 break; 3019 } 3020 case OMPD_target_update: 3021 case OMPD_target_enter_data: 3022 case OMPD_target_exit_data: { 3023 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1).withConst(); 3024 QualType VoidPtrTy = Context.VoidPtrTy.withConst().withRestrict(); 3025 QualType KmpInt32PtrTy = 3026 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 3027 QualType Args[] = {VoidPtrTy}; 3028 FunctionProtoType::ExtProtoInfo EPI; 3029 EPI.Variadic = true; 3030 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 3031 Sema::CapturedParamNameType Params[] = { 3032 std::make_pair(".global_tid.", KmpInt32Ty), 3033 std::make_pair(".part_id.", KmpInt32PtrTy), 3034 std::make_pair(".privates.", VoidPtrTy), 3035 std::make_pair( 3036 ".copy_fn.", 3037 Context.getPointerType(CopyFnType).withConst().withRestrict()), 3038 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 3039 std::make_pair(StringRef(), QualType()) // __context with shared vars 3040 }; 3041 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 3042 Params); 3043 // Mark this captured region as inlined, because we don't use outlined 3044 // function directly. 3045 getCurCapturedRegion()->TheCapturedDecl->addAttr( 3046 AlwaysInlineAttr::CreateImplicit( 3047 Context, AlwaysInlineAttr::Keyword_forceinline)); 3048 break; 3049 } 3050 case OMPD_threadprivate: 3051 case OMPD_allocate: 3052 case OMPD_taskyield: 3053 case OMPD_barrier: 3054 case OMPD_taskwait: 3055 case OMPD_cancellation_point: 3056 case OMPD_cancel: 3057 case OMPD_flush: 3058 case OMPD_declare_reduction: 3059 case OMPD_declare_mapper: 3060 case OMPD_declare_simd: 3061 case OMPD_declare_target: 3062 case OMPD_end_declare_target: 3063 case OMPD_requires: 3064 llvm_unreachable("OpenMP Directive is not allowed"); 3065 case OMPD_unknown: 3066 llvm_unreachable("Unknown OpenMP directive"); 3067 } 3068 } 3069 3070 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 3071 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3072 getOpenMPCaptureRegions(CaptureRegions, DKind); 3073 return CaptureRegions.size(); 3074 } 3075 3076 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 3077 Expr *CaptureExpr, bool WithInit, 3078 bool AsExpression) { 3079 assert(CaptureExpr); 3080 ASTContext &C = S.getASTContext(); 3081 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 3082 QualType Ty = Init->getType(); 3083 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 3084 if (S.getLangOpts().CPlusPlus) { 3085 Ty = C.getLValueReferenceType(Ty); 3086 } else { 3087 Ty = C.getPointerType(Ty); 3088 ExprResult Res = 3089 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 3090 if (!Res.isUsable()) 3091 return nullptr; 3092 Init = Res.get(); 3093 } 3094 WithInit = true; 3095 } 3096 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 3097 CaptureExpr->getBeginLoc()); 3098 if (!WithInit) 3099 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C)); 3100 S.CurContext->addHiddenDecl(CED); 3101 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 3102 return CED; 3103 } 3104 3105 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 3106 bool WithInit) { 3107 OMPCapturedExprDecl *CD; 3108 if (VarDecl *VD = S.isOpenMPCapturedDecl(D)) 3109 CD = cast<OMPCapturedExprDecl>(VD); 3110 else 3111 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 3112 /*AsExpression=*/false); 3113 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3114 CaptureExpr->getExprLoc()); 3115 } 3116 3117 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 3118 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 3119 if (!Ref) { 3120 OMPCapturedExprDecl *CD = buildCaptureDecl( 3121 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 3122 /*WithInit=*/true, /*AsExpression=*/true); 3123 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 3124 CaptureExpr->getExprLoc()); 3125 } 3126 ExprResult Res = Ref; 3127 if (!S.getLangOpts().CPlusPlus && 3128 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 3129 Ref->getType()->isPointerType()) { 3130 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 3131 if (!Res.isUsable()) 3132 return ExprError(); 3133 } 3134 return S.DefaultLvalueConversion(Res.get()); 3135 } 3136 3137 namespace { 3138 // OpenMP directives parsed in this section are represented as a 3139 // CapturedStatement with an associated statement. If a syntax error 3140 // is detected during the parsing of the associated statement, the 3141 // compiler must abort processing and close the CapturedStatement. 3142 // 3143 // Combined directives such as 'target parallel' have more than one 3144 // nested CapturedStatements. This RAII ensures that we unwind out 3145 // of all the nested CapturedStatements when an error is found. 3146 class CaptureRegionUnwinderRAII { 3147 private: 3148 Sema &S; 3149 bool &ErrorFound; 3150 OpenMPDirectiveKind DKind = OMPD_unknown; 3151 3152 public: 3153 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 3154 OpenMPDirectiveKind DKind) 3155 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 3156 ~CaptureRegionUnwinderRAII() { 3157 if (ErrorFound) { 3158 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 3159 while (--ThisCaptureLevel >= 0) 3160 S.ActOnCapturedRegionError(); 3161 } 3162 } 3163 }; 3164 } // namespace 3165 3166 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 3167 ArrayRef<OMPClause *> Clauses) { 3168 bool ErrorFound = false; 3169 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 3170 *this, ErrorFound, DSAStack->getCurrentDirective()); 3171 if (!S.isUsable()) { 3172 ErrorFound = true; 3173 return StmtError(); 3174 } 3175 3176 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 3177 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 3178 OMPOrderedClause *OC = nullptr; 3179 OMPScheduleClause *SC = nullptr; 3180 SmallVector<const OMPLinearClause *, 4> LCs; 3181 SmallVector<const OMPClauseWithPreInit *, 4> PICs; 3182 // This is required for proper codegen. 3183 for (OMPClause *Clause : Clauses) { 3184 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 3185 Clause->getClauseKind() == OMPC_in_reduction) { 3186 // Capture taskgroup task_reduction descriptors inside the tasking regions 3187 // with the corresponding in_reduction items. 3188 auto *IRC = cast<OMPInReductionClause>(Clause); 3189 for (Expr *E : IRC->taskgroup_descriptors()) 3190 if (E) 3191 MarkDeclarationsReferencedInExpr(E); 3192 } 3193 if (isOpenMPPrivate(Clause->getClauseKind()) || 3194 Clause->getClauseKind() == OMPC_copyprivate || 3195 (getLangOpts().OpenMPUseTLS && 3196 getASTContext().getTargetInfo().isTLSSupported() && 3197 Clause->getClauseKind() == OMPC_copyin)) { 3198 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 3199 // Mark all variables in private list clauses as used in inner region. 3200 for (Stmt *VarRef : Clause->children()) { 3201 if (auto *E = cast_or_null<Expr>(VarRef)) { 3202 MarkDeclarationsReferencedInExpr(E); 3203 } 3204 } 3205 DSAStack->setForceVarCapturing(/*V=*/false); 3206 } else if (CaptureRegions.size() > 1 || 3207 CaptureRegions.back() != OMPD_unknown) { 3208 if (auto *C = OMPClauseWithPreInit::get(Clause)) 3209 PICs.push_back(C); 3210 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 3211 if (Expr *E = C->getPostUpdateExpr()) 3212 MarkDeclarationsReferencedInExpr(E); 3213 } 3214 } 3215 if (Clause->getClauseKind() == OMPC_schedule) 3216 SC = cast<OMPScheduleClause>(Clause); 3217 else if (Clause->getClauseKind() == OMPC_ordered) 3218 OC = cast<OMPOrderedClause>(Clause); 3219 else if (Clause->getClauseKind() == OMPC_linear) 3220 LCs.push_back(cast<OMPLinearClause>(Clause)); 3221 } 3222 // OpenMP, 2.7.1 Loop Construct, Restrictions 3223 // The nonmonotonic modifier cannot be specified if an ordered clause is 3224 // specified. 3225 if (SC && 3226 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 3227 SC->getSecondScheduleModifier() == 3228 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 3229 OC) { 3230 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 3231 ? SC->getFirstScheduleModifierLoc() 3232 : SC->getSecondScheduleModifierLoc(), 3233 diag::err_omp_schedule_nonmonotonic_ordered) 3234 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3235 ErrorFound = true; 3236 } 3237 if (!LCs.empty() && OC && OC->getNumForLoops()) { 3238 for (const OMPLinearClause *C : LCs) { 3239 Diag(C->getBeginLoc(), diag::err_omp_linear_ordered) 3240 << SourceRange(OC->getBeginLoc(), OC->getEndLoc()); 3241 } 3242 ErrorFound = true; 3243 } 3244 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 3245 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 3246 OC->getNumForLoops()) { 3247 Diag(OC->getBeginLoc(), diag::err_omp_ordered_simd) 3248 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 3249 ErrorFound = true; 3250 } 3251 if (ErrorFound) { 3252 return StmtError(); 3253 } 3254 StmtResult SR = S; 3255 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 3256 // Mark all variables in private list clauses as used in inner region. 3257 // Required for proper codegen of combined directives. 3258 // TODO: add processing for other clauses. 3259 if (ThisCaptureRegion != OMPD_unknown) { 3260 for (const clang::OMPClauseWithPreInit *C : PICs) { 3261 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 3262 // Find the particular capture region for the clause if the 3263 // directive is a combined one with multiple capture regions. 3264 // If the directive is not a combined one, the capture region 3265 // associated with the clause is OMPD_unknown and is generated 3266 // only once. 3267 if (CaptureRegion == ThisCaptureRegion || 3268 CaptureRegion == OMPD_unknown) { 3269 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 3270 for (Decl *D : DS->decls()) 3271 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 3272 } 3273 } 3274 } 3275 } 3276 SR = ActOnCapturedRegionEnd(SR.get()); 3277 } 3278 return SR; 3279 } 3280 3281 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 3282 OpenMPDirectiveKind CancelRegion, 3283 SourceLocation StartLoc) { 3284 // CancelRegion is only needed for cancel and cancellation_point. 3285 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 3286 return false; 3287 3288 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 3289 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 3290 return false; 3291 3292 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 3293 << getOpenMPDirectiveName(CancelRegion); 3294 return true; 3295 } 3296 3297 static bool checkNestingOfRegions(Sema &SemaRef, const DSAStackTy *Stack, 3298 OpenMPDirectiveKind CurrentRegion, 3299 const DeclarationNameInfo &CurrentName, 3300 OpenMPDirectiveKind CancelRegion, 3301 SourceLocation StartLoc) { 3302 if (Stack->getCurScope()) { 3303 OpenMPDirectiveKind ParentRegion = Stack->getParentDirective(); 3304 OpenMPDirectiveKind OffendingRegion = ParentRegion; 3305 bool NestingProhibited = false; 3306 bool CloseNesting = true; 3307 bool OrphanSeen = false; 3308 enum { 3309 NoRecommend, 3310 ShouldBeInParallelRegion, 3311 ShouldBeInOrderedRegion, 3312 ShouldBeInTargetRegion, 3313 ShouldBeInTeamsRegion 3314 } Recommend = NoRecommend; 3315 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3316 // OpenMP [2.16, Nesting of Regions] 3317 // OpenMP constructs may not be nested inside a simd region. 3318 // OpenMP [2.8.1,simd Construct, Restrictions] 3319 // An ordered construct with the simd clause is the only OpenMP 3320 // construct that can appear in the simd region. 3321 // Allowing a SIMD construct nested in another SIMD construct is an 3322 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3323 // message. 3324 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3325 ? diag::err_omp_prohibited_region_simd 3326 : diag::warn_omp_nesting_simd); 3327 return CurrentRegion != OMPD_simd; 3328 } 3329 if (ParentRegion == OMPD_atomic) { 3330 // OpenMP [2.16, Nesting of Regions] 3331 // OpenMP constructs may not be nested inside an atomic region. 3332 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3333 return true; 3334 } 3335 if (CurrentRegion == OMPD_section) { 3336 // OpenMP [2.7.2, sections Construct, Restrictions] 3337 // Orphaned section directives are prohibited. That is, the section 3338 // directives must appear within the sections construct and must not be 3339 // encountered elsewhere in the sections region. 3340 if (ParentRegion != OMPD_sections && 3341 ParentRegion != OMPD_parallel_sections) { 3342 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3343 << (ParentRegion != OMPD_unknown) 3344 << getOpenMPDirectiveName(ParentRegion); 3345 return true; 3346 } 3347 return false; 3348 } 3349 // Allow some constructs (except teams and cancellation constructs) to be 3350 // orphaned (they could be used in functions, called from OpenMP regions 3351 // with the required preconditions). 3352 if (ParentRegion == OMPD_unknown && 3353 !isOpenMPNestingTeamsDirective(CurrentRegion) && 3354 CurrentRegion != OMPD_cancellation_point && 3355 CurrentRegion != OMPD_cancel) 3356 return false; 3357 if (CurrentRegion == OMPD_cancellation_point || 3358 CurrentRegion == OMPD_cancel) { 3359 // OpenMP [2.16, Nesting of Regions] 3360 // A cancellation point construct for which construct-type-clause is 3361 // taskgroup must be nested inside a task construct. A cancellation 3362 // point construct for which construct-type-clause is not taskgroup must 3363 // be closely nested inside an OpenMP construct that matches the type 3364 // specified in construct-type-clause. 3365 // A cancel construct for which construct-type-clause is taskgroup must be 3366 // nested inside a task construct. A cancel construct for which 3367 // construct-type-clause is not taskgroup must be closely nested inside an 3368 // OpenMP construct that matches the type specified in 3369 // construct-type-clause. 3370 NestingProhibited = 3371 !((CancelRegion == OMPD_parallel && 3372 (ParentRegion == OMPD_parallel || 3373 ParentRegion == OMPD_target_parallel)) || 3374 (CancelRegion == OMPD_for && 3375 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3376 ParentRegion == OMPD_target_parallel_for || 3377 ParentRegion == OMPD_distribute_parallel_for || 3378 ParentRegion == OMPD_teams_distribute_parallel_for || 3379 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 3380 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3381 (CancelRegion == OMPD_sections && 3382 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3383 ParentRegion == OMPD_parallel_sections))); 3384 OrphanSeen = ParentRegion == OMPD_unknown; 3385 } else if (CurrentRegion == OMPD_master) { 3386 // OpenMP [2.16, Nesting of Regions] 3387 // A master region may not be closely nested inside a worksharing, 3388 // atomic, or explicit task region. 3389 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3390 isOpenMPTaskingDirective(ParentRegion); 3391 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3392 // OpenMP [2.16, Nesting of Regions] 3393 // A critical region may not be nested (closely or otherwise) inside a 3394 // critical region with the same name. Note that this restriction is not 3395 // sufficient to prevent deadlock. 3396 SourceLocation PreviousCriticalLoc; 3397 bool DeadLock = Stack->hasDirective( 3398 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3399 const DeclarationNameInfo &DNI, 3400 SourceLocation Loc) { 3401 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3402 PreviousCriticalLoc = Loc; 3403 return true; 3404 } 3405 return false; 3406 }, 3407 false /* skip top directive */); 3408 if (DeadLock) { 3409 SemaRef.Diag(StartLoc, 3410 diag::err_omp_prohibited_region_critical_same_name) 3411 << CurrentName.getName(); 3412 if (PreviousCriticalLoc.isValid()) 3413 SemaRef.Diag(PreviousCriticalLoc, 3414 diag::note_omp_previous_critical_region); 3415 return true; 3416 } 3417 } else if (CurrentRegion == OMPD_barrier) { 3418 // OpenMP [2.16, Nesting of Regions] 3419 // A barrier region may not be closely nested inside a worksharing, 3420 // explicit task, critical, ordered, atomic, or master region. 3421 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3422 isOpenMPTaskingDirective(ParentRegion) || 3423 ParentRegion == OMPD_master || 3424 ParentRegion == OMPD_critical || 3425 ParentRegion == OMPD_ordered; 3426 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3427 !isOpenMPParallelDirective(CurrentRegion) && 3428 !isOpenMPTeamsDirective(CurrentRegion)) { 3429 // OpenMP [2.16, Nesting of Regions] 3430 // A worksharing region may not be closely nested inside a worksharing, 3431 // explicit task, critical, ordered, atomic, or master region. 3432 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3433 isOpenMPTaskingDirective(ParentRegion) || 3434 ParentRegion == OMPD_master || 3435 ParentRegion == OMPD_critical || 3436 ParentRegion == OMPD_ordered; 3437 Recommend = ShouldBeInParallelRegion; 3438 } else if (CurrentRegion == OMPD_ordered) { 3439 // OpenMP [2.16, Nesting of Regions] 3440 // An ordered region may not be closely nested inside a critical, 3441 // atomic, or explicit task region. 3442 // An ordered region must be closely nested inside a loop region (or 3443 // parallel loop region) with an ordered clause. 3444 // OpenMP [2.8.1,simd Construct, Restrictions] 3445 // An ordered construct with the simd clause is the only OpenMP construct 3446 // that can appear in the simd region. 3447 NestingProhibited = ParentRegion == OMPD_critical || 3448 isOpenMPTaskingDirective(ParentRegion) || 3449 !(isOpenMPSimdDirective(ParentRegion) || 3450 Stack->isParentOrderedRegion()); 3451 Recommend = ShouldBeInOrderedRegion; 3452 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 3453 // OpenMP [2.16, Nesting of Regions] 3454 // If specified, a teams construct must be contained within a target 3455 // construct. 3456 NestingProhibited = ParentRegion != OMPD_target; 3457 OrphanSeen = ParentRegion == OMPD_unknown; 3458 Recommend = ShouldBeInTargetRegion; 3459 } 3460 if (!NestingProhibited && 3461 !isOpenMPTargetExecutionDirective(CurrentRegion) && 3462 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 3463 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 3464 // OpenMP [2.16, Nesting of Regions] 3465 // distribute, parallel, parallel sections, parallel workshare, and the 3466 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3467 // constructs that can be closely nested in the teams region. 3468 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3469 !isOpenMPDistributeDirective(CurrentRegion); 3470 Recommend = ShouldBeInParallelRegion; 3471 } 3472 if (!NestingProhibited && 3473 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3474 // OpenMP 4.5 [2.17 Nesting of Regions] 3475 // The region associated with the distribute construct must be strictly 3476 // nested inside a teams region 3477 NestingProhibited = 3478 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 3479 Recommend = ShouldBeInTeamsRegion; 3480 } 3481 if (!NestingProhibited && 3482 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3483 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3484 // OpenMP 4.5 [2.17 Nesting of Regions] 3485 // If a target, target update, target data, target enter data, or 3486 // target exit data construct is encountered during execution of a 3487 // target region, the behavior is unspecified. 3488 NestingProhibited = Stack->hasDirective( 3489 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3490 SourceLocation) { 3491 if (isOpenMPTargetExecutionDirective(K)) { 3492 OffendingRegion = K; 3493 return true; 3494 } 3495 return false; 3496 }, 3497 false /* don't skip top directive */); 3498 CloseNesting = false; 3499 } 3500 if (NestingProhibited) { 3501 if (OrphanSeen) { 3502 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3503 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3504 } else { 3505 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3506 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3507 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3508 } 3509 return true; 3510 } 3511 } 3512 return false; 3513 } 3514 3515 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3516 ArrayRef<OMPClause *> Clauses, 3517 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3518 bool ErrorFound = false; 3519 unsigned NamedModifiersNumber = 0; 3520 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3521 OMPD_unknown + 1); 3522 SmallVector<SourceLocation, 4> NameModifierLoc; 3523 for (const OMPClause *C : Clauses) { 3524 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3525 // At most one if clause without a directive-name-modifier can appear on 3526 // the directive. 3527 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3528 if (FoundNameModifiers[CurNM]) { 3529 S.Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 3530 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3531 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3532 ErrorFound = true; 3533 } else if (CurNM != OMPD_unknown) { 3534 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3535 ++NamedModifiersNumber; 3536 } 3537 FoundNameModifiers[CurNM] = IC; 3538 if (CurNM == OMPD_unknown) 3539 continue; 3540 // Check if the specified name modifier is allowed for the current 3541 // directive. 3542 // At most one if clause with the particular directive-name-modifier can 3543 // appear on the directive. 3544 bool MatchFound = false; 3545 for (auto NM : AllowedNameModifiers) { 3546 if (CurNM == NM) { 3547 MatchFound = true; 3548 break; 3549 } 3550 } 3551 if (!MatchFound) { 3552 S.Diag(IC->getNameModifierLoc(), 3553 diag::err_omp_wrong_if_directive_name_modifier) 3554 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3555 ErrorFound = true; 3556 } 3557 } 3558 } 3559 // If any if clause on the directive includes a directive-name-modifier then 3560 // all if clauses on the directive must include a directive-name-modifier. 3561 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3562 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3563 S.Diag(FoundNameModifiers[OMPD_unknown]->getBeginLoc(), 3564 diag::err_omp_no_more_if_clause); 3565 } else { 3566 std::string Values; 3567 std::string Sep(", "); 3568 unsigned AllowedCnt = 0; 3569 unsigned TotalAllowedNum = 3570 AllowedNameModifiers.size() - NamedModifiersNumber; 3571 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3572 ++Cnt) { 3573 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3574 if (!FoundNameModifiers[NM]) { 3575 Values += "'"; 3576 Values += getOpenMPDirectiveName(NM); 3577 Values += "'"; 3578 if (AllowedCnt + 2 == TotalAllowedNum) 3579 Values += " or "; 3580 else if (AllowedCnt + 1 != TotalAllowedNum) 3581 Values += Sep; 3582 ++AllowedCnt; 3583 } 3584 } 3585 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getBeginLoc(), 3586 diag::err_omp_unnamed_if_clause) 3587 << (TotalAllowedNum > 1) << Values; 3588 } 3589 for (SourceLocation Loc : NameModifierLoc) { 3590 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3591 } 3592 ErrorFound = true; 3593 } 3594 return ErrorFound; 3595 } 3596 3597 StmtResult Sema::ActOnOpenMPExecutableDirective( 3598 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3599 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3600 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3601 StmtResult Res = StmtError(); 3602 // First check CancelRegion which is then used in checkNestingOfRegions. 3603 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 3604 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 3605 StartLoc)) 3606 return StmtError(); 3607 3608 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 3609 VarsWithInheritedDSAType VarsWithInheritedDSA; 3610 bool ErrorFound = false; 3611 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 3612 if (AStmt && !CurContext->isDependentContext()) { 3613 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3614 3615 // Check default data sharing attributes for referenced variables. 3616 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 3617 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 3618 Stmt *S = AStmt; 3619 while (--ThisCaptureLevel >= 0) 3620 S = cast<CapturedStmt>(S)->getCapturedStmt(); 3621 DSAChecker.Visit(S); 3622 if (DSAChecker.isErrorFound()) 3623 return StmtError(); 3624 // Generate list of implicitly defined firstprivate variables. 3625 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 3626 3627 SmallVector<Expr *, 4> ImplicitFirstprivates( 3628 DSAChecker.getImplicitFirstprivate().begin(), 3629 DSAChecker.getImplicitFirstprivate().end()); 3630 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 3631 DSAChecker.getImplicitMap().end()); 3632 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 3633 for (OMPClause *C : Clauses) { 3634 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 3635 for (Expr *E : IRC->taskgroup_descriptors()) 3636 if (E) 3637 ImplicitFirstprivates.emplace_back(E); 3638 } 3639 } 3640 if (!ImplicitFirstprivates.empty()) { 3641 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 3642 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 3643 SourceLocation())) { 3644 ClausesWithImplicit.push_back(Implicit); 3645 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 3646 ImplicitFirstprivates.size(); 3647 } else { 3648 ErrorFound = true; 3649 } 3650 } 3651 if (!ImplicitMaps.empty()) { 3652 CXXScopeSpec MapperIdScopeSpec; 3653 DeclarationNameInfo MapperId; 3654 if (OMPClause *Implicit = ActOnOpenMPMapClause( 3655 llvm::None, llvm::None, MapperIdScopeSpec, MapperId, 3656 OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, SourceLocation(), 3657 SourceLocation(), ImplicitMaps, OMPVarListLocTy())) { 3658 ClausesWithImplicit.emplace_back(Implicit); 3659 ErrorFound |= 3660 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 3661 } else { 3662 ErrorFound = true; 3663 } 3664 } 3665 } 3666 3667 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 3668 switch (Kind) { 3669 case OMPD_parallel: 3670 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 3671 EndLoc); 3672 AllowedNameModifiers.push_back(OMPD_parallel); 3673 break; 3674 case OMPD_simd: 3675 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3676 VarsWithInheritedDSA); 3677 break; 3678 case OMPD_for: 3679 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3680 VarsWithInheritedDSA); 3681 break; 3682 case OMPD_for_simd: 3683 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3684 EndLoc, VarsWithInheritedDSA); 3685 break; 3686 case OMPD_sections: 3687 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 3688 EndLoc); 3689 break; 3690 case OMPD_section: 3691 assert(ClausesWithImplicit.empty() && 3692 "No clauses are allowed for 'omp section' directive"); 3693 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 3694 break; 3695 case OMPD_single: 3696 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 3697 EndLoc); 3698 break; 3699 case OMPD_master: 3700 assert(ClausesWithImplicit.empty() && 3701 "No clauses are allowed for 'omp master' directive"); 3702 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 3703 break; 3704 case OMPD_critical: 3705 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 3706 StartLoc, EndLoc); 3707 break; 3708 case OMPD_parallel_for: 3709 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 3710 EndLoc, VarsWithInheritedDSA); 3711 AllowedNameModifiers.push_back(OMPD_parallel); 3712 break; 3713 case OMPD_parallel_for_simd: 3714 Res = ActOnOpenMPParallelForSimdDirective( 3715 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3716 AllowedNameModifiers.push_back(OMPD_parallel); 3717 break; 3718 case OMPD_parallel_sections: 3719 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 3720 StartLoc, EndLoc); 3721 AllowedNameModifiers.push_back(OMPD_parallel); 3722 break; 3723 case OMPD_task: 3724 Res = 3725 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3726 AllowedNameModifiers.push_back(OMPD_task); 3727 break; 3728 case OMPD_taskyield: 3729 assert(ClausesWithImplicit.empty() && 3730 "No clauses are allowed for 'omp taskyield' directive"); 3731 assert(AStmt == nullptr && 3732 "No associated statement allowed for 'omp taskyield' directive"); 3733 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 3734 break; 3735 case OMPD_barrier: 3736 assert(ClausesWithImplicit.empty() && 3737 "No clauses are allowed for 'omp barrier' directive"); 3738 assert(AStmt == nullptr && 3739 "No associated statement allowed for 'omp barrier' directive"); 3740 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 3741 break; 3742 case OMPD_taskwait: 3743 assert(ClausesWithImplicit.empty() && 3744 "No clauses are allowed for 'omp taskwait' directive"); 3745 assert(AStmt == nullptr && 3746 "No associated statement allowed for 'omp taskwait' directive"); 3747 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 3748 break; 3749 case OMPD_taskgroup: 3750 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 3751 EndLoc); 3752 break; 3753 case OMPD_flush: 3754 assert(AStmt == nullptr && 3755 "No associated statement allowed for 'omp flush' directive"); 3756 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 3757 break; 3758 case OMPD_ordered: 3759 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 3760 EndLoc); 3761 break; 3762 case OMPD_atomic: 3763 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 3764 EndLoc); 3765 break; 3766 case OMPD_teams: 3767 Res = 3768 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3769 break; 3770 case OMPD_target: 3771 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 3772 EndLoc); 3773 AllowedNameModifiers.push_back(OMPD_target); 3774 break; 3775 case OMPD_target_parallel: 3776 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 3777 StartLoc, EndLoc); 3778 AllowedNameModifiers.push_back(OMPD_target); 3779 AllowedNameModifiers.push_back(OMPD_parallel); 3780 break; 3781 case OMPD_target_parallel_for: 3782 Res = ActOnOpenMPTargetParallelForDirective( 3783 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3784 AllowedNameModifiers.push_back(OMPD_target); 3785 AllowedNameModifiers.push_back(OMPD_parallel); 3786 break; 3787 case OMPD_cancellation_point: 3788 assert(ClausesWithImplicit.empty() && 3789 "No clauses are allowed for 'omp cancellation point' directive"); 3790 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 3791 "cancellation point' directive"); 3792 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 3793 break; 3794 case OMPD_cancel: 3795 assert(AStmt == nullptr && 3796 "No associated statement allowed for 'omp cancel' directive"); 3797 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 3798 CancelRegion); 3799 AllowedNameModifiers.push_back(OMPD_cancel); 3800 break; 3801 case OMPD_target_data: 3802 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 3803 EndLoc); 3804 AllowedNameModifiers.push_back(OMPD_target_data); 3805 break; 3806 case OMPD_target_enter_data: 3807 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 3808 EndLoc, AStmt); 3809 AllowedNameModifiers.push_back(OMPD_target_enter_data); 3810 break; 3811 case OMPD_target_exit_data: 3812 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 3813 EndLoc, AStmt); 3814 AllowedNameModifiers.push_back(OMPD_target_exit_data); 3815 break; 3816 case OMPD_taskloop: 3817 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 3818 EndLoc, VarsWithInheritedDSA); 3819 AllowedNameModifiers.push_back(OMPD_taskloop); 3820 break; 3821 case OMPD_taskloop_simd: 3822 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3823 EndLoc, VarsWithInheritedDSA); 3824 AllowedNameModifiers.push_back(OMPD_taskloop); 3825 break; 3826 case OMPD_distribute: 3827 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 3828 EndLoc, VarsWithInheritedDSA); 3829 break; 3830 case OMPD_target_update: 3831 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 3832 EndLoc, AStmt); 3833 AllowedNameModifiers.push_back(OMPD_target_update); 3834 break; 3835 case OMPD_distribute_parallel_for: 3836 Res = ActOnOpenMPDistributeParallelForDirective( 3837 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3838 AllowedNameModifiers.push_back(OMPD_parallel); 3839 break; 3840 case OMPD_distribute_parallel_for_simd: 3841 Res = ActOnOpenMPDistributeParallelForSimdDirective( 3842 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3843 AllowedNameModifiers.push_back(OMPD_parallel); 3844 break; 3845 case OMPD_distribute_simd: 3846 Res = ActOnOpenMPDistributeSimdDirective( 3847 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3848 break; 3849 case OMPD_target_parallel_for_simd: 3850 Res = ActOnOpenMPTargetParallelForSimdDirective( 3851 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3852 AllowedNameModifiers.push_back(OMPD_target); 3853 AllowedNameModifiers.push_back(OMPD_parallel); 3854 break; 3855 case OMPD_target_simd: 3856 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3857 EndLoc, VarsWithInheritedDSA); 3858 AllowedNameModifiers.push_back(OMPD_target); 3859 break; 3860 case OMPD_teams_distribute: 3861 Res = ActOnOpenMPTeamsDistributeDirective( 3862 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3863 break; 3864 case OMPD_teams_distribute_simd: 3865 Res = ActOnOpenMPTeamsDistributeSimdDirective( 3866 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3867 break; 3868 case OMPD_teams_distribute_parallel_for_simd: 3869 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 3870 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3871 AllowedNameModifiers.push_back(OMPD_parallel); 3872 break; 3873 case OMPD_teams_distribute_parallel_for: 3874 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 3875 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3876 AllowedNameModifiers.push_back(OMPD_parallel); 3877 break; 3878 case OMPD_target_teams: 3879 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 3880 EndLoc); 3881 AllowedNameModifiers.push_back(OMPD_target); 3882 break; 3883 case OMPD_target_teams_distribute: 3884 Res = ActOnOpenMPTargetTeamsDistributeDirective( 3885 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3886 AllowedNameModifiers.push_back(OMPD_target); 3887 break; 3888 case OMPD_target_teams_distribute_parallel_for: 3889 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 3890 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3891 AllowedNameModifiers.push_back(OMPD_target); 3892 AllowedNameModifiers.push_back(OMPD_parallel); 3893 break; 3894 case OMPD_target_teams_distribute_parallel_for_simd: 3895 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 3896 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3897 AllowedNameModifiers.push_back(OMPD_target); 3898 AllowedNameModifiers.push_back(OMPD_parallel); 3899 break; 3900 case OMPD_target_teams_distribute_simd: 3901 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 3902 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3903 AllowedNameModifiers.push_back(OMPD_target); 3904 break; 3905 case OMPD_declare_target: 3906 case OMPD_end_declare_target: 3907 case OMPD_threadprivate: 3908 case OMPD_allocate: 3909 case OMPD_declare_reduction: 3910 case OMPD_declare_mapper: 3911 case OMPD_declare_simd: 3912 case OMPD_requires: 3913 llvm_unreachable("OpenMP Directive is not allowed"); 3914 case OMPD_unknown: 3915 llvm_unreachable("Unknown OpenMP directive"); 3916 } 3917 3918 for (const auto &P : VarsWithInheritedDSA) { 3919 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 3920 << P.first << P.second->getSourceRange(); 3921 } 3922 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 3923 3924 if (!AllowedNameModifiers.empty()) 3925 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 3926 ErrorFound; 3927 3928 if (ErrorFound) 3929 return StmtError(); 3930 return Res; 3931 } 3932 3933 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 3934 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 3935 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 3936 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 3937 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 3938 assert(Aligneds.size() == Alignments.size()); 3939 assert(Linears.size() == LinModifiers.size()); 3940 assert(Linears.size() == Steps.size()); 3941 if (!DG || DG.get().isNull()) 3942 return DeclGroupPtrTy(); 3943 3944 if (!DG.get().isSingleDecl()) { 3945 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 3946 return DG; 3947 } 3948 Decl *ADecl = DG.get().getSingleDecl(); 3949 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 3950 ADecl = FTD->getTemplatedDecl(); 3951 3952 auto *FD = dyn_cast<FunctionDecl>(ADecl); 3953 if (!FD) { 3954 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 3955 return DeclGroupPtrTy(); 3956 } 3957 3958 // OpenMP [2.8.2, declare simd construct, Description] 3959 // The parameter of the simdlen clause must be a constant positive integer 3960 // expression. 3961 ExprResult SL; 3962 if (Simdlen) 3963 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 3964 // OpenMP [2.8.2, declare simd construct, Description] 3965 // The special this pointer can be used as if was one of the arguments to the 3966 // function in any of the linear, aligned, or uniform clauses. 3967 // The uniform clause declares one or more arguments to have an invariant 3968 // value for all concurrent invocations of the function in the execution of a 3969 // single SIMD loop. 3970 llvm::DenseMap<const Decl *, const Expr *> UniformedArgs; 3971 const Expr *UniformedLinearThis = nullptr; 3972 for (const Expr *E : Uniforms) { 3973 E = E->IgnoreParenImpCasts(); 3974 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 3975 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 3976 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3977 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3978 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 3979 UniformedArgs.try_emplace(PVD->getCanonicalDecl(), E); 3980 continue; 3981 } 3982 if (isa<CXXThisExpr>(E)) { 3983 UniformedLinearThis = E; 3984 continue; 3985 } 3986 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3987 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3988 } 3989 // OpenMP [2.8.2, declare simd construct, Description] 3990 // The aligned clause declares that the object to which each list item points 3991 // is aligned to the number of bytes expressed in the optional parameter of 3992 // the aligned clause. 3993 // The special this pointer can be used as if was one of the arguments to the 3994 // function in any of the linear, aligned, or uniform clauses. 3995 // The type of list items appearing in the aligned clause must be array, 3996 // pointer, reference to array, or reference to pointer. 3997 llvm::DenseMap<const Decl *, const Expr *> AlignedArgs; 3998 const Expr *AlignedThis = nullptr; 3999 for (const Expr *E : Aligneds) { 4000 E = E->IgnoreParenImpCasts(); 4001 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4002 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4003 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4004 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4005 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4006 ->getCanonicalDecl() == CanonPVD) { 4007 // OpenMP [2.8.1, simd construct, Restrictions] 4008 // A list-item cannot appear in more than one aligned clause. 4009 if (AlignedArgs.count(CanonPVD) > 0) { 4010 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4011 << 1 << E->getSourceRange(); 4012 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4013 diag::note_omp_explicit_dsa) 4014 << getOpenMPClauseName(OMPC_aligned); 4015 continue; 4016 } 4017 AlignedArgs[CanonPVD] = E; 4018 QualType QTy = PVD->getType() 4019 .getNonReferenceType() 4020 .getUnqualifiedType() 4021 .getCanonicalType(); 4022 const Type *Ty = QTy.getTypePtrOrNull(); 4023 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4024 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4025 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4026 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4027 } 4028 continue; 4029 } 4030 } 4031 if (isa<CXXThisExpr>(E)) { 4032 if (AlignedThis) { 4033 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4034 << 2 << E->getSourceRange(); 4035 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4036 << getOpenMPClauseName(OMPC_aligned); 4037 } 4038 AlignedThis = E; 4039 continue; 4040 } 4041 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4042 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4043 } 4044 // The optional parameter of the aligned clause, alignment, must be a constant 4045 // positive integer expression. If no optional parameter is specified, 4046 // implementation-defined default alignments for SIMD instructions on the 4047 // target platforms are assumed. 4048 SmallVector<const Expr *, 4> NewAligns; 4049 for (Expr *E : Alignments) { 4050 ExprResult Align; 4051 if (E) 4052 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4053 NewAligns.push_back(Align.get()); 4054 } 4055 // OpenMP [2.8.2, declare simd construct, Description] 4056 // The linear clause declares one or more list items to be private to a SIMD 4057 // lane and to have a linear relationship with respect to the iteration space 4058 // of a loop. 4059 // The special this pointer can be used as if was one of the arguments to the 4060 // function in any of the linear, aligned, or uniform clauses. 4061 // When a linear-step expression is specified in a linear clause it must be 4062 // either a constant integer expression or an integer-typed parameter that is 4063 // specified in a uniform clause on the directive. 4064 llvm::DenseMap<const Decl *, const Expr *> LinearArgs; 4065 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4066 auto MI = LinModifiers.begin(); 4067 for (const Expr *E : Linears) { 4068 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4069 ++MI; 4070 E = E->IgnoreParenImpCasts(); 4071 if (const auto *DRE = dyn_cast<DeclRefExpr>(E)) 4072 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4073 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4074 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4075 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4076 ->getCanonicalDecl() == CanonPVD) { 4077 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4078 // A list-item cannot appear in more than one linear clause. 4079 if (LinearArgs.count(CanonPVD) > 0) { 4080 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4081 << getOpenMPClauseName(OMPC_linear) 4082 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4083 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4084 diag::note_omp_explicit_dsa) 4085 << getOpenMPClauseName(OMPC_linear); 4086 continue; 4087 } 4088 // Each argument can appear in at most one uniform or linear clause. 4089 if (UniformedArgs.count(CanonPVD) > 0) { 4090 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4091 << getOpenMPClauseName(OMPC_linear) 4092 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4093 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4094 diag::note_omp_explicit_dsa) 4095 << getOpenMPClauseName(OMPC_uniform); 4096 continue; 4097 } 4098 LinearArgs[CanonPVD] = E; 4099 if (E->isValueDependent() || E->isTypeDependent() || 4100 E->isInstantiationDependent() || 4101 E->containsUnexpandedParameterPack()) 4102 continue; 4103 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4104 PVD->getOriginalType()); 4105 continue; 4106 } 4107 } 4108 if (isa<CXXThisExpr>(E)) { 4109 if (UniformedLinearThis) { 4110 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4111 << getOpenMPClauseName(OMPC_linear) 4112 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4113 << E->getSourceRange(); 4114 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4115 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4116 : OMPC_linear); 4117 continue; 4118 } 4119 UniformedLinearThis = E; 4120 if (E->isValueDependent() || E->isTypeDependent() || 4121 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4122 continue; 4123 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4124 E->getType()); 4125 continue; 4126 } 4127 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4128 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4129 } 4130 Expr *Step = nullptr; 4131 Expr *NewStep = nullptr; 4132 SmallVector<Expr *, 4> NewSteps; 4133 for (Expr *E : Steps) { 4134 // Skip the same step expression, it was checked already. 4135 if (Step == E || !E) { 4136 NewSteps.push_back(E ? NewStep : nullptr); 4137 continue; 4138 } 4139 Step = E; 4140 if (const auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4141 if (const auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4142 const VarDecl *CanonPVD = PVD->getCanonicalDecl(); 4143 if (UniformedArgs.count(CanonPVD) == 0) { 4144 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4145 << Step->getSourceRange(); 4146 } else if (E->isValueDependent() || E->isTypeDependent() || 4147 E->isInstantiationDependent() || 4148 E->containsUnexpandedParameterPack() || 4149 CanonPVD->getType()->hasIntegerRepresentation()) { 4150 NewSteps.push_back(Step); 4151 } else { 4152 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4153 << Step->getSourceRange(); 4154 } 4155 continue; 4156 } 4157 NewStep = Step; 4158 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4159 !Step->isInstantiationDependent() && 4160 !Step->containsUnexpandedParameterPack()) { 4161 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4162 .get(); 4163 if (NewStep) 4164 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4165 } 4166 NewSteps.push_back(NewStep); 4167 } 4168 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4169 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4170 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4171 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4172 const_cast<Expr **>(Linears.data()), Linears.size(), 4173 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4174 NewSteps.data(), NewSteps.size(), SR); 4175 ADecl->addAttr(NewAttr); 4176 return ConvertDeclToDeclGroup(ADecl); 4177 } 4178 4179 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4180 Stmt *AStmt, 4181 SourceLocation StartLoc, 4182 SourceLocation EndLoc) { 4183 if (!AStmt) 4184 return StmtError(); 4185 4186 auto *CS = cast<CapturedStmt>(AStmt); 4187 // 1.2.2 OpenMP Language Terminology 4188 // Structured block - An executable statement with a single entry at the 4189 // top and a single exit at the bottom. 4190 // The point of exit cannot be a branch out of the structured block. 4191 // longjmp() and throw() must not violate the entry/exit criteria. 4192 CS->getCapturedDecl()->setNothrow(); 4193 4194 setFunctionHasBranchProtectedScope(); 4195 4196 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4197 DSAStack->isCancelRegion()); 4198 } 4199 4200 namespace { 4201 /// Helper class for checking canonical form of the OpenMP loops and 4202 /// extracting iteration space of each loop in the loop nest, that will be used 4203 /// for IR generation. 4204 class OpenMPIterationSpaceChecker { 4205 /// Reference to Sema. 4206 Sema &SemaRef; 4207 /// A location for diagnostics (when there is no some better location). 4208 SourceLocation DefaultLoc; 4209 /// A location for diagnostics (when increment is not compatible). 4210 SourceLocation ConditionLoc; 4211 /// A source location for referring to loop init later. 4212 SourceRange InitSrcRange; 4213 /// A source location for referring to condition later. 4214 SourceRange ConditionSrcRange; 4215 /// A source location for referring to increment later. 4216 SourceRange IncrementSrcRange; 4217 /// Loop variable. 4218 ValueDecl *LCDecl = nullptr; 4219 /// Reference to loop variable. 4220 Expr *LCRef = nullptr; 4221 /// Lower bound (initializer for the var). 4222 Expr *LB = nullptr; 4223 /// Upper bound. 4224 Expr *UB = nullptr; 4225 /// Loop step (increment). 4226 Expr *Step = nullptr; 4227 /// This flag is true when condition is one of: 4228 /// Var < UB 4229 /// Var <= UB 4230 /// UB > Var 4231 /// UB >= Var 4232 /// This will have no value when the condition is != 4233 llvm::Optional<bool> TestIsLessOp; 4234 /// This flag is true when condition is strict ( < or > ). 4235 bool TestIsStrictOp = false; 4236 /// This flag is true when step is subtracted on each iteration. 4237 bool SubtractStep = false; 4238 4239 public: 4240 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 4241 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 4242 /// Check init-expr for canonical loop form and save loop counter 4243 /// variable - #Var and its initialization value - #LB. 4244 bool checkAndSetInit(Stmt *S, bool EmitDiags = true); 4245 /// Check test-expr for canonical form, save upper-bound (#UB), flags 4246 /// for less/greater and for strict/non-strict comparison. 4247 bool checkAndSetCond(Expr *S); 4248 /// Check incr-expr for canonical loop form and return true if it 4249 /// does not conform, otherwise save loop step (#Step). 4250 bool checkAndSetInc(Expr *S); 4251 /// Return the loop counter variable. 4252 ValueDecl *getLoopDecl() const { return LCDecl; } 4253 /// Return the reference expression to loop counter variable. 4254 Expr *getLoopDeclRefExpr() const { return LCRef; } 4255 /// Source range of the loop init. 4256 SourceRange getInitSrcRange() const { return InitSrcRange; } 4257 /// Source range of the loop condition. 4258 SourceRange getConditionSrcRange() const { return ConditionSrcRange; } 4259 /// Source range of the loop increment. 4260 SourceRange getIncrementSrcRange() const { return IncrementSrcRange; } 4261 /// True if the step should be subtracted. 4262 bool shouldSubtractStep() const { return SubtractStep; } 4263 /// True, if the compare operator is strict (<, > or !=). 4264 bool isStrictTestOp() const { return TestIsStrictOp; } 4265 /// Build the expression to calculate the number of iterations. 4266 Expr *buildNumIterations( 4267 Scope *S, const bool LimitedType, 4268 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4269 /// Build the precondition expression for the loops. 4270 Expr * 4271 buildPreCond(Scope *S, Expr *Cond, 4272 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const; 4273 /// Build reference expression to the counter be used for codegen. 4274 DeclRefExpr * 4275 buildCounterVar(llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4276 DSAStackTy &DSA) const; 4277 /// Build reference expression to the private counter be used for 4278 /// codegen. 4279 Expr *buildPrivateCounterVar() const; 4280 /// Build initialization of the counter be used for codegen. 4281 Expr *buildCounterInit() const; 4282 /// Build step of the counter be used for codegen. 4283 Expr *buildCounterStep() const; 4284 /// Build loop data with counter value for depend clauses in ordered 4285 /// directives. 4286 Expr * 4287 buildOrderedLoopData(Scope *S, Expr *Counter, 4288 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4289 SourceLocation Loc, Expr *Inc = nullptr, 4290 OverloadedOperatorKind OOK = OO_Amp); 4291 /// Return true if any expression is dependent. 4292 bool dependent() const; 4293 4294 private: 4295 /// Check the right-hand side of an assignment in the increment 4296 /// expression. 4297 bool checkAndSetIncRHS(Expr *RHS); 4298 /// Helper to set loop counter variable and its initializer. 4299 bool setLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); 4300 /// Helper to set upper bound. 4301 bool setUB(Expr *NewUB, llvm::Optional<bool> LessOp, bool StrictOp, 4302 SourceRange SR, SourceLocation SL); 4303 /// Helper to set loop increment. 4304 bool setStep(Expr *NewStep, bool Subtract); 4305 }; 4306 4307 bool OpenMPIterationSpaceChecker::dependent() const { 4308 if (!LCDecl) { 4309 assert(!LB && !UB && !Step); 4310 return false; 4311 } 4312 return LCDecl->getType()->isDependentType() || 4313 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 4314 (Step && Step->isValueDependent()); 4315 } 4316 4317 bool OpenMPIterationSpaceChecker::setLCDeclAndLB(ValueDecl *NewLCDecl, 4318 Expr *NewLCRefExpr, 4319 Expr *NewLB) { 4320 // State consistency checking to ensure correct usage. 4321 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 4322 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4323 if (!NewLCDecl || !NewLB) 4324 return true; 4325 LCDecl = getCanonicalDecl(NewLCDecl); 4326 LCRef = NewLCRefExpr; 4327 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 4328 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4329 if ((Ctor->isCopyOrMoveConstructor() || 4330 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4331 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4332 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 4333 LB = NewLB; 4334 return false; 4335 } 4336 4337 bool OpenMPIterationSpaceChecker::setUB(Expr *NewUB, 4338 llvm::Optional<bool> LessOp, 4339 bool StrictOp, SourceRange SR, 4340 SourceLocation SL) { 4341 // State consistency checking to ensure correct usage. 4342 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 4343 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4344 if (!NewUB) 4345 return true; 4346 UB = NewUB; 4347 if (LessOp) 4348 TestIsLessOp = LessOp; 4349 TestIsStrictOp = StrictOp; 4350 ConditionSrcRange = SR; 4351 ConditionLoc = SL; 4352 return false; 4353 } 4354 4355 bool OpenMPIterationSpaceChecker::setStep(Expr *NewStep, bool Subtract) { 4356 // State consistency checking to ensure correct usage. 4357 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 4358 if (!NewStep) 4359 return true; 4360 if (!NewStep->isValueDependent()) { 4361 // Check that the step is integer expression. 4362 SourceLocation StepLoc = NewStep->getBeginLoc(); 4363 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 4364 StepLoc, getExprAsWritten(NewStep)); 4365 if (Val.isInvalid()) 4366 return true; 4367 NewStep = Val.get(); 4368 4369 // OpenMP [2.6, Canonical Loop Form, Restrictions] 4370 // If test-expr is of form var relational-op b and relational-op is < or 4371 // <= then incr-expr must cause var to increase on each iteration of the 4372 // loop. If test-expr is of form var relational-op b and relational-op is 4373 // > or >= then incr-expr must cause var to decrease on each iteration of 4374 // the loop. 4375 // If test-expr is of form b relational-op var and relational-op is < or 4376 // <= then incr-expr must cause var to decrease on each iteration of the 4377 // loop. If test-expr is of form b relational-op var and relational-op is 4378 // > or >= then incr-expr must cause var to increase on each iteration of 4379 // the loop. 4380 llvm::APSInt Result; 4381 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 4382 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 4383 bool IsConstNeg = 4384 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 4385 bool IsConstPos = 4386 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 4387 bool IsConstZero = IsConstant && !Result.getBoolValue(); 4388 4389 // != with increment is treated as <; != with decrement is treated as > 4390 if (!TestIsLessOp.hasValue()) 4391 TestIsLessOp = IsConstPos || (IsUnsigned && !Subtract); 4392 if (UB && (IsConstZero || 4393 (TestIsLessOp.getValue() ? 4394 (IsConstNeg || (IsUnsigned && Subtract)) : 4395 (IsConstPos || (IsUnsigned && !Subtract))))) { 4396 SemaRef.Diag(NewStep->getExprLoc(), 4397 diag::err_omp_loop_incr_not_compatible) 4398 << LCDecl << TestIsLessOp.getValue() << NewStep->getSourceRange(); 4399 SemaRef.Diag(ConditionLoc, 4400 diag::note_omp_loop_cond_requres_compatible_incr) 4401 << TestIsLessOp.getValue() << ConditionSrcRange; 4402 return true; 4403 } 4404 if (TestIsLessOp.getValue() == Subtract) { 4405 NewStep = 4406 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 4407 .get(); 4408 Subtract = !Subtract; 4409 } 4410 } 4411 4412 Step = NewStep; 4413 SubtractStep = Subtract; 4414 return false; 4415 } 4416 4417 bool OpenMPIterationSpaceChecker::checkAndSetInit(Stmt *S, bool EmitDiags) { 4418 // Check init-expr for canonical loop form and save loop counter 4419 // variable - #Var and its initialization value - #LB. 4420 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 4421 // var = lb 4422 // integer-type var = lb 4423 // random-access-iterator-type var = lb 4424 // pointer-type var = lb 4425 // 4426 if (!S) { 4427 if (EmitDiags) { 4428 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 4429 } 4430 return true; 4431 } 4432 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4433 if (!ExprTemp->cleanupsHaveSideEffects()) 4434 S = ExprTemp->getSubExpr(); 4435 4436 InitSrcRange = S->getSourceRange(); 4437 if (Expr *E = dyn_cast<Expr>(S)) 4438 S = E->IgnoreParens(); 4439 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4440 if (BO->getOpcode() == BO_Assign) { 4441 Expr *LHS = BO->getLHS()->IgnoreParens(); 4442 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4443 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4444 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4445 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4446 return setLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); 4447 } 4448 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4449 if (ME->isArrow() && 4450 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4451 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4452 } 4453 } 4454 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 4455 if (DS->isSingleDecl()) { 4456 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 4457 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 4458 // Accept non-canonical init form here but emit ext. warning. 4459 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 4460 SemaRef.Diag(S->getBeginLoc(), 4461 diag::ext_omp_loop_not_canonical_init) 4462 << S->getSourceRange(); 4463 return setLCDeclAndLB( 4464 Var, 4465 buildDeclRefExpr(SemaRef, Var, 4466 Var->getType().getNonReferenceType(), 4467 DS->getBeginLoc()), 4468 Var->getInit()); 4469 } 4470 } 4471 } 4472 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4473 if (CE->getOperator() == OO_Equal) { 4474 Expr *LHS = CE->getArg(0); 4475 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4476 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4477 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4478 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4479 return setLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); 4480 } 4481 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4482 if (ME->isArrow() && 4483 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4484 return setLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4485 } 4486 } 4487 } 4488 4489 if (dependent() || SemaRef.CurContext->isDependentContext()) 4490 return false; 4491 if (EmitDiags) { 4492 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_init) 4493 << S->getSourceRange(); 4494 } 4495 return true; 4496 } 4497 4498 /// Ignore parenthesizes, implicit casts, copy constructor and return the 4499 /// variable (which may be the loop variable) if possible. 4500 static const ValueDecl *getInitLCDecl(const Expr *E) { 4501 if (!E) 4502 return nullptr; 4503 E = getExprAsWritten(E); 4504 if (const auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 4505 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4506 if ((Ctor->isCopyOrMoveConstructor() || 4507 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4508 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4509 E = CE->getArg(0)->IgnoreParenImpCasts(); 4510 if (const auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 4511 if (const auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 4512 return getCanonicalDecl(VD); 4513 } 4514 if (const auto *ME = dyn_cast_or_null<MemberExpr>(E)) 4515 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4516 return getCanonicalDecl(ME->getMemberDecl()); 4517 return nullptr; 4518 } 4519 4520 bool OpenMPIterationSpaceChecker::checkAndSetCond(Expr *S) { 4521 // Check test-expr for canonical form, save upper-bound UB, flags for 4522 // less/greater and for strict/non-strict comparison. 4523 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4524 // var relational-op b 4525 // b relational-op var 4526 // 4527 if (!S) { 4528 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 4529 return true; 4530 } 4531 S = getExprAsWritten(S); 4532 SourceLocation CondLoc = S->getBeginLoc(); 4533 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4534 if (BO->isRelationalOp()) { 4535 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4536 return setUB(BO->getRHS(), 4537 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 4538 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4539 BO->getSourceRange(), BO->getOperatorLoc()); 4540 if (getInitLCDecl(BO->getRHS()) == LCDecl) 4541 return setUB(BO->getLHS(), 4542 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 4543 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4544 BO->getSourceRange(), BO->getOperatorLoc()); 4545 } else if (BO->getOpcode() == BO_NE) 4546 return setUB(getInitLCDecl(BO->getLHS()) == LCDecl ? 4547 BO->getRHS() : BO->getLHS(), 4548 /*LessOp=*/llvm::None, 4549 /*StrictOp=*/true, 4550 BO->getSourceRange(), BO->getOperatorLoc()); 4551 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4552 if (CE->getNumArgs() == 2) { 4553 auto Op = CE->getOperator(); 4554 switch (Op) { 4555 case OO_Greater: 4556 case OO_GreaterEqual: 4557 case OO_Less: 4558 case OO_LessEqual: 4559 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4560 return setUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 4561 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4562 CE->getOperatorLoc()); 4563 if (getInitLCDecl(CE->getArg(1)) == LCDecl) 4564 return setUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 4565 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4566 CE->getOperatorLoc()); 4567 break; 4568 case OO_ExclaimEqual: 4569 return setUB(getInitLCDecl(CE->getArg(0)) == LCDecl ? 4570 CE->getArg(1) : CE->getArg(0), 4571 /*LessOp=*/llvm::None, 4572 /*StrictOp=*/true, 4573 CE->getSourceRange(), 4574 CE->getOperatorLoc()); 4575 break; 4576 default: 4577 break; 4578 } 4579 } 4580 } 4581 if (dependent() || SemaRef.CurContext->isDependentContext()) 4582 return false; 4583 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 4584 << S->getSourceRange() << LCDecl; 4585 return true; 4586 } 4587 4588 bool OpenMPIterationSpaceChecker::checkAndSetIncRHS(Expr *RHS) { 4589 // RHS of canonical loop form increment can be: 4590 // var + incr 4591 // incr + var 4592 // var - incr 4593 // 4594 RHS = RHS->IgnoreParenImpCasts(); 4595 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 4596 if (BO->isAdditiveOp()) { 4597 bool IsAdd = BO->getOpcode() == BO_Add; 4598 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4599 return setStep(BO->getRHS(), !IsAdd); 4600 if (IsAdd && getInitLCDecl(BO->getRHS()) == LCDecl) 4601 return setStep(BO->getLHS(), /*Subtract=*/false); 4602 } 4603 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 4604 bool IsAdd = CE->getOperator() == OO_Plus; 4605 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 4606 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4607 return setStep(CE->getArg(1), !IsAdd); 4608 if (IsAdd && getInitLCDecl(CE->getArg(1)) == LCDecl) 4609 return setStep(CE->getArg(0), /*Subtract=*/false); 4610 } 4611 } 4612 if (dependent() || SemaRef.CurContext->isDependentContext()) 4613 return false; 4614 SemaRef.Diag(RHS->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 4615 << RHS->getSourceRange() << LCDecl; 4616 return true; 4617 } 4618 4619 bool OpenMPIterationSpaceChecker::checkAndSetInc(Expr *S) { 4620 // Check incr-expr for canonical loop form and return true if it 4621 // does not conform. 4622 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4623 // ++var 4624 // var++ 4625 // --var 4626 // var-- 4627 // var += incr 4628 // var -= incr 4629 // var = var + incr 4630 // var = incr + var 4631 // var = var - incr 4632 // 4633 if (!S) { 4634 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 4635 return true; 4636 } 4637 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4638 if (!ExprTemp->cleanupsHaveSideEffects()) 4639 S = ExprTemp->getSubExpr(); 4640 4641 IncrementSrcRange = S->getSourceRange(); 4642 S = S->IgnoreParens(); 4643 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 4644 if (UO->isIncrementDecrementOp() && 4645 getInitLCDecl(UO->getSubExpr()) == LCDecl) 4646 return setStep(SemaRef 4647 .ActOnIntegerConstant(UO->getBeginLoc(), 4648 (UO->isDecrementOp() ? -1 : 1)) 4649 .get(), 4650 /*Subtract=*/false); 4651 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4652 switch (BO->getOpcode()) { 4653 case BO_AddAssign: 4654 case BO_SubAssign: 4655 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4656 return setStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 4657 break; 4658 case BO_Assign: 4659 if (getInitLCDecl(BO->getLHS()) == LCDecl) 4660 return checkAndSetIncRHS(BO->getRHS()); 4661 break; 4662 default: 4663 break; 4664 } 4665 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4666 switch (CE->getOperator()) { 4667 case OO_PlusPlus: 4668 case OO_MinusMinus: 4669 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4670 return setStep(SemaRef 4671 .ActOnIntegerConstant( 4672 CE->getBeginLoc(), 4673 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 4674 .get(), 4675 /*Subtract=*/false); 4676 break; 4677 case OO_PlusEqual: 4678 case OO_MinusEqual: 4679 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4680 return setStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 4681 break; 4682 case OO_Equal: 4683 if (getInitLCDecl(CE->getArg(0)) == LCDecl) 4684 return checkAndSetIncRHS(CE->getArg(1)); 4685 break; 4686 default: 4687 break; 4688 } 4689 } 4690 if (dependent() || SemaRef.CurContext->isDependentContext()) 4691 return false; 4692 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_loop_not_canonical_incr) 4693 << S->getSourceRange() << LCDecl; 4694 return true; 4695 } 4696 4697 static ExprResult 4698 tryBuildCapture(Sema &SemaRef, Expr *Capture, 4699 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 4700 if (SemaRef.CurContext->isDependentContext()) 4701 return ExprResult(Capture); 4702 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 4703 return SemaRef.PerformImplicitConversion( 4704 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 4705 /*AllowExplicit=*/true); 4706 auto I = Captures.find(Capture); 4707 if (I != Captures.end()) 4708 return buildCapture(SemaRef, Capture, I->second); 4709 DeclRefExpr *Ref = nullptr; 4710 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 4711 Captures[Capture] = Ref; 4712 return Res; 4713 } 4714 4715 /// Build the expression to calculate the number of iterations. 4716 Expr *OpenMPIterationSpaceChecker::buildNumIterations( 4717 Scope *S, const bool LimitedType, 4718 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 4719 ExprResult Diff; 4720 QualType VarType = LCDecl->getType().getNonReferenceType(); 4721 if (VarType->isIntegerType() || VarType->isPointerType() || 4722 SemaRef.getLangOpts().CPlusPlus) { 4723 // Upper - Lower 4724 Expr *UBExpr = TestIsLessOp.getValue() ? UB : LB; 4725 Expr *LBExpr = TestIsLessOp.getValue() ? LB : UB; 4726 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 4727 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 4728 if (!Upper || !Lower) 4729 return nullptr; 4730 4731 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4732 4733 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4734 // BuildBinOp already emitted error, this one is to point user to upper 4735 // and lower bound, and to tell what is passed to 'operator-'. 4736 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 4737 << Upper->getSourceRange() << Lower->getSourceRange(); 4738 return nullptr; 4739 } 4740 } 4741 4742 if (!Diff.isUsable()) 4743 return nullptr; 4744 4745 // Upper - Lower [- 1] 4746 if (TestIsStrictOp) 4747 Diff = SemaRef.BuildBinOp( 4748 S, DefaultLoc, BO_Sub, Diff.get(), 4749 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4750 if (!Diff.isUsable()) 4751 return nullptr; 4752 4753 // Upper - Lower [- 1] + Step 4754 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 4755 if (!NewStep.isUsable()) 4756 return nullptr; 4757 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 4758 if (!Diff.isUsable()) 4759 return nullptr; 4760 4761 // Parentheses (for dumping/debugging purposes only). 4762 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4763 if (!Diff.isUsable()) 4764 return nullptr; 4765 4766 // (Upper - Lower [- 1] + Step) / Step 4767 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4768 if (!Diff.isUsable()) 4769 return nullptr; 4770 4771 // OpenMP runtime requires 32-bit or 64-bit loop variables. 4772 QualType Type = Diff.get()->getType(); 4773 ASTContext &C = SemaRef.Context; 4774 bool UseVarType = VarType->hasIntegerRepresentation() && 4775 C.getTypeSize(Type) > C.getTypeSize(VarType); 4776 if (!Type->isIntegerType() || UseVarType) { 4777 unsigned NewSize = 4778 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 4779 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 4780 : Type->hasSignedIntegerRepresentation(); 4781 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 4782 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 4783 Diff = SemaRef.PerformImplicitConversion( 4784 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 4785 if (!Diff.isUsable()) 4786 return nullptr; 4787 } 4788 } 4789 if (LimitedType) { 4790 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 4791 if (NewSize != C.getTypeSize(Type)) { 4792 if (NewSize < C.getTypeSize(Type)) { 4793 assert(NewSize == 64 && "incorrect loop var size"); 4794 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 4795 << InitSrcRange << ConditionSrcRange; 4796 } 4797 QualType NewType = C.getIntTypeForBitwidth( 4798 NewSize, Type->hasSignedIntegerRepresentation() || 4799 C.getTypeSize(Type) < NewSize); 4800 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 4801 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 4802 Sema::AA_Converting, true); 4803 if (!Diff.isUsable()) 4804 return nullptr; 4805 } 4806 } 4807 } 4808 4809 return Diff.get(); 4810 } 4811 4812 Expr *OpenMPIterationSpaceChecker::buildPreCond( 4813 Scope *S, Expr *Cond, 4814 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) const { 4815 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 4816 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4817 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4818 4819 ExprResult NewLB = tryBuildCapture(SemaRef, LB, Captures); 4820 ExprResult NewUB = tryBuildCapture(SemaRef, UB, Captures); 4821 if (!NewLB.isUsable() || !NewUB.isUsable()) 4822 return nullptr; 4823 4824 ExprResult CondExpr = 4825 SemaRef.BuildBinOp(S, DefaultLoc, 4826 TestIsLessOp.getValue() ? 4827 (TestIsStrictOp ? BO_LT : BO_LE) : 4828 (TestIsStrictOp ? BO_GT : BO_GE), 4829 NewLB.get(), NewUB.get()); 4830 if (CondExpr.isUsable()) { 4831 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 4832 SemaRef.Context.BoolTy)) 4833 CondExpr = SemaRef.PerformImplicitConversion( 4834 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 4835 /*AllowExplicit=*/true); 4836 } 4837 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4838 // Otherwise use original loop condition and evaluate it in runtime. 4839 return CondExpr.isUsable() ? CondExpr.get() : Cond; 4840 } 4841 4842 /// Build reference expression to the counter be used for codegen. 4843 DeclRefExpr *OpenMPIterationSpaceChecker::buildCounterVar( 4844 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, 4845 DSAStackTy &DSA) const { 4846 auto *VD = dyn_cast<VarDecl>(LCDecl); 4847 if (!VD) { 4848 VD = SemaRef.isOpenMPCapturedDecl(LCDecl); 4849 DeclRefExpr *Ref = buildDeclRefExpr( 4850 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 4851 const DSAStackTy::DSAVarData Data = 4852 DSA.getTopDSA(LCDecl, /*FromParent=*/false); 4853 // If the loop control decl is explicitly marked as private, do not mark it 4854 // as captured again. 4855 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 4856 Captures.insert(std::make_pair(LCRef, Ref)); 4857 return Ref; 4858 } 4859 return cast<DeclRefExpr>(LCRef); 4860 } 4861 4862 Expr *OpenMPIterationSpaceChecker::buildPrivateCounterVar() const { 4863 if (LCDecl && !LCDecl->isInvalidDecl()) { 4864 QualType Type = LCDecl->getType().getNonReferenceType(); 4865 VarDecl *PrivateVar = buildVarDecl( 4866 SemaRef, DefaultLoc, Type, LCDecl->getName(), 4867 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr, 4868 isa<VarDecl>(LCDecl) 4869 ? buildDeclRefExpr(SemaRef, cast<VarDecl>(LCDecl), Type, DefaultLoc) 4870 : nullptr); 4871 if (PrivateVar->isInvalidDecl()) 4872 return nullptr; 4873 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 4874 } 4875 return nullptr; 4876 } 4877 4878 /// Build initialization of the counter to be used for codegen. 4879 Expr *OpenMPIterationSpaceChecker::buildCounterInit() const { return LB; } 4880 4881 /// Build step of the counter be used for codegen. 4882 Expr *OpenMPIterationSpaceChecker::buildCounterStep() const { return Step; } 4883 4884 Expr *OpenMPIterationSpaceChecker::buildOrderedLoopData( 4885 Scope *S, Expr *Counter, 4886 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures, SourceLocation Loc, 4887 Expr *Inc, OverloadedOperatorKind OOK) { 4888 Expr *Cnt = SemaRef.DefaultLvalueConversion(Counter).get(); 4889 if (!Cnt) 4890 return nullptr; 4891 if (Inc) { 4892 assert((OOK == OO_Plus || OOK == OO_Minus) && 4893 "Expected only + or - operations for depend clauses."); 4894 BinaryOperatorKind BOK = (OOK == OO_Plus) ? BO_Add : BO_Sub; 4895 Cnt = SemaRef.BuildBinOp(S, Loc, BOK, Cnt, Inc).get(); 4896 if (!Cnt) 4897 return nullptr; 4898 } 4899 ExprResult Diff; 4900 QualType VarType = LCDecl->getType().getNonReferenceType(); 4901 if (VarType->isIntegerType() || VarType->isPointerType() || 4902 SemaRef.getLangOpts().CPlusPlus) { 4903 // Upper - Lower 4904 Expr *Upper = TestIsLessOp.getValue() 4905 ? Cnt 4906 : tryBuildCapture(SemaRef, UB, Captures).get(); 4907 Expr *Lower = TestIsLessOp.getValue() 4908 ? tryBuildCapture(SemaRef, LB, Captures).get() 4909 : Cnt; 4910 if (!Upper || !Lower) 4911 return nullptr; 4912 4913 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4914 4915 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4916 // BuildBinOp already emitted error, this one is to point user to upper 4917 // and lower bound, and to tell what is passed to 'operator-'. 4918 SemaRef.Diag(Upper->getBeginLoc(), diag::err_omp_loop_diff_cxx) 4919 << Upper->getSourceRange() << Lower->getSourceRange(); 4920 return nullptr; 4921 } 4922 } 4923 4924 if (!Diff.isUsable()) 4925 return nullptr; 4926 4927 // Parentheses (for dumping/debugging purposes only). 4928 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4929 if (!Diff.isUsable()) 4930 return nullptr; 4931 4932 ExprResult NewStep = tryBuildCapture(SemaRef, Step, Captures); 4933 if (!NewStep.isUsable()) 4934 return nullptr; 4935 // (Upper - Lower) / Step 4936 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4937 if (!Diff.isUsable()) 4938 return nullptr; 4939 4940 return Diff.get(); 4941 } 4942 4943 /// Iteration space of a single for loop. 4944 struct LoopIterationSpace final { 4945 /// True if the condition operator is the strict compare operator (<, > or 4946 /// !=). 4947 bool IsStrictCompare = false; 4948 /// Condition of the loop. 4949 Expr *PreCond = nullptr; 4950 /// This expression calculates the number of iterations in the loop. 4951 /// It is always possible to calculate it before starting the loop. 4952 Expr *NumIterations = nullptr; 4953 /// The loop counter variable. 4954 Expr *CounterVar = nullptr; 4955 /// Private loop counter variable. 4956 Expr *PrivateCounterVar = nullptr; 4957 /// This is initializer for the initial value of #CounterVar. 4958 Expr *CounterInit = nullptr; 4959 /// This is step for the #CounterVar used to generate its update: 4960 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4961 Expr *CounterStep = nullptr; 4962 /// Should step be subtracted? 4963 bool Subtract = false; 4964 /// Source range of the loop init. 4965 SourceRange InitSrcRange; 4966 /// Source range of the loop condition. 4967 SourceRange CondSrcRange; 4968 /// Source range of the loop increment. 4969 SourceRange IncSrcRange; 4970 }; 4971 4972 } // namespace 4973 4974 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 4975 assert(getLangOpts().OpenMP && "OpenMP is not active."); 4976 assert(Init && "Expected loop in canonical form."); 4977 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 4978 if (AssociatedLoops > 0 && 4979 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 4980 DSAStack->loopStart(); 4981 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 4982 if (!ISC.checkAndSetInit(Init, /*EmitDiags=*/false)) { 4983 if (ValueDecl *D = ISC.getLoopDecl()) { 4984 auto *VD = dyn_cast<VarDecl>(D); 4985 if (!VD) { 4986 if (VarDecl *Private = isOpenMPCapturedDecl(D)) { 4987 VD = Private; 4988 } else { 4989 DeclRefExpr *Ref = buildCapture(*this, D, ISC.getLoopDeclRefExpr(), 4990 /*WithInit=*/false); 4991 VD = cast<VarDecl>(Ref->getDecl()); 4992 } 4993 } 4994 DSAStack->addLoopControlVariable(D, VD); 4995 const Decl *LD = DSAStack->getPossiblyLoopCunter(); 4996 if (LD != D->getCanonicalDecl()) { 4997 DSAStack->resetPossibleLoopCounter(); 4998 if (auto *Var = dyn_cast_or_null<VarDecl>(LD)) 4999 MarkDeclarationsReferencedInExpr( 5000 buildDeclRefExpr(*this, const_cast<VarDecl *>(Var), 5001 Var->getType().getNonLValueExprType(Context), 5002 ForLoc, /*RefersToCapture=*/true)); 5003 } 5004 } 5005 } 5006 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 5007 } 5008 } 5009 5010 /// Called on a for stmt to check and extract its iteration space 5011 /// for further processing (such as collapsing). 5012 static bool checkOpenMPIterationSpace( 5013 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 5014 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 5015 unsigned TotalNestedLoopCount, Expr *CollapseLoopCountExpr, 5016 Expr *OrderedLoopCountExpr, 5017 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5018 LoopIterationSpace &ResultIterSpace, 5019 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5020 // OpenMP [2.6, Canonical Loop Form] 5021 // for (init-expr; test-expr; incr-expr) structured-block 5022 auto *For = dyn_cast_or_null<ForStmt>(S); 5023 if (!For) { 5024 SemaRef.Diag(S->getBeginLoc(), diag::err_omp_not_for) 5025 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 5026 << getOpenMPDirectiveName(DKind) << TotalNestedLoopCount 5027 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 5028 if (TotalNestedLoopCount > 1) { 5029 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 5030 SemaRef.Diag(DSA.getConstructLoc(), 5031 diag::note_omp_collapse_ordered_expr) 5032 << 2 << CollapseLoopCountExpr->getSourceRange() 5033 << OrderedLoopCountExpr->getSourceRange(); 5034 else if (CollapseLoopCountExpr) 5035 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5036 diag::note_omp_collapse_ordered_expr) 5037 << 0 << CollapseLoopCountExpr->getSourceRange(); 5038 else 5039 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5040 diag::note_omp_collapse_ordered_expr) 5041 << 1 << OrderedLoopCountExpr->getSourceRange(); 5042 } 5043 return true; 5044 } 5045 assert(For->getBody()); 5046 5047 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 5048 5049 // Check init. 5050 Stmt *Init = For->getInit(); 5051 if (ISC.checkAndSetInit(Init)) 5052 return true; 5053 5054 bool HasErrors = false; 5055 5056 // Check loop variable's type. 5057 if (ValueDecl *LCDecl = ISC.getLoopDecl()) { 5058 Expr *LoopDeclRefExpr = ISC.getLoopDeclRefExpr(); 5059 5060 // OpenMP [2.6, Canonical Loop Form] 5061 // Var is one of the following: 5062 // A variable of signed or unsigned integer type. 5063 // For C++, a variable of a random access iterator type. 5064 // For C, a variable of a pointer type. 5065 QualType VarType = LCDecl->getType().getNonReferenceType(); 5066 if (!VarType->isDependentType() && !VarType->isIntegerType() && 5067 !VarType->isPointerType() && 5068 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 5069 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_variable_type) 5070 << SemaRef.getLangOpts().CPlusPlus; 5071 HasErrors = true; 5072 } 5073 5074 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 5075 // a Construct 5076 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5077 // parallel for construct is (are) private. 5078 // The loop iteration variable in the associated for-loop of a simd 5079 // construct with just one associated for-loop is linear with a 5080 // constant-linear-step that is the increment of the associated for-loop. 5081 // Exclude loop var from the list of variables with implicitly defined data 5082 // sharing attributes. 5083 VarsWithImplicitDSA.erase(LCDecl); 5084 5085 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 5086 // in a Construct, C/C++]. 5087 // The loop iteration variable in the associated for-loop of a simd 5088 // construct with just one associated for-loop may be listed in a linear 5089 // clause with a constant-linear-step that is the increment of the 5090 // associated for-loop. 5091 // The loop iteration variable(s) in the associated for-loop(s) of a for or 5092 // parallel for construct may be listed in a private or lastprivate clause. 5093 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 5094 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 5095 // declared in the loop and it is predetermined as a private. 5096 OpenMPClauseKind PredeterminedCKind = 5097 isOpenMPSimdDirective(DKind) 5098 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 5099 : OMPC_private; 5100 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5101 DVar.CKind != PredeterminedCKind) || 5102 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 5103 isOpenMPDistributeDirective(DKind)) && 5104 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5105 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 5106 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 5107 SemaRef.Diag(Init->getBeginLoc(), diag::err_omp_loop_var_dsa) 5108 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 5109 << getOpenMPClauseName(PredeterminedCKind); 5110 if (DVar.RefExpr == nullptr) 5111 DVar.CKind = PredeterminedCKind; 5112 reportOriginalDsa(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 5113 HasErrors = true; 5114 } else if (LoopDeclRefExpr != nullptr) { 5115 // Make the loop iteration variable private (for worksharing constructs), 5116 // linear (for simd directives with the only one associated loop) or 5117 // lastprivate (for simd directives with several collapsed or ordered 5118 // loops). 5119 if (DVar.CKind == OMPC_unknown) 5120 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 5121 } 5122 5123 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 5124 5125 // Check test-expr. 5126 HasErrors |= ISC.checkAndSetCond(For->getCond()); 5127 5128 // Check incr-expr. 5129 HasErrors |= ISC.checkAndSetInc(For->getInc()); 5130 } 5131 5132 if (ISC.dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 5133 return HasErrors; 5134 5135 // Build the loop's iteration space representation. 5136 ResultIterSpace.PreCond = 5137 ISC.buildPreCond(DSA.getCurScope(), For->getCond(), Captures); 5138 ResultIterSpace.NumIterations = ISC.buildNumIterations( 5139 DSA.getCurScope(), 5140 (isOpenMPWorksharingDirective(DKind) || 5141 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 5142 Captures); 5143 ResultIterSpace.CounterVar = ISC.buildCounterVar(Captures, DSA); 5144 ResultIterSpace.PrivateCounterVar = ISC.buildPrivateCounterVar(); 5145 ResultIterSpace.CounterInit = ISC.buildCounterInit(); 5146 ResultIterSpace.CounterStep = ISC.buildCounterStep(); 5147 ResultIterSpace.InitSrcRange = ISC.getInitSrcRange(); 5148 ResultIterSpace.CondSrcRange = ISC.getConditionSrcRange(); 5149 ResultIterSpace.IncSrcRange = ISC.getIncrementSrcRange(); 5150 ResultIterSpace.Subtract = ISC.shouldSubtractStep(); 5151 ResultIterSpace.IsStrictCompare = ISC.isStrictTestOp(); 5152 5153 HasErrors |= (ResultIterSpace.PreCond == nullptr || 5154 ResultIterSpace.NumIterations == nullptr || 5155 ResultIterSpace.CounterVar == nullptr || 5156 ResultIterSpace.PrivateCounterVar == nullptr || 5157 ResultIterSpace.CounterInit == nullptr || 5158 ResultIterSpace.CounterStep == nullptr); 5159 if (!HasErrors && DSA.isOrderedRegion()) { 5160 if (DSA.getOrderedRegionParam().second->getNumForLoops()) { 5161 if (CurrentNestedLoopCount < 5162 DSA.getOrderedRegionParam().second->getLoopNumIterations().size()) { 5163 DSA.getOrderedRegionParam().second->setLoopNumIterations( 5164 CurrentNestedLoopCount, ResultIterSpace.NumIterations); 5165 DSA.getOrderedRegionParam().second->setLoopCounter( 5166 CurrentNestedLoopCount, ResultIterSpace.CounterVar); 5167 } 5168 } 5169 for (auto &Pair : DSA.getDoacrossDependClauses()) { 5170 if (CurrentNestedLoopCount >= Pair.first->getNumLoops()) { 5171 // Erroneous case - clause has some problems. 5172 continue; 5173 } 5174 if (Pair.first->getDependencyKind() == OMPC_DEPEND_sink && 5175 Pair.second.size() <= CurrentNestedLoopCount) { 5176 // Erroneous case - clause has some problems. 5177 Pair.first->setLoopData(CurrentNestedLoopCount, nullptr); 5178 continue; 5179 } 5180 Expr *CntValue; 5181 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 5182 CntValue = ISC.buildOrderedLoopData( 5183 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5184 Pair.first->getDependencyLoc()); 5185 else 5186 CntValue = ISC.buildOrderedLoopData( 5187 DSA.getCurScope(), ResultIterSpace.CounterVar, Captures, 5188 Pair.first->getDependencyLoc(), 5189 Pair.second[CurrentNestedLoopCount].first, 5190 Pair.second[CurrentNestedLoopCount].second); 5191 Pair.first->setLoopData(CurrentNestedLoopCount, CntValue); 5192 } 5193 } 5194 5195 return HasErrors; 5196 } 5197 5198 /// Build 'VarRef = Start. 5199 static ExprResult 5200 buildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5201 ExprResult Start, 5202 llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5203 // Build 'VarRef = Start. 5204 ExprResult NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 5205 if (!NewStart.isUsable()) 5206 return ExprError(); 5207 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 5208 VarRef.get()->getType())) { 5209 NewStart = SemaRef.PerformImplicitConversion( 5210 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 5211 /*AllowExplicit=*/true); 5212 if (!NewStart.isUsable()) 5213 return ExprError(); 5214 } 5215 5216 ExprResult Init = 5217 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5218 return Init; 5219 } 5220 5221 /// Build 'VarRef = Start + Iter * Step'. 5222 static ExprResult buildCounterUpdate( 5223 Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5224 ExprResult Start, ExprResult Iter, ExprResult Step, bool Subtract, 5225 llvm::MapVector<const Expr *, DeclRefExpr *> *Captures = nullptr) { 5226 // Add parentheses (for debugging purposes only). 5227 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 5228 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 5229 !Step.isUsable()) 5230 return ExprError(); 5231 5232 ExprResult NewStep = Step; 5233 if (Captures) 5234 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 5235 if (NewStep.isInvalid()) 5236 return ExprError(); 5237 ExprResult Update = 5238 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 5239 if (!Update.isUsable()) 5240 return ExprError(); 5241 5242 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 5243 // 'VarRef = Start (+|-) Iter * Step'. 5244 ExprResult NewStart = Start; 5245 if (Captures) 5246 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 5247 if (NewStart.isInvalid()) 5248 return ExprError(); 5249 5250 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 5251 ExprResult SavedUpdate = Update; 5252 ExprResult UpdateVal; 5253 if (VarRef.get()->getType()->isOverloadableType() || 5254 NewStart.get()->getType()->isOverloadableType() || 5255 Update.get()->getType()->isOverloadableType()) { 5256 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5257 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5258 Update = 5259 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5260 if (Update.isUsable()) { 5261 UpdateVal = 5262 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 5263 VarRef.get(), SavedUpdate.get()); 5264 if (UpdateVal.isUsable()) { 5265 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 5266 UpdateVal.get()); 5267 } 5268 } 5269 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5270 } 5271 5272 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 5273 if (!Update.isUsable() || !UpdateVal.isUsable()) { 5274 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 5275 NewStart.get(), SavedUpdate.get()); 5276 if (!Update.isUsable()) 5277 return ExprError(); 5278 5279 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 5280 VarRef.get()->getType())) { 5281 Update = SemaRef.PerformImplicitConversion( 5282 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 5283 if (!Update.isUsable()) 5284 return ExprError(); 5285 } 5286 5287 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 5288 } 5289 return Update; 5290 } 5291 5292 /// Convert integer expression \a E to make it have at least \a Bits 5293 /// bits. 5294 static ExprResult widenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 5295 if (E == nullptr) 5296 return ExprError(); 5297 ASTContext &C = SemaRef.Context; 5298 QualType OldType = E->getType(); 5299 unsigned HasBits = C.getTypeSize(OldType); 5300 if (HasBits >= Bits) 5301 return ExprResult(E); 5302 // OK to convert to signed, because new type has more bits than old. 5303 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 5304 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 5305 true); 5306 } 5307 5308 /// Check if the given expression \a E is a constant integer that fits 5309 /// into \a Bits bits. 5310 static bool fitsInto(unsigned Bits, bool Signed, const Expr *E, Sema &SemaRef) { 5311 if (E == nullptr) 5312 return false; 5313 llvm::APSInt Result; 5314 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 5315 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 5316 return false; 5317 } 5318 5319 /// Build preinits statement for the given declarations. 5320 static Stmt *buildPreInits(ASTContext &Context, 5321 MutableArrayRef<Decl *> PreInits) { 5322 if (!PreInits.empty()) { 5323 return new (Context) DeclStmt( 5324 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 5325 SourceLocation(), SourceLocation()); 5326 } 5327 return nullptr; 5328 } 5329 5330 /// Build preinits statement for the given declarations. 5331 static Stmt * 5332 buildPreInits(ASTContext &Context, 5333 const llvm::MapVector<const Expr *, DeclRefExpr *> &Captures) { 5334 if (!Captures.empty()) { 5335 SmallVector<Decl *, 16> PreInits; 5336 for (const auto &Pair : Captures) 5337 PreInits.push_back(Pair.second->getDecl()); 5338 return buildPreInits(Context, PreInits); 5339 } 5340 return nullptr; 5341 } 5342 5343 /// Build postupdate expression for the given list of postupdates expressions. 5344 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 5345 Expr *PostUpdate = nullptr; 5346 if (!PostUpdates.empty()) { 5347 for (Expr *E : PostUpdates) { 5348 Expr *ConvE = S.BuildCStyleCastExpr( 5349 E->getExprLoc(), 5350 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 5351 E->getExprLoc(), E) 5352 .get(); 5353 PostUpdate = PostUpdate 5354 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 5355 PostUpdate, ConvE) 5356 .get() 5357 : ConvE; 5358 } 5359 } 5360 return PostUpdate; 5361 } 5362 5363 /// Called on a for stmt to check itself and nested loops (if any). 5364 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 5365 /// number of collapsed loops otherwise. 5366 static unsigned 5367 checkOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 5368 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 5369 DSAStackTy &DSA, 5370 Sema::VarsWithInheritedDSAType &VarsWithImplicitDSA, 5371 OMPLoopDirective::HelperExprs &Built) { 5372 unsigned NestedLoopCount = 1; 5373 if (CollapseLoopCountExpr) { 5374 // Found 'collapse' clause - calculate collapse number. 5375 Expr::EvalResult Result; 5376 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 5377 NestedLoopCount = Result.Val.getInt().getLimitedValue(); 5378 } 5379 unsigned OrderedLoopCount = 1; 5380 if (OrderedLoopCountExpr) { 5381 // Found 'ordered' clause - calculate collapse number. 5382 Expr::EvalResult EVResult; 5383 if (OrderedLoopCountExpr->EvaluateAsInt(EVResult, SemaRef.getASTContext())) { 5384 llvm::APSInt Result = EVResult.Val.getInt(); 5385 if (Result.getLimitedValue() < NestedLoopCount) { 5386 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5387 diag::err_omp_wrong_ordered_loop_count) 5388 << OrderedLoopCountExpr->getSourceRange(); 5389 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5390 diag::note_collapse_loop_count) 5391 << CollapseLoopCountExpr->getSourceRange(); 5392 } 5393 OrderedLoopCount = Result.getLimitedValue(); 5394 } 5395 } 5396 // This is helper routine for loop directives (e.g., 'for', 'simd', 5397 // 'for simd', etc.). 5398 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 5399 SmallVector<LoopIterationSpace, 4> IterSpaces( 5400 std::max(OrderedLoopCount, NestedLoopCount)); 5401 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 5402 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 5403 if (checkOpenMPIterationSpace( 5404 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 5405 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 5406 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 5407 Captures)) 5408 return 0; 5409 // Move on to the next nested for loop, or to the loop body. 5410 // OpenMP [2.8.1, simd construct, Restrictions] 5411 // All loops associated with the construct must be perfectly nested; that 5412 // is, there must be no intervening code nor any OpenMP directive between 5413 // any two loops. 5414 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 5415 } 5416 for (unsigned Cnt = NestedLoopCount; Cnt < OrderedLoopCount; ++Cnt) { 5417 if (checkOpenMPIterationSpace( 5418 DKind, CurStmt, SemaRef, DSA, Cnt, NestedLoopCount, 5419 std::max(OrderedLoopCount, NestedLoopCount), CollapseLoopCountExpr, 5420 OrderedLoopCountExpr, VarsWithImplicitDSA, IterSpaces[Cnt], 5421 Captures)) 5422 return 0; 5423 if (Cnt > 0 && IterSpaces[Cnt].CounterVar) { 5424 // Handle initialization of captured loop iterator variables. 5425 auto *DRE = cast<DeclRefExpr>(IterSpaces[Cnt].CounterVar); 5426 if (isa<OMPCapturedExprDecl>(DRE->getDecl())) { 5427 Captures[DRE] = DRE; 5428 } 5429 } 5430 // Move on to the next nested for loop, or to the loop body. 5431 // OpenMP [2.8.1, simd construct, Restrictions] 5432 // All loops associated with the construct must be perfectly nested; that 5433 // is, there must be no intervening code nor any OpenMP directive between 5434 // any two loops. 5435 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 5436 } 5437 5438 Built.clear(/* size */ NestedLoopCount); 5439 5440 if (SemaRef.CurContext->isDependentContext()) 5441 return NestedLoopCount; 5442 5443 // An example of what is generated for the following code: 5444 // 5445 // #pragma omp simd collapse(2) ordered(2) 5446 // for (i = 0; i < NI; ++i) 5447 // for (k = 0; k < NK; ++k) 5448 // for (j = J0; j < NJ; j+=2) { 5449 // <loop body> 5450 // } 5451 // 5452 // We generate the code below. 5453 // Note: the loop body may be outlined in CodeGen. 5454 // Note: some counters may be C++ classes, operator- is used to find number of 5455 // iterations and operator+= to calculate counter value. 5456 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 5457 // or i64 is currently supported). 5458 // 5459 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 5460 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 5461 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 5462 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 5463 // // similar updates for vars in clauses (e.g. 'linear') 5464 // <loop body (using local i and j)> 5465 // } 5466 // i = NI; // assign final values of counters 5467 // j = NJ; 5468 // 5469 5470 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 5471 // the iteration counts of the collapsed for loops. 5472 // Precondition tests if there is at least one iteration (all conditions are 5473 // true). 5474 auto PreCond = ExprResult(IterSpaces[0].PreCond); 5475 Expr *N0 = IterSpaces[0].NumIterations; 5476 ExprResult LastIteration32 = 5477 widenIterationCount(/*Bits=*/32, 5478 SemaRef 5479 .PerformImplicitConversion( 5480 N0->IgnoreImpCasts(), N0->getType(), 5481 Sema::AA_Converting, /*AllowExplicit=*/true) 5482 .get(), 5483 SemaRef); 5484 ExprResult LastIteration64 = widenIterationCount( 5485 /*Bits=*/64, 5486 SemaRef 5487 .PerformImplicitConversion(N0->IgnoreImpCasts(), N0->getType(), 5488 Sema::AA_Converting, 5489 /*AllowExplicit=*/true) 5490 .get(), 5491 SemaRef); 5492 5493 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 5494 return NestedLoopCount; 5495 5496 ASTContext &C = SemaRef.Context; 5497 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 5498 5499 Scope *CurScope = DSA.getCurScope(); 5500 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 5501 if (PreCond.isUsable()) { 5502 PreCond = 5503 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 5504 PreCond.get(), IterSpaces[Cnt].PreCond); 5505 } 5506 Expr *N = IterSpaces[Cnt].NumIterations; 5507 SourceLocation Loc = N->getExprLoc(); 5508 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 5509 if (LastIteration32.isUsable()) 5510 LastIteration32 = SemaRef.BuildBinOp( 5511 CurScope, Loc, BO_Mul, LastIteration32.get(), 5512 SemaRef 5513 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5514 Sema::AA_Converting, 5515 /*AllowExplicit=*/true) 5516 .get()); 5517 if (LastIteration64.isUsable()) 5518 LastIteration64 = SemaRef.BuildBinOp( 5519 CurScope, Loc, BO_Mul, LastIteration64.get(), 5520 SemaRef 5521 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5522 Sema::AA_Converting, 5523 /*AllowExplicit=*/true) 5524 .get()); 5525 } 5526 5527 // Choose either the 32-bit or 64-bit version. 5528 ExprResult LastIteration = LastIteration64; 5529 if (SemaRef.getLangOpts().OpenMPOptimisticCollapse || 5530 (LastIteration32.isUsable() && 5531 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 5532 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 5533 fitsInto( 5534 /*Bits=*/32, 5535 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 5536 LastIteration64.get(), SemaRef)))) 5537 LastIteration = LastIteration32; 5538 QualType VType = LastIteration.get()->getType(); 5539 QualType RealVType = VType; 5540 QualType StrideVType = VType; 5541 if (isOpenMPTaskLoopDirective(DKind)) { 5542 VType = 5543 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 5544 StrideVType = 5545 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 5546 } 5547 5548 if (!LastIteration.isUsable()) 5549 return 0; 5550 5551 // Save the number of iterations. 5552 ExprResult NumIterations = LastIteration; 5553 { 5554 LastIteration = SemaRef.BuildBinOp( 5555 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 5556 LastIteration.get(), 5557 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5558 if (!LastIteration.isUsable()) 5559 return 0; 5560 } 5561 5562 // Calculate the last iteration number beforehand instead of doing this on 5563 // each iteration. Do not do this if the number of iterations may be kfold-ed. 5564 llvm::APSInt Result; 5565 bool IsConstant = 5566 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 5567 ExprResult CalcLastIteration; 5568 if (!IsConstant) { 5569 ExprResult SaveRef = 5570 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 5571 LastIteration = SaveRef; 5572 5573 // Prepare SaveRef + 1. 5574 NumIterations = SemaRef.BuildBinOp( 5575 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 5576 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5577 if (!NumIterations.isUsable()) 5578 return 0; 5579 } 5580 5581 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 5582 5583 // Build variables passed into runtime, necessary for worksharing directives. 5584 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 5585 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5586 isOpenMPDistributeDirective(DKind)) { 5587 // Lower bound variable, initialized with zero. 5588 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 5589 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 5590 SemaRef.AddInitializerToDecl(LBDecl, 5591 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5592 /*DirectInit*/ false); 5593 5594 // Upper bound variable, initialized with last iteration number. 5595 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 5596 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 5597 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 5598 /*DirectInit*/ false); 5599 5600 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 5601 // This will be used to implement clause 'lastprivate'. 5602 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 5603 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 5604 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 5605 SemaRef.AddInitializerToDecl(ILDecl, 5606 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5607 /*DirectInit*/ false); 5608 5609 // Stride variable returned by runtime (we initialize it to 1 by default). 5610 VarDecl *STDecl = 5611 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 5612 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 5613 SemaRef.AddInitializerToDecl(STDecl, 5614 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 5615 /*DirectInit*/ false); 5616 5617 // Build expression: UB = min(UB, LastIteration) 5618 // It is necessary for CodeGen of directives with static scheduling. 5619 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 5620 UB.get(), LastIteration.get()); 5621 ExprResult CondOp = SemaRef.ActOnConditionalOp( 5622 LastIteration.get()->getExprLoc(), InitLoc, IsUBGreater.get(), 5623 LastIteration.get(), UB.get()); 5624 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 5625 CondOp.get()); 5626 EUB = SemaRef.ActOnFinishFullExpr(EUB.get(), /*DiscardedValue*/ false); 5627 5628 // If we have a combined directive that combines 'distribute', 'for' or 5629 // 'simd' we need to be able to access the bounds of the schedule of the 5630 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 5631 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 5632 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5633 // Lower bound variable, initialized with zero. 5634 VarDecl *CombLBDecl = 5635 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 5636 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 5637 SemaRef.AddInitializerToDecl( 5638 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5639 /*DirectInit*/ false); 5640 5641 // Upper bound variable, initialized with last iteration number. 5642 VarDecl *CombUBDecl = 5643 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 5644 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 5645 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 5646 /*DirectInit*/ false); 5647 5648 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 5649 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 5650 ExprResult CombCondOp = 5651 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 5652 LastIteration.get(), CombUB.get()); 5653 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 5654 CombCondOp.get()); 5655 CombEUB = 5656 SemaRef.ActOnFinishFullExpr(CombEUB.get(), /*DiscardedValue*/ false); 5657 5658 const CapturedDecl *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 5659 // We expect to have at least 2 more parameters than the 'parallel' 5660 // directive does - the lower and upper bounds of the previous schedule. 5661 assert(CD->getNumParams() >= 4 && 5662 "Unexpected number of parameters in loop combined directive"); 5663 5664 // Set the proper type for the bounds given what we learned from the 5665 // enclosed loops. 5666 ImplicitParamDecl *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 5667 ImplicitParamDecl *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 5668 5669 // Previous lower and upper bounds are obtained from the region 5670 // parameters. 5671 PrevLB = 5672 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 5673 PrevUB = 5674 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 5675 } 5676 } 5677 5678 // Build the iteration variable and its initialization before loop. 5679 ExprResult IV; 5680 ExprResult Init, CombInit; 5681 { 5682 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 5683 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 5684 Expr *RHS = 5685 (isOpenMPWorksharingDirective(DKind) || 5686 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5687 ? LB.get() 5688 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 5689 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 5690 Init = SemaRef.ActOnFinishFullExpr(Init.get(), /*DiscardedValue*/ false); 5691 5692 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5693 Expr *CombRHS = 5694 (isOpenMPWorksharingDirective(DKind) || 5695 isOpenMPTaskLoopDirective(DKind) || 5696 isOpenMPDistributeDirective(DKind)) 5697 ? CombLB.get() 5698 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 5699 CombInit = 5700 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 5701 CombInit = 5702 SemaRef.ActOnFinishFullExpr(CombInit.get(), /*DiscardedValue*/ false); 5703 } 5704 } 5705 5706 bool UseStrictCompare = 5707 RealVType->hasUnsignedIntegerRepresentation() && 5708 llvm::all_of(IterSpaces, [](const LoopIterationSpace &LIS) { 5709 return LIS.IsStrictCompare; 5710 }); 5711 // Loop condition (IV < NumIterations) or (IV <= UB or IV < UB + 1 (for 5712 // unsigned IV)) for worksharing loops. 5713 SourceLocation CondLoc = AStmt->getBeginLoc(); 5714 Expr *BoundUB = UB.get(); 5715 if (UseStrictCompare) { 5716 BoundUB = 5717 SemaRef 5718 .BuildBinOp(CurScope, CondLoc, BO_Add, BoundUB, 5719 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 5720 .get(); 5721 BoundUB = 5722 SemaRef.ActOnFinishFullExpr(BoundUB, /*DiscardedValue*/ false).get(); 5723 } 5724 ExprResult Cond = 5725 (isOpenMPWorksharingDirective(DKind) || 5726 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5727 ? SemaRef.BuildBinOp(CurScope, CondLoc, 5728 UseStrictCompare ? BO_LT : BO_LE, IV.get(), 5729 BoundUB) 5730 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 5731 NumIterations.get()); 5732 ExprResult CombDistCond; 5733 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5734 CombDistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 5735 NumIterations.get()); 5736 } 5737 5738 ExprResult CombCond; 5739 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5740 Expr *BoundCombUB = CombUB.get(); 5741 if (UseStrictCompare) { 5742 BoundCombUB = 5743 SemaRef 5744 .BuildBinOp( 5745 CurScope, CondLoc, BO_Add, BoundCombUB, 5746 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 5747 .get(); 5748 BoundCombUB = 5749 SemaRef.ActOnFinishFullExpr(BoundCombUB, /*DiscardedValue*/ false) 5750 .get(); 5751 } 5752 CombCond = 5753 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 5754 IV.get(), BoundCombUB); 5755 } 5756 // Loop increment (IV = IV + 1) 5757 SourceLocation IncLoc = AStmt->getBeginLoc(); 5758 ExprResult Inc = 5759 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 5760 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 5761 if (!Inc.isUsable()) 5762 return 0; 5763 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 5764 Inc = SemaRef.ActOnFinishFullExpr(Inc.get(), /*DiscardedValue*/ false); 5765 if (!Inc.isUsable()) 5766 return 0; 5767 5768 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 5769 // Used for directives with static scheduling. 5770 // In combined construct, add combined version that use CombLB and CombUB 5771 // base variables for the update 5772 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 5773 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5774 isOpenMPDistributeDirective(DKind)) { 5775 // LB + ST 5776 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 5777 if (!NextLB.isUsable()) 5778 return 0; 5779 // LB = LB + ST 5780 NextLB = 5781 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 5782 NextLB = 5783 SemaRef.ActOnFinishFullExpr(NextLB.get(), /*DiscardedValue*/ false); 5784 if (!NextLB.isUsable()) 5785 return 0; 5786 // UB + ST 5787 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 5788 if (!NextUB.isUsable()) 5789 return 0; 5790 // UB = UB + ST 5791 NextUB = 5792 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 5793 NextUB = 5794 SemaRef.ActOnFinishFullExpr(NextUB.get(), /*DiscardedValue*/ false); 5795 if (!NextUB.isUsable()) 5796 return 0; 5797 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5798 CombNextLB = 5799 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 5800 if (!NextLB.isUsable()) 5801 return 0; 5802 // LB = LB + ST 5803 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 5804 CombNextLB.get()); 5805 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get(), 5806 /*DiscardedValue*/ false); 5807 if (!CombNextLB.isUsable()) 5808 return 0; 5809 // UB + ST 5810 CombNextUB = 5811 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 5812 if (!CombNextUB.isUsable()) 5813 return 0; 5814 // UB = UB + ST 5815 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 5816 CombNextUB.get()); 5817 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get(), 5818 /*DiscardedValue*/ false); 5819 if (!CombNextUB.isUsable()) 5820 return 0; 5821 } 5822 } 5823 5824 // Create increment expression for distribute loop when combined in a same 5825 // directive with for as IV = IV + ST; ensure upper bound expression based 5826 // on PrevUB instead of NumIterations - used to implement 'for' when found 5827 // in combination with 'distribute', like in 'distribute parallel for' 5828 SourceLocation DistIncLoc = AStmt->getBeginLoc(); 5829 ExprResult DistCond, DistInc, PrevEUB, ParForInDistCond; 5830 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5831 DistCond = SemaRef.BuildBinOp( 5832 CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, IV.get(), BoundUB); 5833 assert(DistCond.isUsable() && "distribute cond expr was not built"); 5834 5835 DistInc = 5836 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 5837 assert(DistInc.isUsable() && "distribute inc expr was not built"); 5838 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 5839 DistInc.get()); 5840 DistInc = 5841 SemaRef.ActOnFinishFullExpr(DistInc.get(), /*DiscardedValue*/ false); 5842 assert(DistInc.isUsable() && "distribute inc expr was not built"); 5843 5844 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 5845 // construct 5846 SourceLocation DistEUBLoc = AStmt->getBeginLoc(); 5847 ExprResult IsUBGreater = 5848 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 5849 ExprResult CondOp = SemaRef.ActOnConditionalOp( 5850 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 5851 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 5852 CondOp.get()); 5853 PrevEUB = 5854 SemaRef.ActOnFinishFullExpr(PrevEUB.get(), /*DiscardedValue*/ false); 5855 5856 // Build IV <= PrevUB or IV < PrevUB + 1 for unsigned IV to be used in 5857 // parallel for is in combination with a distribute directive with 5858 // schedule(static, 1) 5859 Expr *BoundPrevUB = PrevUB.get(); 5860 if (UseStrictCompare) { 5861 BoundPrevUB = 5862 SemaRef 5863 .BuildBinOp( 5864 CurScope, CondLoc, BO_Add, BoundPrevUB, 5865 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()) 5866 .get(); 5867 BoundPrevUB = 5868 SemaRef.ActOnFinishFullExpr(BoundPrevUB, /*DiscardedValue*/ false) 5869 .get(); 5870 } 5871 ParForInDistCond = 5872 SemaRef.BuildBinOp(CurScope, CondLoc, UseStrictCompare ? BO_LT : BO_LE, 5873 IV.get(), BoundPrevUB); 5874 } 5875 5876 // Build updates and final values of the loop counters. 5877 bool HasErrors = false; 5878 Built.Counters.resize(NestedLoopCount); 5879 Built.Inits.resize(NestedLoopCount); 5880 Built.Updates.resize(NestedLoopCount); 5881 Built.Finals.resize(NestedLoopCount); 5882 { 5883 // We implement the following algorithm for obtaining the 5884 // original loop iteration variable values based on the 5885 // value of the collapsed loop iteration variable IV. 5886 // 5887 // Let n+1 be the number of collapsed loops in the nest. 5888 // Iteration variables (I0, I1, .... In) 5889 // Iteration counts (N0, N1, ... Nn) 5890 // 5891 // Acc = IV; 5892 // 5893 // To compute Ik for loop k, 0 <= k <= n, generate: 5894 // Prod = N(k+1) * N(k+2) * ... * Nn; 5895 // Ik = Acc / Prod; 5896 // Acc -= Ik * Prod; 5897 // 5898 ExprResult Acc = IV; 5899 for (unsigned int Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 5900 LoopIterationSpace &IS = IterSpaces[Cnt]; 5901 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 5902 ExprResult Iter; 5903 5904 // Compute prod 5905 ExprResult Prod = 5906 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 5907 for (unsigned int K = Cnt+1; K < NestedLoopCount; ++K) 5908 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Prod.get(), 5909 IterSpaces[K].NumIterations); 5910 5911 // Iter = Acc / Prod 5912 // If there is at least one more inner loop to avoid 5913 // multiplication by 1. 5914 if (Cnt + 1 < NestedLoopCount) 5915 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, 5916 Acc.get(), Prod.get()); 5917 else 5918 Iter = Acc; 5919 if (!Iter.isUsable()) { 5920 HasErrors = true; 5921 break; 5922 } 5923 5924 // Update Acc: 5925 // Acc -= Iter * Prod 5926 // Check if there is at least one more inner loop to avoid 5927 // multiplication by 1. 5928 if (Cnt + 1 < NestedLoopCount) 5929 Prod = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, 5930 Iter.get(), Prod.get()); 5931 else 5932 Prod = Iter; 5933 Acc = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Sub, 5934 Acc.get(), Prod.get()); 5935 5936 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 5937 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 5938 DeclRefExpr *CounterVar = buildDeclRefExpr( 5939 SemaRef, VD, IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 5940 /*RefersToCapture=*/true); 5941 ExprResult Init = buildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 5942 IS.CounterInit, Captures); 5943 if (!Init.isUsable()) { 5944 HasErrors = true; 5945 break; 5946 } 5947 ExprResult Update = buildCounterUpdate( 5948 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 5949 IS.CounterStep, IS.Subtract, &Captures); 5950 if (!Update.isUsable()) { 5951 HasErrors = true; 5952 break; 5953 } 5954 5955 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 5956 ExprResult Final = buildCounterUpdate( 5957 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 5958 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 5959 if (!Final.isUsable()) { 5960 HasErrors = true; 5961 break; 5962 } 5963 5964 if (!Update.isUsable() || !Final.isUsable()) { 5965 HasErrors = true; 5966 break; 5967 } 5968 // Save results 5969 Built.Counters[Cnt] = IS.CounterVar; 5970 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 5971 Built.Inits[Cnt] = Init.get(); 5972 Built.Updates[Cnt] = Update.get(); 5973 Built.Finals[Cnt] = Final.get(); 5974 } 5975 } 5976 5977 if (HasErrors) 5978 return 0; 5979 5980 // Save results 5981 Built.IterationVarRef = IV.get(); 5982 Built.LastIteration = LastIteration.get(); 5983 Built.NumIterations = NumIterations.get(); 5984 Built.CalcLastIteration = SemaRef 5985 .ActOnFinishFullExpr(CalcLastIteration.get(), 5986 /*DiscardedValue*/ false) 5987 .get(); 5988 Built.PreCond = PreCond.get(); 5989 Built.PreInits = buildPreInits(C, Captures); 5990 Built.Cond = Cond.get(); 5991 Built.Init = Init.get(); 5992 Built.Inc = Inc.get(); 5993 Built.LB = LB.get(); 5994 Built.UB = UB.get(); 5995 Built.IL = IL.get(); 5996 Built.ST = ST.get(); 5997 Built.EUB = EUB.get(); 5998 Built.NLB = NextLB.get(); 5999 Built.NUB = NextUB.get(); 6000 Built.PrevLB = PrevLB.get(); 6001 Built.PrevUB = PrevUB.get(); 6002 Built.DistInc = DistInc.get(); 6003 Built.PrevEUB = PrevEUB.get(); 6004 Built.DistCombinedFields.LB = CombLB.get(); 6005 Built.DistCombinedFields.UB = CombUB.get(); 6006 Built.DistCombinedFields.EUB = CombEUB.get(); 6007 Built.DistCombinedFields.Init = CombInit.get(); 6008 Built.DistCombinedFields.Cond = CombCond.get(); 6009 Built.DistCombinedFields.NLB = CombNextLB.get(); 6010 Built.DistCombinedFields.NUB = CombNextUB.get(); 6011 Built.DistCombinedFields.DistCond = CombDistCond.get(); 6012 Built.DistCombinedFields.ParForInDistCond = ParForInDistCond.get(); 6013 6014 return NestedLoopCount; 6015 } 6016 6017 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 6018 auto CollapseClauses = 6019 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 6020 if (CollapseClauses.begin() != CollapseClauses.end()) 6021 return (*CollapseClauses.begin())->getNumForLoops(); 6022 return nullptr; 6023 } 6024 6025 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 6026 auto OrderedClauses = 6027 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 6028 if (OrderedClauses.begin() != OrderedClauses.end()) 6029 return (*OrderedClauses.begin())->getNumForLoops(); 6030 return nullptr; 6031 } 6032 6033 static bool checkSimdlenSafelenSpecified(Sema &S, 6034 const ArrayRef<OMPClause *> Clauses) { 6035 const OMPSafelenClause *Safelen = nullptr; 6036 const OMPSimdlenClause *Simdlen = nullptr; 6037 6038 for (const OMPClause *Clause : Clauses) { 6039 if (Clause->getClauseKind() == OMPC_safelen) 6040 Safelen = cast<OMPSafelenClause>(Clause); 6041 else if (Clause->getClauseKind() == OMPC_simdlen) 6042 Simdlen = cast<OMPSimdlenClause>(Clause); 6043 if (Safelen && Simdlen) 6044 break; 6045 } 6046 6047 if (Simdlen && Safelen) { 6048 const Expr *SimdlenLength = Simdlen->getSimdlen(); 6049 const Expr *SafelenLength = Safelen->getSafelen(); 6050 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 6051 SimdlenLength->isInstantiationDependent() || 6052 SimdlenLength->containsUnexpandedParameterPack()) 6053 return false; 6054 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 6055 SafelenLength->isInstantiationDependent() || 6056 SafelenLength->containsUnexpandedParameterPack()) 6057 return false; 6058 Expr::EvalResult SimdlenResult, SafelenResult; 6059 SimdlenLength->EvaluateAsInt(SimdlenResult, S.Context); 6060 SafelenLength->EvaluateAsInt(SafelenResult, S.Context); 6061 llvm::APSInt SimdlenRes = SimdlenResult.Val.getInt(); 6062 llvm::APSInt SafelenRes = SafelenResult.Val.getInt(); 6063 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 6064 // If both simdlen and safelen clauses are specified, the value of the 6065 // simdlen parameter must be less than or equal to the value of the safelen 6066 // parameter. 6067 if (SimdlenRes > SafelenRes) { 6068 S.Diag(SimdlenLength->getExprLoc(), 6069 diag::err_omp_wrong_simdlen_safelen_values) 6070 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 6071 return true; 6072 } 6073 } 6074 return false; 6075 } 6076 6077 StmtResult 6078 Sema::ActOnOpenMPSimdDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6079 SourceLocation StartLoc, SourceLocation EndLoc, 6080 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6081 if (!AStmt) 6082 return StmtError(); 6083 6084 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6085 OMPLoopDirective::HelperExprs B; 6086 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6087 // define the nested loops number. 6088 unsigned NestedLoopCount = checkOpenMPLoop( 6089 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6090 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6091 if (NestedLoopCount == 0) 6092 return StmtError(); 6093 6094 assert((CurContext->isDependentContext() || B.builtAll()) && 6095 "omp simd loop exprs were not built"); 6096 6097 if (!CurContext->isDependentContext()) { 6098 // Finalize the clauses that need pre-built expressions for CodeGen. 6099 for (OMPClause *C : Clauses) { 6100 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6101 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6102 B.NumIterations, *this, CurScope, 6103 DSAStack)) 6104 return StmtError(); 6105 } 6106 } 6107 6108 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6109 return StmtError(); 6110 6111 setFunctionHasBranchProtectedScope(); 6112 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6113 Clauses, AStmt, B); 6114 } 6115 6116 StmtResult 6117 Sema::ActOnOpenMPForDirective(ArrayRef<OMPClause *> Clauses, Stmt *AStmt, 6118 SourceLocation StartLoc, SourceLocation EndLoc, 6119 VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6120 if (!AStmt) 6121 return StmtError(); 6122 6123 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6124 OMPLoopDirective::HelperExprs B; 6125 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6126 // define the nested loops number. 6127 unsigned NestedLoopCount = checkOpenMPLoop( 6128 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 6129 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 6130 if (NestedLoopCount == 0) 6131 return StmtError(); 6132 6133 assert((CurContext->isDependentContext() || B.builtAll()) && 6134 "omp for loop exprs were not built"); 6135 6136 if (!CurContext->isDependentContext()) { 6137 // Finalize the clauses that need pre-built expressions for CodeGen. 6138 for (OMPClause *C : Clauses) { 6139 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6140 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6141 B.NumIterations, *this, CurScope, 6142 DSAStack)) 6143 return StmtError(); 6144 } 6145 } 6146 6147 setFunctionHasBranchProtectedScope(); 6148 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6149 Clauses, AStmt, B, DSAStack->isCancelRegion()); 6150 } 6151 6152 StmtResult Sema::ActOnOpenMPForSimdDirective( 6153 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6154 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6155 if (!AStmt) 6156 return StmtError(); 6157 6158 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6159 OMPLoopDirective::HelperExprs B; 6160 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6161 // define the nested loops number. 6162 unsigned NestedLoopCount = 6163 checkOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 6164 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6165 VarsWithImplicitDSA, B); 6166 if (NestedLoopCount == 0) 6167 return StmtError(); 6168 6169 assert((CurContext->isDependentContext() || B.builtAll()) && 6170 "omp for simd loop exprs were not built"); 6171 6172 if (!CurContext->isDependentContext()) { 6173 // Finalize the clauses that need pre-built expressions for CodeGen. 6174 for (OMPClause *C : Clauses) { 6175 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6176 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6177 B.NumIterations, *this, CurScope, 6178 DSAStack)) 6179 return StmtError(); 6180 } 6181 } 6182 6183 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6184 return StmtError(); 6185 6186 setFunctionHasBranchProtectedScope(); 6187 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 6188 Clauses, AStmt, B); 6189 } 6190 6191 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 6192 Stmt *AStmt, 6193 SourceLocation StartLoc, 6194 SourceLocation EndLoc) { 6195 if (!AStmt) 6196 return StmtError(); 6197 6198 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6199 auto BaseStmt = AStmt; 6200 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6201 BaseStmt = CS->getCapturedStmt(); 6202 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6203 auto S = C->children(); 6204 if (S.begin() == S.end()) 6205 return StmtError(); 6206 // All associated statements must be '#pragma omp section' except for 6207 // the first one. 6208 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6209 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6210 if (SectionStmt) 6211 Diag(SectionStmt->getBeginLoc(), 6212 diag::err_omp_sections_substmt_not_section); 6213 return StmtError(); 6214 } 6215 cast<OMPSectionDirective>(SectionStmt) 6216 ->setHasCancel(DSAStack->isCancelRegion()); 6217 } 6218 } else { 6219 Diag(AStmt->getBeginLoc(), diag::err_omp_sections_not_compound_stmt); 6220 return StmtError(); 6221 } 6222 6223 setFunctionHasBranchProtectedScope(); 6224 6225 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6226 DSAStack->isCancelRegion()); 6227 } 6228 6229 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 6230 SourceLocation StartLoc, 6231 SourceLocation EndLoc) { 6232 if (!AStmt) 6233 return StmtError(); 6234 6235 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6236 6237 setFunctionHasBranchProtectedScope(); 6238 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 6239 6240 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 6241 DSAStack->isCancelRegion()); 6242 } 6243 6244 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 6245 Stmt *AStmt, 6246 SourceLocation StartLoc, 6247 SourceLocation EndLoc) { 6248 if (!AStmt) 6249 return StmtError(); 6250 6251 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6252 6253 setFunctionHasBranchProtectedScope(); 6254 6255 // OpenMP [2.7.3, single Construct, Restrictions] 6256 // The copyprivate clause must not be used with the nowait clause. 6257 const OMPClause *Nowait = nullptr; 6258 const OMPClause *Copyprivate = nullptr; 6259 for (const OMPClause *Clause : Clauses) { 6260 if (Clause->getClauseKind() == OMPC_nowait) 6261 Nowait = Clause; 6262 else if (Clause->getClauseKind() == OMPC_copyprivate) 6263 Copyprivate = Clause; 6264 if (Copyprivate && Nowait) { 6265 Diag(Copyprivate->getBeginLoc(), 6266 diag::err_omp_single_copyprivate_with_nowait); 6267 Diag(Nowait->getBeginLoc(), diag::note_omp_nowait_clause_here); 6268 return StmtError(); 6269 } 6270 } 6271 6272 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6273 } 6274 6275 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 6276 SourceLocation StartLoc, 6277 SourceLocation EndLoc) { 6278 if (!AStmt) 6279 return StmtError(); 6280 6281 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6282 6283 setFunctionHasBranchProtectedScope(); 6284 6285 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 6286 } 6287 6288 StmtResult Sema::ActOnOpenMPCriticalDirective( 6289 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 6290 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 6291 if (!AStmt) 6292 return StmtError(); 6293 6294 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6295 6296 bool ErrorFound = false; 6297 llvm::APSInt Hint; 6298 SourceLocation HintLoc; 6299 bool DependentHint = false; 6300 for (const OMPClause *C : Clauses) { 6301 if (C->getClauseKind() == OMPC_hint) { 6302 if (!DirName.getName()) { 6303 Diag(C->getBeginLoc(), diag::err_omp_hint_clause_no_name); 6304 ErrorFound = true; 6305 } 6306 Expr *E = cast<OMPHintClause>(C)->getHint(); 6307 if (E->isTypeDependent() || E->isValueDependent() || 6308 E->isInstantiationDependent()) { 6309 DependentHint = true; 6310 } else { 6311 Hint = E->EvaluateKnownConstInt(Context); 6312 HintLoc = C->getBeginLoc(); 6313 } 6314 } 6315 } 6316 if (ErrorFound) 6317 return StmtError(); 6318 const auto Pair = DSAStack->getCriticalWithHint(DirName); 6319 if (Pair.first && DirName.getName() && !DependentHint) { 6320 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 6321 Diag(StartLoc, diag::err_omp_critical_with_hint); 6322 if (HintLoc.isValid()) 6323 Diag(HintLoc, diag::note_omp_critical_hint_here) 6324 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 6325 else 6326 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 6327 if (const auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 6328 Diag(C->getBeginLoc(), diag::note_omp_critical_hint_here) 6329 << 1 6330 << C->getHint()->EvaluateKnownConstInt(Context).toString( 6331 /*Radix=*/10, /*Signed=*/false); 6332 } else { 6333 Diag(Pair.first->getBeginLoc(), diag::note_omp_critical_no_hint) << 1; 6334 } 6335 } 6336 } 6337 6338 setFunctionHasBranchProtectedScope(); 6339 6340 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 6341 Clauses, AStmt); 6342 if (!Pair.first && DirName.getName() && !DependentHint) 6343 DSAStack->addCriticalWithHint(Dir, Hint); 6344 return Dir; 6345 } 6346 6347 StmtResult Sema::ActOnOpenMPParallelForDirective( 6348 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6349 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6350 if (!AStmt) 6351 return StmtError(); 6352 6353 auto *CS = cast<CapturedStmt>(AStmt); 6354 // 1.2.2 OpenMP Language Terminology 6355 // Structured block - An executable statement with a single entry at the 6356 // top and a single exit at the bottom. 6357 // The point of exit cannot be a branch out of the structured block. 6358 // longjmp() and throw() must not violate the entry/exit criteria. 6359 CS->getCapturedDecl()->setNothrow(); 6360 6361 OMPLoopDirective::HelperExprs B; 6362 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6363 // define the nested loops number. 6364 unsigned NestedLoopCount = 6365 checkOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 6366 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6367 VarsWithImplicitDSA, B); 6368 if (NestedLoopCount == 0) 6369 return StmtError(); 6370 6371 assert((CurContext->isDependentContext() || B.builtAll()) && 6372 "omp parallel for loop exprs were not built"); 6373 6374 if (!CurContext->isDependentContext()) { 6375 // Finalize the clauses that need pre-built expressions for CodeGen. 6376 for (OMPClause *C : Clauses) { 6377 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6378 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6379 B.NumIterations, *this, CurScope, 6380 DSAStack)) 6381 return StmtError(); 6382 } 6383 } 6384 6385 setFunctionHasBranchProtectedScope(); 6386 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 6387 NestedLoopCount, Clauses, AStmt, B, 6388 DSAStack->isCancelRegion()); 6389 } 6390 6391 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 6392 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6393 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 6394 if (!AStmt) 6395 return StmtError(); 6396 6397 auto *CS = cast<CapturedStmt>(AStmt); 6398 // 1.2.2 OpenMP Language Terminology 6399 // Structured block - An executable statement with a single entry at the 6400 // top and a single exit at the bottom. 6401 // The point of exit cannot be a branch out of the structured block. 6402 // longjmp() and throw() must not violate the entry/exit criteria. 6403 CS->getCapturedDecl()->setNothrow(); 6404 6405 OMPLoopDirective::HelperExprs B; 6406 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6407 // define the nested loops number. 6408 unsigned NestedLoopCount = 6409 checkOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 6410 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6411 VarsWithImplicitDSA, B); 6412 if (NestedLoopCount == 0) 6413 return StmtError(); 6414 6415 if (!CurContext->isDependentContext()) { 6416 // Finalize the clauses that need pre-built expressions for CodeGen. 6417 for (OMPClause *C : Clauses) { 6418 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6419 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6420 B.NumIterations, *this, CurScope, 6421 DSAStack)) 6422 return StmtError(); 6423 } 6424 } 6425 6426 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6427 return StmtError(); 6428 6429 setFunctionHasBranchProtectedScope(); 6430 return OMPParallelForSimdDirective::Create( 6431 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6432 } 6433 6434 StmtResult 6435 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 6436 Stmt *AStmt, SourceLocation StartLoc, 6437 SourceLocation EndLoc) { 6438 if (!AStmt) 6439 return StmtError(); 6440 6441 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6442 auto BaseStmt = AStmt; 6443 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6444 BaseStmt = CS->getCapturedStmt(); 6445 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6446 auto S = C->children(); 6447 if (S.begin() == S.end()) 6448 return StmtError(); 6449 // All associated statements must be '#pragma omp section' except for 6450 // the first one. 6451 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6452 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6453 if (SectionStmt) 6454 Diag(SectionStmt->getBeginLoc(), 6455 diag::err_omp_parallel_sections_substmt_not_section); 6456 return StmtError(); 6457 } 6458 cast<OMPSectionDirective>(SectionStmt) 6459 ->setHasCancel(DSAStack->isCancelRegion()); 6460 } 6461 } else { 6462 Diag(AStmt->getBeginLoc(), 6463 diag::err_omp_parallel_sections_not_compound_stmt); 6464 return StmtError(); 6465 } 6466 6467 setFunctionHasBranchProtectedScope(); 6468 6469 return OMPParallelSectionsDirective::Create( 6470 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 6471 } 6472 6473 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 6474 Stmt *AStmt, SourceLocation StartLoc, 6475 SourceLocation EndLoc) { 6476 if (!AStmt) 6477 return StmtError(); 6478 6479 auto *CS = cast<CapturedStmt>(AStmt); 6480 // 1.2.2 OpenMP Language Terminology 6481 // Structured block - An executable statement with a single entry at the 6482 // top and a single exit at the bottom. 6483 // The point of exit cannot be a branch out of the structured block. 6484 // longjmp() and throw() must not violate the entry/exit criteria. 6485 CS->getCapturedDecl()->setNothrow(); 6486 6487 setFunctionHasBranchProtectedScope(); 6488 6489 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6490 DSAStack->isCancelRegion()); 6491 } 6492 6493 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 6494 SourceLocation EndLoc) { 6495 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 6496 } 6497 6498 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 6499 SourceLocation EndLoc) { 6500 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 6501 } 6502 6503 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 6504 SourceLocation EndLoc) { 6505 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 6506 } 6507 6508 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 6509 Stmt *AStmt, 6510 SourceLocation StartLoc, 6511 SourceLocation EndLoc) { 6512 if (!AStmt) 6513 return StmtError(); 6514 6515 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6516 6517 setFunctionHasBranchProtectedScope(); 6518 6519 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 6520 AStmt, 6521 DSAStack->getTaskgroupReductionRef()); 6522 } 6523 6524 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 6525 SourceLocation StartLoc, 6526 SourceLocation EndLoc) { 6527 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 6528 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 6529 } 6530 6531 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 6532 Stmt *AStmt, 6533 SourceLocation StartLoc, 6534 SourceLocation EndLoc) { 6535 const OMPClause *DependFound = nullptr; 6536 const OMPClause *DependSourceClause = nullptr; 6537 const OMPClause *DependSinkClause = nullptr; 6538 bool ErrorFound = false; 6539 const OMPThreadsClause *TC = nullptr; 6540 const OMPSIMDClause *SC = nullptr; 6541 for (const OMPClause *C : Clauses) { 6542 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 6543 DependFound = C; 6544 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 6545 if (DependSourceClause) { 6546 Diag(C->getBeginLoc(), diag::err_omp_more_one_clause) 6547 << getOpenMPDirectiveName(OMPD_ordered) 6548 << getOpenMPClauseName(OMPC_depend) << 2; 6549 ErrorFound = true; 6550 } else { 6551 DependSourceClause = C; 6552 } 6553 if (DependSinkClause) { 6554 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 6555 << 0; 6556 ErrorFound = true; 6557 } 6558 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 6559 if (DependSourceClause) { 6560 Diag(C->getBeginLoc(), diag::err_omp_depend_sink_source_not_allowed) 6561 << 1; 6562 ErrorFound = true; 6563 } 6564 DependSinkClause = C; 6565 } 6566 } else if (C->getClauseKind() == OMPC_threads) { 6567 TC = cast<OMPThreadsClause>(C); 6568 } else if (C->getClauseKind() == OMPC_simd) { 6569 SC = cast<OMPSIMDClause>(C); 6570 } 6571 } 6572 if (!ErrorFound && !SC && 6573 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 6574 // OpenMP [2.8.1,simd Construct, Restrictions] 6575 // An ordered construct with the simd clause is the only OpenMP construct 6576 // that can appear in the simd region. 6577 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 6578 ErrorFound = true; 6579 } else if (DependFound && (TC || SC)) { 6580 Diag(DependFound->getBeginLoc(), diag::err_omp_depend_clause_thread_simd) 6581 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 6582 ErrorFound = true; 6583 } else if (DependFound && !DSAStack->getParentOrderedRegionParam().first) { 6584 Diag(DependFound->getBeginLoc(), 6585 diag::err_omp_ordered_directive_without_param); 6586 ErrorFound = true; 6587 } else if (TC || Clauses.empty()) { 6588 if (const Expr *Param = DSAStack->getParentOrderedRegionParam().first) { 6589 SourceLocation ErrLoc = TC ? TC->getBeginLoc() : StartLoc; 6590 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 6591 << (TC != nullptr); 6592 Diag(Param->getBeginLoc(), diag::note_omp_ordered_param); 6593 ErrorFound = true; 6594 } 6595 } 6596 if ((!AStmt && !DependFound) || ErrorFound) 6597 return StmtError(); 6598 6599 if (AStmt) { 6600 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6601 6602 setFunctionHasBranchProtectedScope(); 6603 } 6604 6605 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6606 } 6607 6608 namespace { 6609 /// Helper class for checking expression in 'omp atomic [update]' 6610 /// construct. 6611 class OpenMPAtomicUpdateChecker { 6612 /// Error results for atomic update expressions. 6613 enum ExprAnalysisErrorCode { 6614 /// A statement is not an expression statement. 6615 NotAnExpression, 6616 /// Expression is not builtin binary or unary operation. 6617 NotABinaryOrUnaryExpression, 6618 /// Unary operation is not post-/pre- increment/decrement operation. 6619 NotAnUnaryIncDecExpression, 6620 /// An expression is not of scalar type. 6621 NotAScalarType, 6622 /// A binary operation is not an assignment operation. 6623 NotAnAssignmentOp, 6624 /// RHS part of the binary operation is not a binary expression. 6625 NotABinaryExpression, 6626 /// RHS part is not additive/multiplicative/shift/biwise binary 6627 /// expression. 6628 NotABinaryOperator, 6629 /// RHS binary operation does not have reference to the updated LHS 6630 /// part. 6631 NotAnUpdateExpression, 6632 /// No errors is found. 6633 NoError 6634 }; 6635 /// Reference to Sema. 6636 Sema &SemaRef; 6637 /// A location for note diagnostics (when error is found). 6638 SourceLocation NoteLoc; 6639 /// 'x' lvalue part of the source atomic expression. 6640 Expr *X; 6641 /// 'expr' rvalue part of the source atomic expression. 6642 Expr *E; 6643 /// Helper expression of the form 6644 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 6645 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 6646 Expr *UpdateExpr; 6647 /// Is 'x' a LHS in a RHS part of full update expression. It is 6648 /// important for non-associative operations. 6649 bool IsXLHSInRHSPart; 6650 BinaryOperatorKind Op; 6651 SourceLocation OpLoc; 6652 /// true if the source expression is a postfix unary operation, false 6653 /// if it is a prefix unary operation. 6654 bool IsPostfixUpdate; 6655 6656 public: 6657 OpenMPAtomicUpdateChecker(Sema &SemaRef) 6658 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 6659 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 6660 /// Check specified statement that it is suitable for 'atomic update' 6661 /// constructs and extract 'x', 'expr' and Operation from the original 6662 /// expression. If DiagId and NoteId == 0, then only check is performed 6663 /// without error notification. 6664 /// \param DiagId Diagnostic which should be emitted if error is found. 6665 /// \param NoteId Diagnostic note for the main error message. 6666 /// \return true if statement is not an update expression, false otherwise. 6667 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 6668 /// Return the 'x' lvalue part of the source atomic expression. 6669 Expr *getX() const { return X; } 6670 /// Return the 'expr' rvalue part of the source atomic expression. 6671 Expr *getExpr() const { return E; } 6672 /// Return the update expression used in calculation of the updated 6673 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 6674 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 6675 Expr *getUpdateExpr() const { return UpdateExpr; } 6676 /// Return true if 'x' is LHS in RHS part of full update expression, 6677 /// false otherwise. 6678 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 6679 6680 /// true if the source expression is a postfix unary operation, false 6681 /// if it is a prefix unary operation. 6682 bool isPostfixUpdate() const { return IsPostfixUpdate; } 6683 6684 private: 6685 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 6686 unsigned NoteId = 0); 6687 }; 6688 } // namespace 6689 6690 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 6691 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 6692 ExprAnalysisErrorCode ErrorFound = NoError; 6693 SourceLocation ErrorLoc, NoteLoc; 6694 SourceRange ErrorRange, NoteRange; 6695 // Allowed constructs are: 6696 // x = x binop expr; 6697 // x = expr binop x; 6698 if (AtomicBinOp->getOpcode() == BO_Assign) { 6699 X = AtomicBinOp->getLHS(); 6700 if (const auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 6701 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 6702 if (AtomicInnerBinOp->isMultiplicativeOp() || 6703 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 6704 AtomicInnerBinOp->isBitwiseOp()) { 6705 Op = AtomicInnerBinOp->getOpcode(); 6706 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 6707 Expr *LHS = AtomicInnerBinOp->getLHS(); 6708 Expr *RHS = AtomicInnerBinOp->getRHS(); 6709 llvm::FoldingSetNodeID XId, LHSId, RHSId; 6710 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 6711 /*Canonical=*/true); 6712 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 6713 /*Canonical=*/true); 6714 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 6715 /*Canonical=*/true); 6716 if (XId == LHSId) { 6717 E = RHS; 6718 IsXLHSInRHSPart = true; 6719 } else if (XId == RHSId) { 6720 E = LHS; 6721 IsXLHSInRHSPart = false; 6722 } else { 6723 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6724 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6725 NoteLoc = X->getExprLoc(); 6726 NoteRange = X->getSourceRange(); 6727 ErrorFound = NotAnUpdateExpression; 6728 } 6729 } else { 6730 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6731 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6732 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 6733 NoteRange = SourceRange(NoteLoc, NoteLoc); 6734 ErrorFound = NotABinaryOperator; 6735 } 6736 } else { 6737 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 6738 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 6739 ErrorFound = NotABinaryExpression; 6740 } 6741 } else { 6742 ErrorLoc = AtomicBinOp->getExprLoc(); 6743 ErrorRange = AtomicBinOp->getSourceRange(); 6744 NoteLoc = AtomicBinOp->getOperatorLoc(); 6745 NoteRange = SourceRange(NoteLoc, NoteLoc); 6746 ErrorFound = NotAnAssignmentOp; 6747 } 6748 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6749 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6750 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6751 return true; 6752 } 6753 if (SemaRef.CurContext->isDependentContext()) 6754 E = X = UpdateExpr = nullptr; 6755 return ErrorFound != NoError; 6756 } 6757 6758 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 6759 unsigned NoteId) { 6760 ExprAnalysisErrorCode ErrorFound = NoError; 6761 SourceLocation ErrorLoc, NoteLoc; 6762 SourceRange ErrorRange, NoteRange; 6763 // Allowed constructs are: 6764 // x++; 6765 // x--; 6766 // ++x; 6767 // --x; 6768 // x binop= expr; 6769 // x = x binop expr; 6770 // x = expr binop x; 6771 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 6772 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 6773 if (AtomicBody->getType()->isScalarType() || 6774 AtomicBody->isInstantiationDependent()) { 6775 if (const auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 6776 AtomicBody->IgnoreParenImpCasts())) { 6777 // Check for Compound Assignment Operation 6778 Op = BinaryOperator::getOpForCompoundAssignment( 6779 AtomicCompAssignOp->getOpcode()); 6780 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 6781 E = AtomicCompAssignOp->getRHS(); 6782 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 6783 IsXLHSInRHSPart = true; 6784 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 6785 AtomicBody->IgnoreParenImpCasts())) { 6786 // Check for Binary Operation 6787 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 6788 return true; 6789 } else if (const auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 6790 AtomicBody->IgnoreParenImpCasts())) { 6791 // Check for Unary Operation 6792 if (AtomicUnaryOp->isIncrementDecrementOp()) { 6793 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 6794 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 6795 OpLoc = AtomicUnaryOp->getOperatorLoc(); 6796 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 6797 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 6798 IsXLHSInRHSPart = true; 6799 } else { 6800 ErrorFound = NotAnUnaryIncDecExpression; 6801 ErrorLoc = AtomicUnaryOp->getExprLoc(); 6802 ErrorRange = AtomicUnaryOp->getSourceRange(); 6803 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 6804 NoteRange = SourceRange(NoteLoc, NoteLoc); 6805 } 6806 } else if (!AtomicBody->isInstantiationDependent()) { 6807 ErrorFound = NotABinaryOrUnaryExpression; 6808 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 6809 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 6810 } 6811 } else { 6812 ErrorFound = NotAScalarType; 6813 NoteLoc = ErrorLoc = AtomicBody->getBeginLoc(); 6814 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6815 } 6816 } else { 6817 ErrorFound = NotAnExpression; 6818 NoteLoc = ErrorLoc = S->getBeginLoc(); 6819 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6820 } 6821 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6822 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6823 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6824 return true; 6825 } 6826 if (SemaRef.CurContext->isDependentContext()) 6827 E = X = UpdateExpr = nullptr; 6828 if (ErrorFound == NoError && E && X) { 6829 // Build an update expression of form 'OpaqueValueExpr(x) binop 6830 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 6831 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 6832 auto *OVEX = new (SemaRef.getASTContext()) 6833 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 6834 auto *OVEExpr = new (SemaRef.getASTContext()) 6835 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 6836 ExprResult Update = 6837 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 6838 IsXLHSInRHSPart ? OVEExpr : OVEX); 6839 if (Update.isInvalid()) 6840 return true; 6841 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 6842 Sema::AA_Casting); 6843 if (Update.isInvalid()) 6844 return true; 6845 UpdateExpr = Update.get(); 6846 } 6847 return ErrorFound != NoError; 6848 } 6849 6850 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 6851 Stmt *AStmt, 6852 SourceLocation StartLoc, 6853 SourceLocation EndLoc) { 6854 if (!AStmt) 6855 return StmtError(); 6856 6857 auto *CS = cast<CapturedStmt>(AStmt); 6858 // 1.2.2 OpenMP Language Terminology 6859 // Structured block - An executable statement with a single entry at the 6860 // top and a single exit at the bottom. 6861 // The point of exit cannot be a branch out of the structured block. 6862 // longjmp() and throw() must not violate the entry/exit criteria. 6863 OpenMPClauseKind AtomicKind = OMPC_unknown; 6864 SourceLocation AtomicKindLoc; 6865 for (const OMPClause *C : Clauses) { 6866 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 6867 C->getClauseKind() == OMPC_update || 6868 C->getClauseKind() == OMPC_capture) { 6869 if (AtomicKind != OMPC_unknown) { 6870 Diag(C->getBeginLoc(), diag::err_omp_atomic_several_clauses) 6871 << SourceRange(C->getBeginLoc(), C->getEndLoc()); 6872 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 6873 << getOpenMPClauseName(AtomicKind); 6874 } else { 6875 AtomicKind = C->getClauseKind(); 6876 AtomicKindLoc = C->getBeginLoc(); 6877 } 6878 } 6879 } 6880 6881 Stmt *Body = CS->getCapturedStmt(); 6882 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 6883 Body = EWC->getSubExpr(); 6884 6885 Expr *X = nullptr; 6886 Expr *V = nullptr; 6887 Expr *E = nullptr; 6888 Expr *UE = nullptr; 6889 bool IsXLHSInRHSPart = false; 6890 bool IsPostfixUpdate = false; 6891 // OpenMP [2.12.6, atomic Construct] 6892 // In the next expressions: 6893 // * x and v (as applicable) are both l-value expressions with scalar type. 6894 // * During the execution of an atomic region, multiple syntactic 6895 // occurrences of x must designate the same storage location. 6896 // * Neither of v and expr (as applicable) may access the storage location 6897 // designated by x. 6898 // * Neither of x and expr (as applicable) may access the storage location 6899 // designated by v. 6900 // * expr is an expression with scalar type. 6901 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 6902 // * binop, binop=, ++, and -- are not overloaded operators. 6903 // * The expression x binop expr must be numerically equivalent to x binop 6904 // (expr). This requirement is satisfied if the operators in expr have 6905 // precedence greater than binop, or by using parentheses around expr or 6906 // subexpressions of expr. 6907 // * The expression expr binop x must be numerically equivalent to (expr) 6908 // binop x. This requirement is satisfied if the operators in expr have 6909 // precedence equal to or greater than binop, or by using parentheses around 6910 // expr or subexpressions of expr. 6911 // * For forms that allow multiple occurrences of x, the number of times 6912 // that x is evaluated is unspecified. 6913 if (AtomicKind == OMPC_read) { 6914 enum { 6915 NotAnExpression, 6916 NotAnAssignmentOp, 6917 NotAScalarType, 6918 NotAnLValue, 6919 NoError 6920 } ErrorFound = NoError; 6921 SourceLocation ErrorLoc, NoteLoc; 6922 SourceRange ErrorRange, NoteRange; 6923 // If clause is read: 6924 // v = x; 6925 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6926 const auto *AtomicBinOp = 6927 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6928 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6929 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6930 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 6931 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6932 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 6933 if (!X->isLValue() || !V->isLValue()) { 6934 const Expr *NotLValueExpr = X->isLValue() ? V : X; 6935 ErrorFound = NotAnLValue; 6936 ErrorLoc = AtomicBinOp->getExprLoc(); 6937 ErrorRange = AtomicBinOp->getSourceRange(); 6938 NoteLoc = NotLValueExpr->getExprLoc(); 6939 NoteRange = NotLValueExpr->getSourceRange(); 6940 } 6941 } else if (!X->isInstantiationDependent() || 6942 !V->isInstantiationDependent()) { 6943 const Expr *NotScalarExpr = 6944 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6945 ? V 6946 : X; 6947 ErrorFound = NotAScalarType; 6948 ErrorLoc = AtomicBinOp->getExprLoc(); 6949 ErrorRange = AtomicBinOp->getSourceRange(); 6950 NoteLoc = NotScalarExpr->getExprLoc(); 6951 NoteRange = NotScalarExpr->getSourceRange(); 6952 } 6953 } else if (!AtomicBody->isInstantiationDependent()) { 6954 ErrorFound = NotAnAssignmentOp; 6955 ErrorLoc = AtomicBody->getExprLoc(); 6956 ErrorRange = AtomicBody->getSourceRange(); 6957 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6958 : AtomicBody->getExprLoc(); 6959 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6960 : AtomicBody->getSourceRange(); 6961 } 6962 } else { 6963 ErrorFound = NotAnExpression; 6964 NoteLoc = ErrorLoc = Body->getBeginLoc(); 6965 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6966 } 6967 if (ErrorFound != NoError) { 6968 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 6969 << ErrorRange; 6970 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 6971 << NoteRange; 6972 return StmtError(); 6973 } 6974 if (CurContext->isDependentContext()) 6975 V = X = nullptr; 6976 } else if (AtomicKind == OMPC_write) { 6977 enum { 6978 NotAnExpression, 6979 NotAnAssignmentOp, 6980 NotAScalarType, 6981 NotAnLValue, 6982 NoError 6983 } ErrorFound = NoError; 6984 SourceLocation ErrorLoc, NoteLoc; 6985 SourceRange ErrorRange, NoteRange; 6986 // If clause is write: 6987 // x = expr; 6988 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 6989 const auto *AtomicBinOp = 6990 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6991 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6992 X = AtomicBinOp->getLHS(); 6993 E = AtomicBinOp->getRHS(); 6994 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6995 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 6996 if (!X->isLValue()) { 6997 ErrorFound = NotAnLValue; 6998 ErrorLoc = AtomicBinOp->getExprLoc(); 6999 ErrorRange = AtomicBinOp->getSourceRange(); 7000 NoteLoc = X->getExprLoc(); 7001 NoteRange = X->getSourceRange(); 7002 } 7003 } else if (!X->isInstantiationDependent() || 7004 !E->isInstantiationDependent()) { 7005 const Expr *NotScalarExpr = 7006 (X->isInstantiationDependent() || X->getType()->isScalarType()) 7007 ? E 7008 : X; 7009 ErrorFound = NotAScalarType; 7010 ErrorLoc = AtomicBinOp->getExprLoc(); 7011 ErrorRange = AtomicBinOp->getSourceRange(); 7012 NoteLoc = NotScalarExpr->getExprLoc(); 7013 NoteRange = NotScalarExpr->getSourceRange(); 7014 } 7015 } else if (!AtomicBody->isInstantiationDependent()) { 7016 ErrorFound = NotAnAssignmentOp; 7017 ErrorLoc = AtomicBody->getExprLoc(); 7018 ErrorRange = AtomicBody->getSourceRange(); 7019 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7020 : AtomicBody->getExprLoc(); 7021 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7022 : AtomicBody->getSourceRange(); 7023 } 7024 } else { 7025 ErrorFound = NotAnExpression; 7026 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7027 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 7028 } 7029 if (ErrorFound != NoError) { 7030 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 7031 << ErrorRange; 7032 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 7033 << NoteRange; 7034 return StmtError(); 7035 } 7036 if (CurContext->isDependentContext()) 7037 E = X = nullptr; 7038 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 7039 // If clause is update: 7040 // x++; 7041 // x--; 7042 // ++x; 7043 // --x; 7044 // x binop= expr; 7045 // x = x binop expr; 7046 // x = expr binop x; 7047 OpenMPAtomicUpdateChecker Checker(*this); 7048 if (Checker.checkStatement( 7049 Body, (AtomicKind == OMPC_update) 7050 ? diag::err_omp_atomic_update_not_expression_statement 7051 : diag::err_omp_atomic_not_expression_statement, 7052 diag::note_omp_atomic_update)) 7053 return StmtError(); 7054 if (!CurContext->isDependentContext()) { 7055 E = Checker.getExpr(); 7056 X = Checker.getX(); 7057 UE = Checker.getUpdateExpr(); 7058 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7059 } 7060 } else if (AtomicKind == OMPC_capture) { 7061 enum { 7062 NotAnAssignmentOp, 7063 NotACompoundStatement, 7064 NotTwoSubstatements, 7065 NotASpecificExpression, 7066 NoError 7067 } ErrorFound = NoError; 7068 SourceLocation ErrorLoc, NoteLoc; 7069 SourceRange ErrorRange, NoteRange; 7070 if (const auto *AtomicBody = dyn_cast<Expr>(Body)) { 7071 // If clause is a capture: 7072 // v = x++; 7073 // v = x--; 7074 // v = ++x; 7075 // v = --x; 7076 // v = x binop= expr; 7077 // v = x = x binop expr; 7078 // v = x = expr binop x; 7079 const auto *AtomicBinOp = 7080 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 7081 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 7082 V = AtomicBinOp->getLHS(); 7083 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 7084 OpenMPAtomicUpdateChecker Checker(*this); 7085 if (Checker.checkStatement( 7086 Body, diag::err_omp_atomic_capture_not_expression_statement, 7087 diag::note_omp_atomic_update)) 7088 return StmtError(); 7089 E = Checker.getExpr(); 7090 X = Checker.getX(); 7091 UE = Checker.getUpdateExpr(); 7092 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7093 IsPostfixUpdate = Checker.isPostfixUpdate(); 7094 } else if (!AtomicBody->isInstantiationDependent()) { 7095 ErrorLoc = AtomicBody->getExprLoc(); 7096 ErrorRange = AtomicBody->getSourceRange(); 7097 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 7098 : AtomicBody->getExprLoc(); 7099 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 7100 : AtomicBody->getSourceRange(); 7101 ErrorFound = NotAnAssignmentOp; 7102 } 7103 if (ErrorFound != NoError) { 7104 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 7105 << ErrorRange; 7106 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7107 return StmtError(); 7108 } 7109 if (CurContext->isDependentContext()) 7110 UE = V = E = X = nullptr; 7111 } else { 7112 // If clause is a capture: 7113 // { v = x; x = expr; } 7114 // { v = x; x++; } 7115 // { v = x; x--; } 7116 // { v = x; ++x; } 7117 // { v = x; --x; } 7118 // { v = x; x binop= expr; } 7119 // { v = x; x = x binop expr; } 7120 // { v = x; x = expr binop x; } 7121 // { x++; v = x; } 7122 // { x--; v = x; } 7123 // { ++x; v = x; } 7124 // { --x; v = x; } 7125 // { x binop= expr; v = x; } 7126 // { x = x binop expr; v = x; } 7127 // { x = expr binop x; v = x; } 7128 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 7129 // Check that this is { expr1; expr2; } 7130 if (CS->size() == 2) { 7131 Stmt *First = CS->body_front(); 7132 Stmt *Second = CS->body_back(); 7133 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 7134 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 7135 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 7136 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 7137 // Need to find what subexpression is 'v' and what is 'x'. 7138 OpenMPAtomicUpdateChecker Checker(*this); 7139 bool IsUpdateExprFound = !Checker.checkStatement(Second); 7140 BinaryOperator *BinOp = nullptr; 7141 if (IsUpdateExprFound) { 7142 BinOp = dyn_cast<BinaryOperator>(First); 7143 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7144 } 7145 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7146 // { v = x; x++; } 7147 // { v = x; x--; } 7148 // { v = x; ++x; } 7149 // { v = x; --x; } 7150 // { v = x; x binop= expr; } 7151 // { v = x; x = x binop expr; } 7152 // { v = x; x = expr binop x; } 7153 // Check that the first expression has form v = x. 7154 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7155 llvm::FoldingSetNodeID XId, PossibleXId; 7156 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7157 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7158 IsUpdateExprFound = XId == PossibleXId; 7159 if (IsUpdateExprFound) { 7160 V = BinOp->getLHS(); 7161 X = Checker.getX(); 7162 E = Checker.getExpr(); 7163 UE = Checker.getUpdateExpr(); 7164 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7165 IsPostfixUpdate = true; 7166 } 7167 } 7168 if (!IsUpdateExprFound) { 7169 IsUpdateExprFound = !Checker.checkStatement(First); 7170 BinOp = nullptr; 7171 if (IsUpdateExprFound) { 7172 BinOp = dyn_cast<BinaryOperator>(Second); 7173 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 7174 } 7175 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 7176 // { x++; v = x; } 7177 // { x--; v = x; } 7178 // { ++x; v = x; } 7179 // { --x; v = x; } 7180 // { x binop= expr; v = x; } 7181 // { x = x binop expr; v = x; } 7182 // { x = expr binop x; v = x; } 7183 // Check that the second expression has form v = x. 7184 Expr *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 7185 llvm::FoldingSetNodeID XId, PossibleXId; 7186 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 7187 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 7188 IsUpdateExprFound = XId == PossibleXId; 7189 if (IsUpdateExprFound) { 7190 V = BinOp->getLHS(); 7191 X = Checker.getX(); 7192 E = Checker.getExpr(); 7193 UE = Checker.getUpdateExpr(); 7194 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 7195 IsPostfixUpdate = false; 7196 } 7197 } 7198 } 7199 if (!IsUpdateExprFound) { 7200 // { v = x; x = expr; } 7201 auto *FirstExpr = dyn_cast<Expr>(First); 7202 auto *SecondExpr = dyn_cast<Expr>(Second); 7203 if (!FirstExpr || !SecondExpr || 7204 !(FirstExpr->isInstantiationDependent() || 7205 SecondExpr->isInstantiationDependent())) { 7206 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 7207 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 7208 ErrorFound = NotAnAssignmentOp; 7209 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 7210 : First->getBeginLoc(); 7211 NoteRange = ErrorRange = FirstBinOp 7212 ? FirstBinOp->getSourceRange() 7213 : SourceRange(ErrorLoc, ErrorLoc); 7214 } else { 7215 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 7216 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 7217 ErrorFound = NotAnAssignmentOp; 7218 NoteLoc = ErrorLoc = SecondBinOp 7219 ? SecondBinOp->getOperatorLoc() 7220 : Second->getBeginLoc(); 7221 NoteRange = ErrorRange = 7222 SecondBinOp ? SecondBinOp->getSourceRange() 7223 : SourceRange(ErrorLoc, ErrorLoc); 7224 } else { 7225 Expr *PossibleXRHSInFirst = 7226 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 7227 Expr *PossibleXLHSInSecond = 7228 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 7229 llvm::FoldingSetNodeID X1Id, X2Id; 7230 PossibleXRHSInFirst->Profile(X1Id, Context, 7231 /*Canonical=*/true); 7232 PossibleXLHSInSecond->Profile(X2Id, Context, 7233 /*Canonical=*/true); 7234 IsUpdateExprFound = X1Id == X2Id; 7235 if (IsUpdateExprFound) { 7236 V = FirstBinOp->getLHS(); 7237 X = SecondBinOp->getLHS(); 7238 E = SecondBinOp->getRHS(); 7239 UE = nullptr; 7240 IsXLHSInRHSPart = false; 7241 IsPostfixUpdate = true; 7242 } else { 7243 ErrorFound = NotASpecificExpression; 7244 ErrorLoc = FirstBinOp->getExprLoc(); 7245 ErrorRange = FirstBinOp->getSourceRange(); 7246 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 7247 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 7248 } 7249 } 7250 } 7251 } 7252 } 7253 } else { 7254 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7255 NoteRange = ErrorRange = 7256 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7257 ErrorFound = NotTwoSubstatements; 7258 } 7259 } else { 7260 NoteLoc = ErrorLoc = Body->getBeginLoc(); 7261 NoteRange = ErrorRange = 7262 SourceRange(Body->getBeginLoc(), Body->getBeginLoc()); 7263 ErrorFound = NotACompoundStatement; 7264 } 7265 if (ErrorFound != NoError) { 7266 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 7267 << ErrorRange; 7268 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 7269 return StmtError(); 7270 } 7271 if (CurContext->isDependentContext()) 7272 UE = V = E = X = nullptr; 7273 } 7274 } 7275 7276 setFunctionHasBranchProtectedScope(); 7277 7278 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 7279 X, V, E, UE, IsXLHSInRHSPart, 7280 IsPostfixUpdate); 7281 } 7282 7283 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 7284 Stmt *AStmt, 7285 SourceLocation StartLoc, 7286 SourceLocation EndLoc) { 7287 if (!AStmt) 7288 return StmtError(); 7289 7290 auto *CS = cast<CapturedStmt>(AStmt); 7291 // 1.2.2 OpenMP Language Terminology 7292 // Structured block - An executable statement with a single entry at the 7293 // top and a single exit at the bottom. 7294 // The point of exit cannot be a branch out of the structured block. 7295 // longjmp() and throw() must not violate the entry/exit criteria. 7296 CS->getCapturedDecl()->setNothrow(); 7297 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target); 7298 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7299 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7300 // 1.2.2 OpenMP Language Terminology 7301 // Structured block - An executable statement with a single entry at the 7302 // top and a single exit at the bottom. 7303 // The point of exit cannot be a branch out of the structured block. 7304 // longjmp() and throw() must not violate the entry/exit criteria. 7305 CS->getCapturedDecl()->setNothrow(); 7306 } 7307 7308 // OpenMP [2.16, Nesting of Regions] 7309 // If specified, a teams construct must be contained within a target 7310 // construct. That target construct must contain no statements or directives 7311 // outside of the teams construct. 7312 if (DSAStack->hasInnerTeamsRegion()) { 7313 const Stmt *S = CS->IgnoreContainers(/*IgnoreCaptured=*/true); 7314 bool OMPTeamsFound = true; 7315 if (const auto *CS = dyn_cast<CompoundStmt>(S)) { 7316 auto I = CS->body_begin(); 7317 while (I != CS->body_end()) { 7318 const auto *OED = dyn_cast<OMPExecutableDirective>(*I); 7319 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind()) || 7320 OMPTeamsFound) { 7321 7322 OMPTeamsFound = false; 7323 break; 7324 } 7325 ++I; 7326 } 7327 assert(I != CS->body_end() && "Not found statement"); 7328 S = *I; 7329 } else { 7330 const auto *OED = dyn_cast<OMPExecutableDirective>(S); 7331 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 7332 } 7333 if (!OMPTeamsFound) { 7334 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 7335 Diag(DSAStack->getInnerTeamsRegionLoc(), 7336 diag::note_omp_nested_teams_construct_here); 7337 Diag(S->getBeginLoc(), diag::note_omp_nested_statement_here) 7338 << isa<OMPExecutableDirective>(S); 7339 return StmtError(); 7340 } 7341 } 7342 7343 setFunctionHasBranchProtectedScope(); 7344 7345 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7346 } 7347 7348 StmtResult 7349 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 7350 Stmt *AStmt, SourceLocation StartLoc, 7351 SourceLocation EndLoc) { 7352 if (!AStmt) 7353 return StmtError(); 7354 7355 auto *CS = cast<CapturedStmt>(AStmt); 7356 // 1.2.2 OpenMP Language Terminology 7357 // Structured block - An executable statement with a single entry at the 7358 // top and a single exit at the bottom. 7359 // The point of exit cannot be a branch out of the structured block. 7360 // longjmp() and throw() must not violate the entry/exit criteria. 7361 CS->getCapturedDecl()->setNothrow(); 7362 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel); 7363 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7364 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7365 // 1.2.2 OpenMP Language Terminology 7366 // Structured block - An executable statement with a single entry at the 7367 // top and a single exit at the bottom. 7368 // The point of exit cannot be a branch out of the structured block. 7369 // longjmp() and throw() must not violate the entry/exit criteria. 7370 CS->getCapturedDecl()->setNothrow(); 7371 } 7372 7373 setFunctionHasBranchProtectedScope(); 7374 7375 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7376 AStmt); 7377 } 7378 7379 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 7380 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7381 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7382 if (!AStmt) 7383 return StmtError(); 7384 7385 auto *CS = cast<CapturedStmt>(AStmt); 7386 // 1.2.2 OpenMP Language Terminology 7387 // Structured block - An executable statement with a single entry at the 7388 // top and a single exit at the bottom. 7389 // The point of exit cannot be a branch out of the structured block. 7390 // longjmp() and throw() must not violate the entry/exit criteria. 7391 CS->getCapturedDecl()->setNothrow(); 7392 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 7393 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7394 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7395 // 1.2.2 OpenMP Language Terminology 7396 // Structured block - An executable statement with a single entry at the 7397 // top and a single exit at the bottom. 7398 // The point of exit cannot be a branch out of the structured block. 7399 // longjmp() and throw() must not violate the entry/exit criteria. 7400 CS->getCapturedDecl()->setNothrow(); 7401 } 7402 7403 OMPLoopDirective::HelperExprs B; 7404 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7405 // define the nested loops number. 7406 unsigned NestedLoopCount = 7407 checkOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 7408 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7409 VarsWithImplicitDSA, B); 7410 if (NestedLoopCount == 0) 7411 return StmtError(); 7412 7413 assert((CurContext->isDependentContext() || B.builtAll()) && 7414 "omp target parallel for loop exprs were not built"); 7415 7416 if (!CurContext->isDependentContext()) { 7417 // Finalize the clauses that need pre-built expressions for CodeGen. 7418 for (OMPClause *C : Clauses) { 7419 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7420 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7421 B.NumIterations, *this, CurScope, 7422 DSAStack)) 7423 return StmtError(); 7424 } 7425 } 7426 7427 setFunctionHasBranchProtectedScope(); 7428 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 7429 NestedLoopCount, Clauses, AStmt, 7430 B, DSAStack->isCancelRegion()); 7431 } 7432 7433 /// Check for existence of a map clause in the list of clauses. 7434 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 7435 const OpenMPClauseKind K) { 7436 return llvm::any_of( 7437 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 7438 } 7439 7440 template <typename... Params> 7441 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 7442 const Params... ClauseTypes) { 7443 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 7444 } 7445 7446 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 7447 Stmt *AStmt, 7448 SourceLocation StartLoc, 7449 SourceLocation EndLoc) { 7450 if (!AStmt) 7451 return StmtError(); 7452 7453 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7454 7455 // OpenMP [2.10.1, Restrictions, p. 97] 7456 // At least one map clause must appear on the directive. 7457 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 7458 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7459 << "'map' or 'use_device_ptr'" 7460 << getOpenMPDirectiveName(OMPD_target_data); 7461 return StmtError(); 7462 } 7463 7464 setFunctionHasBranchProtectedScope(); 7465 7466 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7467 AStmt); 7468 } 7469 7470 StmtResult 7471 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 7472 SourceLocation StartLoc, 7473 SourceLocation EndLoc, Stmt *AStmt) { 7474 if (!AStmt) 7475 return StmtError(); 7476 7477 auto *CS = cast<CapturedStmt>(AStmt); 7478 // 1.2.2 OpenMP Language Terminology 7479 // Structured block - An executable statement with a single entry at the 7480 // top and a single exit at the bottom. 7481 // The point of exit cannot be a branch out of the structured block. 7482 // longjmp() and throw() must not violate the entry/exit criteria. 7483 CS->getCapturedDecl()->setNothrow(); 7484 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 7485 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7486 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7487 // 1.2.2 OpenMP Language Terminology 7488 // Structured block - An executable statement with a single entry at the 7489 // top and a single exit at the bottom. 7490 // The point of exit cannot be a branch out of the structured block. 7491 // longjmp() and throw() must not violate the entry/exit criteria. 7492 CS->getCapturedDecl()->setNothrow(); 7493 } 7494 7495 // OpenMP [2.10.2, Restrictions, p. 99] 7496 // At least one map clause must appear on the directive. 7497 if (!hasClauses(Clauses, OMPC_map)) { 7498 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7499 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 7500 return StmtError(); 7501 } 7502 7503 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7504 AStmt); 7505 } 7506 7507 StmtResult 7508 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 7509 SourceLocation StartLoc, 7510 SourceLocation EndLoc, Stmt *AStmt) { 7511 if (!AStmt) 7512 return StmtError(); 7513 7514 auto *CS = cast<CapturedStmt>(AStmt); 7515 // 1.2.2 OpenMP Language Terminology 7516 // Structured block - An executable statement with a single entry at the 7517 // top and a single exit at the bottom. 7518 // The point of exit cannot be a branch out of the structured block. 7519 // longjmp() and throw() must not violate the entry/exit criteria. 7520 CS->getCapturedDecl()->setNothrow(); 7521 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 7522 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7523 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7524 // 1.2.2 OpenMP Language Terminology 7525 // Structured block - An executable statement with a single entry at the 7526 // top and a single exit at the bottom. 7527 // The point of exit cannot be a branch out of the structured block. 7528 // longjmp() and throw() must not violate the entry/exit criteria. 7529 CS->getCapturedDecl()->setNothrow(); 7530 } 7531 7532 // OpenMP [2.10.3, Restrictions, p. 102] 7533 // At least one map clause must appear on the directive. 7534 if (!hasClauses(Clauses, OMPC_map)) { 7535 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 7536 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 7537 return StmtError(); 7538 } 7539 7540 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7541 AStmt); 7542 } 7543 7544 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 7545 SourceLocation StartLoc, 7546 SourceLocation EndLoc, 7547 Stmt *AStmt) { 7548 if (!AStmt) 7549 return StmtError(); 7550 7551 auto *CS = cast<CapturedStmt>(AStmt); 7552 // 1.2.2 OpenMP Language Terminology 7553 // Structured block - An executable statement with a single entry at the 7554 // top and a single exit at the bottom. 7555 // The point of exit cannot be a branch out of the structured block. 7556 // longjmp() and throw() must not violate the entry/exit criteria. 7557 CS->getCapturedDecl()->setNothrow(); 7558 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 7559 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7560 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7561 // 1.2.2 OpenMP Language Terminology 7562 // Structured block - An executable statement with a single entry at the 7563 // top and a single exit at the bottom. 7564 // The point of exit cannot be a branch out of the structured block. 7565 // longjmp() and throw() must not violate the entry/exit criteria. 7566 CS->getCapturedDecl()->setNothrow(); 7567 } 7568 7569 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 7570 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 7571 return StmtError(); 7572 } 7573 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 7574 AStmt); 7575 } 7576 7577 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 7578 Stmt *AStmt, SourceLocation StartLoc, 7579 SourceLocation EndLoc) { 7580 if (!AStmt) 7581 return StmtError(); 7582 7583 auto *CS = cast<CapturedStmt>(AStmt); 7584 // 1.2.2 OpenMP Language Terminology 7585 // Structured block - An executable statement with a single entry at the 7586 // top and a single exit at the bottom. 7587 // The point of exit cannot be a branch out of the structured block. 7588 // longjmp() and throw() must not violate the entry/exit criteria. 7589 CS->getCapturedDecl()->setNothrow(); 7590 7591 setFunctionHasBranchProtectedScope(); 7592 7593 DSAStack->setParentTeamsRegionLoc(StartLoc); 7594 7595 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7596 } 7597 7598 StmtResult 7599 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 7600 SourceLocation EndLoc, 7601 OpenMPDirectiveKind CancelRegion) { 7602 if (DSAStack->isParentNowaitRegion()) { 7603 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 7604 return StmtError(); 7605 } 7606 if (DSAStack->isParentOrderedRegion()) { 7607 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 7608 return StmtError(); 7609 } 7610 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 7611 CancelRegion); 7612 } 7613 7614 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 7615 SourceLocation StartLoc, 7616 SourceLocation EndLoc, 7617 OpenMPDirectiveKind CancelRegion) { 7618 if (DSAStack->isParentNowaitRegion()) { 7619 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 7620 return StmtError(); 7621 } 7622 if (DSAStack->isParentOrderedRegion()) { 7623 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 7624 return StmtError(); 7625 } 7626 DSAStack->setParentCancelRegion(/*Cancel=*/true); 7627 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7628 CancelRegion); 7629 } 7630 7631 static bool checkGrainsizeNumTasksClauses(Sema &S, 7632 ArrayRef<OMPClause *> Clauses) { 7633 const OMPClause *PrevClause = nullptr; 7634 bool ErrorFound = false; 7635 for (const OMPClause *C : Clauses) { 7636 if (C->getClauseKind() == OMPC_grainsize || 7637 C->getClauseKind() == OMPC_num_tasks) { 7638 if (!PrevClause) 7639 PrevClause = C; 7640 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 7641 S.Diag(C->getBeginLoc(), 7642 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 7643 << getOpenMPClauseName(C->getClauseKind()) 7644 << getOpenMPClauseName(PrevClause->getClauseKind()); 7645 S.Diag(PrevClause->getBeginLoc(), 7646 diag::note_omp_previous_grainsize_num_tasks) 7647 << getOpenMPClauseName(PrevClause->getClauseKind()); 7648 ErrorFound = true; 7649 } 7650 } 7651 } 7652 return ErrorFound; 7653 } 7654 7655 static bool checkReductionClauseWithNogroup(Sema &S, 7656 ArrayRef<OMPClause *> Clauses) { 7657 const OMPClause *ReductionClause = nullptr; 7658 const OMPClause *NogroupClause = nullptr; 7659 for (const OMPClause *C : Clauses) { 7660 if (C->getClauseKind() == OMPC_reduction) { 7661 ReductionClause = C; 7662 if (NogroupClause) 7663 break; 7664 continue; 7665 } 7666 if (C->getClauseKind() == OMPC_nogroup) { 7667 NogroupClause = C; 7668 if (ReductionClause) 7669 break; 7670 continue; 7671 } 7672 } 7673 if (ReductionClause && NogroupClause) { 7674 S.Diag(ReductionClause->getBeginLoc(), diag::err_omp_reduction_with_nogroup) 7675 << SourceRange(NogroupClause->getBeginLoc(), 7676 NogroupClause->getEndLoc()); 7677 return true; 7678 } 7679 return false; 7680 } 7681 7682 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 7683 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7684 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7685 if (!AStmt) 7686 return StmtError(); 7687 7688 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7689 OMPLoopDirective::HelperExprs B; 7690 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7691 // define the nested loops number. 7692 unsigned NestedLoopCount = 7693 checkOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 7694 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7695 VarsWithImplicitDSA, B); 7696 if (NestedLoopCount == 0) 7697 return StmtError(); 7698 7699 assert((CurContext->isDependentContext() || B.builtAll()) && 7700 "omp for loop exprs were not built"); 7701 7702 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7703 // The grainsize clause and num_tasks clause are mutually exclusive and may 7704 // not appear on the same taskloop directive. 7705 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7706 return StmtError(); 7707 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7708 // If a reduction clause is present on the taskloop directive, the nogroup 7709 // clause must not be specified. 7710 if (checkReductionClauseWithNogroup(*this, Clauses)) 7711 return StmtError(); 7712 7713 setFunctionHasBranchProtectedScope(); 7714 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 7715 NestedLoopCount, Clauses, AStmt, B); 7716 } 7717 7718 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 7719 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7720 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7721 if (!AStmt) 7722 return StmtError(); 7723 7724 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7725 OMPLoopDirective::HelperExprs B; 7726 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7727 // define the nested loops number. 7728 unsigned NestedLoopCount = 7729 checkOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 7730 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7731 VarsWithImplicitDSA, B); 7732 if (NestedLoopCount == 0) 7733 return StmtError(); 7734 7735 assert((CurContext->isDependentContext() || B.builtAll()) && 7736 "omp for loop exprs were not built"); 7737 7738 if (!CurContext->isDependentContext()) { 7739 // Finalize the clauses that need pre-built expressions for CodeGen. 7740 for (OMPClause *C : Clauses) { 7741 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7742 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7743 B.NumIterations, *this, CurScope, 7744 DSAStack)) 7745 return StmtError(); 7746 } 7747 } 7748 7749 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7750 // The grainsize clause and num_tasks clause are mutually exclusive and may 7751 // not appear on the same taskloop directive. 7752 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7753 return StmtError(); 7754 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7755 // If a reduction clause is present on the taskloop directive, the nogroup 7756 // clause must not be specified. 7757 if (checkReductionClauseWithNogroup(*this, Clauses)) 7758 return StmtError(); 7759 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7760 return StmtError(); 7761 7762 setFunctionHasBranchProtectedScope(); 7763 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 7764 NestedLoopCount, Clauses, AStmt, B); 7765 } 7766 7767 StmtResult Sema::ActOnOpenMPDistributeDirective( 7768 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7769 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7770 if (!AStmt) 7771 return StmtError(); 7772 7773 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7774 OMPLoopDirective::HelperExprs B; 7775 // In presence of clause 'collapse' with number of loops, it will 7776 // define the nested loops number. 7777 unsigned NestedLoopCount = 7778 checkOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 7779 nullptr /*ordered not a clause on distribute*/, AStmt, 7780 *this, *DSAStack, VarsWithImplicitDSA, B); 7781 if (NestedLoopCount == 0) 7782 return StmtError(); 7783 7784 assert((CurContext->isDependentContext() || B.builtAll()) && 7785 "omp for loop exprs were not built"); 7786 7787 setFunctionHasBranchProtectedScope(); 7788 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 7789 NestedLoopCount, Clauses, AStmt, B); 7790 } 7791 7792 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 7793 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7794 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7795 if (!AStmt) 7796 return StmtError(); 7797 7798 auto *CS = cast<CapturedStmt>(AStmt); 7799 // 1.2.2 OpenMP Language Terminology 7800 // Structured block - An executable statement with a single entry at the 7801 // top and a single exit at the bottom. 7802 // The point of exit cannot be a branch out of the structured block. 7803 // longjmp() and throw() must not violate the entry/exit criteria. 7804 CS->getCapturedDecl()->setNothrow(); 7805 for (int ThisCaptureLevel = 7806 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 7807 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7808 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7809 // 1.2.2 OpenMP Language Terminology 7810 // Structured block - An executable statement with a single entry at the 7811 // top and a single exit at the bottom. 7812 // The point of exit cannot be a branch out of the structured block. 7813 // longjmp() and throw() must not violate the entry/exit criteria. 7814 CS->getCapturedDecl()->setNothrow(); 7815 } 7816 7817 OMPLoopDirective::HelperExprs B; 7818 // In presence of clause 'collapse' with number of loops, it will 7819 // define the nested loops number. 7820 unsigned NestedLoopCount = checkOpenMPLoop( 7821 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 7822 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7823 VarsWithImplicitDSA, B); 7824 if (NestedLoopCount == 0) 7825 return StmtError(); 7826 7827 assert((CurContext->isDependentContext() || B.builtAll()) && 7828 "omp for loop exprs were not built"); 7829 7830 setFunctionHasBranchProtectedScope(); 7831 return OMPDistributeParallelForDirective::Create( 7832 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 7833 DSAStack->isCancelRegion()); 7834 } 7835 7836 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 7837 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7838 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7839 if (!AStmt) 7840 return StmtError(); 7841 7842 auto *CS = cast<CapturedStmt>(AStmt); 7843 // 1.2.2 OpenMP Language Terminology 7844 // Structured block - An executable statement with a single entry at the 7845 // top and a single exit at the bottom. 7846 // The point of exit cannot be a branch out of the structured block. 7847 // longjmp() and throw() must not violate the entry/exit criteria. 7848 CS->getCapturedDecl()->setNothrow(); 7849 for (int ThisCaptureLevel = 7850 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 7851 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7852 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7853 // 1.2.2 OpenMP Language Terminology 7854 // Structured block - An executable statement with a single entry at the 7855 // top and a single exit at the bottom. 7856 // The point of exit cannot be a branch out of the structured block. 7857 // longjmp() and throw() must not violate the entry/exit criteria. 7858 CS->getCapturedDecl()->setNothrow(); 7859 } 7860 7861 OMPLoopDirective::HelperExprs B; 7862 // In presence of clause 'collapse' with number of loops, it will 7863 // define the nested loops number. 7864 unsigned NestedLoopCount = checkOpenMPLoop( 7865 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 7866 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7867 VarsWithImplicitDSA, B); 7868 if (NestedLoopCount == 0) 7869 return StmtError(); 7870 7871 assert((CurContext->isDependentContext() || B.builtAll()) && 7872 "omp for loop exprs were not built"); 7873 7874 if (!CurContext->isDependentContext()) { 7875 // Finalize the clauses that need pre-built expressions for CodeGen. 7876 for (OMPClause *C : Clauses) { 7877 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7878 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7879 B.NumIterations, *this, CurScope, 7880 DSAStack)) 7881 return StmtError(); 7882 } 7883 } 7884 7885 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7886 return StmtError(); 7887 7888 setFunctionHasBranchProtectedScope(); 7889 return OMPDistributeParallelForSimdDirective::Create( 7890 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7891 } 7892 7893 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 7894 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7895 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7896 if (!AStmt) 7897 return StmtError(); 7898 7899 auto *CS = cast<CapturedStmt>(AStmt); 7900 // 1.2.2 OpenMP Language Terminology 7901 // Structured block - An executable statement with a single entry at the 7902 // top and a single exit at the bottom. 7903 // The point of exit cannot be a branch out of the structured block. 7904 // longjmp() and throw() must not violate the entry/exit criteria. 7905 CS->getCapturedDecl()->setNothrow(); 7906 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 7907 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7908 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7909 // 1.2.2 OpenMP Language Terminology 7910 // Structured block - An executable statement with a single entry at the 7911 // top and a single exit at the bottom. 7912 // The point of exit cannot be a branch out of the structured block. 7913 // longjmp() and throw() must not violate the entry/exit criteria. 7914 CS->getCapturedDecl()->setNothrow(); 7915 } 7916 7917 OMPLoopDirective::HelperExprs B; 7918 // In presence of clause 'collapse' with number of loops, it will 7919 // define the nested loops number. 7920 unsigned NestedLoopCount = 7921 checkOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 7922 nullptr /*ordered not a clause on distribute*/, CS, *this, 7923 *DSAStack, VarsWithImplicitDSA, B); 7924 if (NestedLoopCount == 0) 7925 return StmtError(); 7926 7927 assert((CurContext->isDependentContext() || B.builtAll()) && 7928 "omp for loop exprs were not built"); 7929 7930 if (!CurContext->isDependentContext()) { 7931 // Finalize the clauses that need pre-built expressions for CodeGen. 7932 for (OMPClause *C : Clauses) { 7933 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7934 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7935 B.NumIterations, *this, CurScope, 7936 DSAStack)) 7937 return StmtError(); 7938 } 7939 } 7940 7941 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7942 return StmtError(); 7943 7944 setFunctionHasBranchProtectedScope(); 7945 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 7946 NestedLoopCount, Clauses, AStmt, B); 7947 } 7948 7949 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 7950 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7951 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 7952 if (!AStmt) 7953 return StmtError(); 7954 7955 auto *CS = cast<CapturedStmt>(AStmt); 7956 // 1.2.2 OpenMP Language Terminology 7957 // Structured block - An executable statement with a single entry at the 7958 // top and a single exit at the bottom. 7959 // The point of exit cannot be a branch out of the structured block. 7960 // longjmp() and throw() must not violate the entry/exit criteria. 7961 CS->getCapturedDecl()->setNothrow(); 7962 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 7963 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7964 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7965 // 1.2.2 OpenMP Language Terminology 7966 // Structured block - An executable statement with a single entry at the 7967 // top and a single exit at the bottom. 7968 // The point of exit cannot be a branch out of the structured block. 7969 // longjmp() and throw() must not violate the entry/exit criteria. 7970 CS->getCapturedDecl()->setNothrow(); 7971 } 7972 7973 OMPLoopDirective::HelperExprs B; 7974 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7975 // define the nested loops number. 7976 unsigned NestedLoopCount = checkOpenMPLoop( 7977 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 7978 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7979 VarsWithImplicitDSA, B); 7980 if (NestedLoopCount == 0) 7981 return StmtError(); 7982 7983 assert((CurContext->isDependentContext() || B.builtAll()) && 7984 "omp target parallel for simd loop exprs were not built"); 7985 7986 if (!CurContext->isDependentContext()) { 7987 // Finalize the clauses that need pre-built expressions for CodeGen. 7988 for (OMPClause *C : Clauses) { 7989 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7990 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7991 B.NumIterations, *this, CurScope, 7992 DSAStack)) 7993 return StmtError(); 7994 } 7995 } 7996 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7997 return StmtError(); 7998 7999 setFunctionHasBranchProtectedScope(); 8000 return OMPTargetParallelForSimdDirective::Create( 8001 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8002 } 8003 8004 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 8005 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8006 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8007 if (!AStmt) 8008 return StmtError(); 8009 8010 auto *CS = cast<CapturedStmt>(AStmt); 8011 // 1.2.2 OpenMP Language Terminology 8012 // Structured block - An executable statement with a single entry at the 8013 // top and a single exit at the bottom. 8014 // The point of exit cannot be a branch out of the structured block. 8015 // longjmp() and throw() must not violate the entry/exit criteria. 8016 CS->getCapturedDecl()->setNothrow(); 8017 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 8018 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8019 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8020 // 1.2.2 OpenMP Language Terminology 8021 // Structured block - An executable statement with a single entry at the 8022 // top and a single exit at the bottom. 8023 // The point of exit cannot be a branch out of the structured block. 8024 // longjmp() and throw() must not violate the entry/exit criteria. 8025 CS->getCapturedDecl()->setNothrow(); 8026 } 8027 8028 OMPLoopDirective::HelperExprs B; 8029 // In presence of clause 'collapse' with number of loops, it will define the 8030 // nested loops number. 8031 unsigned NestedLoopCount = 8032 checkOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 8033 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 8034 VarsWithImplicitDSA, B); 8035 if (NestedLoopCount == 0) 8036 return StmtError(); 8037 8038 assert((CurContext->isDependentContext() || B.builtAll()) && 8039 "omp target simd loop exprs were not built"); 8040 8041 if (!CurContext->isDependentContext()) { 8042 // Finalize the clauses that need pre-built expressions for CodeGen. 8043 for (OMPClause *C : Clauses) { 8044 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8045 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8046 B.NumIterations, *this, CurScope, 8047 DSAStack)) 8048 return StmtError(); 8049 } 8050 } 8051 8052 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8053 return StmtError(); 8054 8055 setFunctionHasBranchProtectedScope(); 8056 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 8057 NestedLoopCount, Clauses, AStmt, B); 8058 } 8059 8060 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 8061 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8062 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8063 if (!AStmt) 8064 return StmtError(); 8065 8066 auto *CS = cast<CapturedStmt>(AStmt); 8067 // 1.2.2 OpenMP Language Terminology 8068 // Structured block - An executable statement with a single entry at the 8069 // top and a single exit at the bottom. 8070 // The point of exit cannot be a branch out of the structured block. 8071 // longjmp() and throw() must not violate the entry/exit criteria. 8072 CS->getCapturedDecl()->setNothrow(); 8073 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 8074 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8075 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8076 // 1.2.2 OpenMP Language Terminology 8077 // Structured block - An executable statement with a single entry at the 8078 // top and a single exit at the bottom. 8079 // The point of exit cannot be a branch out of the structured block. 8080 // longjmp() and throw() must not violate the entry/exit criteria. 8081 CS->getCapturedDecl()->setNothrow(); 8082 } 8083 8084 OMPLoopDirective::HelperExprs B; 8085 // In presence of clause 'collapse' with number of loops, it will 8086 // define the nested loops number. 8087 unsigned NestedLoopCount = 8088 checkOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 8089 nullptr /*ordered not a clause on distribute*/, CS, *this, 8090 *DSAStack, VarsWithImplicitDSA, B); 8091 if (NestedLoopCount == 0) 8092 return StmtError(); 8093 8094 assert((CurContext->isDependentContext() || B.builtAll()) && 8095 "omp teams distribute loop exprs were not built"); 8096 8097 setFunctionHasBranchProtectedScope(); 8098 8099 DSAStack->setParentTeamsRegionLoc(StartLoc); 8100 8101 return OMPTeamsDistributeDirective::Create( 8102 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8103 } 8104 8105 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 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 = 8119 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 8120 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8121 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8122 // 1.2.2 OpenMP Language Terminology 8123 // Structured block - An executable statement with a single entry at the 8124 // top and a single exit at the bottom. 8125 // The point of exit cannot be a branch out of the structured block. 8126 // longjmp() and throw() must not violate the entry/exit criteria. 8127 CS->getCapturedDecl()->setNothrow(); 8128 } 8129 8130 8131 OMPLoopDirective::HelperExprs B; 8132 // In presence of clause 'collapse' with number of loops, it will 8133 // define the nested loops number. 8134 unsigned NestedLoopCount = checkOpenMPLoop( 8135 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8136 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8137 VarsWithImplicitDSA, B); 8138 8139 if (NestedLoopCount == 0) 8140 return StmtError(); 8141 8142 assert((CurContext->isDependentContext() || B.builtAll()) && 8143 "omp teams distribute simd loop exprs were not built"); 8144 8145 if (!CurContext->isDependentContext()) { 8146 // Finalize the clauses that need pre-built expressions for CodeGen. 8147 for (OMPClause *C : Clauses) { 8148 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8149 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8150 B.NumIterations, *this, CurScope, 8151 DSAStack)) 8152 return StmtError(); 8153 } 8154 } 8155 8156 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8157 return StmtError(); 8158 8159 setFunctionHasBranchProtectedScope(); 8160 8161 DSAStack->setParentTeamsRegionLoc(StartLoc); 8162 8163 return OMPTeamsDistributeSimdDirective::Create( 8164 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8165 } 8166 8167 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 8168 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8169 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8170 if (!AStmt) 8171 return StmtError(); 8172 8173 auto *CS = cast<CapturedStmt>(AStmt); 8174 // 1.2.2 OpenMP Language Terminology 8175 // Structured block - An executable statement with a single entry at the 8176 // top and a single exit at the bottom. 8177 // The point of exit cannot be a branch out of the structured block. 8178 // longjmp() and throw() must not violate the entry/exit criteria. 8179 CS->getCapturedDecl()->setNothrow(); 8180 8181 for (int ThisCaptureLevel = 8182 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 8183 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8184 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8185 // 1.2.2 OpenMP Language Terminology 8186 // Structured block - An executable statement with a single entry at the 8187 // top and a single exit at the bottom. 8188 // The point of exit cannot be a branch out of the structured block. 8189 // longjmp() and throw() must not violate the entry/exit criteria. 8190 CS->getCapturedDecl()->setNothrow(); 8191 } 8192 8193 OMPLoopDirective::HelperExprs B; 8194 // In presence of clause 'collapse' with number of loops, it will 8195 // define the nested loops number. 8196 unsigned NestedLoopCount = checkOpenMPLoop( 8197 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 8198 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8199 VarsWithImplicitDSA, B); 8200 8201 if (NestedLoopCount == 0) 8202 return StmtError(); 8203 8204 assert((CurContext->isDependentContext() || B.builtAll()) && 8205 "omp for loop exprs were not built"); 8206 8207 if (!CurContext->isDependentContext()) { 8208 // Finalize the clauses that need pre-built expressions for CodeGen. 8209 for (OMPClause *C : Clauses) { 8210 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8211 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8212 B.NumIterations, *this, CurScope, 8213 DSAStack)) 8214 return StmtError(); 8215 } 8216 } 8217 8218 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8219 return StmtError(); 8220 8221 setFunctionHasBranchProtectedScope(); 8222 8223 DSAStack->setParentTeamsRegionLoc(StartLoc); 8224 8225 return OMPTeamsDistributeParallelForSimdDirective::Create( 8226 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8227 } 8228 8229 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 8230 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8231 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8232 if (!AStmt) 8233 return StmtError(); 8234 8235 auto *CS = cast<CapturedStmt>(AStmt); 8236 // 1.2.2 OpenMP Language Terminology 8237 // Structured block - An executable statement with a single entry at the 8238 // top and a single exit at the bottom. 8239 // The point of exit cannot be a branch out of the structured block. 8240 // longjmp() and throw() must not violate the entry/exit criteria. 8241 CS->getCapturedDecl()->setNothrow(); 8242 8243 for (int ThisCaptureLevel = 8244 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 8245 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8246 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8247 // 1.2.2 OpenMP Language Terminology 8248 // Structured block - An executable statement with a single entry at the 8249 // top and a single exit at the bottom. 8250 // The point of exit cannot be a branch out of the structured block. 8251 // longjmp() and throw() must not violate the entry/exit criteria. 8252 CS->getCapturedDecl()->setNothrow(); 8253 } 8254 8255 OMPLoopDirective::HelperExprs B; 8256 // In presence of clause 'collapse' with number of loops, it will 8257 // define the nested loops number. 8258 unsigned NestedLoopCount = checkOpenMPLoop( 8259 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8260 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8261 VarsWithImplicitDSA, B); 8262 8263 if (NestedLoopCount == 0) 8264 return StmtError(); 8265 8266 assert((CurContext->isDependentContext() || B.builtAll()) && 8267 "omp for loop exprs were not built"); 8268 8269 setFunctionHasBranchProtectedScope(); 8270 8271 DSAStack->setParentTeamsRegionLoc(StartLoc); 8272 8273 return OMPTeamsDistributeParallelForDirective::Create( 8274 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8275 DSAStack->isCancelRegion()); 8276 } 8277 8278 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 8279 Stmt *AStmt, 8280 SourceLocation StartLoc, 8281 SourceLocation EndLoc) { 8282 if (!AStmt) 8283 return StmtError(); 8284 8285 auto *CS = cast<CapturedStmt>(AStmt); 8286 // 1.2.2 OpenMP Language Terminology 8287 // Structured block - An executable statement with a single entry at the 8288 // top and a single exit at the bottom. 8289 // The point of exit cannot be a branch out of the structured block. 8290 // longjmp() and throw() must not violate the entry/exit criteria. 8291 CS->getCapturedDecl()->setNothrow(); 8292 8293 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 8294 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8295 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8296 // 1.2.2 OpenMP Language Terminology 8297 // Structured block - An executable statement with a single entry at the 8298 // top and a single exit at the bottom. 8299 // The point of exit cannot be a branch out of the structured block. 8300 // longjmp() and throw() must not violate the entry/exit criteria. 8301 CS->getCapturedDecl()->setNothrow(); 8302 } 8303 setFunctionHasBranchProtectedScope(); 8304 8305 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 8306 AStmt); 8307 } 8308 8309 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 8310 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8311 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8312 if (!AStmt) 8313 return StmtError(); 8314 8315 auto *CS = cast<CapturedStmt>(AStmt); 8316 // 1.2.2 OpenMP Language Terminology 8317 // Structured block - An executable statement with a single entry at the 8318 // top and a single exit at the bottom. 8319 // The point of exit cannot be a branch out of the structured block. 8320 // longjmp() and throw() must not violate the entry/exit criteria. 8321 CS->getCapturedDecl()->setNothrow(); 8322 for (int ThisCaptureLevel = 8323 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 8324 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8325 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8326 // 1.2.2 OpenMP Language Terminology 8327 // Structured block - An executable statement with a single entry at the 8328 // top and a single exit at the bottom. 8329 // The point of exit cannot be a branch out of the structured block. 8330 // longjmp() and throw() must not violate the entry/exit criteria. 8331 CS->getCapturedDecl()->setNothrow(); 8332 } 8333 8334 OMPLoopDirective::HelperExprs B; 8335 // In presence of clause 'collapse' with number of loops, it will 8336 // define the nested loops number. 8337 unsigned NestedLoopCount = checkOpenMPLoop( 8338 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 8339 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8340 VarsWithImplicitDSA, B); 8341 if (NestedLoopCount == 0) 8342 return StmtError(); 8343 8344 assert((CurContext->isDependentContext() || B.builtAll()) && 8345 "omp target teams distribute loop exprs were not built"); 8346 8347 setFunctionHasBranchProtectedScope(); 8348 return OMPTargetTeamsDistributeDirective::Create( 8349 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8350 } 8351 8352 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 8353 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8354 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8355 if (!AStmt) 8356 return StmtError(); 8357 8358 auto *CS = cast<CapturedStmt>(AStmt); 8359 // 1.2.2 OpenMP Language Terminology 8360 // Structured block - An executable statement with a single entry at the 8361 // top and a single exit at the bottom. 8362 // The point of exit cannot be a branch out of the structured block. 8363 // longjmp() and throw() must not violate the entry/exit criteria. 8364 CS->getCapturedDecl()->setNothrow(); 8365 for (int ThisCaptureLevel = 8366 getOpenMPCaptureLevels(OMPD_target_teams_distribute_parallel_for); 8367 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8368 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8369 // 1.2.2 OpenMP Language Terminology 8370 // Structured block - An executable statement with a single entry at the 8371 // top and a single exit at the bottom. 8372 // The point of exit cannot be a branch out of the structured block. 8373 // longjmp() and throw() must not violate the entry/exit criteria. 8374 CS->getCapturedDecl()->setNothrow(); 8375 } 8376 8377 OMPLoopDirective::HelperExprs B; 8378 // In presence of clause 'collapse' with number of loops, it will 8379 // define the nested loops number. 8380 unsigned NestedLoopCount = checkOpenMPLoop( 8381 OMPD_target_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 8382 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8383 VarsWithImplicitDSA, B); 8384 if (NestedLoopCount == 0) 8385 return StmtError(); 8386 8387 assert((CurContext->isDependentContext() || B.builtAll()) && 8388 "omp target teams distribute parallel for loop exprs were not built"); 8389 8390 if (!CurContext->isDependentContext()) { 8391 // Finalize the clauses that need pre-built expressions for CodeGen. 8392 for (OMPClause *C : Clauses) { 8393 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8394 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8395 B.NumIterations, *this, CurScope, 8396 DSAStack)) 8397 return StmtError(); 8398 } 8399 } 8400 8401 setFunctionHasBranchProtectedScope(); 8402 return OMPTargetTeamsDistributeParallelForDirective::Create( 8403 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 8404 DSAStack->isCancelRegion()); 8405 } 8406 8407 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 8408 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8409 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8410 if (!AStmt) 8411 return StmtError(); 8412 8413 auto *CS = cast<CapturedStmt>(AStmt); 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 for (int ThisCaptureLevel = getOpenMPCaptureLevels( 8421 OMPD_target_teams_distribute_parallel_for_simd); 8422 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8423 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8424 // 1.2.2 OpenMP Language Terminology 8425 // Structured block - An executable statement with a single entry at the 8426 // top and a single exit at the bottom. 8427 // The point of exit cannot be a branch out of the structured block. 8428 // longjmp() and throw() must not violate the entry/exit criteria. 8429 CS->getCapturedDecl()->setNothrow(); 8430 } 8431 8432 OMPLoopDirective::HelperExprs B; 8433 // In presence of clause 'collapse' with number of loops, it will 8434 // define the nested loops number. 8435 unsigned NestedLoopCount = 8436 checkOpenMPLoop(OMPD_target_teams_distribute_parallel_for_simd, 8437 getCollapseNumberExpr(Clauses), 8438 nullptr /*ordered not a clause on distribute*/, CS, *this, 8439 *DSAStack, VarsWithImplicitDSA, B); 8440 if (NestedLoopCount == 0) 8441 return StmtError(); 8442 8443 assert((CurContext->isDependentContext() || B.builtAll()) && 8444 "omp target teams distribute parallel for simd loop exprs were not " 8445 "built"); 8446 8447 if (!CurContext->isDependentContext()) { 8448 // Finalize the clauses that need pre-built expressions for CodeGen. 8449 for (OMPClause *C : Clauses) { 8450 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8451 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8452 B.NumIterations, *this, CurScope, 8453 DSAStack)) 8454 return StmtError(); 8455 } 8456 } 8457 8458 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8459 return StmtError(); 8460 8461 setFunctionHasBranchProtectedScope(); 8462 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 8463 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8464 } 8465 8466 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 8467 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 8468 SourceLocation EndLoc, VarsWithInheritedDSAType &VarsWithImplicitDSA) { 8469 if (!AStmt) 8470 return StmtError(); 8471 8472 auto *CS = cast<CapturedStmt>(AStmt); 8473 // 1.2.2 OpenMP Language Terminology 8474 // Structured block - An executable statement with a single entry at the 8475 // top and a single exit at the bottom. 8476 // The point of exit cannot be a branch out of the structured block. 8477 // longjmp() and throw() must not violate the entry/exit criteria. 8478 CS->getCapturedDecl()->setNothrow(); 8479 for (int ThisCaptureLevel = 8480 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 8481 ThisCaptureLevel > 1; --ThisCaptureLevel) { 8482 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 8483 // 1.2.2 OpenMP Language Terminology 8484 // Structured block - An executable statement with a single entry at the 8485 // top and a single exit at the bottom. 8486 // The point of exit cannot be a branch out of the structured block. 8487 // longjmp() and throw() must not violate the entry/exit criteria. 8488 CS->getCapturedDecl()->setNothrow(); 8489 } 8490 8491 OMPLoopDirective::HelperExprs B; 8492 // In presence of clause 'collapse' with number of loops, it will 8493 // define the nested loops number. 8494 unsigned NestedLoopCount = checkOpenMPLoop( 8495 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 8496 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 8497 VarsWithImplicitDSA, B); 8498 if (NestedLoopCount == 0) 8499 return StmtError(); 8500 8501 assert((CurContext->isDependentContext() || B.builtAll()) && 8502 "omp target teams distribute simd loop exprs were not built"); 8503 8504 if (!CurContext->isDependentContext()) { 8505 // Finalize the clauses that need pre-built expressions for CodeGen. 8506 for (OMPClause *C : Clauses) { 8507 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 8508 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 8509 B.NumIterations, *this, CurScope, 8510 DSAStack)) 8511 return StmtError(); 8512 } 8513 } 8514 8515 if (checkSimdlenSafelenSpecified(*this, Clauses)) 8516 return StmtError(); 8517 8518 setFunctionHasBranchProtectedScope(); 8519 return OMPTargetTeamsDistributeSimdDirective::Create( 8520 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 8521 } 8522 8523 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 8524 SourceLocation StartLoc, 8525 SourceLocation LParenLoc, 8526 SourceLocation EndLoc) { 8527 OMPClause *Res = nullptr; 8528 switch (Kind) { 8529 case OMPC_final: 8530 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 8531 break; 8532 case OMPC_num_threads: 8533 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 8534 break; 8535 case OMPC_safelen: 8536 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 8537 break; 8538 case OMPC_simdlen: 8539 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 8540 break; 8541 case OMPC_allocator: 8542 Res = ActOnOpenMPAllocatorClause(Expr, StartLoc, LParenLoc, EndLoc); 8543 break; 8544 case OMPC_collapse: 8545 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 8546 break; 8547 case OMPC_ordered: 8548 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 8549 break; 8550 case OMPC_device: 8551 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 8552 break; 8553 case OMPC_num_teams: 8554 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 8555 break; 8556 case OMPC_thread_limit: 8557 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 8558 break; 8559 case OMPC_priority: 8560 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 8561 break; 8562 case OMPC_grainsize: 8563 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 8564 break; 8565 case OMPC_num_tasks: 8566 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 8567 break; 8568 case OMPC_hint: 8569 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 8570 break; 8571 case OMPC_if: 8572 case OMPC_default: 8573 case OMPC_proc_bind: 8574 case OMPC_schedule: 8575 case OMPC_private: 8576 case OMPC_firstprivate: 8577 case OMPC_lastprivate: 8578 case OMPC_shared: 8579 case OMPC_reduction: 8580 case OMPC_task_reduction: 8581 case OMPC_in_reduction: 8582 case OMPC_linear: 8583 case OMPC_aligned: 8584 case OMPC_copyin: 8585 case OMPC_copyprivate: 8586 case OMPC_nowait: 8587 case OMPC_untied: 8588 case OMPC_mergeable: 8589 case OMPC_threadprivate: 8590 case OMPC_allocate: 8591 case OMPC_flush: 8592 case OMPC_read: 8593 case OMPC_write: 8594 case OMPC_update: 8595 case OMPC_capture: 8596 case OMPC_seq_cst: 8597 case OMPC_depend: 8598 case OMPC_threads: 8599 case OMPC_simd: 8600 case OMPC_map: 8601 case OMPC_nogroup: 8602 case OMPC_dist_schedule: 8603 case OMPC_defaultmap: 8604 case OMPC_unknown: 8605 case OMPC_uniform: 8606 case OMPC_to: 8607 case OMPC_from: 8608 case OMPC_use_device_ptr: 8609 case OMPC_is_device_ptr: 8610 case OMPC_unified_address: 8611 case OMPC_unified_shared_memory: 8612 case OMPC_reverse_offload: 8613 case OMPC_dynamic_allocators: 8614 case OMPC_atomic_default_mem_order: 8615 llvm_unreachable("Clause is not allowed."); 8616 } 8617 return Res; 8618 } 8619 8620 // An OpenMP directive such as 'target parallel' has two captured regions: 8621 // for the 'target' and 'parallel' respectively. This function returns 8622 // the region in which to capture expressions associated with a clause. 8623 // A return value of OMPD_unknown signifies that the expression should not 8624 // be captured. 8625 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 8626 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 8627 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 8628 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 8629 switch (CKind) { 8630 case OMPC_if: 8631 switch (DKind) { 8632 case OMPD_target_parallel: 8633 case OMPD_target_parallel_for: 8634 case OMPD_target_parallel_for_simd: 8635 // If this clause applies to the nested 'parallel' region, capture within 8636 // the 'target' region, otherwise do not capture. 8637 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 8638 CaptureRegion = OMPD_target; 8639 break; 8640 case OMPD_target_teams_distribute_parallel_for: 8641 case OMPD_target_teams_distribute_parallel_for_simd: 8642 // If this clause applies to the nested 'parallel' region, capture within 8643 // the 'teams' region, otherwise do not capture. 8644 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 8645 CaptureRegion = OMPD_teams; 8646 break; 8647 case OMPD_teams_distribute_parallel_for: 8648 case OMPD_teams_distribute_parallel_for_simd: 8649 CaptureRegion = OMPD_teams; 8650 break; 8651 case OMPD_target_update: 8652 case OMPD_target_enter_data: 8653 case OMPD_target_exit_data: 8654 CaptureRegion = OMPD_task; 8655 break; 8656 case OMPD_cancel: 8657 case OMPD_parallel: 8658 case OMPD_parallel_sections: 8659 case OMPD_parallel_for: 8660 case OMPD_parallel_for_simd: 8661 case OMPD_target: 8662 case OMPD_target_simd: 8663 case OMPD_target_teams: 8664 case OMPD_target_teams_distribute: 8665 case OMPD_target_teams_distribute_simd: 8666 case OMPD_distribute_parallel_for: 8667 case OMPD_distribute_parallel_for_simd: 8668 case OMPD_task: 8669 case OMPD_taskloop: 8670 case OMPD_taskloop_simd: 8671 case OMPD_target_data: 8672 // Do not capture if-clause expressions. 8673 break; 8674 case OMPD_threadprivate: 8675 case OMPD_allocate: 8676 case OMPD_taskyield: 8677 case OMPD_barrier: 8678 case OMPD_taskwait: 8679 case OMPD_cancellation_point: 8680 case OMPD_flush: 8681 case OMPD_declare_reduction: 8682 case OMPD_declare_mapper: 8683 case OMPD_declare_simd: 8684 case OMPD_declare_target: 8685 case OMPD_end_declare_target: 8686 case OMPD_teams: 8687 case OMPD_simd: 8688 case OMPD_for: 8689 case OMPD_for_simd: 8690 case OMPD_sections: 8691 case OMPD_section: 8692 case OMPD_single: 8693 case OMPD_master: 8694 case OMPD_critical: 8695 case OMPD_taskgroup: 8696 case OMPD_distribute: 8697 case OMPD_ordered: 8698 case OMPD_atomic: 8699 case OMPD_distribute_simd: 8700 case OMPD_teams_distribute: 8701 case OMPD_teams_distribute_simd: 8702 case OMPD_requires: 8703 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 8704 case OMPD_unknown: 8705 llvm_unreachable("Unknown OpenMP directive"); 8706 } 8707 break; 8708 case OMPC_num_threads: 8709 switch (DKind) { 8710 case OMPD_target_parallel: 8711 case OMPD_target_parallel_for: 8712 case OMPD_target_parallel_for_simd: 8713 CaptureRegion = OMPD_target; 8714 break; 8715 case OMPD_teams_distribute_parallel_for: 8716 case OMPD_teams_distribute_parallel_for_simd: 8717 case OMPD_target_teams_distribute_parallel_for: 8718 case OMPD_target_teams_distribute_parallel_for_simd: 8719 CaptureRegion = OMPD_teams; 8720 break; 8721 case OMPD_parallel: 8722 case OMPD_parallel_sections: 8723 case OMPD_parallel_for: 8724 case OMPD_parallel_for_simd: 8725 case OMPD_distribute_parallel_for: 8726 case OMPD_distribute_parallel_for_simd: 8727 // Do not capture num_threads-clause expressions. 8728 break; 8729 case OMPD_target_data: 8730 case OMPD_target_enter_data: 8731 case OMPD_target_exit_data: 8732 case OMPD_target_update: 8733 case OMPD_target: 8734 case OMPD_target_simd: 8735 case OMPD_target_teams: 8736 case OMPD_target_teams_distribute: 8737 case OMPD_target_teams_distribute_simd: 8738 case OMPD_cancel: 8739 case OMPD_task: 8740 case OMPD_taskloop: 8741 case OMPD_taskloop_simd: 8742 case OMPD_threadprivate: 8743 case OMPD_allocate: 8744 case OMPD_taskyield: 8745 case OMPD_barrier: 8746 case OMPD_taskwait: 8747 case OMPD_cancellation_point: 8748 case OMPD_flush: 8749 case OMPD_declare_reduction: 8750 case OMPD_declare_mapper: 8751 case OMPD_declare_simd: 8752 case OMPD_declare_target: 8753 case OMPD_end_declare_target: 8754 case OMPD_teams: 8755 case OMPD_simd: 8756 case OMPD_for: 8757 case OMPD_for_simd: 8758 case OMPD_sections: 8759 case OMPD_section: 8760 case OMPD_single: 8761 case OMPD_master: 8762 case OMPD_critical: 8763 case OMPD_taskgroup: 8764 case OMPD_distribute: 8765 case OMPD_ordered: 8766 case OMPD_atomic: 8767 case OMPD_distribute_simd: 8768 case OMPD_teams_distribute: 8769 case OMPD_teams_distribute_simd: 8770 case OMPD_requires: 8771 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 8772 case OMPD_unknown: 8773 llvm_unreachable("Unknown OpenMP directive"); 8774 } 8775 break; 8776 case OMPC_num_teams: 8777 switch (DKind) { 8778 case OMPD_target_teams: 8779 case OMPD_target_teams_distribute: 8780 case OMPD_target_teams_distribute_simd: 8781 case OMPD_target_teams_distribute_parallel_for: 8782 case OMPD_target_teams_distribute_parallel_for_simd: 8783 CaptureRegion = OMPD_target; 8784 break; 8785 case OMPD_teams_distribute_parallel_for: 8786 case OMPD_teams_distribute_parallel_for_simd: 8787 case OMPD_teams: 8788 case OMPD_teams_distribute: 8789 case OMPD_teams_distribute_simd: 8790 // Do not capture num_teams-clause expressions. 8791 break; 8792 case OMPD_distribute_parallel_for: 8793 case OMPD_distribute_parallel_for_simd: 8794 case OMPD_task: 8795 case OMPD_taskloop: 8796 case OMPD_taskloop_simd: 8797 case OMPD_target_data: 8798 case OMPD_target_enter_data: 8799 case OMPD_target_exit_data: 8800 case OMPD_target_update: 8801 case OMPD_cancel: 8802 case OMPD_parallel: 8803 case OMPD_parallel_sections: 8804 case OMPD_parallel_for: 8805 case OMPD_parallel_for_simd: 8806 case OMPD_target: 8807 case OMPD_target_simd: 8808 case OMPD_target_parallel: 8809 case OMPD_target_parallel_for: 8810 case OMPD_target_parallel_for_simd: 8811 case OMPD_threadprivate: 8812 case OMPD_allocate: 8813 case OMPD_taskyield: 8814 case OMPD_barrier: 8815 case OMPD_taskwait: 8816 case OMPD_cancellation_point: 8817 case OMPD_flush: 8818 case OMPD_declare_reduction: 8819 case OMPD_declare_mapper: 8820 case OMPD_declare_simd: 8821 case OMPD_declare_target: 8822 case OMPD_end_declare_target: 8823 case OMPD_simd: 8824 case OMPD_for: 8825 case OMPD_for_simd: 8826 case OMPD_sections: 8827 case OMPD_section: 8828 case OMPD_single: 8829 case OMPD_master: 8830 case OMPD_critical: 8831 case OMPD_taskgroup: 8832 case OMPD_distribute: 8833 case OMPD_ordered: 8834 case OMPD_atomic: 8835 case OMPD_distribute_simd: 8836 case OMPD_requires: 8837 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 8838 case OMPD_unknown: 8839 llvm_unreachable("Unknown OpenMP directive"); 8840 } 8841 break; 8842 case OMPC_thread_limit: 8843 switch (DKind) { 8844 case OMPD_target_teams: 8845 case OMPD_target_teams_distribute: 8846 case OMPD_target_teams_distribute_simd: 8847 case OMPD_target_teams_distribute_parallel_for: 8848 case OMPD_target_teams_distribute_parallel_for_simd: 8849 CaptureRegion = OMPD_target; 8850 break; 8851 case OMPD_teams_distribute_parallel_for: 8852 case OMPD_teams_distribute_parallel_for_simd: 8853 case OMPD_teams: 8854 case OMPD_teams_distribute: 8855 case OMPD_teams_distribute_simd: 8856 // Do not capture thread_limit-clause expressions. 8857 break; 8858 case OMPD_distribute_parallel_for: 8859 case OMPD_distribute_parallel_for_simd: 8860 case OMPD_task: 8861 case OMPD_taskloop: 8862 case OMPD_taskloop_simd: 8863 case OMPD_target_data: 8864 case OMPD_target_enter_data: 8865 case OMPD_target_exit_data: 8866 case OMPD_target_update: 8867 case OMPD_cancel: 8868 case OMPD_parallel: 8869 case OMPD_parallel_sections: 8870 case OMPD_parallel_for: 8871 case OMPD_parallel_for_simd: 8872 case OMPD_target: 8873 case OMPD_target_simd: 8874 case OMPD_target_parallel: 8875 case OMPD_target_parallel_for: 8876 case OMPD_target_parallel_for_simd: 8877 case OMPD_threadprivate: 8878 case OMPD_allocate: 8879 case OMPD_taskyield: 8880 case OMPD_barrier: 8881 case OMPD_taskwait: 8882 case OMPD_cancellation_point: 8883 case OMPD_flush: 8884 case OMPD_declare_reduction: 8885 case OMPD_declare_mapper: 8886 case OMPD_declare_simd: 8887 case OMPD_declare_target: 8888 case OMPD_end_declare_target: 8889 case OMPD_simd: 8890 case OMPD_for: 8891 case OMPD_for_simd: 8892 case OMPD_sections: 8893 case OMPD_section: 8894 case OMPD_single: 8895 case OMPD_master: 8896 case OMPD_critical: 8897 case OMPD_taskgroup: 8898 case OMPD_distribute: 8899 case OMPD_ordered: 8900 case OMPD_atomic: 8901 case OMPD_distribute_simd: 8902 case OMPD_requires: 8903 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 8904 case OMPD_unknown: 8905 llvm_unreachable("Unknown OpenMP directive"); 8906 } 8907 break; 8908 case OMPC_schedule: 8909 switch (DKind) { 8910 case OMPD_parallel_for: 8911 case OMPD_parallel_for_simd: 8912 case OMPD_distribute_parallel_for: 8913 case OMPD_distribute_parallel_for_simd: 8914 case OMPD_teams_distribute_parallel_for: 8915 case OMPD_teams_distribute_parallel_for_simd: 8916 case OMPD_target_parallel_for: 8917 case OMPD_target_parallel_for_simd: 8918 case OMPD_target_teams_distribute_parallel_for: 8919 case OMPD_target_teams_distribute_parallel_for_simd: 8920 CaptureRegion = OMPD_parallel; 8921 break; 8922 case OMPD_for: 8923 case OMPD_for_simd: 8924 // Do not capture schedule-clause expressions. 8925 break; 8926 case OMPD_task: 8927 case OMPD_taskloop: 8928 case OMPD_taskloop_simd: 8929 case OMPD_target_data: 8930 case OMPD_target_enter_data: 8931 case OMPD_target_exit_data: 8932 case OMPD_target_update: 8933 case OMPD_teams: 8934 case OMPD_teams_distribute: 8935 case OMPD_teams_distribute_simd: 8936 case OMPD_target_teams_distribute: 8937 case OMPD_target_teams_distribute_simd: 8938 case OMPD_target: 8939 case OMPD_target_simd: 8940 case OMPD_target_parallel: 8941 case OMPD_cancel: 8942 case OMPD_parallel: 8943 case OMPD_parallel_sections: 8944 case OMPD_threadprivate: 8945 case OMPD_allocate: 8946 case OMPD_taskyield: 8947 case OMPD_barrier: 8948 case OMPD_taskwait: 8949 case OMPD_cancellation_point: 8950 case OMPD_flush: 8951 case OMPD_declare_reduction: 8952 case OMPD_declare_mapper: 8953 case OMPD_declare_simd: 8954 case OMPD_declare_target: 8955 case OMPD_end_declare_target: 8956 case OMPD_simd: 8957 case OMPD_sections: 8958 case OMPD_section: 8959 case OMPD_single: 8960 case OMPD_master: 8961 case OMPD_critical: 8962 case OMPD_taskgroup: 8963 case OMPD_distribute: 8964 case OMPD_ordered: 8965 case OMPD_atomic: 8966 case OMPD_distribute_simd: 8967 case OMPD_target_teams: 8968 case OMPD_requires: 8969 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 8970 case OMPD_unknown: 8971 llvm_unreachable("Unknown OpenMP directive"); 8972 } 8973 break; 8974 case OMPC_dist_schedule: 8975 switch (DKind) { 8976 case OMPD_teams_distribute_parallel_for: 8977 case OMPD_teams_distribute_parallel_for_simd: 8978 case OMPD_teams_distribute: 8979 case OMPD_teams_distribute_simd: 8980 case OMPD_target_teams_distribute_parallel_for: 8981 case OMPD_target_teams_distribute_parallel_for_simd: 8982 case OMPD_target_teams_distribute: 8983 case OMPD_target_teams_distribute_simd: 8984 CaptureRegion = OMPD_teams; 8985 break; 8986 case OMPD_distribute_parallel_for: 8987 case OMPD_distribute_parallel_for_simd: 8988 case OMPD_distribute: 8989 case OMPD_distribute_simd: 8990 // Do not capture thread_limit-clause expressions. 8991 break; 8992 case OMPD_parallel_for: 8993 case OMPD_parallel_for_simd: 8994 case OMPD_target_parallel_for_simd: 8995 case OMPD_target_parallel_for: 8996 case OMPD_task: 8997 case OMPD_taskloop: 8998 case OMPD_taskloop_simd: 8999 case OMPD_target_data: 9000 case OMPD_target_enter_data: 9001 case OMPD_target_exit_data: 9002 case OMPD_target_update: 9003 case OMPD_teams: 9004 case OMPD_target: 9005 case OMPD_target_simd: 9006 case OMPD_target_parallel: 9007 case OMPD_cancel: 9008 case OMPD_parallel: 9009 case OMPD_parallel_sections: 9010 case OMPD_threadprivate: 9011 case OMPD_allocate: 9012 case OMPD_taskyield: 9013 case OMPD_barrier: 9014 case OMPD_taskwait: 9015 case OMPD_cancellation_point: 9016 case OMPD_flush: 9017 case OMPD_declare_reduction: 9018 case OMPD_declare_mapper: 9019 case OMPD_declare_simd: 9020 case OMPD_declare_target: 9021 case OMPD_end_declare_target: 9022 case OMPD_simd: 9023 case OMPD_for: 9024 case OMPD_for_simd: 9025 case OMPD_sections: 9026 case OMPD_section: 9027 case OMPD_single: 9028 case OMPD_master: 9029 case OMPD_critical: 9030 case OMPD_taskgroup: 9031 case OMPD_ordered: 9032 case OMPD_atomic: 9033 case OMPD_target_teams: 9034 case OMPD_requires: 9035 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 9036 case OMPD_unknown: 9037 llvm_unreachable("Unknown OpenMP directive"); 9038 } 9039 break; 9040 case OMPC_device: 9041 switch (DKind) { 9042 case OMPD_target_update: 9043 case OMPD_target_enter_data: 9044 case OMPD_target_exit_data: 9045 case OMPD_target: 9046 case OMPD_target_simd: 9047 case OMPD_target_teams: 9048 case OMPD_target_parallel: 9049 case OMPD_target_teams_distribute: 9050 case OMPD_target_teams_distribute_simd: 9051 case OMPD_target_parallel_for: 9052 case OMPD_target_parallel_for_simd: 9053 case OMPD_target_teams_distribute_parallel_for: 9054 case OMPD_target_teams_distribute_parallel_for_simd: 9055 CaptureRegion = OMPD_task; 9056 break; 9057 case OMPD_target_data: 9058 // Do not capture device-clause expressions. 9059 break; 9060 case OMPD_teams_distribute_parallel_for: 9061 case OMPD_teams_distribute_parallel_for_simd: 9062 case OMPD_teams: 9063 case OMPD_teams_distribute: 9064 case OMPD_teams_distribute_simd: 9065 case OMPD_distribute_parallel_for: 9066 case OMPD_distribute_parallel_for_simd: 9067 case OMPD_task: 9068 case OMPD_taskloop: 9069 case OMPD_taskloop_simd: 9070 case OMPD_cancel: 9071 case OMPD_parallel: 9072 case OMPD_parallel_sections: 9073 case OMPD_parallel_for: 9074 case OMPD_parallel_for_simd: 9075 case OMPD_threadprivate: 9076 case OMPD_allocate: 9077 case OMPD_taskyield: 9078 case OMPD_barrier: 9079 case OMPD_taskwait: 9080 case OMPD_cancellation_point: 9081 case OMPD_flush: 9082 case OMPD_declare_reduction: 9083 case OMPD_declare_mapper: 9084 case OMPD_declare_simd: 9085 case OMPD_declare_target: 9086 case OMPD_end_declare_target: 9087 case OMPD_simd: 9088 case OMPD_for: 9089 case OMPD_for_simd: 9090 case OMPD_sections: 9091 case OMPD_section: 9092 case OMPD_single: 9093 case OMPD_master: 9094 case OMPD_critical: 9095 case OMPD_taskgroup: 9096 case OMPD_distribute: 9097 case OMPD_ordered: 9098 case OMPD_atomic: 9099 case OMPD_distribute_simd: 9100 case OMPD_requires: 9101 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 9102 case OMPD_unknown: 9103 llvm_unreachable("Unknown OpenMP directive"); 9104 } 9105 break; 9106 case OMPC_firstprivate: 9107 case OMPC_lastprivate: 9108 case OMPC_reduction: 9109 case OMPC_task_reduction: 9110 case OMPC_in_reduction: 9111 case OMPC_linear: 9112 case OMPC_default: 9113 case OMPC_proc_bind: 9114 case OMPC_final: 9115 case OMPC_safelen: 9116 case OMPC_simdlen: 9117 case OMPC_allocator: 9118 case OMPC_collapse: 9119 case OMPC_private: 9120 case OMPC_shared: 9121 case OMPC_aligned: 9122 case OMPC_copyin: 9123 case OMPC_copyprivate: 9124 case OMPC_ordered: 9125 case OMPC_nowait: 9126 case OMPC_untied: 9127 case OMPC_mergeable: 9128 case OMPC_threadprivate: 9129 case OMPC_allocate: 9130 case OMPC_flush: 9131 case OMPC_read: 9132 case OMPC_write: 9133 case OMPC_update: 9134 case OMPC_capture: 9135 case OMPC_seq_cst: 9136 case OMPC_depend: 9137 case OMPC_threads: 9138 case OMPC_simd: 9139 case OMPC_map: 9140 case OMPC_priority: 9141 case OMPC_grainsize: 9142 case OMPC_nogroup: 9143 case OMPC_num_tasks: 9144 case OMPC_hint: 9145 case OMPC_defaultmap: 9146 case OMPC_unknown: 9147 case OMPC_uniform: 9148 case OMPC_to: 9149 case OMPC_from: 9150 case OMPC_use_device_ptr: 9151 case OMPC_is_device_ptr: 9152 case OMPC_unified_address: 9153 case OMPC_unified_shared_memory: 9154 case OMPC_reverse_offload: 9155 case OMPC_dynamic_allocators: 9156 case OMPC_atomic_default_mem_order: 9157 llvm_unreachable("Unexpected OpenMP clause."); 9158 } 9159 return CaptureRegion; 9160 } 9161 9162 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 9163 Expr *Condition, SourceLocation StartLoc, 9164 SourceLocation LParenLoc, 9165 SourceLocation NameModifierLoc, 9166 SourceLocation ColonLoc, 9167 SourceLocation EndLoc) { 9168 Expr *ValExpr = Condition; 9169 Stmt *HelperValStmt = nullptr; 9170 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 9171 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9172 !Condition->isInstantiationDependent() && 9173 !Condition->containsUnexpandedParameterPack()) { 9174 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9175 if (Val.isInvalid()) 9176 return nullptr; 9177 9178 ValExpr = Val.get(); 9179 9180 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9181 CaptureRegion = 9182 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 9183 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9184 ValExpr = MakeFullExpr(ValExpr).get(); 9185 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9186 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9187 HelperValStmt = buildPreInits(Context, Captures); 9188 } 9189 } 9190 9191 return new (Context) 9192 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 9193 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 9194 } 9195 9196 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 9197 SourceLocation StartLoc, 9198 SourceLocation LParenLoc, 9199 SourceLocation EndLoc) { 9200 Expr *ValExpr = Condition; 9201 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 9202 !Condition->isInstantiationDependent() && 9203 !Condition->containsUnexpandedParameterPack()) { 9204 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 9205 if (Val.isInvalid()) 9206 return nullptr; 9207 9208 ValExpr = MakeFullExpr(Val.get()).get(); 9209 } 9210 9211 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 9212 } 9213 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 9214 Expr *Op) { 9215 if (!Op) 9216 return ExprError(); 9217 9218 class IntConvertDiagnoser : public ICEConvertDiagnoser { 9219 public: 9220 IntConvertDiagnoser() 9221 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 9222 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 9223 QualType T) override { 9224 return S.Diag(Loc, diag::err_omp_not_integral) << T; 9225 } 9226 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 9227 QualType T) override { 9228 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 9229 } 9230 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 9231 QualType T, 9232 QualType ConvTy) override { 9233 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 9234 } 9235 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 9236 QualType ConvTy) override { 9237 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9238 << ConvTy->isEnumeralType() << ConvTy; 9239 } 9240 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 9241 QualType T) override { 9242 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 9243 } 9244 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 9245 QualType ConvTy) override { 9246 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 9247 << ConvTy->isEnumeralType() << ConvTy; 9248 } 9249 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 9250 QualType) override { 9251 llvm_unreachable("conversion functions are permitted"); 9252 } 9253 } ConvertDiagnoser; 9254 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 9255 } 9256 9257 static bool isNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 9258 OpenMPClauseKind CKind, 9259 bool StrictlyPositive) { 9260 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 9261 !ValExpr->isInstantiationDependent()) { 9262 SourceLocation Loc = ValExpr->getExprLoc(); 9263 ExprResult Value = 9264 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 9265 if (Value.isInvalid()) 9266 return false; 9267 9268 ValExpr = Value.get(); 9269 // The expression must evaluate to a non-negative integer value. 9270 llvm::APSInt Result; 9271 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 9272 Result.isSigned() && 9273 !((!StrictlyPositive && Result.isNonNegative()) || 9274 (StrictlyPositive && Result.isStrictlyPositive()))) { 9275 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 9276 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9277 << ValExpr->getSourceRange(); 9278 return false; 9279 } 9280 } 9281 return true; 9282 } 9283 9284 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 9285 SourceLocation StartLoc, 9286 SourceLocation LParenLoc, 9287 SourceLocation EndLoc) { 9288 Expr *ValExpr = NumThreads; 9289 Stmt *HelperValStmt = nullptr; 9290 9291 // OpenMP [2.5, Restrictions] 9292 // The num_threads expression must evaluate to a positive integer value. 9293 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 9294 /*StrictlyPositive=*/true)) 9295 return nullptr; 9296 9297 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9298 OpenMPDirectiveKind CaptureRegion = 9299 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 9300 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 9301 ValExpr = MakeFullExpr(ValExpr).get(); 9302 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9303 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9304 HelperValStmt = buildPreInits(Context, Captures); 9305 } 9306 9307 return new (Context) OMPNumThreadsClause( 9308 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 9309 } 9310 9311 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 9312 OpenMPClauseKind CKind, 9313 bool StrictlyPositive) { 9314 if (!E) 9315 return ExprError(); 9316 if (E->isValueDependent() || E->isTypeDependent() || 9317 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 9318 return E; 9319 llvm::APSInt Result; 9320 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 9321 if (ICE.isInvalid()) 9322 return ExprError(); 9323 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 9324 (!StrictlyPositive && !Result.isNonNegative())) { 9325 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 9326 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 9327 << E->getSourceRange(); 9328 return ExprError(); 9329 } 9330 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 9331 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 9332 << E->getSourceRange(); 9333 return ExprError(); 9334 } 9335 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 9336 DSAStack->setAssociatedLoops(Result.getExtValue()); 9337 else if (CKind == OMPC_ordered) 9338 DSAStack->setAssociatedLoops(Result.getExtValue()); 9339 return ICE; 9340 } 9341 9342 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 9343 SourceLocation LParenLoc, 9344 SourceLocation EndLoc) { 9345 // OpenMP [2.8.1, simd construct, Description] 9346 // The parameter of the safelen clause must be a constant 9347 // positive integer expression. 9348 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 9349 if (Safelen.isInvalid()) 9350 return nullptr; 9351 return new (Context) 9352 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 9353 } 9354 9355 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 9356 SourceLocation LParenLoc, 9357 SourceLocation EndLoc) { 9358 // OpenMP [2.8.1, simd construct, Description] 9359 // The parameter of the simdlen clause must be a constant 9360 // positive integer expression. 9361 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 9362 if (Simdlen.isInvalid()) 9363 return nullptr; 9364 return new (Context) 9365 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 9366 } 9367 9368 /// Tries to find omp_allocator_handle_t type. 9369 static bool FindOMPAllocatorHandleT(Sema &S, SourceLocation Loc, 9370 QualType &OMPAllocatorHandleT) { 9371 if (!OMPAllocatorHandleT.isNull()) 9372 return true; 9373 DeclarationName OMPAllocatorHandleTName = 9374 &S.getASTContext().Idents.get("omp_allocator_handle_t"); 9375 auto *TD = dyn_cast_or_null<TypeDecl>(S.LookupSingleName( 9376 S.TUScope, OMPAllocatorHandleTName, Loc, Sema::LookupAnyName)); 9377 if (!TD) { 9378 S.Diag(Loc, diag::err_implied_omp_allocator_handle_t_not_found); 9379 return false; 9380 } 9381 OMPAllocatorHandleT = S.getASTContext().getTypeDeclType(TD); 9382 return true; 9383 } 9384 9385 OMPClause *Sema::ActOnOpenMPAllocatorClause(Expr *A, SourceLocation StartLoc, 9386 SourceLocation LParenLoc, 9387 SourceLocation EndLoc) { 9388 // OpenMP [2.11.3, allocate Directive, Description] 9389 // allocator is an expression of omp_allocator_handle_t type. 9390 if (!FindOMPAllocatorHandleT(*this, A->getExprLoc(), OMPAllocatorHandleT)) 9391 return nullptr; 9392 9393 ExprResult Allocator = DefaultLvalueConversion(A); 9394 if (Allocator.isInvalid()) 9395 return nullptr; 9396 Allocator = PerformImplicitConversion(Allocator.get(), OMPAllocatorHandleT, 9397 Sema::AA_Initializing, 9398 /*AllowExplicit=*/true); 9399 if (Allocator.isInvalid()) 9400 return nullptr; 9401 return new (Context) 9402 OMPAllocatorClause(Allocator.get(), StartLoc, LParenLoc, EndLoc); 9403 } 9404 9405 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 9406 SourceLocation StartLoc, 9407 SourceLocation LParenLoc, 9408 SourceLocation EndLoc) { 9409 // OpenMP [2.7.1, loop construct, Description] 9410 // OpenMP [2.8.1, simd construct, Description] 9411 // OpenMP [2.9.6, distribute construct, Description] 9412 // The parameter of the collapse clause must be a constant 9413 // positive integer expression. 9414 ExprResult NumForLoopsResult = 9415 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 9416 if (NumForLoopsResult.isInvalid()) 9417 return nullptr; 9418 return new (Context) 9419 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 9420 } 9421 9422 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 9423 SourceLocation EndLoc, 9424 SourceLocation LParenLoc, 9425 Expr *NumForLoops) { 9426 // OpenMP [2.7.1, loop construct, Description] 9427 // OpenMP [2.8.1, simd construct, Description] 9428 // OpenMP [2.9.6, distribute construct, Description] 9429 // The parameter of the ordered clause must be a constant 9430 // positive integer expression if any. 9431 if (NumForLoops && LParenLoc.isValid()) { 9432 ExprResult NumForLoopsResult = 9433 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 9434 if (NumForLoopsResult.isInvalid()) 9435 return nullptr; 9436 NumForLoops = NumForLoopsResult.get(); 9437 } else { 9438 NumForLoops = nullptr; 9439 } 9440 auto *Clause = OMPOrderedClause::Create( 9441 Context, NumForLoops, NumForLoops ? DSAStack->getAssociatedLoops() : 0, 9442 StartLoc, LParenLoc, EndLoc); 9443 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops, Clause); 9444 return Clause; 9445 } 9446 9447 OMPClause *Sema::ActOnOpenMPSimpleClause( 9448 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 9449 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 9450 OMPClause *Res = nullptr; 9451 switch (Kind) { 9452 case OMPC_default: 9453 Res = 9454 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 9455 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 9456 break; 9457 case OMPC_proc_bind: 9458 Res = ActOnOpenMPProcBindClause( 9459 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 9460 LParenLoc, EndLoc); 9461 break; 9462 case OMPC_atomic_default_mem_order: 9463 Res = ActOnOpenMPAtomicDefaultMemOrderClause( 9464 static_cast<OpenMPAtomicDefaultMemOrderClauseKind>(Argument), 9465 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 9466 break; 9467 case OMPC_if: 9468 case OMPC_final: 9469 case OMPC_num_threads: 9470 case OMPC_safelen: 9471 case OMPC_simdlen: 9472 case OMPC_allocator: 9473 case OMPC_collapse: 9474 case OMPC_schedule: 9475 case OMPC_private: 9476 case OMPC_firstprivate: 9477 case OMPC_lastprivate: 9478 case OMPC_shared: 9479 case OMPC_reduction: 9480 case OMPC_task_reduction: 9481 case OMPC_in_reduction: 9482 case OMPC_linear: 9483 case OMPC_aligned: 9484 case OMPC_copyin: 9485 case OMPC_copyprivate: 9486 case OMPC_ordered: 9487 case OMPC_nowait: 9488 case OMPC_untied: 9489 case OMPC_mergeable: 9490 case OMPC_threadprivate: 9491 case OMPC_allocate: 9492 case OMPC_flush: 9493 case OMPC_read: 9494 case OMPC_write: 9495 case OMPC_update: 9496 case OMPC_capture: 9497 case OMPC_seq_cst: 9498 case OMPC_depend: 9499 case OMPC_device: 9500 case OMPC_threads: 9501 case OMPC_simd: 9502 case OMPC_map: 9503 case OMPC_num_teams: 9504 case OMPC_thread_limit: 9505 case OMPC_priority: 9506 case OMPC_grainsize: 9507 case OMPC_nogroup: 9508 case OMPC_num_tasks: 9509 case OMPC_hint: 9510 case OMPC_dist_schedule: 9511 case OMPC_defaultmap: 9512 case OMPC_unknown: 9513 case OMPC_uniform: 9514 case OMPC_to: 9515 case OMPC_from: 9516 case OMPC_use_device_ptr: 9517 case OMPC_is_device_ptr: 9518 case OMPC_unified_address: 9519 case OMPC_unified_shared_memory: 9520 case OMPC_reverse_offload: 9521 case OMPC_dynamic_allocators: 9522 llvm_unreachable("Clause is not allowed."); 9523 } 9524 return Res; 9525 } 9526 9527 static std::string 9528 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 9529 ArrayRef<unsigned> Exclude = llvm::None) { 9530 SmallString<256> Buffer; 9531 llvm::raw_svector_ostream Out(Buffer); 9532 unsigned Bound = Last >= 2 ? Last - 2 : 0; 9533 unsigned Skipped = Exclude.size(); 9534 auto S = Exclude.begin(), E = Exclude.end(); 9535 for (unsigned I = First; I < Last; ++I) { 9536 if (std::find(S, E, I) != E) { 9537 --Skipped; 9538 continue; 9539 } 9540 Out << "'" << getOpenMPSimpleClauseTypeName(K, I) << "'"; 9541 if (I == Bound - Skipped) 9542 Out << " or "; 9543 else if (I != Bound + 1 - Skipped) 9544 Out << ", "; 9545 } 9546 return Out.str(); 9547 } 9548 9549 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 9550 SourceLocation KindKwLoc, 9551 SourceLocation StartLoc, 9552 SourceLocation LParenLoc, 9553 SourceLocation EndLoc) { 9554 if (Kind == OMPC_DEFAULT_unknown) { 9555 static_assert(OMPC_DEFAULT_unknown > 0, 9556 "OMPC_DEFAULT_unknown not greater than 0"); 9557 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9558 << getListOfPossibleValues(OMPC_default, /*First=*/0, 9559 /*Last=*/OMPC_DEFAULT_unknown) 9560 << getOpenMPClauseName(OMPC_default); 9561 return nullptr; 9562 } 9563 switch (Kind) { 9564 case OMPC_DEFAULT_none: 9565 DSAStack->setDefaultDSANone(KindKwLoc); 9566 break; 9567 case OMPC_DEFAULT_shared: 9568 DSAStack->setDefaultDSAShared(KindKwLoc); 9569 break; 9570 case OMPC_DEFAULT_unknown: 9571 llvm_unreachable("Clause kind is not allowed."); 9572 break; 9573 } 9574 return new (Context) 9575 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 9576 } 9577 9578 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 9579 SourceLocation KindKwLoc, 9580 SourceLocation StartLoc, 9581 SourceLocation LParenLoc, 9582 SourceLocation EndLoc) { 9583 if (Kind == OMPC_PROC_BIND_unknown) { 9584 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9585 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 9586 /*Last=*/OMPC_PROC_BIND_unknown) 9587 << getOpenMPClauseName(OMPC_proc_bind); 9588 return nullptr; 9589 } 9590 return new (Context) 9591 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 9592 } 9593 9594 OMPClause *Sema::ActOnOpenMPAtomicDefaultMemOrderClause( 9595 OpenMPAtomicDefaultMemOrderClauseKind Kind, SourceLocation KindKwLoc, 9596 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 9597 if (Kind == OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) { 9598 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 9599 << getListOfPossibleValues( 9600 OMPC_atomic_default_mem_order, /*First=*/0, 9601 /*Last=*/OMPC_ATOMIC_DEFAULT_MEM_ORDER_unknown) 9602 << getOpenMPClauseName(OMPC_atomic_default_mem_order); 9603 return nullptr; 9604 } 9605 return new (Context) OMPAtomicDefaultMemOrderClause(Kind, KindKwLoc, StartLoc, 9606 LParenLoc, EndLoc); 9607 } 9608 9609 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 9610 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 9611 SourceLocation StartLoc, SourceLocation LParenLoc, 9612 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 9613 SourceLocation EndLoc) { 9614 OMPClause *Res = nullptr; 9615 switch (Kind) { 9616 case OMPC_schedule: 9617 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 9618 assert(Argument.size() == NumberOfElements && 9619 ArgumentLoc.size() == NumberOfElements); 9620 Res = ActOnOpenMPScheduleClause( 9621 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 9622 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 9623 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 9624 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 9625 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 9626 break; 9627 case OMPC_if: 9628 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 9629 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 9630 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 9631 DelimLoc, EndLoc); 9632 break; 9633 case OMPC_dist_schedule: 9634 Res = ActOnOpenMPDistScheduleClause( 9635 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 9636 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 9637 break; 9638 case OMPC_defaultmap: 9639 enum { Modifier, DefaultmapKind }; 9640 Res = ActOnOpenMPDefaultmapClause( 9641 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 9642 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 9643 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 9644 EndLoc); 9645 break; 9646 case OMPC_final: 9647 case OMPC_num_threads: 9648 case OMPC_safelen: 9649 case OMPC_simdlen: 9650 case OMPC_allocator: 9651 case OMPC_collapse: 9652 case OMPC_default: 9653 case OMPC_proc_bind: 9654 case OMPC_private: 9655 case OMPC_firstprivate: 9656 case OMPC_lastprivate: 9657 case OMPC_shared: 9658 case OMPC_reduction: 9659 case OMPC_task_reduction: 9660 case OMPC_in_reduction: 9661 case OMPC_linear: 9662 case OMPC_aligned: 9663 case OMPC_copyin: 9664 case OMPC_copyprivate: 9665 case OMPC_ordered: 9666 case OMPC_nowait: 9667 case OMPC_untied: 9668 case OMPC_mergeable: 9669 case OMPC_threadprivate: 9670 case OMPC_allocate: 9671 case OMPC_flush: 9672 case OMPC_read: 9673 case OMPC_write: 9674 case OMPC_update: 9675 case OMPC_capture: 9676 case OMPC_seq_cst: 9677 case OMPC_depend: 9678 case OMPC_device: 9679 case OMPC_threads: 9680 case OMPC_simd: 9681 case OMPC_map: 9682 case OMPC_num_teams: 9683 case OMPC_thread_limit: 9684 case OMPC_priority: 9685 case OMPC_grainsize: 9686 case OMPC_nogroup: 9687 case OMPC_num_tasks: 9688 case OMPC_hint: 9689 case OMPC_unknown: 9690 case OMPC_uniform: 9691 case OMPC_to: 9692 case OMPC_from: 9693 case OMPC_use_device_ptr: 9694 case OMPC_is_device_ptr: 9695 case OMPC_unified_address: 9696 case OMPC_unified_shared_memory: 9697 case OMPC_reverse_offload: 9698 case OMPC_dynamic_allocators: 9699 case OMPC_atomic_default_mem_order: 9700 llvm_unreachable("Clause is not allowed."); 9701 } 9702 return Res; 9703 } 9704 9705 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 9706 OpenMPScheduleClauseModifier M2, 9707 SourceLocation M1Loc, SourceLocation M2Loc) { 9708 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 9709 SmallVector<unsigned, 2> Excluded; 9710 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 9711 Excluded.push_back(M2); 9712 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 9713 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 9714 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 9715 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 9716 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 9717 << getListOfPossibleValues(OMPC_schedule, 9718 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 9719 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 9720 Excluded) 9721 << getOpenMPClauseName(OMPC_schedule); 9722 return true; 9723 } 9724 return false; 9725 } 9726 9727 OMPClause *Sema::ActOnOpenMPScheduleClause( 9728 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 9729 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 9730 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 9731 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 9732 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 9733 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 9734 return nullptr; 9735 // OpenMP, 2.7.1, Loop Construct, Restrictions 9736 // Either the monotonic modifier or the nonmonotonic modifier can be specified 9737 // but not both. 9738 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 9739 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 9740 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 9741 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 9742 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 9743 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 9744 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 9745 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 9746 return nullptr; 9747 } 9748 if (Kind == OMPC_SCHEDULE_unknown) { 9749 std::string Values; 9750 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 9751 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 9752 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 9753 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 9754 Exclude); 9755 } else { 9756 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 9757 /*Last=*/OMPC_SCHEDULE_unknown); 9758 } 9759 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 9760 << Values << getOpenMPClauseName(OMPC_schedule); 9761 return nullptr; 9762 } 9763 // OpenMP, 2.7.1, Loop Construct, Restrictions 9764 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 9765 // schedule(guided). 9766 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 9767 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 9768 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 9769 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 9770 diag::err_omp_schedule_nonmonotonic_static); 9771 return nullptr; 9772 } 9773 Expr *ValExpr = ChunkSize; 9774 Stmt *HelperValStmt = nullptr; 9775 if (ChunkSize) { 9776 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 9777 !ChunkSize->isInstantiationDependent() && 9778 !ChunkSize->containsUnexpandedParameterPack()) { 9779 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 9780 ExprResult Val = 9781 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 9782 if (Val.isInvalid()) 9783 return nullptr; 9784 9785 ValExpr = Val.get(); 9786 9787 // OpenMP [2.7.1, Restrictions] 9788 // chunk_size must be a loop invariant integer expression with a positive 9789 // value. 9790 llvm::APSInt Result; 9791 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 9792 if (Result.isSigned() && !Result.isStrictlyPositive()) { 9793 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 9794 << "schedule" << 1 << ChunkSize->getSourceRange(); 9795 return nullptr; 9796 } 9797 } else if (getOpenMPCaptureRegionForClause( 9798 DSAStack->getCurrentDirective(), OMPC_schedule) != 9799 OMPD_unknown && 9800 !CurContext->isDependentContext()) { 9801 ValExpr = MakeFullExpr(ValExpr).get(); 9802 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 9803 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 9804 HelperValStmt = buildPreInits(Context, Captures); 9805 } 9806 } 9807 } 9808 9809 return new (Context) 9810 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 9811 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 9812 } 9813 9814 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 9815 SourceLocation StartLoc, 9816 SourceLocation EndLoc) { 9817 OMPClause *Res = nullptr; 9818 switch (Kind) { 9819 case OMPC_ordered: 9820 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 9821 break; 9822 case OMPC_nowait: 9823 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 9824 break; 9825 case OMPC_untied: 9826 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 9827 break; 9828 case OMPC_mergeable: 9829 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 9830 break; 9831 case OMPC_read: 9832 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 9833 break; 9834 case OMPC_write: 9835 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 9836 break; 9837 case OMPC_update: 9838 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 9839 break; 9840 case OMPC_capture: 9841 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 9842 break; 9843 case OMPC_seq_cst: 9844 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 9845 break; 9846 case OMPC_threads: 9847 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 9848 break; 9849 case OMPC_simd: 9850 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 9851 break; 9852 case OMPC_nogroup: 9853 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 9854 break; 9855 case OMPC_unified_address: 9856 Res = ActOnOpenMPUnifiedAddressClause(StartLoc, EndLoc); 9857 break; 9858 case OMPC_unified_shared_memory: 9859 Res = ActOnOpenMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 9860 break; 9861 case OMPC_reverse_offload: 9862 Res = ActOnOpenMPReverseOffloadClause(StartLoc, EndLoc); 9863 break; 9864 case OMPC_dynamic_allocators: 9865 Res = ActOnOpenMPDynamicAllocatorsClause(StartLoc, EndLoc); 9866 break; 9867 case OMPC_if: 9868 case OMPC_final: 9869 case OMPC_num_threads: 9870 case OMPC_safelen: 9871 case OMPC_simdlen: 9872 case OMPC_allocator: 9873 case OMPC_collapse: 9874 case OMPC_schedule: 9875 case OMPC_private: 9876 case OMPC_firstprivate: 9877 case OMPC_lastprivate: 9878 case OMPC_shared: 9879 case OMPC_reduction: 9880 case OMPC_task_reduction: 9881 case OMPC_in_reduction: 9882 case OMPC_linear: 9883 case OMPC_aligned: 9884 case OMPC_copyin: 9885 case OMPC_copyprivate: 9886 case OMPC_default: 9887 case OMPC_proc_bind: 9888 case OMPC_threadprivate: 9889 case OMPC_allocate: 9890 case OMPC_flush: 9891 case OMPC_depend: 9892 case OMPC_device: 9893 case OMPC_map: 9894 case OMPC_num_teams: 9895 case OMPC_thread_limit: 9896 case OMPC_priority: 9897 case OMPC_grainsize: 9898 case OMPC_num_tasks: 9899 case OMPC_hint: 9900 case OMPC_dist_schedule: 9901 case OMPC_defaultmap: 9902 case OMPC_unknown: 9903 case OMPC_uniform: 9904 case OMPC_to: 9905 case OMPC_from: 9906 case OMPC_use_device_ptr: 9907 case OMPC_is_device_ptr: 9908 case OMPC_atomic_default_mem_order: 9909 llvm_unreachable("Clause is not allowed."); 9910 } 9911 return Res; 9912 } 9913 9914 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 9915 SourceLocation EndLoc) { 9916 DSAStack->setNowaitRegion(); 9917 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 9918 } 9919 9920 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 9921 SourceLocation EndLoc) { 9922 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 9923 } 9924 9925 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 9926 SourceLocation EndLoc) { 9927 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 9928 } 9929 9930 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 9931 SourceLocation EndLoc) { 9932 return new (Context) OMPReadClause(StartLoc, EndLoc); 9933 } 9934 9935 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 9936 SourceLocation EndLoc) { 9937 return new (Context) OMPWriteClause(StartLoc, EndLoc); 9938 } 9939 9940 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 9941 SourceLocation EndLoc) { 9942 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 9943 } 9944 9945 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 9946 SourceLocation EndLoc) { 9947 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 9948 } 9949 9950 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 9951 SourceLocation EndLoc) { 9952 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 9953 } 9954 9955 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 9956 SourceLocation EndLoc) { 9957 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 9958 } 9959 9960 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 9961 SourceLocation EndLoc) { 9962 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 9963 } 9964 9965 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 9966 SourceLocation EndLoc) { 9967 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 9968 } 9969 9970 OMPClause *Sema::ActOnOpenMPUnifiedAddressClause(SourceLocation StartLoc, 9971 SourceLocation EndLoc) { 9972 return new (Context) OMPUnifiedAddressClause(StartLoc, EndLoc); 9973 } 9974 9975 OMPClause *Sema::ActOnOpenMPUnifiedSharedMemoryClause(SourceLocation StartLoc, 9976 SourceLocation EndLoc) { 9977 return new (Context) OMPUnifiedSharedMemoryClause(StartLoc, EndLoc); 9978 } 9979 9980 OMPClause *Sema::ActOnOpenMPReverseOffloadClause(SourceLocation StartLoc, 9981 SourceLocation EndLoc) { 9982 return new (Context) OMPReverseOffloadClause(StartLoc, EndLoc); 9983 } 9984 9985 OMPClause *Sema::ActOnOpenMPDynamicAllocatorsClause(SourceLocation StartLoc, 9986 SourceLocation EndLoc) { 9987 return new (Context) OMPDynamicAllocatorsClause(StartLoc, EndLoc); 9988 } 9989 9990 OMPClause *Sema::ActOnOpenMPVarListClause( 9991 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 9992 const OMPVarListLocTy &Locs, SourceLocation ColonLoc, 9993 CXXScopeSpec &ReductionOrMapperIdScopeSpec, 9994 DeclarationNameInfo &ReductionOrMapperId, OpenMPDependClauseKind DepKind, 9995 OpenMPLinearClauseKind LinKind, 9996 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 9997 ArrayRef<SourceLocation> MapTypeModifiersLoc, OpenMPMapClauseKind MapType, 9998 bool IsMapTypeImplicit, SourceLocation DepLinMapLoc) { 9999 SourceLocation StartLoc = Locs.StartLoc; 10000 SourceLocation LParenLoc = Locs.LParenLoc; 10001 SourceLocation EndLoc = Locs.EndLoc; 10002 OMPClause *Res = nullptr; 10003 switch (Kind) { 10004 case OMPC_private: 10005 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10006 break; 10007 case OMPC_firstprivate: 10008 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10009 break; 10010 case OMPC_lastprivate: 10011 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10012 break; 10013 case OMPC_shared: 10014 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 10015 break; 10016 case OMPC_reduction: 10017 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10018 EndLoc, ReductionOrMapperIdScopeSpec, 10019 ReductionOrMapperId); 10020 break; 10021 case OMPC_task_reduction: 10022 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10023 EndLoc, ReductionOrMapperIdScopeSpec, 10024 ReductionOrMapperId); 10025 break; 10026 case OMPC_in_reduction: 10027 Res = ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 10028 EndLoc, ReductionOrMapperIdScopeSpec, 10029 ReductionOrMapperId); 10030 break; 10031 case OMPC_linear: 10032 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 10033 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 10034 break; 10035 case OMPC_aligned: 10036 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 10037 ColonLoc, EndLoc); 10038 break; 10039 case OMPC_copyin: 10040 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 10041 break; 10042 case OMPC_copyprivate: 10043 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 10044 break; 10045 case OMPC_flush: 10046 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 10047 break; 10048 case OMPC_depend: 10049 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 10050 StartLoc, LParenLoc, EndLoc); 10051 break; 10052 case OMPC_map: 10053 Res = ActOnOpenMPMapClause(MapTypeModifiers, MapTypeModifiersLoc, 10054 ReductionOrMapperIdScopeSpec, 10055 ReductionOrMapperId, MapType, IsMapTypeImplicit, 10056 DepLinMapLoc, ColonLoc, VarList, Locs); 10057 break; 10058 case OMPC_to: 10059 Res = ActOnOpenMPToClause(VarList, ReductionOrMapperIdScopeSpec, 10060 ReductionOrMapperId, Locs); 10061 break; 10062 case OMPC_from: 10063 Res = ActOnOpenMPFromClause(VarList, ReductionOrMapperIdScopeSpec, 10064 ReductionOrMapperId, Locs); 10065 break; 10066 case OMPC_use_device_ptr: 10067 Res = ActOnOpenMPUseDevicePtrClause(VarList, Locs); 10068 break; 10069 case OMPC_is_device_ptr: 10070 Res = ActOnOpenMPIsDevicePtrClause(VarList, Locs); 10071 break; 10072 case OMPC_if: 10073 case OMPC_final: 10074 case OMPC_num_threads: 10075 case OMPC_safelen: 10076 case OMPC_simdlen: 10077 case OMPC_allocator: 10078 case OMPC_collapse: 10079 case OMPC_default: 10080 case OMPC_proc_bind: 10081 case OMPC_schedule: 10082 case OMPC_ordered: 10083 case OMPC_nowait: 10084 case OMPC_untied: 10085 case OMPC_mergeable: 10086 case OMPC_threadprivate: 10087 case OMPC_allocate: 10088 case OMPC_read: 10089 case OMPC_write: 10090 case OMPC_update: 10091 case OMPC_capture: 10092 case OMPC_seq_cst: 10093 case OMPC_device: 10094 case OMPC_threads: 10095 case OMPC_simd: 10096 case OMPC_num_teams: 10097 case OMPC_thread_limit: 10098 case OMPC_priority: 10099 case OMPC_grainsize: 10100 case OMPC_nogroup: 10101 case OMPC_num_tasks: 10102 case OMPC_hint: 10103 case OMPC_dist_schedule: 10104 case OMPC_defaultmap: 10105 case OMPC_unknown: 10106 case OMPC_uniform: 10107 case OMPC_unified_address: 10108 case OMPC_unified_shared_memory: 10109 case OMPC_reverse_offload: 10110 case OMPC_dynamic_allocators: 10111 case OMPC_atomic_default_mem_order: 10112 llvm_unreachable("Clause is not allowed."); 10113 } 10114 return Res; 10115 } 10116 10117 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 10118 ExprObjectKind OK, SourceLocation Loc) { 10119 ExprResult Res = BuildDeclRefExpr( 10120 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 10121 if (!Res.isUsable()) 10122 return ExprError(); 10123 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 10124 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 10125 if (!Res.isUsable()) 10126 return ExprError(); 10127 } 10128 if (VK != VK_LValue && Res.get()->isGLValue()) { 10129 Res = DefaultLvalueConversion(Res.get()); 10130 if (!Res.isUsable()) 10131 return ExprError(); 10132 } 10133 return Res; 10134 } 10135 10136 static std::pair<ValueDecl *, bool> 10137 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 10138 SourceRange &ERange, bool AllowArraySection = false) { 10139 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 10140 RefExpr->containsUnexpandedParameterPack()) 10141 return std::make_pair(nullptr, true); 10142 10143 // OpenMP [3.1, C/C++] 10144 // A list item is a variable name. 10145 // OpenMP [2.9.3.3, Restrictions, p.1] 10146 // A variable that is part of another variable (as an array or 10147 // structure element) cannot appear in a private clause. 10148 RefExpr = RefExpr->IgnoreParens(); 10149 enum { 10150 NoArrayExpr = -1, 10151 ArraySubscript = 0, 10152 OMPArraySection = 1 10153 } IsArrayExpr = NoArrayExpr; 10154 if (AllowArraySection) { 10155 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 10156 Expr *Base = ASE->getBase()->IgnoreParenImpCasts(); 10157 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 10158 Base = TempASE->getBase()->IgnoreParenImpCasts(); 10159 RefExpr = Base; 10160 IsArrayExpr = ArraySubscript; 10161 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 10162 Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 10163 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 10164 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 10165 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 10166 Base = TempASE->getBase()->IgnoreParenImpCasts(); 10167 RefExpr = Base; 10168 IsArrayExpr = OMPArraySection; 10169 } 10170 } 10171 ELoc = RefExpr->getExprLoc(); 10172 ERange = RefExpr->getSourceRange(); 10173 RefExpr = RefExpr->IgnoreParenImpCasts(); 10174 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 10175 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 10176 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 10177 (S.getCurrentThisType().isNull() || !ME || 10178 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 10179 !isa<FieldDecl>(ME->getMemberDecl()))) { 10180 if (IsArrayExpr != NoArrayExpr) { 10181 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 10182 << ERange; 10183 } else { 10184 S.Diag(ELoc, 10185 AllowArraySection 10186 ? diag::err_omp_expected_var_name_member_expr_or_array_item 10187 : diag::err_omp_expected_var_name_member_expr) 10188 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 10189 } 10190 return std::make_pair(nullptr, false); 10191 } 10192 return std::make_pair( 10193 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 10194 } 10195 10196 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 10197 SourceLocation StartLoc, 10198 SourceLocation LParenLoc, 10199 SourceLocation EndLoc) { 10200 SmallVector<Expr *, 8> Vars; 10201 SmallVector<Expr *, 8> PrivateCopies; 10202 for (Expr *RefExpr : VarList) { 10203 assert(RefExpr && "NULL expr in OpenMP private clause."); 10204 SourceLocation ELoc; 10205 SourceRange ERange; 10206 Expr *SimpleRefExpr = RefExpr; 10207 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10208 if (Res.second) { 10209 // It will be analyzed later. 10210 Vars.push_back(RefExpr); 10211 PrivateCopies.push_back(nullptr); 10212 } 10213 ValueDecl *D = Res.first; 10214 if (!D) 10215 continue; 10216 10217 QualType Type = D->getType(); 10218 auto *VD = dyn_cast<VarDecl>(D); 10219 10220 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10221 // A variable that appears in a private clause must not have an incomplete 10222 // type or a reference type. 10223 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 10224 continue; 10225 Type = Type.getNonReferenceType(); 10226 10227 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 10228 // A variable that is privatized must not have a const-qualified type 10229 // unless it is of class type with a mutable member. This restriction does 10230 // not apply to the firstprivate clause. 10231 // 10232 // OpenMP 3.1 [2.9.3.3, private clause, Restrictions] 10233 // A variable that appears in a private clause must not have a 10234 // const-qualified type unless it is of class type with a mutable member. 10235 if (rejectConstNotMutableType(*this, D, Type, OMPC_private, ELoc)) 10236 continue; 10237 10238 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10239 // in a Construct] 10240 // Variables with the predetermined data-sharing attributes may not be 10241 // listed in data-sharing attributes clauses, except for the cases 10242 // listed below. For these exceptions only, listing a predetermined 10243 // variable in a data-sharing attribute clause is allowed and overrides 10244 // the variable's predetermined data-sharing attributes. 10245 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10246 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 10247 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10248 << getOpenMPClauseName(OMPC_private); 10249 reportOriginalDsa(*this, DSAStack, D, DVar); 10250 continue; 10251 } 10252 10253 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10254 // Variably modified types are not supported for tasks. 10255 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10256 isOpenMPTaskingDirective(CurrDir)) { 10257 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10258 << getOpenMPClauseName(OMPC_private) << Type 10259 << getOpenMPDirectiveName(CurrDir); 10260 bool IsDecl = 10261 !VD || 10262 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10263 Diag(D->getLocation(), 10264 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10265 << D; 10266 continue; 10267 } 10268 10269 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10270 // A list item cannot appear in both a map clause and a data-sharing 10271 // attribute clause on the same construct 10272 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10273 OpenMPClauseKind ConflictKind; 10274 if (DSAStack->checkMappableExprComponentListsForDecl( 10275 VD, /*CurrentRegionOnly=*/true, 10276 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 10277 OpenMPClauseKind WhereFoundClauseKind) -> bool { 10278 ConflictKind = WhereFoundClauseKind; 10279 return true; 10280 })) { 10281 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10282 << getOpenMPClauseName(OMPC_private) 10283 << getOpenMPClauseName(ConflictKind) 10284 << getOpenMPDirectiveName(CurrDir); 10285 reportOriginalDsa(*this, DSAStack, D, DVar); 10286 continue; 10287 } 10288 } 10289 10290 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 10291 // A variable of class type (or array thereof) that appears in a private 10292 // clause requires an accessible, unambiguous default constructor for the 10293 // class type. 10294 // Generate helper private variable and initialize it with the default 10295 // value. The address of the original variable is replaced by the address of 10296 // the new private variable in CodeGen. This new variable is not added to 10297 // IdResolver, so the code in the OpenMP region uses original variable for 10298 // proper diagnostics. 10299 Type = Type.getUnqualifiedType(); 10300 VarDecl *VDPrivate = 10301 buildVarDecl(*this, ELoc, Type, D->getName(), 10302 D->hasAttrs() ? &D->getAttrs() : nullptr, 10303 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10304 ActOnUninitializedDecl(VDPrivate); 10305 if (VDPrivate->isInvalidDecl()) 10306 continue; 10307 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10308 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 10309 10310 DeclRefExpr *Ref = nullptr; 10311 if (!VD && !CurContext->isDependentContext()) 10312 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10313 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 10314 Vars.push_back((VD || CurContext->isDependentContext()) 10315 ? RefExpr->IgnoreParens() 10316 : Ref); 10317 PrivateCopies.push_back(VDPrivateRefExpr); 10318 } 10319 10320 if (Vars.empty()) 10321 return nullptr; 10322 10323 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 10324 PrivateCopies); 10325 } 10326 10327 namespace { 10328 class DiagsUninitializedSeveretyRAII { 10329 private: 10330 DiagnosticsEngine &Diags; 10331 SourceLocation SavedLoc; 10332 bool IsIgnored = false; 10333 10334 public: 10335 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 10336 bool IsIgnored) 10337 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 10338 if (!IsIgnored) { 10339 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 10340 /*Map*/ diag::Severity::Ignored, Loc); 10341 } 10342 } 10343 ~DiagsUninitializedSeveretyRAII() { 10344 if (!IsIgnored) 10345 Diags.popMappings(SavedLoc); 10346 } 10347 }; 10348 } 10349 10350 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 10351 SourceLocation StartLoc, 10352 SourceLocation LParenLoc, 10353 SourceLocation EndLoc) { 10354 SmallVector<Expr *, 8> Vars; 10355 SmallVector<Expr *, 8> PrivateCopies; 10356 SmallVector<Expr *, 8> Inits; 10357 SmallVector<Decl *, 4> ExprCaptures; 10358 bool IsImplicitClause = 10359 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 10360 SourceLocation ImplicitClauseLoc = DSAStack->getConstructLoc(); 10361 10362 for (Expr *RefExpr : VarList) { 10363 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 10364 SourceLocation ELoc; 10365 SourceRange ERange; 10366 Expr *SimpleRefExpr = RefExpr; 10367 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10368 if (Res.second) { 10369 // It will be analyzed later. 10370 Vars.push_back(RefExpr); 10371 PrivateCopies.push_back(nullptr); 10372 Inits.push_back(nullptr); 10373 } 10374 ValueDecl *D = Res.first; 10375 if (!D) 10376 continue; 10377 10378 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 10379 QualType Type = D->getType(); 10380 auto *VD = dyn_cast<VarDecl>(D); 10381 10382 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10383 // A variable that appears in a private clause must not have an incomplete 10384 // type or a reference type. 10385 if (RequireCompleteType(ELoc, Type, 10386 diag::err_omp_firstprivate_incomplete_type)) 10387 continue; 10388 Type = Type.getNonReferenceType(); 10389 10390 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 10391 // A variable of class type (or array thereof) that appears in a private 10392 // clause requires an accessible, unambiguous copy constructor for the 10393 // class type. 10394 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 10395 10396 // If an implicit firstprivate variable found it was checked already. 10397 DSAStackTy::DSAVarData TopDVar; 10398 if (!IsImplicitClause) { 10399 DSAStackTy::DSAVarData DVar = 10400 DSAStack->getTopDSA(D, /*FromParent=*/false); 10401 TopDVar = DVar; 10402 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10403 bool IsConstant = ElemType.isConstant(Context); 10404 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 10405 // A list item that specifies a given variable may not appear in more 10406 // than one clause on the same directive, except that a variable may be 10407 // specified in both firstprivate and lastprivate clauses. 10408 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 10409 // A list item may appear in a firstprivate or lastprivate clause but not 10410 // both. 10411 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 10412 (isOpenMPDistributeDirective(CurrDir) || 10413 DVar.CKind != OMPC_lastprivate) && 10414 DVar.RefExpr) { 10415 Diag(ELoc, diag::err_omp_wrong_dsa) 10416 << getOpenMPClauseName(DVar.CKind) 10417 << getOpenMPClauseName(OMPC_firstprivate); 10418 reportOriginalDsa(*this, DSAStack, D, DVar); 10419 continue; 10420 } 10421 10422 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10423 // in a Construct] 10424 // Variables with the predetermined data-sharing attributes may not be 10425 // listed in data-sharing attributes clauses, except for the cases 10426 // listed below. For these exceptions only, listing a predetermined 10427 // variable in a data-sharing attribute clause is allowed and overrides 10428 // the variable's predetermined data-sharing attributes. 10429 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10430 // in a Construct, C/C++, p.2] 10431 // Variables with const-qualified type having no mutable member may be 10432 // listed in a firstprivate clause, even if they are static data members. 10433 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 10434 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 10435 Diag(ELoc, diag::err_omp_wrong_dsa) 10436 << getOpenMPClauseName(DVar.CKind) 10437 << getOpenMPClauseName(OMPC_firstprivate); 10438 reportOriginalDsa(*this, DSAStack, D, DVar); 10439 continue; 10440 } 10441 10442 // OpenMP [2.9.3.4, Restrictions, p.2] 10443 // A list item that is private within a parallel region must not appear 10444 // in a firstprivate clause on a worksharing construct if any of the 10445 // worksharing regions arising from the worksharing construct ever bind 10446 // to any of the parallel regions arising from the parallel construct. 10447 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 10448 // A list item that is private within a teams region must not appear in a 10449 // firstprivate clause on a distribute construct if any of the distribute 10450 // regions arising from the distribute construct ever bind to any of the 10451 // teams regions arising from the teams construct. 10452 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 10453 // A list item that appears in a reduction clause of a teams construct 10454 // must not appear in a firstprivate clause on a distribute construct if 10455 // any of the distribute regions arising from the distribute construct 10456 // ever bind to any of the teams regions arising from the teams construct. 10457 if ((isOpenMPWorksharingDirective(CurrDir) || 10458 isOpenMPDistributeDirective(CurrDir)) && 10459 !isOpenMPParallelDirective(CurrDir) && 10460 !isOpenMPTeamsDirective(CurrDir)) { 10461 DVar = DSAStack->getImplicitDSA(D, true); 10462 if (DVar.CKind != OMPC_shared && 10463 (isOpenMPParallelDirective(DVar.DKind) || 10464 isOpenMPTeamsDirective(DVar.DKind) || 10465 DVar.DKind == OMPD_unknown)) { 10466 Diag(ELoc, diag::err_omp_required_access) 10467 << getOpenMPClauseName(OMPC_firstprivate) 10468 << getOpenMPClauseName(OMPC_shared); 10469 reportOriginalDsa(*this, DSAStack, D, DVar); 10470 continue; 10471 } 10472 } 10473 // OpenMP [2.9.3.4, Restrictions, p.3] 10474 // A list item that appears in a reduction clause of a parallel construct 10475 // must not appear in a firstprivate clause on a worksharing or task 10476 // construct if any of the worksharing or task regions arising from the 10477 // worksharing or task construct ever bind to any of the parallel regions 10478 // arising from the parallel construct. 10479 // OpenMP [2.9.3.4, Restrictions, p.4] 10480 // A list item that appears in a reduction clause in worksharing 10481 // construct must not appear in a firstprivate clause in a task construct 10482 // encountered during execution of any of the worksharing regions arising 10483 // from the worksharing construct. 10484 if (isOpenMPTaskingDirective(CurrDir)) { 10485 DVar = DSAStack->hasInnermostDSA( 10486 D, [](OpenMPClauseKind C) { return C == OMPC_reduction; }, 10487 [](OpenMPDirectiveKind K) { 10488 return isOpenMPParallelDirective(K) || 10489 isOpenMPWorksharingDirective(K) || 10490 isOpenMPTeamsDirective(K); 10491 }, 10492 /*FromParent=*/true); 10493 if (DVar.CKind == OMPC_reduction && 10494 (isOpenMPParallelDirective(DVar.DKind) || 10495 isOpenMPWorksharingDirective(DVar.DKind) || 10496 isOpenMPTeamsDirective(DVar.DKind))) { 10497 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 10498 << getOpenMPDirectiveName(DVar.DKind); 10499 reportOriginalDsa(*this, DSAStack, D, DVar); 10500 continue; 10501 } 10502 } 10503 10504 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10505 // A list item cannot appear in both a map clause and a data-sharing 10506 // attribute clause on the same construct 10507 if (isOpenMPTargetExecutionDirective(CurrDir)) { 10508 OpenMPClauseKind ConflictKind; 10509 if (DSAStack->checkMappableExprComponentListsForDecl( 10510 VD, /*CurrentRegionOnly=*/true, 10511 [&ConflictKind]( 10512 OMPClauseMappableExprCommon::MappableExprComponentListRef, 10513 OpenMPClauseKind WhereFoundClauseKind) { 10514 ConflictKind = WhereFoundClauseKind; 10515 return true; 10516 })) { 10517 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10518 << getOpenMPClauseName(OMPC_firstprivate) 10519 << getOpenMPClauseName(ConflictKind) 10520 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10521 reportOriginalDsa(*this, DSAStack, D, DVar); 10522 continue; 10523 } 10524 } 10525 } 10526 10527 // Variably modified types are not supported for tasks. 10528 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 10529 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 10530 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10531 << getOpenMPClauseName(OMPC_firstprivate) << Type 10532 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10533 bool IsDecl = 10534 !VD || 10535 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10536 Diag(D->getLocation(), 10537 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10538 << D; 10539 continue; 10540 } 10541 10542 Type = Type.getUnqualifiedType(); 10543 VarDecl *VDPrivate = 10544 buildVarDecl(*this, ELoc, Type, D->getName(), 10545 D->hasAttrs() ? &D->getAttrs() : nullptr, 10546 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 10547 // Generate helper private variable and initialize it with the value of the 10548 // original variable. The address of the original variable is replaced by 10549 // the address of the new private variable in the CodeGen. This new variable 10550 // is not added to IdResolver, so the code in the OpenMP region uses 10551 // original variable for proper diagnostics and variable capturing. 10552 Expr *VDInitRefExpr = nullptr; 10553 // For arrays generate initializer for single element and replace it by the 10554 // original array element in CodeGen. 10555 if (Type->isArrayType()) { 10556 VarDecl *VDInit = 10557 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 10558 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 10559 Expr *Init = DefaultLvalueConversion(VDInitRefExpr).get(); 10560 ElemType = ElemType.getUnqualifiedType(); 10561 VarDecl *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 10562 ".firstprivate.temp"); 10563 InitializedEntity Entity = 10564 InitializedEntity::InitializeVariable(VDInitTemp); 10565 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 10566 10567 InitializationSequence InitSeq(*this, Entity, Kind, Init); 10568 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 10569 if (Result.isInvalid()) 10570 VDPrivate->setInvalidDecl(); 10571 else 10572 VDPrivate->setInit(Result.getAs<Expr>()); 10573 // Remove temp variable declaration. 10574 Context.Deallocate(VDInitTemp); 10575 } else { 10576 VarDecl *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 10577 ".firstprivate.temp"); 10578 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 10579 RefExpr->getExprLoc()); 10580 AddInitializerToDecl(VDPrivate, 10581 DefaultLvalueConversion(VDInitRefExpr).get(), 10582 /*DirectInit=*/false); 10583 } 10584 if (VDPrivate->isInvalidDecl()) { 10585 if (IsImplicitClause) { 10586 Diag(RefExpr->getExprLoc(), 10587 diag::note_omp_task_predetermined_firstprivate_here); 10588 } 10589 continue; 10590 } 10591 CurContext->addDecl(VDPrivate); 10592 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 10593 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 10594 RefExpr->getExprLoc()); 10595 DeclRefExpr *Ref = nullptr; 10596 if (!VD && !CurContext->isDependentContext()) { 10597 if (TopDVar.CKind == OMPC_lastprivate) { 10598 Ref = TopDVar.PrivateCopy; 10599 } else { 10600 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10601 if (!isOpenMPCapturedDecl(D)) 10602 ExprCaptures.push_back(Ref->getDecl()); 10603 } 10604 } 10605 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 10606 Vars.push_back((VD || CurContext->isDependentContext()) 10607 ? RefExpr->IgnoreParens() 10608 : Ref); 10609 PrivateCopies.push_back(VDPrivateRefExpr); 10610 Inits.push_back(VDInitRefExpr); 10611 } 10612 10613 if (Vars.empty()) 10614 return nullptr; 10615 10616 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10617 Vars, PrivateCopies, Inits, 10618 buildPreInits(Context, ExprCaptures)); 10619 } 10620 10621 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 10622 SourceLocation StartLoc, 10623 SourceLocation LParenLoc, 10624 SourceLocation EndLoc) { 10625 SmallVector<Expr *, 8> Vars; 10626 SmallVector<Expr *, 8> SrcExprs; 10627 SmallVector<Expr *, 8> DstExprs; 10628 SmallVector<Expr *, 8> AssignmentOps; 10629 SmallVector<Decl *, 4> ExprCaptures; 10630 SmallVector<Expr *, 4> ExprPostUpdates; 10631 for (Expr *RefExpr : VarList) { 10632 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 10633 SourceLocation ELoc; 10634 SourceRange ERange; 10635 Expr *SimpleRefExpr = RefExpr; 10636 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10637 if (Res.second) { 10638 // It will be analyzed later. 10639 Vars.push_back(RefExpr); 10640 SrcExprs.push_back(nullptr); 10641 DstExprs.push_back(nullptr); 10642 AssignmentOps.push_back(nullptr); 10643 } 10644 ValueDecl *D = Res.first; 10645 if (!D) 10646 continue; 10647 10648 QualType Type = D->getType(); 10649 auto *VD = dyn_cast<VarDecl>(D); 10650 10651 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 10652 // A variable that appears in a lastprivate clause must not have an 10653 // incomplete type or a reference type. 10654 if (RequireCompleteType(ELoc, Type, 10655 diag::err_omp_lastprivate_incomplete_type)) 10656 continue; 10657 Type = Type.getNonReferenceType(); 10658 10659 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 10660 // A variable that is privatized must not have a const-qualified type 10661 // unless it is of class type with a mutable member. This restriction does 10662 // not apply to the firstprivate clause. 10663 // 10664 // OpenMP 3.1 [2.9.3.5, lastprivate clause, Restrictions] 10665 // A variable that appears in a lastprivate clause must not have a 10666 // const-qualified type unless it is of class type with a mutable member. 10667 if (rejectConstNotMutableType(*this, D, Type, OMPC_lastprivate, ELoc)) 10668 continue; 10669 10670 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 10671 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 10672 // in a Construct] 10673 // Variables with the predetermined data-sharing attributes may not be 10674 // listed in data-sharing attributes clauses, except for the cases 10675 // listed below. 10676 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 10677 // A list item may appear in a firstprivate or lastprivate clause but not 10678 // both. 10679 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10680 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 10681 (isOpenMPDistributeDirective(CurrDir) || 10682 DVar.CKind != OMPC_firstprivate) && 10683 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 10684 Diag(ELoc, diag::err_omp_wrong_dsa) 10685 << getOpenMPClauseName(DVar.CKind) 10686 << getOpenMPClauseName(OMPC_lastprivate); 10687 reportOriginalDsa(*this, DSAStack, D, DVar); 10688 continue; 10689 } 10690 10691 // OpenMP [2.14.3.5, Restrictions, p.2] 10692 // A list item that is private within a parallel region, or that appears in 10693 // the reduction clause of a parallel construct, must not appear in a 10694 // lastprivate clause on a worksharing construct if any of the corresponding 10695 // worksharing regions ever binds to any of the corresponding parallel 10696 // regions. 10697 DSAStackTy::DSAVarData TopDVar = DVar; 10698 if (isOpenMPWorksharingDirective(CurrDir) && 10699 !isOpenMPParallelDirective(CurrDir) && 10700 !isOpenMPTeamsDirective(CurrDir)) { 10701 DVar = DSAStack->getImplicitDSA(D, true); 10702 if (DVar.CKind != OMPC_shared) { 10703 Diag(ELoc, diag::err_omp_required_access) 10704 << getOpenMPClauseName(OMPC_lastprivate) 10705 << getOpenMPClauseName(OMPC_shared); 10706 reportOriginalDsa(*this, DSAStack, D, DVar); 10707 continue; 10708 } 10709 } 10710 10711 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 10712 // A variable of class type (or array thereof) that appears in a 10713 // lastprivate clause requires an accessible, unambiguous default 10714 // constructor for the class type, unless the list item is also specified 10715 // in a firstprivate clause. 10716 // A variable of class type (or array thereof) that appears in a 10717 // lastprivate clause requires an accessible, unambiguous copy assignment 10718 // operator for the class type. 10719 Type = Context.getBaseElementType(Type).getNonReferenceType(); 10720 VarDecl *SrcVD = buildVarDecl(*this, ERange.getBegin(), 10721 Type.getUnqualifiedType(), ".lastprivate.src", 10722 D->hasAttrs() ? &D->getAttrs() : nullptr); 10723 DeclRefExpr *PseudoSrcExpr = 10724 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 10725 VarDecl *DstVD = 10726 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 10727 D->hasAttrs() ? &D->getAttrs() : nullptr); 10728 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 10729 // For arrays generate assignment operation for single element and replace 10730 // it by the original array element in CodeGen. 10731 ExprResult AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 10732 PseudoDstExpr, PseudoSrcExpr); 10733 if (AssignmentOp.isInvalid()) 10734 continue; 10735 AssignmentOp = 10736 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 10737 if (AssignmentOp.isInvalid()) 10738 continue; 10739 10740 DeclRefExpr *Ref = nullptr; 10741 if (!VD && !CurContext->isDependentContext()) { 10742 if (TopDVar.CKind == OMPC_firstprivate) { 10743 Ref = TopDVar.PrivateCopy; 10744 } else { 10745 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10746 if (!isOpenMPCapturedDecl(D)) 10747 ExprCaptures.push_back(Ref->getDecl()); 10748 } 10749 if (TopDVar.CKind == OMPC_firstprivate || 10750 (!isOpenMPCapturedDecl(D) && 10751 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 10752 ExprResult RefRes = DefaultLvalueConversion(Ref); 10753 if (!RefRes.isUsable()) 10754 continue; 10755 ExprResult PostUpdateRes = 10756 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 10757 RefRes.get()); 10758 if (!PostUpdateRes.isUsable()) 10759 continue; 10760 ExprPostUpdates.push_back( 10761 IgnoredValueConversions(PostUpdateRes.get()).get()); 10762 } 10763 } 10764 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 10765 Vars.push_back((VD || CurContext->isDependentContext()) 10766 ? RefExpr->IgnoreParens() 10767 : Ref); 10768 SrcExprs.push_back(PseudoSrcExpr); 10769 DstExprs.push_back(PseudoDstExpr); 10770 AssignmentOps.push_back(AssignmentOp.get()); 10771 } 10772 10773 if (Vars.empty()) 10774 return nullptr; 10775 10776 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10777 Vars, SrcExprs, DstExprs, AssignmentOps, 10778 buildPreInits(Context, ExprCaptures), 10779 buildPostUpdate(*this, ExprPostUpdates)); 10780 } 10781 10782 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 10783 SourceLocation StartLoc, 10784 SourceLocation LParenLoc, 10785 SourceLocation EndLoc) { 10786 SmallVector<Expr *, 8> Vars; 10787 for (Expr *RefExpr : VarList) { 10788 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 10789 SourceLocation ELoc; 10790 SourceRange ERange; 10791 Expr *SimpleRefExpr = RefExpr; 10792 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 10793 if (Res.second) { 10794 // It will be analyzed later. 10795 Vars.push_back(RefExpr); 10796 } 10797 ValueDecl *D = Res.first; 10798 if (!D) 10799 continue; 10800 10801 auto *VD = dyn_cast<VarDecl>(D); 10802 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 10803 // in a Construct] 10804 // Variables with the predetermined data-sharing attributes may not be 10805 // listed in data-sharing attributes clauses, except for the cases 10806 // listed below. For these exceptions only, listing a predetermined 10807 // variable in a data-sharing attribute clause is allowed and overrides 10808 // the variable's predetermined data-sharing attributes. 10809 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 10810 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 10811 DVar.RefExpr) { 10812 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10813 << getOpenMPClauseName(OMPC_shared); 10814 reportOriginalDsa(*this, DSAStack, D, DVar); 10815 continue; 10816 } 10817 10818 DeclRefExpr *Ref = nullptr; 10819 if (!VD && isOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 10820 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10821 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 10822 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 10823 ? RefExpr->IgnoreParens() 10824 : Ref); 10825 } 10826 10827 if (Vars.empty()) 10828 return nullptr; 10829 10830 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 10831 } 10832 10833 namespace { 10834 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 10835 DSAStackTy *Stack; 10836 10837 public: 10838 bool VisitDeclRefExpr(DeclRefExpr *E) { 10839 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 10840 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, /*FromParent=*/false); 10841 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 10842 return false; 10843 if (DVar.CKind != OMPC_unknown) 10844 return true; 10845 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 10846 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) { return true; }, 10847 /*FromParent=*/true); 10848 return DVarPrivate.CKind != OMPC_unknown; 10849 } 10850 return false; 10851 } 10852 bool VisitStmt(Stmt *S) { 10853 for (Stmt *Child : S->children()) { 10854 if (Child && Visit(Child)) 10855 return true; 10856 } 10857 return false; 10858 } 10859 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 10860 }; 10861 } // namespace 10862 10863 namespace { 10864 // Transform MemberExpression for specified FieldDecl of current class to 10865 // DeclRefExpr to specified OMPCapturedExprDecl. 10866 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 10867 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 10868 ValueDecl *Field = nullptr; 10869 DeclRefExpr *CapturedExpr = nullptr; 10870 10871 public: 10872 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 10873 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 10874 10875 ExprResult TransformMemberExpr(MemberExpr *E) { 10876 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 10877 E->getMemberDecl() == Field) { 10878 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 10879 return CapturedExpr; 10880 } 10881 return BaseTransform::TransformMemberExpr(E); 10882 } 10883 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 10884 }; 10885 } // namespace 10886 10887 template <typename T, typename U> 10888 static T filterLookupForUDReductionAndMapper( 10889 SmallVectorImpl<U> &Lookups, const llvm::function_ref<T(ValueDecl *)> Gen) { 10890 for (U &Set : Lookups) { 10891 for (auto *D : Set) { 10892 if (T Res = Gen(cast<ValueDecl>(D))) 10893 return Res; 10894 } 10895 } 10896 return T(); 10897 } 10898 10899 static NamedDecl *findAcceptableDecl(Sema &SemaRef, NamedDecl *D) { 10900 assert(!LookupResult::isVisible(SemaRef, D) && "not in slow case"); 10901 10902 for (auto RD : D->redecls()) { 10903 // Don't bother with extra checks if we already know this one isn't visible. 10904 if (RD == D) 10905 continue; 10906 10907 auto ND = cast<NamedDecl>(RD); 10908 if (LookupResult::isVisible(SemaRef, ND)) 10909 return ND; 10910 } 10911 10912 return nullptr; 10913 } 10914 10915 static void 10916 argumentDependentLookup(Sema &SemaRef, const DeclarationNameInfo &Id, 10917 SourceLocation Loc, QualType Ty, 10918 SmallVectorImpl<UnresolvedSet<8>> &Lookups) { 10919 // Find all of the associated namespaces and classes based on the 10920 // arguments we have. 10921 Sema::AssociatedNamespaceSet AssociatedNamespaces; 10922 Sema::AssociatedClassSet AssociatedClasses; 10923 OpaqueValueExpr OVE(Loc, Ty, VK_LValue); 10924 SemaRef.FindAssociatedClassesAndNamespaces(Loc, &OVE, AssociatedNamespaces, 10925 AssociatedClasses); 10926 10927 // C++ [basic.lookup.argdep]p3: 10928 // Let X be the lookup set produced by unqualified lookup (3.4.1) 10929 // and let Y be the lookup set produced by argument dependent 10930 // lookup (defined as follows). If X contains [...] then Y is 10931 // empty. Otherwise Y is the set of declarations found in the 10932 // namespaces associated with the argument types as described 10933 // below. The set of declarations found by the lookup of the name 10934 // is the union of X and Y. 10935 // 10936 // Here, we compute Y and add its members to the overloaded 10937 // candidate set. 10938 for (auto *NS : AssociatedNamespaces) { 10939 // When considering an associated namespace, the lookup is the 10940 // same as the lookup performed when the associated namespace is 10941 // used as a qualifier (3.4.3.2) except that: 10942 // 10943 // -- Any using-directives in the associated namespace are 10944 // ignored. 10945 // 10946 // -- Any namespace-scope friend functions declared in 10947 // associated classes are visible within their respective 10948 // namespaces even if they are not visible during an ordinary 10949 // lookup (11.4). 10950 DeclContext::lookup_result R = NS->lookup(Id.getName()); 10951 for (auto *D : R) { 10952 auto *Underlying = D; 10953 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 10954 Underlying = USD->getTargetDecl(); 10955 10956 if (!isa<OMPDeclareReductionDecl>(Underlying) && 10957 !isa<OMPDeclareMapperDecl>(Underlying)) 10958 continue; 10959 10960 if (!SemaRef.isVisible(D)) { 10961 D = findAcceptableDecl(SemaRef, D); 10962 if (!D) 10963 continue; 10964 if (auto *USD = dyn_cast<UsingShadowDecl>(D)) 10965 Underlying = USD->getTargetDecl(); 10966 } 10967 Lookups.emplace_back(); 10968 Lookups.back().addDecl(Underlying); 10969 } 10970 } 10971 } 10972 10973 static ExprResult 10974 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 10975 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 10976 const DeclarationNameInfo &ReductionId, QualType Ty, 10977 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 10978 if (ReductionIdScopeSpec.isInvalid()) 10979 return ExprError(); 10980 SmallVector<UnresolvedSet<8>, 4> Lookups; 10981 if (S) { 10982 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 10983 Lookup.suppressDiagnostics(); 10984 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 10985 NamedDecl *D = Lookup.getRepresentativeDecl(); 10986 do { 10987 S = S->getParent(); 10988 } while (S && !S->isDeclScope(D)); 10989 if (S) 10990 S = S->getParent(); 10991 Lookups.emplace_back(); 10992 Lookups.back().append(Lookup.begin(), Lookup.end()); 10993 Lookup.clear(); 10994 } 10995 } else if (auto *ULE = 10996 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 10997 Lookups.push_back(UnresolvedSet<8>()); 10998 Decl *PrevD = nullptr; 10999 for (NamedDecl *D : ULE->decls()) { 11000 if (D == PrevD) 11001 Lookups.push_back(UnresolvedSet<8>()); 11002 else if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(D)) 11003 Lookups.back().addDecl(DRD); 11004 PrevD = D; 11005 } 11006 } 11007 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 11008 Ty->isInstantiationDependentType() || 11009 Ty->containsUnexpandedParameterPack() || 11010 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 11011 return !D->isInvalidDecl() && 11012 (D->getType()->isDependentType() || 11013 D->getType()->isInstantiationDependentType() || 11014 D->getType()->containsUnexpandedParameterPack()); 11015 })) { 11016 UnresolvedSet<8> ResSet; 11017 for (const UnresolvedSet<8> &Set : Lookups) { 11018 if (Set.empty()) 11019 continue; 11020 ResSet.append(Set.begin(), Set.end()); 11021 // The last item marks the end of all declarations at the specified scope. 11022 ResSet.addDecl(Set[Set.size() - 1]); 11023 } 11024 return UnresolvedLookupExpr::Create( 11025 SemaRef.Context, /*NamingClass=*/nullptr, 11026 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 11027 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 11028 } 11029 // Lookup inside the classes. 11030 // C++ [over.match.oper]p3: 11031 // For a unary operator @ with an operand of a type whose 11032 // cv-unqualified version is T1, and for a binary operator @ with 11033 // a left operand of a type whose cv-unqualified version is T1 and 11034 // a right operand of a type whose cv-unqualified version is T2, 11035 // three sets of candidate functions, designated member 11036 // candidates, non-member candidates and built-in candidates, are 11037 // constructed as follows: 11038 // -- If T1 is a complete class type or a class currently being 11039 // defined, the set of member candidates is the result of the 11040 // qualified lookup of T1::operator@ (13.3.1.1.1); otherwise, 11041 // the set of member candidates is empty. 11042 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 11043 Lookup.suppressDiagnostics(); 11044 if (const auto *TyRec = Ty->getAs<RecordType>()) { 11045 // Complete the type if it can be completed. 11046 // If the type is neither complete nor being defined, bail out now. 11047 if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() || 11048 TyRec->getDecl()->getDefinition()) { 11049 Lookup.clear(); 11050 SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl()); 11051 if (Lookup.empty()) { 11052 Lookups.emplace_back(); 11053 Lookups.back().append(Lookup.begin(), Lookup.end()); 11054 } 11055 } 11056 } 11057 // Perform ADL. 11058 if (SemaRef.getLangOpts().CPlusPlus) { 11059 argumentDependentLookup(SemaRef, ReductionId, Loc, Ty, Lookups); 11060 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11061 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 11062 if (!D->isInvalidDecl() && 11063 SemaRef.Context.hasSameType(D->getType(), Ty)) 11064 return D; 11065 return nullptr; 11066 })) 11067 return SemaRef.BuildDeclRefExpr(VD, VD->getType().getNonReferenceType(), 11068 VK_LValue, Loc); 11069 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 11070 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 11071 if (!D->isInvalidDecl() && 11072 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 11073 !Ty.isMoreQualifiedThan(D->getType())) 11074 return D; 11075 return nullptr; 11076 })) { 11077 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 11078 /*DetectVirtual=*/false); 11079 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 11080 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 11081 VD->getType().getUnqualifiedType()))) { 11082 if (SemaRef.CheckBaseClassAccess( 11083 Loc, VD->getType(), Ty, Paths.front(), 11084 /*DiagID=*/0) != Sema::AR_inaccessible) { 11085 SemaRef.BuildBasePathArray(Paths, BasePath); 11086 return SemaRef.BuildDeclRefExpr( 11087 VD, VD->getType().getNonReferenceType(), VK_LValue, Loc); 11088 } 11089 } 11090 } 11091 } 11092 } 11093 if (ReductionIdScopeSpec.isSet()) { 11094 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 11095 return ExprError(); 11096 } 11097 return ExprEmpty(); 11098 } 11099 11100 namespace { 11101 /// Data for the reduction-based clauses. 11102 struct ReductionData { 11103 /// List of original reduction items. 11104 SmallVector<Expr *, 8> Vars; 11105 /// List of private copies of the reduction items. 11106 SmallVector<Expr *, 8> Privates; 11107 /// LHS expressions for the reduction_op expressions. 11108 SmallVector<Expr *, 8> LHSs; 11109 /// RHS expressions for the reduction_op expressions. 11110 SmallVector<Expr *, 8> RHSs; 11111 /// Reduction operation expression. 11112 SmallVector<Expr *, 8> ReductionOps; 11113 /// Taskgroup descriptors for the corresponding reduction items in 11114 /// in_reduction clauses. 11115 SmallVector<Expr *, 8> TaskgroupDescriptors; 11116 /// List of captures for clause. 11117 SmallVector<Decl *, 4> ExprCaptures; 11118 /// List of postupdate expressions. 11119 SmallVector<Expr *, 4> ExprPostUpdates; 11120 ReductionData() = delete; 11121 /// Reserves required memory for the reduction data. 11122 ReductionData(unsigned Size) { 11123 Vars.reserve(Size); 11124 Privates.reserve(Size); 11125 LHSs.reserve(Size); 11126 RHSs.reserve(Size); 11127 ReductionOps.reserve(Size); 11128 TaskgroupDescriptors.reserve(Size); 11129 ExprCaptures.reserve(Size); 11130 ExprPostUpdates.reserve(Size); 11131 } 11132 /// Stores reduction item and reduction operation only (required for dependent 11133 /// reduction item). 11134 void push(Expr *Item, Expr *ReductionOp) { 11135 Vars.emplace_back(Item); 11136 Privates.emplace_back(nullptr); 11137 LHSs.emplace_back(nullptr); 11138 RHSs.emplace_back(nullptr); 11139 ReductionOps.emplace_back(ReductionOp); 11140 TaskgroupDescriptors.emplace_back(nullptr); 11141 } 11142 /// Stores reduction data. 11143 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 11144 Expr *TaskgroupDescriptor) { 11145 Vars.emplace_back(Item); 11146 Privates.emplace_back(Private); 11147 LHSs.emplace_back(LHS); 11148 RHSs.emplace_back(RHS); 11149 ReductionOps.emplace_back(ReductionOp); 11150 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 11151 } 11152 }; 11153 } // namespace 11154 11155 static bool checkOMPArraySectionConstantForReduction( 11156 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 11157 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 11158 const Expr *Length = OASE->getLength(); 11159 if (Length == nullptr) { 11160 // For array sections of the form [1:] or [:], we would need to analyze 11161 // the lower bound... 11162 if (OASE->getColonLoc().isValid()) 11163 return false; 11164 11165 // This is an array subscript which has implicit length 1! 11166 SingleElement = true; 11167 ArraySizes.push_back(llvm::APSInt::get(1)); 11168 } else { 11169 Expr::EvalResult Result; 11170 if (!Length->EvaluateAsInt(Result, Context)) 11171 return false; 11172 11173 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11174 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 11175 ArraySizes.push_back(ConstantLengthValue); 11176 } 11177 11178 // Get the base of this array section and walk up from there. 11179 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 11180 11181 // We require length = 1 for all array sections except the right-most to 11182 // guarantee that the memory region is contiguous and has no holes in it. 11183 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 11184 Length = TempOASE->getLength(); 11185 if (Length == nullptr) { 11186 // For array sections of the form [1:] or [:], we would need to analyze 11187 // the lower bound... 11188 if (OASE->getColonLoc().isValid()) 11189 return false; 11190 11191 // This is an array subscript which has implicit length 1! 11192 ArraySizes.push_back(llvm::APSInt::get(1)); 11193 } else { 11194 Expr::EvalResult Result; 11195 if (!Length->EvaluateAsInt(Result, Context)) 11196 return false; 11197 11198 llvm::APSInt ConstantLengthValue = Result.Val.getInt(); 11199 if (ConstantLengthValue.getSExtValue() != 1) 11200 return false; 11201 11202 ArraySizes.push_back(ConstantLengthValue); 11203 } 11204 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 11205 } 11206 11207 // If we have a single element, we don't need to add the implicit lengths. 11208 if (!SingleElement) { 11209 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 11210 // Has implicit length 1! 11211 ArraySizes.push_back(llvm::APSInt::get(1)); 11212 Base = TempASE->getBase()->IgnoreParenImpCasts(); 11213 } 11214 } 11215 11216 // This array section can be privatized as a single value or as a constant 11217 // sized array. 11218 return true; 11219 } 11220 11221 static bool actOnOMPReductionKindClause( 11222 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 11223 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11224 SourceLocation ColonLoc, SourceLocation EndLoc, 11225 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11226 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 11227 DeclarationName DN = ReductionId.getName(); 11228 OverloadedOperatorKind OOK = DN.getCXXOverloadedOperator(); 11229 BinaryOperatorKind BOK = BO_Comma; 11230 11231 ASTContext &Context = S.Context; 11232 // OpenMP [2.14.3.6, reduction clause] 11233 // C 11234 // reduction-identifier is either an identifier or one of the following 11235 // operators: +, -, *, &, |, ^, && and || 11236 // C++ 11237 // reduction-identifier is either an id-expression or one of the following 11238 // operators: +, -, *, &, |, ^, && and || 11239 switch (OOK) { 11240 case OO_Plus: 11241 case OO_Minus: 11242 BOK = BO_Add; 11243 break; 11244 case OO_Star: 11245 BOK = BO_Mul; 11246 break; 11247 case OO_Amp: 11248 BOK = BO_And; 11249 break; 11250 case OO_Pipe: 11251 BOK = BO_Or; 11252 break; 11253 case OO_Caret: 11254 BOK = BO_Xor; 11255 break; 11256 case OO_AmpAmp: 11257 BOK = BO_LAnd; 11258 break; 11259 case OO_PipePipe: 11260 BOK = BO_LOr; 11261 break; 11262 case OO_New: 11263 case OO_Delete: 11264 case OO_Array_New: 11265 case OO_Array_Delete: 11266 case OO_Slash: 11267 case OO_Percent: 11268 case OO_Tilde: 11269 case OO_Exclaim: 11270 case OO_Equal: 11271 case OO_Less: 11272 case OO_Greater: 11273 case OO_LessEqual: 11274 case OO_GreaterEqual: 11275 case OO_PlusEqual: 11276 case OO_MinusEqual: 11277 case OO_StarEqual: 11278 case OO_SlashEqual: 11279 case OO_PercentEqual: 11280 case OO_CaretEqual: 11281 case OO_AmpEqual: 11282 case OO_PipeEqual: 11283 case OO_LessLess: 11284 case OO_GreaterGreater: 11285 case OO_LessLessEqual: 11286 case OO_GreaterGreaterEqual: 11287 case OO_EqualEqual: 11288 case OO_ExclaimEqual: 11289 case OO_Spaceship: 11290 case OO_PlusPlus: 11291 case OO_MinusMinus: 11292 case OO_Comma: 11293 case OO_ArrowStar: 11294 case OO_Arrow: 11295 case OO_Call: 11296 case OO_Subscript: 11297 case OO_Conditional: 11298 case OO_Coawait: 11299 case NUM_OVERLOADED_OPERATORS: 11300 llvm_unreachable("Unexpected reduction identifier"); 11301 case OO_None: 11302 if (IdentifierInfo *II = DN.getAsIdentifierInfo()) { 11303 if (II->isStr("max")) 11304 BOK = BO_GT; 11305 else if (II->isStr("min")) 11306 BOK = BO_LT; 11307 } 11308 break; 11309 } 11310 SourceRange ReductionIdRange; 11311 if (ReductionIdScopeSpec.isValid()) 11312 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 11313 else 11314 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 11315 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 11316 11317 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 11318 bool FirstIter = true; 11319 for (Expr *RefExpr : VarList) { 11320 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 11321 // OpenMP [2.1, C/C++] 11322 // A list item is a variable or array section, subject to the restrictions 11323 // specified in Section 2.4 on page 42 and in each of the sections 11324 // describing clauses and directives for which a list appears. 11325 // OpenMP [2.14.3.3, Restrictions, p.1] 11326 // A variable that is part of another variable (as an array or 11327 // structure element) cannot appear in a private clause. 11328 if (!FirstIter && IR != ER) 11329 ++IR; 11330 FirstIter = false; 11331 SourceLocation ELoc; 11332 SourceRange ERange; 11333 Expr *SimpleRefExpr = RefExpr; 11334 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 11335 /*AllowArraySection=*/true); 11336 if (Res.second) { 11337 // Try to find 'declare reduction' corresponding construct before using 11338 // builtin/overloaded operators. 11339 QualType Type = Context.DependentTy; 11340 CXXCastPath BasePath; 11341 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11342 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11343 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11344 Expr *ReductionOp = nullptr; 11345 if (S.CurContext->isDependentContext() && 11346 (DeclareReductionRef.isUnset() || 11347 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 11348 ReductionOp = DeclareReductionRef.get(); 11349 // It will be analyzed later. 11350 RD.push(RefExpr, ReductionOp); 11351 } 11352 ValueDecl *D = Res.first; 11353 if (!D) 11354 continue; 11355 11356 Expr *TaskgroupDescriptor = nullptr; 11357 QualType Type; 11358 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 11359 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 11360 if (ASE) { 11361 Type = ASE->getType().getNonReferenceType(); 11362 } else if (OASE) { 11363 QualType BaseType = 11364 OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 11365 if (const auto *ATy = BaseType->getAsArrayTypeUnsafe()) 11366 Type = ATy->getElementType(); 11367 else 11368 Type = BaseType->getPointeeType(); 11369 Type = Type.getNonReferenceType(); 11370 } else { 11371 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 11372 } 11373 auto *VD = dyn_cast<VarDecl>(D); 11374 11375 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 11376 // A variable that appears in a private clause must not have an incomplete 11377 // type or a reference type. 11378 if (S.RequireCompleteType(ELoc, D->getType(), 11379 diag::err_omp_reduction_incomplete_type)) 11380 continue; 11381 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11382 // A list item that appears in a reduction clause must not be 11383 // const-qualified. 11384 if (rejectConstNotMutableType(S, D, Type, ClauseKind, ELoc, 11385 /*AcceptIfMutable*/ false, ASE || OASE)) 11386 continue; 11387 11388 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 11389 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 11390 // If a list-item is a reference type then it must bind to the same object 11391 // for all threads of the team. 11392 if (!ASE && !OASE) { 11393 if (VD) { 11394 VarDecl *VDDef = VD->getDefinition(); 11395 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 11396 DSARefChecker Check(Stack); 11397 if (Check.Visit(VDDef->getInit())) { 11398 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 11399 << getOpenMPClauseName(ClauseKind) << ERange; 11400 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 11401 continue; 11402 } 11403 } 11404 } 11405 11406 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 11407 // in a Construct] 11408 // Variables with the predetermined data-sharing attributes may not be 11409 // listed in data-sharing attributes clauses, except for the cases 11410 // listed below. For these exceptions only, listing a predetermined 11411 // variable in a data-sharing attribute clause is allowed and overrides 11412 // the variable's predetermined data-sharing attributes. 11413 // OpenMP [2.14.3.6, Restrictions, p.3] 11414 // Any number of reduction clauses can be specified on the directive, 11415 // but a list item can appear only once in the reduction clauses for that 11416 // directive. 11417 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(D, /*FromParent=*/false); 11418 if (DVar.CKind == OMPC_reduction) { 11419 S.Diag(ELoc, diag::err_omp_once_referenced) 11420 << getOpenMPClauseName(ClauseKind); 11421 if (DVar.RefExpr) 11422 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 11423 continue; 11424 } 11425 if (DVar.CKind != OMPC_unknown) { 11426 S.Diag(ELoc, diag::err_omp_wrong_dsa) 11427 << getOpenMPClauseName(DVar.CKind) 11428 << getOpenMPClauseName(OMPC_reduction); 11429 reportOriginalDsa(S, Stack, D, DVar); 11430 continue; 11431 } 11432 11433 // OpenMP [2.14.3.6, Restrictions, p.1] 11434 // A list item that appears in a reduction clause of a worksharing 11435 // construct must be shared in the parallel regions to which any of the 11436 // worksharing regions arising from the worksharing construct bind. 11437 if (isOpenMPWorksharingDirective(CurrDir) && 11438 !isOpenMPParallelDirective(CurrDir) && 11439 !isOpenMPTeamsDirective(CurrDir)) { 11440 DVar = Stack->getImplicitDSA(D, true); 11441 if (DVar.CKind != OMPC_shared) { 11442 S.Diag(ELoc, diag::err_omp_required_access) 11443 << getOpenMPClauseName(OMPC_reduction) 11444 << getOpenMPClauseName(OMPC_shared); 11445 reportOriginalDsa(S, Stack, D, DVar); 11446 continue; 11447 } 11448 } 11449 } 11450 11451 // Try to find 'declare reduction' corresponding construct before using 11452 // builtin/overloaded operators. 11453 CXXCastPath BasePath; 11454 ExprResult DeclareReductionRef = buildDeclareReductionRef( 11455 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 11456 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 11457 if (DeclareReductionRef.isInvalid()) 11458 continue; 11459 if (S.CurContext->isDependentContext() && 11460 (DeclareReductionRef.isUnset() || 11461 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 11462 RD.push(RefExpr, DeclareReductionRef.get()); 11463 continue; 11464 } 11465 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 11466 // Not allowed reduction identifier is found. 11467 S.Diag(ReductionId.getBeginLoc(), 11468 diag::err_omp_unknown_reduction_identifier) 11469 << Type << ReductionIdRange; 11470 continue; 11471 } 11472 11473 // OpenMP [2.14.3.6, reduction clause, Restrictions] 11474 // The type of a list item that appears in a reduction clause must be valid 11475 // for the reduction-identifier. For a max or min reduction in C, the type 11476 // of the list item must be an allowed arithmetic data type: char, int, 11477 // float, double, or _Bool, possibly modified with long, short, signed, or 11478 // unsigned. For a max or min reduction in C++, the type of the list item 11479 // must be an allowed arithmetic data type: char, wchar_t, int, float, 11480 // double, or bool, possibly modified with long, short, signed, or unsigned. 11481 if (DeclareReductionRef.isUnset()) { 11482 if ((BOK == BO_GT || BOK == BO_LT) && 11483 !(Type->isScalarType() || 11484 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 11485 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 11486 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 11487 if (!ASE && !OASE) { 11488 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11489 VarDecl::DeclarationOnly; 11490 S.Diag(D->getLocation(), 11491 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11492 << D; 11493 } 11494 continue; 11495 } 11496 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 11497 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 11498 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 11499 << getOpenMPClauseName(ClauseKind); 11500 if (!ASE && !OASE) { 11501 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11502 VarDecl::DeclarationOnly; 11503 S.Diag(D->getLocation(), 11504 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11505 << D; 11506 } 11507 continue; 11508 } 11509 } 11510 11511 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 11512 VarDecl *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 11513 D->hasAttrs() ? &D->getAttrs() : nullptr); 11514 VarDecl *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 11515 D->hasAttrs() ? &D->getAttrs() : nullptr); 11516 QualType PrivateTy = Type; 11517 11518 // Try if we can determine constant lengths for all array sections and avoid 11519 // the VLA. 11520 bool ConstantLengthOASE = false; 11521 if (OASE) { 11522 bool SingleElement; 11523 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 11524 ConstantLengthOASE = checkOMPArraySectionConstantForReduction( 11525 Context, OASE, SingleElement, ArraySizes); 11526 11527 // If we don't have a single element, we must emit a constant array type. 11528 if (ConstantLengthOASE && !SingleElement) { 11529 for (llvm::APSInt &Size : ArraySizes) 11530 PrivateTy = Context.getConstantArrayType( 11531 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 11532 } 11533 } 11534 11535 if ((OASE && !ConstantLengthOASE) || 11536 (!OASE && !ASE && 11537 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 11538 if (!Context.getTargetInfo().isVLASupported() && 11539 S.shouldDiagnoseTargetSupportFromOpenMP()) { 11540 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 11541 S.Diag(ELoc, diag::note_vla_unsupported); 11542 continue; 11543 } 11544 // For arrays/array sections only: 11545 // Create pseudo array type for private copy. The size for this array will 11546 // be generated during codegen. 11547 // For array subscripts or single variables Private Ty is the same as Type 11548 // (type of the variable or single array element). 11549 PrivateTy = Context.getVariableArrayType( 11550 Type, 11551 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 11552 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 11553 } else if (!ASE && !OASE && 11554 Context.getAsArrayType(D->getType().getNonReferenceType())) { 11555 PrivateTy = D->getType().getNonReferenceType(); 11556 } 11557 // Private copy. 11558 VarDecl *PrivateVD = 11559 buildVarDecl(S, ELoc, PrivateTy, D->getName(), 11560 D->hasAttrs() ? &D->getAttrs() : nullptr, 11561 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 11562 // Add initializer for private variable. 11563 Expr *Init = nullptr; 11564 DeclRefExpr *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 11565 DeclRefExpr *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 11566 if (DeclareReductionRef.isUsable()) { 11567 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 11568 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 11569 if (DRD->getInitializer()) { 11570 Init = DRDRef; 11571 RHSVD->setInit(DRDRef); 11572 RHSVD->setInitStyle(VarDecl::CallInit); 11573 } 11574 } else { 11575 switch (BOK) { 11576 case BO_Add: 11577 case BO_Xor: 11578 case BO_Or: 11579 case BO_LOr: 11580 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 11581 if (Type->isScalarType() || Type->isAnyComplexType()) 11582 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 11583 break; 11584 case BO_Mul: 11585 case BO_LAnd: 11586 if (Type->isScalarType() || Type->isAnyComplexType()) { 11587 // '*' and '&&' reduction ops - initializer is '1'. 11588 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 11589 } 11590 break; 11591 case BO_And: { 11592 // '&' reduction op - initializer is '~0'. 11593 QualType OrigType = Type; 11594 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 11595 Type = ComplexTy->getElementType(); 11596 if (Type->isRealFloatingType()) { 11597 llvm::APFloat InitValue = 11598 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 11599 /*isIEEE=*/true); 11600 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 11601 Type, ELoc); 11602 } else if (Type->isScalarType()) { 11603 uint64_t Size = Context.getTypeSize(Type); 11604 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 11605 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 11606 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 11607 } 11608 if (Init && OrigType->isAnyComplexType()) { 11609 // Init = 0xFFFF + 0xFFFFi; 11610 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 11611 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 11612 } 11613 Type = OrigType; 11614 break; 11615 } 11616 case BO_LT: 11617 case BO_GT: { 11618 // 'min' reduction op - initializer is 'Largest representable number in 11619 // the reduction list item type'. 11620 // 'max' reduction op - initializer is 'Least representable number in 11621 // the reduction list item type'. 11622 if (Type->isIntegerType() || Type->isPointerType()) { 11623 bool IsSigned = Type->hasSignedIntegerRepresentation(); 11624 uint64_t Size = Context.getTypeSize(Type); 11625 QualType IntTy = 11626 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 11627 llvm::APInt InitValue = 11628 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 11629 : llvm::APInt::getMinValue(Size) 11630 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 11631 : llvm::APInt::getMaxValue(Size); 11632 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 11633 if (Type->isPointerType()) { 11634 // Cast to pointer type. 11635 ExprResult CastExpr = S.BuildCStyleCastExpr( 11636 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 11637 if (CastExpr.isInvalid()) 11638 continue; 11639 Init = CastExpr.get(); 11640 } 11641 } else if (Type->isRealFloatingType()) { 11642 llvm::APFloat InitValue = llvm::APFloat::getLargest( 11643 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 11644 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 11645 Type, ELoc); 11646 } 11647 break; 11648 } 11649 case BO_PtrMemD: 11650 case BO_PtrMemI: 11651 case BO_MulAssign: 11652 case BO_Div: 11653 case BO_Rem: 11654 case BO_Sub: 11655 case BO_Shl: 11656 case BO_Shr: 11657 case BO_LE: 11658 case BO_GE: 11659 case BO_EQ: 11660 case BO_NE: 11661 case BO_Cmp: 11662 case BO_AndAssign: 11663 case BO_XorAssign: 11664 case BO_OrAssign: 11665 case BO_Assign: 11666 case BO_AddAssign: 11667 case BO_SubAssign: 11668 case BO_DivAssign: 11669 case BO_RemAssign: 11670 case BO_ShlAssign: 11671 case BO_ShrAssign: 11672 case BO_Comma: 11673 llvm_unreachable("Unexpected reduction operation"); 11674 } 11675 } 11676 if (Init && DeclareReductionRef.isUnset()) 11677 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 11678 else if (!Init) 11679 S.ActOnUninitializedDecl(RHSVD); 11680 if (RHSVD->isInvalidDecl()) 11681 continue; 11682 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 11683 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 11684 << Type << ReductionIdRange; 11685 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 11686 VarDecl::DeclarationOnly; 11687 S.Diag(D->getLocation(), 11688 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11689 << D; 11690 continue; 11691 } 11692 // Store initializer for single element in private copy. Will be used during 11693 // codegen. 11694 PrivateVD->setInit(RHSVD->getInit()); 11695 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 11696 DeclRefExpr *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 11697 ExprResult ReductionOp; 11698 if (DeclareReductionRef.isUsable()) { 11699 QualType RedTy = DeclareReductionRef.get()->getType(); 11700 QualType PtrRedTy = Context.getPointerType(RedTy); 11701 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 11702 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 11703 if (!BasePath.empty()) { 11704 LHS = S.DefaultLvalueConversion(LHS.get()); 11705 RHS = S.DefaultLvalueConversion(RHS.get()); 11706 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 11707 CK_UncheckedDerivedToBase, LHS.get(), 11708 &BasePath, LHS.get()->getValueKind()); 11709 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 11710 CK_UncheckedDerivedToBase, RHS.get(), 11711 &BasePath, RHS.get()->getValueKind()); 11712 } 11713 FunctionProtoType::ExtProtoInfo EPI; 11714 QualType Params[] = {PtrRedTy, PtrRedTy}; 11715 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 11716 auto *OVE = new (Context) OpaqueValueExpr( 11717 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 11718 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 11719 Expr *Args[] = {LHS.get(), RHS.get()}; 11720 ReductionOp = 11721 CallExpr::Create(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 11722 } else { 11723 ReductionOp = S.BuildBinOp( 11724 Stack->getCurScope(), ReductionId.getBeginLoc(), BOK, LHSDRE, RHSDRE); 11725 if (ReductionOp.isUsable()) { 11726 if (BOK != BO_LT && BOK != BO_GT) { 11727 ReductionOp = 11728 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 11729 BO_Assign, LHSDRE, ReductionOp.get()); 11730 } else { 11731 auto *ConditionalOp = new (Context) 11732 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 11733 Type, VK_LValue, OK_Ordinary); 11734 ReductionOp = 11735 S.BuildBinOp(Stack->getCurScope(), ReductionId.getBeginLoc(), 11736 BO_Assign, LHSDRE, ConditionalOp); 11737 } 11738 if (ReductionOp.isUsable()) 11739 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get(), 11740 /*DiscardedValue*/ false); 11741 } 11742 if (!ReductionOp.isUsable()) 11743 continue; 11744 } 11745 11746 // OpenMP [2.15.4.6, Restrictions, p.2] 11747 // A list item that appears in an in_reduction clause of a task construct 11748 // must appear in a task_reduction clause of a construct associated with a 11749 // taskgroup region that includes the participating task in its taskgroup 11750 // set. The construct associated with the innermost region that meets this 11751 // condition must specify the same reduction-identifier as the in_reduction 11752 // clause. 11753 if (ClauseKind == OMPC_in_reduction) { 11754 SourceRange ParentSR; 11755 BinaryOperatorKind ParentBOK; 11756 const Expr *ParentReductionOp; 11757 Expr *ParentBOKTD, *ParentReductionOpTD; 11758 DSAStackTy::DSAVarData ParentBOKDSA = 11759 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 11760 ParentBOKTD); 11761 DSAStackTy::DSAVarData ParentReductionOpDSA = 11762 Stack->getTopMostTaskgroupReductionData( 11763 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 11764 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 11765 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 11766 if (!IsParentBOK && !IsParentReductionOp) { 11767 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 11768 continue; 11769 } 11770 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 11771 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 11772 IsParentReductionOp) { 11773 bool EmitError = true; 11774 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 11775 llvm::FoldingSetNodeID RedId, ParentRedId; 11776 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 11777 DeclareReductionRef.get()->Profile(RedId, Context, 11778 /*Canonical=*/true); 11779 EmitError = RedId != ParentRedId; 11780 } 11781 if (EmitError) { 11782 S.Diag(ReductionId.getBeginLoc(), 11783 diag::err_omp_reduction_identifier_mismatch) 11784 << ReductionIdRange << RefExpr->getSourceRange(); 11785 S.Diag(ParentSR.getBegin(), 11786 diag::note_omp_previous_reduction_identifier) 11787 << ParentSR 11788 << (IsParentBOK ? ParentBOKDSA.RefExpr 11789 : ParentReductionOpDSA.RefExpr) 11790 ->getSourceRange(); 11791 continue; 11792 } 11793 } 11794 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 11795 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 11796 } 11797 11798 DeclRefExpr *Ref = nullptr; 11799 Expr *VarsExpr = RefExpr->IgnoreParens(); 11800 if (!VD && !S.CurContext->isDependentContext()) { 11801 if (ASE || OASE) { 11802 TransformExprToCaptures RebuildToCapture(S, D); 11803 VarsExpr = 11804 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 11805 Ref = RebuildToCapture.getCapturedExpr(); 11806 } else { 11807 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 11808 } 11809 if (!S.isOpenMPCapturedDecl(D)) { 11810 RD.ExprCaptures.emplace_back(Ref->getDecl()); 11811 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 11812 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 11813 if (!RefRes.isUsable()) 11814 continue; 11815 ExprResult PostUpdateRes = 11816 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 11817 RefRes.get()); 11818 if (!PostUpdateRes.isUsable()) 11819 continue; 11820 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 11821 Stack->getCurrentDirective() == OMPD_taskgroup) { 11822 S.Diag(RefExpr->getExprLoc(), 11823 diag::err_omp_reduction_non_addressable_expression) 11824 << RefExpr->getSourceRange(); 11825 continue; 11826 } 11827 RD.ExprPostUpdates.emplace_back( 11828 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 11829 } 11830 } 11831 } 11832 // All reduction items are still marked as reduction (to do not increase 11833 // code base size). 11834 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 11835 if (CurrDir == OMPD_taskgroup) { 11836 if (DeclareReductionRef.isUsable()) 11837 Stack->addTaskgroupReductionData(D, ReductionIdRange, 11838 DeclareReductionRef.get()); 11839 else 11840 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 11841 } 11842 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 11843 TaskgroupDescriptor); 11844 } 11845 return RD.Vars.empty(); 11846 } 11847 11848 OMPClause *Sema::ActOnOpenMPReductionClause( 11849 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11850 SourceLocation ColonLoc, SourceLocation EndLoc, 11851 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11852 ArrayRef<Expr *> UnresolvedReductions) { 11853 ReductionData RD(VarList.size()); 11854 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 11855 StartLoc, LParenLoc, ColonLoc, EndLoc, 11856 ReductionIdScopeSpec, ReductionId, 11857 UnresolvedReductions, RD)) 11858 return nullptr; 11859 11860 return OMPReductionClause::Create( 11861 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11862 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11863 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 11864 buildPreInits(Context, RD.ExprCaptures), 11865 buildPostUpdate(*this, RD.ExprPostUpdates)); 11866 } 11867 11868 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 11869 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11870 SourceLocation ColonLoc, SourceLocation EndLoc, 11871 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11872 ArrayRef<Expr *> UnresolvedReductions) { 11873 ReductionData RD(VarList.size()); 11874 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, VarList, 11875 StartLoc, LParenLoc, ColonLoc, EndLoc, 11876 ReductionIdScopeSpec, ReductionId, 11877 UnresolvedReductions, RD)) 11878 return nullptr; 11879 11880 return OMPTaskReductionClause::Create( 11881 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11882 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11883 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 11884 buildPreInits(Context, RD.ExprCaptures), 11885 buildPostUpdate(*this, RD.ExprPostUpdates)); 11886 } 11887 11888 OMPClause *Sema::ActOnOpenMPInReductionClause( 11889 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 11890 SourceLocation ColonLoc, SourceLocation EndLoc, 11891 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 11892 ArrayRef<Expr *> UnresolvedReductions) { 11893 ReductionData RD(VarList.size()); 11894 if (actOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 11895 StartLoc, LParenLoc, ColonLoc, EndLoc, 11896 ReductionIdScopeSpec, ReductionId, 11897 UnresolvedReductions, RD)) 11898 return nullptr; 11899 11900 return OMPInReductionClause::Create( 11901 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 11902 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 11903 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 11904 buildPreInits(Context, RD.ExprCaptures), 11905 buildPostUpdate(*this, RD.ExprPostUpdates)); 11906 } 11907 11908 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 11909 SourceLocation LinLoc) { 11910 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 11911 LinKind == OMPC_LINEAR_unknown) { 11912 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 11913 return true; 11914 } 11915 return false; 11916 } 11917 11918 bool Sema::CheckOpenMPLinearDecl(const ValueDecl *D, SourceLocation ELoc, 11919 OpenMPLinearClauseKind LinKind, 11920 QualType Type) { 11921 const auto *VD = dyn_cast_or_null<VarDecl>(D); 11922 // A variable must not have an incomplete type or a reference type. 11923 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 11924 return true; 11925 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 11926 !Type->isReferenceType()) { 11927 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 11928 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 11929 return true; 11930 } 11931 Type = Type.getNonReferenceType(); 11932 11933 // OpenMP 5.0 [2.19.3, List Item Privatization, Restrictions] 11934 // A variable that is privatized must not have a const-qualified type 11935 // unless it is of class type with a mutable member. This restriction does 11936 // not apply to the firstprivate clause. 11937 if (rejectConstNotMutableType(*this, D, Type, OMPC_linear, ELoc)) 11938 return true; 11939 11940 // A list item must be of integral or pointer type. 11941 Type = Type.getUnqualifiedType().getCanonicalType(); 11942 const auto *Ty = Type.getTypePtrOrNull(); 11943 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 11944 !Ty->isPointerType())) { 11945 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 11946 if (D) { 11947 bool IsDecl = 11948 !VD || 11949 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11950 Diag(D->getLocation(), 11951 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11952 << D; 11953 } 11954 return true; 11955 } 11956 return false; 11957 } 11958 11959 OMPClause *Sema::ActOnOpenMPLinearClause( 11960 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 11961 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 11962 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 11963 SmallVector<Expr *, 8> Vars; 11964 SmallVector<Expr *, 8> Privates; 11965 SmallVector<Expr *, 8> Inits; 11966 SmallVector<Decl *, 4> ExprCaptures; 11967 SmallVector<Expr *, 4> ExprPostUpdates; 11968 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 11969 LinKind = OMPC_LINEAR_val; 11970 for (Expr *RefExpr : VarList) { 11971 assert(RefExpr && "NULL expr in OpenMP linear clause."); 11972 SourceLocation ELoc; 11973 SourceRange ERange; 11974 Expr *SimpleRefExpr = RefExpr; 11975 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11976 if (Res.second) { 11977 // It will be analyzed later. 11978 Vars.push_back(RefExpr); 11979 Privates.push_back(nullptr); 11980 Inits.push_back(nullptr); 11981 } 11982 ValueDecl *D = Res.first; 11983 if (!D) 11984 continue; 11985 11986 QualType Type = D->getType(); 11987 auto *VD = dyn_cast<VarDecl>(D); 11988 11989 // OpenMP [2.14.3.7, linear clause] 11990 // A list-item cannot appear in more than one linear clause. 11991 // A list-item that appears in a linear clause cannot appear in any 11992 // other data-sharing attribute clause. 11993 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 11994 if (DVar.RefExpr) { 11995 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 11996 << getOpenMPClauseName(OMPC_linear); 11997 reportOriginalDsa(*this, DSAStack, D, DVar); 11998 continue; 11999 } 12000 12001 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 12002 continue; 12003 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12004 12005 // Build private copy of original var. 12006 VarDecl *Private = 12007 buildVarDecl(*this, ELoc, Type, D->getName(), 12008 D->hasAttrs() ? &D->getAttrs() : nullptr, 12009 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 12010 DeclRefExpr *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 12011 // Build var to save initial value. 12012 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 12013 Expr *InitExpr; 12014 DeclRefExpr *Ref = nullptr; 12015 if (!VD && !CurContext->isDependentContext()) { 12016 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 12017 if (!isOpenMPCapturedDecl(D)) { 12018 ExprCaptures.push_back(Ref->getDecl()); 12019 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 12020 ExprResult RefRes = DefaultLvalueConversion(Ref); 12021 if (!RefRes.isUsable()) 12022 continue; 12023 ExprResult PostUpdateRes = 12024 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 12025 SimpleRefExpr, RefRes.get()); 12026 if (!PostUpdateRes.isUsable()) 12027 continue; 12028 ExprPostUpdates.push_back( 12029 IgnoredValueConversions(PostUpdateRes.get()).get()); 12030 } 12031 } 12032 } 12033 if (LinKind == OMPC_LINEAR_uval) 12034 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 12035 else 12036 InitExpr = VD ? SimpleRefExpr : Ref; 12037 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 12038 /*DirectInit=*/false); 12039 DeclRefExpr *InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 12040 12041 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 12042 Vars.push_back((VD || CurContext->isDependentContext()) 12043 ? RefExpr->IgnoreParens() 12044 : Ref); 12045 Privates.push_back(PrivateRef); 12046 Inits.push_back(InitRef); 12047 } 12048 12049 if (Vars.empty()) 12050 return nullptr; 12051 12052 Expr *StepExpr = Step; 12053 Expr *CalcStepExpr = nullptr; 12054 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 12055 !Step->isInstantiationDependent() && 12056 !Step->containsUnexpandedParameterPack()) { 12057 SourceLocation StepLoc = Step->getBeginLoc(); 12058 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 12059 if (Val.isInvalid()) 12060 return nullptr; 12061 StepExpr = Val.get(); 12062 12063 // Build var to save the step value. 12064 VarDecl *SaveVar = 12065 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 12066 ExprResult SaveRef = 12067 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 12068 ExprResult CalcStep = 12069 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 12070 CalcStep = ActOnFinishFullExpr(CalcStep.get(), /*DiscardedValue*/ false); 12071 12072 // Warn about zero linear step (it would be probably better specified as 12073 // making corresponding variables 'const'). 12074 llvm::APSInt Result; 12075 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 12076 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 12077 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 12078 << (Vars.size() > 1); 12079 if (!IsConstant && CalcStep.isUsable()) { 12080 // Calculate the step beforehand instead of doing this on each iteration. 12081 // (This is not used if the number of iterations may be kfold-ed). 12082 CalcStepExpr = CalcStep.get(); 12083 } 12084 } 12085 12086 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 12087 ColonLoc, EndLoc, Vars, Privates, Inits, 12088 StepExpr, CalcStepExpr, 12089 buildPreInits(Context, ExprCaptures), 12090 buildPostUpdate(*this, ExprPostUpdates)); 12091 } 12092 12093 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 12094 Expr *NumIterations, Sema &SemaRef, 12095 Scope *S, DSAStackTy *Stack) { 12096 // Walk the vars and build update/final expressions for the CodeGen. 12097 SmallVector<Expr *, 8> Updates; 12098 SmallVector<Expr *, 8> Finals; 12099 Expr *Step = Clause.getStep(); 12100 Expr *CalcStep = Clause.getCalcStep(); 12101 // OpenMP [2.14.3.7, linear clause] 12102 // If linear-step is not specified it is assumed to be 1. 12103 if (!Step) 12104 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 12105 else if (CalcStep) 12106 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 12107 bool HasErrors = false; 12108 auto CurInit = Clause.inits().begin(); 12109 auto CurPrivate = Clause.privates().begin(); 12110 OpenMPLinearClauseKind LinKind = Clause.getModifier(); 12111 for (Expr *RefExpr : Clause.varlists()) { 12112 SourceLocation ELoc; 12113 SourceRange ERange; 12114 Expr *SimpleRefExpr = RefExpr; 12115 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange); 12116 ValueDecl *D = Res.first; 12117 if (Res.second || !D) { 12118 Updates.push_back(nullptr); 12119 Finals.push_back(nullptr); 12120 HasErrors = true; 12121 continue; 12122 } 12123 auto &&Info = Stack->isLoopControlVariable(D); 12124 // OpenMP [2.15.11, distribute simd Construct] 12125 // A list item may not appear in a linear clause, unless it is the loop 12126 // iteration variable. 12127 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 12128 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 12129 SemaRef.Diag(ELoc, 12130 diag::err_omp_linear_distribute_var_non_loop_iteration); 12131 Updates.push_back(nullptr); 12132 Finals.push_back(nullptr); 12133 HasErrors = true; 12134 continue; 12135 } 12136 Expr *InitExpr = *CurInit; 12137 12138 // Build privatized reference to the current linear var. 12139 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 12140 Expr *CapturedRef; 12141 if (LinKind == OMPC_LINEAR_uval) 12142 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 12143 else 12144 CapturedRef = 12145 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 12146 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 12147 /*RefersToCapture=*/true); 12148 12149 // Build update: Var = InitExpr + IV * Step 12150 ExprResult Update; 12151 if (!Info.first) 12152 Update = 12153 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 12154 InitExpr, IV, Step, /* Subtract */ false); 12155 else 12156 Update = *CurPrivate; 12157 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getBeginLoc(), 12158 /*DiscardedValue*/ false); 12159 12160 // Build final: Var = InitExpr + NumIterations * Step 12161 ExprResult Final; 12162 if (!Info.first) 12163 Final = 12164 buildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 12165 InitExpr, NumIterations, Step, /*Subtract=*/false); 12166 else 12167 Final = *CurPrivate; 12168 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getBeginLoc(), 12169 /*DiscardedValue*/ false); 12170 12171 if (!Update.isUsable() || !Final.isUsable()) { 12172 Updates.push_back(nullptr); 12173 Finals.push_back(nullptr); 12174 HasErrors = true; 12175 } else { 12176 Updates.push_back(Update.get()); 12177 Finals.push_back(Final.get()); 12178 } 12179 ++CurInit; 12180 ++CurPrivate; 12181 } 12182 Clause.setUpdates(Updates); 12183 Clause.setFinals(Finals); 12184 return HasErrors; 12185 } 12186 12187 OMPClause *Sema::ActOnOpenMPAlignedClause( 12188 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 12189 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 12190 SmallVector<Expr *, 8> Vars; 12191 for (Expr *RefExpr : VarList) { 12192 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12193 SourceLocation ELoc; 12194 SourceRange ERange; 12195 Expr *SimpleRefExpr = RefExpr; 12196 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12197 if (Res.second) { 12198 // It will be analyzed later. 12199 Vars.push_back(RefExpr); 12200 } 12201 ValueDecl *D = Res.first; 12202 if (!D) 12203 continue; 12204 12205 QualType QType = D->getType(); 12206 auto *VD = dyn_cast<VarDecl>(D); 12207 12208 // OpenMP [2.8.1, simd construct, Restrictions] 12209 // The type of list items appearing in the aligned clause must be 12210 // array, pointer, reference to array, or reference to pointer. 12211 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 12212 const Type *Ty = QType.getTypePtrOrNull(); 12213 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 12214 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 12215 << QType << getLangOpts().CPlusPlus << ERange; 12216 bool IsDecl = 12217 !VD || 12218 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12219 Diag(D->getLocation(), 12220 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12221 << D; 12222 continue; 12223 } 12224 12225 // OpenMP [2.8.1, simd construct, Restrictions] 12226 // A list-item cannot appear in more than one aligned clause. 12227 if (const Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 12228 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 12229 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 12230 << getOpenMPClauseName(OMPC_aligned); 12231 continue; 12232 } 12233 12234 DeclRefExpr *Ref = nullptr; 12235 if (!VD && isOpenMPCapturedDecl(D)) 12236 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12237 Vars.push_back(DefaultFunctionArrayConversion( 12238 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 12239 .get()); 12240 } 12241 12242 // OpenMP [2.8.1, simd construct, Description] 12243 // The parameter of the aligned clause, alignment, must be a constant 12244 // positive integer expression. 12245 // If no optional parameter is specified, implementation-defined default 12246 // alignments for SIMD instructions on the target platforms are assumed. 12247 if (Alignment != nullptr) { 12248 ExprResult AlignResult = 12249 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 12250 if (AlignResult.isInvalid()) 12251 return nullptr; 12252 Alignment = AlignResult.get(); 12253 } 12254 if (Vars.empty()) 12255 return nullptr; 12256 12257 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 12258 EndLoc, Vars, Alignment); 12259 } 12260 12261 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 12262 SourceLocation StartLoc, 12263 SourceLocation LParenLoc, 12264 SourceLocation EndLoc) { 12265 SmallVector<Expr *, 8> Vars; 12266 SmallVector<Expr *, 8> SrcExprs; 12267 SmallVector<Expr *, 8> DstExprs; 12268 SmallVector<Expr *, 8> AssignmentOps; 12269 for (Expr *RefExpr : VarList) { 12270 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 12271 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12272 // It will be analyzed later. 12273 Vars.push_back(RefExpr); 12274 SrcExprs.push_back(nullptr); 12275 DstExprs.push_back(nullptr); 12276 AssignmentOps.push_back(nullptr); 12277 continue; 12278 } 12279 12280 SourceLocation ELoc = RefExpr->getExprLoc(); 12281 // OpenMP [2.1, C/C++] 12282 // A list item is a variable name. 12283 // OpenMP [2.14.4.1, Restrictions, p.1] 12284 // A list item that appears in a copyin clause must be threadprivate. 12285 auto *DE = dyn_cast<DeclRefExpr>(RefExpr); 12286 if (!DE || !isa<VarDecl>(DE->getDecl())) { 12287 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 12288 << 0 << RefExpr->getSourceRange(); 12289 continue; 12290 } 12291 12292 Decl *D = DE->getDecl(); 12293 auto *VD = cast<VarDecl>(D); 12294 12295 QualType Type = VD->getType(); 12296 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 12297 // It will be analyzed later. 12298 Vars.push_back(DE); 12299 SrcExprs.push_back(nullptr); 12300 DstExprs.push_back(nullptr); 12301 AssignmentOps.push_back(nullptr); 12302 continue; 12303 } 12304 12305 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 12306 // A list item that appears in a copyin clause must be threadprivate. 12307 if (!DSAStack->isThreadPrivate(VD)) { 12308 Diag(ELoc, diag::err_omp_required_access) 12309 << getOpenMPClauseName(OMPC_copyin) 12310 << getOpenMPDirectiveName(OMPD_threadprivate); 12311 continue; 12312 } 12313 12314 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12315 // A variable of class type (or array thereof) that appears in a 12316 // copyin clause requires an accessible, unambiguous copy assignment 12317 // operator for the class type. 12318 QualType ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 12319 VarDecl *SrcVD = 12320 buildVarDecl(*this, DE->getBeginLoc(), ElemType.getUnqualifiedType(), 12321 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12322 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr( 12323 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 12324 VarDecl *DstVD = 12325 buildVarDecl(*this, DE->getBeginLoc(), ElemType, ".copyin.dst", 12326 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 12327 DeclRefExpr *PseudoDstExpr = 12328 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 12329 // For arrays generate assignment operation for single element and replace 12330 // it by the original array element in CodeGen. 12331 ExprResult AssignmentOp = 12332 BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, PseudoDstExpr, 12333 PseudoSrcExpr); 12334 if (AssignmentOp.isInvalid()) 12335 continue; 12336 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 12337 /*DiscardedValue*/ false); 12338 if (AssignmentOp.isInvalid()) 12339 continue; 12340 12341 DSAStack->addDSA(VD, DE, OMPC_copyin); 12342 Vars.push_back(DE); 12343 SrcExprs.push_back(PseudoSrcExpr); 12344 DstExprs.push_back(PseudoDstExpr); 12345 AssignmentOps.push_back(AssignmentOp.get()); 12346 } 12347 12348 if (Vars.empty()) 12349 return nullptr; 12350 12351 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 12352 SrcExprs, DstExprs, AssignmentOps); 12353 } 12354 12355 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 12356 SourceLocation StartLoc, 12357 SourceLocation LParenLoc, 12358 SourceLocation EndLoc) { 12359 SmallVector<Expr *, 8> Vars; 12360 SmallVector<Expr *, 8> SrcExprs; 12361 SmallVector<Expr *, 8> DstExprs; 12362 SmallVector<Expr *, 8> AssignmentOps; 12363 for (Expr *RefExpr : VarList) { 12364 assert(RefExpr && "NULL expr in OpenMP linear clause."); 12365 SourceLocation ELoc; 12366 SourceRange ERange; 12367 Expr *SimpleRefExpr = RefExpr; 12368 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12369 if (Res.second) { 12370 // It will be analyzed later. 12371 Vars.push_back(RefExpr); 12372 SrcExprs.push_back(nullptr); 12373 DstExprs.push_back(nullptr); 12374 AssignmentOps.push_back(nullptr); 12375 } 12376 ValueDecl *D = Res.first; 12377 if (!D) 12378 continue; 12379 12380 QualType Type = D->getType(); 12381 auto *VD = dyn_cast<VarDecl>(D); 12382 12383 // OpenMP [2.14.4.2, Restrictions, p.2] 12384 // A list item that appears in a copyprivate clause may not appear in a 12385 // private or firstprivate clause on the single construct. 12386 if (!VD || !DSAStack->isThreadPrivate(VD)) { 12387 DSAStackTy::DSAVarData DVar = 12388 DSAStack->getTopDSA(D, /*FromParent=*/false); 12389 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 12390 DVar.RefExpr) { 12391 Diag(ELoc, diag::err_omp_wrong_dsa) 12392 << getOpenMPClauseName(DVar.CKind) 12393 << getOpenMPClauseName(OMPC_copyprivate); 12394 reportOriginalDsa(*this, DSAStack, D, DVar); 12395 continue; 12396 } 12397 12398 // OpenMP [2.11.4.2, Restrictions, p.1] 12399 // All list items that appear in a copyprivate clause must be either 12400 // threadprivate or private in the enclosing context. 12401 if (DVar.CKind == OMPC_unknown) { 12402 DVar = DSAStack->getImplicitDSA(D, false); 12403 if (DVar.CKind == OMPC_shared) { 12404 Diag(ELoc, diag::err_omp_required_access) 12405 << getOpenMPClauseName(OMPC_copyprivate) 12406 << "threadprivate or private in the enclosing context"; 12407 reportOriginalDsa(*this, DSAStack, D, DVar); 12408 continue; 12409 } 12410 } 12411 } 12412 12413 // Variably modified types are not supported. 12414 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 12415 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 12416 << getOpenMPClauseName(OMPC_copyprivate) << Type 12417 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12418 bool IsDecl = 12419 !VD || 12420 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 12421 Diag(D->getLocation(), 12422 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 12423 << D; 12424 continue; 12425 } 12426 12427 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 12428 // A variable of class type (or array thereof) that appears in a 12429 // copyin clause requires an accessible, unambiguous copy assignment 12430 // operator for the class type. 12431 Type = Context.getBaseElementType(Type.getNonReferenceType()) 12432 .getUnqualifiedType(); 12433 VarDecl *SrcVD = 12434 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.src", 12435 D->hasAttrs() ? &D->getAttrs() : nullptr); 12436 DeclRefExpr *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 12437 VarDecl *DstVD = 12438 buildVarDecl(*this, RefExpr->getBeginLoc(), Type, ".copyprivate.dst", 12439 D->hasAttrs() ? &D->getAttrs() : nullptr); 12440 DeclRefExpr *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 12441 ExprResult AssignmentOp = BuildBinOp( 12442 DSAStack->getCurScope(), ELoc, BO_Assign, PseudoDstExpr, PseudoSrcExpr); 12443 if (AssignmentOp.isInvalid()) 12444 continue; 12445 AssignmentOp = 12446 ActOnFinishFullExpr(AssignmentOp.get(), ELoc, /*DiscardedValue*/ false); 12447 if (AssignmentOp.isInvalid()) 12448 continue; 12449 12450 // No need to mark vars as copyprivate, they are already threadprivate or 12451 // implicitly private. 12452 assert(VD || isOpenMPCapturedDecl(D)); 12453 Vars.push_back( 12454 VD ? RefExpr->IgnoreParens() 12455 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 12456 SrcExprs.push_back(PseudoSrcExpr); 12457 DstExprs.push_back(PseudoDstExpr); 12458 AssignmentOps.push_back(AssignmentOp.get()); 12459 } 12460 12461 if (Vars.empty()) 12462 return nullptr; 12463 12464 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12465 Vars, SrcExprs, DstExprs, AssignmentOps); 12466 } 12467 12468 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 12469 SourceLocation StartLoc, 12470 SourceLocation LParenLoc, 12471 SourceLocation EndLoc) { 12472 if (VarList.empty()) 12473 return nullptr; 12474 12475 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 12476 } 12477 12478 OMPClause * 12479 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 12480 SourceLocation DepLoc, SourceLocation ColonLoc, 12481 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 12482 SourceLocation LParenLoc, SourceLocation EndLoc) { 12483 if (DSAStack->getCurrentDirective() == OMPD_ordered && 12484 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 12485 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 12486 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 12487 return nullptr; 12488 } 12489 if (DSAStack->getCurrentDirective() != OMPD_ordered && 12490 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 12491 DepKind == OMPC_DEPEND_sink)) { 12492 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 12493 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 12494 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 12495 /*Last=*/OMPC_DEPEND_unknown, Except) 12496 << getOpenMPClauseName(OMPC_depend); 12497 return nullptr; 12498 } 12499 SmallVector<Expr *, 8> Vars; 12500 DSAStackTy::OperatorOffsetTy OpsOffs; 12501 llvm::APSInt DepCounter(/*BitWidth=*/32); 12502 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 12503 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) { 12504 if (const Expr *OrderedCountExpr = 12505 DSAStack->getParentOrderedRegionParam().first) { 12506 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 12507 TotalDepCount.setIsUnsigned(/*Val=*/true); 12508 } 12509 } 12510 for (Expr *RefExpr : VarList) { 12511 assert(RefExpr && "NULL expr in OpenMP shared clause."); 12512 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 12513 // It will be analyzed later. 12514 Vars.push_back(RefExpr); 12515 continue; 12516 } 12517 12518 SourceLocation ELoc = RefExpr->getExprLoc(); 12519 Expr *SimpleExpr = RefExpr->IgnoreParenCasts(); 12520 if (DepKind == OMPC_DEPEND_sink) { 12521 if (DSAStack->getParentOrderedRegionParam().first && 12522 DepCounter >= TotalDepCount) { 12523 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 12524 continue; 12525 } 12526 ++DepCounter; 12527 // OpenMP [2.13.9, Summary] 12528 // depend(dependence-type : vec), where dependence-type is: 12529 // 'sink' and where vec is the iteration vector, which has the form: 12530 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 12531 // where n is the value specified by the ordered clause in the loop 12532 // directive, xi denotes the loop iteration variable of the i-th nested 12533 // loop associated with the loop directive, and di is a constant 12534 // non-negative integer. 12535 if (CurContext->isDependentContext()) { 12536 // It will be analyzed later. 12537 Vars.push_back(RefExpr); 12538 continue; 12539 } 12540 SimpleExpr = SimpleExpr->IgnoreImplicit(); 12541 OverloadedOperatorKind OOK = OO_None; 12542 SourceLocation OOLoc; 12543 Expr *LHS = SimpleExpr; 12544 Expr *RHS = nullptr; 12545 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 12546 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 12547 OOLoc = BO->getOperatorLoc(); 12548 LHS = BO->getLHS()->IgnoreParenImpCasts(); 12549 RHS = BO->getRHS()->IgnoreParenImpCasts(); 12550 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 12551 OOK = OCE->getOperator(); 12552 OOLoc = OCE->getOperatorLoc(); 12553 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 12554 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 12555 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 12556 OOK = MCE->getMethodDecl() 12557 ->getNameInfo() 12558 .getName() 12559 .getCXXOverloadedOperator(); 12560 OOLoc = MCE->getCallee()->getExprLoc(); 12561 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 12562 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 12563 } 12564 SourceLocation ELoc; 12565 SourceRange ERange; 12566 auto Res = getPrivateItem(*this, LHS, ELoc, ERange); 12567 if (Res.second) { 12568 // It will be analyzed later. 12569 Vars.push_back(RefExpr); 12570 } 12571 ValueDecl *D = Res.first; 12572 if (!D) 12573 continue; 12574 12575 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 12576 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 12577 continue; 12578 } 12579 if (RHS) { 12580 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 12581 RHS, OMPC_depend, /*StrictlyPositive=*/false); 12582 if (RHSRes.isInvalid()) 12583 continue; 12584 } 12585 if (!CurContext->isDependentContext() && 12586 DSAStack->getParentOrderedRegionParam().first && 12587 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 12588 const ValueDecl *VD = 12589 DSAStack->getParentLoopControlVariable(DepCounter.getZExtValue()); 12590 if (VD) 12591 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 12592 << 1 << VD; 12593 else 12594 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 12595 continue; 12596 } 12597 OpsOffs.emplace_back(RHS, OOK); 12598 } else { 12599 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 12600 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 12601 (ASE && 12602 !ASE->getBase()->getType().getNonReferenceType()->isPointerType() && 12603 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 12604 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 12605 << RefExpr->getSourceRange(); 12606 continue; 12607 } 12608 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 12609 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 12610 ExprResult Res = 12611 CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RefExpr->IgnoreParenImpCasts()); 12612 getDiagnostics().setSuppressAllDiagnostics(Suppress); 12613 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 12614 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 12615 << RefExpr->getSourceRange(); 12616 continue; 12617 } 12618 } 12619 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 12620 } 12621 12622 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 12623 TotalDepCount > VarList.size() && 12624 DSAStack->getParentOrderedRegionParam().first && 12625 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 12626 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 12627 << 1 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 12628 } 12629 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 12630 Vars.empty()) 12631 return nullptr; 12632 12633 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12634 DepKind, DepLoc, ColonLoc, Vars, 12635 TotalDepCount.getZExtValue()); 12636 if ((DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) && 12637 DSAStack->isParentOrderedRegion()) 12638 DSAStack->addDoacrossDependClause(C, OpsOffs); 12639 return C; 12640 } 12641 12642 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 12643 SourceLocation LParenLoc, 12644 SourceLocation EndLoc) { 12645 Expr *ValExpr = Device; 12646 Stmt *HelperValStmt = nullptr; 12647 12648 // OpenMP [2.9.1, Restrictions] 12649 // The device expression must evaluate to a non-negative integer value. 12650 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 12651 /*StrictlyPositive=*/false)) 12652 return nullptr; 12653 12654 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12655 OpenMPDirectiveKind CaptureRegion = 12656 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 12657 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12658 ValExpr = MakeFullExpr(ValExpr).get(); 12659 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 12660 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12661 HelperValStmt = buildPreInits(Context, Captures); 12662 } 12663 12664 return new (Context) OMPDeviceClause(ValExpr, HelperValStmt, CaptureRegion, 12665 StartLoc, LParenLoc, EndLoc); 12666 } 12667 12668 static bool checkTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 12669 DSAStackTy *Stack, QualType QTy, 12670 bool FullCheck = true) { 12671 NamedDecl *ND; 12672 if (QTy->isIncompleteType(&ND)) { 12673 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 12674 return false; 12675 } 12676 if (FullCheck && !SemaRef.CurContext->isDependentContext() && 12677 !QTy.isTrivialType(SemaRef.Context)) 12678 SemaRef.Diag(SL, diag::warn_omp_non_trivial_type_mapped) << QTy << SR; 12679 return true; 12680 } 12681 12682 /// Return true if it can be proven that the provided array expression 12683 /// (array section or array subscript) does NOT specify the whole size of the 12684 /// array whose base type is \a BaseQTy. 12685 static bool checkArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 12686 const Expr *E, 12687 QualType BaseQTy) { 12688 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 12689 12690 // If this is an array subscript, it refers to the whole size if the size of 12691 // the dimension is constant and equals 1. Also, an array section assumes the 12692 // format of an array subscript if no colon is used. 12693 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 12694 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 12695 return ATy->getSize().getSExtValue() != 1; 12696 // Size can't be evaluated statically. 12697 return false; 12698 } 12699 12700 assert(OASE && "Expecting array section if not an array subscript."); 12701 const Expr *LowerBound = OASE->getLowerBound(); 12702 const Expr *Length = OASE->getLength(); 12703 12704 // If there is a lower bound that does not evaluates to zero, we are not 12705 // covering the whole dimension. 12706 if (LowerBound) { 12707 Expr::EvalResult Result; 12708 if (!LowerBound->EvaluateAsInt(Result, SemaRef.getASTContext())) 12709 return false; // Can't get the integer value as a constant. 12710 12711 llvm::APSInt ConstLowerBound = Result.Val.getInt(); 12712 if (ConstLowerBound.getSExtValue()) 12713 return true; 12714 } 12715 12716 // If we don't have a length we covering the whole dimension. 12717 if (!Length) 12718 return false; 12719 12720 // If the base is a pointer, we don't have a way to get the size of the 12721 // pointee. 12722 if (BaseQTy->isPointerType()) 12723 return false; 12724 12725 // We can only check if the length is the same as the size of the dimension 12726 // if we have a constant array. 12727 const auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 12728 if (!CATy) 12729 return false; 12730 12731 Expr::EvalResult Result; 12732 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 12733 return false; // Can't get the integer value as a constant. 12734 12735 llvm::APSInt ConstLength = Result.Val.getInt(); 12736 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 12737 } 12738 12739 // Return true if it can be proven that the provided array expression (array 12740 // section or array subscript) does NOT specify a single element of the array 12741 // whose base type is \a BaseQTy. 12742 static bool checkArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 12743 const Expr *E, 12744 QualType BaseQTy) { 12745 const auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 12746 12747 // An array subscript always refer to a single element. Also, an array section 12748 // assumes the format of an array subscript if no colon is used. 12749 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 12750 return false; 12751 12752 assert(OASE && "Expecting array section if not an array subscript."); 12753 const Expr *Length = OASE->getLength(); 12754 12755 // If we don't have a length we have to check if the array has unitary size 12756 // for this dimension. Also, we should always expect a length if the base type 12757 // is pointer. 12758 if (!Length) { 12759 if (const auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 12760 return ATy->getSize().getSExtValue() != 1; 12761 // We cannot assume anything. 12762 return false; 12763 } 12764 12765 // Check if the length evaluates to 1. 12766 Expr::EvalResult Result; 12767 if (!Length->EvaluateAsInt(Result, SemaRef.getASTContext())) 12768 return false; // Can't get the integer value as a constant. 12769 12770 llvm::APSInt ConstLength = Result.Val.getInt(); 12771 return ConstLength.getSExtValue() != 1; 12772 } 12773 12774 // Return the expression of the base of the mappable expression or null if it 12775 // cannot be determined and do all the necessary checks to see if the expression 12776 // is valid as a standalone mappable expression. In the process, record all the 12777 // components of the expression. 12778 static const Expr *checkMapClauseExpressionBase( 12779 Sema &SemaRef, Expr *E, 12780 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 12781 OpenMPClauseKind CKind, bool NoDiagnose) { 12782 SourceLocation ELoc = E->getExprLoc(); 12783 SourceRange ERange = E->getSourceRange(); 12784 12785 // The base of elements of list in a map clause have to be either: 12786 // - a reference to variable or field. 12787 // - a member expression. 12788 // - an array expression. 12789 // 12790 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 12791 // reference to 'r'. 12792 // 12793 // If we have: 12794 // 12795 // struct SS { 12796 // Bla S; 12797 // foo() { 12798 // #pragma omp target map (S.Arr[:12]); 12799 // } 12800 // } 12801 // 12802 // We want to retrieve the member expression 'this->S'; 12803 12804 const Expr *RelevantExpr = nullptr; 12805 12806 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 12807 // If a list item is an array section, it must specify contiguous storage. 12808 // 12809 // For this restriction it is sufficient that we make sure only references 12810 // to variables or fields and array expressions, and that no array sections 12811 // exist except in the rightmost expression (unless they cover the whole 12812 // dimension of the array). E.g. these would be invalid: 12813 // 12814 // r.ArrS[3:5].Arr[6:7] 12815 // 12816 // r.ArrS[3:5].x 12817 // 12818 // but these would be valid: 12819 // r.ArrS[3].Arr[6:7] 12820 // 12821 // r.ArrS[3].x 12822 12823 bool AllowUnitySizeArraySection = true; 12824 bool AllowWholeSizeArraySection = true; 12825 12826 while (!RelevantExpr) { 12827 E = E->IgnoreParenImpCasts(); 12828 12829 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 12830 if (!isa<VarDecl>(CurE->getDecl())) 12831 return nullptr; 12832 12833 RelevantExpr = CurE; 12834 12835 // If we got a reference to a declaration, we should not expect any array 12836 // section before that. 12837 AllowUnitySizeArraySection = false; 12838 AllowWholeSizeArraySection = false; 12839 12840 // Record the component. 12841 CurComponents.emplace_back(CurE, CurE->getDecl()); 12842 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 12843 Expr *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 12844 12845 if (isa<CXXThisExpr>(BaseE)) 12846 // We found a base expression: this->Val. 12847 RelevantExpr = CurE; 12848 else 12849 E = BaseE; 12850 12851 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 12852 if (!NoDiagnose) { 12853 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 12854 << CurE->getSourceRange(); 12855 return nullptr; 12856 } 12857 if (RelevantExpr) 12858 return nullptr; 12859 continue; 12860 } 12861 12862 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 12863 12864 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 12865 // A bit-field cannot appear in a map clause. 12866 // 12867 if (FD->isBitField()) { 12868 if (!NoDiagnose) { 12869 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 12870 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 12871 return nullptr; 12872 } 12873 if (RelevantExpr) 12874 return nullptr; 12875 continue; 12876 } 12877 12878 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12879 // If the type of a list item is a reference to a type T then the type 12880 // will be considered to be T for all purposes of this clause. 12881 QualType CurType = BaseE->getType().getNonReferenceType(); 12882 12883 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 12884 // A list item cannot be a variable that is a member of a structure with 12885 // a union type. 12886 // 12887 if (CurType->isUnionType()) { 12888 if (!NoDiagnose) { 12889 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 12890 << CurE->getSourceRange(); 12891 return nullptr; 12892 } 12893 continue; 12894 } 12895 12896 // If we got a member expression, we should not expect any array section 12897 // before that: 12898 // 12899 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 12900 // If a list item is an element of a structure, only the rightmost symbol 12901 // of the variable reference can be an array section. 12902 // 12903 AllowUnitySizeArraySection = false; 12904 AllowWholeSizeArraySection = false; 12905 12906 // Record the component. 12907 CurComponents.emplace_back(CurE, FD); 12908 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 12909 E = CurE->getBase()->IgnoreParenImpCasts(); 12910 12911 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 12912 if (!NoDiagnose) { 12913 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 12914 << 0 << CurE->getSourceRange(); 12915 return nullptr; 12916 } 12917 continue; 12918 } 12919 12920 // If we got an array subscript that express the whole dimension we 12921 // can have any array expressions before. If it only expressing part of 12922 // the dimension, we can only have unitary-size array expressions. 12923 if (checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 12924 E->getType())) 12925 AllowWholeSizeArraySection = false; 12926 12927 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 12928 Expr::EvalResult Result; 12929 if (CurE->getIdx()->EvaluateAsInt(Result, SemaRef.getASTContext())) { 12930 if (!Result.Val.getInt().isNullValue()) { 12931 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 12932 diag::err_omp_invalid_map_this_expr); 12933 SemaRef.Diag(CurE->getIdx()->getExprLoc(), 12934 diag::note_omp_invalid_subscript_on_this_ptr_map); 12935 } 12936 } 12937 RelevantExpr = TE; 12938 } 12939 12940 // Record the component - we don't have any declaration associated. 12941 CurComponents.emplace_back(CurE, nullptr); 12942 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 12943 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 12944 E = CurE->getBase()->IgnoreParenImpCasts(); 12945 12946 QualType CurType = 12947 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 12948 12949 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12950 // If the type of a list item is a reference to a type T then the type 12951 // will be considered to be T for all purposes of this clause. 12952 if (CurType->isReferenceType()) 12953 CurType = CurType->getPointeeType(); 12954 12955 bool IsPointer = CurType->isAnyPointerType(); 12956 12957 if (!IsPointer && !CurType->isArrayType()) { 12958 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 12959 << 0 << CurE->getSourceRange(); 12960 return nullptr; 12961 } 12962 12963 bool NotWhole = 12964 checkArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 12965 bool NotUnity = 12966 checkArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 12967 12968 if (AllowWholeSizeArraySection) { 12969 // Any array section is currently allowed. Allowing a whole size array 12970 // section implies allowing a unity array section as well. 12971 // 12972 // If this array section refers to the whole dimension we can still 12973 // accept other array sections before this one, except if the base is a 12974 // pointer. Otherwise, only unitary sections are accepted. 12975 if (NotWhole || IsPointer) 12976 AllowWholeSizeArraySection = false; 12977 } else if (AllowUnitySizeArraySection && NotUnity) { 12978 // A unity or whole array section is not allowed and that is not 12979 // compatible with the properties of the current array section. 12980 SemaRef.Diag( 12981 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 12982 << CurE->getSourceRange(); 12983 return nullptr; 12984 } 12985 12986 if (const auto *TE = dyn_cast<CXXThisExpr>(E)) { 12987 Expr::EvalResult ResultR; 12988 Expr::EvalResult ResultL; 12989 if (CurE->getLength()->EvaluateAsInt(ResultR, 12990 SemaRef.getASTContext())) { 12991 if (!ResultR.Val.getInt().isOneValue()) { 12992 SemaRef.Diag(CurE->getLength()->getExprLoc(), 12993 diag::err_omp_invalid_map_this_expr); 12994 SemaRef.Diag(CurE->getLength()->getExprLoc(), 12995 diag::note_omp_invalid_length_on_this_ptr_mapping); 12996 } 12997 } 12998 if (CurE->getLowerBound() && CurE->getLowerBound()->EvaluateAsInt( 12999 ResultL, SemaRef.getASTContext())) { 13000 if (!ResultL.Val.getInt().isNullValue()) { 13001 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13002 diag::err_omp_invalid_map_this_expr); 13003 SemaRef.Diag(CurE->getLowerBound()->getExprLoc(), 13004 diag::note_omp_invalid_lower_bound_on_this_ptr_mapping); 13005 } 13006 } 13007 RelevantExpr = TE; 13008 } 13009 13010 // Record the component - we don't have any declaration associated. 13011 CurComponents.emplace_back(CurE, nullptr); 13012 } else { 13013 if (!NoDiagnose) { 13014 // If nothing else worked, this is not a valid map clause expression. 13015 SemaRef.Diag( 13016 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 13017 << ERange; 13018 } 13019 return nullptr; 13020 } 13021 } 13022 13023 return RelevantExpr; 13024 } 13025 13026 // Return true if expression E associated with value VD has conflicts with other 13027 // map information. 13028 static bool checkMapConflicts( 13029 Sema &SemaRef, DSAStackTy *DSAS, const ValueDecl *VD, const Expr *E, 13030 bool CurrentRegionOnly, 13031 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 13032 OpenMPClauseKind CKind) { 13033 assert(VD && E); 13034 SourceLocation ELoc = E->getExprLoc(); 13035 SourceRange ERange = E->getSourceRange(); 13036 13037 // In order to easily check the conflicts we need to match each component of 13038 // the expression under test with the components of the expressions that are 13039 // already in the stack. 13040 13041 assert(!CurComponents.empty() && "Map clause expression with no components!"); 13042 assert(CurComponents.back().getAssociatedDeclaration() == VD && 13043 "Map clause expression with unexpected base!"); 13044 13045 // Variables to help detecting enclosing problems in data environment nests. 13046 bool IsEnclosedByDataEnvironmentExpr = false; 13047 const Expr *EnclosingExpr = nullptr; 13048 13049 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 13050 VD, CurrentRegionOnly, 13051 [&IsEnclosedByDataEnvironmentExpr, &SemaRef, VD, CurrentRegionOnly, ELoc, 13052 ERange, CKind, &EnclosingExpr, 13053 CurComponents](OMPClauseMappableExprCommon::MappableExprComponentListRef 13054 StackComponents, 13055 OpenMPClauseKind) { 13056 assert(!StackComponents.empty() && 13057 "Map clause expression with no components!"); 13058 assert(StackComponents.back().getAssociatedDeclaration() == VD && 13059 "Map clause expression with unexpected base!"); 13060 (void)VD; 13061 13062 // The whole expression in the stack. 13063 const Expr *RE = StackComponents.front().getAssociatedExpression(); 13064 13065 // Expressions must start from the same base. Here we detect at which 13066 // point both expressions diverge from each other and see if we can 13067 // detect if the memory referred to both expressions is contiguous and 13068 // do not overlap. 13069 auto CI = CurComponents.rbegin(); 13070 auto CE = CurComponents.rend(); 13071 auto SI = StackComponents.rbegin(); 13072 auto SE = StackComponents.rend(); 13073 for (; CI != CE && SI != SE; ++CI, ++SI) { 13074 13075 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 13076 // At most one list item can be an array item derived from a given 13077 // variable in map clauses of the same construct. 13078 if (CurrentRegionOnly && 13079 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 13080 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 13081 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 13082 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 13083 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 13084 diag::err_omp_multiple_array_items_in_map_clause) 13085 << CI->getAssociatedExpression()->getSourceRange(); 13086 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 13087 diag::note_used_here) 13088 << SI->getAssociatedExpression()->getSourceRange(); 13089 return true; 13090 } 13091 13092 // Do both expressions have the same kind? 13093 if (CI->getAssociatedExpression()->getStmtClass() != 13094 SI->getAssociatedExpression()->getStmtClass()) 13095 break; 13096 13097 // Are we dealing with different variables/fields? 13098 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 13099 break; 13100 } 13101 // Check if the extra components of the expressions in the enclosing 13102 // data environment are redundant for the current base declaration. 13103 // If they are, the maps completely overlap, which is legal. 13104 for (; SI != SE; ++SI) { 13105 QualType Type; 13106 if (const auto *ASE = 13107 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 13108 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 13109 } else if (const auto *OASE = dyn_cast<OMPArraySectionExpr>( 13110 SI->getAssociatedExpression())) { 13111 const Expr *E = OASE->getBase()->IgnoreParenImpCasts(); 13112 Type = 13113 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 13114 } 13115 if (Type.isNull() || Type->isAnyPointerType() || 13116 checkArrayExpressionDoesNotReferToWholeSize( 13117 SemaRef, SI->getAssociatedExpression(), Type)) 13118 break; 13119 } 13120 13121 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13122 // List items of map clauses in the same construct must not share 13123 // original storage. 13124 // 13125 // If the expressions are exactly the same or one is a subset of the 13126 // other, it means they are sharing storage. 13127 if (CI == CE && SI == SE) { 13128 if (CurrentRegionOnly) { 13129 if (CKind == OMPC_map) { 13130 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13131 } else { 13132 assert(CKind == OMPC_to || CKind == OMPC_from); 13133 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13134 << ERange; 13135 } 13136 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13137 << RE->getSourceRange(); 13138 return true; 13139 } 13140 // If we find the same expression in the enclosing data environment, 13141 // that is legal. 13142 IsEnclosedByDataEnvironmentExpr = true; 13143 return false; 13144 } 13145 13146 QualType DerivedType = 13147 std::prev(CI)->getAssociatedDeclaration()->getType(); 13148 SourceLocation DerivedLoc = 13149 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 13150 13151 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13152 // If the type of a list item is a reference to a type T then the type 13153 // will be considered to be T for all purposes of this clause. 13154 DerivedType = DerivedType.getNonReferenceType(); 13155 13156 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 13157 // A variable for which the type is pointer and an array section 13158 // derived from that variable must not appear as list items of map 13159 // clauses of the same construct. 13160 // 13161 // Also, cover one of the cases in: 13162 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13163 // If any part of the original storage of a list item has corresponding 13164 // storage in the device data environment, all of the original storage 13165 // must have corresponding storage in the device data environment. 13166 // 13167 if (DerivedType->isAnyPointerType()) { 13168 if (CI == CE || SI == SE) { 13169 SemaRef.Diag( 13170 DerivedLoc, 13171 diag::err_omp_pointer_mapped_along_with_derived_section) 13172 << DerivedLoc; 13173 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13174 << RE->getSourceRange(); 13175 return true; 13176 } 13177 if (CI->getAssociatedExpression()->getStmtClass() != 13178 SI->getAssociatedExpression()->getStmtClass() || 13179 CI->getAssociatedDeclaration()->getCanonicalDecl() == 13180 SI->getAssociatedDeclaration()->getCanonicalDecl()) { 13181 assert(CI != CE && SI != SE); 13182 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_dereferenced) 13183 << DerivedLoc; 13184 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13185 << RE->getSourceRange(); 13186 return true; 13187 } 13188 } 13189 13190 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 13191 // List items of map clauses in the same construct must not share 13192 // original storage. 13193 // 13194 // An expression is a subset of the other. 13195 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 13196 if (CKind == OMPC_map) { 13197 if (CI != CE || SI != SE) { 13198 // Allow constructs like this: map(s, s.ptr[0:1]), where s.ptr is 13199 // a pointer. 13200 auto Begin = 13201 CI != CE ? CurComponents.begin() : StackComponents.begin(); 13202 auto End = CI != CE ? CurComponents.end() : StackComponents.end(); 13203 auto It = Begin; 13204 while (It != End && !It->getAssociatedDeclaration()) 13205 std::advance(It, 1); 13206 assert(It != End && 13207 "Expected at least one component with the declaration."); 13208 if (It != Begin && It->getAssociatedDeclaration() 13209 ->getType() 13210 .getCanonicalType() 13211 ->isAnyPointerType()) { 13212 IsEnclosedByDataEnvironmentExpr = false; 13213 EnclosingExpr = nullptr; 13214 return false; 13215 } 13216 } 13217 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 13218 } else { 13219 assert(CKind == OMPC_to || CKind == OMPC_from); 13220 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 13221 << ERange; 13222 } 13223 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 13224 << RE->getSourceRange(); 13225 return true; 13226 } 13227 13228 // The current expression uses the same base as other expression in the 13229 // data environment but does not contain it completely. 13230 if (!CurrentRegionOnly && SI != SE) 13231 EnclosingExpr = RE; 13232 13233 // The current expression is a subset of the expression in the data 13234 // environment. 13235 IsEnclosedByDataEnvironmentExpr |= 13236 (!CurrentRegionOnly && CI != CE && SI == SE); 13237 13238 return false; 13239 }); 13240 13241 if (CurrentRegionOnly) 13242 return FoundError; 13243 13244 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 13245 // If any part of the original storage of a list item has corresponding 13246 // storage in the device data environment, all of the original storage must 13247 // have corresponding storage in the device data environment. 13248 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 13249 // If a list item is an element of a structure, and a different element of 13250 // the structure has a corresponding list item in the device data environment 13251 // prior to a task encountering the construct associated with the map clause, 13252 // then the list item must also have a corresponding list item in the device 13253 // data environment prior to the task encountering the construct. 13254 // 13255 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 13256 SemaRef.Diag(ELoc, 13257 diag::err_omp_original_storage_is_shared_and_does_not_contain) 13258 << ERange; 13259 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 13260 << EnclosingExpr->getSourceRange(); 13261 return true; 13262 } 13263 13264 return FoundError; 13265 } 13266 13267 // Look up the user-defined mapper given the mapper name and mapped type, and 13268 // build a reference to it. 13269 ExprResult buildUserDefinedMapperRef(Sema &SemaRef, Scope *S, 13270 CXXScopeSpec &MapperIdScopeSpec, 13271 const DeclarationNameInfo &MapperId, 13272 QualType Type, Expr *UnresolvedMapper) { 13273 if (MapperIdScopeSpec.isInvalid()) 13274 return ExprError(); 13275 // Find all user-defined mappers with the given MapperId. 13276 SmallVector<UnresolvedSet<8>, 4> Lookups; 13277 LookupResult Lookup(SemaRef, MapperId, Sema::LookupOMPMapperName); 13278 Lookup.suppressDiagnostics(); 13279 if (S) { 13280 while (S && SemaRef.LookupParsedName(Lookup, S, &MapperIdScopeSpec)) { 13281 NamedDecl *D = Lookup.getRepresentativeDecl(); 13282 while (S && !S->isDeclScope(D)) 13283 S = S->getParent(); 13284 if (S) 13285 S = S->getParent(); 13286 Lookups.emplace_back(); 13287 Lookups.back().append(Lookup.begin(), Lookup.end()); 13288 Lookup.clear(); 13289 } 13290 } else if (auto *ULE = cast_or_null<UnresolvedLookupExpr>(UnresolvedMapper)) { 13291 // Extract the user-defined mappers with the given MapperId. 13292 Lookups.push_back(UnresolvedSet<8>()); 13293 for (NamedDecl *D : ULE->decls()) { 13294 auto *DMD = cast<OMPDeclareMapperDecl>(D); 13295 assert(DMD && "Expect valid OMPDeclareMapperDecl during instantiation."); 13296 Lookups.back().addDecl(DMD); 13297 } 13298 } 13299 // Defer the lookup for dependent types. The results will be passed through 13300 // UnresolvedMapper on instantiation. 13301 if (SemaRef.CurContext->isDependentContext() || Type->isDependentType() || 13302 Type->isInstantiationDependentType() || 13303 Type->containsUnexpandedParameterPack() || 13304 filterLookupForUDReductionAndMapper<bool>(Lookups, [](ValueDecl *D) { 13305 return !D->isInvalidDecl() && 13306 (D->getType()->isDependentType() || 13307 D->getType()->isInstantiationDependentType() || 13308 D->getType()->containsUnexpandedParameterPack()); 13309 })) { 13310 UnresolvedSet<8> URS; 13311 for (const UnresolvedSet<8> &Set : Lookups) { 13312 if (Set.empty()) 13313 continue; 13314 URS.append(Set.begin(), Set.end()); 13315 } 13316 return UnresolvedLookupExpr::Create( 13317 SemaRef.Context, /*NamingClass=*/nullptr, 13318 MapperIdScopeSpec.getWithLocInContext(SemaRef.Context), MapperId, 13319 /*ADL=*/false, /*Overloaded=*/true, URS.begin(), URS.end()); 13320 } 13321 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 13322 // The type must be of struct, union or class type in C and C++ 13323 if (!Type->isStructureOrClassType() && !Type->isUnionType()) 13324 return ExprEmpty(); 13325 SourceLocation Loc = MapperId.getLoc(); 13326 // Perform argument dependent lookup. 13327 if (SemaRef.getLangOpts().CPlusPlus && !MapperIdScopeSpec.isSet()) 13328 argumentDependentLookup(SemaRef, MapperId, Loc, Type, Lookups); 13329 // Return the first user-defined mapper with the desired type. 13330 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13331 Lookups, [&SemaRef, Type](ValueDecl *D) -> ValueDecl * { 13332 if (!D->isInvalidDecl() && 13333 SemaRef.Context.hasSameType(D->getType(), Type)) 13334 return D; 13335 return nullptr; 13336 })) 13337 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13338 // Find the first user-defined mapper with a type derived from the desired 13339 // type. 13340 if (auto *VD = filterLookupForUDReductionAndMapper<ValueDecl *>( 13341 Lookups, [&SemaRef, Type, Loc](ValueDecl *D) -> ValueDecl * { 13342 if (!D->isInvalidDecl() && 13343 SemaRef.IsDerivedFrom(Loc, Type, D->getType()) && 13344 !Type.isMoreQualifiedThan(D->getType())) 13345 return D; 13346 return nullptr; 13347 })) { 13348 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 13349 /*DetectVirtual=*/false); 13350 if (SemaRef.IsDerivedFrom(Loc, Type, VD->getType(), Paths)) { 13351 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 13352 VD->getType().getUnqualifiedType()))) { 13353 if (SemaRef.CheckBaseClassAccess( 13354 Loc, VD->getType(), Type, Paths.front(), 13355 /*DiagID=*/0) != Sema::AR_inaccessible) { 13356 return SemaRef.BuildDeclRefExpr(VD, Type, VK_LValue, Loc); 13357 } 13358 } 13359 } 13360 } 13361 // Report error if a mapper is specified, but cannot be found. 13362 if (MapperIdScopeSpec.isSet() || MapperId.getAsString() != "default") { 13363 SemaRef.Diag(Loc, diag::err_omp_invalid_mapper) 13364 << Type << MapperId.getName(); 13365 return ExprError(); 13366 } 13367 return ExprEmpty(); 13368 } 13369 13370 namespace { 13371 // Utility struct that gathers all the related lists associated with a mappable 13372 // expression. 13373 struct MappableVarListInfo { 13374 // The list of expressions. 13375 ArrayRef<Expr *> VarList; 13376 // The list of processed expressions. 13377 SmallVector<Expr *, 16> ProcessedVarList; 13378 // The mappble components for each expression. 13379 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 13380 // The base declaration of the variable. 13381 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 13382 // The reference to the user-defined mapper associated with every expression. 13383 SmallVector<Expr *, 16> UDMapperList; 13384 13385 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 13386 // We have a list of components and base declarations for each entry in the 13387 // variable list. 13388 VarComponents.reserve(VarList.size()); 13389 VarBaseDeclarations.reserve(VarList.size()); 13390 } 13391 }; 13392 } 13393 13394 // Check the validity of the provided variable list for the provided clause kind 13395 // \a CKind. In the check process the valid expressions, mappable expression 13396 // components, variables, and user-defined mappers are extracted and used to 13397 // fill \a ProcessedVarList, \a VarComponents, \a VarBaseDeclarations, and \a 13398 // UDMapperList in MVLI. \a MapType, \a IsMapTypeImplicit, \a MapperIdScopeSpec, 13399 // and \a MapperId are expected to be valid if the clause kind is 'map'. 13400 static void checkMappableExpressionList( 13401 Sema &SemaRef, DSAStackTy *DSAS, OpenMPClauseKind CKind, 13402 MappableVarListInfo &MVLI, SourceLocation StartLoc, 13403 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo MapperId, 13404 ArrayRef<Expr *> UnresolvedMappers, 13405 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 13406 bool IsMapTypeImplicit = false) { 13407 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 13408 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 13409 "Unexpected clause kind with mappable expressions!"); 13410 13411 // If the identifier of user-defined mapper is not specified, it is "default". 13412 // We do not change the actual name in this clause to distinguish whether a 13413 // mapper is specified explicitly, i.e., it is not explicitly specified when 13414 // MapperId.getName() is empty. 13415 if (!MapperId.getName() || MapperId.getName().isEmpty()) { 13416 auto &DeclNames = SemaRef.getASTContext().DeclarationNames; 13417 MapperId.setName(DeclNames.getIdentifier( 13418 &SemaRef.getASTContext().Idents.get("default"))); 13419 } 13420 13421 // Iterators to find the current unresolved mapper expression. 13422 auto UMIt = UnresolvedMappers.begin(), UMEnd = UnresolvedMappers.end(); 13423 bool UpdateUMIt = false; 13424 Expr *UnresolvedMapper = nullptr; 13425 13426 // Keep track of the mappable components and base declarations in this clause. 13427 // Each entry in the list is going to have a list of components associated. We 13428 // record each set of the components so that we can build the clause later on. 13429 // In the end we should have the same amount of declarations and component 13430 // lists. 13431 13432 for (Expr *RE : MVLI.VarList) { 13433 assert(RE && "Null expr in omp to/from/map clause"); 13434 SourceLocation ELoc = RE->getExprLoc(); 13435 13436 // Find the current unresolved mapper expression. 13437 if (UpdateUMIt && UMIt != UMEnd) { 13438 UMIt++; 13439 assert( 13440 UMIt != UMEnd && 13441 "Expect the size of UnresolvedMappers to match with that of VarList"); 13442 } 13443 UpdateUMIt = true; 13444 if (UMIt != UMEnd) 13445 UnresolvedMapper = *UMIt; 13446 13447 const Expr *VE = RE->IgnoreParenLValueCasts(); 13448 13449 if (VE->isValueDependent() || VE->isTypeDependent() || 13450 VE->isInstantiationDependent() || 13451 VE->containsUnexpandedParameterPack()) { 13452 // Try to find the associated user-defined mapper. 13453 ExprResult ER = buildUserDefinedMapperRef( 13454 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13455 VE->getType().getCanonicalType(), UnresolvedMapper); 13456 if (ER.isInvalid()) 13457 continue; 13458 MVLI.UDMapperList.push_back(ER.get()); 13459 // We can only analyze this information once the missing information is 13460 // resolved. 13461 MVLI.ProcessedVarList.push_back(RE); 13462 continue; 13463 } 13464 13465 Expr *SimpleExpr = RE->IgnoreParenCasts(); 13466 13467 if (!RE->IgnoreParenImpCasts()->isLValue()) { 13468 SemaRef.Diag(ELoc, 13469 diag::err_omp_expected_named_var_member_or_array_expression) 13470 << RE->getSourceRange(); 13471 continue; 13472 } 13473 13474 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 13475 ValueDecl *CurDeclaration = nullptr; 13476 13477 // Obtain the array or member expression bases if required. Also, fill the 13478 // components array with all the components identified in the process. 13479 const Expr *BE = checkMapClauseExpressionBase( 13480 SemaRef, SimpleExpr, CurComponents, CKind, /*NoDiagnose=*/false); 13481 if (!BE) 13482 continue; 13483 13484 assert(!CurComponents.empty() && 13485 "Invalid mappable expression information."); 13486 13487 if (const auto *TE = dyn_cast<CXXThisExpr>(BE)) { 13488 // Add store "this" pointer to class in DSAStackTy for future checking 13489 DSAS->addMappedClassesQualTypes(TE->getType()); 13490 // Try to find the associated user-defined mapper. 13491 ExprResult ER = buildUserDefinedMapperRef( 13492 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13493 VE->getType().getCanonicalType(), UnresolvedMapper); 13494 if (ER.isInvalid()) 13495 continue; 13496 MVLI.UDMapperList.push_back(ER.get()); 13497 // Skip restriction checking for variable or field declarations 13498 MVLI.ProcessedVarList.push_back(RE); 13499 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13500 MVLI.VarComponents.back().append(CurComponents.begin(), 13501 CurComponents.end()); 13502 MVLI.VarBaseDeclarations.push_back(nullptr); 13503 continue; 13504 } 13505 13506 // For the following checks, we rely on the base declaration which is 13507 // expected to be associated with the last component. The declaration is 13508 // expected to be a variable or a field (if 'this' is being mapped). 13509 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 13510 assert(CurDeclaration && "Null decl on map clause."); 13511 assert( 13512 CurDeclaration->isCanonicalDecl() && 13513 "Expecting components to have associated only canonical declarations."); 13514 13515 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 13516 const auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 13517 13518 assert((VD || FD) && "Only variables or fields are expected here!"); 13519 (void)FD; 13520 13521 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 13522 // threadprivate variables cannot appear in a map clause. 13523 // OpenMP 4.5 [2.10.5, target update Construct] 13524 // threadprivate variables cannot appear in a from clause. 13525 if (VD && DSAS->isThreadPrivate(VD)) { 13526 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 13527 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 13528 << getOpenMPClauseName(CKind); 13529 reportOriginalDsa(SemaRef, DSAS, VD, DVar); 13530 continue; 13531 } 13532 13533 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 13534 // A list item cannot appear in both a map clause and a data-sharing 13535 // attribute clause on the same construct. 13536 13537 // Check conflicts with other map clause expressions. We check the conflicts 13538 // with the current construct separately from the enclosing data 13539 // environment, because the restrictions are different. We only have to 13540 // check conflicts across regions for the map clauses. 13541 if (checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 13542 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 13543 break; 13544 if (CKind == OMPC_map && 13545 checkMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 13546 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 13547 break; 13548 13549 // OpenMP 4.5 [2.10.5, target update Construct] 13550 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 13551 // If the type of a list item is a reference to a type T then the type will 13552 // be considered to be T for all purposes of this clause. 13553 auto I = llvm::find_if( 13554 CurComponents, 13555 [](const OMPClauseMappableExprCommon::MappableComponent &MC) { 13556 return MC.getAssociatedDeclaration(); 13557 }); 13558 assert(I != CurComponents.end() && "Null decl on map clause."); 13559 QualType Type = 13560 I->getAssociatedDeclaration()->getType().getNonReferenceType(); 13561 13562 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 13563 // A list item in a to or from clause must have a mappable type. 13564 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 13565 // A list item must have a mappable type. 13566 if (!checkTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 13567 DSAS, Type)) 13568 continue; 13569 13570 if (CKind == OMPC_map) { 13571 // target enter data 13572 // OpenMP [2.10.2, Restrictions, p. 99] 13573 // A map-type must be specified in all map clauses and must be either 13574 // to or alloc. 13575 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 13576 if (DKind == OMPD_target_enter_data && 13577 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 13578 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 13579 << (IsMapTypeImplicit ? 1 : 0) 13580 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 13581 << getOpenMPDirectiveName(DKind); 13582 continue; 13583 } 13584 13585 // target exit_data 13586 // OpenMP [2.10.3, Restrictions, p. 102] 13587 // A map-type must be specified in all map clauses and must be either 13588 // from, release, or delete. 13589 if (DKind == OMPD_target_exit_data && 13590 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 13591 MapType == OMPC_MAP_delete)) { 13592 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 13593 << (IsMapTypeImplicit ? 1 : 0) 13594 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 13595 << getOpenMPDirectiveName(DKind); 13596 continue; 13597 } 13598 13599 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 13600 // A list item cannot appear in both a map clause and a data-sharing 13601 // attribute clause on the same construct 13602 if (VD && isOpenMPTargetExecutionDirective(DKind)) { 13603 DSAStackTy::DSAVarData DVar = DSAS->getTopDSA(VD, /*FromParent=*/false); 13604 if (isOpenMPPrivate(DVar.CKind)) { 13605 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 13606 << getOpenMPClauseName(DVar.CKind) 13607 << getOpenMPClauseName(OMPC_map) 13608 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 13609 reportOriginalDsa(SemaRef, DSAS, CurDeclaration, DVar); 13610 continue; 13611 } 13612 } 13613 } 13614 13615 // Try to find the associated user-defined mapper. 13616 ExprResult ER = buildUserDefinedMapperRef( 13617 SemaRef, DSAS->getCurScope(), MapperIdScopeSpec, MapperId, 13618 Type.getCanonicalType(), UnresolvedMapper); 13619 if (ER.isInvalid()) 13620 continue; 13621 MVLI.UDMapperList.push_back(ER.get()); 13622 13623 // Save the current expression. 13624 MVLI.ProcessedVarList.push_back(RE); 13625 13626 // Store the components in the stack so that they can be used to check 13627 // against other clauses later on. 13628 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 13629 /*WhereFoundClauseKind=*/OMPC_map); 13630 13631 // Save the components and declaration to create the clause. For purposes of 13632 // the clause creation, any component list that has has base 'this' uses 13633 // null as base declaration. 13634 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 13635 MVLI.VarComponents.back().append(CurComponents.begin(), 13636 CurComponents.end()); 13637 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 13638 : CurDeclaration); 13639 } 13640 } 13641 13642 OMPClause *Sema::ActOnOpenMPMapClause( 13643 ArrayRef<OpenMPMapModifierKind> MapTypeModifiers, 13644 ArrayRef<SourceLocation> MapTypeModifiersLoc, 13645 CXXScopeSpec &MapperIdScopeSpec, DeclarationNameInfo &MapperId, 13646 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, SourceLocation MapLoc, 13647 SourceLocation ColonLoc, ArrayRef<Expr *> VarList, 13648 const OMPVarListLocTy &Locs, ArrayRef<Expr *> UnresolvedMappers) { 13649 OpenMPMapModifierKind Modifiers[] = {OMPC_MAP_MODIFIER_unknown, 13650 OMPC_MAP_MODIFIER_unknown, 13651 OMPC_MAP_MODIFIER_unknown}; 13652 SourceLocation ModifiersLoc[OMPMapClause::NumberOfModifiers]; 13653 13654 // Process map-type-modifiers, flag errors for duplicate modifiers. 13655 unsigned Count = 0; 13656 for (unsigned I = 0, E = MapTypeModifiers.size(); I < E; ++I) { 13657 if (MapTypeModifiers[I] != OMPC_MAP_MODIFIER_unknown && 13658 llvm::find(Modifiers, MapTypeModifiers[I]) != std::end(Modifiers)) { 13659 Diag(MapTypeModifiersLoc[I], diag::err_omp_duplicate_map_type_modifier); 13660 continue; 13661 } 13662 assert(Count < OMPMapClause::NumberOfModifiers && 13663 "Modifiers exceed the allowed number of map type modifiers"); 13664 Modifiers[Count] = MapTypeModifiers[I]; 13665 ModifiersLoc[Count] = MapTypeModifiersLoc[I]; 13666 ++Count; 13667 } 13668 13669 MappableVarListInfo MVLI(VarList); 13670 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, Locs.StartLoc, 13671 MapperIdScopeSpec, MapperId, UnresolvedMappers, 13672 MapType, IsMapTypeImplicit); 13673 13674 // We need to produce a map clause even if we don't have variables so that 13675 // other diagnostics related with non-existing map clauses are accurate. 13676 return OMPMapClause::Create(Context, Locs, MVLI.ProcessedVarList, 13677 MVLI.VarBaseDeclarations, MVLI.VarComponents, 13678 MVLI.UDMapperList, Modifiers, ModifiersLoc, 13679 MapperIdScopeSpec.getWithLocInContext(Context), 13680 MapperId, MapType, IsMapTypeImplicit, MapLoc); 13681 } 13682 13683 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 13684 TypeResult ParsedType) { 13685 assert(ParsedType.isUsable()); 13686 13687 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 13688 if (ReductionType.isNull()) 13689 return QualType(); 13690 13691 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 13692 // A type name in a declare reduction directive cannot be a function type, an 13693 // array type, a reference type, or a type qualified with const, volatile or 13694 // restrict. 13695 if (ReductionType.hasQualifiers()) { 13696 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 13697 return QualType(); 13698 } 13699 13700 if (ReductionType->isFunctionType()) { 13701 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 13702 return QualType(); 13703 } 13704 if (ReductionType->isReferenceType()) { 13705 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 13706 return QualType(); 13707 } 13708 if (ReductionType->isArrayType()) { 13709 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 13710 return QualType(); 13711 } 13712 return ReductionType; 13713 } 13714 13715 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 13716 Scope *S, DeclContext *DC, DeclarationName Name, 13717 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 13718 AccessSpecifier AS, Decl *PrevDeclInScope) { 13719 SmallVector<Decl *, 8> Decls; 13720 Decls.reserve(ReductionTypes.size()); 13721 13722 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 13723 forRedeclarationInCurContext()); 13724 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 13725 // A reduction-identifier may not be re-declared in the current scope for the 13726 // same type or for a type that is compatible according to the base language 13727 // rules. 13728 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 13729 OMPDeclareReductionDecl *PrevDRD = nullptr; 13730 bool InCompoundScope = true; 13731 if (S != nullptr) { 13732 // Find previous declaration with the same name not referenced in other 13733 // declarations. 13734 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 13735 InCompoundScope = 13736 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 13737 LookupName(Lookup, S); 13738 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 13739 /*AllowInlineNamespace=*/false); 13740 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 13741 LookupResult::Filter Filter = Lookup.makeFilter(); 13742 while (Filter.hasNext()) { 13743 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 13744 if (InCompoundScope) { 13745 auto I = UsedAsPrevious.find(PrevDecl); 13746 if (I == UsedAsPrevious.end()) 13747 UsedAsPrevious[PrevDecl] = false; 13748 if (OMPDeclareReductionDecl *D = PrevDecl->getPrevDeclInScope()) 13749 UsedAsPrevious[D] = true; 13750 } 13751 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 13752 PrevDecl->getLocation(); 13753 } 13754 Filter.done(); 13755 if (InCompoundScope) { 13756 for (const auto &PrevData : UsedAsPrevious) { 13757 if (!PrevData.second) { 13758 PrevDRD = PrevData.first; 13759 break; 13760 } 13761 } 13762 } 13763 } else if (PrevDeclInScope != nullptr) { 13764 auto *PrevDRDInScope = PrevDRD = 13765 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 13766 do { 13767 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 13768 PrevDRDInScope->getLocation(); 13769 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 13770 } while (PrevDRDInScope != nullptr); 13771 } 13772 for (const auto &TyData : ReductionTypes) { 13773 const auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 13774 bool Invalid = false; 13775 if (I != PreviousRedeclTypes.end()) { 13776 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 13777 << TyData.first; 13778 Diag(I->second, diag::note_previous_definition); 13779 Invalid = true; 13780 } 13781 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 13782 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 13783 Name, TyData.first, PrevDRD); 13784 DC->addDecl(DRD); 13785 DRD->setAccess(AS); 13786 Decls.push_back(DRD); 13787 if (Invalid) 13788 DRD->setInvalidDecl(); 13789 else 13790 PrevDRD = DRD; 13791 } 13792 13793 return DeclGroupPtrTy::make( 13794 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 13795 } 13796 13797 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 13798 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13799 13800 // Enter new function scope. 13801 PushFunctionScope(); 13802 setFunctionHasBranchProtectedScope(); 13803 getCurFunction()->setHasOMPDeclareReductionCombiner(); 13804 13805 if (S != nullptr) 13806 PushDeclContext(S, DRD); 13807 else 13808 CurContext = DRD; 13809 13810 PushExpressionEvaluationContext( 13811 ExpressionEvaluationContext::PotentiallyEvaluated); 13812 13813 QualType ReductionType = DRD->getType(); 13814 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 13815 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 13816 // uses semantics of argument handles by value, but it should be passed by 13817 // reference. C lang does not support references, so pass all parameters as 13818 // pointers. 13819 // Create 'T omp_in;' variable. 13820 VarDecl *OmpInParm = 13821 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 13822 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 13823 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 13824 // uses semantics of argument handles by value, but it should be passed by 13825 // reference. C lang does not support references, so pass all parameters as 13826 // pointers. 13827 // Create 'T omp_out;' variable. 13828 VarDecl *OmpOutParm = 13829 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 13830 if (S != nullptr) { 13831 PushOnScopeChains(OmpInParm, S); 13832 PushOnScopeChains(OmpOutParm, S); 13833 } else { 13834 DRD->addDecl(OmpInParm); 13835 DRD->addDecl(OmpOutParm); 13836 } 13837 Expr *InE = 13838 ::buildDeclRefExpr(*this, OmpInParm, ReductionType, D->getLocation()); 13839 Expr *OutE = 13840 ::buildDeclRefExpr(*this, OmpOutParm, ReductionType, D->getLocation()); 13841 DRD->setCombinerData(InE, OutE); 13842 } 13843 13844 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 13845 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13846 DiscardCleanupsInEvaluationContext(); 13847 PopExpressionEvaluationContext(); 13848 13849 PopDeclContext(); 13850 PopFunctionScopeInfo(); 13851 13852 if (Combiner != nullptr) 13853 DRD->setCombiner(Combiner); 13854 else 13855 DRD->setInvalidDecl(); 13856 } 13857 13858 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 13859 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13860 13861 // Enter new function scope. 13862 PushFunctionScope(); 13863 setFunctionHasBranchProtectedScope(); 13864 13865 if (S != nullptr) 13866 PushDeclContext(S, DRD); 13867 else 13868 CurContext = DRD; 13869 13870 PushExpressionEvaluationContext( 13871 ExpressionEvaluationContext::PotentiallyEvaluated); 13872 13873 QualType ReductionType = DRD->getType(); 13874 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 13875 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 13876 // uses semantics of argument handles by value, but it should be passed by 13877 // reference. C lang does not support references, so pass all parameters as 13878 // pointers. 13879 // Create 'T omp_priv;' variable. 13880 VarDecl *OmpPrivParm = 13881 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 13882 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 13883 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 13884 // uses semantics of argument handles by value, but it should be passed by 13885 // reference. C lang does not support references, so pass all parameters as 13886 // pointers. 13887 // Create 'T omp_orig;' variable. 13888 VarDecl *OmpOrigParm = 13889 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 13890 if (S != nullptr) { 13891 PushOnScopeChains(OmpPrivParm, S); 13892 PushOnScopeChains(OmpOrigParm, S); 13893 } else { 13894 DRD->addDecl(OmpPrivParm); 13895 DRD->addDecl(OmpOrigParm); 13896 } 13897 Expr *OrigE = 13898 ::buildDeclRefExpr(*this, OmpOrigParm, ReductionType, D->getLocation()); 13899 Expr *PrivE = 13900 ::buildDeclRefExpr(*this, OmpPrivParm, ReductionType, D->getLocation()); 13901 DRD->setInitializerData(OrigE, PrivE); 13902 return OmpPrivParm; 13903 } 13904 13905 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 13906 VarDecl *OmpPrivParm) { 13907 auto *DRD = cast<OMPDeclareReductionDecl>(D); 13908 DiscardCleanupsInEvaluationContext(); 13909 PopExpressionEvaluationContext(); 13910 13911 PopDeclContext(); 13912 PopFunctionScopeInfo(); 13913 13914 if (Initializer != nullptr) { 13915 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 13916 } else if (OmpPrivParm->hasInit()) { 13917 DRD->setInitializer(OmpPrivParm->getInit(), 13918 OmpPrivParm->isDirectInit() 13919 ? OMPDeclareReductionDecl::DirectInit 13920 : OMPDeclareReductionDecl::CopyInit); 13921 } else { 13922 DRD->setInvalidDecl(); 13923 } 13924 } 13925 13926 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 13927 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 13928 for (Decl *D : DeclReductions.get()) { 13929 if (IsValid) { 13930 if (S) 13931 PushOnScopeChains(cast<OMPDeclareReductionDecl>(D), S, 13932 /*AddToContext=*/false); 13933 } else { 13934 D->setInvalidDecl(); 13935 } 13936 } 13937 return DeclReductions; 13938 } 13939 13940 TypeResult Sema::ActOnOpenMPDeclareMapperVarDecl(Scope *S, Declarator &D) { 13941 TypeSourceInfo *TInfo = GetTypeForDeclarator(D, S); 13942 QualType T = TInfo->getType(); 13943 if (D.isInvalidType()) 13944 return true; 13945 13946 if (getLangOpts().CPlusPlus) { 13947 // Check that there are no default arguments (C++ only). 13948 CheckExtraCXXDefaultArguments(D); 13949 } 13950 13951 return CreateParsedType(T, TInfo); 13952 } 13953 13954 QualType Sema::ActOnOpenMPDeclareMapperType(SourceLocation TyLoc, 13955 TypeResult ParsedType) { 13956 assert(ParsedType.isUsable() && "Expect usable parsed mapper type"); 13957 13958 QualType MapperType = GetTypeFromParser(ParsedType.get()); 13959 assert(!MapperType.isNull() && "Expect valid mapper type"); 13960 13961 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 13962 // The type must be of struct, union or class type in C and C++ 13963 if (!MapperType->isStructureOrClassType() && !MapperType->isUnionType()) { 13964 Diag(TyLoc, diag::err_omp_mapper_wrong_type); 13965 return QualType(); 13966 } 13967 return MapperType; 13968 } 13969 13970 OMPDeclareMapperDecl *Sema::ActOnOpenMPDeclareMapperDirectiveStart( 13971 Scope *S, DeclContext *DC, DeclarationName Name, QualType MapperType, 13972 SourceLocation StartLoc, DeclarationName VN, AccessSpecifier AS, 13973 Decl *PrevDeclInScope) { 13974 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPMapperName, 13975 forRedeclarationInCurContext()); 13976 // [OpenMP 5.0], 2.19.7.3 declare mapper Directive, Restrictions 13977 // A mapper-identifier may not be redeclared in the current scope for the 13978 // same type or for a type that is compatible according to the base language 13979 // rules. 13980 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 13981 OMPDeclareMapperDecl *PrevDMD = nullptr; 13982 bool InCompoundScope = true; 13983 if (S != nullptr) { 13984 // Find previous declaration with the same name not referenced in other 13985 // declarations. 13986 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 13987 InCompoundScope = 13988 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 13989 LookupName(Lookup, S); 13990 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 13991 /*AllowInlineNamespace=*/false); 13992 llvm::DenseMap<OMPDeclareMapperDecl *, bool> UsedAsPrevious; 13993 LookupResult::Filter Filter = Lookup.makeFilter(); 13994 while (Filter.hasNext()) { 13995 auto *PrevDecl = cast<OMPDeclareMapperDecl>(Filter.next()); 13996 if (InCompoundScope) { 13997 auto I = UsedAsPrevious.find(PrevDecl); 13998 if (I == UsedAsPrevious.end()) 13999 UsedAsPrevious[PrevDecl] = false; 14000 if (OMPDeclareMapperDecl *D = PrevDecl->getPrevDeclInScope()) 14001 UsedAsPrevious[D] = true; 14002 } 14003 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 14004 PrevDecl->getLocation(); 14005 } 14006 Filter.done(); 14007 if (InCompoundScope) { 14008 for (const auto &PrevData : UsedAsPrevious) { 14009 if (!PrevData.second) { 14010 PrevDMD = PrevData.first; 14011 break; 14012 } 14013 } 14014 } 14015 } else if (PrevDeclInScope) { 14016 auto *PrevDMDInScope = PrevDMD = 14017 cast<OMPDeclareMapperDecl>(PrevDeclInScope); 14018 do { 14019 PreviousRedeclTypes[PrevDMDInScope->getType().getCanonicalType()] = 14020 PrevDMDInScope->getLocation(); 14021 PrevDMDInScope = PrevDMDInScope->getPrevDeclInScope(); 14022 } while (PrevDMDInScope != nullptr); 14023 } 14024 const auto I = PreviousRedeclTypes.find(MapperType.getCanonicalType()); 14025 bool Invalid = false; 14026 if (I != PreviousRedeclTypes.end()) { 14027 Diag(StartLoc, diag::err_omp_declare_mapper_redefinition) 14028 << MapperType << Name; 14029 Diag(I->second, diag::note_previous_definition); 14030 Invalid = true; 14031 } 14032 auto *DMD = OMPDeclareMapperDecl::Create(Context, DC, StartLoc, Name, 14033 MapperType, VN, PrevDMD); 14034 DC->addDecl(DMD); 14035 DMD->setAccess(AS); 14036 if (Invalid) 14037 DMD->setInvalidDecl(); 14038 14039 // Enter new function scope. 14040 PushFunctionScope(); 14041 setFunctionHasBranchProtectedScope(); 14042 14043 CurContext = DMD; 14044 14045 return DMD; 14046 } 14047 14048 void Sema::ActOnOpenMPDeclareMapperDirectiveVarDecl(OMPDeclareMapperDecl *DMD, 14049 Scope *S, 14050 QualType MapperType, 14051 SourceLocation StartLoc, 14052 DeclarationName VN) { 14053 VarDecl *VD = buildVarDecl(*this, StartLoc, MapperType, VN.getAsString()); 14054 if (S) 14055 PushOnScopeChains(VD, S); 14056 else 14057 DMD->addDecl(VD); 14058 Expr *MapperVarRefExpr = buildDeclRefExpr(*this, VD, MapperType, StartLoc); 14059 DMD->setMapperVarRef(MapperVarRefExpr); 14060 } 14061 14062 Sema::DeclGroupPtrTy 14063 Sema::ActOnOpenMPDeclareMapperDirectiveEnd(OMPDeclareMapperDecl *D, Scope *S, 14064 ArrayRef<OMPClause *> ClauseList) { 14065 PopDeclContext(); 14066 PopFunctionScopeInfo(); 14067 14068 if (D) { 14069 if (S) 14070 PushOnScopeChains(D, S, /*AddToContext=*/false); 14071 D->CreateClauses(Context, ClauseList); 14072 } 14073 14074 return DeclGroupPtrTy::make(DeclGroupRef(D)); 14075 } 14076 14077 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 14078 SourceLocation StartLoc, 14079 SourceLocation LParenLoc, 14080 SourceLocation EndLoc) { 14081 Expr *ValExpr = NumTeams; 14082 Stmt *HelperValStmt = nullptr; 14083 14084 // OpenMP [teams Constrcut, Restrictions] 14085 // The num_teams expression must evaluate to a positive integer value. 14086 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 14087 /*StrictlyPositive=*/true)) 14088 return nullptr; 14089 14090 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14091 OpenMPDirectiveKind CaptureRegion = 14092 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 14093 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14094 ValExpr = MakeFullExpr(ValExpr).get(); 14095 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14096 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14097 HelperValStmt = buildPreInits(Context, Captures); 14098 } 14099 14100 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 14101 StartLoc, LParenLoc, EndLoc); 14102 } 14103 14104 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 14105 SourceLocation StartLoc, 14106 SourceLocation LParenLoc, 14107 SourceLocation EndLoc) { 14108 Expr *ValExpr = ThreadLimit; 14109 Stmt *HelperValStmt = nullptr; 14110 14111 // OpenMP [teams Constrcut, Restrictions] 14112 // The thread_limit expression must evaluate to a positive integer value. 14113 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 14114 /*StrictlyPositive=*/true)) 14115 return nullptr; 14116 14117 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 14118 OpenMPDirectiveKind CaptureRegion = 14119 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 14120 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 14121 ValExpr = MakeFullExpr(ValExpr).get(); 14122 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14123 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14124 HelperValStmt = buildPreInits(Context, Captures); 14125 } 14126 14127 return new (Context) OMPThreadLimitClause( 14128 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 14129 } 14130 14131 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 14132 SourceLocation StartLoc, 14133 SourceLocation LParenLoc, 14134 SourceLocation EndLoc) { 14135 Expr *ValExpr = Priority; 14136 14137 // OpenMP [2.9.1, task Constrcut] 14138 // The priority-value is a non-negative numerical scalar expression. 14139 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 14140 /*StrictlyPositive=*/false)) 14141 return nullptr; 14142 14143 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14144 } 14145 14146 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 14147 SourceLocation StartLoc, 14148 SourceLocation LParenLoc, 14149 SourceLocation EndLoc) { 14150 Expr *ValExpr = Grainsize; 14151 14152 // OpenMP [2.9.2, taskloop Constrcut] 14153 // The parameter of the grainsize clause must be a positive integer 14154 // expression. 14155 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 14156 /*StrictlyPositive=*/true)) 14157 return nullptr; 14158 14159 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14160 } 14161 14162 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 14163 SourceLocation StartLoc, 14164 SourceLocation LParenLoc, 14165 SourceLocation EndLoc) { 14166 Expr *ValExpr = NumTasks; 14167 14168 // OpenMP [2.9.2, taskloop Constrcut] 14169 // The parameter of the num_tasks clause must be a positive integer 14170 // expression. 14171 if (!isNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 14172 /*StrictlyPositive=*/true)) 14173 return nullptr; 14174 14175 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 14176 } 14177 14178 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 14179 SourceLocation LParenLoc, 14180 SourceLocation EndLoc) { 14181 // OpenMP [2.13.2, critical construct, Description] 14182 // ... where hint-expression is an integer constant expression that evaluates 14183 // to a valid lock hint. 14184 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 14185 if (HintExpr.isInvalid()) 14186 return nullptr; 14187 return new (Context) 14188 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 14189 } 14190 14191 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 14192 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 14193 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 14194 SourceLocation EndLoc) { 14195 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 14196 std::string Values; 14197 Values += "'"; 14198 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 14199 Values += "'"; 14200 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 14201 << Values << getOpenMPClauseName(OMPC_dist_schedule); 14202 return nullptr; 14203 } 14204 Expr *ValExpr = ChunkSize; 14205 Stmt *HelperValStmt = nullptr; 14206 if (ChunkSize) { 14207 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 14208 !ChunkSize->isInstantiationDependent() && 14209 !ChunkSize->containsUnexpandedParameterPack()) { 14210 SourceLocation ChunkSizeLoc = ChunkSize->getBeginLoc(); 14211 ExprResult Val = 14212 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 14213 if (Val.isInvalid()) 14214 return nullptr; 14215 14216 ValExpr = Val.get(); 14217 14218 // OpenMP [2.7.1, Restrictions] 14219 // chunk_size must be a loop invariant integer expression with a positive 14220 // value. 14221 llvm::APSInt Result; 14222 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 14223 if (Result.isSigned() && !Result.isStrictlyPositive()) { 14224 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 14225 << "dist_schedule" << ChunkSize->getSourceRange(); 14226 return nullptr; 14227 } 14228 } else if (getOpenMPCaptureRegionForClause( 14229 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 14230 OMPD_unknown && 14231 !CurContext->isDependentContext()) { 14232 ValExpr = MakeFullExpr(ValExpr).get(); 14233 llvm::MapVector<const Expr *, DeclRefExpr *> Captures; 14234 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 14235 HelperValStmt = buildPreInits(Context, Captures); 14236 } 14237 } 14238 } 14239 14240 return new (Context) 14241 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 14242 Kind, ValExpr, HelperValStmt); 14243 } 14244 14245 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 14246 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 14247 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 14248 SourceLocation KindLoc, SourceLocation EndLoc) { 14249 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 14250 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 14251 std::string Value; 14252 SourceLocation Loc; 14253 Value += "'"; 14254 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 14255 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14256 OMPC_DEFAULTMAP_MODIFIER_tofrom); 14257 Loc = MLoc; 14258 } else { 14259 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 14260 OMPC_DEFAULTMAP_scalar); 14261 Loc = KindLoc; 14262 } 14263 Value += "'"; 14264 Diag(Loc, diag::err_omp_unexpected_clause_value) 14265 << Value << getOpenMPClauseName(OMPC_defaultmap); 14266 return nullptr; 14267 } 14268 DSAStack->setDefaultDMAToFromScalar(StartLoc); 14269 14270 return new (Context) 14271 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 14272 } 14273 14274 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 14275 DeclContext *CurLexicalContext = getCurLexicalContext(); 14276 if (!CurLexicalContext->isFileContext() && 14277 !CurLexicalContext->isExternCContext() && 14278 !CurLexicalContext->isExternCXXContext() && 14279 !isa<CXXRecordDecl>(CurLexicalContext) && 14280 !isa<ClassTemplateDecl>(CurLexicalContext) && 14281 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 14282 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 14283 Diag(Loc, diag::err_omp_region_not_file_context); 14284 return false; 14285 } 14286 ++DeclareTargetNestingLevel; 14287 return true; 14288 } 14289 14290 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 14291 assert(DeclareTargetNestingLevel > 0 && 14292 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 14293 --DeclareTargetNestingLevel; 14294 } 14295 14296 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 14297 CXXScopeSpec &ScopeSpec, 14298 const DeclarationNameInfo &Id, 14299 OMPDeclareTargetDeclAttr::MapTypeTy MT, 14300 NamedDeclSetType &SameDirectiveDecls) { 14301 LookupResult Lookup(*this, Id, LookupOrdinaryName); 14302 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 14303 14304 if (Lookup.isAmbiguous()) 14305 return; 14306 Lookup.suppressDiagnostics(); 14307 14308 if (!Lookup.isSingleResult()) { 14309 if (TypoCorrection Corrected = 14310 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, 14311 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), 14312 CTK_ErrorRecovery)) { 14313 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 14314 << Id.getName()); 14315 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 14316 return; 14317 } 14318 14319 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 14320 return; 14321 } 14322 14323 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 14324 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND) || 14325 isa<FunctionTemplateDecl>(ND)) { 14326 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 14327 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 14328 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14329 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration( 14330 cast<ValueDecl>(ND)); 14331 if (!Res) { 14332 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 14333 ND->addAttr(A); 14334 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14335 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 14336 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 14337 } else if (*Res != MT) { 14338 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 14339 << Id.getName(); 14340 } 14341 } else { 14342 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 14343 } 14344 } 14345 14346 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 14347 Sema &SemaRef, Decl *D) { 14348 if (!D || !isa<VarDecl>(D)) 14349 return; 14350 auto *VD = cast<VarDecl>(D); 14351 if (OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) 14352 return; 14353 SemaRef.Diag(VD->getLocation(), diag::warn_omp_not_in_target_context); 14354 SemaRef.Diag(SL, diag::note_used_here) << SR; 14355 } 14356 14357 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 14358 Sema &SemaRef, DSAStackTy *Stack, 14359 ValueDecl *VD) { 14360 return VD->hasAttr<OMPDeclareTargetDeclAttr>() || 14361 checkTypeMappable(SL, SR, SemaRef, Stack, VD->getType(), 14362 /*FullCheck=*/false); 14363 } 14364 14365 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 14366 SourceLocation IdLoc) { 14367 if (!D || D->isInvalidDecl()) 14368 return; 14369 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 14370 SourceLocation SL = E ? E->getBeginLoc() : D->getLocation(); 14371 if (auto *VD = dyn_cast<VarDecl>(D)) { 14372 // Only global variables can be marked as declare target. 14373 if (!VD->isFileVarDecl() && !VD->isStaticLocal() && 14374 !VD->isStaticDataMember()) 14375 return; 14376 // 2.10.6: threadprivate variable cannot appear in a declare target 14377 // directive. 14378 if (DSAStack->isThreadPrivate(VD)) { 14379 Diag(SL, diag::err_omp_threadprivate_in_target); 14380 reportOriginalDsa(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 14381 return; 14382 } 14383 } 14384 if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(D)) 14385 D = FTD->getTemplatedDecl(); 14386 if (const auto *FD = dyn_cast<FunctionDecl>(D)) { 14387 llvm::Optional<OMPDeclareTargetDeclAttr::MapTypeTy> Res = 14388 OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(FD); 14389 if (Res && *Res == OMPDeclareTargetDeclAttr::MT_Link) { 14390 assert(IdLoc.isValid() && "Source location is expected"); 14391 Diag(IdLoc, diag::err_omp_function_in_link_clause); 14392 Diag(FD->getLocation(), diag::note_defined_here) << FD; 14393 return; 14394 } 14395 } 14396 if (auto *VD = dyn_cast<ValueDecl>(D)) { 14397 // Problem if any with var declared with incomplete type will be reported 14398 // as normal, so no need to check it here. 14399 if ((E || !VD->getType()->isIncompleteType()) && 14400 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) 14401 return; 14402 if (!E && !OMPDeclareTargetDeclAttr::isDeclareTargetDeclaration(VD)) { 14403 // Checking declaration inside declare target region. 14404 if (isa<VarDecl>(D) || isa<FunctionDecl>(D) || 14405 isa<FunctionTemplateDecl>(D)) { 14406 auto *A = OMPDeclareTargetDeclAttr::CreateImplicit( 14407 Context, OMPDeclareTargetDeclAttr::MT_To); 14408 D->addAttr(A); 14409 if (ASTMutationListener *ML = Context.getASTMutationListener()) 14410 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 14411 } 14412 return; 14413 } 14414 } 14415 if (!E) 14416 return; 14417 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 14418 } 14419 14420 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 14421 CXXScopeSpec &MapperIdScopeSpec, 14422 DeclarationNameInfo &MapperId, 14423 const OMPVarListLocTy &Locs, 14424 ArrayRef<Expr *> UnresolvedMappers) { 14425 MappableVarListInfo MVLI(VarList); 14426 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, Locs.StartLoc, 14427 MapperIdScopeSpec, MapperId, UnresolvedMappers); 14428 if (MVLI.ProcessedVarList.empty()) 14429 return nullptr; 14430 14431 return OMPToClause::Create( 14432 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 14433 MVLI.VarComponents, MVLI.UDMapperList, 14434 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 14435 } 14436 14437 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 14438 CXXScopeSpec &MapperIdScopeSpec, 14439 DeclarationNameInfo &MapperId, 14440 const OMPVarListLocTy &Locs, 14441 ArrayRef<Expr *> UnresolvedMappers) { 14442 MappableVarListInfo MVLI(VarList); 14443 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, Locs.StartLoc, 14444 MapperIdScopeSpec, MapperId, UnresolvedMappers); 14445 if (MVLI.ProcessedVarList.empty()) 14446 return nullptr; 14447 14448 return OMPFromClause::Create( 14449 Context, Locs, MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 14450 MVLI.VarComponents, MVLI.UDMapperList, 14451 MapperIdScopeSpec.getWithLocInContext(Context), MapperId); 14452 } 14453 14454 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 14455 const OMPVarListLocTy &Locs) { 14456 MappableVarListInfo MVLI(VarList); 14457 SmallVector<Expr *, 8> PrivateCopies; 14458 SmallVector<Expr *, 8> Inits; 14459 14460 for (Expr *RefExpr : VarList) { 14461 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 14462 SourceLocation ELoc; 14463 SourceRange ERange; 14464 Expr *SimpleRefExpr = RefExpr; 14465 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14466 if (Res.second) { 14467 // It will be analyzed later. 14468 MVLI.ProcessedVarList.push_back(RefExpr); 14469 PrivateCopies.push_back(nullptr); 14470 Inits.push_back(nullptr); 14471 } 14472 ValueDecl *D = Res.first; 14473 if (!D) 14474 continue; 14475 14476 QualType Type = D->getType(); 14477 Type = Type.getNonReferenceType().getUnqualifiedType(); 14478 14479 auto *VD = dyn_cast<VarDecl>(D); 14480 14481 // Item should be a pointer or reference to pointer. 14482 if (!Type->isPointerType()) { 14483 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 14484 << 0 << RefExpr->getSourceRange(); 14485 continue; 14486 } 14487 14488 // Build the private variable and the expression that refers to it. 14489 auto VDPrivate = 14490 buildVarDecl(*this, ELoc, Type, D->getName(), 14491 D->hasAttrs() ? &D->getAttrs() : nullptr, 14492 VD ? cast<DeclRefExpr>(SimpleRefExpr) : nullptr); 14493 if (VDPrivate->isInvalidDecl()) 14494 continue; 14495 14496 CurContext->addDecl(VDPrivate); 14497 DeclRefExpr *VDPrivateRefExpr = buildDeclRefExpr( 14498 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 14499 14500 // Add temporary variable to initialize the private copy of the pointer. 14501 VarDecl *VDInit = 14502 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 14503 DeclRefExpr *VDInitRefExpr = buildDeclRefExpr( 14504 *this, VDInit, RefExpr->getType(), RefExpr->getExprLoc()); 14505 AddInitializerToDecl(VDPrivate, 14506 DefaultLvalueConversion(VDInitRefExpr).get(), 14507 /*DirectInit=*/false); 14508 14509 // If required, build a capture to implement the privatization initialized 14510 // with the current list item value. 14511 DeclRefExpr *Ref = nullptr; 14512 if (!VD) 14513 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 14514 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 14515 PrivateCopies.push_back(VDPrivateRefExpr); 14516 Inits.push_back(VDInitRefExpr); 14517 14518 // We need to add a data sharing attribute for this variable to make sure it 14519 // is correctly captured. A variable that shows up in a use_device_ptr has 14520 // similar properties of a first private variable. 14521 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 14522 14523 // Create a mappable component for the list item. List items in this clause 14524 // only need a component. 14525 MVLI.VarBaseDeclarations.push_back(D); 14526 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14527 MVLI.VarComponents.back().push_back( 14528 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 14529 } 14530 14531 if (MVLI.ProcessedVarList.empty()) 14532 return nullptr; 14533 14534 return OMPUseDevicePtrClause::Create( 14535 Context, Locs, MVLI.ProcessedVarList, PrivateCopies, Inits, 14536 MVLI.VarBaseDeclarations, MVLI.VarComponents); 14537 } 14538 14539 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 14540 const OMPVarListLocTy &Locs) { 14541 MappableVarListInfo MVLI(VarList); 14542 for (Expr *RefExpr : VarList) { 14543 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 14544 SourceLocation ELoc; 14545 SourceRange ERange; 14546 Expr *SimpleRefExpr = RefExpr; 14547 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 14548 if (Res.second) { 14549 // It will be analyzed later. 14550 MVLI.ProcessedVarList.push_back(RefExpr); 14551 } 14552 ValueDecl *D = Res.first; 14553 if (!D) 14554 continue; 14555 14556 QualType Type = D->getType(); 14557 // item should be a pointer or array or reference to pointer or array 14558 if (!Type.getNonReferenceType()->isPointerType() && 14559 !Type.getNonReferenceType()->isArrayType()) { 14560 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 14561 << 0 << RefExpr->getSourceRange(); 14562 continue; 14563 } 14564 14565 // Check if the declaration in the clause does not show up in any data 14566 // sharing attribute. 14567 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, /*FromParent=*/false); 14568 if (isOpenMPPrivate(DVar.CKind)) { 14569 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 14570 << getOpenMPClauseName(DVar.CKind) 14571 << getOpenMPClauseName(OMPC_is_device_ptr) 14572 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 14573 reportOriginalDsa(*this, DSAStack, D, DVar); 14574 continue; 14575 } 14576 14577 const Expr *ConflictExpr; 14578 if (DSAStack->checkMappableExprComponentListsForDecl( 14579 D, /*CurrentRegionOnly=*/true, 14580 [&ConflictExpr]( 14581 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 14582 OpenMPClauseKind) -> bool { 14583 ConflictExpr = R.front().getAssociatedExpression(); 14584 return true; 14585 })) { 14586 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 14587 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 14588 << ConflictExpr->getSourceRange(); 14589 continue; 14590 } 14591 14592 // Store the components in the stack so that they can be used to check 14593 // against other clauses later on. 14594 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 14595 DSAStack->addMappableExpressionComponents( 14596 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 14597 14598 // Record the expression we've just processed. 14599 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 14600 14601 // Create a mappable component for the list item. List items in this clause 14602 // only need a component. We use a null declaration to signal fields in 14603 // 'this'. 14604 assert((isa<DeclRefExpr>(SimpleRefExpr) || 14605 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 14606 "Unexpected device pointer expression!"); 14607 MVLI.VarBaseDeclarations.push_back( 14608 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 14609 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 14610 MVLI.VarComponents.back().push_back(MC); 14611 } 14612 14613 if (MVLI.ProcessedVarList.empty()) 14614 return nullptr; 14615 14616 return OMPIsDevicePtrClause::Create(Context, Locs, MVLI.ProcessedVarList, 14617 MVLI.VarBaseDeclarations, 14618 MVLI.VarComponents); 14619 } 14620