1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// \file 10 /// \brief This file implements semantic analysis for OpenMP directives and 11 /// clauses. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "TreeTransform.h" 16 #include "clang/AST/ASTContext.h" 17 #include "clang/AST/ASTMutationListener.h" 18 #include "clang/AST/CXXInheritance.h" 19 #include "clang/AST/Decl.h" 20 #include "clang/AST/DeclCXX.h" 21 #include "clang/AST/DeclOpenMP.h" 22 #include "clang/AST/StmtCXX.h" 23 #include "clang/AST/StmtOpenMP.h" 24 #include "clang/AST/StmtVisitor.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 Expr *CheckMapClauseExpressionBase( 39 Sema &SemaRef, Expr *E, 40 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 41 OpenMPClauseKind CKind, bool NoDiagnose); 42 43 namespace { 44 /// \brief Default data sharing attributes, which can be applied to directive. 45 enum DefaultDataSharingAttributes { 46 DSA_unspecified = 0, /// \brief Data sharing attribute not specified. 47 DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'. 48 DSA_shared = 1 << 1, /// \brief 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 /// \brief Stack for tracking declarations used in OpenMP directives and 58 /// clauses and their data-sharing attributes. 59 class DSAStackTy final { 60 public: 61 struct DSAVarData final { 62 OpenMPDirectiveKind DKind = OMPD_unknown; 63 OpenMPClauseKind CKind = OMPC_unknown; 64 Expr *RefExpr = nullptr; 65 DeclRefExpr *PrivateCopy = nullptr; 66 SourceLocation ImplicitDSALoc; 67 DSAVarData() = default; 68 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, Expr *RefExpr, 69 DeclRefExpr *PrivateCopy, SourceLocation ImplicitDSALoc) 70 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 71 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 72 }; 73 typedef llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4> 74 OperatorOffsetTy; 75 76 private: 77 struct DSAInfo final { 78 OpenMPClauseKind Attributes = OMPC_unknown; 79 /// Pointer to a reference expression and a flag which shows that the 80 /// variable is marked as lastprivate(true) or not (false). 81 llvm::PointerIntPair<Expr *, 1, bool> RefExpr; 82 DeclRefExpr *PrivateCopy = nullptr; 83 }; 84 typedef llvm::DenseMap<ValueDecl *, DSAInfo> DeclSAMapTy; 85 typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy; 86 typedef std::pair<unsigned, VarDecl *> LCDeclInfo; 87 typedef llvm::DenseMap<ValueDecl *, LCDeclInfo> LoopControlVariablesMapTy; 88 /// Struct that associates a component with the clause kind where they are 89 /// found. 90 struct MappedExprComponentTy { 91 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 92 OpenMPClauseKind Kind = OMPC_unknown; 93 }; 94 typedef llvm::DenseMap<ValueDecl *, MappedExprComponentTy> 95 MappedExprComponentsTy; 96 typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>> 97 CriticalsWithHintsTy; 98 typedef llvm::DenseMap<OMPDependClause *, OperatorOffsetTy> 99 DoacrossDependMapTy; 100 struct ReductionData { 101 typedef llvm::PointerEmbeddedInt<BinaryOperatorKind, 16> BOKPtrType; 102 SourceRange ReductionRange; 103 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 104 ReductionData() = default; 105 void set(BinaryOperatorKind BO, SourceRange RR) { 106 ReductionRange = RR; 107 ReductionOp = BO; 108 } 109 void set(const Expr *RefExpr, SourceRange RR) { 110 ReductionRange = RR; 111 ReductionOp = RefExpr; 112 } 113 }; 114 typedef llvm::DenseMap<ValueDecl *, ReductionData> DeclReductionMapTy; 115 116 struct SharingMapTy final { 117 DeclSAMapTy SharingMap; 118 DeclReductionMapTy ReductionMap; 119 AlignedMapTy AlignedMap; 120 MappedExprComponentsTy MappedExprComponents; 121 LoopControlVariablesMapTy LCVMap; 122 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 123 SourceLocation DefaultAttrLoc; 124 DefaultMapAttributes DefaultMapAttr = DMA_unspecified; 125 SourceLocation DefaultMapAttrLoc; 126 OpenMPDirectiveKind Directive = OMPD_unknown; 127 DeclarationNameInfo DirectiveName; 128 Scope *CurScope = nullptr; 129 SourceLocation ConstructLoc; 130 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 131 /// get the data (loop counters etc.) about enclosing loop-based construct. 132 /// This data is required during codegen. 133 DoacrossDependMapTy DoacrossDepends; 134 /// \brief first argument (Expr *) contains optional argument of the 135 /// 'ordered' clause, the second one is true if the regions has 'ordered' 136 /// clause, false otherwise. 137 llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion; 138 bool NowaitRegion = false; 139 bool CancelRegion = false; 140 unsigned AssociatedLoops = 1; 141 SourceLocation InnerTeamsRegionLoc; 142 /// Reference to the taskgroup task_reduction reference expression. 143 Expr *TaskgroupReductionRef = nullptr; 144 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 145 Scope *CurScope, SourceLocation Loc) 146 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 147 ConstructLoc(Loc) {} 148 SharingMapTy() = default; 149 }; 150 151 typedef SmallVector<SharingMapTy, 4> StackTy; 152 153 /// \brief Stack of used declaration and their data-sharing attributes. 154 DeclSAMapTy Threadprivates; 155 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 156 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 157 /// \brief true, if check for DSA must be from parent directive, false, if 158 /// from current directive. 159 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 160 Sema &SemaRef; 161 bool ForceCapturing = false; 162 CriticalsWithHintsTy Criticals; 163 164 typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; 165 166 DSAVarData getDSA(StackTy::reverse_iterator &Iter, ValueDecl *D); 167 168 /// \brief Checks if the variable is a local for OpenMP region. 169 bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter); 170 171 bool isStackEmpty() const { 172 return Stack.empty() || 173 Stack.back().second != CurrentNonCapturingFunctionScope || 174 Stack.back().first.empty(); 175 } 176 177 public: 178 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 179 180 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 181 OpenMPClauseKind getClauseParsingMode() const { 182 assert(isClauseParsingMode() && "Must be in clause parsing mode."); 183 return ClauseKindMode; 184 } 185 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 186 187 bool isForceVarCapturing() const { return ForceCapturing; } 188 void setForceVarCapturing(bool V) { ForceCapturing = V; } 189 190 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 191 Scope *CurScope, SourceLocation Loc) { 192 if (Stack.empty() || 193 Stack.back().second != CurrentNonCapturingFunctionScope) 194 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 195 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 196 Stack.back().first.back().DefaultAttrLoc = Loc; 197 } 198 199 void pop() { 200 assert(!Stack.back().first.empty() && 201 "Data-sharing attributes stack is empty!"); 202 Stack.back().first.pop_back(); 203 } 204 205 /// Start new OpenMP region stack in new non-capturing function. 206 void pushFunction() { 207 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 208 assert(!isa<CapturingScopeInfo>(CurFnScope)); 209 CurrentNonCapturingFunctionScope = CurFnScope; 210 } 211 /// Pop region stack for non-capturing function. 212 void popFunction(const FunctionScopeInfo *OldFSI) { 213 if (!Stack.empty() && Stack.back().second == OldFSI) { 214 assert(Stack.back().first.empty()); 215 Stack.pop_back(); 216 } 217 CurrentNonCapturingFunctionScope = nullptr; 218 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 219 if (!isa<CapturingScopeInfo>(FSI)) { 220 CurrentNonCapturingFunctionScope = FSI; 221 break; 222 } 223 } 224 } 225 226 void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) { 227 Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint); 228 } 229 const std::pair<OMPCriticalDirective *, llvm::APSInt> 230 getCriticalWithHint(const DeclarationNameInfo &Name) const { 231 auto I = Criticals.find(Name.getAsString()); 232 if (I != Criticals.end()) 233 return I->second; 234 return std::make_pair(nullptr, llvm::APSInt()); 235 } 236 /// \brief If 'aligned' declaration for given variable \a D was not seen yet, 237 /// add it and return NULL; otherwise return previous occurrence's expression 238 /// for diagnostics. 239 Expr *addUniqueAligned(ValueDecl *D, Expr *NewDE); 240 241 /// \brief Register specified variable as loop control variable. 242 void addLoopControlVariable(ValueDecl *D, VarDecl *Capture); 243 /// \brief Check if the specified variable is a loop control variable for 244 /// current region. 245 /// \return The index of the loop control variable in the list of associated 246 /// for-loops (from outer to inner). 247 LCDeclInfo isLoopControlVariable(ValueDecl *D); 248 /// \brief Check if the specified variable is a loop control variable for 249 /// parent region. 250 /// \return The index of the loop control variable in the list of associated 251 /// for-loops (from outer to inner). 252 LCDeclInfo isParentLoopControlVariable(ValueDecl *D); 253 /// \brief Get the loop control variable for the I-th loop (or nullptr) in 254 /// parent directive. 255 ValueDecl *getParentLoopControlVariable(unsigned I); 256 257 /// \brief Adds explicit data sharing attribute to the specified declaration. 258 void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 259 DeclRefExpr *PrivateCopy = nullptr); 260 261 /// Adds additional information for the reduction items with the reduction id 262 /// represented as an operator. 263 void addTaskgroupReductionData(ValueDecl *D, SourceRange SR, 264 BinaryOperatorKind BOK); 265 /// Adds additional information for the reduction items with the reduction id 266 /// represented as reduction identifier. 267 void addTaskgroupReductionData(ValueDecl *D, SourceRange SR, 268 const Expr *ReductionRef); 269 /// Returns the location and reduction operation from the innermost parent 270 /// region for the given \p D. 271 DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, 272 BinaryOperatorKind &BOK, 273 Expr *&TaskgroupDescriptor); 274 /// Returns the location and reduction operation from the innermost parent 275 /// region for the given \p D. 276 DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, 277 const Expr *&ReductionRef, 278 Expr *&TaskgroupDescriptor); 279 /// Return reduction reference expression for the current taskgroup. 280 Expr *getTaskgroupReductionRef() const { 281 assert(Stack.back().first.back().Directive == OMPD_taskgroup && 282 "taskgroup reference expression requested for non taskgroup " 283 "directive."); 284 return Stack.back().first.back().TaskgroupReductionRef; 285 } 286 /// Checks if the given \p VD declaration is actually a taskgroup reduction 287 /// descriptor variable at the \p Level of OpenMP regions. 288 bool isTaskgroupReductionRef(ValueDecl *VD, unsigned Level) const { 289 return Stack.back().first[Level].TaskgroupReductionRef && 290 cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef) 291 ->getDecl() == VD; 292 } 293 294 /// \brief Returns data sharing attributes from top of the stack for the 295 /// specified declaration. 296 DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 297 /// \brief Returns data-sharing attributes for the specified declaration. 298 DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent); 299 /// \brief Checks if the specified variables has data-sharing attributes which 300 /// match specified \a CPred predicate in any directive which matches \a DPred 301 /// predicate. 302 DSAVarData hasDSA(ValueDecl *D, 303 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 304 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 305 bool FromParent); 306 /// \brief Checks if the specified variables has data-sharing attributes which 307 /// match specified \a CPred predicate in any innermost directive which 308 /// matches \a DPred predicate. 309 DSAVarData 310 hasInnermostDSA(ValueDecl *D, 311 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 312 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 313 bool FromParent); 314 /// \brief Checks if the specified variables has explicit data-sharing 315 /// attributes which match specified \a CPred predicate at the specified 316 /// OpenMP region. 317 bool hasExplicitDSA(ValueDecl *D, 318 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 319 unsigned Level, bool NotLastprivate = false); 320 321 /// \brief Returns true if the directive at level \Level matches in the 322 /// specified \a DPred predicate. 323 bool hasExplicitDirective( 324 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 325 unsigned Level); 326 327 /// \brief Finds a directive which matches specified \a DPred predicate. 328 bool hasDirective(const llvm::function_ref<bool(OpenMPDirectiveKind, 329 const DeclarationNameInfo &, 330 SourceLocation)> &DPred, 331 bool FromParent); 332 333 /// \brief Returns currently analyzed directive. 334 OpenMPDirectiveKind getCurrentDirective() const { 335 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive; 336 } 337 /// \brief Returns directive kind at specified level. 338 OpenMPDirectiveKind getDirective(unsigned Level) const { 339 assert(!isStackEmpty() && "No directive at specified level."); 340 return Stack.back().first[Level].Directive; 341 } 342 /// \brief Returns parent directive. 343 OpenMPDirectiveKind getParentDirective() const { 344 if (isStackEmpty() || Stack.back().first.size() == 1) 345 return OMPD_unknown; 346 return std::next(Stack.back().first.rbegin())->Directive; 347 } 348 349 /// \brief Set default data sharing attribute to none. 350 void setDefaultDSANone(SourceLocation Loc) { 351 assert(!isStackEmpty()); 352 Stack.back().first.back().DefaultAttr = DSA_none; 353 Stack.back().first.back().DefaultAttrLoc = Loc; 354 } 355 /// \brief Set default data sharing attribute to shared. 356 void setDefaultDSAShared(SourceLocation Loc) { 357 assert(!isStackEmpty()); 358 Stack.back().first.back().DefaultAttr = DSA_shared; 359 Stack.back().first.back().DefaultAttrLoc = Loc; 360 } 361 /// Set default data mapping attribute to 'tofrom:scalar'. 362 void setDefaultDMAToFromScalar(SourceLocation Loc) { 363 assert(!isStackEmpty()); 364 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar; 365 Stack.back().first.back().DefaultMapAttrLoc = Loc; 366 } 367 368 DefaultDataSharingAttributes getDefaultDSA() const { 369 return isStackEmpty() ? DSA_unspecified 370 : Stack.back().first.back().DefaultAttr; 371 } 372 SourceLocation getDefaultDSALocation() const { 373 return isStackEmpty() ? SourceLocation() 374 : Stack.back().first.back().DefaultAttrLoc; 375 } 376 DefaultMapAttributes getDefaultDMA() const { 377 return isStackEmpty() ? DMA_unspecified 378 : Stack.back().first.back().DefaultMapAttr; 379 } 380 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 381 return Stack.back().first[Level].DefaultMapAttr; 382 } 383 SourceLocation getDefaultDMALocation() const { 384 return isStackEmpty() ? SourceLocation() 385 : Stack.back().first.back().DefaultMapAttrLoc; 386 } 387 388 /// \brief Checks if the specified variable is a threadprivate. 389 bool isThreadPrivate(VarDecl *D) { 390 DSAVarData DVar = getTopDSA(D, false); 391 return isOpenMPThreadPrivate(DVar.CKind); 392 } 393 394 /// \brief Marks current region as ordered (it has an 'ordered' clause). 395 void setOrderedRegion(bool IsOrdered, Expr *Param) { 396 assert(!isStackEmpty()); 397 Stack.back().first.back().OrderedRegion.setInt(IsOrdered); 398 Stack.back().first.back().OrderedRegion.setPointer(Param); 399 } 400 /// \brief Returns true, if parent region is ordered (has associated 401 /// 'ordered' clause), false - otherwise. 402 bool isParentOrderedRegion() const { 403 if (isStackEmpty() || Stack.back().first.size() == 1) 404 return false; 405 return std::next(Stack.back().first.rbegin())->OrderedRegion.getInt(); 406 } 407 /// \brief Returns optional parameter for the ordered region. 408 Expr *getParentOrderedRegionParam() const { 409 if (isStackEmpty() || Stack.back().first.size() == 1) 410 return nullptr; 411 return std::next(Stack.back().first.rbegin())->OrderedRegion.getPointer(); 412 } 413 /// \brief Marks current region as nowait (it has a 'nowait' clause). 414 void setNowaitRegion(bool IsNowait = true) { 415 assert(!isStackEmpty()); 416 Stack.back().first.back().NowaitRegion = IsNowait; 417 } 418 /// \brief Returns true, if parent region is nowait (has associated 419 /// 'nowait' clause), false - otherwise. 420 bool isParentNowaitRegion() const { 421 if (isStackEmpty() || Stack.back().first.size() == 1) 422 return false; 423 return std::next(Stack.back().first.rbegin())->NowaitRegion; 424 } 425 /// \brief Marks parent region as cancel region. 426 void setParentCancelRegion(bool Cancel = true) { 427 if (!isStackEmpty() && Stack.back().first.size() > 1) { 428 auto &StackElemRef = *std::next(Stack.back().first.rbegin()); 429 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel; 430 } 431 } 432 /// \brief Return true if current region has inner cancel construct. 433 bool isCancelRegion() const { 434 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion; 435 } 436 437 /// \brief Set collapse value for the region. 438 void setAssociatedLoops(unsigned Val) { 439 assert(!isStackEmpty()); 440 Stack.back().first.back().AssociatedLoops = Val; 441 } 442 /// \brief Return collapse value for region. 443 unsigned getAssociatedLoops() const { 444 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops; 445 } 446 447 /// \brief Marks current target region as one with closely nested teams 448 /// region. 449 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 450 if (!isStackEmpty() && Stack.back().first.size() > 1) { 451 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc = 452 TeamsRegionLoc; 453 } 454 } 455 /// \brief Returns true, if current region has closely nested teams region. 456 bool hasInnerTeamsRegion() const { 457 return getInnerTeamsRegionLoc().isValid(); 458 } 459 /// \brief Returns location of the nested teams region (if any). 460 SourceLocation getInnerTeamsRegionLoc() const { 461 return isStackEmpty() ? SourceLocation() 462 : Stack.back().first.back().InnerTeamsRegionLoc; 463 } 464 465 Scope *getCurScope() const { 466 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 467 } 468 Scope *getCurScope() { 469 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 470 } 471 SourceLocation getConstructLoc() { 472 return isStackEmpty() ? SourceLocation() 473 : Stack.back().first.back().ConstructLoc; 474 } 475 476 /// Do the check specified in \a Check to all component lists and return true 477 /// if any issue is found. 478 bool checkMappableExprComponentListsForDecl( 479 ValueDecl *VD, bool CurrentRegionOnly, 480 const llvm::function_ref< 481 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 482 OpenMPClauseKind)> &Check) { 483 if (isStackEmpty()) 484 return false; 485 auto SI = Stack.back().first.rbegin(); 486 auto SE = Stack.back().first.rend(); 487 488 if (SI == SE) 489 return false; 490 491 if (CurrentRegionOnly) { 492 SE = std::next(SI); 493 } else { 494 ++SI; 495 } 496 497 for (; SI != SE; ++SI) { 498 auto MI = SI->MappedExprComponents.find(VD); 499 if (MI != SI->MappedExprComponents.end()) 500 for (auto &L : MI->second.Components) 501 if (Check(L, MI->second.Kind)) 502 return true; 503 } 504 return false; 505 } 506 507 /// Do the check specified in \a Check to all component lists at a given level 508 /// and return true if any issue is found. 509 bool checkMappableExprComponentListsForDeclAtLevel( 510 ValueDecl *VD, unsigned Level, 511 const llvm::function_ref< 512 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 513 OpenMPClauseKind)> &Check) { 514 if (isStackEmpty()) 515 return false; 516 517 auto StartI = Stack.back().first.begin(); 518 auto EndI = Stack.back().first.end(); 519 if (std::distance(StartI, EndI) <= (int)Level) 520 return false; 521 std::advance(StartI, Level); 522 523 auto MI = StartI->MappedExprComponents.find(VD); 524 if (MI != StartI->MappedExprComponents.end()) 525 for (auto &L : MI->second.Components) 526 if (Check(L, MI->second.Kind)) 527 return true; 528 return false; 529 } 530 531 /// Create a new mappable expression component list associated with a given 532 /// declaration and initialize it with the provided list of components. 533 void addMappableExpressionComponents( 534 ValueDecl *VD, 535 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 536 OpenMPClauseKind WhereFoundClauseKind) { 537 assert(!isStackEmpty() && 538 "Not expecting to retrieve components from a empty stack!"); 539 auto &MEC = Stack.back().first.back().MappedExprComponents[VD]; 540 // Create new entry and append the new components there. 541 MEC.Components.resize(MEC.Components.size() + 1); 542 MEC.Components.back().append(Components.begin(), Components.end()); 543 MEC.Kind = WhereFoundClauseKind; 544 } 545 546 unsigned getNestingLevel() const { 547 assert(!isStackEmpty()); 548 return Stack.back().first.size() - 1; 549 } 550 void addDoacrossDependClause(OMPDependClause *C, OperatorOffsetTy &OpsOffs) { 551 assert(!isStackEmpty() && Stack.back().first.size() > 1); 552 auto &StackElem = *std::next(Stack.back().first.rbegin()); 553 assert(isOpenMPWorksharingDirective(StackElem.Directive)); 554 StackElem.DoacrossDepends.insert({C, OpsOffs}); 555 } 556 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 557 getDoacrossDependClauses() const { 558 assert(!isStackEmpty()); 559 auto &StackElem = Stack.back().first.back(); 560 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 561 auto &Ref = StackElem.DoacrossDepends; 562 return llvm::make_range(Ref.begin(), Ref.end()); 563 } 564 return llvm::make_range(StackElem.DoacrossDepends.end(), 565 StackElem.DoacrossDepends.end()); 566 } 567 }; 568 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { 569 return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) || 570 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; 571 } 572 } // namespace 573 574 static Expr *getExprAsWritten(Expr *E) { 575 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) 576 E = ExprTemp->getSubExpr(); 577 578 if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 579 E = MTE->GetTemporaryExpr(); 580 581 while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 582 E = Binder->getSubExpr(); 583 584 if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 585 E = ICE->getSubExprAsWritten(); 586 return E->IgnoreParens(); 587 } 588 589 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 590 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 591 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 592 D = ME->getMemberDecl(); 593 auto *VD = dyn_cast<VarDecl>(D); 594 auto *FD = dyn_cast<FieldDecl>(D); 595 if (VD != nullptr) { 596 VD = VD->getCanonicalDecl(); 597 D = VD; 598 } else { 599 assert(FD); 600 FD = FD->getCanonicalDecl(); 601 D = FD; 602 } 603 return D; 604 } 605 606 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter, 607 ValueDecl *D) { 608 D = getCanonicalDecl(D); 609 auto *VD = dyn_cast<VarDecl>(D); 610 auto *FD = dyn_cast<FieldDecl>(D); 611 DSAVarData DVar; 612 if (isStackEmpty() || Iter == Stack.back().first.rend()) { 613 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 614 // in a region but not in construct] 615 // File-scope or namespace-scope variables referenced in called routines 616 // in the region are shared unless they appear in a threadprivate 617 // directive. 618 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D)) 619 DVar.CKind = OMPC_shared; 620 621 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 622 // in a region but not in construct] 623 // Variables with static storage duration that are declared in called 624 // routines in the region are shared. 625 if (VD && VD->hasGlobalStorage()) 626 DVar.CKind = OMPC_shared; 627 628 // Non-static data members are shared by default. 629 if (FD) 630 DVar.CKind = OMPC_shared; 631 632 return DVar; 633 } 634 635 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 636 // in a Construct, C/C++, predetermined, p.1] 637 // Variables with automatic storage duration that are declared in a scope 638 // inside the construct are private. 639 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 640 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 641 DVar.CKind = OMPC_private; 642 return DVar; 643 } 644 645 DVar.DKind = Iter->Directive; 646 // Explicitly specified attributes and local variables with predetermined 647 // attributes. 648 if (Iter->SharingMap.count(D)) { 649 DVar.RefExpr = Iter->SharingMap[D].RefExpr.getPointer(); 650 DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy; 651 DVar.CKind = Iter->SharingMap[D].Attributes; 652 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 653 return DVar; 654 } 655 656 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 657 // in a Construct, C/C++, implicitly determined, p.1] 658 // In a parallel or task construct, the data-sharing attributes of these 659 // variables are determined by the default clause, if present. 660 switch (Iter->DefaultAttr) { 661 case DSA_shared: 662 DVar.CKind = OMPC_shared; 663 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 664 return DVar; 665 case DSA_none: 666 return DVar; 667 case DSA_unspecified: 668 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 669 // in a Construct, implicitly determined, p.2] 670 // In a parallel construct, if no default clause is present, these 671 // variables are shared. 672 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 673 if (isOpenMPParallelDirective(DVar.DKind) || 674 isOpenMPTeamsDirective(DVar.DKind)) { 675 DVar.CKind = OMPC_shared; 676 return DVar; 677 } 678 679 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 680 // in a Construct, implicitly determined, p.4] 681 // In a task construct, if no default clause is present, a variable that in 682 // the enclosing context is determined to be shared by all implicit tasks 683 // bound to the current team is shared. 684 if (isOpenMPTaskingDirective(DVar.DKind)) { 685 DSAVarData DVarTemp; 686 auto I = Iter, E = Stack.back().first.rend(); 687 do { 688 ++I; 689 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 690 // Referenced in a Construct, implicitly determined, p.6] 691 // In a task construct, if no default clause is present, a variable 692 // whose data-sharing attribute is not determined by the rules above is 693 // firstprivate. 694 DVarTemp = getDSA(I, D); 695 if (DVarTemp.CKind != OMPC_shared) { 696 DVar.RefExpr = nullptr; 697 DVar.CKind = OMPC_firstprivate; 698 return DVar; 699 } 700 } while (I != E && !isParallelOrTaskRegion(I->Directive)); 701 DVar.CKind = 702 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 703 return DVar; 704 } 705 } 706 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 707 // in a Construct, implicitly determined, p.3] 708 // For constructs other than task, if no default clause is present, these 709 // variables inherit their data-sharing attributes from the enclosing 710 // context. 711 return getDSA(++Iter, D); 712 } 713 714 Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) { 715 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 716 D = getCanonicalDecl(D); 717 auto &StackElem = Stack.back().first.back(); 718 auto It = StackElem.AlignedMap.find(D); 719 if (It == StackElem.AlignedMap.end()) { 720 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 721 StackElem.AlignedMap[D] = NewDE; 722 return nullptr; 723 } else { 724 assert(It->second && "Unexpected nullptr expr in the aligned map"); 725 return It->second; 726 } 727 return nullptr; 728 } 729 730 void DSAStackTy::addLoopControlVariable(ValueDecl *D, VarDecl *Capture) { 731 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 732 D = getCanonicalDecl(D); 733 auto &StackElem = Stack.back().first.back(); 734 StackElem.LCVMap.insert( 735 {D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)}); 736 } 737 738 DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(ValueDecl *D) { 739 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 740 D = getCanonicalDecl(D); 741 auto &StackElem = Stack.back().first.back(); 742 auto It = StackElem.LCVMap.find(D); 743 if (It != StackElem.LCVMap.end()) 744 return It->second; 745 return {0, nullptr}; 746 } 747 748 DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(ValueDecl *D) { 749 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 750 "Data-sharing attributes stack is empty"); 751 D = getCanonicalDecl(D); 752 auto &StackElem = *std::next(Stack.back().first.rbegin()); 753 auto It = StackElem.LCVMap.find(D); 754 if (It != StackElem.LCVMap.end()) 755 return It->second; 756 return {0, nullptr}; 757 } 758 759 ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) { 760 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 761 "Data-sharing attributes stack is empty"); 762 auto &StackElem = *std::next(Stack.back().first.rbegin()); 763 if (StackElem.LCVMap.size() < I) 764 return nullptr; 765 for (auto &Pair : StackElem.LCVMap) 766 if (Pair.second.first == I) 767 return Pair.first; 768 return nullptr; 769 } 770 771 void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 772 DeclRefExpr *PrivateCopy) { 773 D = getCanonicalDecl(D); 774 if (A == OMPC_threadprivate) { 775 auto &Data = Threadprivates[D]; 776 Data.Attributes = A; 777 Data.RefExpr.setPointer(E); 778 Data.PrivateCopy = nullptr; 779 } else { 780 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 781 auto &Data = Stack.back().first.back().SharingMap[D]; 782 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 783 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 784 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 785 (isLoopControlVariable(D).first && A == OMPC_private)); 786 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 787 Data.RefExpr.setInt(/*IntVal=*/true); 788 return; 789 } 790 const bool IsLastprivate = 791 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 792 Data.Attributes = A; 793 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 794 Data.PrivateCopy = PrivateCopy; 795 if (PrivateCopy) { 796 auto &Data = Stack.back().first.back().SharingMap[PrivateCopy->getDecl()]; 797 Data.Attributes = A; 798 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 799 Data.PrivateCopy = nullptr; 800 } 801 } 802 } 803 804 /// \brief Build a variable declaration for OpenMP loop iteration variable. 805 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 806 StringRef Name, const AttrVec *Attrs = nullptr) { 807 DeclContext *DC = SemaRef.CurContext; 808 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 809 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 810 VarDecl *Decl = 811 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 812 if (Attrs) { 813 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 814 I != E; ++I) 815 Decl->addAttr(*I); 816 } 817 Decl->setImplicit(); 818 return Decl; 819 } 820 821 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 822 SourceLocation Loc, 823 bool RefersToCapture = false) { 824 D->setReferenced(); 825 D->markUsed(S.Context); 826 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 827 SourceLocation(), D, RefersToCapture, Loc, Ty, 828 VK_LValue); 829 } 830 831 void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR, 832 BinaryOperatorKind BOK) { 833 D = getCanonicalDecl(D); 834 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 835 assert( 836 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 837 "Additional reduction info may be specified only for reduction items."); 838 auto &ReductionData = Stack.back().first.back().ReductionMap[D]; 839 assert(ReductionData.ReductionRange.isInvalid() && 840 Stack.back().first.back().Directive == OMPD_taskgroup && 841 "Additional reduction info may be specified only once for reduction " 842 "items."); 843 ReductionData.set(BOK, SR); 844 Expr *&TaskgroupReductionRef = 845 Stack.back().first.back().TaskgroupReductionRef; 846 if (!TaskgroupReductionRef) { 847 auto *VD = buildVarDecl(SemaRef, SR.getBegin(), 848 SemaRef.Context.VoidPtrTy, ".task_red."); 849 TaskgroupReductionRef = 850 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 851 } 852 } 853 854 void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR, 855 const Expr *ReductionRef) { 856 D = getCanonicalDecl(D); 857 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 858 assert( 859 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 860 "Additional reduction info may be specified only for reduction items."); 861 auto &ReductionData = Stack.back().first.back().ReductionMap[D]; 862 assert(ReductionData.ReductionRange.isInvalid() && 863 Stack.back().first.back().Directive == OMPD_taskgroup && 864 "Additional reduction info may be specified only once for reduction " 865 "items."); 866 ReductionData.set(ReductionRef, SR); 867 Expr *&TaskgroupReductionRef = 868 Stack.back().first.back().TaskgroupReductionRef; 869 if (!TaskgroupReductionRef) { 870 auto *VD = buildVarDecl(SemaRef, SR.getBegin(), SemaRef.Context.VoidPtrTy, 871 ".task_red."); 872 TaskgroupReductionRef = 873 buildDeclRefExpr(SemaRef, VD, SemaRef.Context.VoidPtrTy, SR.getBegin()); 874 } 875 } 876 877 DSAStackTy::DSAVarData 878 DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, 879 BinaryOperatorKind &BOK, 880 Expr *&TaskgroupDescriptor) { 881 D = getCanonicalDecl(D); 882 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 883 if (Stack.back().first.empty()) 884 return DSAVarData(); 885 for (auto I = std::next(Stack.back().first.rbegin(), 1), 886 E = Stack.back().first.rend(); 887 I != E; std::advance(I, 1)) { 888 auto &Data = I->SharingMap[D]; 889 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 890 continue; 891 auto &ReductionData = I->ReductionMap[D]; 892 if (!ReductionData.ReductionOp || 893 ReductionData.ReductionOp.is<const Expr *>()) 894 return DSAVarData(); 895 SR = ReductionData.ReductionRange; 896 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 897 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 898 "expression for the descriptor is not " 899 "set."); 900 TaskgroupDescriptor = I->TaskgroupReductionRef; 901 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 902 Data.PrivateCopy, I->DefaultAttrLoc); 903 } 904 return DSAVarData(); 905 } 906 907 DSAStackTy::DSAVarData 908 DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, 909 const Expr *&ReductionRef, 910 Expr *&TaskgroupDescriptor) { 911 D = getCanonicalDecl(D); 912 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 913 if (Stack.back().first.empty()) 914 return DSAVarData(); 915 for (auto I = std::next(Stack.back().first.rbegin(), 1), 916 E = Stack.back().first.rend(); 917 I != E; std::advance(I, 1)) { 918 auto &Data = I->SharingMap[D]; 919 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 920 continue; 921 auto &ReductionData = I->ReductionMap[D]; 922 if (!ReductionData.ReductionOp || 923 !ReductionData.ReductionOp.is<const Expr *>()) 924 return DSAVarData(); 925 SR = ReductionData.ReductionRange; 926 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 927 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 928 "expression for the descriptor is not " 929 "set."); 930 TaskgroupDescriptor = I->TaskgroupReductionRef; 931 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 932 Data.PrivateCopy, I->DefaultAttrLoc); 933 } 934 return DSAVarData(); 935 } 936 937 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) { 938 D = D->getCanonicalDecl(); 939 if (!isStackEmpty() && Stack.back().first.size() > 1) { 940 reverse_iterator I = Iter, E = Stack.back().first.rend(); 941 Scope *TopScope = nullptr; 942 while (I != E && !isParallelOrTaskRegion(I->Directive)) 943 ++I; 944 if (I == E) 945 return false; 946 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 947 Scope *CurScope = getCurScope(); 948 while (CurScope != TopScope && !CurScope->isDeclScope(D)) 949 CurScope = CurScope->getParent(); 950 return CurScope != TopScope; 951 } 952 return false; 953 } 954 955 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) { 956 D = getCanonicalDecl(D); 957 DSAVarData DVar; 958 959 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 960 // in a Construct, C/C++, predetermined, p.1] 961 // Variables appearing in threadprivate directives are threadprivate. 962 auto *VD = dyn_cast<VarDecl>(D); 963 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 964 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 965 SemaRef.getLangOpts().OpenMPUseTLS && 966 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 967 (VD && VD->getStorageClass() == SC_Register && 968 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 969 addDSA(D, buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 970 D->getLocation()), 971 OMPC_threadprivate); 972 } 973 auto TI = Threadprivates.find(D); 974 if (TI != Threadprivates.end()) { 975 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 976 DVar.CKind = OMPC_threadprivate; 977 return DVar; 978 } else if (VD && VD->hasAttr<OMPThreadPrivateDeclAttr>()) { 979 DVar.RefExpr = buildDeclRefExpr( 980 SemaRef, VD, D->getType().getNonReferenceType(), 981 VD->getAttr<OMPThreadPrivateDeclAttr>()->getLocation()); 982 DVar.CKind = OMPC_threadprivate; 983 addDSA(D, DVar.RefExpr, OMPC_threadprivate); 984 } 985 986 if (isStackEmpty()) 987 // Not in OpenMP execution region and top scope was already checked. 988 return DVar; 989 990 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 991 // in a Construct, C/C++, predetermined, p.4] 992 // Static data members are shared. 993 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 994 // in a Construct, C/C++, predetermined, p.7] 995 // Variables with static storage duration that are declared in a scope 996 // inside the construct are shared. 997 auto &&MatchesAlways = [](OpenMPDirectiveKind) -> bool { return true; }; 998 if (VD && VD->isStaticDataMember()) { 999 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 1000 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 1001 return DVar; 1002 1003 DVar.CKind = OMPC_shared; 1004 return DVar; 1005 } 1006 1007 QualType Type = D->getType().getNonReferenceType().getCanonicalType(); 1008 bool IsConstant = Type.isConstant(SemaRef.getASTContext()); 1009 Type = SemaRef.getASTContext().getBaseElementType(Type); 1010 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 1011 // in a Construct, C/C++, predetermined, p.6] 1012 // Variables with const qualified type having no mutable member are 1013 // shared. 1014 CXXRecordDecl *RD = 1015 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 1016 if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1017 if (auto *CTD = CTSD->getSpecializedTemplate()) 1018 RD = CTD->getTemplatedDecl(); 1019 if (IsConstant && 1020 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() && 1021 RD->hasMutableFields())) { 1022 // Variables with const-qualified type having no mutable member may be 1023 // listed in a firstprivate clause, even if they are static data members. 1024 DSAVarData DVarTemp = hasDSA( 1025 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_firstprivate; }, 1026 MatchesAlways, FromParent); 1027 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 1028 return DVar; 1029 1030 DVar.CKind = OMPC_shared; 1031 return DVar; 1032 } 1033 1034 // Explicitly specified attributes and local variables with predetermined 1035 // attributes. 1036 auto I = Stack.back().first.rbegin(); 1037 auto EndI = Stack.back().first.rend(); 1038 if (FromParent && I != EndI) 1039 std::advance(I, 1); 1040 if (I->SharingMap.count(D)) { 1041 DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer(); 1042 DVar.PrivateCopy = I->SharingMap[D].PrivateCopy; 1043 DVar.CKind = I->SharingMap[D].Attributes; 1044 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1045 DVar.DKind = I->Directive; 1046 } 1047 1048 return DVar; 1049 } 1050 1051 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1052 bool FromParent) { 1053 if (isStackEmpty()) { 1054 StackTy::reverse_iterator I; 1055 return getDSA(I, D); 1056 } 1057 D = getCanonicalDecl(D); 1058 auto StartI = Stack.back().first.rbegin(); 1059 auto EndI = Stack.back().first.rend(); 1060 if (FromParent && StartI != EndI) 1061 std::advance(StartI, 1); 1062 return getDSA(StartI, D); 1063 } 1064 1065 DSAStackTy::DSAVarData 1066 DSAStackTy::hasDSA(ValueDecl *D, 1067 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 1068 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 1069 bool FromParent) { 1070 if (isStackEmpty()) 1071 return {}; 1072 D = getCanonicalDecl(D); 1073 auto I = Stack.back().first.rbegin(); 1074 auto EndI = Stack.back().first.rend(); 1075 if (FromParent && I != EndI) 1076 std::advance(I, 1); 1077 for (; I != EndI; std::advance(I, 1)) { 1078 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) 1079 continue; 1080 auto NewI = I; 1081 DSAVarData DVar = getDSA(NewI, D); 1082 if (I == NewI && CPred(DVar.CKind)) 1083 return DVar; 1084 } 1085 return {}; 1086 } 1087 1088 DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1089 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 1090 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 1091 bool FromParent) { 1092 if (isStackEmpty()) 1093 return {}; 1094 D = getCanonicalDecl(D); 1095 auto StartI = Stack.back().first.rbegin(); 1096 auto EndI = Stack.back().first.rend(); 1097 if (FromParent && StartI != EndI) 1098 std::advance(StartI, 1); 1099 if (StartI == EndI || !DPred(StartI->Directive)) 1100 return {}; 1101 auto NewI = StartI; 1102 DSAVarData DVar = getDSA(NewI, D); 1103 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1104 } 1105 1106 bool DSAStackTy::hasExplicitDSA( 1107 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 1108 unsigned Level, bool NotLastprivate) { 1109 if (isStackEmpty()) 1110 return false; 1111 D = getCanonicalDecl(D); 1112 auto StartI = Stack.back().first.begin(); 1113 auto EndI = Stack.back().first.end(); 1114 if (std::distance(StartI, EndI) <= (int)Level) 1115 return false; 1116 std::advance(StartI, Level); 1117 return (StartI->SharingMap.count(D) > 0) && 1118 StartI->SharingMap[D].RefExpr.getPointer() && 1119 CPred(StartI->SharingMap[D].Attributes) && 1120 (!NotLastprivate || !StartI->SharingMap[D].RefExpr.getInt()); 1121 } 1122 1123 bool DSAStackTy::hasExplicitDirective( 1124 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 1125 unsigned Level) { 1126 if (isStackEmpty()) 1127 return false; 1128 auto StartI = Stack.back().first.begin(); 1129 auto EndI = Stack.back().first.end(); 1130 if (std::distance(StartI, EndI) <= (int)Level) 1131 return false; 1132 std::advance(StartI, Level); 1133 return DPred(StartI->Directive); 1134 } 1135 1136 bool DSAStackTy::hasDirective( 1137 const llvm::function_ref<bool(OpenMPDirectiveKind, 1138 const DeclarationNameInfo &, SourceLocation)> 1139 &DPred, 1140 bool FromParent) { 1141 // We look only in the enclosing region. 1142 if (isStackEmpty()) 1143 return false; 1144 auto StartI = std::next(Stack.back().first.rbegin()); 1145 auto EndI = Stack.back().first.rend(); 1146 if (FromParent && StartI != EndI) 1147 StartI = std::next(StartI); 1148 for (auto I = StartI, EE = EndI; I != EE; ++I) { 1149 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1150 return true; 1151 } 1152 return false; 1153 } 1154 1155 void Sema::InitDataSharingAttributesStack() { 1156 VarDataSharingAttributesStack = new DSAStackTy(*this); 1157 } 1158 1159 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1160 1161 void Sema::pushOpenMPFunctionRegion() { 1162 DSAStack->pushFunction(); 1163 } 1164 1165 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1166 DSAStack->popFunction(OldFSI); 1167 } 1168 1169 bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level) { 1170 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1171 1172 auto &Ctx = getASTContext(); 1173 bool IsByRef = true; 1174 1175 // Find the directive that is associated with the provided scope. 1176 D = cast<ValueDecl>(D->getCanonicalDecl()); 1177 auto Ty = D->getType(); 1178 1179 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1180 // This table summarizes how a given variable should be passed to the device 1181 // given its type and the clauses where it appears. This table is based on 1182 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1183 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1184 // 1185 // ========================================================================= 1186 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1187 // | |(tofrom:scalar)| | pvt | | | | 1188 // ========================================================================= 1189 // | scl | | | | - | | bycopy| 1190 // | scl | | - | x | - | - | bycopy| 1191 // | scl | | x | - | - | - | null | 1192 // | scl | x | | | - | | byref | 1193 // | scl | x | - | x | - | - | bycopy| 1194 // | scl | x | x | - | - | - | null | 1195 // | scl | | - | - | - | x | byref | 1196 // | scl | x | - | - | - | x | byref | 1197 // 1198 // | agg | n.a. | | | - | | byref | 1199 // | agg | n.a. | - | x | - | - | byref | 1200 // | agg | n.a. | x | - | - | - | null | 1201 // | agg | n.a. | - | - | - | x | byref | 1202 // | agg | n.a. | - | - | - | x[] | byref | 1203 // 1204 // | ptr | n.a. | | | - | | bycopy| 1205 // | ptr | n.a. | - | x | - | - | bycopy| 1206 // | ptr | n.a. | x | - | - | - | null | 1207 // | ptr | n.a. | - | - | - | x | byref | 1208 // | ptr | n.a. | - | - | - | x[] | bycopy| 1209 // | ptr | n.a. | - | - | x | | bycopy| 1210 // | ptr | n.a. | - | - | x | x | bycopy| 1211 // | ptr | n.a. | - | - | x | x[] | bycopy| 1212 // ========================================================================= 1213 // Legend: 1214 // scl - scalar 1215 // ptr - pointer 1216 // agg - aggregate 1217 // x - applies 1218 // - - invalid in this combination 1219 // [] - mapped with an array section 1220 // byref - should be mapped by reference 1221 // byval - should be mapped by value 1222 // null - initialize a local variable to null on the device 1223 // 1224 // Observations: 1225 // - All scalar declarations that show up in a map clause have to be passed 1226 // by reference, because they may have been mapped in the enclosing data 1227 // environment. 1228 // - If the scalar value does not fit the size of uintptr, it has to be 1229 // passed by reference, regardless the result in the table above. 1230 // - For pointers mapped by value that have either an implicit map or an 1231 // array section, the runtime library may pass the NULL value to the 1232 // device instead of the value passed to it by the compiler. 1233 1234 if (Ty->isReferenceType()) 1235 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1236 1237 // Locate map clauses and see if the variable being captured is referred to 1238 // in any of those clauses. Here we only care about variables, not fields, 1239 // because fields are part of aggregates. 1240 bool IsVariableUsedInMapClause = false; 1241 bool IsVariableAssociatedWithSection = false; 1242 1243 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1244 D, Level, [&](OMPClauseMappableExprCommon::MappableExprComponentListRef 1245 MapExprComponents, 1246 OpenMPClauseKind WhereFoundClauseKind) { 1247 // Only the map clause information influences how a variable is 1248 // captured. E.g. is_device_ptr does not require changing the default 1249 // behavior. 1250 if (WhereFoundClauseKind != OMPC_map) 1251 return false; 1252 1253 auto EI = MapExprComponents.rbegin(); 1254 auto EE = MapExprComponents.rend(); 1255 1256 assert(EI != EE && "Invalid map expression!"); 1257 1258 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1259 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1260 1261 ++EI; 1262 if (EI == EE) 1263 return false; 1264 1265 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1266 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1267 isa<MemberExpr>(EI->getAssociatedExpression())) { 1268 IsVariableAssociatedWithSection = true; 1269 // There is nothing more we need to know about this variable. 1270 return true; 1271 } 1272 1273 // Keep looking for more map info. 1274 return false; 1275 }); 1276 1277 if (IsVariableUsedInMapClause) { 1278 // If variable is identified in a map clause it is always captured by 1279 // reference except if it is a pointer that is dereferenced somehow. 1280 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1281 } else { 1282 // By default, all the data that has a scalar type is mapped by copy 1283 // (except for reduction variables). 1284 IsByRef = 1285 !Ty->isScalarType() || 1286 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar || 1287 DSAStack->hasExplicitDSA( 1288 D, [](OpenMPClauseKind K) { return K == OMPC_reduction; }, Level); 1289 } 1290 } 1291 1292 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1293 IsByRef = 1294 !DSAStack->hasExplicitDSA( 1295 D, 1296 [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1297 Level, /*NotLastprivate=*/true) && 1298 // If the variable is artificial and must be captured by value - try to 1299 // capture by value. 1300 !(isa<OMPCapturedExprDecl>(D) && !D->hasAttr<OMPCaptureNoInitAttr>() && 1301 !cast<OMPCapturedExprDecl>(D)->getInit()->isGLValue()); 1302 } 1303 1304 // When passing data by copy, we need to make sure it fits the uintptr size 1305 // and alignment, because the runtime library only deals with uintptr types. 1306 // If it does not fit the uintptr size, we need to pass the data by reference 1307 // instead. 1308 if (!IsByRef && 1309 (Ctx.getTypeSizeInChars(Ty) > 1310 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1311 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1312 IsByRef = true; 1313 } 1314 1315 return IsByRef; 1316 } 1317 1318 unsigned Sema::getOpenMPNestingLevel() const { 1319 assert(getLangOpts().OpenMP); 1320 return DSAStack->getNestingLevel(); 1321 } 1322 1323 bool Sema::isInOpenMPTargetExecutionDirective() const { 1324 return (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1325 !DSAStack->isClauseParsingMode()) || 1326 DSAStack->hasDirective( 1327 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1328 SourceLocation) -> bool { 1329 return isOpenMPTargetExecutionDirective(K); 1330 }, 1331 false); 1332 } 1333 1334 VarDecl *Sema::IsOpenMPCapturedDecl(ValueDecl *D) { 1335 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1336 D = getCanonicalDecl(D); 1337 1338 // If we are attempting to capture a global variable in a directive with 1339 // 'target' we return true so that this global is also mapped to the device. 1340 // 1341 // FIXME: If the declaration is enclosed in a 'declare target' directive, 1342 // then it should not be captured. Therefore, an extra check has to be 1343 // inserted here once support for 'declare target' is added. 1344 // 1345 auto *VD = dyn_cast<VarDecl>(D); 1346 if (VD && !VD->hasLocalStorage() && isInOpenMPTargetExecutionDirective()) 1347 return VD; 1348 1349 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1350 (!DSAStack->isClauseParsingMode() || 1351 DSAStack->getParentDirective() != OMPD_unknown)) { 1352 auto &&Info = DSAStack->isLoopControlVariable(D); 1353 if (Info.first || 1354 (VD && VD->hasLocalStorage() && 1355 isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || 1356 (VD && DSAStack->isForceVarCapturing())) 1357 return VD ? VD : Info.second; 1358 auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1359 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1360 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1361 DVarPrivate = DSAStack->hasDSA( 1362 D, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, 1363 DSAStack->isClauseParsingMode()); 1364 if (DVarPrivate.CKind != OMPC_unknown) 1365 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1366 } 1367 return nullptr; 1368 } 1369 1370 void Sema::adjustOpenMPTargetScopeIndex(unsigned &FunctionScopesIndex, 1371 unsigned Level) const { 1372 SmallVector<OpenMPDirectiveKind, 4> Regions; 1373 getOpenMPCaptureRegions(Regions, DSAStack->getDirective(Level)); 1374 FunctionScopesIndex -= Regions.size(); 1375 } 1376 1377 bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) { 1378 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1379 return DSAStack->hasExplicitDSA( 1380 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, 1381 Level) || 1382 (DSAStack->isClauseParsingMode() && 1383 DSAStack->getClauseParsingMode() == OMPC_private) || 1384 // Consider taskgroup reduction descriptor variable a private to avoid 1385 // possible capture in the region. 1386 (DSAStack->hasExplicitDirective( 1387 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1388 Level) && 1389 DSAStack->isTaskgroupReductionRef(D, Level)); 1390 } 1391 1392 void Sema::setOpenMPCaptureKind(FieldDecl *FD, ValueDecl *D, unsigned Level) { 1393 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1394 D = getCanonicalDecl(D); 1395 OpenMPClauseKind OMPC = OMPC_unknown; 1396 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1397 const unsigned NewLevel = I - 1; 1398 if (DSAStack->hasExplicitDSA(D, 1399 [&OMPC](const OpenMPClauseKind K) { 1400 if (isOpenMPPrivate(K)) { 1401 OMPC = K; 1402 return true; 1403 } 1404 return false; 1405 }, 1406 NewLevel)) 1407 break; 1408 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1409 D, NewLevel, 1410 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1411 OpenMPClauseKind) { return true; })) { 1412 OMPC = OMPC_map; 1413 break; 1414 } 1415 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1416 NewLevel)) { 1417 OMPC = OMPC_firstprivate; 1418 break; 1419 } 1420 } 1421 if (OMPC != OMPC_unknown) 1422 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1423 } 1424 1425 bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) { 1426 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1427 // Return true if the current level is no longer enclosed in a target region. 1428 1429 auto *VD = dyn_cast<VarDecl>(D); 1430 return VD && !VD->hasLocalStorage() && 1431 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1432 Level); 1433 } 1434 1435 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1436 1437 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1438 const DeclarationNameInfo &DirName, 1439 Scope *CurScope, SourceLocation Loc) { 1440 DSAStack->push(DKind, DirName, CurScope, Loc); 1441 PushExpressionEvaluationContext( 1442 ExpressionEvaluationContext::PotentiallyEvaluated); 1443 } 1444 1445 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1446 DSAStack->setClauseParsingMode(K); 1447 } 1448 1449 void Sema::EndOpenMPClause() { 1450 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1451 } 1452 1453 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1454 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1455 // A variable of class type (or array thereof) that appears in a lastprivate 1456 // clause requires an accessible, unambiguous default constructor for the 1457 // class type, unless the list item is also specified in a firstprivate 1458 // clause. 1459 if (auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1460 for (auto *C : D->clauses()) { 1461 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1462 SmallVector<Expr *, 8> PrivateCopies; 1463 for (auto *DE : Clause->varlists()) { 1464 if (DE->isValueDependent() || DE->isTypeDependent()) { 1465 PrivateCopies.push_back(nullptr); 1466 continue; 1467 } 1468 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1469 VarDecl *VD = cast<VarDecl>(DRE->getDecl()); 1470 QualType Type = VD->getType().getNonReferenceType(); 1471 auto DVar = DSAStack->getTopDSA(VD, false); 1472 if (DVar.CKind == OMPC_lastprivate) { 1473 // Generate helper private variable and initialize it with the 1474 // default value. The address of the original variable is replaced 1475 // by the address of the new private variable in CodeGen. This new 1476 // variable is not added to IdResolver, so the code in the OpenMP 1477 // region uses original variable for proper diagnostics. 1478 auto *VDPrivate = buildVarDecl( 1479 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1480 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr); 1481 ActOnUninitializedDecl(VDPrivate); 1482 if (VDPrivate->isInvalidDecl()) 1483 continue; 1484 PrivateCopies.push_back(buildDeclRefExpr( 1485 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1486 } else { 1487 // The variable is also a firstprivate, so initialization sequence 1488 // for private copy is generated already. 1489 PrivateCopies.push_back(nullptr); 1490 } 1491 } 1492 // Set initializers to private copies if no errors were found. 1493 if (PrivateCopies.size() == Clause->varlist_size()) 1494 Clause->setPrivateCopies(PrivateCopies); 1495 } 1496 } 1497 } 1498 1499 DSAStack->pop(); 1500 DiscardCleanupsInEvaluationContext(); 1501 PopExpressionEvaluationContext(); 1502 } 1503 1504 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1505 Expr *NumIterations, Sema &SemaRef, 1506 Scope *S, DSAStackTy *Stack); 1507 1508 namespace { 1509 1510 class VarDeclFilterCCC : public CorrectionCandidateCallback { 1511 private: 1512 Sema &SemaRef; 1513 1514 public: 1515 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1516 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1517 NamedDecl *ND = Candidate.getCorrectionDecl(); 1518 if (auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 1519 return VD->hasGlobalStorage() && 1520 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1521 SemaRef.getCurScope()); 1522 } 1523 return false; 1524 } 1525 }; 1526 1527 class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback { 1528 private: 1529 Sema &SemaRef; 1530 1531 public: 1532 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 1533 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1534 NamedDecl *ND = Candidate.getCorrectionDecl(); 1535 if (ND && (isa<VarDecl>(ND) || isa<FunctionDecl>(ND))) { 1536 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1537 SemaRef.getCurScope()); 1538 } 1539 return false; 1540 } 1541 }; 1542 1543 } // namespace 1544 1545 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 1546 CXXScopeSpec &ScopeSpec, 1547 const DeclarationNameInfo &Id) { 1548 LookupResult Lookup(*this, Id, LookupOrdinaryName); 1549 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 1550 1551 if (Lookup.isAmbiguous()) 1552 return ExprError(); 1553 1554 VarDecl *VD; 1555 if (!Lookup.isSingleResult()) { 1556 if (TypoCorrection Corrected = CorrectTypo( 1557 Id, LookupOrdinaryName, CurScope, nullptr, 1558 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 1559 diagnoseTypo(Corrected, 1560 PDiag(Lookup.empty() 1561 ? diag::err_undeclared_var_use_suggest 1562 : diag::err_omp_expected_var_arg_suggest) 1563 << Id.getName()); 1564 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 1565 } else { 1566 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 1567 : diag::err_omp_expected_var_arg) 1568 << Id.getName(); 1569 return ExprError(); 1570 } 1571 } else { 1572 if (!(VD = Lookup.getAsSingle<VarDecl>())) { 1573 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 1574 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 1575 return ExprError(); 1576 } 1577 } 1578 Lookup.suppressDiagnostics(); 1579 1580 // OpenMP [2.9.2, Syntax, C/C++] 1581 // Variables must be file-scope, namespace-scope, or static block-scope. 1582 if (!VD->hasGlobalStorage()) { 1583 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 1584 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); 1585 bool IsDecl = 1586 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1587 Diag(VD->getLocation(), 1588 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1589 << VD; 1590 return ExprError(); 1591 } 1592 1593 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 1594 NamedDecl *ND = cast<NamedDecl>(CanonicalVD); 1595 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 1596 // A threadprivate directive for file-scope variables must appear outside 1597 // any definition or declaration. 1598 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 1599 !getCurLexicalContext()->isTranslationUnit()) { 1600 Diag(Id.getLoc(), diag::err_omp_var_scope) 1601 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1602 bool IsDecl = 1603 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1604 Diag(VD->getLocation(), 1605 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1606 << VD; 1607 return ExprError(); 1608 } 1609 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 1610 // A threadprivate directive for static class member variables must appear 1611 // in the class definition, in the same scope in which the member 1612 // variables are declared. 1613 if (CanonicalVD->isStaticDataMember() && 1614 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 1615 Diag(Id.getLoc(), diag::err_omp_var_scope) 1616 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1617 bool IsDecl = 1618 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1619 Diag(VD->getLocation(), 1620 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1621 << VD; 1622 return ExprError(); 1623 } 1624 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 1625 // A threadprivate directive for namespace-scope variables must appear 1626 // outside any definition or declaration other than the namespace 1627 // definition itself. 1628 if (CanonicalVD->getDeclContext()->isNamespace() && 1629 (!getCurLexicalContext()->isFileContext() || 1630 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 1631 Diag(Id.getLoc(), diag::err_omp_var_scope) 1632 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1633 bool IsDecl = 1634 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1635 Diag(VD->getLocation(), 1636 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1637 << VD; 1638 return ExprError(); 1639 } 1640 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 1641 // A threadprivate directive for static block-scope variables must appear 1642 // in the scope of the variable and not in a nested scope. 1643 if (CanonicalVD->isStaticLocal() && CurScope && 1644 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 1645 Diag(Id.getLoc(), diag::err_omp_var_scope) 1646 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1647 bool IsDecl = 1648 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1649 Diag(VD->getLocation(), 1650 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1651 << VD; 1652 return ExprError(); 1653 } 1654 1655 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 1656 // A threadprivate directive must lexically precede all references to any 1657 // of the variables in its list. 1658 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { 1659 Diag(Id.getLoc(), diag::err_omp_var_used) 1660 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1661 return ExprError(); 1662 } 1663 1664 QualType ExprType = VD->getType().getNonReferenceType(); 1665 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 1666 SourceLocation(), VD, 1667 /*RefersToEnclosingVariableOrCapture=*/false, 1668 Id.getLoc(), ExprType, VK_LValue); 1669 } 1670 1671 Sema::DeclGroupPtrTy 1672 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 1673 ArrayRef<Expr *> VarList) { 1674 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 1675 CurContext->addDecl(D); 1676 return DeclGroupPtrTy::make(DeclGroupRef(D)); 1677 } 1678 return nullptr; 1679 } 1680 1681 namespace { 1682 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> { 1683 Sema &SemaRef; 1684 1685 public: 1686 bool VisitDeclRefExpr(const DeclRefExpr *E) { 1687 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1688 if (VD->hasLocalStorage()) { 1689 SemaRef.Diag(E->getLocStart(), 1690 diag::err_omp_local_var_in_threadprivate_init) 1691 << E->getSourceRange(); 1692 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 1693 << VD << VD->getSourceRange(); 1694 return true; 1695 } 1696 } 1697 return false; 1698 } 1699 bool VisitStmt(const Stmt *S) { 1700 for (auto Child : S->children()) { 1701 if (Child && Visit(Child)) 1702 return true; 1703 } 1704 return false; 1705 } 1706 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 1707 }; 1708 } // namespace 1709 1710 OMPThreadPrivateDecl * 1711 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 1712 SmallVector<Expr *, 8> Vars; 1713 for (auto &RefExpr : VarList) { 1714 DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr); 1715 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 1716 SourceLocation ILoc = DE->getExprLoc(); 1717 1718 // Mark variable as used. 1719 VD->setReferenced(); 1720 VD->markUsed(Context); 1721 1722 QualType QType = VD->getType(); 1723 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 1724 // It will be analyzed later. 1725 Vars.push_back(DE); 1726 continue; 1727 } 1728 1729 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1730 // A threadprivate variable must not have an incomplete type. 1731 if (RequireCompleteType(ILoc, VD->getType(), 1732 diag::err_omp_threadprivate_incomplete_type)) { 1733 continue; 1734 } 1735 1736 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1737 // A threadprivate variable must not have a reference type. 1738 if (VD->getType()->isReferenceType()) { 1739 Diag(ILoc, diag::err_omp_ref_type_arg) 1740 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 1741 bool IsDecl = 1742 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1743 Diag(VD->getLocation(), 1744 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1745 << VD; 1746 continue; 1747 } 1748 1749 // Check if this is a TLS variable. If TLS is not being supported, produce 1750 // the corresponding diagnostic. 1751 if ((VD->getTLSKind() != VarDecl::TLS_None && 1752 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1753 getLangOpts().OpenMPUseTLS && 1754 getASTContext().getTargetInfo().isTLSSupported())) || 1755 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 1756 !VD->isLocalVarDecl())) { 1757 Diag(ILoc, diag::err_omp_var_thread_local) 1758 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 1759 bool IsDecl = 1760 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1761 Diag(VD->getLocation(), 1762 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1763 << VD; 1764 continue; 1765 } 1766 1767 // Check if initial value of threadprivate variable reference variable with 1768 // local storage (it is not supported by runtime). 1769 if (auto Init = VD->getAnyInitializer()) { 1770 LocalVarRefChecker Checker(*this); 1771 if (Checker.Visit(Init)) 1772 continue; 1773 } 1774 1775 Vars.push_back(RefExpr); 1776 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 1777 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 1778 Context, SourceRange(Loc, Loc))); 1779 if (auto *ML = Context.getASTMutationListener()) 1780 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 1781 } 1782 OMPThreadPrivateDecl *D = nullptr; 1783 if (!Vars.empty()) { 1784 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 1785 Vars); 1786 D->setAccess(AS_public); 1787 } 1788 return D; 1789 } 1790 1791 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, 1792 const ValueDecl *D, DSAStackTy::DSAVarData DVar, 1793 bool IsLoopIterVar = false) { 1794 if (DVar.RefExpr) { 1795 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 1796 << getOpenMPClauseName(DVar.CKind); 1797 return; 1798 } 1799 enum { 1800 PDSA_StaticMemberShared, 1801 PDSA_StaticLocalVarShared, 1802 PDSA_LoopIterVarPrivate, 1803 PDSA_LoopIterVarLinear, 1804 PDSA_LoopIterVarLastprivate, 1805 PDSA_ConstVarShared, 1806 PDSA_GlobalVarShared, 1807 PDSA_TaskVarFirstprivate, 1808 PDSA_LocalVarPrivate, 1809 PDSA_Implicit 1810 } Reason = PDSA_Implicit; 1811 bool ReportHint = false; 1812 auto ReportLoc = D->getLocation(); 1813 auto *VD = dyn_cast<VarDecl>(D); 1814 if (IsLoopIterVar) { 1815 if (DVar.CKind == OMPC_private) 1816 Reason = PDSA_LoopIterVarPrivate; 1817 else if (DVar.CKind == OMPC_lastprivate) 1818 Reason = PDSA_LoopIterVarLastprivate; 1819 else 1820 Reason = PDSA_LoopIterVarLinear; 1821 } else if (isOpenMPTaskingDirective(DVar.DKind) && 1822 DVar.CKind == OMPC_firstprivate) { 1823 Reason = PDSA_TaskVarFirstprivate; 1824 ReportLoc = DVar.ImplicitDSALoc; 1825 } else if (VD && VD->isStaticLocal()) 1826 Reason = PDSA_StaticLocalVarShared; 1827 else if (VD && VD->isStaticDataMember()) 1828 Reason = PDSA_StaticMemberShared; 1829 else if (VD && VD->isFileVarDecl()) 1830 Reason = PDSA_GlobalVarShared; 1831 else if (D->getType().isConstant(SemaRef.getASTContext())) 1832 Reason = PDSA_ConstVarShared; 1833 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 1834 ReportHint = true; 1835 Reason = PDSA_LocalVarPrivate; 1836 } 1837 if (Reason != PDSA_Implicit) { 1838 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 1839 << Reason << ReportHint 1840 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 1841 } else if (DVar.ImplicitDSALoc.isValid()) { 1842 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 1843 << getOpenMPClauseName(DVar.CKind); 1844 } 1845 } 1846 1847 namespace { 1848 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> { 1849 DSAStackTy *Stack; 1850 Sema &SemaRef; 1851 bool ErrorFound; 1852 CapturedStmt *CS; 1853 llvm::SmallVector<Expr *, 8> ImplicitFirstprivate; 1854 llvm::SmallVector<Expr *, 8> ImplicitMap; 1855 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 1856 llvm::DenseSet<ValueDecl *> ImplicitDeclarations; 1857 1858 public: 1859 void VisitDeclRefExpr(DeclRefExpr *E) { 1860 if (E->isTypeDependent() || E->isValueDependent() || 1861 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 1862 return; 1863 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1864 VD = VD->getCanonicalDecl(); 1865 // Skip internally declared variables. 1866 if (VD->hasLocalStorage() && !CS->capturesVariable(VD)) 1867 return; 1868 1869 auto DVar = Stack->getTopDSA(VD, false); 1870 // Check if the variable has explicit DSA set and stop analysis if it so. 1871 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 1872 return; 1873 1874 // Skip internally declared static variables. 1875 if (VD->hasGlobalStorage() && !CS->capturesVariable(VD)) 1876 return; 1877 1878 auto ELoc = E->getExprLoc(); 1879 auto DKind = Stack->getCurrentDirective(); 1880 // The default(none) clause requires that each variable that is referenced 1881 // in the construct, and does not have a predetermined data-sharing 1882 // attribute, must have its data-sharing attribute explicitly determined 1883 // by being listed in a data-sharing attribute clause. 1884 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 1885 isParallelOrTaskRegion(DKind) && 1886 VarsWithInheritedDSA.count(VD) == 0) { 1887 VarsWithInheritedDSA[VD] = E; 1888 return; 1889 } 1890 1891 if (isOpenMPTargetExecutionDirective(DKind) && 1892 !Stack->isLoopControlVariable(VD).first) { 1893 if (!Stack->checkMappableExprComponentListsForDecl( 1894 VD, /*CurrentRegionOnly=*/true, 1895 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 1896 StackComponents, 1897 OpenMPClauseKind) { 1898 // Variable is used if it has been marked as an array, array 1899 // section or the variable iself. 1900 return StackComponents.size() == 1 || 1901 std::all_of( 1902 std::next(StackComponents.rbegin()), 1903 StackComponents.rend(), 1904 [](const OMPClauseMappableExprCommon:: 1905 MappableComponent &MC) { 1906 return MC.getAssociatedDeclaration() == 1907 nullptr && 1908 (isa<OMPArraySectionExpr>( 1909 MC.getAssociatedExpression()) || 1910 isa<ArraySubscriptExpr>( 1911 MC.getAssociatedExpression())); 1912 }); 1913 })) { 1914 bool IsFirstprivate = false; 1915 // By default lambdas are captured as firstprivates. 1916 if (const auto *RD = 1917 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 1918 IsFirstprivate = RD->isLambda(); 1919 IsFirstprivate = 1920 IsFirstprivate || 1921 (VD->getType().getNonReferenceType()->isScalarType() && 1922 Stack->getDefaultDMA() != DMA_tofrom_scalar); 1923 if (IsFirstprivate) 1924 ImplicitFirstprivate.emplace_back(E); 1925 else 1926 ImplicitMap.emplace_back(E); 1927 return; 1928 } 1929 } 1930 1931 // OpenMP [2.9.3.6, Restrictions, p.2] 1932 // A list item that appears in a reduction clause of the innermost 1933 // enclosing worksharing or parallel construct may not be accessed in an 1934 // explicit task. 1935 DVar = Stack->hasInnermostDSA( 1936 VD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 1937 [](OpenMPDirectiveKind K) -> bool { 1938 return isOpenMPParallelDirective(K) || 1939 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 1940 }, 1941 /*FromParent=*/true); 1942 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 1943 ErrorFound = true; 1944 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1945 ReportOriginalDSA(SemaRef, Stack, VD, DVar); 1946 return; 1947 } 1948 1949 // Define implicit data-sharing attributes for task. 1950 DVar = Stack->getImplicitDSA(VD, false); 1951 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 1952 !Stack->isLoopControlVariable(VD).first) 1953 ImplicitFirstprivate.push_back(E); 1954 } 1955 } 1956 void VisitMemberExpr(MemberExpr *E) { 1957 if (E->isTypeDependent() || E->isValueDependent() || 1958 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 1959 return; 1960 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 1961 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 1962 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 1963 if (!FD) 1964 return; 1965 auto DVar = Stack->getTopDSA(FD, false); 1966 // Check if the variable has explicit DSA set and stop analysis if it 1967 // so. 1968 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 1969 return; 1970 1971 if (isOpenMPTargetExecutionDirective(DKind) && 1972 !Stack->isLoopControlVariable(FD).first && 1973 !Stack->checkMappableExprComponentListsForDecl( 1974 FD, /*CurrentRegionOnly=*/true, 1975 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 1976 StackComponents, 1977 OpenMPClauseKind) { 1978 return isa<CXXThisExpr>( 1979 cast<MemberExpr>( 1980 StackComponents.back().getAssociatedExpression()) 1981 ->getBase() 1982 ->IgnoreParens()); 1983 })) { 1984 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 1985 // A bit-field cannot appear in a map clause. 1986 // 1987 if (FD->isBitField()) 1988 return; 1989 ImplicitMap.emplace_back(E); 1990 return; 1991 } 1992 1993 auto ELoc = E->getExprLoc(); 1994 // OpenMP [2.9.3.6, Restrictions, p.2] 1995 // A list item that appears in a reduction clause of the innermost 1996 // enclosing worksharing or parallel construct may not be accessed in 1997 // an explicit task. 1998 DVar = Stack->hasInnermostDSA( 1999 FD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 2000 [](OpenMPDirectiveKind K) -> bool { 2001 return isOpenMPParallelDirective(K) || 2002 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 2003 }, 2004 /*FromParent=*/true); 2005 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 2006 ErrorFound = true; 2007 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 2008 ReportOriginalDSA(SemaRef, Stack, FD, DVar); 2009 return; 2010 } 2011 2012 // Define implicit data-sharing attributes for task. 2013 DVar = Stack->getImplicitDSA(FD, false); 2014 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 2015 !Stack->isLoopControlVariable(FD).first) 2016 ImplicitFirstprivate.push_back(E); 2017 return; 2018 } 2019 if (isOpenMPTargetExecutionDirective(DKind)) { 2020 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 2021 if (!CheckMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map, 2022 /*NoDiagnose=*/true)) 2023 return; 2024 auto *VD = cast<ValueDecl>( 2025 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 2026 if (!Stack->checkMappableExprComponentListsForDecl( 2027 VD, /*CurrentRegionOnly=*/true, 2028 [&CurComponents]( 2029 OMPClauseMappableExprCommon::MappableExprComponentListRef 2030 StackComponents, 2031 OpenMPClauseKind) { 2032 auto CCI = CurComponents.rbegin(); 2033 auto CCE = CurComponents.rend(); 2034 for (const auto &SC : llvm::reverse(StackComponents)) { 2035 // Do both expressions have the same kind? 2036 if (CCI->getAssociatedExpression()->getStmtClass() != 2037 SC.getAssociatedExpression()->getStmtClass()) 2038 if (!(isa<OMPArraySectionExpr>( 2039 SC.getAssociatedExpression()) && 2040 isa<ArraySubscriptExpr>( 2041 CCI->getAssociatedExpression()))) 2042 return false; 2043 2044 Decl *CCD = CCI->getAssociatedDeclaration(); 2045 Decl *SCD = SC.getAssociatedDeclaration(); 2046 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2047 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2048 if (SCD != CCD) 2049 return false; 2050 std::advance(CCI, 1); 2051 if (CCI == CCE) 2052 break; 2053 } 2054 return true; 2055 })) { 2056 Visit(E->getBase()); 2057 } 2058 } else 2059 Visit(E->getBase()); 2060 } 2061 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2062 for (auto *C : S->clauses()) { 2063 // Skip analysis of arguments of implicitly defined firstprivate clause 2064 // for task|target directives. 2065 // Skip analysis of arguments of implicitly defined map clause for target 2066 // directives. 2067 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2068 C->isImplicit())) { 2069 for (auto *CC : C->children()) { 2070 if (CC) 2071 Visit(CC); 2072 } 2073 } 2074 } 2075 } 2076 void VisitStmt(Stmt *S) { 2077 for (auto *C : S->children()) { 2078 if (C && !isa<OMPExecutableDirective>(C)) 2079 Visit(C); 2080 } 2081 } 2082 2083 bool isErrorFound() { return ErrorFound; } 2084 ArrayRef<Expr *> getImplicitFirstprivate() const { 2085 return ImplicitFirstprivate; 2086 } 2087 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2088 llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() { 2089 return VarsWithInheritedDSA; 2090 } 2091 2092 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2093 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} 2094 }; 2095 } // namespace 2096 2097 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2098 switch (DKind) { 2099 case OMPD_parallel: 2100 case OMPD_parallel_for: 2101 case OMPD_parallel_for_simd: 2102 case OMPD_parallel_sections: 2103 case OMPD_teams: 2104 case OMPD_teams_distribute: 2105 case OMPD_teams_distribute_simd: { 2106 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 2107 QualType KmpInt32PtrTy = 2108 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2109 Sema::CapturedParamNameType Params[] = { 2110 std::make_pair(".global_tid.", KmpInt32PtrTy), 2111 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2112 std::make_pair(StringRef(), QualType()) // __context with shared vars 2113 }; 2114 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2115 Params); 2116 break; 2117 } 2118 case OMPD_target_teams: 2119 case OMPD_target_parallel: 2120 case OMPD_target_parallel_for: 2121 case OMPD_target_parallel_for_simd: 2122 case OMPD_target_teams_distribute: 2123 case OMPD_target_teams_distribute_simd: { 2124 Sema::CapturedParamNameType ParamsTarget[] = { 2125 std::make_pair(StringRef(), QualType()) // __context with shared vars 2126 }; 2127 // Start a captured region for 'target' with no implicit parameters. 2128 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2129 ParamsTarget); 2130 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 2131 QualType KmpInt32PtrTy = 2132 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2133 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2134 std::make_pair(".global_tid.", KmpInt32PtrTy), 2135 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2136 std::make_pair(StringRef(), QualType()) // __context with shared vars 2137 }; 2138 // Start a captured region for 'teams' or 'parallel'. Both regions have 2139 // the same implicit parameters. 2140 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2141 ParamsTeamsOrParallel); 2142 break; 2143 } 2144 case OMPD_simd: 2145 case OMPD_for: 2146 case OMPD_for_simd: 2147 case OMPD_sections: 2148 case OMPD_section: 2149 case OMPD_single: 2150 case OMPD_master: 2151 case OMPD_critical: 2152 case OMPD_taskgroup: 2153 case OMPD_distribute: 2154 case OMPD_distribute_simd: 2155 case OMPD_ordered: 2156 case OMPD_atomic: 2157 case OMPD_target_data: 2158 case OMPD_target: 2159 case OMPD_target_simd: { 2160 Sema::CapturedParamNameType Params[] = { 2161 std::make_pair(StringRef(), QualType()) // __context with shared vars 2162 }; 2163 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2164 Params); 2165 break; 2166 } 2167 case OMPD_task: { 2168 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 2169 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 2170 FunctionProtoType::ExtProtoInfo EPI; 2171 EPI.Variadic = true; 2172 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2173 Sema::CapturedParamNameType Params[] = { 2174 std::make_pair(".global_tid.", KmpInt32Ty), 2175 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), 2176 std::make_pair(".privates.", Context.VoidPtrTy.withConst()), 2177 std::make_pair(".copy_fn.", 2178 Context.getPointerType(CopyFnType).withConst()), 2179 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2180 std::make_pair(StringRef(), QualType()) // __context with shared vars 2181 }; 2182 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2183 Params); 2184 // Mark this captured region as inlined, because we don't use outlined 2185 // function directly. 2186 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2187 AlwaysInlineAttr::CreateImplicit( 2188 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 2189 break; 2190 } 2191 case OMPD_taskloop: 2192 case OMPD_taskloop_simd: { 2193 QualType KmpInt32Ty = 2194 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1); 2195 QualType KmpUInt64Ty = 2196 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 2197 QualType KmpInt64Ty = 2198 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 2199 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 2200 FunctionProtoType::ExtProtoInfo EPI; 2201 EPI.Variadic = true; 2202 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2203 Sema::CapturedParamNameType Params[] = { 2204 std::make_pair(".global_tid.", KmpInt32Ty), 2205 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), 2206 std::make_pair(".privates.", 2207 Context.VoidPtrTy.withConst().withRestrict()), 2208 std::make_pair( 2209 ".copy_fn.", 2210 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2211 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2212 std::make_pair(".lb.", KmpUInt64Ty), 2213 std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty), 2214 std::make_pair(".liter.", KmpInt32Ty), 2215 std::make_pair(".reductions.", 2216 Context.VoidPtrTy.withConst().withRestrict()), 2217 std::make_pair(StringRef(), QualType()) // __context with shared vars 2218 }; 2219 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2220 Params); 2221 // Mark this captured region as inlined, because we don't use outlined 2222 // function directly. 2223 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2224 AlwaysInlineAttr::CreateImplicit( 2225 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 2226 break; 2227 } 2228 case OMPD_distribute_parallel_for_simd: 2229 case OMPD_distribute_parallel_for: 2230 case OMPD_target_teams_distribute_parallel_for: 2231 case OMPD_target_teams_distribute_parallel_for_simd: { 2232 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 2233 QualType KmpInt32PtrTy = 2234 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2235 Sema::CapturedParamNameType Params[] = { 2236 std::make_pair(".global_tid.", KmpInt32PtrTy), 2237 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2238 std::make_pair(".previous.lb.", Context.getSizeType()), 2239 std::make_pair(".previous.ub.", Context.getSizeType()), 2240 std::make_pair(StringRef(), QualType()) // __context with shared vars 2241 }; 2242 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2243 Params); 2244 break; 2245 } 2246 case OMPD_teams_distribute_parallel_for: 2247 case OMPD_teams_distribute_parallel_for_simd: { 2248 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 2249 QualType KmpInt32PtrTy = 2250 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2251 2252 Sema::CapturedParamNameType ParamsTeams[] = { 2253 std::make_pair(".global_tid.", KmpInt32PtrTy), 2254 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2255 std::make_pair(StringRef(), QualType()) // __context with shared vars 2256 }; 2257 // Start a captured region for 'target' with no implicit parameters. 2258 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2259 ParamsTeams); 2260 2261 Sema::CapturedParamNameType ParamsParallel[] = { 2262 std::make_pair(".global_tid.", KmpInt32PtrTy), 2263 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2264 std::make_pair(".previous.lb.", Context.getSizeType()), 2265 std::make_pair(".previous.ub.", Context.getSizeType()), 2266 std::make_pair(StringRef(), QualType()) // __context with shared vars 2267 }; 2268 // Start a captured region for 'teams' or 'parallel'. Both regions have 2269 // the same implicit parameters. 2270 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2271 ParamsParallel); 2272 break; 2273 } 2274 case OMPD_target_update: 2275 case OMPD_target_enter_data: 2276 case OMPD_target_exit_data: { 2277 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 2278 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 2279 FunctionProtoType::ExtProtoInfo EPI; 2280 EPI.Variadic = true; 2281 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2282 Sema::CapturedParamNameType Params[] = { 2283 std::make_pair(".global_tid.", KmpInt32Ty), 2284 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), 2285 std::make_pair(".privates.", Context.VoidPtrTy.withConst()), 2286 std::make_pair(".copy_fn.", 2287 Context.getPointerType(CopyFnType).withConst()), 2288 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2289 std::make_pair(StringRef(), QualType()) // __context with shared vars 2290 }; 2291 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2292 Params); 2293 // Mark this captured region as inlined, because we don't use outlined 2294 // function directly. 2295 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2296 AlwaysInlineAttr::CreateImplicit( 2297 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 2298 break; 2299 } 2300 case OMPD_threadprivate: 2301 case OMPD_taskyield: 2302 case OMPD_barrier: 2303 case OMPD_taskwait: 2304 case OMPD_cancellation_point: 2305 case OMPD_cancel: 2306 case OMPD_flush: 2307 case OMPD_declare_reduction: 2308 case OMPD_declare_simd: 2309 case OMPD_declare_target: 2310 case OMPD_end_declare_target: 2311 llvm_unreachable("OpenMP Directive is not allowed"); 2312 case OMPD_unknown: 2313 llvm_unreachable("Unknown OpenMP directive"); 2314 } 2315 } 2316 2317 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 2318 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2319 getOpenMPCaptureRegions(CaptureRegions, DKind); 2320 return CaptureRegions.size(); 2321 } 2322 2323 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 2324 Expr *CaptureExpr, bool WithInit, 2325 bool AsExpression) { 2326 assert(CaptureExpr); 2327 ASTContext &C = S.getASTContext(); 2328 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 2329 QualType Ty = Init->getType(); 2330 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 2331 if (S.getLangOpts().CPlusPlus) { 2332 Ty = C.getLValueReferenceType(Ty); 2333 } else { 2334 Ty = C.getPointerType(Ty); 2335 ExprResult Res = 2336 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 2337 if (!Res.isUsable()) 2338 return nullptr; 2339 Init = Res.get(); 2340 } 2341 WithInit = true; 2342 } 2343 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 2344 CaptureExpr->getLocStart()); 2345 if (!WithInit) 2346 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange())); 2347 S.CurContext->addHiddenDecl(CED); 2348 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 2349 return CED; 2350 } 2351 2352 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2353 bool WithInit) { 2354 OMPCapturedExprDecl *CD; 2355 if (auto *VD = S.IsOpenMPCapturedDecl(D)) { 2356 CD = cast<OMPCapturedExprDecl>(VD); 2357 } else { 2358 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 2359 /*AsExpression=*/false); 2360 } 2361 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 2362 CaptureExpr->getExprLoc()); 2363 } 2364 2365 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 2366 CaptureExpr = S.DefaultLvalueConversion(CaptureExpr).get(); 2367 if (!Ref) { 2368 OMPCapturedExprDecl *CD = buildCaptureDecl( 2369 S, &S.getASTContext().Idents.get(".capture_expr."), CaptureExpr, 2370 /*WithInit=*/true, /*AsExpression=*/true); 2371 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 2372 CaptureExpr->getExprLoc()); 2373 } 2374 ExprResult Res = Ref; 2375 if (!S.getLangOpts().CPlusPlus && 2376 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 2377 Ref->getType()->isPointerType()) { 2378 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 2379 if (!Res.isUsable()) 2380 return ExprError(); 2381 } 2382 return S.DefaultLvalueConversion(Res.get()); 2383 } 2384 2385 namespace { 2386 // OpenMP directives parsed in this section are represented as a 2387 // CapturedStatement with an associated statement. If a syntax error 2388 // is detected during the parsing of the associated statement, the 2389 // compiler must abort processing and close the CapturedStatement. 2390 // 2391 // Combined directives such as 'target parallel' have more than one 2392 // nested CapturedStatements. This RAII ensures that we unwind out 2393 // of all the nested CapturedStatements when an error is found. 2394 class CaptureRegionUnwinderRAII { 2395 private: 2396 Sema &S; 2397 bool &ErrorFound; 2398 OpenMPDirectiveKind DKind; 2399 2400 public: 2401 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 2402 OpenMPDirectiveKind DKind) 2403 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 2404 ~CaptureRegionUnwinderRAII() { 2405 if (ErrorFound) { 2406 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 2407 while (--ThisCaptureLevel >= 0) 2408 S.ActOnCapturedRegionError(); 2409 } 2410 } 2411 }; 2412 } // namespace 2413 2414 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 2415 ArrayRef<OMPClause *> Clauses) { 2416 bool ErrorFound = false; 2417 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 2418 *this, ErrorFound, DSAStack->getCurrentDirective()); 2419 if (!S.isUsable()) { 2420 ErrorFound = true; 2421 return StmtError(); 2422 } 2423 2424 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2425 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 2426 OMPOrderedClause *OC = nullptr; 2427 OMPScheduleClause *SC = nullptr; 2428 SmallVector<OMPLinearClause *, 4> LCs; 2429 SmallVector<OMPClauseWithPreInit *, 8> PICs; 2430 // This is required for proper codegen. 2431 for (auto *Clause : Clauses) { 2432 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 2433 Clause->getClauseKind() == OMPC_in_reduction) { 2434 // Capture taskgroup task_reduction descriptors inside the tasking regions 2435 // with the corresponding in_reduction items. 2436 auto *IRC = cast<OMPInReductionClause>(Clause); 2437 for (auto *E : IRC->taskgroup_descriptors()) 2438 if (E) 2439 MarkDeclarationsReferencedInExpr(E); 2440 } 2441 if (isOpenMPPrivate(Clause->getClauseKind()) || 2442 Clause->getClauseKind() == OMPC_copyprivate || 2443 (getLangOpts().OpenMPUseTLS && 2444 getASTContext().getTargetInfo().isTLSSupported() && 2445 Clause->getClauseKind() == OMPC_copyin)) { 2446 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 2447 // Mark all variables in private list clauses as used in inner region. 2448 for (auto *VarRef : Clause->children()) { 2449 if (auto *E = cast_or_null<Expr>(VarRef)) { 2450 MarkDeclarationsReferencedInExpr(E); 2451 } 2452 } 2453 DSAStack->setForceVarCapturing(/*V=*/false); 2454 } else if (CaptureRegions.size() > 1 || 2455 CaptureRegions.back() != OMPD_unknown) { 2456 if (auto *C = OMPClauseWithPreInit::get(Clause)) 2457 PICs.push_back(C); 2458 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 2459 if (auto *E = C->getPostUpdateExpr()) 2460 MarkDeclarationsReferencedInExpr(E); 2461 } 2462 } 2463 if (Clause->getClauseKind() == OMPC_schedule) 2464 SC = cast<OMPScheduleClause>(Clause); 2465 else if (Clause->getClauseKind() == OMPC_ordered) 2466 OC = cast<OMPOrderedClause>(Clause); 2467 else if (Clause->getClauseKind() == OMPC_linear) 2468 LCs.push_back(cast<OMPLinearClause>(Clause)); 2469 } 2470 // OpenMP, 2.7.1 Loop Construct, Restrictions 2471 // The nonmonotonic modifier cannot be specified if an ordered clause is 2472 // specified. 2473 if (SC && 2474 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 2475 SC->getSecondScheduleModifier() == 2476 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 2477 OC) { 2478 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 2479 ? SC->getFirstScheduleModifierLoc() 2480 : SC->getSecondScheduleModifierLoc(), 2481 diag::err_omp_schedule_nonmonotonic_ordered) 2482 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 2483 ErrorFound = true; 2484 } 2485 if (!LCs.empty() && OC && OC->getNumForLoops()) { 2486 for (auto *C : LCs) { 2487 Diag(C->getLocStart(), diag::err_omp_linear_ordered) 2488 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 2489 } 2490 ErrorFound = true; 2491 } 2492 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 2493 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 2494 OC->getNumForLoops()) { 2495 Diag(OC->getLocStart(), diag::err_omp_ordered_simd) 2496 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 2497 ErrorFound = true; 2498 } 2499 if (ErrorFound) { 2500 return StmtError(); 2501 } 2502 StmtResult SR = S; 2503 for (OpenMPDirectiveKind ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 2504 // Mark all variables in private list clauses as used in inner region. 2505 // Required for proper codegen of combined directives. 2506 // TODO: add processing for other clauses. 2507 if (ThisCaptureRegion != OMPD_unknown) { 2508 for (auto *C : PICs) { 2509 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 2510 // Find the particular capture region for the clause if the 2511 // directive is a combined one with multiple capture regions. 2512 // If the directive is not a combined one, the capture region 2513 // associated with the clause is OMPD_unknown and is generated 2514 // only once. 2515 if (CaptureRegion == ThisCaptureRegion || 2516 CaptureRegion == OMPD_unknown) { 2517 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 2518 for (auto *D : DS->decls()) 2519 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 2520 } 2521 } 2522 } 2523 } 2524 SR = ActOnCapturedRegionEnd(SR.get()); 2525 } 2526 return SR; 2527 } 2528 2529 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 2530 OpenMPDirectiveKind CancelRegion, 2531 SourceLocation StartLoc) { 2532 // CancelRegion is only needed for cancel and cancellation_point. 2533 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 2534 return false; 2535 2536 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 2537 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 2538 return false; 2539 2540 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 2541 << getOpenMPDirectiveName(CancelRegion); 2542 return true; 2543 } 2544 2545 static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, 2546 OpenMPDirectiveKind CurrentRegion, 2547 const DeclarationNameInfo &CurrentName, 2548 OpenMPDirectiveKind CancelRegion, 2549 SourceLocation StartLoc) { 2550 if (Stack->getCurScope()) { 2551 auto ParentRegion = Stack->getParentDirective(); 2552 auto OffendingRegion = ParentRegion; 2553 bool NestingProhibited = false; 2554 bool CloseNesting = true; 2555 bool OrphanSeen = false; 2556 enum { 2557 NoRecommend, 2558 ShouldBeInParallelRegion, 2559 ShouldBeInOrderedRegion, 2560 ShouldBeInTargetRegion, 2561 ShouldBeInTeamsRegion 2562 } Recommend = NoRecommend; 2563 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 2564 // OpenMP [2.16, Nesting of Regions] 2565 // OpenMP constructs may not be nested inside a simd region. 2566 // OpenMP [2.8.1,simd Construct, Restrictions] 2567 // An ordered construct with the simd clause is the only OpenMP 2568 // construct that can appear in the simd region. 2569 // Allowing a SIMD construct nested in another SIMD construct is an 2570 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 2571 // message. 2572 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 2573 ? diag::err_omp_prohibited_region_simd 2574 : diag::warn_omp_nesting_simd); 2575 return CurrentRegion != OMPD_simd; 2576 } 2577 if (ParentRegion == OMPD_atomic) { 2578 // OpenMP [2.16, Nesting of Regions] 2579 // OpenMP constructs may not be nested inside an atomic region. 2580 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 2581 return true; 2582 } 2583 if (CurrentRegion == OMPD_section) { 2584 // OpenMP [2.7.2, sections Construct, Restrictions] 2585 // Orphaned section directives are prohibited. That is, the section 2586 // directives must appear within the sections construct and must not be 2587 // encountered elsewhere in the sections region. 2588 if (ParentRegion != OMPD_sections && 2589 ParentRegion != OMPD_parallel_sections) { 2590 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 2591 << (ParentRegion != OMPD_unknown) 2592 << getOpenMPDirectiveName(ParentRegion); 2593 return true; 2594 } 2595 return false; 2596 } 2597 // Allow some constructs (except teams) to be orphaned (they could be 2598 // used in functions, called from OpenMP regions with the required 2599 // preconditions). 2600 if (ParentRegion == OMPD_unknown && 2601 !isOpenMPNestingTeamsDirective(CurrentRegion)) 2602 return false; 2603 if (CurrentRegion == OMPD_cancellation_point || 2604 CurrentRegion == OMPD_cancel) { 2605 // OpenMP [2.16, Nesting of Regions] 2606 // A cancellation point construct for which construct-type-clause is 2607 // taskgroup must be nested inside a task construct. A cancellation 2608 // point construct for which construct-type-clause is not taskgroup must 2609 // be closely nested inside an OpenMP construct that matches the type 2610 // specified in construct-type-clause. 2611 // A cancel construct for which construct-type-clause is taskgroup must be 2612 // nested inside a task construct. A cancel construct for which 2613 // construct-type-clause is not taskgroup must be closely nested inside an 2614 // OpenMP construct that matches the type specified in 2615 // construct-type-clause. 2616 NestingProhibited = 2617 !((CancelRegion == OMPD_parallel && 2618 (ParentRegion == OMPD_parallel || 2619 ParentRegion == OMPD_target_parallel)) || 2620 (CancelRegion == OMPD_for && 2621 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 2622 ParentRegion == OMPD_target_parallel_for || 2623 ParentRegion == OMPD_distribute_parallel_for || 2624 ParentRegion == OMPD_teams_distribute_parallel_for || 2625 ParentRegion == OMPD_target_teams_distribute_parallel_for)) || 2626 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 2627 (CancelRegion == OMPD_sections && 2628 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 2629 ParentRegion == OMPD_parallel_sections))); 2630 } else if (CurrentRegion == OMPD_master) { 2631 // OpenMP [2.16, Nesting of Regions] 2632 // A master region may not be closely nested inside a worksharing, 2633 // atomic, or explicit task region. 2634 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2635 isOpenMPTaskingDirective(ParentRegion); 2636 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 2637 // OpenMP [2.16, Nesting of Regions] 2638 // A critical region may not be nested (closely or otherwise) inside a 2639 // critical region with the same name. Note that this restriction is not 2640 // sufficient to prevent deadlock. 2641 SourceLocation PreviousCriticalLoc; 2642 bool DeadLock = Stack->hasDirective( 2643 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 2644 const DeclarationNameInfo &DNI, 2645 SourceLocation Loc) -> bool { 2646 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 2647 PreviousCriticalLoc = Loc; 2648 return true; 2649 } else 2650 return false; 2651 }, 2652 false /* skip top directive */); 2653 if (DeadLock) { 2654 SemaRef.Diag(StartLoc, 2655 diag::err_omp_prohibited_region_critical_same_name) 2656 << CurrentName.getName(); 2657 if (PreviousCriticalLoc.isValid()) 2658 SemaRef.Diag(PreviousCriticalLoc, 2659 diag::note_omp_previous_critical_region); 2660 return true; 2661 } 2662 } else if (CurrentRegion == OMPD_barrier) { 2663 // OpenMP [2.16, Nesting of Regions] 2664 // A barrier region may not be closely nested inside a worksharing, 2665 // explicit task, critical, ordered, atomic, or master region. 2666 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2667 isOpenMPTaskingDirective(ParentRegion) || 2668 ParentRegion == OMPD_master || 2669 ParentRegion == OMPD_critical || 2670 ParentRegion == OMPD_ordered; 2671 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 2672 !isOpenMPParallelDirective(CurrentRegion) && 2673 !isOpenMPTeamsDirective(CurrentRegion)) { 2674 // OpenMP [2.16, Nesting of Regions] 2675 // A worksharing region may not be closely nested inside a worksharing, 2676 // explicit task, critical, ordered, atomic, or master region. 2677 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2678 isOpenMPTaskingDirective(ParentRegion) || 2679 ParentRegion == OMPD_master || 2680 ParentRegion == OMPD_critical || 2681 ParentRegion == OMPD_ordered; 2682 Recommend = ShouldBeInParallelRegion; 2683 } else if (CurrentRegion == OMPD_ordered) { 2684 // OpenMP [2.16, Nesting of Regions] 2685 // An ordered region may not be closely nested inside a critical, 2686 // atomic, or explicit task region. 2687 // An ordered region must be closely nested inside a loop region (or 2688 // parallel loop region) with an ordered clause. 2689 // OpenMP [2.8.1,simd Construct, Restrictions] 2690 // An ordered construct with the simd clause is the only OpenMP construct 2691 // that can appear in the simd region. 2692 NestingProhibited = ParentRegion == OMPD_critical || 2693 isOpenMPTaskingDirective(ParentRegion) || 2694 !(isOpenMPSimdDirective(ParentRegion) || 2695 Stack->isParentOrderedRegion()); 2696 Recommend = ShouldBeInOrderedRegion; 2697 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 2698 // OpenMP [2.16, Nesting of Regions] 2699 // If specified, a teams construct must be contained within a target 2700 // construct. 2701 NestingProhibited = ParentRegion != OMPD_target; 2702 OrphanSeen = ParentRegion == OMPD_unknown; 2703 Recommend = ShouldBeInTargetRegion; 2704 } 2705 if (!NestingProhibited && 2706 !isOpenMPTargetExecutionDirective(CurrentRegion) && 2707 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 2708 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 2709 // OpenMP [2.16, Nesting of Regions] 2710 // distribute, parallel, parallel sections, parallel workshare, and the 2711 // parallel loop and parallel loop SIMD constructs are the only OpenMP 2712 // constructs that can be closely nested in the teams region. 2713 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 2714 !isOpenMPDistributeDirective(CurrentRegion); 2715 Recommend = ShouldBeInParallelRegion; 2716 } 2717 if (!NestingProhibited && 2718 isOpenMPNestingDistributeDirective(CurrentRegion)) { 2719 // OpenMP 4.5 [2.17 Nesting of Regions] 2720 // The region associated with the distribute construct must be strictly 2721 // nested inside a teams region 2722 NestingProhibited = 2723 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 2724 Recommend = ShouldBeInTeamsRegion; 2725 } 2726 if (!NestingProhibited && 2727 (isOpenMPTargetExecutionDirective(CurrentRegion) || 2728 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 2729 // OpenMP 4.5 [2.17 Nesting of Regions] 2730 // If a target, target update, target data, target enter data, or 2731 // target exit data construct is encountered during execution of a 2732 // target region, the behavior is unspecified. 2733 NestingProhibited = Stack->hasDirective( 2734 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2735 SourceLocation) -> bool { 2736 if (isOpenMPTargetExecutionDirective(K)) { 2737 OffendingRegion = K; 2738 return true; 2739 } else 2740 return false; 2741 }, 2742 false /* don't skip top directive */); 2743 CloseNesting = false; 2744 } 2745 if (NestingProhibited) { 2746 if (OrphanSeen) { 2747 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 2748 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 2749 } else { 2750 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 2751 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 2752 << Recommend << getOpenMPDirectiveName(CurrentRegion); 2753 } 2754 return true; 2755 } 2756 } 2757 return false; 2758 } 2759 2760 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 2761 ArrayRef<OMPClause *> Clauses, 2762 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 2763 bool ErrorFound = false; 2764 unsigned NamedModifiersNumber = 0; 2765 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 2766 OMPD_unknown + 1); 2767 SmallVector<SourceLocation, 4> NameModifierLoc; 2768 for (const auto *C : Clauses) { 2769 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 2770 // At most one if clause without a directive-name-modifier can appear on 2771 // the directive. 2772 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 2773 if (FoundNameModifiers[CurNM]) { 2774 S.Diag(C->getLocStart(), diag::err_omp_more_one_clause) 2775 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 2776 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 2777 ErrorFound = true; 2778 } else if (CurNM != OMPD_unknown) { 2779 NameModifierLoc.push_back(IC->getNameModifierLoc()); 2780 ++NamedModifiersNumber; 2781 } 2782 FoundNameModifiers[CurNM] = IC; 2783 if (CurNM == OMPD_unknown) 2784 continue; 2785 // Check if the specified name modifier is allowed for the current 2786 // directive. 2787 // At most one if clause with the particular directive-name-modifier can 2788 // appear on the directive. 2789 bool MatchFound = false; 2790 for (auto NM : AllowedNameModifiers) { 2791 if (CurNM == NM) { 2792 MatchFound = true; 2793 break; 2794 } 2795 } 2796 if (!MatchFound) { 2797 S.Diag(IC->getNameModifierLoc(), 2798 diag::err_omp_wrong_if_directive_name_modifier) 2799 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 2800 ErrorFound = true; 2801 } 2802 } 2803 } 2804 // If any if clause on the directive includes a directive-name-modifier then 2805 // all if clauses on the directive must include a directive-name-modifier. 2806 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 2807 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 2808 S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(), 2809 diag::err_omp_no_more_if_clause); 2810 } else { 2811 std::string Values; 2812 std::string Sep(", "); 2813 unsigned AllowedCnt = 0; 2814 unsigned TotalAllowedNum = 2815 AllowedNameModifiers.size() - NamedModifiersNumber; 2816 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 2817 ++Cnt) { 2818 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 2819 if (!FoundNameModifiers[NM]) { 2820 Values += "'"; 2821 Values += getOpenMPDirectiveName(NM); 2822 Values += "'"; 2823 if (AllowedCnt + 2 == TotalAllowedNum) 2824 Values += " or "; 2825 else if (AllowedCnt + 1 != TotalAllowedNum) 2826 Values += Sep; 2827 ++AllowedCnt; 2828 } 2829 } 2830 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(), 2831 diag::err_omp_unnamed_if_clause) 2832 << (TotalAllowedNum > 1) << Values; 2833 } 2834 for (auto Loc : NameModifierLoc) { 2835 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 2836 } 2837 ErrorFound = true; 2838 } 2839 return ErrorFound; 2840 } 2841 2842 StmtResult Sema::ActOnOpenMPExecutableDirective( 2843 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 2844 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 2845 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 2846 StmtResult Res = StmtError(); 2847 // First check CancelRegion which is then used in checkNestingOfRegions. 2848 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 2849 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 2850 StartLoc)) 2851 return StmtError(); 2852 2853 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 2854 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 2855 bool ErrorFound = false; 2856 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 2857 if (AStmt && !CurContext->isDependentContext()) { 2858 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 2859 2860 // Check default data sharing attributes for referenced variables. 2861 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 2862 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 2863 Stmt *S = AStmt; 2864 while (--ThisCaptureLevel >= 0) 2865 S = cast<CapturedStmt>(S)->getCapturedStmt(); 2866 DSAChecker.Visit(S); 2867 if (DSAChecker.isErrorFound()) 2868 return StmtError(); 2869 // Generate list of implicitly defined firstprivate variables. 2870 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 2871 2872 SmallVector<Expr *, 4> ImplicitFirstprivates( 2873 DSAChecker.getImplicitFirstprivate().begin(), 2874 DSAChecker.getImplicitFirstprivate().end()); 2875 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 2876 DSAChecker.getImplicitMap().end()); 2877 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 2878 for (auto *C : Clauses) { 2879 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 2880 for (auto *E : IRC->taskgroup_descriptors()) 2881 if (E) 2882 ImplicitFirstprivates.emplace_back(E); 2883 } 2884 } 2885 if (!ImplicitFirstprivates.empty()) { 2886 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 2887 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 2888 SourceLocation())) { 2889 ClausesWithImplicit.push_back(Implicit); 2890 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 2891 ImplicitFirstprivates.size(); 2892 } else 2893 ErrorFound = true; 2894 } 2895 if (!ImplicitMaps.empty()) { 2896 if (OMPClause *Implicit = ActOnOpenMPMapClause( 2897 OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, 2898 SourceLocation(), SourceLocation(), ImplicitMaps, 2899 SourceLocation(), SourceLocation(), SourceLocation())) { 2900 ClausesWithImplicit.emplace_back(Implicit); 2901 ErrorFound |= 2902 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 2903 } else 2904 ErrorFound = true; 2905 } 2906 } 2907 2908 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 2909 switch (Kind) { 2910 case OMPD_parallel: 2911 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 2912 EndLoc); 2913 AllowedNameModifiers.push_back(OMPD_parallel); 2914 break; 2915 case OMPD_simd: 2916 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 2917 VarsWithInheritedDSA); 2918 break; 2919 case OMPD_for: 2920 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 2921 VarsWithInheritedDSA); 2922 break; 2923 case OMPD_for_simd: 2924 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 2925 EndLoc, VarsWithInheritedDSA); 2926 break; 2927 case OMPD_sections: 2928 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 2929 EndLoc); 2930 break; 2931 case OMPD_section: 2932 assert(ClausesWithImplicit.empty() && 2933 "No clauses are allowed for 'omp section' directive"); 2934 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 2935 break; 2936 case OMPD_single: 2937 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 2938 EndLoc); 2939 break; 2940 case OMPD_master: 2941 assert(ClausesWithImplicit.empty() && 2942 "No clauses are allowed for 'omp master' directive"); 2943 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 2944 break; 2945 case OMPD_critical: 2946 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 2947 StartLoc, EndLoc); 2948 break; 2949 case OMPD_parallel_for: 2950 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 2951 EndLoc, VarsWithInheritedDSA); 2952 AllowedNameModifiers.push_back(OMPD_parallel); 2953 break; 2954 case OMPD_parallel_for_simd: 2955 Res = ActOnOpenMPParallelForSimdDirective( 2956 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2957 AllowedNameModifiers.push_back(OMPD_parallel); 2958 break; 2959 case OMPD_parallel_sections: 2960 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 2961 StartLoc, EndLoc); 2962 AllowedNameModifiers.push_back(OMPD_parallel); 2963 break; 2964 case OMPD_task: 2965 Res = 2966 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 2967 AllowedNameModifiers.push_back(OMPD_task); 2968 break; 2969 case OMPD_taskyield: 2970 assert(ClausesWithImplicit.empty() && 2971 "No clauses are allowed for 'omp taskyield' directive"); 2972 assert(AStmt == nullptr && 2973 "No associated statement allowed for 'omp taskyield' directive"); 2974 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 2975 break; 2976 case OMPD_barrier: 2977 assert(ClausesWithImplicit.empty() && 2978 "No clauses are allowed for 'omp barrier' directive"); 2979 assert(AStmt == nullptr && 2980 "No associated statement allowed for 'omp barrier' directive"); 2981 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 2982 break; 2983 case OMPD_taskwait: 2984 assert(ClausesWithImplicit.empty() && 2985 "No clauses are allowed for 'omp taskwait' directive"); 2986 assert(AStmt == nullptr && 2987 "No associated statement allowed for 'omp taskwait' directive"); 2988 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 2989 break; 2990 case OMPD_taskgroup: 2991 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 2992 EndLoc); 2993 break; 2994 case OMPD_flush: 2995 assert(AStmt == nullptr && 2996 "No associated statement allowed for 'omp flush' directive"); 2997 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 2998 break; 2999 case OMPD_ordered: 3000 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 3001 EndLoc); 3002 break; 3003 case OMPD_atomic: 3004 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 3005 EndLoc); 3006 break; 3007 case OMPD_teams: 3008 Res = 3009 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3010 break; 3011 case OMPD_target: 3012 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 3013 EndLoc); 3014 AllowedNameModifiers.push_back(OMPD_target); 3015 break; 3016 case OMPD_target_parallel: 3017 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 3018 StartLoc, EndLoc); 3019 AllowedNameModifiers.push_back(OMPD_target); 3020 AllowedNameModifiers.push_back(OMPD_parallel); 3021 break; 3022 case OMPD_target_parallel_for: 3023 Res = ActOnOpenMPTargetParallelForDirective( 3024 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3025 AllowedNameModifiers.push_back(OMPD_target); 3026 AllowedNameModifiers.push_back(OMPD_parallel); 3027 break; 3028 case OMPD_cancellation_point: 3029 assert(ClausesWithImplicit.empty() && 3030 "No clauses are allowed for 'omp cancellation point' directive"); 3031 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 3032 "cancellation point' directive"); 3033 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 3034 break; 3035 case OMPD_cancel: 3036 assert(AStmt == nullptr && 3037 "No associated statement allowed for 'omp cancel' directive"); 3038 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 3039 CancelRegion); 3040 AllowedNameModifiers.push_back(OMPD_cancel); 3041 break; 3042 case OMPD_target_data: 3043 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 3044 EndLoc); 3045 AllowedNameModifiers.push_back(OMPD_target_data); 3046 break; 3047 case OMPD_target_enter_data: 3048 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 3049 EndLoc, AStmt); 3050 AllowedNameModifiers.push_back(OMPD_target_enter_data); 3051 break; 3052 case OMPD_target_exit_data: 3053 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 3054 EndLoc, AStmt); 3055 AllowedNameModifiers.push_back(OMPD_target_exit_data); 3056 break; 3057 case OMPD_taskloop: 3058 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 3059 EndLoc, VarsWithInheritedDSA); 3060 AllowedNameModifiers.push_back(OMPD_taskloop); 3061 break; 3062 case OMPD_taskloop_simd: 3063 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3064 EndLoc, VarsWithInheritedDSA); 3065 AllowedNameModifiers.push_back(OMPD_taskloop); 3066 break; 3067 case OMPD_distribute: 3068 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 3069 EndLoc, VarsWithInheritedDSA); 3070 break; 3071 case OMPD_target_update: 3072 Res = ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, 3073 EndLoc, AStmt); 3074 AllowedNameModifiers.push_back(OMPD_target_update); 3075 break; 3076 case OMPD_distribute_parallel_for: 3077 Res = ActOnOpenMPDistributeParallelForDirective( 3078 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3079 AllowedNameModifiers.push_back(OMPD_parallel); 3080 break; 3081 case OMPD_distribute_parallel_for_simd: 3082 Res = ActOnOpenMPDistributeParallelForSimdDirective( 3083 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3084 AllowedNameModifiers.push_back(OMPD_parallel); 3085 break; 3086 case OMPD_distribute_simd: 3087 Res = ActOnOpenMPDistributeSimdDirective( 3088 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3089 break; 3090 case OMPD_target_parallel_for_simd: 3091 Res = ActOnOpenMPTargetParallelForSimdDirective( 3092 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3093 AllowedNameModifiers.push_back(OMPD_target); 3094 AllowedNameModifiers.push_back(OMPD_parallel); 3095 break; 3096 case OMPD_target_simd: 3097 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3098 EndLoc, VarsWithInheritedDSA); 3099 AllowedNameModifiers.push_back(OMPD_target); 3100 break; 3101 case OMPD_teams_distribute: 3102 Res = ActOnOpenMPTeamsDistributeDirective( 3103 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3104 break; 3105 case OMPD_teams_distribute_simd: 3106 Res = ActOnOpenMPTeamsDistributeSimdDirective( 3107 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3108 break; 3109 case OMPD_teams_distribute_parallel_for_simd: 3110 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 3111 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3112 AllowedNameModifiers.push_back(OMPD_parallel); 3113 break; 3114 case OMPD_teams_distribute_parallel_for: 3115 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 3116 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3117 AllowedNameModifiers.push_back(OMPD_parallel); 3118 break; 3119 case OMPD_target_teams: 3120 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 3121 EndLoc); 3122 AllowedNameModifiers.push_back(OMPD_target); 3123 break; 3124 case OMPD_target_teams_distribute: 3125 Res = ActOnOpenMPTargetTeamsDistributeDirective( 3126 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3127 AllowedNameModifiers.push_back(OMPD_target); 3128 break; 3129 case OMPD_target_teams_distribute_parallel_for: 3130 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 3131 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3132 AllowedNameModifiers.push_back(OMPD_target); 3133 AllowedNameModifiers.push_back(OMPD_parallel); 3134 break; 3135 case OMPD_target_teams_distribute_parallel_for_simd: 3136 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 3137 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3138 AllowedNameModifiers.push_back(OMPD_target); 3139 AllowedNameModifiers.push_back(OMPD_parallel); 3140 break; 3141 case OMPD_target_teams_distribute_simd: 3142 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 3143 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3144 AllowedNameModifiers.push_back(OMPD_target); 3145 break; 3146 case OMPD_declare_target: 3147 case OMPD_end_declare_target: 3148 case OMPD_threadprivate: 3149 case OMPD_declare_reduction: 3150 case OMPD_declare_simd: 3151 llvm_unreachable("OpenMP Directive is not allowed"); 3152 case OMPD_unknown: 3153 llvm_unreachable("Unknown OpenMP directive"); 3154 } 3155 3156 for (auto P : VarsWithInheritedDSA) { 3157 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 3158 << P.first << P.second->getSourceRange(); 3159 } 3160 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 3161 3162 if (!AllowedNameModifiers.empty()) 3163 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 3164 ErrorFound; 3165 3166 if (ErrorFound) 3167 return StmtError(); 3168 return Res; 3169 } 3170 3171 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 3172 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 3173 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 3174 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 3175 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 3176 assert(Aligneds.size() == Alignments.size()); 3177 assert(Linears.size() == LinModifiers.size()); 3178 assert(Linears.size() == Steps.size()); 3179 if (!DG || DG.get().isNull()) 3180 return DeclGroupPtrTy(); 3181 3182 if (!DG.get().isSingleDecl()) { 3183 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 3184 return DG; 3185 } 3186 auto *ADecl = DG.get().getSingleDecl(); 3187 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 3188 ADecl = FTD->getTemplatedDecl(); 3189 3190 auto *FD = dyn_cast<FunctionDecl>(ADecl); 3191 if (!FD) { 3192 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 3193 return DeclGroupPtrTy(); 3194 } 3195 3196 // OpenMP [2.8.2, declare simd construct, Description] 3197 // The parameter of the simdlen clause must be a constant positive integer 3198 // expression. 3199 ExprResult SL; 3200 if (Simdlen) 3201 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 3202 // OpenMP [2.8.2, declare simd construct, Description] 3203 // The special this pointer can be used as if was one of the arguments to the 3204 // function in any of the linear, aligned, or uniform clauses. 3205 // The uniform clause declares one or more arguments to have an invariant 3206 // value for all concurrent invocations of the function in the execution of a 3207 // single SIMD loop. 3208 llvm::DenseMap<Decl *, Expr *> UniformedArgs; 3209 Expr *UniformedLinearThis = nullptr; 3210 for (auto *E : Uniforms) { 3211 E = E->IgnoreParenImpCasts(); 3212 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3213 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 3214 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3215 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3216 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 3217 UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E)); 3218 continue; 3219 } 3220 if (isa<CXXThisExpr>(E)) { 3221 UniformedLinearThis = E; 3222 continue; 3223 } 3224 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3225 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3226 } 3227 // OpenMP [2.8.2, declare simd construct, Description] 3228 // The aligned clause declares that the object to which each list item points 3229 // is aligned to the number of bytes expressed in the optional parameter of 3230 // the aligned clause. 3231 // The special this pointer can be used as if was one of the arguments to the 3232 // function in any of the linear, aligned, or uniform clauses. 3233 // The type of list items appearing in the aligned clause must be array, 3234 // pointer, reference to array, or reference to pointer. 3235 llvm::DenseMap<Decl *, Expr *> AlignedArgs; 3236 Expr *AlignedThis = nullptr; 3237 for (auto *E : Aligneds) { 3238 E = E->IgnoreParenImpCasts(); 3239 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3240 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3241 auto *CanonPVD = PVD->getCanonicalDecl(); 3242 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3243 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3244 ->getCanonicalDecl() == CanonPVD) { 3245 // OpenMP [2.8.1, simd construct, Restrictions] 3246 // A list-item cannot appear in more than one aligned clause. 3247 if (AlignedArgs.count(CanonPVD) > 0) { 3248 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3249 << 1 << E->getSourceRange(); 3250 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 3251 diag::note_omp_explicit_dsa) 3252 << getOpenMPClauseName(OMPC_aligned); 3253 continue; 3254 } 3255 AlignedArgs[CanonPVD] = E; 3256 QualType QTy = PVD->getType() 3257 .getNonReferenceType() 3258 .getUnqualifiedType() 3259 .getCanonicalType(); 3260 const Type *Ty = QTy.getTypePtrOrNull(); 3261 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 3262 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 3263 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 3264 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 3265 } 3266 continue; 3267 } 3268 } 3269 if (isa<CXXThisExpr>(E)) { 3270 if (AlignedThis) { 3271 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3272 << 2 << E->getSourceRange(); 3273 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 3274 << getOpenMPClauseName(OMPC_aligned); 3275 } 3276 AlignedThis = E; 3277 continue; 3278 } 3279 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3280 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3281 } 3282 // The optional parameter of the aligned clause, alignment, must be a constant 3283 // positive integer expression. If no optional parameter is specified, 3284 // implementation-defined default alignments for SIMD instructions on the 3285 // target platforms are assumed. 3286 SmallVector<Expr *, 4> NewAligns; 3287 for (auto *E : Alignments) { 3288 ExprResult Align; 3289 if (E) 3290 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 3291 NewAligns.push_back(Align.get()); 3292 } 3293 // OpenMP [2.8.2, declare simd construct, Description] 3294 // The linear clause declares one or more list items to be private to a SIMD 3295 // lane and to have a linear relationship with respect to the iteration space 3296 // of a loop. 3297 // The special this pointer can be used as if was one of the arguments to the 3298 // function in any of the linear, aligned, or uniform clauses. 3299 // When a linear-step expression is specified in a linear clause it must be 3300 // either a constant integer expression or an integer-typed parameter that is 3301 // specified in a uniform clause on the directive. 3302 llvm::DenseMap<Decl *, Expr *> LinearArgs; 3303 const bool IsUniformedThis = UniformedLinearThis != nullptr; 3304 auto MI = LinModifiers.begin(); 3305 for (auto *E : Linears) { 3306 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 3307 ++MI; 3308 E = E->IgnoreParenImpCasts(); 3309 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3310 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3311 auto *CanonPVD = PVD->getCanonicalDecl(); 3312 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3313 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3314 ->getCanonicalDecl() == CanonPVD) { 3315 // OpenMP [2.15.3.7, linear Clause, Restrictions] 3316 // A list-item cannot appear in more than one linear clause. 3317 if (LinearArgs.count(CanonPVD) > 0) { 3318 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3319 << getOpenMPClauseName(OMPC_linear) 3320 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 3321 Diag(LinearArgs[CanonPVD]->getExprLoc(), 3322 diag::note_omp_explicit_dsa) 3323 << getOpenMPClauseName(OMPC_linear); 3324 continue; 3325 } 3326 // Each argument can appear in at most one uniform or linear clause. 3327 if (UniformedArgs.count(CanonPVD) > 0) { 3328 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3329 << getOpenMPClauseName(OMPC_linear) 3330 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 3331 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 3332 diag::note_omp_explicit_dsa) 3333 << getOpenMPClauseName(OMPC_uniform); 3334 continue; 3335 } 3336 LinearArgs[CanonPVD] = E; 3337 if (E->isValueDependent() || E->isTypeDependent() || 3338 E->isInstantiationDependent() || 3339 E->containsUnexpandedParameterPack()) 3340 continue; 3341 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 3342 PVD->getOriginalType()); 3343 continue; 3344 } 3345 } 3346 if (isa<CXXThisExpr>(E)) { 3347 if (UniformedLinearThis) { 3348 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3349 << getOpenMPClauseName(OMPC_linear) 3350 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 3351 << E->getSourceRange(); 3352 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 3353 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 3354 : OMPC_linear); 3355 continue; 3356 } 3357 UniformedLinearThis = E; 3358 if (E->isValueDependent() || E->isTypeDependent() || 3359 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 3360 continue; 3361 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 3362 E->getType()); 3363 continue; 3364 } 3365 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3366 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3367 } 3368 Expr *Step = nullptr; 3369 Expr *NewStep = nullptr; 3370 SmallVector<Expr *, 4> NewSteps; 3371 for (auto *E : Steps) { 3372 // Skip the same step expression, it was checked already. 3373 if (Step == E || !E) { 3374 NewSteps.push_back(E ? NewStep : nullptr); 3375 continue; 3376 } 3377 Step = E; 3378 if (auto *DRE = dyn_cast<DeclRefExpr>(Step)) 3379 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3380 auto *CanonPVD = PVD->getCanonicalDecl(); 3381 if (UniformedArgs.count(CanonPVD) == 0) { 3382 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 3383 << Step->getSourceRange(); 3384 } else if (E->isValueDependent() || E->isTypeDependent() || 3385 E->isInstantiationDependent() || 3386 E->containsUnexpandedParameterPack() || 3387 CanonPVD->getType()->hasIntegerRepresentation()) 3388 NewSteps.push_back(Step); 3389 else { 3390 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 3391 << Step->getSourceRange(); 3392 } 3393 continue; 3394 } 3395 NewStep = Step; 3396 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 3397 !Step->isInstantiationDependent() && 3398 !Step->containsUnexpandedParameterPack()) { 3399 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 3400 .get(); 3401 if (NewStep) 3402 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 3403 } 3404 NewSteps.push_back(NewStep); 3405 } 3406 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 3407 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 3408 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 3409 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 3410 const_cast<Expr **>(Linears.data()), Linears.size(), 3411 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 3412 NewSteps.data(), NewSteps.size(), SR); 3413 ADecl->addAttr(NewAttr); 3414 return ConvertDeclToDeclGroup(ADecl); 3415 } 3416 3417 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 3418 Stmt *AStmt, 3419 SourceLocation StartLoc, 3420 SourceLocation EndLoc) { 3421 if (!AStmt) 3422 return StmtError(); 3423 3424 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 3425 // 1.2.2 OpenMP Language Terminology 3426 // Structured block - An executable statement with a single entry at the 3427 // top and a single exit at the bottom. 3428 // The point of exit cannot be a branch out of the structured block. 3429 // longjmp() and throw() must not violate the entry/exit criteria. 3430 CS->getCapturedDecl()->setNothrow(); 3431 3432 getCurFunction()->setHasBranchProtectedScope(); 3433 3434 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 3435 DSAStack->isCancelRegion()); 3436 } 3437 3438 namespace { 3439 /// \brief Helper class for checking canonical form of the OpenMP loops and 3440 /// extracting iteration space of each loop in the loop nest, that will be used 3441 /// for IR generation. 3442 class OpenMPIterationSpaceChecker { 3443 /// \brief Reference to Sema. 3444 Sema &SemaRef; 3445 /// \brief A location for diagnostics (when there is no some better location). 3446 SourceLocation DefaultLoc; 3447 /// \brief A location for diagnostics (when increment is not compatible). 3448 SourceLocation ConditionLoc; 3449 /// \brief A source location for referring to loop init later. 3450 SourceRange InitSrcRange; 3451 /// \brief A source location for referring to condition later. 3452 SourceRange ConditionSrcRange; 3453 /// \brief A source location for referring to increment later. 3454 SourceRange IncrementSrcRange; 3455 /// \brief Loop variable. 3456 ValueDecl *LCDecl = nullptr; 3457 /// \brief Reference to loop variable. 3458 Expr *LCRef = nullptr; 3459 /// \brief Lower bound (initializer for the var). 3460 Expr *LB = nullptr; 3461 /// \brief Upper bound. 3462 Expr *UB = nullptr; 3463 /// \brief Loop step (increment). 3464 Expr *Step = nullptr; 3465 /// \brief This flag is true when condition is one of: 3466 /// Var < UB 3467 /// Var <= UB 3468 /// UB > Var 3469 /// UB >= Var 3470 bool TestIsLessOp = false; 3471 /// \brief This flag is true when condition is strict ( < or > ). 3472 bool TestIsStrictOp = false; 3473 /// \brief This flag is true when step is subtracted on each iteration. 3474 bool SubtractStep = false; 3475 3476 public: 3477 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 3478 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 3479 /// \brief Check init-expr for canonical loop form and save loop counter 3480 /// variable - #Var and its initialization value - #LB. 3481 bool CheckInit(Stmt *S, bool EmitDiags = true); 3482 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags 3483 /// for less/greater and for strict/non-strict comparison. 3484 bool CheckCond(Expr *S); 3485 /// \brief Check incr-expr for canonical loop form and return true if it 3486 /// does not conform, otherwise save loop step (#Step). 3487 bool CheckInc(Expr *S); 3488 /// \brief Return the loop counter variable. 3489 ValueDecl *GetLoopDecl() const { return LCDecl; } 3490 /// \brief Return the reference expression to loop counter variable. 3491 Expr *GetLoopDeclRefExpr() const { return LCRef; } 3492 /// \brief Source range of the loop init. 3493 SourceRange GetInitSrcRange() const { return InitSrcRange; } 3494 /// \brief Source range of the loop condition. 3495 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; } 3496 /// \brief Source range of the loop increment. 3497 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; } 3498 /// \brief True if the step should be subtracted. 3499 bool ShouldSubtractStep() const { return SubtractStep; } 3500 /// \brief Build the expression to calculate the number of iterations. 3501 Expr * 3502 BuildNumIterations(Scope *S, const bool LimitedType, 3503 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3504 /// \brief Build the precondition expression for the loops. 3505 Expr *BuildPreCond(Scope *S, Expr *Cond, 3506 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3507 /// \brief Build reference expression to the counter be used for codegen. 3508 DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures, 3509 DSAStackTy &DSA) const; 3510 /// \brief Build reference expression to the private counter be used for 3511 /// codegen. 3512 Expr *BuildPrivateCounterVar() const; 3513 /// \brief Build initialization of the counter be used for codegen. 3514 Expr *BuildCounterInit() const; 3515 /// \brief Build step of the counter be used for codegen. 3516 Expr *BuildCounterStep() const; 3517 /// \brief Return true if any expression is dependent. 3518 bool Dependent() const; 3519 3520 private: 3521 /// \brief Check the right-hand side of an assignment in the increment 3522 /// expression. 3523 bool CheckIncRHS(Expr *RHS); 3524 /// \brief Helper to set loop counter variable and its initializer. 3525 bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); 3526 /// \brief Helper to set upper bound. 3527 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR, 3528 SourceLocation SL); 3529 /// \brief Helper to set loop increment. 3530 bool SetStep(Expr *NewStep, bool Subtract); 3531 }; 3532 3533 bool OpenMPIterationSpaceChecker::Dependent() const { 3534 if (!LCDecl) { 3535 assert(!LB && !UB && !Step); 3536 return false; 3537 } 3538 return LCDecl->getType()->isDependentType() || 3539 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 3540 (Step && Step->isValueDependent()); 3541 } 3542 3543 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl, 3544 Expr *NewLCRefExpr, 3545 Expr *NewLB) { 3546 // State consistency checking to ensure correct usage. 3547 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 3548 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3549 if (!NewLCDecl || !NewLB) 3550 return true; 3551 LCDecl = getCanonicalDecl(NewLCDecl); 3552 LCRef = NewLCRefExpr; 3553 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 3554 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3555 if ((Ctor->isCopyOrMoveConstructor() || 3556 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3557 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3558 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 3559 LB = NewLB; 3560 return false; 3561 } 3562 3563 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp, 3564 SourceRange SR, SourceLocation SL) { 3565 // State consistency checking to ensure correct usage. 3566 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 3567 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3568 if (!NewUB) 3569 return true; 3570 UB = NewUB; 3571 TestIsLessOp = LessOp; 3572 TestIsStrictOp = StrictOp; 3573 ConditionSrcRange = SR; 3574 ConditionLoc = SL; 3575 return false; 3576 } 3577 3578 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) { 3579 // State consistency checking to ensure correct usage. 3580 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 3581 if (!NewStep) 3582 return true; 3583 if (!NewStep->isValueDependent()) { 3584 // Check that the step is integer expression. 3585 SourceLocation StepLoc = NewStep->getLocStart(); 3586 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 3587 StepLoc, getExprAsWritten(NewStep)); 3588 if (Val.isInvalid()) 3589 return true; 3590 NewStep = Val.get(); 3591 3592 // OpenMP [2.6, Canonical Loop Form, Restrictions] 3593 // If test-expr is of form var relational-op b and relational-op is < or 3594 // <= then incr-expr must cause var to increase on each iteration of the 3595 // loop. If test-expr is of form var relational-op b and relational-op is 3596 // > or >= then incr-expr must cause var to decrease on each iteration of 3597 // the loop. 3598 // If test-expr is of form b relational-op var and relational-op is < or 3599 // <= then incr-expr must cause var to decrease on each iteration of the 3600 // loop. If test-expr is of form b relational-op var and relational-op is 3601 // > or >= then incr-expr must cause var to increase on each iteration of 3602 // the loop. 3603 llvm::APSInt Result; 3604 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 3605 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 3606 bool IsConstNeg = 3607 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 3608 bool IsConstPos = 3609 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 3610 bool IsConstZero = IsConstant && !Result.getBoolValue(); 3611 if (UB && (IsConstZero || 3612 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 3613 : (IsConstPos || (IsUnsigned && !Subtract))))) { 3614 SemaRef.Diag(NewStep->getExprLoc(), 3615 diag::err_omp_loop_incr_not_compatible) 3616 << LCDecl << TestIsLessOp << NewStep->getSourceRange(); 3617 SemaRef.Diag(ConditionLoc, 3618 diag::note_omp_loop_cond_requres_compatible_incr) 3619 << TestIsLessOp << ConditionSrcRange; 3620 return true; 3621 } 3622 if (TestIsLessOp == Subtract) { 3623 NewStep = 3624 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 3625 .get(); 3626 Subtract = !Subtract; 3627 } 3628 } 3629 3630 Step = NewStep; 3631 SubtractStep = Subtract; 3632 return false; 3633 } 3634 3635 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { 3636 // Check init-expr for canonical loop form and save loop counter 3637 // variable - #Var and its initialization value - #LB. 3638 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 3639 // var = lb 3640 // integer-type var = lb 3641 // random-access-iterator-type var = lb 3642 // pointer-type var = lb 3643 // 3644 if (!S) { 3645 if (EmitDiags) { 3646 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 3647 } 3648 return true; 3649 } 3650 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 3651 if (!ExprTemp->cleanupsHaveSideEffects()) 3652 S = ExprTemp->getSubExpr(); 3653 3654 InitSrcRange = S->getSourceRange(); 3655 if (Expr *E = dyn_cast<Expr>(S)) 3656 S = E->IgnoreParens(); 3657 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 3658 if (BO->getOpcode() == BO_Assign) { 3659 auto *LHS = BO->getLHS()->IgnoreParens(); 3660 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 3661 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3662 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3663 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3664 return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); 3665 } 3666 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3667 if (ME->isArrow() && 3668 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3669 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3670 } 3671 } 3672 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 3673 if (DS->isSingleDecl()) { 3674 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 3675 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 3676 // Accept non-canonical init form here but emit ext. warning. 3677 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 3678 SemaRef.Diag(S->getLocStart(), 3679 diag::ext_omp_loop_not_canonical_init) 3680 << S->getSourceRange(); 3681 return SetLCDeclAndLB(Var, nullptr, Var->getInit()); 3682 } 3683 } 3684 } 3685 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3686 if (CE->getOperator() == OO_Equal) { 3687 auto *LHS = CE->getArg(0); 3688 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 3689 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3690 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3691 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3692 return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); 3693 } 3694 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3695 if (ME->isArrow() && 3696 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3697 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3698 } 3699 } 3700 } 3701 3702 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3703 return false; 3704 if (EmitDiags) { 3705 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init) 3706 << S->getSourceRange(); 3707 } 3708 return true; 3709 } 3710 3711 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the 3712 /// variable (which may be the loop variable) if possible. 3713 static const ValueDecl *GetInitLCDecl(Expr *E) { 3714 if (!E) 3715 return nullptr; 3716 E = getExprAsWritten(E); 3717 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 3718 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3719 if ((Ctor->isCopyOrMoveConstructor() || 3720 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3721 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3722 E = CE->getArg(0)->IgnoreParenImpCasts(); 3723 if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 3724 if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 3725 return getCanonicalDecl(VD); 3726 } 3727 if (auto *ME = dyn_cast_or_null<MemberExpr>(E)) 3728 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3729 return getCanonicalDecl(ME->getMemberDecl()); 3730 return nullptr; 3731 } 3732 3733 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { 3734 // Check test-expr for canonical form, save upper-bound UB, flags for 3735 // less/greater and for strict/non-strict comparison. 3736 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3737 // var relational-op b 3738 // b relational-op var 3739 // 3740 if (!S) { 3741 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 3742 return true; 3743 } 3744 S = getExprAsWritten(S); 3745 SourceLocation CondLoc = S->getLocStart(); 3746 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 3747 if (BO->isRelationalOp()) { 3748 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3749 return SetUB(BO->getRHS(), 3750 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 3751 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3752 BO->getSourceRange(), BO->getOperatorLoc()); 3753 if (GetInitLCDecl(BO->getRHS()) == LCDecl) 3754 return SetUB(BO->getLHS(), 3755 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 3756 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3757 BO->getSourceRange(), BO->getOperatorLoc()); 3758 } 3759 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3760 if (CE->getNumArgs() == 2) { 3761 auto Op = CE->getOperator(); 3762 switch (Op) { 3763 case OO_Greater: 3764 case OO_GreaterEqual: 3765 case OO_Less: 3766 case OO_LessEqual: 3767 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3768 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 3769 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3770 CE->getOperatorLoc()); 3771 if (GetInitLCDecl(CE->getArg(1)) == LCDecl) 3772 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 3773 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3774 CE->getOperatorLoc()); 3775 break; 3776 default: 3777 break; 3778 } 3779 } 3780 } 3781 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3782 return false; 3783 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 3784 << S->getSourceRange() << LCDecl; 3785 return true; 3786 } 3787 3788 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) { 3789 // RHS of canonical loop form increment can be: 3790 // var + incr 3791 // incr + var 3792 // var - incr 3793 // 3794 RHS = RHS->IgnoreParenImpCasts(); 3795 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 3796 if (BO->isAdditiveOp()) { 3797 bool IsAdd = BO->getOpcode() == BO_Add; 3798 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3799 return SetStep(BO->getRHS(), !IsAdd); 3800 if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl) 3801 return SetStep(BO->getLHS(), false); 3802 } 3803 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 3804 bool IsAdd = CE->getOperator() == OO_Plus; 3805 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 3806 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3807 return SetStep(CE->getArg(1), !IsAdd); 3808 if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl) 3809 return SetStep(CE->getArg(0), false); 3810 } 3811 } 3812 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3813 return false; 3814 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr) 3815 << RHS->getSourceRange() << LCDecl; 3816 return true; 3817 } 3818 3819 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { 3820 // Check incr-expr for canonical loop form and return true if it 3821 // does not conform. 3822 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3823 // ++var 3824 // var++ 3825 // --var 3826 // var-- 3827 // var += incr 3828 // var -= incr 3829 // var = var + incr 3830 // var = incr + var 3831 // var = var - incr 3832 // 3833 if (!S) { 3834 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 3835 return true; 3836 } 3837 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 3838 if (!ExprTemp->cleanupsHaveSideEffects()) 3839 S = ExprTemp->getSubExpr(); 3840 3841 IncrementSrcRange = S->getSourceRange(); 3842 S = S->IgnoreParens(); 3843 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 3844 if (UO->isIncrementDecrementOp() && 3845 GetInitLCDecl(UO->getSubExpr()) == LCDecl) 3846 return SetStep(SemaRef 3847 .ActOnIntegerConstant(UO->getLocStart(), 3848 (UO->isDecrementOp() ? -1 : 1)) 3849 .get(), 3850 false); 3851 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 3852 switch (BO->getOpcode()) { 3853 case BO_AddAssign: 3854 case BO_SubAssign: 3855 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3856 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 3857 break; 3858 case BO_Assign: 3859 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3860 return CheckIncRHS(BO->getRHS()); 3861 break; 3862 default: 3863 break; 3864 } 3865 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3866 switch (CE->getOperator()) { 3867 case OO_PlusPlus: 3868 case OO_MinusMinus: 3869 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3870 return SetStep(SemaRef 3871 .ActOnIntegerConstant( 3872 CE->getLocStart(), 3873 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 3874 .get(), 3875 false); 3876 break; 3877 case OO_PlusEqual: 3878 case OO_MinusEqual: 3879 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3880 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 3881 break; 3882 case OO_Equal: 3883 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3884 return CheckIncRHS(CE->getArg(1)); 3885 break; 3886 default: 3887 break; 3888 } 3889 } 3890 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3891 return false; 3892 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr) 3893 << S->getSourceRange() << LCDecl; 3894 return true; 3895 } 3896 3897 static ExprResult 3898 tryBuildCapture(Sema &SemaRef, Expr *Capture, 3899 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 3900 if (SemaRef.CurContext->isDependentContext()) 3901 return ExprResult(Capture); 3902 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 3903 return SemaRef.PerformImplicitConversion( 3904 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 3905 /*AllowExplicit=*/true); 3906 auto I = Captures.find(Capture); 3907 if (I != Captures.end()) 3908 return buildCapture(SemaRef, Capture, I->second); 3909 DeclRefExpr *Ref = nullptr; 3910 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 3911 Captures[Capture] = Ref; 3912 return Res; 3913 } 3914 3915 /// \brief Build the expression to calculate the number of iterations. 3916 Expr *OpenMPIterationSpaceChecker::BuildNumIterations( 3917 Scope *S, const bool LimitedType, 3918 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 3919 ExprResult Diff; 3920 auto VarType = LCDecl->getType().getNonReferenceType(); 3921 if (VarType->isIntegerType() || VarType->isPointerType() || 3922 SemaRef.getLangOpts().CPlusPlus) { 3923 // Upper - Lower 3924 auto *UBExpr = TestIsLessOp ? UB : LB; 3925 auto *LBExpr = TestIsLessOp ? LB : UB; 3926 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 3927 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 3928 if (!Upper || !Lower) 3929 return nullptr; 3930 3931 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 3932 3933 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 3934 // BuildBinOp already emitted error, this one is to point user to upper 3935 // and lower bound, and to tell what is passed to 'operator-'. 3936 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) 3937 << Upper->getSourceRange() << Lower->getSourceRange(); 3938 return nullptr; 3939 } 3940 } 3941 3942 if (!Diff.isUsable()) 3943 return nullptr; 3944 3945 // Upper - Lower [- 1] 3946 if (TestIsStrictOp) 3947 Diff = SemaRef.BuildBinOp( 3948 S, DefaultLoc, BO_Sub, Diff.get(), 3949 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 3950 if (!Diff.isUsable()) 3951 return nullptr; 3952 3953 // Upper - Lower [- 1] + Step 3954 auto NewStep = tryBuildCapture(SemaRef, Step, Captures); 3955 if (!NewStep.isUsable()) 3956 return nullptr; 3957 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 3958 if (!Diff.isUsable()) 3959 return nullptr; 3960 3961 // Parentheses (for dumping/debugging purposes only). 3962 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 3963 if (!Diff.isUsable()) 3964 return nullptr; 3965 3966 // (Upper - Lower [- 1] + Step) / Step 3967 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 3968 if (!Diff.isUsable()) 3969 return nullptr; 3970 3971 // OpenMP runtime requires 32-bit or 64-bit loop variables. 3972 QualType Type = Diff.get()->getType(); 3973 auto &C = SemaRef.Context; 3974 bool UseVarType = VarType->hasIntegerRepresentation() && 3975 C.getTypeSize(Type) > C.getTypeSize(VarType); 3976 if (!Type->isIntegerType() || UseVarType) { 3977 unsigned NewSize = 3978 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 3979 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 3980 : Type->hasSignedIntegerRepresentation(); 3981 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 3982 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 3983 Diff = SemaRef.PerformImplicitConversion( 3984 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 3985 if (!Diff.isUsable()) 3986 return nullptr; 3987 } 3988 } 3989 if (LimitedType) { 3990 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 3991 if (NewSize != C.getTypeSize(Type)) { 3992 if (NewSize < C.getTypeSize(Type)) { 3993 assert(NewSize == 64 && "incorrect loop var size"); 3994 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 3995 << InitSrcRange << ConditionSrcRange; 3996 } 3997 QualType NewType = C.getIntTypeForBitwidth( 3998 NewSize, Type->hasSignedIntegerRepresentation() || 3999 C.getTypeSize(Type) < NewSize); 4000 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 4001 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 4002 Sema::AA_Converting, true); 4003 if (!Diff.isUsable()) 4004 return nullptr; 4005 } 4006 } 4007 } 4008 4009 return Diff.get(); 4010 } 4011 4012 Expr *OpenMPIterationSpaceChecker::BuildPreCond( 4013 Scope *S, Expr *Cond, 4014 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 4015 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 4016 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4017 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4018 4019 auto NewLB = tryBuildCapture(SemaRef, LB, Captures); 4020 auto NewUB = tryBuildCapture(SemaRef, UB, Captures); 4021 if (!NewLB.isUsable() || !NewUB.isUsable()) 4022 return nullptr; 4023 4024 auto CondExpr = SemaRef.BuildBinOp( 4025 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) 4026 : (TestIsStrictOp ? BO_GT : BO_GE), 4027 NewLB.get(), NewUB.get()); 4028 if (CondExpr.isUsable()) { 4029 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 4030 SemaRef.Context.BoolTy)) 4031 CondExpr = SemaRef.PerformImplicitConversion( 4032 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 4033 /*AllowExplicit=*/true); 4034 } 4035 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4036 // Otherwise use original loop conditon and evaluate it in runtime. 4037 return CondExpr.isUsable() ? CondExpr.get() : Cond; 4038 } 4039 4040 /// \brief Build reference expression to the counter be used for codegen. 4041 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar( 4042 llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const { 4043 auto *VD = dyn_cast<VarDecl>(LCDecl); 4044 if (!VD) { 4045 VD = SemaRef.IsOpenMPCapturedDecl(LCDecl); 4046 auto *Ref = buildDeclRefExpr( 4047 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 4048 DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl, /*FromParent=*/false); 4049 // If the loop control decl is explicitly marked as private, do not mark it 4050 // as captured again. 4051 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 4052 Captures.insert(std::make_pair(LCRef, Ref)); 4053 return Ref; 4054 } 4055 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(), 4056 DefaultLoc); 4057 } 4058 4059 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const { 4060 if (LCDecl && !LCDecl->isInvalidDecl()) { 4061 auto Type = LCDecl->getType().getNonReferenceType(); 4062 auto *PrivateVar = 4063 buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(), 4064 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr); 4065 if (PrivateVar->isInvalidDecl()) 4066 return nullptr; 4067 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 4068 } 4069 return nullptr; 4070 } 4071 4072 /// \brief Build initialization of the counter to be used for codegen. 4073 Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; } 4074 4075 /// \brief Build step of the counter be used for codegen. 4076 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; } 4077 4078 /// \brief Iteration space of a single for loop. 4079 struct LoopIterationSpace final { 4080 /// \brief Condition of the loop. 4081 Expr *PreCond = nullptr; 4082 /// \brief This expression calculates the number of iterations in the loop. 4083 /// It is always possible to calculate it before starting the loop. 4084 Expr *NumIterations = nullptr; 4085 /// \brief The loop counter variable. 4086 Expr *CounterVar = nullptr; 4087 /// \brief Private loop counter variable. 4088 Expr *PrivateCounterVar = nullptr; 4089 /// \brief This is initializer for the initial value of #CounterVar. 4090 Expr *CounterInit = nullptr; 4091 /// \brief This is step for the #CounterVar used to generate its update: 4092 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4093 Expr *CounterStep = nullptr; 4094 /// \brief Should step be subtracted? 4095 bool Subtract = false; 4096 /// \brief Source range of the loop init. 4097 SourceRange InitSrcRange; 4098 /// \brief Source range of the loop condition. 4099 SourceRange CondSrcRange; 4100 /// \brief Source range of the loop increment. 4101 SourceRange IncSrcRange; 4102 }; 4103 4104 } // namespace 4105 4106 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 4107 assert(getLangOpts().OpenMP && "OpenMP is not active."); 4108 assert(Init && "Expected loop in canonical form."); 4109 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 4110 if (AssociatedLoops > 0 && 4111 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 4112 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 4113 if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) { 4114 if (auto *D = ISC.GetLoopDecl()) { 4115 auto *VD = dyn_cast<VarDecl>(D); 4116 if (!VD) { 4117 if (auto *Private = IsOpenMPCapturedDecl(D)) 4118 VD = Private; 4119 else { 4120 auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(), 4121 /*WithInit=*/false); 4122 VD = cast<VarDecl>(Ref->getDecl()); 4123 } 4124 } 4125 DSAStack->addLoopControlVariable(D, VD); 4126 } 4127 } 4128 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 4129 } 4130 } 4131 4132 /// \brief Called on a for stmt to check and extract its iteration space 4133 /// for further processing (such as collapsing). 4134 static bool CheckOpenMPIterationSpace( 4135 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 4136 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 4137 Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, 4138 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 4139 LoopIterationSpace &ResultIterSpace, 4140 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4141 // OpenMP [2.6, Canonical Loop Form] 4142 // for (init-expr; test-expr; incr-expr) structured-block 4143 auto *For = dyn_cast_or_null<ForStmt>(S); 4144 if (!For) { 4145 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for) 4146 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 4147 << getOpenMPDirectiveName(DKind) << NestedLoopCount 4148 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 4149 if (NestedLoopCount > 1) { 4150 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 4151 SemaRef.Diag(DSA.getConstructLoc(), 4152 diag::note_omp_collapse_ordered_expr) 4153 << 2 << CollapseLoopCountExpr->getSourceRange() 4154 << OrderedLoopCountExpr->getSourceRange(); 4155 else if (CollapseLoopCountExpr) 4156 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4157 diag::note_omp_collapse_ordered_expr) 4158 << 0 << CollapseLoopCountExpr->getSourceRange(); 4159 else 4160 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4161 diag::note_omp_collapse_ordered_expr) 4162 << 1 << OrderedLoopCountExpr->getSourceRange(); 4163 } 4164 return true; 4165 } 4166 assert(For->getBody()); 4167 4168 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 4169 4170 // Check init. 4171 auto Init = For->getInit(); 4172 if (ISC.CheckInit(Init)) 4173 return true; 4174 4175 bool HasErrors = false; 4176 4177 // Check loop variable's type. 4178 if (auto *LCDecl = ISC.GetLoopDecl()) { 4179 auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr(); 4180 4181 // OpenMP [2.6, Canonical Loop Form] 4182 // Var is one of the following: 4183 // A variable of signed or unsigned integer type. 4184 // For C++, a variable of a random access iterator type. 4185 // For C, a variable of a pointer type. 4186 auto VarType = LCDecl->getType().getNonReferenceType(); 4187 if (!VarType->isDependentType() && !VarType->isIntegerType() && 4188 !VarType->isPointerType() && 4189 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 4190 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type) 4191 << SemaRef.getLangOpts().CPlusPlus; 4192 HasErrors = true; 4193 } 4194 4195 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 4196 // a Construct 4197 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4198 // parallel for construct is (are) private. 4199 // The loop iteration variable in the associated for-loop of a simd 4200 // construct with just one associated for-loop is linear with a 4201 // constant-linear-step that is the increment of the associated for-loop. 4202 // Exclude loop var from the list of variables with implicitly defined data 4203 // sharing attributes. 4204 VarsWithImplicitDSA.erase(LCDecl); 4205 4206 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 4207 // in a Construct, C/C++]. 4208 // The loop iteration variable in the associated for-loop of a simd 4209 // construct with just one associated for-loop may be listed in a linear 4210 // clause with a constant-linear-step that is the increment of the 4211 // associated for-loop. 4212 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4213 // parallel for construct may be listed in a private or lastprivate clause. 4214 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 4215 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 4216 // declared in the loop and it is predetermined as a private. 4217 auto PredeterminedCKind = 4218 isOpenMPSimdDirective(DKind) 4219 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 4220 : OMPC_private; 4221 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4222 DVar.CKind != PredeterminedCKind) || 4223 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 4224 isOpenMPDistributeDirective(DKind)) && 4225 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4226 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 4227 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 4228 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa) 4229 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 4230 << getOpenMPClauseName(PredeterminedCKind); 4231 if (DVar.RefExpr == nullptr) 4232 DVar.CKind = PredeterminedCKind; 4233 ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 4234 HasErrors = true; 4235 } else if (LoopDeclRefExpr != nullptr) { 4236 // Make the loop iteration variable private (for worksharing constructs), 4237 // linear (for simd directives with the only one associated loop) or 4238 // lastprivate (for simd directives with several collapsed or ordered 4239 // loops). 4240 if (DVar.CKind == OMPC_unknown) 4241 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate, 4242 [](OpenMPDirectiveKind) -> bool { return true; }, 4243 /*FromParent=*/false); 4244 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 4245 } 4246 4247 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 4248 4249 // Check test-expr. 4250 HasErrors |= ISC.CheckCond(For->getCond()); 4251 4252 // Check incr-expr. 4253 HasErrors |= ISC.CheckInc(For->getInc()); 4254 } 4255 4256 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 4257 return HasErrors; 4258 4259 // Build the loop's iteration space representation. 4260 ResultIterSpace.PreCond = 4261 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures); 4262 ResultIterSpace.NumIterations = ISC.BuildNumIterations( 4263 DSA.getCurScope(), 4264 (isOpenMPWorksharingDirective(DKind) || 4265 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 4266 Captures); 4267 ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA); 4268 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); 4269 ResultIterSpace.CounterInit = ISC.BuildCounterInit(); 4270 ResultIterSpace.CounterStep = ISC.BuildCounterStep(); 4271 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); 4272 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange(); 4273 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange(); 4274 ResultIterSpace.Subtract = ISC.ShouldSubtractStep(); 4275 4276 HasErrors |= (ResultIterSpace.PreCond == nullptr || 4277 ResultIterSpace.NumIterations == nullptr || 4278 ResultIterSpace.CounterVar == nullptr || 4279 ResultIterSpace.PrivateCounterVar == nullptr || 4280 ResultIterSpace.CounterInit == nullptr || 4281 ResultIterSpace.CounterStep == nullptr); 4282 4283 return HasErrors; 4284 } 4285 4286 /// \brief Build 'VarRef = Start. 4287 static ExprResult 4288 BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 4289 ExprResult Start, 4290 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4291 // Build 'VarRef = Start. 4292 auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 4293 if (!NewStart.isUsable()) 4294 return ExprError(); 4295 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 4296 VarRef.get()->getType())) { 4297 NewStart = SemaRef.PerformImplicitConversion( 4298 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 4299 /*AllowExplicit=*/true); 4300 if (!NewStart.isUsable()) 4301 return ExprError(); 4302 } 4303 4304 auto Init = 4305 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4306 return Init; 4307 } 4308 4309 /// \brief Build 'VarRef = Start + Iter * Step'. 4310 static ExprResult 4311 BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, 4312 ExprResult VarRef, ExprResult Start, ExprResult Iter, 4313 ExprResult Step, bool Subtract, 4314 llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) { 4315 // Add parentheses (for debugging purposes only). 4316 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 4317 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 4318 !Step.isUsable()) 4319 return ExprError(); 4320 4321 ExprResult NewStep = Step; 4322 if (Captures) 4323 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 4324 if (NewStep.isInvalid()) 4325 return ExprError(); 4326 ExprResult Update = 4327 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 4328 if (!Update.isUsable()) 4329 return ExprError(); 4330 4331 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 4332 // 'VarRef = Start (+|-) Iter * Step'. 4333 ExprResult NewStart = Start; 4334 if (Captures) 4335 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 4336 if (NewStart.isInvalid()) 4337 return ExprError(); 4338 4339 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 4340 ExprResult SavedUpdate = Update; 4341 ExprResult UpdateVal; 4342 if (VarRef.get()->getType()->isOverloadableType() || 4343 NewStart.get()->getType()->isOverloadableType() || 4344 Update.get()->getType()->isOverloadableType()) { 4345 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4346 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4347 Update = 4348 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4349 if (Update.isUsable()) { 4350 UpdateVal = 4351 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 4352 VarRef.get(), SavedUpdate.get()); 4353 if (UpdateVal.isUsable()) { 4354 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 4355 UpdateVal.get()); 4356 } 4357 } 4358 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4359 } 4360 4361 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 4362 if (!Update.isUsable() || !UpdateVal.isUsable()) { 4363 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 4364 NewStart.get(), SavedUpdate.get()); 4365 if (!Update.isUsable()) 4366 return ExprError(); 4367 4368 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 4369 VarRef.get()->getType())) { 4370 Update = SemaRef.PerformImplicitConversion( 4371 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 4372 if (!Update.isUsable()) 4373 return ExprError(); 4374 } 4375 4376 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 4377 } 4378 return Update; 4379 } 4380 4381 /// \brief Convert integer expression \a E to make it have at least \a Bits 4382 /// bits. 4383 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 4384 if (E == nullptr) 4385 return ExprError(); 4386 auto &C = SemaRef.Context; 4387 QualType OldType = E->getType(); 4388 unsigned HasBits = C.getTypeSize(OldType); 4389 if (HasBits >= Bits) 4390 return ExprResult(E); 4391 // OK to convert to signed, because new type has more bits than old. 4392 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 4393 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 4394 true); 4395 } 4396 4397 /// \brief Check if the given expression \a E is a constant integer that fits 4398 /// into \a Bits bits. 4399 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { 4400 if (E == nullptr) 4401 return false; 4402 llvm::APSInt Result; 4403 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 4404 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 4405 return false; 4406 } 4407 4408 /// Build preinits statement for the given declarations. 4409 static Stmt *buildPreInits(ASTContext &Context, 4410 MutableArrayRef<Decl *> PreInits) { 4411 if (!PreInits.empty()) { 4412 return new (Context) DeclStmt( 4413 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 4414 SourceLocation(), SourceLocation()); 4415 } 4416 return nullptr; 4417 } 4418 4419 /// Build preinits statement for the given declarations. 4420 static Stmt * 4421 buildPreInits(ASTContext &Context, 4422 const llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4423 if (!Captures.empty()) { 4424 SmallVector<Decl *, 16> PreInits; 4425 for (auto &Pair : Captures) 4426 PreInits.push_back(Pair.second->getDecl()); 4427 return buildPreInits(Context, PreInits); 4428 } 4429 return nullptr; 4430 } 4431 4432 /// Build postupdate expression for the given list of postupdates expressions. 4433 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 4434 Expr *PostUpdate = nullptr; 4435 if (!PostUpdates.empty()) { 4436 for (auto *E : PostUpdates) { 4437 Expr *ConvE = S.BuildCStyleCastExpr( 4438 E->getExprLoc(), 4439 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 4440 E->getExprLoc(), E) 4441 .get(); 4442 PostUpdate = PostUpdate 4443 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 4444 PostUpdate, ConvE) 4445 .get() 4446 : ConvE; 4447 } 4448 } 4449 return PostUpdate; 4450 } 4451 4452 /// \brief Called on a for stmt to check itself and nested loops (if any). 4453 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 4454 /// number of collapsed loops otherwise. 4455 static unsigned 4456 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 4457 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 4458 DSAStackTy &DSA, 4459 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 4460 OMPLoopDirective::HelperExprs &Built) { 4461 unsigned NestedLoopCount = 1; 4462 if (CollapseLoopCountExpr) { 4463 // Found 'collapse' clause - calculate collapse number. 4464 llvm::APSInt Result; 4465 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 4466 NestedLoopCount = Result.getLimitedValue(); 4467 } 4468 if (OrderedLoopCountExpr) { 4469 // Found 'ordered' clause - calculate collapse number. 4470 llvm::APSInt Result; 4471 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 4472 if (Result.getLimitedValue() < NestedLoopCount) { 4473 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4474 diag::err_omp_wrong_ordered_loop_count) 4475 << OrderedLoopCountExpr->getSourceRange(); 4476 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4477 diag::note_collapse_loop_count) 4478 << CollapseLoopCountExpr->getSourceRange(); 4479 } 4480 NestedLoopCount = Result.getLimitedValue(); 4481 } 4482 } 4483 // This is helper routine for loop directives (e.g., 'for', 'simd', 4484 // 'for simd', etc.). 4485 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 4486 SmallVector<LoopIterationSpace, 4> IterSpaces; 4487 IterSpaces.resize(NestedLoopCount); 4488 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 4489 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 4490 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, 4491 NestedLoopCount, CollapseLoopCountExpr, 4492 OrderedLoopCountExpr, VarsWithImplicitDSA, 4493 IterSpaces[Cnt], Captures)) 4494 return 0; 4495 // Move on to the next nested for loop, or to the loop body. 4496 // OpenMP [2.8.1, simd construct, Restrictions] 4497 // All loops associated with the construct must be perfectly nested; that 4498 // is, there must be no intervening code nor any OpenMP directive between 4499 // any two loops. 4500 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 4501 } 4502 4503 Built.clear(/* size */ NestedLoopCount); 4504 4505 if (SemaRef.CurContext->isDependentContext()) 4506 return NestedLoopCount; 4507 4508 // An example of what is generated for the following code: 4509 // 4510 // #pragma omp simd collapse(2) ordered(2) 4511 // for (i = 0; i < NI; ++i) 4512 // for (k = 0; k < NK; ++k) 4513 // for (j = J0; j < NJ; j+=2) { 4514 // <loop body> 4515 // } 4516 // 4517 // We generate the code below. 4518 // Note: the loop body may be outlined in CodeGen. 4519 // Note: some counters may be C++ classes, operator- is used to find number of 4520 // iterations and operator+= to calculate counter value. 4521 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 4522 // or i64 is currently supported). 4523 // 4524 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 4525 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 4526 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 4527 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 4528 // // similar updates for vars in clauses (e.g. 'linear') 4529 // <loop body (using local i and j)> 4530 // } 4531 // i = NI; // assign final values of counters 4532 // j = NJ; 4533 // 4534 4535 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 4536 // the iteration counts of the collapsed for loops. 4537 // Precondition tests if there is at least one iteration (all conditions are 4538 // true). 4539 auto PreCond = ExprResult(IterSpaces[0].PreCond); 4540 auto N0 = IterSpaces[0].NumIterations; 4541 ExprResult LastIteration32 = WidenIterationCount( 4542 32 /* Bits */, SemaRef 4543 .PerformImplicitConversion( 4544 N0->IgnoreImpCasts(), N0->getType(), 4545 Sema::AA_Converting, /*AllowExplicit=*/true) 4546 .get(), 4547 SemaRef); 4548 ExprResult LastIteration64 = WidenIterationCount( 4549 64 /* Bits */, SemaRef 4550 .PerformImplicitConversion( 4551 N0->IgnoreImpCasts(), N0->getType(), 4552 Sema::AA_Converting, /*AllowExplicit=*/true) 4553 .get(), 4554 SemaRef); 4555 4556 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 4557 return NestedLoopCount; 4558 4559 auto &C = SemaRef.Context; 4560 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 4561 4562 Scope *CurScope = DSA.getCurScope(); 4563 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 4564 if (PreCond.isUsable()) { 4565 PreCond = 4566 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 4567 PreCond.get(), IterSpaces[Cnt].PreCond); 4568 } 4569 auto N = IterSpaces[Cnt].NumIterations; 4570 SourceLocation Loc = N->getExprLoc(); 4571 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 4572 if (LastIteration32.isUsable()) 4573 LastIteration32 = SemaRef.BuildBinOp( 4574 CurScope, Loc, BO_Mul, LastIteration32.get(), 4575 SemaRef 4576 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4577 Sema::AA_Converting, 4578 /*AllowExplicit=*/true) 4579 .get()); 4580 if (LastIteration64.isUsable()) 4581 LastIteration64 = SemaRef.BuildBinOp( 4582 CurScope, Loc, BO_Mul, LastIteration64.get(), 4583 SemaRef 4584 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4585 Sema::AA_Converting, 4586 /*AllowExplicit=*/true) 4587 .get()); 4588 } 4589 4590 // Choose either the 32-bit or 64-bit version. 4591 ExprResult LastIteration = LastIteration64; 4592 if (LastIteration32.isUsable() && 4593 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 4594 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 4595 FitsInto( 4596 32 /* Bits */, 4597 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 4598 LastIteration64.get(), SemaRef))) 4599 LastIteration = LastIteration32; 4600 QualType VType = LastIteration.get()->getType(); 4601 QualType RealVType = VType; 4602 QualType StrideVType = VType; 4603 if (isOpenMPTaskLoopDirective(DKind)) { 4604 VType = 4605 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 4606 StrideVType = 4607 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 4608 } 4609 4610 if (!LastIteration.isUsable()) 4611 return 0; 4612 4613 // Save the number of iterations. 4614 ExprResult NumIterations = LastIteration; 4615 { 4616 LastIteration = SemaRef.BuildBinOp( 4617 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 4618 LastIteration.get(), 4619 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4620 if (!LastIteration.isUsable()) 4621 return 0; 4622 } 4623 4624 // Calculate the last iteration number beforehand instead of doing this on 4625 // each iteration. Do not do this if the number of iterations may be kfold-ed. 4626 llvm::APSInt Result; 4627 bool IsConstant = 4628 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 4629 ExprResult CalcLastIteration; 4630 if (!IsConstant) { 4631 ExprResult SaveRef = 4632 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 4633 LastIteration = SaveRef; 4634 4635 // Prepare SaveRef + 1. 4636 NumIterations = SemaRef.BuildBinOp( 4637 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 4638 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4639 if (!NumIterations.isUsable()) 4640 return 0; 4641 } 4642 4643 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 4644 4645 // Build variables passed into runtime, necessary for worksharing directives. 4646 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 4647 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4648 isOpenMPDistributeDirective(DKind)) { 4649 // Lower bound variable, initialized with zero. 4650 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 4651 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 4652 SemaRef.AddInitializerToDecl(LBDecl, 4653 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4654 /*DirectInit*/ false); 4655 4656 // Upper bound variable, initialized with last iteration number. 4657 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 4658 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 4659 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 4660 /*DirectInit*/ false); 4661 4662 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 4663 // This will be used to implement clause 'lastprivate'. 4664 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 4665 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 4666 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 4667 SemaRef.AddInitializerToDecl(ILDecl, 4668 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4669 /*DirectInit*/ false); 4670 4671 // Stride variable returned by runtime (we initialize it to 1 by default). 4672 VarDecl *STDecl = 4673 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 4674 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 4675 SemaRef.AddInitializerToDecl(STDecl, 4676 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 4677 /*DirectInit*/ false); 4678 4679 // Build expression: UB = min(UB, LastIteration) 4680 // It is necessary for CodeGen of directives with static scheduling. 4681 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 4682 UB.get(), LastIteration.get()); 4683 ExprResult CondOp = SemaRef.ActOnConditionalOp( 4684 InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get()); 4685 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 4686 CondOp.get()); 4687 EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); 4688 4689 // If we have a combined directive that combines 'distribute', 'for' or 4690 // 'simd' we need to be able to access the bounds of the schedule of the 4691 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 4692 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 4693 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4694 4695 // Lower bound variable, initialized with zero. 4696 VarDecl *CombLBDecl = 4697 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 4698 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 4699 SemaRef.AddInitializerToDecl( 4700 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4701 /*DirectInit*/ false); 4702 4703 // Upper bound variable, initialized with last iteration number. 4704 VarDecl *CombUBDecl = 4705 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 4706 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 4707 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 4708 /*DirectInit*/ false); 4709 4710 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 4711 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 4712 ExprResult CombCondOp = 4713 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 4714 LastIteration.get(), CombUB.get()); 4715 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 4716 CombCondOp.get()); 4717 CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get()); 4718 4719 auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 4720 // We expect to have at least 2 more parameters than the 'parallel' 4721 // directive does - the lower and upper bounds of the previous schedule. 4722 assert(CD->getNumParams() >= 4 && 4723 "Unexpected number of parameters in loop combined directive"); 4724 4725 // Set the proper type for the bounds given what we learned from the 4726 // enclosed loops. 4727 auto *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 4728 auto *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 4729 4730 // Previous lower and upper bounds are obtained from the region 4731 // parameters. 4732 PrevLB = 4733 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 4734 PrevUB = 4735 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 4736 } 4737 } 4738 4739 // Build the iteration variable and its initialization before loop. 4740 ExprResult IV; 4741 ExprResult Init, CombInit; 4742 { 4743 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 4744 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 4745 Expr *RHS = 4746 (isOpenMPWorksharingDirective(DKind) || 4747 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 4748 ? LB.get() 4749 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 4750 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 4751 Init = SemaRef.ActOnFinishFullExpr(Init.get()); 4752 4753 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4754 Expr *CombRHS = 4755 (isOpenMPWorksharingDirective(DKind) || 4756 isOpenMPTaskLoopDirective(DKind) || 4757 isOpenMPDistributeDirective(DKind)) 4758 ? CombLB.get() 4759 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 4760 CombInit = 4761 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 4762 CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get()); 4763 } 4764 } 4765 4766 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. 4767 SourceLocation CondLoc; 4768 ExprResult Cond = 4769 (isOpenMPWorksharingDirective(DKind) || 4770 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 4771 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) 4772 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 4773 NumIterations.get()); 4774 ExprResult CombCond; 4775 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4776 CombCond = 4777 SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get()); 4778 } 4779 // Loop increment (IV = IV + 1) 4780 SourceLocation IncLoc; 4781 ExprResult Inc = 4782 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 4783 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 4784 if (!Inc.isUsable()) 4785 return 0; 4786 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 4787 Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); 4788 if (!Inc.isUsable()) 4789 return 0; 4790 4791 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 4792 // Used for directives with static scheduling. 4793 // In combined construct, add combined version that use CombLB and CombUB 4794 // base variables for the update 4795 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 4796 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4797 isOpenMPDistributeDirective(DKind)) { 4798 // LB + ST 4799 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 4800 if (!NextLB.isUsable()) 4801 return 0; 4802 // LB = LB + ST 4803 NextLB = 4804 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 4805 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); 4806 if (!NextLB.isUsable()) 4807 return 0; 4808 // UB + ST 4809 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 4810 if (!NextUB.isUsable()) 4811 return 0; 4812 // UB = UB + ST 4813 NextUB = 4814 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 4815 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); 4816 if (!NextUB.isUsable()) 4817 return 0; 4818 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4819 CombNextLB = 4820 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 4821 if (!NextLB.isUsable()) 4822 return 0; 4823 // LB = LB + ST 4824 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 4825 CombNextLB.get()); 4826 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get()); 4827 if (!CombNextLB.isUsable()) 4828 return 0; 4829 // UB + ST 4830 CombNextUB = 4831 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 4832 if (!CombNextUB.isUsable()) 4833 return 0; 4834 // UB = UB + ST 4835 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 4836 CombNextUB.get()); 4837 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get()); 4838 if (!CombNextUB.isUsable()) 4839 return 0; 4840 } 4841 } 4842 4843 // Create increment expression for distribute loop when combined in a same 4844 // directive with for as IV = IV + ST; ensure upper bound expression based 4845 // on PrevUB instead of NumIterations - used to implement 'for' when found 4846 // in combination with 'distribute', like in 'distribute parallel for' 4847 SourceLocation DistIncLoc; 4848 ExprResult DistCond, DistInc, PrevEUB; 4849 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4850 DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()); 4851 assert(DistCond.isUsable() && "distribute cond expr was not built"); 4852 4853 DistInc = 4854 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 4855 assert(DistInc.isUsable() && "distribute inc expr was not built"); 4856 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 4857 DistInc.get()); 4858 DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get()); 4859 assert(DistInc.isUsable() && "distribute inc expr was not built"); 4860 4861 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 4862 // construct 4863 SourceLocation DistEUBLoc; 4864 ExprResult IsUBGreater = 4865 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 4866 ExprResult CondOp = SemaRef.ActOnConditionalOp( 4867 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 4868 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 4869 CondOp.get()); 4870 PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get()); 4871 } 4872 4873 // Build updates and final values of the loop counters. 4874 bool HasErrors = false; 4875 Built.Counters.resize(NestedLoopCount); 4876 Built.Inits.resize(NestedLoopCount); 4877 Built.Updates.resize(NestedLoopCount); 4878 Built.Finals.resize(NestedLoopCount); 4879 SmallVector<Expr *, 4> LoopMultipliers; 4880 { 4881 ExprResult Div; 4882 // Go from inner nested loop to outer. 4883 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 4884 LoopIterationSpace &IS = IterSpaces[Cnt]; 4885 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 4886 // Build: Iter = (IV / Div) % IS.NumIters 4887 // where Div is product of previous iterations' IS.NumIters. 4888 ExprResult Iter; 4889 if (Div.isUsable()) { 4890 Iter = 4891 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); 4892 } else { 4893 Iter = IV; 4894 assert((Cnt == (int)NestedLoopCount - 1) && 4895 "unusable div expected on first iteration only"); 4896 } 4897 4898 if (Cnt != 0 && Iter.isUsable()) 4899 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), 4900 IS.NumIterations); 4901 if (!Iter.isUsable()) { 4902 HasErrors = true; 4903 break; 4904 } 4905 4906 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 4907 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 4908 auto *CounterVar = buildDeclRefExpr(SemaRef, VD, IS.CounterVar->getType(), 4909 IS.CounterVar->getExprLoc(), 4910 /*RefersToCapture=*/true); 4911 ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 4912 IS.CounterInit, Captures); 4913 if (!Init.isUsable()) { 4914 HasErrors = true; 4915 break; 4916 } 4917 ExprResult Update = BuildCounterUpdate( 4918 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 4919 IS.CounterStep, IS.Subtract, &Captures); 4920 if (!Update.isUsable()) { 4921 HasErrors = true; 4922 break; 4923 } 4924 4925 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 4926 ExprResult Final = BuildCounterUpdate( 4927 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 4928 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 4929 if (!Final.isUsable()) { 4930 HasErrors = true; 4931 break; 4932 } 4933 4934 // Build Div for the next iteration: Div <- Div * IS.NumIters 4935 if (Cnt != 0) { 4936 if (Div.isUnset()) 4937 Div = IS.NumIterations; 4938 else 4939 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), 4940 IS.NumIterations); 4941 4942 // Add parentheses (for debugging purposes only). 4943 if (Div.isUsable()) 4944 Div = tryBuildCapture(SemaRef, Div.get(), Captures); 4945 if (!Div.isUsable()) { 4946 HasErrors = true; 4947 break; 4948 } 4949 LoopMultipliers.push_back(Div.get()); 4950 } 4951 if (!Update.isUsable() || !Final.isUsable()) { 4952 HasErrors = true; 4953 break; 4954 } 4955 // Save results 4956 Built.Counters[Cnt] = IS.CounterVar; 4957 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 4958 Built.Inits[Cnt] = Init.get(); 4959 Built.Updates[Cnt] = Update.get(); 4960 Built.Finals[Cnt] = Final.get(); 4961 } 4962 } 4963 4964 if (HasErrors) 4965 return 0; 4966 4967 // Save results 4968 Built.IterationVarRef = IV.get(); 4969 Built.LastIteration = LastIteration.get(); 4970 Built.NumIterations = NumIterations.get(); 4971 Built.CalcLastIteration = 4972 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); 4973 Built.PreCond = PreCond.get(); 4974 Built.PreInits = buildPreInits(C, Captures); 4975 Built.Cond = Cond.get(); 4976 Built.Init = Init.get(); 4977 Built.Inc = Inc.get(); 4978 Built.LB = LB.get(); 4979 Built.UB = UB.get(); 4980 Built.IL = IL.get(); 4981 Built.ST = ST.get(); 4982 Built.EUB = EUB.get(); 4983 Built.NLB = NextLB.get(); 4984 Built.NUB = NextUB.get(); 4985 Built.PrevLB = PrevLB.get(); 4986 Built.PrevUB = PrevUB.get(); 4987 Built.DistInc = DistInc.get(); 4988 Built.PrevEUB = PrevEUB.get(); 4989 Built.DistCombinedFields.LB = CombLB.get(); 4990 Built.DistCombinedFields.UB = CombUB.get(); 4991 Built.DistCombinedFields.EUB = CombEUB.get(); 4992 Built.DistCombinedFields.Init = CombInit.get(); 4993 Built.DistCombinedFields.Cond = CombCond.get(); 4994 Built.DistCombinedFields.NLB = CombNextLB.get(); 4995 Built.DistCombinedFields.NUB = CombNextUB.get(); 4996 4997 Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get(); 4998 // Fill data for doacross depend clauses. 4999 for (auto Pair : DSA.getDoacrossDependClauses()) { 5000 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 5001 Pair.first->setCounterValue(CounterVal); 5002 else { 5003 if (NestedLoopCount != Pair.second.size() || 5004 NestedLoopCount != LoopMultipliers.size() + 1) { 5005 // Erroneous case - clause has some problems. 5006 Pair.first->setCounterValue(CounterVal); 5007 continue; 5008 } 5009 assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink); 5010 auto I = Pair.second.rbegin(); 5011 auto IS = IterSpaces.rbegin(); 5012 auto ILM = LoopMultipliers.rbegin(); 5013 Expr *UpCounterVal = CounterVal; 5014 Expr *Multiplier = nullptr; 5015 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 5016 if (I->first) { 5017 assert(IS->CounterStep); 5018 Expr *NormalizedOffset = 5019 SemaRef 5020 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div, 5021 I->first, IS->CounterStep) 5022 .get(); 5023 if (Multiplier) { 5024 NormalizedOffset = 5025 SemaRef 5026 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul, 5027 NormalizedOffset, Multiplier) 5028 .get(); 5029 } 5030 assert(I->second == OO_Plus || I->second == OO_Minus); 5031 BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : BO_Sub; 5032 UpCounterVal = SemaRef 5033 .BuildBinOp(CurScope, I->first->getExprLoc(), BOK, 5034 UpCounterVal, NormalizedOffset) 5035 .get(); 5036 } 5037 Multiplier = *ILM; 5038 ++I; 5039 ++IS; 5040 ++ILM; 5041 } 5042 Pair.first->setCounterValue(UpCounterVal); 5043 } 5044 } 5045 5046 return NestedLoopCount; 5047 } 5048 5049 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 5050 auto CollapseClauses = 5051 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 5052 if (CollapseClauses.begin() != CollapseClauses.end()) 5053 return (*CollapseClauses.begin())->getNumForLoops(); 5054 return nullptr; 5055 } 5056 5057 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 5058 auto OrderedClauses = 5059 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 5060 if (OrderedClauses.begin() != OrderedClauses.end()) 5061 return (*OrderedClauses.begin())->getNumForLoops(); 5062 return nullptr; 5063 } 5064 5065 static bool checkSimdlenSafelenSpecified(Sema &S, 5066 const ArrayRef<OMPClause *> Clauses) { 5067 OMPSafelenClause *Safelen = nullptr; 5068 OMPSimdlenClause *Simdlen = nullptr; 5069 5070 for (auto *Clause : Clauses) { 5071 if (Clause->getClauseKind() == OMPC_safelen) 5072 Safelen = cast<OMPSafelenClause>(Clause); 5073 else if (Clause->getClauseKind() == OMPC_simdlen) 5074 Simdlen = cast<OMPSimdlenClause>(Clause); 5075 if (Safelen && Simdlen) 5076 break; 5077 } 5078 5079 if (Simdlen && Safelen) { 5080 llvm::APSInt SimdlenRes, SafelenRes; 5081 auto SimdlenLength = Simdlen->getSimdlen(); 5082 auto SafelenLength = Safelen->getSafelen(); 5083 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 5084 SimdlenLength->isInstantiationDependent() || 5085 SimdlenLength->containsUnexpandedParameterPack()) 5086 return false; 5087 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 5088 SafelenLength->isInstantiationDependent() || 5089 SafelenLength->containsUnexpandedParameterPack()) 5090 return false; 5091 SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context); 5092 SafelenLength->EvaluateAsInt(SafelenRes, S.Context); 5093 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 5094 // If both simdlen and safelen clauses are specified, the value of the 5095 // simdlen parameter must be less than or equal to the value of the safelen 5096 // parameter. 5097 if (SimdlenRes > SafelenRes) { 5098 S.Diag(SimdlenLength->getExprLoc(), 5099 diag::err_omp_wrong_simdlen_safelen_values) 5100 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 5101 return true; 5102 } 5103 } 5104 return false; 5105 } 5106 5107 StmtResult Sema::ActOnOpenMPSimdDirective( 5108 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5109 SourceLocation EndLoc, 5110 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5111 if (!AStmt) 5112 return StmtError(); 5113 5114 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5115 OMPLoopDirective::HelperExprs B; 5116 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5117 // define the nested loops number. 5118 unsigned NestedLoopCount = CheckOpenMPLoop( 5119 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5120 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5121 if (NestedLoopCount == 0) 5122 return StmtError(); 5123 5124 assert((CurContext->isDependentContext() || B.builtAll()) && 5125 "omp simd loop exprs were not built"); 5126 5127 if (!CurContext->isDependentContext()) { 5128 // Finalize the clauses that need pre-built expressions for CodeGen. 5129 for (auto C : Clauses) { 5130 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5131 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5132 B.NumIterations, *this, CurScope, 5133 DSAStack)) 5134 return StmtError(); 5135 } 5136 } 5137 5138 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5139 return StmtError(); 5140 5141 getCurFunction()->setHasBranchProtectedScope(); 5142 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5143 Clauses, AStmt, B); 5144 } 5145 5146 StmtResult Sema::ActOnOpenMPForDirective( 5147 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5148 SourceLocation EndLoc, 5149 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5150 if (!AStmt) 5151 return StmtError(); 5152 5153 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5154 OMPLoopDirective::HelperExprs B; 5155 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5156 // define the nested loops number. 5157 unsigned NestedLoopCount = CheckOpenMPLoop( 5158 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5159 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5160 if (NestedLoopCount == 0) 5161 return StmtError(); 5162 5163 assert((CurContext->isDependentContext() || B.builtAll()) && 5164 "omp for loop exprs were not built"); 5165 5166 if (!CurContext->isDependentContext()) { 5167 // Finalize the clauses that need pre-built expressions for CodeGen. 5168 for (auto C : Clauses) { 5169 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5170 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5171 B.NumIterations, *this, CurScope, 5172 DSAStack)) 5173 return StmtError(); 5174 } 5175 } 5176 5177 getCurFunction()->setHasBranchProtectedScope(); 5178 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5179 Clauses, AStmt, B, DSAStack->isCancelRegion()); 5180 } 5181 5182 StmtResult Sema::ActOnOpenMPForSimdDirective( 5183 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5184 SourceLocation EndLoc, 5185 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5186 if (!AStmt) 5187 return StmtError(); 5188 5189 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5190 OMPLoopDirective::HelperExprs B; 5191 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5192 // define the nested loops number. 5193 unsigned NestedLoopCount = 5194 CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 5195 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5196 VarsWithImplicitDSA, B); 5197 if (NestedLoopCount == 0) 5198 return StmtError(); 5199 5200 assert((CurContext->isDependentContext() || B.builtAll()) && 5201 "omp for simd loop exprs were not built"); 5202 5203 if (!CurContext->isDependentContext()) { 5204 // Finalize the clauses that need pre-built expressions for CodeGen. 5205 for (auto C : Clauses) { 5206 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5207 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5208 B.NumIterations, *this, CurScope, 5209 DSAStack)) 5210 return StmtError(); 5211 } 5212 } 5213 5214 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5215 return StmtError(); 5216 5217 getCurFunction()->setHasBranchProtectedScope(); 5218 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5219 Clauses, AStmt, B); 5220 } 5221 5222 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 5223 Stmt *AStmt, 5224 SourceLocation StartLoc, 5225 SourceLocation EndLoc) { 5226 if (!AStmt) 5227 return StmtError(); 5228 5229 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5230 auto BaseStmt = AStmt; 5231 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5232 BaseStmt = CS->getCapturedStmt(); 5233 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5234 auto S = C->children(); 5235 if (S.begin() == S.end()) 5236 return StmtError(); 5237 // All associated statements must be '#pragma omp section' except for 5238 // the first one. 5239 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5240 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5241 if (SectionStmt) 5242 Diag(SectionStmt->getLocStart(), 5243 diag::err_omp_sections_substmt_not_section); 5244 return StmtError(); 5245 } 5246 cast<OMPSectionDirective>(SectionStmt) 5247 ->setHasCancel(DSAStack->isCancelRegion()); 5248 } 5249 } else { 5250 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt); 5251 return StmtError(); 5252 } 5253 5254 getCurFunction()->setHasBranchProtectedScope(); 5255 5256 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5257 DSAStack->isCancelRegion()); 5258 } 5259 5260 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 5261 SourceLocation StartLoc, 5262 SourceLocation EndLoc) { 5263 if (!AStmt) 5264 return StmtError(); 5265 5266 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5267 5268 getCurFunction()->setHasBranchProtectedScope(); 5269 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 5270 5271 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 5272 DSAStack->isCancelRegion()); 5273 } 5274 5275 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 5276 Stmt *AStmt, 5277 SourceLocation StartLoc, 5278 SourceLocation EndLoc) { 5279 if (!AStmt) 5280 return StmtError(); 5281 5282 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5283 5284 getCurFunction()->setHasBranchProtectedScope(); 5285 5286 // OpenMP [2.7.3, single Construct, Restrictions] 5287 // The copyprivate clause must not be used with the nowait clause. 5288 OMPClause *Nowait = nullptr; 5289 OMPClause *Copyprivate = nullptr; 5290 for (auto *Clause : Clauses) { 5291 if (Clause->getClauseKind() == OMPC_nowait) 5292 Nowait = Clause; 5293 else if (Clause->getClauseKind() == OMPC_copyprivate) 5294 Copyprivate = Clause; 5295 if (Copyprivate && Nowait) { 5296 Diag(Copyprivate->getLocStart(), 5297 diag::err_omp_single_copyprivate_with_nowait); 5298 Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here); 5299 return StmtError(); 5300 } 5301 } 5302 5303 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5304 } 5305 5306 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 5307 SourceLocation StartLoc, 5308 SourceLocation EndLoc) { 5309 if (!AStmt) 5310 return StmtError(); 5311 5312 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5313 5314 getCurFunction()->setHasBranchProtectedScope(); 5315 5316 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 5317 } 5318 5319 StmtResult Sema::ActOnOpenMPCriticalDirective( 5320 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 5321 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5322 if (!AStmt) 5323 return StmtError(); 5324 5325 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5326 5327 bool ErrorFound = false; 5328 llvm::APSInt Hint; 5329 SourceLocation HintLoc; 5330 bool DependentHint = false; 5331 for (auto *C : Clauses) { 5332 if (C->getClauseKind() == OMPC_hint) { 5333 if (!DirName.getName()) { 5334 Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name); 5335 ErrorFound = true; 5336 } 5337 Expr *E = cast<OMPHintClause>(C)->getHint(); 5338 if (E->isTypeDependent() || E->isValueDependent() || 5339 E->isInstantiationDependent()) 5340 DependentHint = true; 5341 else { 5342 Hint = E->EvaluateKnownConstInt(Context); 5343 HintLoc = C->getLocStart(); 5344 } 5345 } 5346 } 5347 if (ErrorFound) 5348 return StmtError(); 5349 auto Pair = DSAStack->getCriticalWithHint(DirName); 5350 if (Pair.first && DirName.getName() && !DependentHint) { 5351 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 5352 Diag(StartLoc, diag::err_omp_critical_with_hint); 5353 if (HintLoc.isValid()) { 5354 Diag(HintLoc, diag::note_omp_critical_hint_here) 5355 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 5356 } else 5357 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 5358 if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 5359 Diag(C->getLocStart(), diag::note_omp_critical_hint_here) 5360 << 1 5361 << C->getHint()->EvaluateKnownConstInt(Context).toString( 5362 /*Radix=*/10, /*Signed=*/false); 5363 } else 5364 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1; 5365 } 5366 } 5367 5368 getCurFunction()->setHasBranchProtectedScope(); 5369 5370 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 5371 Clauses, AStmt); 5372 if (!Pair.first && DirName.getName() && !DependentHint) 5373 DSAStack->addCriticalWithHint(Dir, Hint); 5374 return Dir; 5375 } 5376 5377 StmtResult Sema::ActOnOpenMPParallelForDirective( 5378 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5379 SourceLocation EndLoc, 5380 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5381 if (!AStmt) 5382 return StmtError(); 5383 5384 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5385 // 1.2.2 OpenMP Language Terminology 5386 // Structured block - An executable statement with a single entry at the 5387 // top and a single exit at the bottom. 5388 // The point of exit cannot be a branch out of the structured block. 5389 // longjmp() and throw() must not violate the entry/exit criteria. 5390 CS->getCapturedDecl()->setNothrow(); 5391 5392 OMPLoopDirective::HelperExprs B; 5393 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5394 // define the nested loops number. 5395 unsigned NestedLoopCount = 5396 CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 5397 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5398 VarsWithImplicitDSA, B); 5399 if (NestedLoopCount == 0) 5400 return StmtError(); 5401 5402 assert((CurContext->isDependentContext() || B.builtAll()) && 5403 "omp parallel for loop exprs were not built"); 5404 5405 if (!CurContext->isDependentContext()) { 5406 // Finalize the clauses that need pre-built expressions for CodeGen. 5407 for (auto C : Clauses) { 5408 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5409 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5410 B.NumIterations, *this, CurScope, 5411 DSAStack)) 5412 return StmtError(); 5413 } 5414 } 5415 5416 getCurFunction()->setHasBranchProtectedScope(); 5417 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 5418 NestedLoopCount, Clauses, AStmt, B, 5419 DSAStack->isCancelRegion()); 5420 } 5421 5422 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 5423 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5424 SourceLocation EndLoc, 5425 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5426 if (!AStmt) 5427 return StmtError(); 5428 5429 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5430 // 1.2.2 OpenMP Language Terminology 5431 // Structured block - An executable statement with a single entry at the 5432 // top and a single exit at the bottom. 5433 // The point of exit cannot be a branch out of the structured block. 5434 // longjmp() and throw() must not violate the entry/exit criteria. 5435 CS->getCapturedDecl()->setNothrow(); 5436 5437 OMPLoopDirective::HelperExprs B; 5438 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5439 // define the nested loops number. 5440 unsigned NestedLoopCount = 5441 CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 5442 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5443 VarsWithImplicitDSA, B); 5444 if (NestedLoopCount == 0) 5445 return StmtError(); 5446 5447 if (!CurContext->isDependentContext()) { 5448 // Finalize the clauses that need pre-built expressions for CodeGen. 5449 for (auto C : Clauses) { 5450 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5451 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5452 B.NumIterations, *this, CurScope, 5453 DSAStack)) 5454 return StmtError(); 5455 } 5456 } 5457 5458 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5459 return StmtError(); 5460 5461 getCurFunction()->setHasBranchProtectedScope(); 5462 return OMPParallelForSimdDirective::Create( 5463 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 5464 } 5465 5466 StmtResult 5467 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 5468 Stmt *AStmt, SourceLocation StartLoc, 5469 SourceLocation EndLoc) { 5470 if (!AStmt) 5471 return StmtError(); 5472 5473 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5474 auto BaseStmt = AStmt; 5475 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5476 BaseStmt = CS->getCapturedStmt(); 5477 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5478 auto S = C->children(); 5479 if (S.begin() == S.end()) 5480 return StmtError(); 5481 // All associated statements must be '#pragma omp section' except for 5482 // the first one. 5483 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5484 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5485 if (SectionStmt) 5486 Diag(SectionStmt->getLocStart(), 5487 diag::err_omp_parallel_sections_substmt_not_section); 5488 return StmtError(); 5489 } 5490 cast<OMPSectionDirective>(SectionStmt) 5491 ->setHasCancel(DSAStack->isCancelRegion()); 5492 } 5493 } else { 5494 Diag(AStmt->getLocStart(), 5495 diag::err_omp_parallel_sections_not_compound_stmt); 5496 return StmtError(); 5497 } 5498 5499 getCurFunction()->setHasBranchProtectedScope(); 5500 5501 return OMPParallelSectionsDirective::Create( 5502 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 5503 } 5504 5505 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 5506 Stmt *AStmt, SourceLocation StartLoc, 5507 SourceLocation EndLoc) { 5508 if (!AStmt) 5509 return StmtError(); 5510 5511 auto *CS = cast<CapturedStmt>(AStmt); 5512 // 1.2.2 OpenMP Language Terminology 5513 // Structured block - An executable statement with a single entry at the 5514 // top and a single exit at the bottom. 5515 // The point of exit cannot be a branch out of the structured block. 5516 // longjmp() and throw() must not violate the entry/exit criteria. 5517 CS->getCapturedDecl()->setNothrow(); 5518 5519 getCurFunction()->setHasBranchProtectedScope(); 5520 5521 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5522 DSAStack->isCancelRegion()); 5523 } 5524 5525 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 5526 SourceLocation EndLoc) { 5527 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 5528 } 5529 5530 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 5531 SourceLocation EndLoc) { 5532 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 5533 } 5534 5535 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 5536 SourceLocation EndLoc) { 5537 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 5538 } 5539 5540 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 5541 Stmt *AStmt, 5542 SourceLocation StartLoc, 5543 SourceLocation EndLoc) { 5544 if (!AStmt) 5545 return StmtError(); 5546 5547 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5548 5549 getCurFunction()->setHasBranchProtectedScope(); 5550 5551 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 5552 AStmt, 5553 DSAStack->getTaskgroupReductionRef()); 5554 } 5555 5556 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 5557 SourceLocation StartLoc, 5558 SourceLocation EndLoc) { 5559 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 5560 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 5561 } 5562 5563 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 5564 Stmt *AStmt, 5565 SourceLocation StartLoc, 5566 SourceLocation EndLoc) { 5567 OMPClause *DependFound = nullptr; 5568 OMPClause *DependSourceClause = nullptr; 5569 OMPClause *DependSinkClause = nullptr; 5570 bool ErrorFound = false; 5571 OMPThreadsClause *TC = nullptr; 5572 OMPSIMDClause *SC = nullptr; 5573 for (auto *C : Clauses) { 5574 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 5575 DependFound = C; 5576 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 5577 if (DependSourceClause) { 5578 Diag(C->getLocStart(), diag::err_omp_more_one_clause) 5579 << getOpenMPDirectiveName(OMPD_ordered) 5580 << getOpenMPClauseName(OMPC_depend) << 2; 5581 ErrorFound = true; 5582 } else 5583 DependSourceClause = C; 5584 if (DependSinkClause) { 5585 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5586 << 0; 5587 ErrorFound = true; 5588 } 5589 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 5590 if (DependSourceClause) { 5591 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5592 << 1; 5593 ErrorFound = true; 5594 } 5595 DependSinkClause = C; 5596 } 5597 } else if (C->getClauseKind() == OMPC_threads) 5598 TC = cast<OMPThreadsClause>(C); 5599 else if (C->getClauseKind() == OMPC_simd) 5600 SC = cast<OMPSIMDClause>(C); 5601 } 5602 if (!ErrorFound && !SC && 5603 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 5604 // OpenMP [2.8.1,simd Construct, Restrictions] 5605 // An ordered construct with the simd clause is the only OpenMP construct 5606 // that can appear in the simd region. 5607 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 5608 ErrorFound = true; 5609 } else if (DependFound && (TC || SC)) { 5610 Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd) 5611 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 5612 ErrorFound = true; 5613 } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) { 5614 Diag(DependFound->getLocStart(), 5615 diag::err_omp_ordered_directive_without_param); 5616 ErrorFound = true; 5617 } else if (TC || Clauses.empty()) { 5618 if (auto *Param = DSAStack->getParentOrderedRegionParam()) { 5619 SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc; 5620 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 5621 << (TC != nullptr); 5622 Diag(Param->getLocStart(), diag::note_omp_ordered_param); 5623 ErrorFound = true; 5624 } 5625 } 5626 if ((!AStmt && !DependFound) || ErrorFound) 5627 return StmtError(); 5628 5629 if (AStmt) { 5630 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5631 5632 getCurFunction()->setHasBranchProtectedScope(); 5633 } 5634 5635 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5636 } 5637 5638 namespace { 5639 /// \brief Helper class for checking expression in 'omp atomic [update]' 5640 /// construct. 5641 class OpenMPAtomicUpdateChecker { 5642 /// \brief Error results for atomic update expressions. 5643 enum ExprAnalysisErrorCode { 5644 /// \brief A statement is not an expression statement. 5645 NotAnExpression, 5646 /// \brief Expression is not builtin binary or unary operation. 5647 NotABinaryOrUnaryExpression, 5648 /// \brief Unary operation is not post-/pre- increment/decrement operation. 5649 NotAnUnaryIncDecExpression, 5650 /// \brief An expression is not of scalar type. 5651 NotAScalarType, 5652 /// \brief A binary operation is not an assignment operation. 5653 NotAnAssignmentOp, 5654 /// \brief RHS part of the binary operation is not a binary expression. 5655 NotABinaryExpression, 5656 /// \brief RHS part is not additive/multiplicative/shift/biwise binary 5657 /// expression. 5658 NotABinaryOperator, 5659 /// \brief RHS binary operation does not have reference to the updated LHS 5660 /// part. 5661 NotAnUpdateExpression, 5662 /// \brief No errors is found. 5663 NoError 5664 }; 5665 /// \brief Reference to Sema. 5666 Sema &SemaRef; 5667 /// \brief A location for note diagnostics (when error is found). 5668 SourceLocation NoteLoc; 5669 /// \brief 'x' lvalue part of the source atomic expression. 5670 Expr *X; 5671 /// \brief 'expr' rvalue part of the source atomic expression. 5672 Expr *E; 5673 /// \brief Helper expression of the form 5674 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5675 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5676 Expr *UpdateExpr; 5677 /// \brief Is 'x' a LHS in a RHS part of full update expression. It is 5678 /// important for non-associative operations. 5679 bool IsXLHSInRHSPart; 5680 BinaryOperatorKind Op; 5681 SourceLocation OpLoc; 5682 /// \brief true if the source expression is a postfix unary operation, false 5683 /// if it is a prefix unary operation. 5684 bool IsPostfixUpdate; 5685 5686 public: 5687 OpenMPAtomicUpdateChecker(Sema &SemaRef) 5688 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 5689 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 5690 /// \brief Check specified statement that it is suitable for 'atomic update' 5691 /// constructs and extract 'x', 'expr' and Operation from the original 5692 /// expression. If DiagId and NoteId == 0, then only check is performed 5693 /// without error notification. 5694 /// \param DiagId Diagnostic which should be emitted if error is found. 5695 /// \param NoteId Diagnostic note for the main error message. 5696 /// \return true if statement is not an update expression, false otherwise. 5697 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 5698 /// \brief Return the 'x' lvalue part of the source atomic expression. 5699 Expr *getX() const { return X; } 5700 /// \brief Return the 'expr' rvalue part of the source atomic expression. 5701 Expr *getExpr() const { return E; } 5702 /// \brief Return the update expression used in calculation of the updated 5703 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5704 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5705 Expr *getUpdateExpr() const { return UpdateExpr; } 5706 /// \brief Return true if 'x' is LHS in RHS part of full update expression, 5707 /// false otherwise. 5708 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 5709 5710 /// \brief true if the source expression is a postfix unary operation, false 5711 /// if it is a prefix unary operation. 5712 bool isPostfixUpdate() const { return IsPostfixUpdate; } 5713 5714 private: 5715 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 5716 unsigned NoteId = 0); 5717 }; 5718 } // namespace 5719 5720 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 5721 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 5722 ExprAnalysisErrorCode ErrorFound = NoError; 5723 SourceLocation ErrorLoc, NoteLoc; 5724 SourceRange ErrorRange, NoteRange; 5725 // Allowed constructs are: 5726 // x = x binop expr; 5727 // x = expr binop x; 5728 if (AtomicBinOp->getOpcode() == BO_Assign) { 5729 X = AtomicBinOp->getLHS(); 5730 if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 5731 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 5732 if (AtomicInnerBinOp->isMultiplicativeOp() || 5733 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 5734 AtomicInnerBinOp->isBitwiseOp()) { 5735 Op = AtomicInnerBinOp->getOpcode(); 5736 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 5737 auto *LHS = AtomicInnerBinOp->getLHS(); 5738 auto *RHS = AtomicInnerBinOp->getRHS(); 5739 llvm::FoldingSetNodeID XId, LHSId, RHSId; 5740 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 5741 /*Canonical=*/true); 5742 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 5743 /*Canonical=*/true); 5744 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 5745 /*Canonical=*/true); 5746 if (XId == LHSId) { 5747 E = RHS; 5748 IsXLHSInRHSPart = true; 5749 } else if (XId == RHSId) { 5750 E = LHS; 5751 IsXLHSInRHSPart = false; 5752 } else { 5753 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5754 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5755 NoteLoc = X->getExprLoc(); 5756 NoteRange = X->getSourceRange(); 5757 ErrorFound = NotAnUpdateExpression; 5758 } 5759 } else { 5760 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5761 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5762 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 5763 NoteRange = SourceRange(NoteLoc, NoteLoc); 5764 ErrorFound = NotABinaryOperator; 5765 } 5766 } else { 5767 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 5768 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 5769 ErrorFound = NotABinaryExpression; 5770 } 5771 } else { 5772 ErrorLoc = AtomicBinOp->getExprLoc(); 5773 ErrorRange = AtomicBinOp->getSourceRange(); 5774 NoteLoc = AtomicBinOp->getOperatorLoc(); 5775 NoteRange = SourceRange(NoteLoc, NoteLoc); 5776 ErrorFound = NotAnAssignmentOp; 5777 } 5778 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5779 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5780 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5781 return true; 5782 } else if (SemaRef.CurContext->isDependentContext()) 5783 E = X = UpdateExpr = nullptr; 5784 return ErrorFound != NoError; 5785 } 5786 5787 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 5788 unsigned NoteId) { 5789 ExprAnalysisErrorCode ErrorFound = NoError; 5790 SourceLocation ErrorLoc, NoteLoc; 5791 SourceRange ErrorRange, NoteRange; 5792 // Allowed constructs are: 5793 // x++; 5794 // x--; 5795 // ++x; 5796 // --x; 5797 // x binop= expr; 5798 // x = x binop expr; 5799 // x = expr binop x; 5800 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 5801 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 5802 if (AtomicBody->getType()->isScalarType() || 5803 AtomicBody->isInstantiationDependent()) { 5804 if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 5805 AtomicBody->IgnoreParenImpCasts())) { 5806 // Check for Compound Assignment Operation 5807 Op = BinaryOperator::getOpForCompoundAssignment( 5808 AtomicCompAssignOp->getOpcode()); 5809 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 5810 E = AtomicCompAssignOp->getRHS(); 5811 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 5812 IsXLHSInRHSPart = true; 5813 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 5814 AtomicBody->IgnoreParenImpCasts())) { 5815 // Check for Binary Operation 5816 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 5817 return true; 5818 } else if (auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 5819 AtomicBody->IgnoreParenImpCasts())) { 5820 // Check for Unary Operation 5821 if (AtomicUnaryOp->isIncrementDecrementOp()) { 5822 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 5823 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 5824 OpLoc = AtomicUnaryOp->getOperatorLoc(); 5825 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 5826 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 5827 IsXLHSInRHSPart = true; 5828 } else { 5829 ErrorFound = NotAnUnaryIncDecExpression; 5830 ErrorLoc = AtomicUnaryOp->getExprLoc(); 5831 ErrorRange = AtomicUnaryOp->getSourceRange(); 5832 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 5833 NoteRange = SourceRange(NoteLoc, NoteLoc); 5834 } 5835 } else if (!AtomicBody->isInstantiationDependent()) { 5836 ErrorFound = NotABinaryOrUnaryExpression; 5837 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 5838 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 5839 } 5840 } else { 5841 ErrorFound = NotAScalarType; 5842 NoteLoc = ErrorLoc = AtomicBody->getLocStart(); 5843 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5844 } 5845 } else { 5846 ErrorFound = NotAnExpression; 5847 NoteLoc = ErrorLoc = S->getLocStart(); 5848 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5849 } 5850 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5851 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5852 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5853 return true; 5854 } else if (SemaRef.CurContext->isDependentContext()) 5855 E = X = UpdateExpr = nullptr; 5856 if (ErrorFound == NoError && E && X) { 5857 // Build an update expression of form 'OpaqueValueExpr(x) binop 5858 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 5859 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 5860 auto *OVEX = new (SemaRef.getASTContext()) 5861 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 5862 auto *OVEExpr = new (SemaRef.getASTContext()) 5863 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 5864 auto Update = 5865 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 5866 IsXLHSInRHSPart ? OVEExpr : OVEX); 5867 if (Update.isInvalid()) 5868 return true; 5869 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 5870 Sema::AA_Casting); 5871 if (Update.isInvalid()) 5872 return true; 5873 UpdateExpr = Update.get(); 5874 } 5875 return ErrorFound != NoError; 5876 } 5877 5878 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 5879 Stmt *AStmt, 5880 SourceLocation StartLoc, 5881 SourceLocation EndLoc) { 5882 if (!AStmt) 5883 return StmtError(); 5884 5885 auto *CS = cast<CapturedStmt>(AStmt); 5886 // 1.2.2 OpenMP Language Terminology 5887 // Structured block - An executable statement with a single entry at the 5888 // top and a single exit at the bottom. 5889 // The point of exit cannot be a branch out of the structured block. 5890 // longjmp() and throw() must not violate the entry/exit criteria. 5891 OpenMPClauseKind AtomicKind = OMPC_unknown; 5892 SourceLocation AtomicKindLoc; 5893 for (auto *C : Clauses) { 5894 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 5895 C->getClauseKind() == OMPC_update || 5896 C->getClauseKind() == OMPC_capture) { 5897 if (AtomicKind != OMPC_unknown) { 5898 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) 5899 << SourceRange(C->getLocStart(), C->getLocEnd()); 5900 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 5901 << getOpenMPClauseName(AtomicKind); 5902 } else { 5903 AtomicKind = C->getClauseKind(); 5904 AtomicKindLoc = C->getLocStart(); 5905 } 5906 } 5907 } 5908 5909 auto Body = CS->getCapturedStmt(); 5910 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 5911 Body = EWC->getSubExpr(); 5912 5913 Expr *X = nullptr; 5914 Expr *V = nullptr; 5915 Expr *E = nullptr; 5916 Expr *UE = nullptr; 5917 bool IsXLHSInRHSPart = false; 5918 bool IsPostfixUpdate = false; 5919 // OpenMP [2.12.6, atomic Construct] 5920 // In the next expressions: 5921 // * x and v (as applicable) are both l-value expressions with scalar type. 5922 // * During the execution of an atomic region, multiple syntactic 5923 // occurrences of x must designate the same storage location. 5924 // * Neither of v and expr (as applicable) may access the storage location 5925 // designated by x. 5926 // * Neither of x and expr (as applicable) may access the storage location 5927 // designated by v. 5928 // * expr is an expression with scalar type. 5929 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 5930 // * binop, binop=, ++, and -- are not overloaded operators. 5931 // * The expression x binop expr must be numerically equivalent to x binop 5932 // (expr). This requirement is satisfied if the operators in expr have 5933 // precedence greater than binop, or by using parentheses around expr or 5934 // subexpressions of expr. 5935 // * The expression expr binop x must be numerically equivalent to (expr) 5936 // binop x. This requirement is satisfied if the operators in expr have 5937 // precedence equal to or greater than binop, or by using parentheses around 5938 // expr or subexpressions of expr. 5939 // * For forms that allow multiple occurrences of x, the number of times 5940 // that x is evaluated is unspecified. 5941 if (AtomicKind == OMPC_read) { 5942 enum { 5943 NotAnExpression, 5944 NotAnAssignmentOp, 5945 NotAScalarType, 5946 NotAnLValue, 5947 NoError 5948 } ErrorFound = NoError; 5949 SourceLocation ErrorLoc, NoteLoc; 5950 SourceRange ErrorRange, NoteRange; 5951 // If clause is read: 5952 // v = x; 5953 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 5954 auto *AtomicBinOp = 5955 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5956 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5957 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 5958 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 5959 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 5960 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 5961 if (!X->isLValue() || !V->isLValue()) { 5962 auto NotLValueExpr = X->isLValue() ? V : X; 5963 ErrorFound = NotAnLValue; 5964 ErrorLoc = AtomicBinOp->getExprLoc(); 5965 ErrorRange = AtomicBinOp->getSourceRange(); 5966 NoteLoc = NotLValueExpr->getExprLoc(); 5967 NoteRange = NotLValueExpr->getSourceRange(); 5968 } 5969 } else if (!X->isInstantiationDependent() || 5970 !V->isInstantiationDependent()) { 5971 auto NotScalarExpr = 5972 (X->isInstantiationDependent() || X->getType()->isScalarType()) 5973 ? V 5974 : X; 5975 ErrorFound = NotAScalarType; 5976 ErrorLoc = AtomicBinOp->getExprLoc(); 5977 ErrorRange = AtomicBinOp->getSourceRange(); 5978 NoteLoc = NotScalarExpr->getExprLoc(); 5979 NoteRange = NotScalarExpr->getSourceRange(); 5980 } 5981 } else if (!AtomicBody->isInstantiationDependent()) { 5982 ErrorFound = NotAnAssignmentOp; 5983 ErrorLoc = AtomicBody->getExprLoc(); 5984 ErrorRange = AtomicBody->getSourceRange(); 5985 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5986 : AtomicBody->getExprLoc(); 5987 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5988 : AtomicBody->getSourceRange(); 5989 } 5990 } else { 5991 ErrorFound = NotAnExpression; 5992 NoteLoc = ErrorLoc = Body->getLocStart(); 5993 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5994 } 5995 if (ErrorFound != NoError) { 5996 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 5997 << ErrorRange; 5998 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 5999 << NoteRange; 6000 return StmtError(); 6001 } else if (CurContext->isDependentContext()) 6002 V = X = nullptr; 6003 } else if (AtomicKind == OMPC_write) { 6004 enum { 6005 NotAnExpression, 6006 NotAnAssignmentOp, 6007 NotAScalarType, 6008 NotAnLValue, 6009 NoError 6010 } ErrorFound = NoError; 6011 SourceLocation ErrorLoc, NoteLoc; 6012 SourceRange ErrorRange, NoteRange; 6013 // If clause is write: 6014 // x = expr; 6015 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 6016 auto *AtomicBinOp = 6017 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6018 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6019 X = AtomicBinOp->getLHS(); 6020 E = AtomicBinOp->getRHS(); 6021 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6022 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 6023 if (!X->isLValue()) { 6024 ErrorFound = NotAnLValue; 6025 ErrorLoc = AtomicBinOp->getExprLoc(); 6026 ErrorRange = AtomicBinOp->getSourceRange(); 6027 NoteLoc = X->getExprLoc(); 6028 NoteRange = X->getSourceRange(); 6029 } 6030 } else if (!X->isInstantiationDependent() || 6031 !E->isInstantiationDependent()) { 6032 auto NotScalarExpr = 6033 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6034 ? E 6035 : X; 6036 ErrorFound = NotAScalarType; 6037 ErrorLoc = AtomicBinOp->getExprLoc(); 6038 ErrorRange = AtomicBinOp->getSourceRange(); 6039 NoteLoc = NotScalarExpr->getExprLoc(); 6040 NoteRange = NotScalarExpr->getSourceRange(); 6041 } 6042 } else if (!AtomicBody->isInstantiationDependent()) { 6043 ErrorFound = NotAnAssignmentOp; 6044 ErrorLoc = AtomicBody->getExprLoc(); 6045 ErrorRange = AtomicBody->getSourceRange(); 6046 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6047 : AtomicBody->getExprLoc(); 6048 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6049 : AtomicBody->getSourceRange(); 6050 } 6051 } else { 6052 ErrorFound = NotAnExpression; 6053 NoteLoc = ErrorLoc = Body->getLocStart(); 6054 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6055 } 6056 if (ErrorFound != NoError) { 6057 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 6058 << ErrorRange; 6059 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 6060 << NoteRange; 6061 return StmtError(); 6062 } else if (CurContext->isDependentContext()) 6063 E = X = nullptr; 6064 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 6065 // If clause is update: 6066 // x++; 6067 // x--; 6068 // ++x; 6069 // --x; 6070 // x binop= expr; 6071 // x = x binop expr; 6072 // x = expr binop x; 6073 OpenMPAtomicUpdateChecker Checker(*this); 6074 if (Checker.checkStatement( 6075 Body, (AtomicKind == OMPC_update) 6076 ? diag::err_omp_atomic_update_not_expression_statement 6077 : diag::err_omp_atomic_not_expression_statement, 6078 diag::note_omp_atomic_update)) 6079 return StmtError(); 6080 if (!CurContext->isDependentContext()) { 6081 E = Checker.getExpr(); 6082 X = Checker.getX(); 6083 UE = Checker.getUpdateExpr(); 6084 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6085 } 6086 } else if (AtomicKind == OMPC_capture) { 6087 enum { 6088 NotAnAssignmentOp, 6089 NotACompoundStatement, 6090 NotTwoSubstatements, 6091 NotASpecificExpression, 6092 NoError 6093 } ErrorFound = NoError; 6094 SourceLocation ErrorLoc, NoteLoc; 6095 SourceRange ErrorRange, NoteRange; 6096 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 6097 // If clause is a capture: 6098 // v = x++; 6099 // v = x--; 6100 // v = ++x; 6101 // v = --x; 6102 // v = x binop= expr; 6103 // v = x = x binop expr; 6104 // v = x = expr binop x; 6105 auto *AtomicBinOp = 6106 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6107 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6108 V = AtomicBinOp->getLHS(); 6109 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6110 OpenMPAtomicUpdateChecker Checker(*this); 6111 if (Checker.checkStatement( 6112 Body, diag::err_omp_atomic_capture_not_expression_statement, 6113 diag::note_omp_atomic_update)) 6114 return StmtError(); 6115 E = Checker.getExpr(); 6116 X = Checker.getX(); 6117 UE = Checker.getUpdateExpr(); 6118 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6119 IsPostfixUpdate = Checker.isPostfixUpdate(); 6120 } else if (!AtomicBody->isInstantiationDependent()) { 6121 ErrorLoc = AtomicBody->getExprLoc(); 6122 ErrorRange = AtomicBody->getSourceRange(); 6123 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6124 : AtomicBody->getExprLoc(); 6125 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6126 : AtomicBody->getSourceRange(); 6127 ErrorFound = NotAnAssignmentOp; 6128 } 6129 if (ErrorFound != NoError) { 6130 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 6131 << ErrorRange; 6132 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6133 return StmtError(); 6134 } else if (CurContext->isDependentContext()) { 6135 UE = V = E = X = nullptr; 6136 } 6137 } else { 6138 // If clause is a capture: 6139 // { v = x; x = expr; } 6140 // { v = x; x++; } 6141 // { v = x; x--; } 6142 // { v = x; ++x; } 6143 // { v = x; --x; } 6144 // { v = x; x binop= expr; } 6145 // { v = x; x = x binop expr; } 6146 // { v = x; x = expr binop x; } 6147 // { x++; v = x; } 6148 // { x--; v = x; } 6149 // { ++x; v = x; } 6150 // { --x; v = x; } 6151 // { x binop= expr; v = x; } 6152 // { x = x binop expr; v = x; } 6153 // { x = expr binop x; v = x; } 6154 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 6155 // Check that this is { expr1; expr2; } 6156 if (CS->size() == 2) { 6157 auto *First = CS->body_front(); 6158 auto *Second = CS->body_back(); 6159 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 6160 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 6161 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 6162 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 6163 // Need to find what subexpression is 'v' and what is 'x'. 6164 OpenMPAtomicUpdateChecker Checker(*this); 6165 bool IsUpdateExprFound = !Checker.checkStatement(Second); 6166 BinaryOperator *BinOp = nullptr; 6167 if (IsUpdateExprFound) { 6168 BinOp = dyn_cast<BinaryOperator>(First); 6169 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6170 } 6171 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6172 // { v = x; x++; } 6173 // { v = x; x--; } 6174 // { v = x; ++x; } 6175 // { v = x; --x; } 6176 // { v = x; x binop= expr; } 6177 // { v = x; x = x binop expr; } 6178 // { v = x; x = expr binop x; } 6179 // Check that the first expression has form v = x. 6180 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6181 llvm::FoldingSetNodeID XId, PossibleXId; 6182 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6183 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6184 IsUpdateExprFound = XId == PossibleXId; 6185 if (IsUpdateExprFound) { 6186 V = BinOp->getLHS(); 6187 X = Checker.getX(); 6188 E = Checker.getExpr(); 6189 UE = Checker.getUpdateExpr(); 6190 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6191 IsPostfixUpdate = true; 6192 } 6193 } 6194 if (!IsUpdateExprFound) { 6195 IsUpdateExprFound = !Checker.checkStatement(First); 6196 BinOp = nullptr; 6197 if (IsUpdateExprFound) { 6198 BinOp = dyn_cast<BinaryOperator>(Second); 6199 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6200 } 6201 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6202 // { x++; v = x; } 6203 // { x--; v = x; } 6204 // { ++x; v = x; } 6205 // { --x; v = x; } 6206 // { x binop= expr; v = x; } 6207 // { x = x binop expr; v = x; } 6208 // { x = expr binop x; v = x; } 6209 // Check that the second expression has form v = x. 6210 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6211 llvm::FoldingSetNodeID XId, PossibleXId; 6212 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6213 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6214 IsUpdateExprFound = XId == PossibleXId; 6215 if (IsUpdateExprFound) { 6216 V = BinOp->getLHS(); 6217 X = Checker.getX(); 6218 E = Checker.getExpr(); 6219 UE = Checker.getUpdateExpr(); 6220 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6221 IsPostfixUpdate = false; 6222 } 6223 } 6224 } 6225 if (!IsUpdateExprFound) { 6226 // { v = x; x = expr; } 6227 auto *FirstExpr = dyn_cast<Expr>(First); 6228 auto *SecondExpr = dyn_cast<Expr>(Second); 6229 if (!FirstExpr || !SecondExpr || 6230 !(FirstExpr->isInstantiationDependent() || 6231 SecondExpr->isInstantiationDependent())) { 6232 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 6233 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 6234 ErrorFound = NotAnAssignmentOp; 6235 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 6236 : First->getLocStart(); 6237 NoteRange = ErrorRange = FirstBinOp 6238 ? FirstBinOp->getSourceRange() 6239 : SourceRange(ErrorLoc, ErrorLoc); 6240 } else { 6241 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 6242 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 6243 ErrorFound = NotAnAssignmentOp; 6244 NoteLoc = ErrorLoc = SecondBinOp 6245 ? SecondBinOp->getOperatorLoc() 6246 : Second->getLocStart(); 6247 NoteRange = ErrorRange = 6248 SecondBinOp ? SecondBinOp->getSourceRange() 6249 : SourceRange(ErrorLoc, ErrorLoc); 6250 } else { 6251 auto *PossibleXRHSInFirst = 6252 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 6253 auto *PossibleXLHSInSecond = 6254 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 6255 llvm::FoldingSetNodeID X1Id, X2Id; 6256 PossibleXRHSInFirst->Profile(X1Id, Context, 6257 /*Canonical=*/true); 6258 PossibleXLHSInSecond->Profile(X2Id, Context, 6259 /*Canonical=*/true); 6260 IsUpdateExprFound = X1Id == X2Id; 6261 if (IsUpdateExprFound) { 6262 V = FirstBinOp->getLHS(); 6263 X = SecondBinOp->getLHS(); 6264 E = SecondBinOp->getRHS(); 6265 UE = nullptr; 6266 IsXLHSInRHSPart = false; 6267 IsPostfixUpdate = true; 6268 } else { 6269 ErrorFound = NotASpecificExpression; 6270 ErrorLoc = FirstBinOp->getExprLoc(); 6271 ErrorRange = FirstBinOp->getSourceRange(); 6272 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 6273 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 6274 } 6275 } 6276 } 6277 } 6278 } 6279 } else { 6280 NoteLoc = ErrorLoc = Body->getLocStart(); 6281 NoteRange = ErrorRange = 6282 SourceRange(Body->getLocStart(), Body->getLocStart()); 6283 ErrorFound = NotTwoSubstatements; 6284 } 6285 } else { 6286 NoteLoc = ErrorLoc = Body->getLocStart(); 6287 NoteRange = ErrorRange = 6288 SourceRange(Body->getLocStart(), Body->getLocStart()); 6289 ErrorFound = NotACompoundStatement; 6290 } 6291 if (ErrorFound != NoError) { 6292 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 6293 << ErrorRange; 6294 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6295 return StmtError(); 6296 } else if (CurContext->isDependentContext()) { 6297 UE = V = E = X = nullptr; 6298 } 6299 } 6300 } 6301 6302 getCurFunction()->setHasBranchProtectedScope(); 6303 6304 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6305 X, V, E, UE, IsXLHSInRHSPart, 6306 IsPostfixUpdate); 6307 } 6308 6309 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 6310 Stmt *AStmt, 6311 SourceLocation StartLoc, 6312 SourceLocation EndLoc) { 6313 if (!AStmt) 6314 return StmtError(); 6315 6316 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6317 // 1.2.2 OpenMP Language Terminology 6318 // Structured block - An executable statement with a single entry at the 6319 // top and a single exit at the bottom. 6320 // The point of exit cannot be a branch out of the structured block. 6321 // longjmp() and throw() must not violate the entry/exit criteria. 6322 CS->getCapturedDecl()->setNothrow(); 6323 6324 // OpenMP [2.16, Nesting of Regions] 6325 // If specified, a teams construct must be contained within a target 6326 // construct. That target construct must contain no statements or directives 6327 // outside of the teams construct. 6328 if (DSAStack->hasInnerTeamsRegion()) { 6329 auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true); 6330 bool OMPTeamsFound = true; 6331 if (auto *CS = dyn_cast<CompoundStmt>(S)) { 6332 auto I = CS->body_begin(); 6333 while (I != CS->body_end()) { 6334 auto *OED = dyn_cast<OMPExecutableDirective>(*I); 6335 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { 6336 OMPTeamsFound = false; 6337 break; 6338 } 6339 ++I; 6340 } 6341 assert(I != CS->body_end() && "Not found statement"); 6342 S = *I; 6343 } else { 6344 auto *OED = dyn_cast<OMPExecutableDirective>(S); 6345 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 6346 } 6347 if (!OMPTeamsFound) { 6348 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 6349 Diag(DSAStack->getInnerTeamsRegionLoc(), 6350 diag::note_omp_nested_teams_construct_here); 6351 Diag(S->getLocStart(), diag::note_omp_nested_statement_here) 6352 << isa<OMPExecutableDirective>(S); 6353 return StmtError(); 6354 } 6355 } 6356 6357 getCurFunction()->setHasBranchProtectedScope(); 6358 6359 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6360 } 6361 6362 StmtResult 6363 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 6364 Stmt *AStmt, SourceLocation StartLoc, 6365 SourceLocation EndLoc) { 6366 if (!AStmt) 6367 return StmtError(); 6368 6369 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6370 // 1.2.2 OpenMP Language Terminology 6371 // Structured block - An executable statement with a single entry at the 6372 // top and a single exit at the bottom. 6373 // The point of exit cannot be a branch out of the structured block. 6374 // longjmp() and throw() must not violate the entry/exit criteria. 6375 CS->getCapturedDecl()->setNothrow(); 6376 6377 getCurFunction()->setHasBranchProtectedScope(); 6378 6379 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6380 AStmt); 6381 } 6382 6383 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 6384 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6385 SourceLocation EndLoc, 6386 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6387 if (!AStmt) 6388 return StmtError(); 6389 6390 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6391 // 1.2.2 OpenMP Language Terminology 6392 // Structured block - An executable statement with a single entry at the 6393 // top and a single exit at the bottom. 6394 // The point of exit cannot be a branch out of the structured block. 6395 // longjmp() and throw() must not violate the entry/exit criteria. 6396 CS->getCapturedDecl()->setNothrow(); 6397 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 6398 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6399 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6400 // 1.2.2 OpenMP Language Terminology 6401 // Structured block - An executable statement with a single entry at the 6402 // top and a single exit at the bottom. 6403 // The point of exit cannot be a branch out of the structured block. 6404 // longjmp() and throw() must not violate the entry/exit criteria. 6405 CS->getCapturedDecl()->setNothrow(); 6406 } 6407 6408 OMPLoopDirective::HelperExprs B; 6409 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6410 // define the nested loops number. 6411 unsigned NestedLoopCount = 6412 CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 6413 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 6414 VarsWithImplicitDSA, B); 6415 if (NestedLoopCount == 0) 6416 return StmtError(); 6417 6418 assert((CurContext->isDependentContext() || B.builtAll()) && 6419 "omp target parallel for loop exprs were not built"); 6420 6421 if (!CurContext->isDependentContext()) { 6422 // Finalize the clauses that need pre-built expressions for CodeGen. 6423 for (auto C : Clauses) { 6424 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6425 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6426 B.NumIterations, *this, CurScope, 6427 DSAStack)) 6428 return StmtError(); 6429 } 6430 } 6431 6432 getCurFunction()->setHasBranchProtectedScope(); 6433 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 6434 NestedLoopCount, Clauses, AStmt, 6435 B, DSAStack->isCancelRegion()); 6436 } 6437 6438 /// Check for existence of a map clause in the list of clauses. 6439 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 6440 const OpenMPClauseKind K) { 6441 return llvm::any_of( 6442 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 6443 } 6444 6445 template <typename... Params> 6446 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 6447 const Params... ClauseTypes) { 6448 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 6449 } 6450 6451 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 6452 Stmt *AStmt, 6453 SourceLocation StartLoc, 6454 SourceLocation EndLoc) { 6455 if (!AStmt) 6456 return StmtError(); 6457 6458 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6459 6460 // OpenMP [2.10.1, Restrictions, p. 97] 6461 // At least one map clause must appear on the directive. 6462 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 6463 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6464 << "'map' or 'use_device_ptr'" 6465 << getOpenMPDirectiveName(OMPD_target_data); 6466 return StmtError(); 6467 } 6468 6469 getCurFunction()->setHasBranchProtectedScope(); 6470 6471 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 6472 AStmt); 6473 } 6474 6475 StmtResult 6476 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 6477 SourceLocation StartLoc, 6478 SourceLocation EndLoc, Stmt *AStmt) { 6479 if (!AStmt) 6480 return StmtError(); 6481 6482 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6483 // 1.2.2 OpenMP Language Terminology 6484 // Structured block - An executable statement with a single entry at the 6485 // top and a single exit at the bottom. 6486 // The point of exit cannot be a branch out of the structured block. 6487 // longjmp() and throw() must not violate the entry/exit criteria. 6488 CS->getCapturedDecl()->setNothrow(); 6489 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_enter_data); 6490 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6491 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6492 // 1.2.2 OpenMP Language Terminology 6493 // Structured block - An executable statement with a single entry at the 6494 // top and a single exit at the bottom. 6495 // The point of exit cannot be a branch out of the structured block. 6496 // longjmp() and throw() must not violate the entry/exit criteria. 6497 CS->getCapturedDecl()->setNothrow(); 6498 } 6499 6500 // OpenMP [2.10.2, Restrictions, p. 99] 6501 // At least one map clause must appear on the directive. 6502 if (!hasClauses(Clauses, OMPC_map)) { 6503 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6504 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 6505 return StmtError(); 6506 } 6507 6508 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 6509 AStmt); 6510 } 6511 6512 StmtResult 6513 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 6514 SourceLocation StartLoc, 6515 SourceLocation EndLoc, Stmt *AStmt) { 6516 if (!AStmt) 6517 return StmtError(); 6518 6519 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6520 // 1.2.2 OpenMP Language Terminology 6521 // Structured block - An executable statement with a single entry at the 6522 // top and a single exit at the bottom. 6523 // The point of exit cannot be a branch out of the structured block. 6524 // longjmp() and throw() must not violate the entry/exit criteria. 6525 CS->getCapturedDecl()->setNothrow(); 6526 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_exit_data); 6527 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6528 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6529 // 1.2.2 OpenMP Language Terminology 6530 // Structured block - An executable statement with a single entry at the 6531 // top and a single exit at the bottom. 6532 // The point of exit cannot be a branch out of the structured block. 6533 // longjmp() and throw() must not violate the entry/exit criteria. 6534 CS->getCapturedDecl()->setNothrow(); 6535 } 6536 6537 // OpenMP [2.10.3, Restrictions, p. 102] 6538 // At least one map clause must appear on the directive. 6539 if (!hasClauses(Clauses, OMPC_map)) { 6540 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6541 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 6542 return StmtError(); 6543 } 6544 6545 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 6546 AStmt); 6547 } 6548 6549 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 6550 SourceLocation StartLoc, 6551 SourceLocation EndLoc, 6552 Stmt *AStmt) { 6553 if (!AStmt) 6554 return StmtError(); 6555 6556 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6557 // 1.2.2 OpenMP Language Terminology 6558 // Structured block - An executable statement with a single entry at the 6559 // top and a single exit at the bottom. 6560 // The point of exit cannot be a branch out of the structured block. 6561 // longjmp() and throw() must not violate the entry/exit criteria. 6562 CS->getCapturedDecl()->setNothrow(); 6563 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_update); 6564 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6565 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6566 // 1.2.2 OpenMP Language Terminology 6567 // Structured block - An executable statement with a single entry at the 6568 // top and a single exit at the bottom. 6569 // The point of exit cannot be a branch out of the structured block. 6570 // longjmp() and throw() must not violate the entry/exit criteria. 6571 CS->getCapturedDecl()->setNothrow(); 6572 } 6573 6574 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 6575 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 6576 return StmtError(); 6577 } 6578 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses, 6579 AStmt); 6580 } 6581 6582 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 6583 Stmt *AStmt, SourceLocation StartLoc, 6584 SourceLocation EndLoc) { 6585 if (!AStmt) 6586 return StmtError(); 6587 6588 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6589 // 1.2.2 OpenMP Language Terminology 6590 // Structured block - An executable statement with a single entry at the 6591 // top and a single exit at the bottom. 6592 // The point of exit cannot be a branch out of the structured block. 6593 // longjmp() and throw() must not violate the entry/exit criteria. 6594 CS->getCapturedDecl()->setNothrow(); 6595 6596 getCurFunction()->setHasBranchProtectedScope(); 6597 6598 DSAStack->setParentTeamsRegionLoc(StartLoc); 6599 6600 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6601 } 6602 6603 StmtResult 6604 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 6605 SourceLocation EndLoc, 6606 OpenMPDirectiveKind CancelRegion) { 6607 if (DSAStack->isParentNowaitRegion()) { 6608 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 6609 return StmtError(); 6610 } 6611 if (DSAStack->isParentOrderedRegion()) { 6612 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 6613 return StmtError(); 6614 } 6615 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 6616 CancelRegion); 6617 } 6618 6619 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 6620 SourceLocation StartLoc, 6621 SourceLocation EndLoc, 6622 OpenMPDirectiveKind CancelRegion) { 6623 if (DSAStack->isParentNowaitRegion()) { 6624 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 6625 return StmtError(); 6626 } 6627 if (DSAStack->isParentOrderedRegion()) { 6628 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 6629 return StmtError(); 6630 } 6631 DSAStack->setParentCancelRegion(/*Cancel=*/true); 6632 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6633 CancelRegion); 6634 } 6635 6636 static bool checkGrainsizeNumTasksClauses(Sema &S, 6637 ArrayRef<OMPClause *> Clauses) { 6638 OMPClause *PrevClause = nullptr; 6639 bool ErrorFound = false; 6640 for (auto *C : Clauses) { 6641 if (C->getClauseKind() == OMPC_grainsize || 6642 C->getClauseKind() == OMPC_num_tasks) { 6643 if (!PrevClause) 6644 PrevClause = C; 6645 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 6646 S.Diag(C->getLocStart(), 6647 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 6648 << getOpenMPClauseName(C->getClauseKind()) 6649 << getOpenMPClauseName(PrevClause->getClauseKind()); 6650 S.Diag(PrevClause->getLocStart(), 6651 diag::note_omp_previous_grainsize_num_tasks) 6652 << getOpenMPClauseName(PrevClause->getClauseKind()); 6653 ErrorFound = true; 6654 } 6655 } 6656 } 6657 return ErrorFound; 6658 } 6659 6660 static bool checkReductionClauseWithNogroup(Sema &S, 6661 ArrayRef<OMPClause *> Clauses) { 6662 OMPClause *ReductionClause = nullptr; 6663 OMPClause *NogroupClause = nullptr; 6664 for (auto *C : Clauses) { 6665 if (C->getClauseKind() == OMPC_reduction) { 6666 ReductionClause = C; 6667 if (NogroupClause) 6668 break; 6669 continue; 6670 } 6671 if (C->getClauseKind() == OMPC_nogroup) { 6672 NogroupClause = C; 6673 if (ReductionClause) 6674 break; 6675 continue; 6676 } 6677 } 6678 if (ReductionClause && NogroupClause) { 6679 S.Diag(ReductionClause->getLocStart(), diag::err_omp_reduction_with_nogroup) 6680 << SourceRange(NogroupClause->getLocStart(), 6681 NogroupClause->getLocEnd()); 6682 return true; 6683 } 6684 return false; 6685 } 6686 6687 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 6688 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6689 SourceLocation EndLoc, 6690 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6691 if (!AStmt) 6692 return StmtError(); 6693 6694 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6695 OMPLoopDirective::HelperExprs B; 6696 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6697 // define the nested loops number. 6698 unsigned NestedLoopCount = 6699 CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 6700 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6701 VarsWithImplicitDSA, B); 6702 if (NestedLoopCount == 0) 6703 return StmtError(); 6704 6705 assert((CurContext->isDependentContext() || B.builtAll()) && 6706 "omp for loop exprs were not built"); 6707 6708 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6709 // The grainsize clause and num_tasks clause are mutually exclusive and may 6710 // not appear on the same taskloop directive. 6711 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6712 return StmtError(); 6713 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6714 // If a reduction clause is present on the taskloop directive, the nogroup 6715 // clause must not be specified. 6716 if (checkReductionClauseWithNogroup(*this, Clauses)) 6717 return StmtError(); 6718 6719 getCurFunction()->setHasBranchProtectedScope(); 6720 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 6721 NestedLoopCount, Clauses, AStmt, B); 6722 } 6723 6724 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 6725 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6726 SourceLocation EndLoc, 6727 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6728 if (!AStmt) 6729 return StmtError(); 6730 6731 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6732 OMPLoopDirective::HelperExprs B; 6733 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6734 // define the nested loops number. 6735 unsigned NestedLoopCount = 6736 CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 6737 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6738 VarsWithImplicitDSA, B); 6739 if (NestedLoopCount == 0) 6740 return StmtError(); 6741 6742 assert((CurContext->isDependentContext() || B.builtAll()) && 6743 "omp for loop exprs were not built"); 6744 6745 if (!CurContext->isDependentContext()) { 6746 // Finalize the clauses that need pre-built expressions for CodeGen. 6747 for (auto C : Clauses) { 6748 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6749 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6750 B.NumIterations, *this, CurScope, 6751 DSAStack)) 6752 return StmtError(); 6753 } 6754 } 6755 6756 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6757 // The grainsize clause and num_tasks clause are mutually exclusive and may 6758 // not appear on the same taskloop directive. 6759 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6760 return StmtError(); 6761 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6762 // If a reduction clause is present on the taskloop directive, the nogroup 6763 // clause must not be specified. 6764 if (checkReductionClauseWithNogroup(*this, Clauses)) 6765 return StmtError(); 6766 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6767 return StmtError(); 6768 6769 getCurFunction()->setHasBranchProtectedScope(); 6770 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 6771 NestedLoopCount, Clauses, AStmt, B); 6772 } 6773 6774 StmtResult Sema::ActOnOpenMPDistributeDirective( 6775 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6776 SourceLocation EndLoc, 6777 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6778 if (!AStmt) 6779 return StmtError(); 6780 6781 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6782 OMPLoopDirective::HelperExprs B; 6783 // In presence of clause 'collapse' with number of loops, it will 6784 // define the nested loops number. 6785 unsigned NestedLoopCount = 6786 CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 6787 nullptr /*ordered not a clause on distribute*/, AStmt, 6788 *this, *DSAStack, VarsWithImplicitDSA, B); 6789 if (NestedLoopCount == 0) 6790 return StmtError(); 6791 6792 assert((CurContext->isDependentContext() || B.builtAll()) && 6793 "omp for loop exprs were not built"); 6794 6795 getCurFunction()->setHasBranchProtectedScope(); 6796 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 6797 NestedLoopCount, Clauses, AStmt, B); 6798 } 6799 6800 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 6801 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6802 SourceLocation EndLoc, 6803 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6804 if (!AStmt) 6805 return StmtError(); 6806 6807 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6808 // 1.2.2 OpenMP Language Terminology 6809 // Structured block - An executable statement with a single entry at the 6810 // top and a single exit at the bottom. 6811 // The point of exit cannot be a branch out of the structured block. 6812 // longjmp() and throw() must not violate the entry/exit criteria. 6813 CS->getCapturedDecl()->setNothrow(); 6814 for (int ThisCaptureLevel = 6815 getOpenMPCaptureLevels(OMPD_distribute_parallel_for); 6816 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6817 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6818 // 1.2.2 OpenMP Language Terminology 6819 // Structured block - An executable statement with a single entry at the 6820 // top and a single exit at the bottom. 6821 // The point of exit cannot be a branch out of the structured block. 6822 // longjmp() and throw() must not violate the entry/exit criteria. 6823 CS->getCapturedDecl()->setNothrow(); 6824 } 6825 6826 OMPLoopDirective::HelperExprs B; 6827 // In presence of clause 'collapse' with number of loops, it will 6828 // define the nested loops number. 6829 unsigned NestedLoopCount = CheckOpenMPLoop( 6830 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 6831 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 6832 VarsWithImplicitDSA, B); 6833 if (NestedLoopCount == 0) 6834 return StmtError(); 6835 6836 assert((CurContext->isDependentContext() || B.builtAll()) && 6837 "omp for loop exprs were not built"); 6838 6839 getCurFunction()->setHasBranchProtectedScope(); 6840 return OMPDistributeParallelForDirective::Create( 6841 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 6842 DSAStack->isCancelRegion()); 6843 } 6844 6845 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 6846 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6847 SourceLocation EndLoc, 6848 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6849 if (!AStmt) 6850 return StmtError(); 6851 6852 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6853 // 1.2.2 OpenMP Language Terminology 6854 // Structured block - An executable statement with a single entry at the 6855 // top and a single exit at the bottom. 6856 // The point of exit cannot be a branch out of the structured block. 6857 // longjmp() and throw() must not violate the entry/exit criteria. 6858 CS->getCapturedDecl()->setNothrow(); 6859 for (int ThisCaptureLevel = 6860 getOpenMPCaptureLevels(OMPD_distribute_parallel_for_simd); 6861 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6862 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6863 // 1.2.2 OpenMP Language Terminology 6864 // Structured block - An executable statement with a single entry at the 6865 // top and a single exit at the bottom. 6866 // The point of exit cannot be a branch out of the structured block. 6867 // longjmp() and throw() must not violate the entry/exit criteria. 6868 CS->getCapturedDecl()->setNothrow(); 6869 } 6870 6871 OMPLoopDirective::HelperExprs B; 6872 // In presence of clause 'collapse' with number of loops, it will 6873 // define the nested loops number. 6874 unsigned NestedLoopCount = CheckOpenMPLoop( 6875 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 6876 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 6877 VarsWithImplicitDSA, B); 6878 if (NestedLoopCount == 0) 6879 return StmtError(); 6880 6881 assert((CurContext->isDependentContext() || B.builtAll()) && 6882 "omp for loop exprs were not built"); 6883 6884 if (!CurContext->isDependentContext()) { 6885 // Finalize the clauses that need pre-built expressions for CodeGen. 6886 for (auto C : Clauses) { 6887 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6888 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6889 B.NumIterations, *this, CurScope, 6890 DSAStack)) 6891 return StmtError(); 6892 } 6893 } 6894 6895 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6896 return StmtError(); 6897 6898 getCurFunction()->setHasBranchProtectedScope(); 6899 return OMPDistributeParallelForSimdDirective::Create( 6900 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6901 } 6902 6903 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 6904 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6905 SourceLocation EndLoc, 6906 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6907 if (!AStmt) 6908 return StmtError(); 6909 6910 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6911 // 1.2.2 OpenMP Language Terminology 6912 // Structured block - An executable statement with a single entry at the 6913 // top and a single exit at the bottom. 6914 // The point of exit cannot be a branch out of the structured block. 6915 // longjmp() and throw() must not violate the entry/exit criteria. 6916 CS->getCapturedDecl()->setNothrow(); 6917 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_distribute_simd); 6918 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6919 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6920 // 1.2.2 OpenMP Language Terminology 6921 // Structured block - An executable statement with a single entry at the 6922 // top and a single exit at the bottom. 6923 // The point of exit cannot be a branch out of the structured block. 6924 // longjmp() and throw() must not violate the entry/exit criteria. 6925 CS->getCapturedDecl()->setNothrow(); 6926 } 6927 6928 OMPLoopDirective::HelperExprs B; 6929 // In presence of clause 'collapse' with number of loops, it will 6930 // define the nested loops number. 6931 unsigned NestedLoopCount = 6932 CheckOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 6933 nullptr /*ordered not a clause on distribute*/, CS, *this, 6934 *DSAStack, VarsWithImplicitDSA, B); 6935 if (NestedLoopCount == 0) 6936 return StmtError(); 6937 6938 assert((CurContext->isDependentContext() || B.builtAll()) && 6939 "omp for loop exprs were not built"); 6940 6941 if (!CurContext->isDependentContext()) { 6942 // Finalize the clauses that need pre-built expressions for CodeGen. 6943 for (auto C : Clauses) { 6944 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6945 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6946 B.NumIterations, *this, CurScope, 6947 DSAStack)) 6948 return StmtError(); 6949 } 6950 } 6951 6952 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6953 return StmtError(); 6954 6955 getCurFunction()->setHasBranchProtectedScope(); 6956 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 6957 NestedLoopCount, Clauses, AStmt, B); 6958 } 6959 6960 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 6961 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6962 SourceLocation EndLoc, 6963 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6964 if (!AStmt) 6965 return StmtError(); 6966 6967 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6968 // 1.2.2 OpenMP Language Terminology 6969 // Structured block - An executable statement with a single entry at the 6970 // top and a single exit at the bottom. 6971 // The point of exit cannot be a branch out of the structured block. 6972 // longjmp() and throw() must not violate the entry/exit criteria. 6973 CS->getCapturedDecl()->setNothrow(); 6974 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_parallel_for); 6975 ThisCaptureLevel > 1; --ThisCaptureLevel) { 6976 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 6977 // 1.2.2 OpenMP Language Terminology 6978 // Structured block - An executable statement with a single entry at the 6979 // top and a single exit at the bottom. 6980 // The point of exit cannot be a branch out of the structured block. 6981 // longjmp() and throw() must not violate the entry/exit criteria. 6982 CS->getCapturedDecl()->setNothrow(); 6983 } 6984 6985 OMPLoopDirective::HelperExprs B; 6986 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6987 // define the nested loops number. 6988 unsigned NestedLoopCount = CheckOpenMPLoop( 6989 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 6990 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 6991 VarsWithImplicitDSA, B); 6992 if (NestedLoopCount == 0) 6993 return StmtError(); 6994 6995 assert((CurContext->isDependentContext() || B.builtAll()) && 6996 "omp target parallel for simd loop exprs were not built"); 6997 6998 if (!CurContext->isDependentContext()) { 6999 // Finalize the clauses that need pre-built expressions for CodeGen. 7000 for (auto C : Clauses) { 7001 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7002 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7003 B.NumIterations, *this, CurScope, 7004 DSAStack)) 7005 return StmtError(); 7006 } 7007 } 7008 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7009 return StmtError(); 7010 7011 getCurFunction()->setHasBranchProtectedScope(); 7012 return OMPTargetParallelForSimdDirective::Create( 7013 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7014 } 7015 7016 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 7017 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7018 SourceLocation EndLoc, 7019 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7020 if (!AStmt) 7021 return StmtError(); 7022 7023 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7024 // 1.2.2 OpenMP Language Terminology 7025 // Structured block - An executable statement with a single entry at the 7026 // top and a single exit at the bottom. 7027 // The point of exit cannot be a branch out of the structured block. 7028 // longjmp() and throw() must not violate the entry/exit criteria. 7029 CS->getCapturedDecl()->setNothrow(); 7030 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_simd); 7031 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7032 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7033 // 1.2.2 OpenMP Language Terminology 7034 // Structured block - An executable statement with a single entry at the 7035 // top and a single exit at the bottom. 7036 // The point of exit cannot be a branch out of the structured block. 7037 // longjmp() and throw() must not violate the entry/exit criteria. 7038 CS->getCapturedDecl()->setNothrow(); 7039 } 7040 7041 OMPLoopDirective::HelperExprs B; 7042 // In presence of clause 'collapse' with number of loops, it will define the 7043 // nested loops number. 7044 unsigned NestedLoopCount = 7045 CheckOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 7046 getOrderedNumberExpr(Clauses), CS, *this, *DSAStack, 7047 VarsWithImplicitDSA, B); 7048 if (NestedLoopCount == 0) 7049 return StmtError(); 7050 7051 assert((CurContext->isDependentContext() || B.builtAll()) && 7052 "omp target simd loop exprs were not built"); 7053 7054 if (!CurContext->isDependentContext()) { 7055 // Finalize the clauses that need pre-built expressions for CodeGen. 7056 for (auto C : Clauses) { 7057 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7058 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7059 B.NumIterations, *this, CurScope, 7060 DSAStack)) 7061 return StmtError(); 7062 } 7063 } 7064 7065 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7066 return StmtError(); 7067 7068 getCurFunction()->setHasBranchProtectedScope(); 7069 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 7070 NestedLoopCount, Clauses, AStmt, B); 7071 } 7072 7073 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 7074 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7075 SourceLocation EndLoc, 7076 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7077 if (!AStmt) 7078 return StmtError(); 7079 7080 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7081 // 1.2.2 OpenMP Language Terminology 7082 // Structured block - An executable statement with a single entry at the 7083 // top and a single exit at the bottom. 7084 // The point of exit cannot be a branch out of the structured block. 7085 // longjmp() and throw() must not violate the entry/exit criteria. 7086 CS->getCapturedDecl()->setNothrow(); 7087 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_teams_distribute); 7088 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7089 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7090 // 1.2.2 OpenMP Language Terminology 7091 // Structured block - An executable statement with a single entry at the 7092 // top and a single exit at the bottom. 7093 // The point of exit cannot be a branch out of the structured block. 7094 // longjmp() and throw() must not violate the entry/exit criteria. 7095 CS->getCapturedDecl()->setNothrow(); 7096 } 7097 7098 OMPLoopDirective::HelperExprs B; 7099 // In presence of clause 'collapse' with number of loops, it will 7100 // define the nested loops number. 7101 unsigned NestedLoopCount = 7102 CheckOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 7103 nullptr /*ordered not a clause on distribute*/, CS, *this, 7104 *DSAStack, VarsWithImplicitDSA, B); 7105 if (NestedLoopCount == 0) 7106 return StmtError(); 7107 7108 assert((CurContext->isDependentContext() || B.builtAll()) && 7109 "omp teams distribute loop exprs were not built"); 7110 7111 getCurFunction()->setHasBranchProtectedScope(); 7112 7113 DSAStack->setParentTeamsRegionLoc(StartLoc); 7114 7115 return OMPTeamsDistributeDirective::Create( 7116 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7117 } 7118 7119 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 7120 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7121 SourceLocation EndLoc, 7122 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7123 if (!AStmt) 7124 return StmtError(); 7125 7126 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7127 // 1.2.2 OpenMP Language Terminology 7128 // Structured block - An executable statement with a single entry at the 7129 // top and a single exit at the bottom. 7130 // The point of exit cannot be a branch out of the structured block. 7131 // longjmp() and throw() must not violate the entry/exit criteria. 7132 CS->getCapturedDecl()->setNothrow(); 7133 for (int ThisCaptureLevel = 7134 getOpenMPCaptureLevels(OMPD_teams_distribute_simd); 7135 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7136 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7137 // 1.2.2 OpenMP Language Terminology 7138 // Structured block - An executable statement with a single entry at the 7139 // top and a single exit at the bottom. 7140 // The point of exit cannot be a branch out of the structured block. 7141 // longjmp() and throw() must not violate the entry/exit criteria. 7142 CS->getCapturedDecl()->setNothrow(); 7143 } 7144 7145 7146 OMPLoopDirective::HelperExprs B; 7147 // In presence of clause 'collapse' with number of loops, it will 7148 // define the nested loops number. 7149 unsigned NestedLoopCount = CheckOpenMPLoop( 7150 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 7151 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7152 VarsWithImplicitDSA, B); 7153 7154 if (NestedLoopCount == 0) 7155 return StmtError(); 7156 7157 assert((CurContext->isDependentContext() || B.builtAll()) && 7158 "omp teams distribute simd loop exprs were not built"); 7159 7160 if (!CurContext->isDependentContext()) { 7161 // Finalize the clauses that need pre-built expressions for CodeGen. 7162 for (auto C : Clauses) { 7163 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7164 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7165 B.NumIterations, *this, CurScope, 7166 DSAStack)) 7167 return StmtError(); 7168 } 7169 } 7170 7171 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7172 return StmtError(); 7173 7174 getCurFunction()->setHasBranchProtectedScope(); 7175 7176 DSAStack->setParentTeamsRegionLoc(StartLoc); 7177 7178 return OMPTeamsDistributeSimdDirective::Create( 7179 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7180 } 7181 7182 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 7183 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7184 SourceLocation EndLoc, 7185 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7186 if (!AStmt) 7187 return StmtError(); 7188 7189 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7190 // 1.2.2 OpenMP Language Terminology 7191 // Structured block - An executable statement with a single entry at the 7192 // top and a single exit at the bottom. 7193 // The point of exit cannot be a branch out of the structured block. 7194 // longjmp() and throw() must not violate the entry/exit criteria. 7195 CS->getCapturedDecl()->setNothrow(); 7196 7197 for (int ThisCaptureLevel = 7198 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for_simd); 7199 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7200 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7201 // 1.2.2 OpenMP Language Terminology 7202 // Structured block - An executable statement with a single entry at the 7203 // top and a single exit at the bottom. 7204 // The point of exit cannot be a branch out of the structured block. 7205 // longjmp() and throw() must not violate the entry/exit criteria. 7206 CS->getCapturedDecl()->setNothrow(); 7207 } 7208 7209 OMPLoopDirective::HelperExprs B; 7210 // In presence of clause 'collapse' with number of loops, it will 7211 // define the nested loops number. 7212 auto NestedLoopCount = CheckOpenMPLoop( 7213 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 7214 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7215 VarsWithImplicitDSA, B); 7216 7217 if (NestedLoopCount == 0) 7218 return StmtError(); 7219 7220 assert((CurContext->isDependentContext() || B.builtAll()) && 7221 "omp for loop exprs were not built"); 7222 7223 if (!CurContext->isDependentContext()) { 7224 // Finalize the clauses that need pre-built expressions for CodeGen. 7225 for (auto C : Clauses) { 7226 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7227 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7228 B.NumIterations, *this, CurScope, 7229 DSAStack)) 7230 return StmtError(); 7231 } 7232 } 7233 7234 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7235 return StmtError(); 7236 7237 getCurFunction()->setHasBranchProtectedScope(); 7238 7239 DSAStack->setParentTeamsRegionLoc(StartLoc); 7240 7241 return OMPTeamsDistributeParallelForSimdDirective::Create( 7242 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7243 } 7244 7245 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 7246 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7247 SourceLocation EndLoc, 7248 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7249 if (!AStmt) 7250 return StmtError(); 7251 7252 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7253 // 1.2.2 OpenMP Language Terminology 7254 // Structured block - An executable statement with a single entry at the 7255 // top and a single exit at the bottom. 7256 // The point of exit cannot be a branch out of the structured block. 7257 // longjmp() and throw() must not violate the entry/exit criteria. 7258 CS->getCapturedDecl()->setNothrow(); 7259 7260 for (int ThisCaptureLevel = 7261 getOpenMPCaptureLevels(OMPD_teams_distribute_parallel_for); 7262 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7263 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7264 // 1.2.2 OpenMP Language Terminology 7265 // Structured block - An executable statement with a single entry at the 7266 // top and a single exit at the bottom. 7267 // The point of exit cannot be a branch out of the structured block. 7268 // longjmp() and throw() must not violate the entry/exit criteria. 7269 CS->getCapturedDecl()->setNothrow(); 7270 } 7271 7272 OMPLoopDirective::HelperExprs B; 7273 // In presence of clause 'collapse' with number of loops, it will 7274 // define the nested loops number. 7275 unsigned NestedLoopCount = CheckOpenMPLoop( 7276 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 7277 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7278 VarsWithImplicitDSA, B); 7279 7280 if (NestedLoopCount == 0) 7281 return StmtError(); 7282 7283 assert((CurContext->isDependentContext() || B.builtAll()) && 7284 "omp for loop exprs were not built"); 7285 7286 getCurFunction()->setHasBranchProtectedScope(); 7287 7288 DSAStack->setParentTeamsRegionLoc(StartLoc); 7289 7290 return OMPTeamsDistributeParallelForDirective::Create( 7291 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 7292 DSAStack->isCancelRegion()); 7293 } 7294 7295 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 7296 Stmt *AStmt, 7297 SourceLocation StartLoc, 7298 SourceLocation EndLoc) { 7299 if (!AStmt) 7300 return StmtError(); 7301 7302 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7303 // 1.2.2 OpenMP Language Terminology 7304 // Structured block - An executable statement with a single entry at the 7305 // top and a single exit at the bottom. 7306 // The point of exit cannot be a branch out of the structured block. 7307 // longjmp() and throw() must not violate the entry/exit criteria. 7308 CS->getCapturedDecl()->setNothrow(); 7309 7310 for (int ThisCaptureLevel = getOpenMPCaptureLevels(OMPD_target_teams); 7311 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7312 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7313 // 1.2.2 OpenMP Language Terminology 7314 // Structured block - An executable statement with a single entry at the 7315 // top and a single exit at the bottom. 7316 // The point of exit cannot be a branch out of the structured block. 7317 // longjmp() and throw() must not violate the entry/exit criteria. 7318 CS->getCapturedDecl()->setNothrow(); 7319 } 7320 getCurFunction()->setHasBranchProtectedScope(); 7321 7322 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 7323 AStmt); 7324 } 7325 7326 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 7327 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7328 SourceLocation EndLoc, 7329 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7330 if (!AStmt) 7331 return StmtError(); 7332 7333 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7334 // 1.2.2 OpenMP Language Terminology 7335 // Structured block - An executable statement with a single entry at the 7336 // top and a single exit at the bottom. 7337 // The point of exit cannot be a branch out of the structured block. 7338 // longjmp() and throw() must not violate the entry/exit criteria. 7339 CS->getCapturedDecl()->setNothrow(); 7340 for (int ThisCaptureLevel = 7341 getOpenMPCaptureLevels(OMPD_target_teams_distribute); 7342 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7343 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7344 // 1.2.2 OpenMP Language Terminology 7345 // Structured block - An executable statement with a single entry at the 7346 // top and a single exit at the bottom. 7347 // The point of exit cannot be a branch out of the structured block. 7348 // longjmp() and throw() must not violate the entry/exit criteria. 7349 CS->getCapturedDecl()->setNothrow(); 7350 } 7351 7352 OMPLoopDirective::HelperExprs B; 7353 // In presence of clause 'collapse' with number of loops, it will 7354 // define the nested loops number. 7355 auto NestedLoopCount = CheckOpenMPLoop( 7356 OMPD_target_teams_distribute, getCollapseNumberExpr(Clauses), 7357 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7358 VarsWithImplicitDSA, B); 7359 if (NestedLoopCount == 0) 7360 return StmtError(); 7361 7362 assert((CurContext->isDependentContext() || B.builtAll()) && 7363 "omp target teams distribute loop exprs were not built"); 7364 7365 getCurFunction()->setHasBranchProtectedScope(); 7366 return OMPTargetTeamsDistributeDirective::Create( 7367 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7368 } 7369 7370 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 7371 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7372 SourceLocation EndLoc, 7373 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7374 if (!AStmt) 7375 return StmtError(); 7376 7377 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7378 // 1.2.2 OpenMP Language Terminology 7379 // Structured block - An executable statement with a single entry at the 7380 // top and a single exit at the bottom. 7381 // The point of exit cannot be a branch out of the structured block. 7382 // longjmp() and throw() must not violate the entry/exit criteria. 7383 CS->getCapturedDecl()->setNothrow(); 7384 7385 OMPLoopDirective::HelperExprs B; 7386 // In presence of clause 'collapse' with number of loops, it will 7387 // define the nested loops number. 7388 auto NestedLoopCount = CheckOpenMPLoop( 7389 OMPD_target_teams_distribute_parallel_for, 7390 getCollapseNumberExpr(Clauses), 7391 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 7392 VarsWithImplicitDSA, B); 7393 if (NestedLoopCount == 0) 7394 return StmtError(); 7395 7396 assert((CurContext->isDependentContext() || B.builtAll()) && 7397 "omp target teams distribute parallel for loop exprs were not built"); 7398 7399 getCurFunction()->setHasBranchProtectedScope(); 7400 return OMPTargetTeamsDistributeParallelForDirective::Create( 7401 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B, 7402 DSAStack->isCancelRegion()); 7403 } 7404 7405 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 7406 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7407 SourceLocation EndLoc, 7408 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7409 if (!AStmt) 7410 return StmtError(); 7411 7412 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7413 // 1.2.2 OpenMP Language Terminology 7414 // Structured block - An executable statement with a single entry at the 7415 // top and a single exit at the bottom. 7416 // The point of exit cannot be a branch out of the structured block. 7417 // longjmp() and throw() must not violate the entry/exit criteria. 7418 CS->getCapturedDecl()->setNothrow(); 7419 7420 OMPLoopDirective::HelperExprs B; 7421 // In presence of clause 'collapse' with number of loops, it will 7422 // define the nested loops number. 7423 auto NestedLoopCount = CheckOpenMPLoop( 7424 OMPD_target_teams_distribute_parallel_for_simd, 7425 getCollapseNumberExpr(Clauses), 7426 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 7427 VarsWithImplicitDSA, B); 7428 if (NestedLoopCount == 0) 7429 return StmtError(); 7430 7431 assert((CurContext->isDependentContext() || B.builtAll()) && 7432 "omp target teams distribute parallel for simd loop exprs were not " 7433 "built"); 7434 7435 if (!CurContext->isDependentContext()) { 7436 // Finalize the clauses that need pre-built expressions for CodeGen. 7437 for (auto C : Clauses) { 7438 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7439 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7440 B.NumIterations, *this, CurScope, 7441 DSAStack)) 7442 return StmtError(); 7443 } 7444 } 7445 7446 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7447 return StmtError(); 7448 7449 getCurFunction()->setHasBranchProtectedScope(); 7450 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 7451 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7452 } 7453 7454 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 7455 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7456 SourceLocation EndLoc, 7457 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7458 if (!AStmt) 7459 return StmtError(); 7460 7461 auto *CS = cast<CapturedStmt>(AStmt); 7462 // 1.2.2 OpenMP Language Terminology 7463 // Structured block - An executable statement with a single entry at the 7464 // top and a single exit at the bottom. 7465 // The point of exit cannot be a branch out of the structured block. 7466 // longjmp() and throw() must not violate the entry/exit criteria. 7467 CS->getCapturedDecl()->setNothrow(); 7468 for (int ThisCaptureLevel = 7469 getOpenMPCaptureLevels(OMPD_target_teams_distribute_simd); 7470 ThisCaptureLevel > 1; --ThisCaptureLevel) { 7471 CS = cast<CapturedStmt>(CS->getCapturedStmt()); 7472 // 1.2.2 OpenMP Language Terminology 7473 // Structured block - An executable statement with a single entry at the 7474 // top and a single exit at the bottom. 7475 // The point of exit cannot be a branch out of the structured block. 7476 // longjmp() and throw() must not violate the entry/exit criteria. 7477 CS->getCapturedDecl()->setNothrow(); 7478 } 7479 7480 OMPLoopDirective::HelperExprs B; 7481 // In presence of clause 'collapse' with number of loops, it will 7482 // define the nested loops number. 7483 auto NestedLoopCount = CheckOpenMPLoop( 7484 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 7485 nullptr /*ordered not a clause on distribute*/, CS, *this, *DSAStack, 7486 VarsWithImplicitDSA, B); 7487 if (NestedLoopCount == 0) 7488 return StmtError(); 7489 7490 assert((CurContext->isDependentContext() || B.builtAll()) && 7491 "omp target teams distribute simd loop exprs were not built"); 7492 7493 if (!CurContext->isDependentContext()) { 7494 // Finalize the clauses that need pre-built expressions for CodeGen. 7495 for (auto C : Clauses) { 7496 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7497 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7498 B.NumIterations, *this, CurScope, 7499 DSAStack)) 7500 return StmtError(); 7501 } 7502 } 7503 7504 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7505 return StmtError(); 7506 7507 getCurFunction()->setHasBranchProtectedScope(); 7508 return OMPTargetTeamsDistributeSimdDirective::Create( 7509 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7510 } 7511 7512 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 7513 SourceLocation StartLoc, 7514 SourceLocation LParenLoc, 7515 SourceLocation EndLoc) { 7516 OMPClause *Res = nullptr; 7517 switch (Kind) { 7518 case OMPC_final: 7519 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 7520 break; 7521 case OMPC_num_threads: 7522 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 7523 break; 7524 case OMPC_safelen: 7525 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 7526 break; 7527 case OMPC_simdlen: 7528 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 7529 break; 7530 case OMPC_collapse: 7531 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 7532 break; 7533 case OMPC_ordered: 7534 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 7535 break; 7536 case OMPC_device: 7537 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 7538 break; 7539 case OMPC_num_teams: 7540 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 7541 break; 7542 case OMPC_thread_limit: 7543 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 7544 break; 7545 case OMPC_priority: 7546 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 7547 break; 7548 case OMPC_grainsize: 7549 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 7550 break; 7551 case OMPC_num_tasks: 7552 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 7553 break; 7554 case OMPC_hint: 7555 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 7556 break; 7557 case OMPC_if: 7558 case OMPC_default: 7559 case OMPC_proc_bind: 7560 case OMPC_schedule: 7561 case OMPC_private: 7562 case OMPC_firstprivate: 7563 case OMPC_lastprivate: 7564 case OMPC_shared: 7565 case OMPC_reduction: 7566 case OMPC_task_reduction: 7567 case OMPC_in_reduction: 7568 case OMPC_linear: 7569 case OMPC_aligned: 7570 case OMPC_copyin: 7571 case OMPC_copyprivate: 7572 case OMPC_nowait: 7573 case OMPC_untied: 7574 case OMPC_mergeable: 7575 case OMPC_threadprivate: 7576 case OMPC_flush: 7577 case OMPC_read: 7578 case OMPC_write: 7579 case OMPC_update: 7580 case OMPC_capture: 7581 case OMPC_seq_cst: 7582 case OMPC_depend: 7583 case OMPC_threads: 7584 case OMPC_simd: 7585 case OMPC_map: 7586 case OMPC_nogroup: 7587 case OMPC_dist_schedule: 7588 case OMPC_defaultmap: 7589 case OMPC_unknown: 7590 case OMPC_uniform: 7591 case OMPC_to: 7592 case OMPC_from: 7593 case OMPC_use_device_ptr: 7594 case OMPC_is_device_ptr: 7595 llvm_unreachable("Clause is not allowed."); 7596 } 7597 return Res; 7598 } 7599 7600 // An OpenMP directive such as 'target parallel' has two captured regions: 7601 // for the 'target' and 'parallel' respectively. This function returns 7602 // the region in which to capture expressions associated with a clause. 7603 // A return value of OMPD_unknown signifies that the expression should not 7604 // be captured. 7605 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 7606 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 7607 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 7608 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 7609 switch (CKind) { 7610 case OMPC_if: 7611 switch (DKind) { 7612 case OMPD_target_parallel: 7613 case OMPD_target_parallel_for: 7614 case OMPD_target_parallel_for_simd: 7615 case OMPD_target_teams_distribute_parallel_for: 7616 case OMPD_target_teams_distribute_parallel_for_simd: 7617 // If this clause applies to the nested 'parallel' region, capture within 7618 // the 'target' region, otherwise do not capture. 7619 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 7620 CaptureRegion = OMPD_target; 7621 break; 7622 case OMPD_teams_distribute_parallel_for: 7623 case OMPD_teams_distribute_parallel_for_simd: 7624 CaptureRegion = OMPD_teams; 7625 break; 7626 case OMPD_target_update: 7627 case OMPD_target_enter_data: 7628 case OMPD_target_exit_data: 7629 CaptureRegion = OMPD_task; 7630 break; 7631 case OMPD_cancel: 7632 case OMPD_parallel: 7633 case OMPD_parallel_sections: 7634 case OMPD_parallel_for: 7635 case OMPD_parallel_for_simd: 7636 case OMPD_target: 7637 case OMPD_target_simd: 7638 case OMPD_target_teams: 7639 case OMPD_target_teams_distribute: 7640 case OMPD_target_teams_distribute_simd: 7641 case OMPD_distribute_parallel_for: 7642 case OMPD_distribute_parallel_for_simd: 7643 case OMPD_task: 7644 case OMPD_taskloop: 7645 case OMPD_taskloop_simd: 7646 case OMPD_target_data: 7647 // Do not capture if-clause expressions. 7648 break; 7649 case OMPD_threadprivate: 7650 case OMPD_taskyield: 7651 case OMPD_barrier: 7652 case OMPD_taskwait: 7653 case OMPD_cancellation_point: 7654 case OMPD_flush: 7655 case OMPD_declare_reduction: 7656 case OMPD_declare_simd: 7657 case OMPD_declare_target: 7658 case OMPD_end_declare_target: 7659 case OMPD_teams: 7660 case OMPD_simd: 7661 case OMPD_for: 7662 case OMPD_for_simd: 7663 case OMPD_sections: 7664 case OMPD_section: 7665 case OMPD_single: 7666 case OMPD_master: 7667 case OMPD_critical: 7668 case OMPD_taskgroup: 7669 case OMPD_distribute: 7670 case OMPD_ordered: 7671 case OMPD_atomic: 7672 case OMPD_distribute_simd: 7673 case OMPD_teams_distribute: 7674 case OMPD_teams_distribute_simd: 7675 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 7676 case OMPD_unknown: 7677 llvm_unreachable("Unknown OpenMP directive"); 7678 } 7679 break; 7680 case OMPC_num_threads: 7681 switch (DKind) { 7682 case OMPD_target_parallel: 7683 case OMPD_target_parallel_for: 7684 case OMPD_target_parallel_for_simd: 7685 case OMPD_target_teams_distribute_parallel_for: 7686 case OMPD_target_teams_distribute_parallel_for_simd: 7687 CaptureRegion = OMPD_target; 7688 break; 7689 case OMPD_teams_distribute_parallel_for: 7690 case OMPD_teams_distribute_parallel_for_simd: 7691 CaptureRegion = OMPD_teams; 7692 break; 7693 case OMPD_parallel: 7694 case OMPD_parallel_sections: 7695 case OMPD_parallel_for: 7696 case OMPD_parallel_for_simd: 7697 case OMPD_distribute_parallel_for: 7698 case OMPD_distribute_parallel_for_simd: 7699 // Do not capture num_threads-clause expressions. 7700 break; 7701 case OMPD_target_data: 7702 case OMPD_target_enter_data: 7703 case OMPD_target_exit_data: 7704 case OMPD_target_update: 7705 case OMPD_target: 7706 case OMPD_target_simd: 7707 case OMPD_target_teams: 7708 case OMPD_target_teams_distribute: 7709 case OMPD_target_teams_distribute_simd: 7710 case OMPD_cancel: 7711 case OMPD_task: 7712 case OMPD_taskloop: 7713 case OMPD_taskloop_simd: 7714 case OMPD_threadprivate: 7715 case OMPD_taskyield: 7716 case OMPD_barrier: 7717 case OMPD_taskwait: 7718 case OMPD_cancellation_point: 7719 case OMPD_flush: 7720 case OMPD_declare_reduction: 7721 case OMPD_declare_simd: 7722 case OMPD_declare_target: 7723 case OMPD_end_declare_target: 7724 case OMPD_teams: 7725 case OMPD_simd: 7726 case OMPD_for: 7727 case OMPD_for_simd: 7728 case OMPD_sections: 7729 case OMPD_section: 7730 case OMPD_single: 7731 case OMPD_master: 7732 case OMPD_critical: 7733 case OMPD_taskgroup: 7734 case OMPD_distribute: 7735 case OMPD_ordered: 7736 case OMPD_atomic: 7737 case OMPD_distribute_simd: 7738 case OMPD_teams_distribute: 7739 case OMPD_teams_distribute_simd: 7740 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 7741 case OMPD_unknown: 7742 llvm_unreachable("Unknown OpenMP directive"); 7743 } 7744 break; 7745 case OMPC_num_teams: 7746 switch (DKind) { 7747 case OMPD_target_teams: 7748 case OMPD_target_teams_distribute: 7749 case OMPD_target_teams_distribute_simd: 7750 case OMPD_target_teams_distribute_parallel_for: 7751 case OMPD_target_teams_distribute_parallel_for_simd: 7752 CaptureRegion = OMPD_target; 7753 break; 7754 case OMPD_teams_distribute_parallel_for: 7755 case OMPD_teams_distribute_parallel_for_simd: 7756 case OMPD_teams: 7757 case OMPD_teams_distribute: 7758 case OMPD_teams_distribute_simd: 7759 // Do not capture num_teams-clause expressions. 7760 break; 7761 case OMPD_distribute_parallel_for: 7762 case OMPD_distribute_parallel_for_simd: 7763 case OMPD_task: 7764 case OMPD_taskloop: 7765 case OMPD_taskloop_simd: 7766 case OMPD_target_data: 7767 case OMPD_target_enter_data: 7768 case OMPD_target_exit_data: 7769 case OMPD_target_update: 7770 case OMPD_cancel: 7771 case OMPD_parallel: 7772 case OMPD_parallel_sections: 7773 case OMPD_parallel_for: 7774 case OMPD_parallel_for_simd: 7775 case OMPD_target: 7776 case OMPD_target_simd: 7777 case OMPD_target_parallel: 7778 case OMPD_target_parallel_for: 7779 case OMPD_target_parallel_for_simd: 7780 case OMPD_threadprivate: 7781 case OMPD_taskyield: 7782 case OMPD_barrier: 7783 case OMPD_taskwait: 7784 case OMPD_cancellation_point: 7785 case OMPD_flush: 7786 case OMPD_declare_reduction: 7787 case OMPD_declare_simd: 7788 case OMPD_declare_target: 7789 case OMPD_end_declare_target: 7790 case OMPD_simd: 7791 case OMPD_for: 7792 case OMPD_for_simd: 7793 case OMPD_sections: 7794 case OMPD_section: 7795 case OMPD_single: 7796 case OMPD_master: 7797 case OMPD_critical: 7798 case OMPD_taskgroup: 7799 case OMPD_distribute: 7800 case OMPD_ordered: 7801 case OMPD_atomic: 7802 case OMPD_distribute_simd: 7803 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 7804 case OMPD_unknown: 7805 llvm_unreachable("Unknown OpenMP directive"); 7806 } 7807 break; 7808 case OMPC_thread_limit: 7809 switch (DKind) { 7810 case OMPD_target_teams: 7811 case OMPD_target_teams_distribute: 7812 case OMPD_target_teams_distribute_simd: 7813 case OMPD_target_teams_distribute_parallel_for: 7814 case OMPD_target_teams_distribute_parallel_for_simd: 7815 CaptureRegion = OMPD_target; 7816 break; 7817 case OMPD_teams_distribute_parallel_for: 7818 case OMPD_teams_distribute_parallel_for_simd: 7819 case OMPD_teams: 7820 case OMPD_teams_distribute: 7821 case OMPD_teams_distribute_simd: 7822 // Do not capture thread_limit-clause expressions. 7823 break; 7824 case OMPD_distribute_parallel_for: 7825 case OMPD_distribute_parallel_for_simd: 7826 case OMPD_task: 7827 case OMPD_taskloop: 7828 case OMPD_taskloop_simd: 7829 case OMPD_target_data: 7830 case OMPD_target_enter_data: 7831 case OMPD_target_exit_data: 7832 case OMPD_target_update: 7833 case OMPD_cancel: 7834 case OMPD_parallel: 7835 case OMPD_parallel_sections: 7836 case OMPD_parallel_for: 7837 case OMPD_parallel_for_simd: 7838 case OMPD_target: 7839 case OMPD_target_simd: 7840 case OMPD_target_parallel: 7841 case OMPD_target_parallel_for: 7842 case OMPD_target_parallel_for_simd: 7843 case OMPD_threadprivate: 7844 case OMPD_taskyield: 7845 case OMPD_barrier: 7846 case OMPD_taskwait: 7847 case OMPD_cancellation_point: 7848 case OMPD_flush: 7849 case OMPD_declare_reduction: 7850 case OMPD_declare_simd: 7851 case OMPD_declare_target: 7852 case OMPD_end_declare_target: 7853 case OMPD_simd: 7854 case OMPD_for: 7855 case OMPD_for_simd: 7856 case OMPD_sections: 7857 case OMPD_section: 7858 case OMPD_single: 7859 case OMPD_master: 7860 case OMPD_critical: 7861 case OMPD_taskgroup: 7862 case OMPD_distribute: 7863 case OMPD_ordered: 7864 case OMPD_atomic: 7865 case OMPD_distribute_simd: 7866 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 7867 case OMPD_unknown: 7868 llvm_unreachable("Unknown OpenMP directive"); 7869 } 7870 break; 7871 case OMPC_schedule: 7872 switch (DKind) { 7873 case OMPD_target_parallel_for: 7874 case OMPD_target_parallel_for_simd: 7875 case OMPD_target_teams_distribute_parallel_for: 7876 case OMPD_target_teams_distribute_parallel_for_simd: 7877 CaptureRegion = OMPD_target; 7878 break; 7879 case OMPD_teams_distribute_parallel_for: 7880 case OMPD_teams_distribute_parallel_for_simd: 7881 CaptureRegion = OMPD_teams; 7882 break; 7883 case OMPD_parallel_for: 7884 case OMPD_parallel_for_simd: 7885 case OMPD_distribute_parallel_for: 7886 case OMPD_distribute_parallel_for_simd: 7887 CaptureRegion = OMPD_parallel; 7888 break; 7889 case OMPD_for: 7890 case OMPD_for_simd: 7891 // Do not capture schedule-clause expressions. 7892 break; 7893 case OMPD_task: 7894 case OMPD_taskloop: 7895 case OMPD_taskloop_simd: 7896 case OMPD_target_data: 7897 case OMPD_target_enter_data: 7898 case OMPD_target_exit_data: 7899 case OMPD_target_update: 7900 case OMPD_teams: 7901 case OMPD_teams_distribute: 7902 case OMPD_teams_distribute_simd: 7903 case OMPD_target_teams_distribute: 7904 case OMPD_target_teams_distribute_simd: 7905 case OMPD_target: 7906 case OMPD_target_simd: 7907 case OMPD_target_parallel: 7908 case OMPD_cancel: 7909 case OMPD_parallel: 7910 case OMPD_parallel_sections: 7911 case OMPD_threadprivate: 7912 case OMPD_taskyield: 7913 case OMPD_barrier: 7914 case OMPD_taskwait: 7915 case OMPD_cancellation_point: 7916 case OMPD_flush: 7917 case OMPD_declare_reduction: 7918 case OMPD_declare_simd: 7919 case OMPD_declare_target: 7920 case OMPD_end_declare_target: 7921 case OMPD_simd: 7922 case OMPD_sections: 7923 case OMPD_section: 7924 case OMPD_single: 7925 case OMPD_master: 7926 case OMPD_critical: 7927 case OMPD_taskgroup: 7928 case OMPD_distribute: 7929 case OMPD_ordered: 7930 case OMPD_atomic: 7931 case OMPD_distribute_simd: 7932 case OMPD_target_teams: 7933 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 7934 case OMPD_unknown: 7935 llvm_unreachable("Unknown OpenMP directive"); 7936 } 7937 break; 7938 case OMPC_dist_schedule: 7939 switch (DKind) { 7940 case OMPD_teams_distribute_parallel_for: 7941 case OMPD_teams_distribute_parallel_for_simd: 7942 case OMPD_teams_distribute: 7943 case OMPD_teams_distribute_simd: 7944 CaptureRegion = OMPD_teams; 7945 break; 7946 case OMPD_target_teams_distribute_parallel_for: 7947 case OMPD_target_teams_distribute_parallel_for_simd: 7948 case OMPD_target_teams_distribute: 7949 case OMPD_target_teams_distribute_simd: 7950 CaptureRegion = OMPD_target; 7951 break; 7952 case OMPD_distribute_parallel_for: 7953 case OMPD_distribute_parallel_for_simd: 7954 CaptureRegion = OMPD_parallel; 7955 break; 7956 case OMPD_distribute: 7957 case OMPD_distribute_simd: 7958 // Do not capture thread_limit-clause expressions. 7959 break; 7960 case OMPD_parallel_for: 7961 case OMPD_parallel_for_simd: 7962 case OMPD_target_parallel_for_simd: 7963 case OMPD_target_parallel_for: 7964 case OMPD_task: 7965 case OMPD_taskloop: 7966 case OMPD_taskloop_simd: 7967 case OMPD_target_data: 7968 case OMPD_target_enter_data: 7969 case OMPD_target_exit_data: 7970 case OMPD_target_update: 7971 case OMPD_teams: 7972 case OMPD_target: 7973 case OMPD_target_simd: 7974 case OMPD_target_parallel: 7975 case OMPD_cancel: 7976 case OMPD_parallel: 7977 case OMPD_parallel_sections: 7978 case OMPD_threadprivate: 7979 case OMPD_taskyield: 7980 case OMPD_barrier: 7981 case OMPD_taskwait: 7982 case OMPD_cancellation_point: 7983 case OMPD_flush: 7984 case OMPD_declare_reduction: 7985 case OMPD_declare_simd: 7986 case OMPD_declare_target: 7987 case OMPD_end_declare_target: 7988 case OMPD_simd: 7989 case OMPD_for: 7990 case OMPD_for_simd: 7991 case OMPD_sections: 7992 case OMPD_section: 7993 case OMPD_single: 7994 case OMPD_master: 7995 case OMPD_critical: 7996 case OMPD_taskgroup: 7997 case OMPD_ordered: 7998 case OMPD_atomic: 7999 case OMPD_target_teams: 8000 llvm_unreachable("Unexpected OpenMP directive with schedule clause"); 8001 case OMPD_unknown: 8002 llvm_unreachable("Unknown OpenMP directive"); 8003 } 8004 break; 8005 case OMPC_device: 8006 switch (DKind) { 8007 case OMPD_target_update: 8008 case OMPD_target_enter_data: 8009 case OMPD_target_exit_data: 8010 CaptureRegion = OMPD_task; 8011 break; 8012 case OMPD_target_teams: 8013 case OMPD_target_teams_distribute: 8014 case OMPD_target_teams_distribute_simd: 8015 case OMPD_target_teams_distribute_parallel_for: 8016 case OMPD_target_teams_distribute_parallel_for_simd: 8017 case OMPD_target_data: 8018 case OMPD_target: 8019 case OMPD_target_simd: 8020 case OMPD_target_parallel: 8021 case OMPD_target_parallel_for: 8022 case OMPD_target_parallel_for_simd: 8023 // Do not capture device-clause expressions. 8024 break; 8025 case OMPD_teams_distribute_parallel_for: 8026 case OMPD_teams_distribute_parallel_for_simd: 8027 case OMPD_teams: 8028 case OMPD_teams_distribute: 8029 case OMPD_teams_distribute_simd: 8030 case OMPD_distribute_parallel_for: 8031 case OMPD_distribute_parallel_for_simd: 8032 case OMPD_task: 8033 case OMPD_taskloop: 8034 case OMPD_taskloop_simd: 8035 case OMPD_cancel: 8036 case OMPD_parallel: 8037 case OMPD_parallel_sections: 8038 case OMPD_parallel_for: 8039 case OMPD_parallel_for_simd: 8040 case OMPD_threadprivate: 8041 case OMPD_taskyield: 8042 case OMPD_barrier: 8043 case OMPD_taskwait: 8044 case OMPD_cancellation_point: 8045 case OMPD_flush: 8046 case OMPD_declare_reduction: 8047 case OMPD_declare_simd: 8048 case OMPD_declare_target: 8049 case OMPD_end_declare_target: 8050 case OMPD_simd: 8051 case OMPD_for: 8052 case OMPD_for_simd: 8053 case OMPD_sections: 8054 case OMPD_section: 8055 case OMPD_single: 8056 case OMPD_master: 8057 case OMPD_critical: 8058 case OMPD_taskgroup: 8059 case OMPD_distribute: 8060 case OMPD_ordered: 8061 case OMPD_atomic: 8062 case OMPD_distribute_simd: 8063 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 8064 case OMPD_unknown: 8065 llvm_unreachable("Unknown OpenMP directive"); 8066 } 8067 break; 8068 case OMPC_firstprivate: 8069 case OMPC_lastprivate: 8070 case OMPC_reduction: 8071 case OMPC_task_reduction: 8072 case OMPC_in_reduction: 8073 case OMPC_linear: 8074 case OMPC_default: 8075 case OMPC_proc_bind: 8076 case OMPC_final: 8077 case OMPC_safelen: 8078 case OMPC_simdlen: 8079 case OMPC_collapse: 8080 case OMPC_private: 8081 case OMPC_shared: 8082 case OMPC_aligned: 8083 case OMPC_copyin: 8084 case OMPC_copyprivate: 8085 case OMPC_ordered: 8086 case OMPC_nowait: 8087 case OMPC_untied: 8088 case OMPC_mergeable: 8089 case OMPC_threadprivate: 8090 case OMPC_flush: 8091 case OMPC_read: 8092 case OMPC_write: 8093 case OMPC_update: 8094 case OMPC_capture: 8095 case OMPC_seq_cst: 8096 case OMPC_depend: 8097 case OMPC_threads: 8098 case OMPC_simd: 8099 case OMPC_map: 8100 case OMPC_priority: 8101 case OMPC_grainsize: 8102 case OMPC_nogroup: 8103 case OMPC_num_tasks: 8104 case OMPC_hint: 8105 case OMPC_defaultmap: 8106 case OMPC_unknown: 8107 case OMPC_uniform: 8108 case OMPC_to: 8109 case OMPC_from: 8110 case OMPC_use_device_ptr: 8111 case OMPC_is_device_ptr: 8112 llvm_unreachable("Unexpected OpenMP clause."); 8113 } 8114 return CaptureRegion; 8115 } 8116 8117 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 8118 Expr *Condition, SourceLocation StartLoc, 8119 SourceLocation LParenLoc, 8120 SourceLocation NameModifierLoc, 8121 SourceLocation ColonLoc, 8122 SourceLocation EndLoc) { 8123 Expr *ValExpr = Condition; 8124 Stmt *HelperValStmt = nullptr; 8125 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 8126 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 8127 !Condition->isInstantiationDependent() && 8128 !Condition->containsUnexpandedParameterPack()) { 8129 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 8130 if (Val.isInvalid()) 8131 return nullptr; 8132 8133 ValExpr = Val.get(); 8134 8135 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 8136 CaptureRegion = 8137 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 8138 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 8139 ValExpr = MakeFullExpr(ValExpr).get(); 8140 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 8141 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 8142 HelperValStmt = buildPreInits(Context, Captures); 8143 } 8144 } 8145 8146 return new (Context) 8147 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 8148 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 8149 } 8150 8151 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 8152 SourceLocation StartLoc, 8153 SourceLocation LParenLoc, 8154 SourceLocation EndLoc) { 8155 Expr *ValExpr = Condition; 8156 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 8157 !Condition->isInstantiationDependent() && 8158 !Condition->containsUnexpandedParameterPack()) { 8159 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 8160 if (Val.isInvalid()) 8161 return nullptr; 8162 8163 ValExpr = MakeFullExpr(Val.get()).get(); 8164 } 8165 8166 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 8167 } 8168 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 8169 Expr *Op) { 8170 if (!Op) 8171 return ExprError(); 8172 8173 class IntConvertDiagnoser : public ICEConvertDiagnoser { 8174 public: 8175 IntConvertDiagnoser() 8176 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 8177 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 8178 QualType T) override { 8179 return S.Diag(Loc, diag::err_omp_not_integral) << T; 8180 } 8181 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 8182 QualType T) override { 8183 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 8184 } 8185 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 8186 QualType T, 8187 QualType ConvTy) override { 8188 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 8189 } 8190 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 8191 QualType ConvTy) override { 8192 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 8193 << ConvTy->isEnumeralType() << ConvTy; 8194 } 8195 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 8196 QualType T) override { 8197 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 8198 } 8199 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 8200 QualType ConvTy) override { 8201 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 8202 << ConvTy->isEnumeralType() << ConvTy; 8203 } 8204 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 8205 QualType) override { 8206 llvm_unreachable("conversion functions are permitted"); 8207 } 8208 } ConvertDiagnoser; 8209 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 8210 } 8211 8212 static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 8213 OpenMPClauseKind CKind, 8214 bool StrictlyPositive) { 8215 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 8216 !ValExpr->isInstantiationDependent()) { 8217 SourceLocation Loc = ValExpr->getExprLoc(); 8218 ExprResult Value = 8219 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 8220 if (Value.isInvalid()) 8221 return false; 8222 8223 ValExpr = Value.get(); 8224 // The expression must evaluate to a non-negative integer value. 8225 llvm::APSInt Result; 8226 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 8227 Result.isSigned() && 8228 !((!StrictlyPositive && Result.isNonNegative()) || 8229 (StrictlyPositive && Result.isStrictlyPositive()))) { 8230 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 8231 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 8232 << ValExpr->getSourceRange(); 8233 return false; 8234 } 8235 } 8236 return true; 8237 } 8238 8239 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 8240 SourceLocation StartLoc, 8241 SourceLocation LParenLoc, 8242 SourceLocation EndLoc) { 8243 Expr *ValExpr = NumThreads; 8244 Stmt *HelperValStmt = nullptr; 8245 8246 // OpenMP [2.5, Restrictions] 8247 // The num_threads expression must evaluate to a positive integer value. 8248 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 8249 /*StrictlyPositive=*/true)) 8250 return nullptr; 8251 8252 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 8253 OpenMPDirectiveKind CaptureRegion = 8254 getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 8255 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 8256 ValExpr = MakeFullExpr(ValExpr).get(); 8257 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 8258 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 8259 HelperValStmt = buildPreInits(Context, Captures); 8260 } 8261 8262 return new (Context) OMPNumThreadsClause( 8263 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 8264 } 8265 8266 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 8267 OpenMPClauseKind CKind, 8268 bool StrictlyPositive) { 8269 if (!E) 8270 return ExprError(); 8271 if (E->isValueDependent() || E->isTypeDependent() || 8272 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 8273 return E; 8274 llvm::APSInt Result; 8275 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 8276 if (ICE.isInvalid()) 8277 return ExprError(); 8278 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 8279 (!StrictlyPositive && !Result.isNonNegative())) { 8280 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 8281 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 8282 << E->getSourceRange(); 8283 return ExprError(); 8284 } 8285 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 8286 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 8287 << E->getSourceRange(); 8288 return ExprError(); 8289 } 8290 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 8291 DSAStack->setAssociatedLoops(Result.getExtValue()); 8292 else if (CKind == OMPC_ordered) 8293 DSAStack->setAssociatedLoops(Result.getExtValue()); 8294 return ICE; 8295 } 8296 8297 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 8298 SourceLocation LParenLoc, 8299 SourceLocation EndLoc) { 8300 // OpenMP [2.8.1, simd construct, Description] 8301 // The parameter of the safelen clause must be a constant 8302 // positive integer expression. 8303 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 8304 if (Safelen.isInvalid()) 8305 return nullptr; 8306 return new (Context) 8307 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 8308 } 8309 8310 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 8311 SourceLocation LParenLoc, 8312 SourceLocation EndLoc) { 8313 // OpenMP [2.8.1, simd construct, Description] 8314 // The parameter of the simdlen clause must be a constant 8315 // positive integer expression. 8316 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 8317 if (Simdlen.isInvalid()) 8318 return nullptr; 8319 return new (Context) 8320 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 8321 } 8322 8323 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 8324 SourceLocation StartLoc, 8325 SourceLocation LParenLoc, 8326 SourceLocation EndLoc) { 8327 // OpenMP [2.7.1, loop construct, Description] 8328 // OpenMP [2.8.1, simd construct, Description] 8329 // OpenMP [2.9.6, distribute construct, Description] 8330 // The parameter of the collapse clause must be a constant 8331 // positive integer expression. 8332 ExprResult NumForLoopsResult = 8333 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 8334 if (NumForLoopsResult.isInvalid()) 8335 return nullptr; 8336 return new (Context) 8337 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 8338 } 8339 8340 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 8341 SourceLocation EndLoc, 8342 SourceLocation LParenLoc, 8343 Expr *NumForLoops) { 8344 // OpenMP [2.7.1, loop construct, Description] 8345 // OpenMP [2.8.1, simd construct, Description] 8346 // OpenMP [2.9.6, distribute construct, Description] 8347 // The parameter of the ordered clause must be a constant 8348 // positive integer expression if any. 8349 if (NumForLoops && LParenLoc.isValid()) { 8350 ExprResult NumForLoopsResult = 8351 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 8352 if (NumForLoopsResult.isInvalid()) 8353 return nullptr; 8354 NumForLoops = NumForLoopsResult.get(); 8355 } else 8356 NumForLoops = nullptr; 8357 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops); 8358 return new (Context) 8359 OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc); 8360 } 8361 8362 OMPClause *Sema::ActOnOpenMPSimpleClause( 8363 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 8364 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 8365 OMPClause *Res = nullptr; 8366 switch (Kind) { 8367 case OMPC_default: 8368 Res = 8369 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 8370 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 8371 break; 8372 case OMPC_proc_bind: 8373 Res = ActOnOpenMPProcBindClause( 8374 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 8375 LParenLoc, EndLoc); 8376 break; 8377 case OMPC_if: 8378 case OMPC_final: 8379 case OMPC_num_threads: 8380 case OMPC_safelen: 8381 case OMPC_simdlen: 8382 case OMPC_collapse: 8383 case OMPC_schedule: 8384 case OMPC_private: 8385 case OMPC_firstprivate: 8386 case OMPC_lastprivate: 8387 case OMPC_shared: 8388 case OMPC_reduction: 8389 case OMPC_task_reduction: 8390 case OMPC_in_reduction: 8391 case OMPC_linear: 8392 case OMPC_aligned: 8393 case OMPC_copyin: 8394 case OMPC_copyprivate: 8395 case OMPC_ordered: 8396 case OMPC_nowait: 8397 case OMPC_untied: 8398 case OMPC_mergeable: 8399 case OMPC_threadprivate: 8400 case OMPC_flush: 8401 case OMPC_read: 8402 case OMPC_write: 8403 case OMPC_update: 8404 case OMPC_capture: 8405 case OMPC_seq_cst: 8406 case OMPC_depend: 8407 case OMPC_device: 8408 case OMPC_threads: 8409 case OMPC_simd: 8410 case OMPC_map: 8411 case OMPC_num_teams: 8412 case OMPC_thread_limit: 8413 case OMPC_priority: 8414 case OMPC_grainsize: 8415 case OMPC_nogroup: 8416 case OMPC_num_tasks: 8417 case OMPC_hint: 8418 case OMPC_dist_schedule: 8419 case OMPC_defaultmap: 8420 case OMPC_unknown: 8421 case OMPC_uniform: 8422 case OMPC_to: 8423 case OMPC_from: 8424 case OMPC_use_device_ptr: 8425 case OMPC_is_device_ptr: 8426 llvm_unreachable("Clause is not allowed."); 8427 } 8428 return Res; 8429 } 8430 8431 static std::string 8432 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 8433 ArrayRef<unsigned> Exclude = llvm::None) { 8434 std::string Values; 8435 unsigned Bound = Last >= 2 ? Last - 2 : 0; 8436 unsigned Skipped = Exclude.size(); 8437 auto S = Exclude.begin(), E = Exclude.end(); 8438 for (unsigned i = First; i < Last; ++i) { 8439 if (std::find(S, E, i) != E) { 8440 --Skipped; 8441 continue; 8442 } 8443 Values += "'"; 8444 Values += getOpenMPSimpleClauseTypeName(K, i); 8445 Values += "'"; 8446 if (i == Bound - Skipped) 8447 Values += " or "; 8448 else if (i != Bound + 1 - Skipped) 8449 Values += ", "; 8450 } 8451 return Values; 8452 } 8453 8454 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 8455 SourceLocation KindKwLoc, 8456 SourceLocation StartLoc, 8457 SourceLocation LParenLoc, 8458 SourceLocation EndLoc) { 8459 if (Kind == OMPC_DEFAULT_unknown) { 8460 static_assert(OMPC_DEFAULT_unknown > 0, 8461 "OMPC_DEFAULT_unknown not greater than 0"); 8462 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 8463 << getListOfPossibleValues(OMPC_default, /*First=*/0, 8464 /*Last=*/OMPC_DEFAULT_unknown) 8465 << getOpenMPClauseName(OMPC_default); 8466 return nullptr; 8467 } 8468 switch (Kind) { 8469 case OMPC_DEFAULT_none: 8470 DSAStack->setDefaultDSANone(KindKwLoc); 8471 break; 8472 case OMPC_DEFAULT_shared: 8473 DSAStack->setDefaultDSAShared(KindKwLoc); 8474 break; 8475 case OMPC_DEFAULT_unknown: 8476 llvm_unreachable("Clause kind is not allowed."); 8477 break; 8478 } 8479 return new (Context) 8480 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 8481 } 8482 8483 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 8484 SourceLocation KindKwLoc, 8485 SourceLocation StartLoc, 8486 SourceLocation LParenLoc, 8487 SourceLocation EndLoc) { 8488 if (Kind == OMPC_PROC_BIND_unknown) { 8489 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 8490 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 8491 /*Last=*/OMPC_PROC_BIND_unknown) 8492 << getOpenMPClauseName(OMPC_proc_bind); 8493 return nullptr; 8494 } 8495 return new (Context) 8496 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 8497 } 8498 8499 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 8500 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 8501 SourceLocation StartLoc, SourceLocation LParenLoc, 8502 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 8503 SourceLocation EndLoc) { 8504 OMPClause *Res = nullptr; 8505 switch (Kind) { 8506 case OMPC_schedule: 8507 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 8508 assert(Argument.size() == NumberOfElements && 8509 ArgumentLoc.size() == NumberOfElements); 8510 Res = ActOnOpenMPScheduleClause( 8511 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 8512 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 8513 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 8514 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 8515 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 8516 break; 8517 case OMPC_if: 8518 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 8519 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 8520 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 8521 DelimLoc, EndLoc); 8522 break; 8523 case OMPC_dist_schedule: 8524 Res = ActOnOpenMPDistScheduleClause( 8525 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 8526 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 8527 break; 8528 case OMPC_defaultmap: 8529 enum { Modifier, DefaultmapKind }; 8530 Res = ActOnOpenMPDefaultmapClause( 8531 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 8532 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 8533 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 8534 EndLoc); 8535 break; 8536 case OMPC_final: 8537 case OMPC_num_threads: 8538 case OMPC_safelen: 8539 case OMPC_simdlen: 8540 case OMPC_collapse: 8541 case OMPC_default: 8542 case OMPC_proc_bind: 8543 case OMPC_private: 8544 case OMPC_firstprivate: 8545 case OMPC_lastprivate: 8546 case OMPC_shared: 8547 case OMPC_reduction: 8548 case OMPC_task_reduction: 8549 case OMPC_in_reduction: 8550 case OMPC_linear: 8551 case OMPC_aligned: 8552 case OMPC_copyin: 8553 case OMPC_copyprivate: 8554 case OMPC_ordered: 8555 case OMPC_nowait: 8556 case OMPC_untied: 8557 case OMPC_mergeable: 8558 case OMPC_threadprivate: 8559 case OMPC_flush: 8560 case OMPC_read: 8561 case OMPC_write: 8562 case OMPC_update: 8563 case OMPC_capture: 8564 case OMPC_seq_cst: 8565 case OMPC_depend: 8566 case OMPC_device: 8567 case OMPC_threads: 8568 case OMPC_simd: 8569 case OMPC_map: 8570 case OMPC_num_teams: 8571 case OMPC_thread_limit: 8572 case OMPC_priority: 8573 case OMPC_grainsize: 8574 case OMPC_nogroup: 8575 case OMPC_num_tasks: 8576 case OMPC_hint: 8577 case OMPC_unknown: 8578 case OMPC_uniform: 8579 case OMPC_to: 8580 case OMPC_from: 8581 case OMPC_use_device_ptr: 8582 case OMPC_is_device_ptr: 8583 llvm_unreachable("Clause is not allowed."); 8584 } 8585 return Res; 8586 } 8587 8588 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 8589 OpenMPScheduleClauseModifier M2, 8590 SourceLocation M1Loc, SourceLocation M2Loc) { 8591 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 8592 SmallVector<unsigned, 2> Excluded; 8593 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 8594 Excluded.push_back(M2); 8595 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 8596 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 8597 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 8598 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 8599 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 8600 << getListOfPossibleValues(OMPC_schedule, 8601 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 8602 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 8603 Excluded) 8604 << getOpenMPClauseName(OMPC_schedule); 8605 return true; 8606 } 8607 return false; 8608 } 8609 8610 OMPClause *Sema::ActOnOpenMPScheduleClause( 8611 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 8612 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 8613 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 8614 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 8615 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 8616 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 8617 return nullptr; 8618 // OpenMP, 2.7.1, Loop Construct, Restrictions 8619 // Either the monotonic modifier or the nonmonotonic modifier can be specified 8620 // but not both. 8621 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 8622 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 8623 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 8624 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 8625 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 8626 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 8627 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 8628 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 8629 return nullptr; 8630 } 8631 if (Kind == OMPC_SCHEDULE_unknown) { 8632 std::string Values; 8633 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 8634 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 8635 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 8636 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 8637 Exclude); 8638 } else { 8639 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 8640 /*Last=*/OMPC_SCHEDULE_unknown); 8641 } 8642 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 8643 << Values << getOpenMPClauseName(OMPC_schedule); 8644 return nullptr; 8645 } 8646 // OpenMP, 2.7.1, Loop Construct, Restrictions 8647 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 8648 // schedule(guided). 8649 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 8650 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 8651 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 8652 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 8653 diag::err_omp_schedule_nonmonotonic_static); 8654 return nullptr; 8655 } 8656 Expr *ValExpr = ChunkSize; 8657 Stmt *HelperValStmt = nullptr; 8658 if (ChunkSize) { 8659 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 8660 !ChunkSize->isInstantiationDependent() && 8661 !ChunkSize->containsUnexpandedParameterPack()) { 8662 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 8663 ExprResult Val = 8664 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 8665 if (Val.isInvalid()) 8666 return nullptr; 8667 8668 ValExpr = Val.get(); 8669 8670 // OpenMP [2.7.1, Restrictions] 8671 // chunk_size must be a loop invariant integer expression with a positive 8672 // value. 8673 llvm::APSInt Result; 8674 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 8675 if (Result.isSigned() && !Result.isStrictlyPositive()) { 8676 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 8677 << "schedule" << 1 << ChunkSize->getSourceRange(); 8678 return nullptr; 8679 } 8680 } else if (getOpenMPCaptureRegionForClause( 8681 DSAStack->getCurrentDirective(), OMPC_schedule) != 8682 OMPD_unknown && 8683 !CurContext->isDependentContext()) { 8684 ValExpr = MakeFullExpr(ValExpr).get(); 8685 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 8686 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 8687 HelperValStmt = buildPreInits(Context, Captures); 8688 } 8689 } 8690 } 8691 8692 return new (Context) 8693 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 8694 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 8695 } 8696 8697 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 8698 SourceLocation StartLoc, 8699 SourceLocation EndLoc) { 8700 OMPClause *Res = nullptr; 8701 switch (Kind) { 8702 case OMPC_ordered: 8703 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 8704 break; 8705 case OMPC_nowait: 8706 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 8707 break; 8708 case OMPC_untied: 8709 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 8710 break; 8711 case OMPC_mergeable: 8712 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 8713 break; 8714 case OMPC_read: 8715 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 8716 break; 8717 case OMPC_write: 8718 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 8719 break; 8720 case OMPC_update: 8721 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 8722 break; 8723 case OMPC_capture: 8724 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 8725 break; 8726 case OMPC_seq_cst: 8727 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 8728 break; 8729 case OMPC_threads: 8730 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 8731 break; 8732 case OMPC_simd: 8733 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 8734 break; 8735 case OMPC_nogroup: 8736 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 8737 break; 8738 case OMPC_if: 8739 case OMPC_final: 8740 case OMPC_num_threads: 8741 case OMPC_safelen: 8742 case OMPC_simdlen: 8743 case OMPC_collapse: 8744 case OMPC_schedule: 8745 case OMPC_private: 8746 case OMPC_firstprivate: 8747 case OMPC_lastprivate: 8748 case OMPC_shared: 8749 case OMPC_reduction: 8750 case OMPC_task_reduction: 8751 case OMPC_in_reduction: 8752 case OMPC_linear: 8753 case OMPC_aligned: 8754 case OMPC_copyin: 8755 case OMPC_copyprivate: 8756 case OMPC_default: 8757 case OMPC_proc_bind: 8758 case OMPC_threadprivate: 8759 case OMPC_flush: 8760 case OMPC_depend: 8761 case OMPC_device: 8762 case OMPC_map: 8763 case OMPC_num_teams: 8764 case OMPC_thread_limit: 8765 case OMPC_priority: 8766 case OMPC_grainsize: 8767 case OMPC_num_tasks: 8768 case OMPC_hint: 8769 case OMPC_dist_schedule: 8770 case OMPC_defaultmap: 8771 case OMPC_unknown: 8772 case OMPC_uniform: 8773 case OMPC_to: 8774 case OMPC_from: 8775 case OMPC_use_device_ptr: 8776 case OMPC_is_device_ptr: 8777 llvm_unreachable("Clause is not allowed."); 8778 } 8779 return Res; 8780 } 8781 8782 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 8783 SourceLocation EndLoc) { 8784 DSAStack->setNowaitRegion(); 8785 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 8786 } 8787 8788 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 8789 SourceLocation EndLoc) { 8790 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 8791 } 8792 8793 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 8794 SourceLocation EndLoc) { 8795 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 8796 } 8797 8798 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 8799 SourceLocation EndLoc) { 8800 return new (Context) OMPReadClause(StartLoc, EndLoc); 8801 } 8802 8803 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 8804 SourceLocation EndLoc) { 8805 return new (Context) OMPWriteClause(StartLoc, EndLoc); 8806 } 8807 8808 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 8809 SourceLocation EndLoc) { 8810 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 8811 } 8812 8813 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 8814 SourceLocation EndLoc) { 8815 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 8816 } 8817 8818 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 8819 SourceLocation EndLoc) { 8820 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 8821 } 8822 8823 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 8824 SourceLocation EndLoc) { 8825 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 8826 } 8827 8828 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 8829 SourceLocation EndLoc) { 8830 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 8831 } 8832 8833 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 8834 SourceLocation EndLoc) { 8835 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 8836 } 8837 8838 OMPClause *Sema::ActOnOpenMPVarListClause( 8839 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 8840 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 8841 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 8842 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, 8843 OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, 8844 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 8845 SourceLocation DepLinMapLoc) { 8846 OMPClause *Res = nullptr; 8847 switch (Kind) { 8848 case OMPC_private: 8849 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8850 break; 8851 case OMPC_firstprivate: 8852 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8853 break; 8854 case OMPC_lastprivate: 8855 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8856 break; 8857 case OMPC_shared: 8858 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 8859 break; 8860 case OMPC_reduction: 8861 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 8862 EndLoc, ReductionIdScopeSpec, ReductionId); 8863 break; 8864 case OMPC_task_reduction: 8865 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 8866 EndLoc, ReductionIdScopeSpec, 8867 ReductionId); 8868 break; 8869 case OMPC_in_reduction: 8870 Res = 8871 ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 8872 EndLoc, ReductionIdScopeSpec, ReductionId); 8873 break; 8874 case OMPC_linear: 8875 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 8876 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 8877 break; 8878 case OMPC_aligned: 8879 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 8880 ColonLoc, EndLoc); 8881 break; 8882 case OMPC_copyin: 8883 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 8884 break; 8885 case OMPC_copyprivate: 8886 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8887 break; 8888 case OMPC_flush: 8889 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 8890 break; 8891 case OMPC_depend: 8892 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 8893 StartLoc, LParenLoc, EndLoc); 8894 break; 8895 case OMPC_map: 8896 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, 8897 DepLinMapLoc, ColonLoc, VarList, StartLoc, 8898 LParenLoc, EndLoc); 8899 break; 8900 case OMPC_to: 8901 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc); 8902 break; 8903 case OMPC_from: 8904 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc); 8905 break; 8906 case OMPC_use_device_ptr: 8907 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); 8908 break; 8909 case OMPC_is_device_ptr: 8910 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); 8911 break; 8912 case OMPC_if: 8913 case OMPC_final: 8914 case OMPC_num_threads: 8915 case OMPC_safelen: 8916 case OMPC_simdlen: 8917 case OMPC_collapse: 8918 case OMPC_default: 8919 case OMPC_proc_bind: 8920 case OMPC_schedule: 8921 case OMPC_ordered: 8922 case OMPC_nowait: 8923 case OMPC_untied: 8924 case OMPC_mergeable: 8925 case OMPC_threadprivate: 8926 case OMPC_read: 8927 case OMPC_write: 8928 case OMPC_update: 8929 case OMPC_capture: 8930 case OMPC_seq_cst: 8931 case OMPC_device: 8932 case OMPC_threads: 8933 case OMPC_simd: 8934 case OMPC_num_teams: 8935 case OMPC_thread_limit: 8936 case OMPC_priority: 8937 case OMPC_grainsize: 8938 case OMPC_nogroup: 8939 case OMPC_num_tasks: 8940 case OMPC_hint: 8941 case OMPC_dist_schedule: 8942 case OMPC_defaultmap: 8943 case OMPC_unknown: 8944 case OMPC_uniform: 8945 llvm_unreachable("Clause is not allowed."); 8946 } 8947 return Res; 8948 } 8949 8950 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 8951 ExprObjectKind OK, SourceLocation Loc) { 8952 ExprResult Res = BuildDeclRefExpr( 8953 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 8954 if (!Res.isUsable()) 8955 return ExprError(); 8956 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 8957 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 8958 if (!Res.isUsable()) 8959 return ExprError(); 8960 } 8961 if (VK != VK_LValue && Res.get()->isGLValue()) { 8962 Res = DefaultLvalueConversion(Res.get()); 8963 if (!Res.isUsable()) 8964 return ExprError(); 8965 } 8966 return Res; 8967 } 8968 8969 static std::pair<ValueDecl *, bool> 8970 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 8971 SourceRange &ERange, bool AllowArraySection = false) { 8972 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 8973 RefExpr->containsUnexpandedParameterPack()) 8974 return std::make_pair(nullptr, true); 8975 8976 // OpenMP [3.1, C/C++] 8977 // A list item is a variable name. 8978 // OpenMP [2.9.3.3, Restrictions, p.1] 8979 // A variable that is part of another variable (as an array or 8980 // structure element) cannot appear in a private clause. 8981 RefExpr = RefExpr->IgnoreParens(); 8982 enum { 8983 NoArrayExpr = -1, 8984 ArraySubscript = 0, 8985 OMPArraySection = 1 8986 } IsArrayExpr = NoArrayExpr; 8987 if (AllowArraySection) { 8988 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 8989 auto *Base = ASE->getBase()->IgnoreParenImpCasts(); 8990 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 8991 Base = TempASE->getBase()->IgnoreParenImpCasts(); 8992 RefExpr = Base; 8993 IsArrayExpr = ArraySubscript; 8994 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 8995 auto *Base = OASE->getBase()->IgnoreParenImpCasts(); 8996 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 8997 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 8998 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 8999 Base = TempASE->getBase()->IgnoreParenImpCasts(); 9000 RefExpr = Base; 9001 IsArrayExpr = OMPArraySection; 9002 } 9003 } 9004 ELoc = RefExpr->getExprLoc(); 9005 ERange = RefExpr->getSourceRange(); 9006 RefExpr = RefExpr->IgnoreParenImpCasts(); 9007 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 9008 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 9009 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 9010 (S.getCurrentThisType().isNull() || !ME || 9011 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 9012 !isa<FieldDecl>(ME->getMemberDecl()))) { 9013 if (IsArrayExpr != NoArrayExpr) 9014 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 9015 << ERange; 9016 else { 9017 S.Diag(ELoc, 9018 AllowArraySection 9019 ? diag::err_omp_expected_var_name_member_expr_or_array_item 9020 : diag::err_omp_expected_var_name_member_expr) 9021 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 9022 } 9023 return std::make_pair(nullptr, false); 9024 } 9025 return std::make_pair( 9026 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 9027 } 9028 9029 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 9030 SourceLocation StartLoc, 9031 SourceLocation LParenLoc, 9032 SourceLocation EndLoc) { 9033 SmallVector<Expr *, 8> Vars; 9034 SmallVector<Expr *, 8> PrivateCopies; 9035 for (auto &RefExpr : VarList) { 9036 assert(RefExpr && "NULL expr in OpenMP private clause."); 9037 SourceLocation ELoc; 9038 SourceRange ERange; 9039 Expr *SimpleRefExpr = RefExpr; 9040 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9041 if (Res.second) { 9042 // It will be analyzed later. 9043 Vars.push_back(RefExpr); 9044 PrivateCopies.push_back(nullptr); 9045 } 9046 ValueDecl *D = Res.first; 9047 if (!D) 9048 continue; 9049 9050 QualType Type = D->getType(); 9051 auto *VD = dyn_cast<VarDecl>(D); 9052 9053 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 9054 // A variable that appears in a private clause must not have an incomplete 9055 // type or a reference type. 9056 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 9057 continue; 9058 Type = Type.getNonReferenceType(); 9059 9060 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 9061 // in a Construct] 9062 // Variables with the predetermined data-sharing attributes may not be 9063 // listed in data-sharing attributes clauses, except for the cases 9064 // listed below. For these exceptions only, listing a predetermined 9065 // variable in a data-sharing attribute clause is allowed and overrides 9066 // the variable's predetermined data-sharing attributes. 9067 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 9068 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 9069 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 9070 << getOpenMPClauseName(OMPC_private); 9071 ReportOriginalDSA(*this, DSAStack, D, DVar); 9072 continue; 9073 } 9074 9075 auto CurrDir = DSAStack->getCurrentDirective(); 9076 // Variably modified types are not supported for tasks. 9077 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 9078 isOpenMPTaskingDirective(CurrDir)) { 9079 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 9080 << getOpenMPClauseName(OMPC_private) << Type 9081 << getOpenMPDirectiveName(CurrDir); 9082 bool IsDecl = 9083 !VD || 9084 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9085 Diag(D->getLocation(), 9086 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9087 << D; 9088 continue; 9089 } 9090 9091 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 9092 // A list item cannot appear in both a map clause and a data-sharing 9093 // attribute clause on the same construct 9094 if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel || 9095 CurrDir == OMPD_target_teams || 9096 CurrDir == OMPD_target_teams_distribute || 9097 CurrDir == OMPD_target_teams_distribute_parallel_for || 9098 CurrDir == OMPD_target_teams_distribute_parallel_for_simd || 9099 CurrDir == OMPD_target_teams_distribute_simd || 9100 CurrDir == OMPD_target_parallel_for_simd || 9101 CurrDir == OMPD_target_parallel_for) { 9102 OpenMPClauseKind ConflictKind; 9103 if (DSAStack->checkMappableExprComponentListsForDecl( 9104 VD, /*CurrentRegionOnly=*/true, 9105 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 9106 OpenMPClauseKind WhereFoundClauseKind) -> bool { 9107 ConflictKind = WhereFoundClauseKind; 9108 return true; 9109 })) { 9110 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 9111 << getOpenMPClauseName(OMPC_private) 9112 << getOpenMPClauseName(ConflictKind) 9113 << getOpenMPDirectiveName(CurrDir); 9114 ReportOriginalDSA(*this, DSAStack, D, DVar); 9115 continue; 9116 } 9117 } 9118 9119 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 9120 // A variable of class type (or array thereof) that appears in a private 9121 // clause requires an accessible, unambiguous default constructor for the 9122 // class type. 9123 // Generate helper private variable and initialize it with the default 9124 // value. The address of the original variable is replaced by the address of 9125 // the new private variable in CodeGen. This new variable is not added to 9126 // IdResolver, so the code in the OpenMP region uses original variable for 9127 // proper diagnostics. 9128 Type = Type.getUnqualifiedType(); 9129 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 9130 D->hasAttrs() ? &D->getAttrs() : nullptr); 9131 ActOnUninitializedDecl(VDPrivate); 9132 if (VDPrivate->isInvalidDecl()) 9133 continue; 9134 auto VDPrivateRefExpr = buildDeclRefExpr( 9135 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 9136 9137 DeclRefExpr *Ref = nullptr; 9138 if (!VD && !CurContext->isDependentContext()) 9139 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 9140 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 9141 Vars.push_back((VD || CurContext->isDependentContext()) 9142 ? RefExpr->IgnoreParens() 9143 : Ref); 9144 PrivateCopies.push_back(VDPrivateRefExpr); 9145 } 9146 9147 if (Vars.empty()) 9148 return nullptr; 9149 9150 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 9151 PrivateCopies); 9152 } 9153 9154 namespace { 9155 class DiagsUninitializedSeveretyRAII { 9156 private: 9157 DiagnosticsEngine &Diags; 9158 SourceLocation SavedLoc; 9159 bool IsIgnored; 9160 9161 public: 9162 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 9163 bool IsIgnored) 9164 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 9165 if (!IsIgnored) { 9166 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 9167 /*Map*/ diag::Severity::Ignored, Loc); 9168 } 9169 } 9170 ~DiagsUninitializedSeveretyRAII() { 9171 if (!IsIgnored) 9172 Diags.popMappings(SavedLoc); 9173 } 9174 }; 9175 } 9176 9177 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 9178 SourceLocation StartLoc, 9179 SourceLocation LParenLoc, 9180 SourceLocation EndLoc) { 9181 SmallVector<Expr *, 8> Vars; 9182 SmallVector<Expr *, 8> PrivateCopies; 9183 SmallVector<Expr *, 8> Inits; 9184 SmallVector<Decl *, 4> ExprCaptures; 9185 bool IsImplicitClause = 9186 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 9187 auto ImplicitClauseLoc = DSAStack->getConstructLoc(); 9188 9189 for (auto &RefExpr : VarList) { 9190 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 9191 SourceLocation ELoc; 9192 SourceRange ERange; 9193 Expr *SimpleRefExpr = RefExpr; 9194 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9195 if (Res.second) { 9196 // It will be analyzed later. 9197 Vars.push_back(RefExpr); 9198 PrivateCopies.push_back(nullptr); 9199 Inits.push_back(nullptr); 9200 } 9201 ValueDecl *D = Res.first; 9202 if (!D) 9203 continue; 9204 9205 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 9206 QualType Type = D->getType(); 9207 auto *VD = dyn_cast<VarDecl>(D); 9208 9209 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 9210 // A variable that appears in a private clause must not have an incomplete 9211 // type or a reference type. 9212 if (RequireCompleteType(ELoc, Type, 9213 diag::err_omp_firstprivate_incomplete_type)) 9214 continue; 9215 Type = Type.getNonReferenceType(); 9216 9217 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 9218 // A variable of class type (or array thereof) that appears in a private 9219 // clause requires an accessible, unambiguous copy constructor for the 9220 // class type. 9221 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 9222 9223 // If an implicit firstprivate variable found it was checked already. 9224 DSAStackTy::DSAVarData TopDVar; 9225 if (!IsImplicitClause) { 9226 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 9227 TopDVar = DVar; 9228 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 9229 bool IsConstant = ElemType.isConstant(Context); 9230 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 9231 // A list item that specifies a given variable may not appear in more 9232 // than one clause on the same directive, except that a variable may be 9233 // specified in both firstprivate and lastprivate clauses. 9234 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 9235 // A list item may appear in a firstprivate or lastprivate clause but not 9236 // both. 9237 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 9238 (isOpenMPDistributeDirective(CurrDir) || 9239 DVar.CKind != OMPC_lastprivate) && 9240 DVar.RefExpr) { 9241 Diag(ELoc, diag::err_omp_wrong_dsa) 9242 << getOpenMPClauseName(DVar.CKind) 9243 << getOpenMPClauseName(OMPC_firstprivate); 9244 ReportOriginalDSA(*this, DSAStack, D, DVar); 9245 continue; 9246 } 9247 9248 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 9249 // in a Construct] 9250 // Variables with the predetermined data-sharing attributes may not be 9251 // listed in data-sharing attributes clauses, except for the cases 9252 // listed below. For these exceptions only, listing a predetermined 9253 // variable in a data-sharing attribute clause is allowed and overrides 9254 // the variable's predetermined data-sharing attributes. 9255 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 9256 // in a Construct, C/C++, p.2] 9257 // Variables with const-qualified type having no mutable member may be 9258 // listed in a firstprivate clause, even if they are static data members. 9259 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 9260 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 9261 Diag(ELoc, diag::err_omp_wrong_dsa) 9262 << getOpenMPClauseName(DVar.CKind) 9263 << getOpenMPClauseName(OMPC_firstprivate); 9264 ReportOriginalDSA(*this, DSAStack, D, DVar); 9265 continue; 9266 } 9267 9268 // OpenMP [2.9.3.4, Restrictions, p.2] 9269 // A list item that is private within a parallel region must not appear 9270 // in a firstprivate clause on a worksharing construct if any of the 9271 // worksharing regions arising from the worksharing construct ever bind 9272 // to any of the parallel regions arising from the parallel construct. 9273 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 9274 // A list item that is private within a teams region must not appear in a 9275 // firstprivate clause on a distribute construct if any of the distribute 9276 // regions arising from the distribute construct ever bind to any of the 9277 // teams regions arising from the teams construct. 9278 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 9279 // A list item that appears in a reduction clause of a teams construct 9280 // must not appear in a firstprivate clause on a distribute construct if 9281 // any of the distribute regions arising from the distribute construct 9282 // ever bind to any of the teams regions arising from the teams construct. 9283 if ((isOpenMPWorksharingDirective(CurrDir) || 9284 isOpenMPDistributeDirective(CurrDir)) && 9285 !isOpenMPParallelDirective(CurrDir) && 9286 !isOpenMPTeamsDirective(CurrDir)) { 9287 DVar = DSAStack->getImplicitDSA(D, true); 9288 if (DVar.CKind != OMPC_shared && 9289 (isOpenMPParallelDirective(DVar.DKind) || 9290 isOpenMPTeamsDirective(DVar.DKind) || 9291 DVar.DKind == OMPD_unknown)) { 9292 Diag(ELoc, diag::err_omp_required_access) 9293 << getOpenMPClauseName(OMPC_firstprivate) 9294 << getOpenMPClauseName(OMPC_shared); 9295 ReportOriginalDSA(*this, DSAStack, D, DVar); 9296 continue; 9297 } 9298 } 9299 // OpenMP [2.9.3.4, Restrictions, p.3] 9300 // A list item that appears in a reduction clause of a parallel construct 9301 // must not appear in a firstprivate clause on a worksharing or task 9302 // construct if any of the worksharing or task regions arising from the 9303 // worksharing or task construct ever bind to any of the parallel regions 9304 // arising from the parallel construct. 9305 // OpenMP [2.9.3.4, Restrictions, p.4] 9306 // A list item that appears in a reduction clause in worksharing 9307 // construct must not appear in a firstprivate clause in a task construct 9308 // encountered during execution of any of the worksharing regions arising 9309 // from the worksharing construct. 9310 if (isOpenMPTaskingDirective(CurrDir)) { 9311 DVar = DSAStack->hasInnermostDSA( 9312 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 9313 [](OpenMPDirectiveKind K) -> bool { 9314 return isOpenMPParallelDirective(K) || 9315 isOpenMPWorksharingDirective(K) || 9316 isOpenMPTeamsDirective(K); 9317 }, 9318 /*FromParent=*/true); 9319 if (DVar.CKind == OMPC_reduction && 9320 (isOpenMPParallelDirective(DVar.DKind) || 9321 isOpenMPWorksharingDirective(DVar.DKind) || 9322 isOpenMPTeamsDirective(DVar.DKind))) { 9323 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 9324 << getOpenMPDirectiveName(DVar.DKind); 9325 ReportOriginalDSA(*this, DSAStack, D, DVar); 9326 continue; 9327 } 9328 } 9329 9330 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 9331 // A list item cannot appear in both a map clause and a data-sharing 9332 // attribute clause on the same construct 9333 if (isOpenMPTargetExecutionDirective(CurrDir)) { 9334 OpenMPClauseKind ConflictKind; 9335 if (DSAStack->checkMappableExprComponentListsForDecl( 9336 VD, /*CurrentRegionOnly=*/true, 9337 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 9338 OpenMPClauseKind WhereFoundClauseKind) -> bool { 9339 ConflictKind = WhereFoundClauseKind; 9340 return true; 9341 })) { 9342 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 9343 << getOpenMPClauseName(OMPC_firstprivate) 9344 << getOpenMPClauseName(ConflictKind) 9345 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 9346 ReportOriginalDSA(*this, DSAStack, D, DVar); 9347 continue; 9348 } 9349 } 9350 } 9351 9352 // Variably modified types are not supported for tasks. 9353 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 9354 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 9355 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 9356 << getOpenMPClauseName(OMPC_firstprivate) << Type 9357 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 9358 bool IsDecl = 9359 !VD || 9360 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9361 Diag(D->getLocation(), 9362 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9363 << D; 9364 continue; 9365 } 9366 9367 Type = Type.getUnqualifiedType(); 9368 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 9369 D->hasAttrs() ? &D->getAttrs() : nullptr); 9370 // Generate helper private variable and initialize it with the value of the 9371 // original variable. The address of the original variable is replaced by 9372 // the address of the new private variable in the CodeGen. This new variable 9373 // is not added to IdResolver, so the code in the OpenMP region uses 9374 // original variable for proper diagnostics and variable capturing. 9375 Expr *VDInitRefExpr = nullptr; 9376 // For arrays generate initializer for single element and replace it by the 9377 // original array element in CodeGen. 9378 if (Type->isArrayType()) { 9379 auto VDInit = 9380 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 9381 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 9382 auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); 9383 ElemType = ElemType.getUnqualifiedType(); 9384 auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 9385 ".firstprivate.temp"); 9386 InitializedEntity Entity = 9387 InitializedEntity::InitializeVariable(VDInitTemp); 9388 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 9389 9390 InitializationSequence InitSeq(*this, Entity, Kind, Init); 9391 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 9392 if (Result.isInvalid()) 9393 VDPrivate->setInvalidDecl(); 9394 else 9395 VDPrivate->setInit(Result.getAs<Expr>()); 9396 // Remove temp variable declaration. 9397 Context.Deallocate(VDInitTemp); 9398 } else { 9399 auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 9400 ".firstprivate.temp"); 9401 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 9402 RefExpr->getExprLoc()); 9403 AddInitializerToDecl(VDPrivate, 9404 DefaultLvalueConversion(VDInitRefExpr).get(), 9405 /*DirectInit=*/false); 9406 } 9407 if (VDPrivate->isInvalidDecl()) { 9408 if (IsImplicitClause) { 9409 Diag(RefExpr->getExprLoc(), 9410 diag::note_omp_task_predetermined_firstprivate_here); 9411 } 9412 continue; 9413 } 9414 CurContext->addDecl(VDPrivate); 9415 auto VDPrivateRefExpr = buildDeclRefExpr( 9416 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 9417 RefExpr->getExprLoc()); 9418 DeclRefExpr *Ref = nullptr; 9419 if (!VD && !CurContext->isDependentContext()) { 9420 if (TopDVar.CKind == OMPC_lastprivate) 9421 Ref = TopDVar.PrivateCopy; 9422 else { 9423 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 9424 if (!IsOpenMPCapturedDecl(D)) 9425 ExprCaptures.push_back(Ref->getDecl()); 9426 } 9427 } 9428 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 9429 Vars.push_back((VD || CurContext->isDependentContext()) 9430 ? RefExpr->IgnoreParens() 9431 : Ref); 9432 PrivateCopies.push_back(VDPrivateRefExpr); 9433 Inits.push_back(VDInitRefExpr); 9434 } 9435 9436 if (Vars.empty()) 9437 return nullptr; 9438 9439 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9440 Vars, PrivateCopies, Inits, 9441 buildPreInits(Context, ExprCaptures)); 9442 } 9443 9444 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 9445 SourceLocation StartLoc, 9446 SourceLocation LParenLoc, 9447 SourceLocation EndLoc) { 9448 SmallVector<Expr *, 8> Vars; 9449 SmallVector<Expr *, 8> SrcExprs; 9450 SmallVector<Expr *, 8> DstExprs; 9451 SmallVector<Expr *, 8> AssignmentOps; 9452 SmallVector<Decl *, 4> ExprCaptures; 9453 SmallVector<Expr *, 4> ExprPostUpdates; 9454 for (auto &RefExpr : VarList) { 9455 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 9456 SourceLocation ELoc; 9457 SourceRange ERange; 9458 Expr *SimpleRefExpr = RefExpr; 9459 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9460 if (Res.second) { 9461 // It will be analyzed later. 9462 Vars.push_back(RefExpr); 9463 SrcExprs.push_back(nullptr); 9464 DstExprs.push_back(nullptr); 9465 AssignmentOps.push_back(nullptr); 9466 } 9467 ValueDecl *D = Res.first; 9468 if (!D) 9469 continue; 9470 9471 QualType Type = D->getType(); 9472 auto *VD = dyn_cast<VarDecl>(D); 9473 9474 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 9475 // A variable that appears in a lastprivate clause must not have an 9476 // incomplete type or a reference type. 9477 if (RequireCompleteType(ELoc, Type, 9478 diag::err_omp_lastprivate_incomplete_type)) 9479 continue; 9480 Type = Type.getNonReferenceType(); 9481 9482 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 9483 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 9484 // in a Construct] 9485 // Variables with the predetermined data-sharing attributes may not be 9486 // listed in data-sharing attributes clauses, except for the cases 9487 // listed below. 9488 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 9489 // A list item may appear in a firstprivate or lastprivate clause but not 9490 // both. 9491 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 9492 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 9493 (isOpenMPDistributeDirective(CurrDir) || 9494 DVar.CKind != OMPC_firstprivate) && 9495 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 9496 Diag(ELoc, diag::err_omp_wrong_dsa) 9497 << getOpenMPClauseName(DVar.CKind) 9498 << getOpenMPClauseName(OMPC_lastprivate); 9499 ReportOriginalDSA(*this, DSAStack, D, DVar); 9500 continue; 9501 } 9502 9503 // OpenMP [2.14.3.5, Restrictions, p.2] 9504 // A list item that is private within a parallel region, or that appears in 9505 // the reduction clause of a parallel construct, must not appear in a 9506 // lastprivate clause on a worksharing construct if any of the corresponding 9507 // worksharing regions ever binds to any of the corresponding parallel 9508 // regions. 9509 DSAStackTy::DSAVarData TopDVar = DVar; 9510 if (isOpenMPWorksharingDirective(CurrDir) && 9511 !isOpenMPParallelDirective(CurrDir) && 9512 !isOpenMPTeamsDirective(CurrDir)) { 9513 DVar = DSAStack->getImplicitDSA(D, true); 9514 if (DVar.CKind != OMPC_shared) { 9515 Diag(ELoc, diag::err_omp_required_access) 9516 << getOpenMPClauseName(OMPC_lastprivate) 9517 << getOpenMPClauseName(OMPC_shared); 9518 ReportOriginalDSA(*this, DSAStack, D, DVar); 9519 continue; 9520 } 9521 } 9522 9523 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 9524 // A variable of class type (or array thereof) that appears in a 9525 // lastprivate clause requires an accessible, unambiguous default 9526 // constructor for the class type, unless the list item is also specified 9527 // in a firstprivate clause. 9528 // A variable of class type (or array thereof) that appears in a 9529 // lastprivate clause requires an accessible, unambiguous copy assignment 9530 // operator for the class type. 9531 Type = Context.getBaseElementType(Type).getNonReferenceType(); 9532 auto *SrcVD = buildVarDecl(*this, ERange.getBegin(), 9533 Type.getUnqualifiedType(), ".lastprivate.src", 9534 D->hasAttrs() ? &D->getAttrs() : nullptr); 9535 auto *PseudoSrcExpr = 9536 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 9537 auto *DstVD = 9538 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 9539 D->hasAttrs() ? &D->getAttrs() : nullptr); 9540 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 9541 // For arrays generate assignment operation for single element and replace 9542 // it by the original array element in CodeGen. 9543 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 9544 PseudoDstExpr, PseudoSrcExpr); 9545 if (AssignmentOp.isInvalid()) 9546 continue; 9547 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 9548 /*DiscardedValue=*/true); 9549 if (AssignmentOp.isInvalid()) 9550 continue; 9551 9552 DeclRefExpr *Ref = nullptr; 9553 if (!VD && !CurContext->isDependentContext()) { 9554 if (TopDVar.CKind == OMPC_firstprivate) 9555 Ref = TopDVar.PrivateCopy; 9556 else { 9557 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 9558 if (!IsOpenMPCapturedDecl(D)) 9559 ExprCaptures.push_back(Ref->getDecl()); 9560 } 9561 if (TopDVar.CKind == OMPC_firstprivate || 9562 (!IsOpenMPCapturedDecl(D) && 9563 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 9564 ExprResult RefRes = DefaultLvalueConversion(Ref); 9565 if (!RefRes.isUsable()) 9566 continue; 9567 ExprResult PostUpdateRes = 9568 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 9569 RefRes.get()); 9570 if (!PostUpdateRes.isUsable()) 9571 continue; 9572 ExprPostUpdates.push_back( 9573 IgnoredValueConversions(PostUpdateRes.get()).get()); 9574 } 9575 } 9576 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 9577 Vars.push_back((VD || CurContext->isDependentContext()) 9578 ? RefExpr->IgnoreParens() 9579 : Ref); 9580 SrcExprs.push_back(PseudoSrcExpr); 9581 DstExprs.push_back(PseudoDstExpr); 9582 AssignmentOps.push_back(AssignmentOp.get()); 9583 } 9584 9585 if (Vars.empty()) 9586 return nullptr; 9587 9588 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9589 Vars, SrcExprs, DstExprs, AssignmentOps, 9590 buildPreInits(Context, ExprCaptures), 9591 buildPostUpdate(*this, ExprPostUpdates)); 9592 } 9593 9594 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 9595 SourceLocation StartLoc, 9596 SourceLocation LParenLoc, 9597 SourceLocation EndLoc) { 9598 SmallVector<Expr *, 8> Vars; 9599 for (auto &RefExpr : VarList) { 9600 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 9601 SourceLocation ELoc; 9602 SourceRange ERange; 9603 Expr *SimpleRefExpr = RefExpr; 9604 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9605 if (Res.second) { 9606 // It will be analyzed later. 9607 Vars.push_back(RefExpr); 9608 } 9609 ValueDecl *D = Res.first; 9610 if (!D) 9611 continue; 9612 9613 auto *VD = dyn_cast<VarDecl>(D); 9614 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 9615 // in a Construct] 9616 // Variables with the predetermined data-sharing attributes may not be 9617 // listed in data-sharing attributes clauses, except for the cases 9618 // listed below. For these exceptions only, listing a predetermined 9619 // variable in a data-sharing attribute clause is allowed and overrides 9620 // the variable's predetermined data-sharing attributes. 9621 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 9622 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 9623 DVar.RefExpr) { 9624 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 9625 << getOpenMPClauseName(OMPC_shared); 9626 ReportOriginalDSA(*this, DSAStack, D, DVar); 9627 continue; 9628 } 9629 9630 DeclRefExpr *Ref = nullptr; 9631 if (!VD && IsOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 9632 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 9633 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 9634 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 9635 ? RefExpr->IgnoreParens() 9636 : Ref); 9637 } 9638 9639 if (Vars.empty()) 9640 return nullptr; 9641 9642 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 9643 } 9644 9645 namespace { 9646 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 9647 DSAStackTy *Stack; 9648 9649 public: 9650 bool VisitDeclRefExpr(DeclRefExpr *E) { 9651 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { 9652 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false); 9653 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 9654 return false; 9655 if (DVar.CKind != OMPC_unknown) 9656 return true; 9657 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 9658 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, 9659 /*FromParent=*/true); 9660 if (DVarPrivate.CKind != OMPC_unknown) 9661 return true; 9662 return false; 9663 } 9664 return false; 9665 } 9666 bool VisitStmt(Stmt *S) { 9667 for (auto Child : S->children()) { 9668 if (Child && Visit(Child)) 9669 return true; 9670 } 9671 return false; 9672 } 9673 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 9674 }; 9675 } // namespace 9676 9677 namespace { 9678 // Transform MemberExpression for specified FieldDecl of current class to 9679 // DeclRefExpr to specified OMPCapturedExprDecl. 9680 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 9681 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 9682 ValueDecl *Field; 9683 DeclRefExpr *CapturedExpr; 9684 9685 public: 9686 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 9687 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 9688 9689 ExprResult TransformMemberExpr(MemberExpr *E) { 9690 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 9691 E->getMemberDecl() == Field) { 9692 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 9693 return CapturedExpr; 9694 } 9695 return BaseTransform::TransformMemberExpr(E); 9696 } 9697 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 9698 }; 9699 } // namespace 9700 9701 template <typename T> 9702 static T filterLookupForUDR(SmallVectorImpl<UnresolvedSet<8>> &Lookups, 9703 const llvm::function_ref<T(ValueDecl *)> &Gen) { 9704 for (auto &Set : Lookups) { 9705 for (auto *D : Set) { 9706 if (auto Res = Gen(cast<ValueDecl>(D))) 9707 return Res; 9708 } 9709 } 9710 return T(); 9711 } 9712 9713 static ExprResult 9714 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 9715 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 9716 const DeclarationNameInfo &ReductionId, QualType Ty, 9717 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 9718 if (ReductionIdScopeSpec.isInvalid()) 9719 return ExprError(); 9720 SmallVector<UnresolvedSet<8>, 4> Lookups; 9721 if (S) { 9722 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 9723 Lookup.suppressDiagnostics(); 9724 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 9725 auto *D = Lookup.getRepresentativeDecl(); 9726 do { 9727 S = S->getParent(); 9728 } while (S && !S->isDeclScope(D)); 9729 if (S) 9730 S = S->getParent(); 9731 Lookups.push_back(UnresolvedSet<8>()); 9732 Lookups.back().append(Lookup.begin(), Lookup.end()); 9733 Lookup.clear(); 9734 } 9735 } else if (auto *ULE = 9736 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 9737 Lookups.push_back(UnresolvedSet<8>()); 9738 Decl *PrevD = nullptr; 9739 for (auto *D : ULE->decls()) { 9740 if (D == PrevD) 9741 Lookups.push_back(UnresolvedSet<8>()); 9742 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) 9743 Lookups.back().addDecl(DRD); 9744 PrevD = D; 9745 } 9746 } 9747 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 9748 Ty->isInstantiationDependentType() || 9749 Ty->containsUnexpandedParameterPack() || 9750 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool { 9751 return !D->isInvalidDecl() && 9752 (D->getType()->isDependentType() || 9753 D->getType()->isInstantiationDependentType() || 9754 D->getType()->containsUnexpandedParameterPack()); 9755 })) { 9756 UnresolvedSet<8> ResSet; 9757 for (auto &Set : Lookups) { 9758 ResSet.append(Set.begin(), Set.end()); 9759 // The last item marks the end of all declarations at the specified scope. 9760 ResSet.addDecl(Set[Set.size() - 1]); 9761 } 9762 return UnresolvedLookupExpr::Create( 9763 SemaRef.Context, /*NamingClass=*/nullptr, 9764 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 9765 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 9766 } 9767 if (auto *VD = filterLookupForUDR<ValueDecl *>( 9768 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 9769 if (!D->isInvalidDecl() && 9770 SemaRef.Context.hasSameType(D->getType(), Ty)) 9771 return D; 9772 return nullptr; 9773 })) 9774 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 9775 if (auto *VD = filterLookupForUDR<ValueDecl *>( 9776 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 9777 if (!D->isInvalidDecl() && 9778 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 9779 !Ty.isMoreQualifiedThan(D->getType())) 9780 return D; 9781 return nullptr; 9782 })) { 9783 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 9784 /*DetectVirtual=*/false); 9785 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 9786 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 9787 VD->getType().getUnqualifiedType()))) { 9788 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), 9789 /*DiagID=*/0) != 9790 Sema::AR_inaccessible) { 9791 SemaRef.BuildBasePathArray(Paths, BasePath); 9792 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 9793 } 9794 } 9795 } 9796 } 9797 if (ReductionIdScopeSpec.isSet()) { 9798 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 9799 return ExprError(); 9800 } 9801 return ExprEmpty(); 9802 } 9803 9804 namespace { 9805 /// Data for the reduction-based clauses. 9806 struct ReductionData { 9807 /// List of original reduction items. 9808 SmallVector<Expr *, 8> Vars; 9809 /// List of private copies of the reduction items. 9810 SmallVector<Expr *, 8> Privates; 9811 /// LHS expressions for the reduction_op expressions. 9812 SmallVector<Expr *, 8> LHSs; 9813 /// RHS expressions for the reduction_op expressions. 9814 SmallVector<Expr *, 8> RHSs; 9815 /// Reduction operation expression. 9816 SmallVector<Expr *, 8> ReductionOps; 9817 /// Taskgroup descriptors for the corresponding reduction items in 9818 /// in_reduction clauses. 9819 SmallVector<Expr *, 8> TaskgroupDescriptors; 9820 /// List of captures for clause. 9821 SmallVector<Decl *, 4> ExprCaptures; 9822 /// List of postupdate expressions. 9823 SmallVector<Expr *, 4> ExprPostUpdates; 9824 ReductionData() = delete; 9825 /// Reserves required memory for the reduction data. 9826 ReductionData(unsigned Size) { 9827 Vars.reserve(Size); 9828 Privates.reserve(Size); 9829 LHSs.reserve(Size); 9830 RHSs.reserve(Size); 9831 ReductionOps.reserve(Size); 9832 TaskgroupDescriptors.reserve(Size); 9833 ExprCaptures.reserve(Size); 9834 ExprPostUpdates.reserve(Size); 9835 } 9836 /// Stores reduction item and reduction operation only (required for dependent 9837 /// reduction item). 9838 void push(Expr *Item, Expr *ReductionOp) { 9839 Vars.emplace_back(Item); 9840 Privates.emplace_back(nullptr); 9841 LHSs.emplace_back(nullptr); 9842 RHSs.emplace_back(nullptr); 9843 ReductionOps.emplace_back(ReductionOp); 9844 TaskgroupDescriptors.emplace_back(nullptr); 9845 } 9846 /// Stores reduction data. 9847 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 9848 Expr *TaskgroupDescriptor) { 9849 Vars.emplace_back(Item); 9850 Privates.emplace_back(Private); 9851 LHSs.emplace_back(LHS); 9852 RHSs.emplace_back(RHS); 9853 ReductionOps.emplace_back(ReductionOp); 9854 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 9855 } 9856 }; 9857 } // namespace 9858 9859 static bool CheckOMPArraySectionConstantForReduction( 9860 ASTContext &Context, const OMPArraySectionExpr *OASE, bool &SingleElement, 9861 SmallVectorImpl<llvm::APSInt> &ArraySizes) { 9862 const Expr *Length = OASE->getLength(); 9863 if (Length == nullptr) { 9864 // For array sections of the form [1:] or [:], we would need to analyze 9865 // the lower bound... 9866 if (OASE->getColonLoc().isValid()) 9867 return false; 9868 9869 // This is an array subscript which has implicit length 1! 9870 SingleElement = true; 9871 ArraySizes.push_back(llvm::APSInt::get(1)); 9872 } else { 9873 llvm::APSInt ConstantLengthValue; 9874 if (!Length->EvaluateAsInt(ConstantLengthValue, Context)) 9875 return false; 9876 9877 SingleElement = (ConstantLengthValue.getSExtValue() == 1); 9878 ArraySizes.push_back(ConstantLengthValue); 9879 } 9880 9881 // Get the base of this array section and walk up from there. 9882 const Expr *Base = OASE->getBase()->IgnoreParenImpCasts(); 9883 9884 // We require length = 1 for all array sections except the right-most to 9885 // guarantee that the memory region is contiguous and has no holes in it. 9886 while (const auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) { 9887 Length = TempOASE->getLength(); 9888 if (Length == nullptr) { 9889 // For array sections of the form [1:] or [:], we would need to analyze 9890 // the lower bound... 9891 if (OASE->getColonLoc().isValid()) 9892 return false; 9893 9894 // This is an array subscript which has implicit length 1! 9895 ArraySizes.push_back(llvm::APSInt::get(1)); 9896 } else { 9897 llvm::APSInt ConstantLengthValue; 9898 if (!Length->EvaluateAsInt(ConstantLengthValue, Context) || 9899 ConstantLengthValue.getSExtValue() != 1) 9900 return false; 9901 9902 ArraySizes.push_back(ConstantLengthValue); 9903 } 9904 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 9905 } 9906 9907 // If we have a single element, we don't need to add the implicit lengths. 9908 if (!SingleElement) { 9909 while (const auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) { 9910 // Has implicit length 1! 9911 ArraySizes.push_back(llvm::APSInt::get(1)); 9912 Base = TempASE->getBase()->IgnoreParenImpCasts(); 9913 } 9914 } 9915 9916 // This array section can be privatized as a single value or as a constant 9917 // sized array. 9918 return true; 9919 } 9920 9921 static bool ActOnOMPReductionKindClause( 9922 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 9923 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 9924 SourceLocation ColonLoc, SourceLocation EndLoc, 9925 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 9926 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 9927 auto DN = ReductionId.getName(); 9928 auto OOK = DN.getCXXOverloadedOperator(); 9929 BinaryOperatorKind BOK = BO_Comma; 9930 9931 ASTContext &Context = S.Context; 9932 // OpenMP [2.14.3.6, reduction clause] 9933 // C 9934 // reduction-identifier is either an identifier or one of the following 9935 // operators: +, -, *, &, |, ^, && and || 9936 // C++ 9937 // reduction-identifier is either an id-expression or one of the following 9938 // operators: +, -, *, &, |, ^, && and || 9939 switch (OOK) { 9940 case OO_Plus: 9941 case OO_Minus: 9942 BOK = BO_Add; 9943 break; 9944 case OO_Star: 9945 BOK = BO_Mul; 9946 break; 9947 case OO_Amp: 9948 BOK = BO_And; 9949 break; 9950 case OO_Pipe: 9951 BOK = BO_Or; 9952 break; 9953 case OO_Caret: 9954 BOK = BO_Xor; 9955 break; 9956 case OO_AmpAmp: 9957 BOK = BO_LAnd; 9958 break; 9959 case OO_PipePipe: 9960 BOK = BO_LOr; 9961 break; 9962 case OO_New: 9963 case OO_Delete: 9964 case OO_Array_New: 9965 case OO_Array_Delete: 9966 case OO_Slash: 9967 case OO_Percent: 9968 case OO_Tilde: 9969 case OO_Exclaim: 9970 case OO_Equal: 9971 case OO_Less: 9972 case OO_Greater: 9973 case OO_LessEqual: 9974 case OO_GreaterEqual: 9975 case OO_PlusEqual: 9976 case OO_MinusEqual: 9977 case OO_StarEqual: 9978 case OO_SlashEqual: 9979 case OO_PercentEqual: 9980 case OO_CaretEqual: 9981 case OO_AmpEqual: 9982 case OO_PipeEqual: 9983 case OO_LessLess: 9984 case OO_GreaterGreater: 9985 case OO_LessLessEqual: 9986 case OO_GreaterGreaterEqual: 9987 case OO_EqualEqual: 9988 case OO_ExclaimEqual: 9989 case OO_Spaceship: 9990 case OO_PlusPlus: 9991 case OO_MinusMinus: 9992 case OO_Comma: 9993 case OO_ArrowStar: 9994 case OO_Arrow: 9995 case OO_Call: 9996 case OO_Subscript: 9997 case OO_Conditional: 9998 case OO_Coawait: 9999 case NUM_OVERLOADED_OPERATORS: 10000 llvm_unreachable("Unexpected reduction identifier"); 10001 case OO_None: 10002 if (auto *II = DN.getAsIdentifierInfo()) { 10003 if (II->isStr("max")) 10004 BOK = BO_GT; 10005 else if (II->isStr("min")) 10006 BOK = BO_LT; 10007 } 10008 break; 10009 } 10010 SourceRange ReductionIdRange; 10011 if (ReductionIdScopeSpec.isValid()) 10012 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 10013 else 10014 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 10015 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 10016 10017 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 10018 bool FirstIter = true; 10019 for (auto RefExpr : VarList) { 10020 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 10021 // OpenMP [2.1, C/C++] 10022 // A list item is a variable or array section, subject to the restrictions 10023 // specified in Section 2.4 on page 42 and in each of the sections 10024 // describing clauses and directives for which a list appears. 10025 // OpenMP [2.14.3.3, Restrictions, p.1] 10026 // A variable that is part of another variable (as an array or 10027 // structure element) cannot appear in a private clause. 10028 if (!FirstIter && IR != ER) 10029 ++IR; 10030 FirstIter = false; 10031 SourceLocation ELoc; 10032 SourceRange ERange; 10033 Expr *SimpleRefExpr = RefExpr; 10034 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 10035 /*AllowArraySection=*/true); 10036 if (Res.second) { 10037 // Try to find 'declare reduction' corresponding construct before using 10038 // builtin/overloaded operators. 10039 QualType Type = Context.DependentTy; 10040 CXXCastPath BasePath; 10041 ExprResult DeclareReductionRef = buildDeclareReductionRef( 10042 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 10043 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 10044 Expr *ReductionOp = nullptr; 10045 if (S.CurContext->isDependentContext() && 10046 (DeclareReductionRef.isUnset() || 10047 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 10048 ReductionOp = DeclareReductionRef.get(); 10049 // It will be analyzed later. 10050 RD.push(RefExpr, ReductionOp); 10051 } 10052 ValueDecl *D = Res.first; 10053 if (!D) 10054 continue; 10055 10056 Expr *TaskgroupDescriptor = nullptr; 10057 QualType Type; 10058 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 10059 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 10060 if (ASE) 10061 Type = ASE->getType().getNonReferenceType(); 10062 else if (OASE) { 10063 auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 10064 if (auto *ATy = BaseType->getAsArrayTypeUnsafe()) 10065 Type = ATy->getElementType(); 10066 else 10067 Type = BaseType->getPointeeType(); 10068 Type = Type.getNonReferenceType(); 10069 } else 10070 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 10071 auto *VD = dyn_cast<VarDecl>(D); 10072 10073 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 10074 // A variable that appears in a private clause must not have an incomplete 10075 // type or a reference type. 10076 if (S.RequireCompleteType(ELoc, Type, 10077 diag::err_omp_reduction_incomplete_type)) 10078 continue; 10079 // OpenMP [2.14.3.6, reduction clause, Restrictions] 10080 // A list item that appears in a reduction clause must not be 10081 // const-qualified. 10082 if (Type.getNonReferenceType().isConstant(Context)) { 10083 S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange; 10084 if (!ASE && !OASE) { 10085 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 10086 VarDecl::DeclarationOnly; 10087 S.Diag(D->getLocation(), 10088 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10089 << D; 10090 } 10091 continue; 10092 } 10093 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 10094 // If a list-item is a reference type then it must bind to the same object 10095 // for all threads of the team. 10096 if (!ASE && !OASE && VD) { 10097 VarDecl *VDDef = VD->getDefinition(); 10098 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 10099 DSARefChecker Check(Stack); 10100 if (Check.Visit(VDDef->getInit())) { 10101 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 10102 << getOpenMPClauseName(ClauseKind) << ERange; 10103 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 10104 continue; 10105 } 10106 } 10107 } 10108 10109 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 10110 // in a Construct] 10111 // Variables with the predetermined data-sharing attributes may not be 10112 // listed in data-sharing attributes clauses, except for the cases 10113 // listed below. For these exceptions only, listing a predetermined 10114 // variable in a data-sharing attribute clause is allowed and overrides 10115 // the variable's predetermined data-sharing attributes. 10116 // OpenMP [2.14.3.6, Restrictions, p.3] 10117 // Any number of reduction clauses can be specified on the directive, 10118 // but a list item can appear only once in the reduction clauses for that 10119 // directive. 10120 DSAStackTy::DSAVarData DVar; 10121 DVar = Stack->getTopDSA(D, false); 10122 if (DVar.CKind == OMPC_reduction) { 10123 S.Diag(ELoc, diag::err_omp_once_referenced) 10124 << getOpenMPClauseName(ClauseKind); 10125 if (DVar.RefExpr) 10126 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 10127 continue; 10128 } else if (DVar.CKind != OMPC_unknown) { 10129 S.Diag(ELoc, diag::err_omp_wrong_dsa) 10130 << getOpenMPClauseName(DVar.CKind) 10131 << getOpenMPClauseName(OMPC_reduction); 10132 ReportOriginalDSA(S, Stack, D, DVar); 10133 continue; 10134 } 10135 10136 // OpenMP [2.14.3.6, Restrictions, p.1] 10137 // A list item that appears in a reduction clause of a worksharing 10138 // construct must be shared in the parallel regions to which any of the 10139 // worksharing regions arising from the worksharing construct bind. 10140 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 10141 if (isOpenMPWorksharingDirective(CurrDir) && 10142 !isOpenMPParallelDirective(CurrDir) && 10143 !isOpenMPTeamsDirective(CurrDir)) { 10144 DVar = Stack->getImplicitDSA(D, true); 10145 if (DVar.CKind != OMPC_shared) { 10146 S.Diag(ELoc, diag::err_omp_required_access) 10147 << getOpenMPClauseName(OMPC_reduction) 10148 << getOpenMPClauseName(OMPC_shared); 10149 ReportOriginalDSA(S, Stack, D, DVar); 10150 continue; 10151 } 10152 } 10153 10154 // Try to find 'declare reduction' corresponding construct before using 10155 // builtin/overloaded operators. 10156 CXXCastPath BasePath; 10157 ExprResult DeclareReductionRef = buildDeclareReductionRef( 10158 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 10159 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 10160 if (DeclareReductionRef.isInvalid()) 10161 continue; 10162 if (S.CurContext->isDependentContext() && 10163 (DeclareReductionRef.isUnset() || 10164 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 10165 RD.push(RefExpr, DeclareReductionRef.get()); 10166 continue; 10167 } 10168 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 10169 // Not allowed reduction identifier is found. 10170 S.Diag(ReductionId.getLocStart(), 10171 diag::err_omp_unknown_reduction_identifier) 10172 << Type << ReductionIdRange; 10173 continue; 10174 } 10175 10176 // OpenMP [2.14.3.6, reduction clause, Restrictions] 10177 // The type of a list item that appears in a reduction clause must be valid 10178 // for the reduction-identifier. For a max or min reduction in C, the type 10179 // of the list item must be an allowed arithmetic data type: char, int, 10180 // float, double, or _Bool, possibly modified with long, short, signed, or 10181 // unsigned. For a max or min reduction in C++, the type of the list item 10182 // must be an allowed arithmetic data type: char, wchar_t, int, float, 10183 // double, or bool, possibly modified with long, short, signed, or unsigned. 10184 if (DeclareReductionRef.isUnset()) { 10185 if ((BOK == BO_GT || BOK == BO_LT) && 10186 !(Type->isScalarType() || 10187 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 10188 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 10189 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 10190 if (!ASE && !OASE) { 10191 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 10192 VarDecl::DeclarationOnly; 10193 S.Diag(D->getLocation(), 10194 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10195 << D; 10196 } 10197 continue; 10198 } 10199 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 10200 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 10201 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 10202 << getOpenMPClauseName(ClauseKind); 10203 if (!ASE && !OASE) { 10204 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 10205 VarDecl::DeclarationOnly; 10206 S.Diag(D->getLocation(), 10207 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10208 << D; 10209 } 10210 continue; 10211 } 10212 } 10213 10214 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 10215 auto *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 10216 D->hasAttrs() ? &D->getAttrs() : nullptr); 10217 auto *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 10218 D->hasAttrs() ? &D->getAttrs() : nullptr); 10219 auto PrivateTy = Type; 10220 10221 // Try if we can determine constant lengths for all array sections and avoid 10222 // the VLA. 10223 bool ConstantLengthOASE = false; 10224 if (OASE) { 10225 bool SingleElement; 10226 llvm::SmallVector<llvm::APSInt, 4> ArraySizes; 10227 ConstantLengthOASE = CheckOMPArraySectionConstantForReduction( 10228 Context, OASE, SingleElement, ArraySizes); 10229 10230 // If we don't have a single element, we must emit a constant array type. 10231 if (ConstantLengthOASE && !SingleElement) { 10232 for (auto &Size : ArraySizes) { 10233 PrivateTy = Context.getConstantArrayType( 10234 PrivateTy, Size, ArrayType::Normal, /*IndexTypeQuals=*/0); 10235 } 10236 } 10237 } 10238 10239 if ((OASE && !ConstantLengthOASE) || 10240 (!OASE && !ASE && 10241 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 10242 if (!Context.getTargetInfo().isVLASupported() && 10243 S.shouldDiagnoseTargetSupportFromOpenMP()) { 10244 S.Diag(ELoc, diag::err_omp_reduction_vla_unsupported) << !!OASE; 10245 S.Diag(ELoc, diag::note_vla_unsupported); 10246 continue; 10247 } 10248 // For arrays/array sections only: 10249 // Create pseudo array type for private copy. The size for this array will 10250 // be generated during codegen. 10251 // For array subscripts or single variables Private Ty is the same as Type 10252 // (type of the variable or single array element). 10253 PrivateTy = Context.getVariableArrayType( 10254 Type, 10255 new (Context) OpaqueValueExpr(ELoc, Context.getSizeType(), VK_RValue), 10256 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 10257 } else if (!ASE && !OASE && 10258 Context.getAsArrayType(D->getType().getNonReferenceType())) 10259 PrivateTy = D->getType().getNonReferenceType(); 10260 // Private copy. 10261 auto *PrivateVD = buildVarDecl(S, ELoc, PrivateTy, D->getName(), 10262 D->hasAttrs() ? &D->getAttrs() : nullptr); 10263 // Add initializer for private variable. 10264 Expr *Init = nullptr; 10265 auto *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 10266 auto *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 10267 if (DeclareReductionRef.isUsable()) { 10268 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 10269 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 10270 if (DRD->getInitializer()) { 10271 Init = DRDRef; 10272 RHSVD->setInit(DRDRef); 10273 RHSVD->setInitStyle(VarDecl::CallInit); 10274 } 10275 } else { 10276 switch (BOK) { 10277 case BO_Add: 10278 case BO_Xor: 10279 case BO_Or: 10280 case BO_LOr: 10281 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 10282 if (Type->isScalarType() || Type->isAnyComplexType()) 10283 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 10284 break; 10285 case BO_Mul: 10286 case BO_LAnd: 10287 if (Type->isScalarType() || Type->isAnyComplexType()) { 10288 // '*' and '&&' reduction ops - initializer is '1'. 10289 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 10290 } 10291 break; 10292 case BO_And: { 10293 // '&' reduction op - initializer is '~0'. 10294 QualType OrigType = Type; 10295 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 10296 Type = ComplexTy->getElementType(); 10297 if (Type->isRealFloatingType()) { 10298 llvm::APFloat InitValue = 10299 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 10300 /*isIEEE=*/true); 10301 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 10302 Type, ELoc); 10303 } else if (Type->isScalarType()) { 10304 auto Size = Context.getTypeSize(Type); 10305 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 10306 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 10307 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 10308 } 10309 if (Init && OrigType->isAnyComplexType()) { 10310 // Init = 0xFFFF + 0xFFFFi; 10311 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 10312 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 10313 } 10314 Type = OrigType; 10315 break; 10316 } 10317 case BO_LT: 10318 case BO_GT: { 10319 // 'min' reduction op - initializer is 'Largest representable number in 10320 // the reduction list item type'. 10321 // 'max' reduction op - initializer is 'Least representable number in 10322 // the reduction list item type'. 10323 if (Type->isIntegerType() || Type->isPointerType()) { 10324 bool IsSigned = Type->hasSignedIntegerRepresentation(); 10325 auto Size = Context.getTypeSize(Type); 10326 QualType IntTy = 10327 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 10328 llvm::APInt InitValue = 10329 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 10330 : llvm::APInt::getMinValue(Size) 10331 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 10332 : llvm::APInt::getMaxValue(Size); 10333 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 10334 if (Type->isPointerType()) { 10335 // Cast to pointer type. 10336 auto CastExpr = S.BuildCStyleCastExpr( 10337 ELoc, Context.getTrivialTypeSourceInfo(Type, ELoc), ELoc, Init); 10338 if (CastExpr.isInvalid()) 10339 continue; 10340 Init = CastExpr.get(); 10341 } 10342 } else if (Type->isRealFloatingType()) { 10343 llvm::APFloat InitValue = llvm::APFloat::getLargest( 10344 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 10345 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 10346 Type, ELoc); 10347 } 10348 break; 10349 } 10350 case BO_PtrMemD: 10351 case BO_PtrMemI: 10352 case BO_MulAssign: 10353 case BO_Div: 10354 case BO_Rem: 10355 case BO_Sub: 10356 case BO_Shl: 10357 case BO_Shr: 10358 case BO_LE: 10359 case BO_GE: 10360 case BO_EQ: 10361 case BO_NE: 10362 case BO_Cmp: 10363 case BO_AndAssign: 10364 case BO_XorAssign: 10365 case BO_OrAssign: 10366 case BO_Assign: 10367 case BO_AddAssign: 10368 case BO_SubAssign: 10369 case BO_DivAssign: 10370 case BO_RemAssign: 10371 case BO_ShlAssign: 10372 case BO_ShrAssign: 10373 case BO_Comma: 10374 llvm_unreachable("Unexpected reduction operation"); 10375 } 10376 } 10377 if (Init && DeclareReductionRef.isUnset()) 10378 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 10379 else if (!Init) 10380 S.ActOnUninitializedDecl(RHSVD); 10381 if (RHSVD->isInvalidDecl()) 10382 continue; 10383 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 10384 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 10385 << Type << ReductionIdRange; 10386 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 10387 VarDecl::DeclarationOnly; 10388 S.Diag(D->getLocation(), 10389 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10390 << D; 10391 continue; 10392 } 10393 // Store initializer for single element in private copy. Will be used during 10394 // codegen. 10395 PrivateVD->setInit(RHSVD->getInit()); 10396 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 10397 auto *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 10398 ExprResult ReductionOp; 10399 if (DeclareReductionRef.isUsable()) { 10400 QualType RedTy = DeclareReductionRef.get()->getType(); 10401 QualType PtrRedTy = Context.getPointerType(RedTy); 10402 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 10403 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 10404 if (!BasePath.empty()) { 10405 LHS = S.DefaultLvalueConversion(LHS.get()); 10406 RHS = S.DefaultLvalueConversion(RHS.get()); 10407 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 10408 CK_UncheckedDerivedToBase, LHS.get(), 10409 &BasePath, LHS.get()->getValueKind()); 10410 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 10411 CK_UncheckedDerivedToBase, RHS.get(), 10412 &BasePath, RHS.get()->getValueKind()); 10413 } 10414 FunctionProtoType::ExtProtoInfo EPI; 10415 QualType Params[] = {PtrRedTy, PtrRedTy}; 10416 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 10417 auto *OVE = new (Context) OpaqueValueExpr( 10418 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 10419 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 10420 Expr *Args[] = {LHS.get(), RHS.get()}; 10421 ReductionOp = new (Context) 10422 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 10423 } else { 10424 ReductionOp = S.BuildBinOp( 10425 Stack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE); 10426 if (ReductionOp.isUsable()) { 10427 if (BOK != BO_LT && BOK != BO_GT) { 10428 ReductionOp = 10429 S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(), 10430 BO_Assign, LHSDRE, ReductionOp.get()); 10431 } else { 10432 auto *ConditionalOp = new (Context) 10433 ConditionalOperator(ReductionOp.get(), ELoc, LHSDRE, ELoc, RHSDRE, 10434 Type, VK_LValue, OK_Ordinary); 10435 ReductionOp = 10436 S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(), 10437 BO_Assign, LHSDRE, ConditionalOp); 10438 } 10439 if (ReductionOp.isUsable()) 10440 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get()); 10441 } 10442 if (!ReductionOp.isUsable()) 10443 continue; 10444 } 10445 10446 // OpenMP [2.15.4.6, Restrictions, p.2] 10447 // A list item that appears in an in_reduction clause of a task construct 10448 // must appear in a task_reduction clause of a construct associated with a 10449 // taskgroup region that includes the participating task in its taskgroup 10450 // set. The construct associated with the innermost region that meets this 10451 // condition must specify the same reduction-identifier as the in_reduction 10452 // clause. 10453 if (ClauseKind == OMPC_in_reduction) { 10454 SourceRange ParentSR; 10455 BinaryOperatorKind ParentBOK; 10456 const Expr *ParentReductionOp; 10457 Expr *ParentBOKTD, *ParentReductionOpTD; 10458 DSAStackTy::DSAVarData ParentBOKDSA = 10459 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 10460 ParentBOKTD); 10461 DSAStackTy::DSAVarData ParentReductionOpDSA = 10462 Stack->getTopMostTaskgroupReductionData( 10463 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 10464 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 10465 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 10466 if (!IsParentBOK && !IsParentReductionOp) { 10467 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 10468 continue; 10469 } 10470 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 10471 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 10472 IsParentReductionOp) { 10473 bool EmitError = true; 10474 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 10475 llvm::FoldingSetNodeID RedId, ParentRedId; 10476 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 10477 DeclareReductionRef.get()->Profile(RedId, Context, 10478 /*Canonical=*/true); 10479 EmitError = RedId != ParentRedId; 10480 } 10481 if (EmitError) { 10482 S.Diag(ReductionId.getLocStart(), 10483 diag::err_omp_reduction_identifier_mismatch) 10484 << ReductionIdRange << RefExpr->getSourceRange(); 10485 S.Diag(ParentSR.getBegin(), 10486 diag::note_omp_previous_reduction_identifier) 10487 << ParentSR 10488 << (IsParentBOK ? ParentBOKDSA.RefExpr 10489 : ParentReductionOpDSA.RefExpr) 10490 ->getSourceRange(); 10491 continue; 10492 } 10493 } 10494 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 10495 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 10496 } 10497 10498 DeclRefExpr *Ref = nullptr; 10499 Expr *VarsExpr = RefExpr->IgnoreParens(); 10500 if (!VD && !S.CurContext->isDependentContext()) { 10501 if (ASE || OASE) { 10502 TransformExprToCaptures RebuildToCapture(S, D); 10503 VarsExpr = 10504 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 10505 Ref = RebuildToCapture.getCapturedExpr(); 10506 } else { 10507 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 10508 } 10509 if (!S.IsOpenMPCapturedDecl(D)) { 10510 RD.ExprCaptures.emplace_back(Ref->getDecl()); 10511 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 10512 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 10513 if (!RefRes.isUsable()) 10514 continue; 10515 ExprResult PostUpdateRes = 10516 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 10517 RefRes.get()); 10518 if (!PostUpdateRes.isUsable()) 10519 continue; 10520 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 10521 Stack->getCurrentDirective() == OMPD_taskgroup) { 10522 S.Diag(RefExpr->getExprLoc(), 10523 diag::err_omp_reduction_non_addressable_expression) 10524 << RefExpr->getSourceRange(); 10525 continue; 10526 } 10527 RD.ExprPostUpdates.emplace_back( 10528 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 10529 } 10530 } 10531 } 10532 // All reduction items are still marked as reduction (to do not increase 10533 // code base size). 10534 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 10535 if (CurrDir == OMPD_taskgroup) { 10536 if (DeclareReductionRef.isUsable()) 10537 Stack->addTaskgroupReductionData(D, ReductionIdRange, 10538 DeclareReductionRef.get()); 10539 else 10540 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 10541 } 10542 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 10543 TaskgroupDescriptor); 10544 } 10545 return RD.Vars.empty(); 10546 } 10547 10548 OMPClause *Sema::ActOnOpenMPReductionClause( 10549 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 10550 SourceLocation ColonLoc, SourceLocation EndLoc, 10551 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 10552 ArrayRef<Expr *> UnresolvedReductions) { 10553 ReductionData RD(VarList.size()); 10554 10555 if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 10556 StartLoc, LParenLoc, ColonLoc, EndLoc, 10557 ReductionIdScopeSpec, ReductionId, 10558 UnresolvedReductions, RD)) 10559 return nullptr; 10560 10561 return OMPReductionClause::Create( 10562 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 10563 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 10564 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 10565 buildPreInits(Context, RD.ExprCaptures), 10566 buildPostUpdate(*this, RD.ExprPostUpdates)); 10567 } 10568 10569 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 10570 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 10571 SourceLocation ColonLoc, SourceLocation EndLoc, 10572 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 10573 ArrayRef<Expr *> UnresolvedReductions) { 10574 ReductionData RD(VarList.size()); 10575 10576 if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, 10577 VarList, StartLoc, LParenLoc, ColonLoc, 10578 EndLoc, ReductionIdScopeSpec, ReductionId, 10579 UnresolvedReductions, RD)) 10580 return nullptr; 10581 10582 return OMPTaskReductionClause::Create( 10583 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 10584 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 10585 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 10586 buildPreInits(Context, RD.ExprCaptures), 10587 buildPostUpdate(*this, RD.ExprPostUpdates)); 10588 } 10589 10590 OMPClause *Sema::ActOnOpenMPInReductionClause( 10591 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 10592 SourceLocation ColonLoc, SourceLocation EndLoc, 10593 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 10594 ArrayRef<Expr *> UnresolvedReductions) { 10595 ReductionData RD(VarList.size()); 10596 10597 if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 10598 StartLoc, LParenLoc, ColonLoc, EndLoc, 10599 ReductionIdScopeSpec, ReductionId, 10600 UnresolvedReductions, RD)) 10601 return nullptr; 10602 10603 return OMPInReductionClause::Create( 10604 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 10605 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 10606 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 10607 buildPreInits(Context, RD.ExprCaptures), 10608 buildPostUpdate(*this, RD.ExprPostUpdates)); 10609 } 10610 10611 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 10612 SourceLocation LinLoc) { 10613 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 10614 LinKind == OMPC_LINEAR_unknown) { 10615 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 10616 return true; 10617 } 10618 return false; 10619 } 10620 10621 bool Sema::CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, 10622 OpenMPLinearClauseKind LinKind, 10623 QualType Type) { 10624 auto *VD = dyn_cast_or_null<VarDecl>(D); 10625 // A variable must not have an incomplete type or a reference type. 10626 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 10627 return true; 10628 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 10629 !Type->isReferenceType()) { 10630 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 10631 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 10632 return true; 10633 } 10634 Type = Type.getNonReferenceType(); 10635 10636 // A list item must not be const-qualified. 10637 if (Type.isConstant(Context)) { 10638 Diag(ELoc, diag::err_omp_const_variable) 10639 << getOpenMPClauseName(OMPC_linear); 10640 if (D) { 10641 bool IsDecl = 10642 !VD || 10643 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10644 Diag(D->getLocation(), 10645 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10646 << D; 10647 } 10648 return true; 10649 } 10650 10651 // A list item must be of integral or pointer type. 10652 Type = Type.getUnqualifiedType().getCanonicalType(); 10653 const auto *Ty = Type.getTypePtrOrNull(); 10654 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 10655 !Ty->isPointerType())) { 10656 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 10657 if (D) { 10658 bool IsDecl = 10659 !VD || 10660 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10661 Diag(D->getLocation(), 10662 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10663 << D; 10664 } 10665 return true; 10666 } 10667 return false; 10668 } 10669 10670 OMPClause *Sema::ActOnOpenMPLinearClause( 10671 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 10672 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 10673 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 10674 SmallVector<Expr *, 8> Vars; 10675 SmallVector<Expr *, 8> Privates; 10676 SmallVector<Expr *, 8> Inits; 10677 SmallVector<Decl *, 4> ExprCaptures; 10678 SmallVector<Expr *, 4> ExprPostUpdates; 10679 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 10680 LinKind = OMPC_LINEAR_val; 10681 for (auto &RefExpr : VarList) { 10682 assert(RefExpr && "NULL expr in OpenMP linear clause."); 10683 SourceLocation ELoc; 10684 SourceRange ERange; 10685 Expr *SimpleRefExpr = RefExpr; 10686 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 10687 /*AllowArraySection=*/false); 10688 if (Res.second) { 10689 // It will be analyzed later. 10690 Vars.push_back(RefExpr); 10691 Privates.push_back(nullptr); 10692 Inits.push_back(nullptr); 10693 } 10694 ValueDecl *D = Res.first; 10695 if (!D) 10696 continue; 10697 10698 QualType Type = D->getType(); 10699 auto *VD = dyn_cast<VarDecl>(D); 10700 10701 // OpenMP [2.14.3.7, linear clause] 10702 // A list-item cannot appear in more than one linear clause. 10703 // A list-item that appears in a linear clause cannot appear in any 10704 // other data-sharing attribute clause. 10705 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 10706 if (DVar.RefExpr) { 10707 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10708 << getOpenMPClauseName(OMPC_linear); 10709 ReportOriginalDSA(*this, DSAStack, D, DVar); 10710 continue; 10711 } 10712 10713 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 10714 continue; 10715 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 10716 10717 // Build private copy of original var. 10718 auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(), 10719 D->hasAttrs() ? &D->getAttrs() : nullptr); 10720 auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 10721 // Build var to save initial value. 10722 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 10723 Expr *InitExpr; 10724 DeclRefExpr *Ref = nullptr; 10725 if (!VD && !CurContext->isDependentContext()) { 10726 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10727 if (!IsOpenMPCapturedDecl(D)) { 10728 ExprCaptures.push_back(Ref->getDecl()); 10729 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 10730 ExprResult RefRes = DefaultLvalueConversion(Ref); 10731 if (!RefRes.isUsable()) 10732 continue; 10733 ExprResult PostUpdateRes = 10734 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 10735 SimpleRefExpr, RefRes.get()); 10736 if (!PostUpdateRes.isUsable()) 10737 continue; 10738 ExprPostUpdates.push_back( 10739 IgnoredValueConversions(PostUpdateRes.get()).get()); 10740 } 10741 } 10742 } 10743 if (LinKind == OMPC_LINEAR_uval) 10744 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 10745 else 10746 InitExpr = VD ? SimpleRefExpr : Ref; 10747 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 10748 /*DirectInit=*/false); 10749 auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 10750 10751 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 10752 Vars.push_back((VD || CurContext->isDependentContext()) 10753 ? RefExpr->IgnoreParens() 10754 : Ref); 10755 Privates.push_back(PrivateRef); 10756 Inits.push_back(InitRef); 10757 } 10758 10759 if (Vars.empty()) 10760 return nullptr; 10761 10762 Expr *StepExpr = Step; 10763 Expr *CalcStepExpr = nullptr; 10764 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 10765 !Step->isInstantiationDependent() && 10766 !Step->containsUnexpandedParameterPack()) { 10767 SourceLocation StepLoc = Step->getLocStart(); 10768 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 10769 if (Val.isInvalid()) 10770 return nullptr; 10771 StepExpr = Val.get(); 10772 10773 // Build var to save the step value. 10774 VarDecl *SaveVar = 10775 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 10776 ExprResult SaveRef = 10777 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 10778 ExprResult CalcStep = 10779 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 10780 CalcStep = ActOnFinishFullExpr(CalcStep.get()); 10781 10782 // Warn about zero linear step (it would be probably better specified as 10783 // making corresponding variables 'const'). 10784 llvm::APSInt Result; 10785 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 10786 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 10787 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 10788 << (Vars.size() > 1); 10789 if (!IsConstant && CalcStep.isUsable()) { 10790 // Calculate the step beforehand instead of doing this on each iteration. 10791 // (This is not used if the number of iterations may be kfold-ed). 10792 CalcStepExpr = CalcStep.get(); 10793 } 10794 } 10795 10796 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 10797 ColonLoc, EndLoc, Vars, Privates, Inits, 10798 StepExpr, CalcStepExpr, 10799 buildPreInits(Context, ExprCaptures), 10800 buildPostUpdate(*this, ExprPostUpdates)); 10801 } 10802 10803 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 10804 Expr *NumIterations, Sema &SemaRef, 10805 Scope *S, DSAStackTy *Stack) { 10806 // Walk the vars and build update/final expressions for the CodeGen. 10807 SmallVector<Expr *, 8> Updates; 10808 SmallVector<Expr *, 8> Finals; 10809 Expr *Step = Clause.getStep(); 10810 Expr *CalcStep = Clause.getCalcStep(); 10811 // OpenMP [2.14.3.7, linear clause] 10812 // If linear-step is not specified it is assumed to be 1. 10813 if (Step == nullptr) 10814 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 10815 else if (CalcStep) { 10816 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 10817 } 10818 bool HasErrors = false; 10819 auto CurInit = Clause.inits().begin(); 10820 auto CurPrivate = Clause.privates().begin(); 10821 auto LinKind = Clause.getModifier(); 10822 for (auto &RefExpr : Clause.varlists()) { 10823 SourceLocation ELoc; 10824 SourceRange ERange; 10825 Expr *SimpleRefExpr = RefExpr; 10826 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange, 10827 /*AllowArraySection=*/false); 10828 ValueDecl *D = Res.first; 10829 if (Res.second || !D) { 10830 Updates.push_back(nullptr); 10831 Finals.push_back(nullptr); 10832 HasErrors = true; 10833 continue; 10834 } 10835 auto &&Info = Stack->isLoopControlVariable(D); 10836 // OpenMP [2.15.11, distribute simd Construct] 10837 // A list item may not appear in a linear clause, unless it is the loop 10838 // iteration variable. 10839 if (isOpenMPDistributeDirective(Stack->getCurrentDirective()) && 10840 isOpenMPSimdDirective(Stack->getCurrentDirective()) && !Info.first) { 10841 SemaRef.Diag(ELoc, 10842 diag::err_omp_linear_distribute_var_non_loop_iteration); 10843 Updates.push_back(nullptr); 10844 Finals.push_back(nullptr); 10845 HasErrors = true; 10846 continue; 10847 } 10848 Expr *InitExpr = *CurInit; 10849 10850 // Build privatized reference to the current linear var. 10851 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 10852 Expr *CapturedRef; 10853 if (LinKind == OMPC_LINEAR_uval) 10854 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 10855 else 10856 CapturedRef = 10857 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 10858 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 10859 /*RefersToCapture=*/true); 10860 10861 // Build update: Var = InitExpr + IV * Step 10862 ExprResult Update; 10863 if (!Info.first) { 10864 Update = 10865 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 10866 InitExpr, IV, Step, /* Subtract */ false); 10867 } else 10868 Update = *CurPrivate; 10869 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(), 10870 /*DiscardedValue=*/true); 10871 10872 // Build final: Var = InitExpr + NumIterations * Step 10873 ExprResult Final; 10874 if (!Info.first) { 10875 Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 10876 InitExpr, NumIterations, Step, 10877 /* Subtract */ false); 10878 } else 10879 Final = *CurPrivate; 10880 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(), 10881 /*DiscardedValue=*/true); 10882 10883 if (!Update.isUsable() || !Final.isUsable()) { 10884 Updates.push_back(nullptr); 10885 Finals.push_back(nullptr); 10886 HasErrors = true; 10887 } else { 10888 Updates.push_back(Update.get()); 10889 Finals.push_back(Final.get()); 10890 } 10891 ++CurInit; 10892 ++CurPrivate; 10893 } 10894 Clause.setUpdates(Updates); 10895 Clause.setFinals(Finals); 10896 return HasErrors; 10897 } 10898 10899 OMPClause *Sema::ActOnOpenMPAlignedClause( 10900 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 10901 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 10902 10903 SmallVector<Expr *, 8> Vars; 10904 for (auto &RefExpr : VarList) { 10905 assert(RefExpr && "NULL expr in OpenMP linear clause."); 10906 SourceLocation ELoc; 10907 SourceRange ERange; 10908 Expr *SimpleRefExpr = RefExpr; 10909 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 10910 /*AllowArraySection=*/false); 10911 if (Res.second) { 10912 // It will be analyzed later. 10913 Vars.push_back(RefExpr); 10914 } 10915 ValueDecl *D = Res.first; 10916 if (!D) 10917 continue; 10918 10919 QualType QType = D->getType(); 10920 auto *VD = dyn_cast<VarDecl>(D); 10921 10922 // OpenMP [2.8.1, simd construct, Restrictions] 10923 // The type of list items appearing in the aligned clause must be 10924 // array, pointer, reference to array, or reference to pointer. 10925 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 10926 const Type *Ty = QType.getTypePtrOrNull(); 10927 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 10928 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 10929 << QType << getLangOpts().CPlusPlus << ERange; 10930 bool IsDecl = 10931 !VD || 10932 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10933 Diag(D->getLocation(), 10934 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10935 << D; 10936 continue; 10937 } 10938 10939 // OpenMP [2.8.1, simd construct, Restrictions] 10940 // A list-item cannot appear in more than one aligned clause. 10941 if (Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 10942 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 10943 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 10944 << getOpenMPClauseName(OMPC_aligned); 10945 continue; 10946 } 10947 10948 DeclRefExpr *Ref = nullptr; 10949 if (!VD && IsOpenMPCapturedDecl(D)) 10950 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10951 Vars.push_back(DefaultFunctionArrayConversion( 10952 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 10953 .get()); 10954 } 10955 10956 // OpenMP [2.8.1, simd construct, Description] 10957 // The parameter of the aligned clause, alignment, must be a constant 10958 // positive integer expression. 10959 // If no optional parameter is specified, implementation-defined default 10960 // alignments for SIMD instructions on the target platforms are assumed. 10961 if (Alignment != nullptr) { 10962 ExprResult AlignResult = 10963 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 10964 if (AlignResult.isInvalid()) 10965 return nullptr; 10966 Alignment = AlignResult.get(); 10967 } 10968 if (Vars.empty()) 10969 return nullptr; 10970 10971 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 10972 EndLoc, Vars, Alignment); 10973 } 10974 10975 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 10976 SourceLocation StartLoc, 10977 SourceLocation LParenLoc, 10978 SourceLocation EndLoc) { 10979 SmallVector<Expr *, 8> Vars; 10980 SmallVector<Expr *, 8> SrcExprs; 10981 SmallVector<Expr *, 8> DstExprs; 10982 SmallVector<Expr *, 8> AssignmentOps; 10983 for (auto &RefExpr : VarList) { 10984 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 10985 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 10986 // It will be analyzed later. 10987 Vars.push_back(RefExpr); 10988 SrcExprs.push_back(nullptr); 10989 DstExprs.push_back(nullptr); 10990 AssignmentOps.push_back(nullptr); 10991 continue; 10992 } 10993 10994 SourceLocation ELoc = RefExpr->getExprLoc(); 10995 // OpenMP [2.1, C/C++] 10996 // A list item is a variable name. 10997 // OpenMP [2.14.4.1, Restrictions, p.1] 10998 // A list item that appears in a copyin clause must be threadprivate. 10999 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 11000 if (!DE || !isa<VarDecl>(DE->getDecl())) { 11001 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 11002 << 0 << RefExpr->getSourceRange(); 11003 continue; 11004 } 11005 11006 Decl *D = DE->getDecl(); 11007 VarDecl *VD = cast<VarDecl>(D); 11008 11009 QualType Type = VD->getType(); 11010 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 11011 // It will be analyzed later. 11012 Vars.push_back(DE); 11013 SrcExprs.push_back(nullptr); 11014 DstExprs.push_back(nullptr); 11015 AssignmentOps.push_back(nullptr); 11016 continue; 11017 } 11018 11019 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 11020 // A list item that appears in a copyin clause must be threadprivate. 11021 if (!DSAStack->isThreadPrivate(VD)) { 11022 Diag(ELoc, diag::err_omp_required_access) 11023 << getOpenMPClauseName(OMPC_copyin) 11024 << getOpenMPDirectiveName(OMPD_threadprivate); 11025 continue; 11026 } 11027 11028 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 11029 // A variable of class type (or array thereof) that appears in a 11030 // copyin clause requires an accessible, unambiguous copy assignment 11031 // operator for the class type. 11032 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 11033 auto *SrcVD = 11034 buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(), 11035 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 11036 auto *PseudoSrcExpr = buildDeclRefExpr( 11037 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 11038 auto *DstVD = 11039 buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst", 11040 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 11041 auto *PseudoDstExpr = 11042 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 11043 // For arrays generate assignment operation for single element and replace 11044 // it by the original array element in CodeGen. 11045 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 11046 PseudoDstExpr, PseudoSrcExpr); 11047 if (AssignmentOp.isInvalid()) 11048 continue; 11049 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 11050 /*DiscardedValue=*/true); 11051 if (AssignmentOp.isInvalid()) 11052 continue; 11053 11054 DSAStack->addDSA(VD, DE, OMPC_copyin); 11055 Vars.push_back(DE); 11056 SrcExprs.push_back(PseudoSrcExpr); 11057 DstExprs.push_back(PseudoDstExpr); 11058 AssignmentOps.push_back(AssignmentOp.get()); 11059 } 11060 11061 if (Vars.empty()) 11062 return nullptr; 11063 11064 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 11065 SrcExprs, DstExprs, AssignmentOps); 11066 } 11067 11068 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 11069 SourceLocation StartLoc, 11070 SourceLocation LParenLoc, 11071 SourceLocation EndLoc) { 11072 SmallVector<Expr *, 8> Vars; 11073 SmallVector<Expr *, 8> SrcExprs; 11074 SmallVector<Expr *, 8> DstExprs; 11075 SmallVector<Expr *, 8> AssignmentOps; 11076 for (auto &RefExpr : VarList) { 11077 assert(RefExpr && "NULL expr in OpenMP linear clause."); 11078 SourceLocation ELoc; 11079 SourceRange ERange; 11080 Expr *SimpleRefExpr = RefExpr; 11081 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 11082 /*AllowArraySection=*/false); 11083 if (Res.second) { 11084 // It will be analyzed later. 11085 Vars.push_back(RefExpr); 11086 SrcExprs.push_back(nullptr); 11087 DstExprs.push_back(nullptr); 11088 AssignmentOps.push_back(nullptr); 11089 } 11090 ValueDecl *D = Res.first; 11091 if (!D) 11092 continue; 11093 11094 QualType Type = D->getType(); 11095 auto *VD = dyn_cast<VarDecl>(D); 11096 11097 // OpenMP [2.14.4.2, Restrictions, p.2] 11098 // A list item that appears in a copyprivate clause may not appear in a 11099 // private or firstprivate clause on the single construct. 11100 if (!VD || !DSAStack->isThreadPrivate(VD)) { 11101 auto DVar = DSAStack->getTopDSA(D, false); 11102 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 11103 DVar.RefExpr) { 11104 Diag(ELoc, diag::err_omp_wrong_dsa) 11105 << getOpenMPClauseName(DVar.CKind) 11106 << getOpenMPClauseName(OMPC_copyprivate); 11107 ReportOriginalDSA(*this, DSAStack, D, DVar); 11108 continue; 11109 } 11110 11111 // OpenMP [2.11.4.2, Restrictions, p.1] 11112 // All list items that appear in a copyprivate clause must be either 11113 // threadprivate or private in the enclosing context. 11114 if (DVar.CKind == OMPC_unknown) { 11115 DVar = DSAStack->getImplicitDSA(D, false); 11116 if (DVar.CKind == OMPC_shared) { 11117 Diag(ELoc, diag::err_omp_required_access) 11118 << getOpenMPClauseName(OMPC_copyprivate) 11119 << "threadprivate or private in the enclosing context"; 11120 ReportOriginalDSA(*this, DSAStack, D, DVar); 11121 continue; 11122 } 11123 } 11124 } 11125 11126 // Variably modified types are not supported. 11127 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 11128 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 11129 << getOpenMPClauseName(OMPC_copyprivate) << Type 11130 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11131 bool IsDecl = 11132 !VD || 11133 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 11134 Diag(D->getLocation(), 11135 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 11136 << D; 11137 continue; 11138 } 11139 11140 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 11141 // A variable of class type (or array thereof) that appears in a 11142 // copyin clause requires an accessible, unambiguous copy assignment 11143 // operator for the class type. 11144 Type = Context.getBaseElementType(Type.getNonReferenceType()) 11145 .getUnqualifiedType(); 11146 auto *SrcVD = 11147 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src", 11148 D->hasAttrs() ? &D->getAttrs() : nullptr); 11149 auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 11150 auto *DstVD = 11151 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst", 11152 D->hasAttrs() ? &D->getAttrs() : nullptr); 11153 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 11154 auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 11155 PseudoDstExpr, PseudoSrcExpr); 11156 if (AssignmentOp.isInvalid()) 11157 continue; 11158 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 11159 /*DiscardedValue=*/true); 11160 if (AssignmentOp.isInvalid()) 11161 continue; 11162 11163 // No need to mark vars as copyprivate, they are already threadprivate or 11164 // implicitly private. 11165 assert(VD || IsOpenMPCapturedDecl(D)); 11166 Vars.push_back( 11167 VD ? RefExpr->IgnoreParens() 11168 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 11169 SrcExprs.push_back(PseudoSrcExpr); 11170 DstExprs.push_back(PseudoDstExpr); 11171 AssignmentOps.push_back(AssignmentOp.get()); 11172 } 11173 11174 if (Vars.empty()) 11175 return nullptr; 11176 11177 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11178 Vars, SrcExprs, DstExprs, AssignmentOps); 11179 } 11180 11181 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 11182 SourceLocation StartLoc, 11183 SourceLocation LParenLoc, 11184 SourceLocation EndLoc) { 11185 if (VarList.empty()) 11186 return nullptr; 11187 11188 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 11189 } 11190 11191 OMPClause * 11192 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 11193 SourceLocation DepLoc, SourceLocation ColonLoc, 11194 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 11195 SourceLocation LParenLoc, SourceLocation EndLoc) { 11196 if (DSAStack->getCurrentDirective() == OMPD_ordered && 11197 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 11198 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 11199 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 11200 return nullptr; 11201 } 11202 if (DSAStack->getCurrentDirective() != OMPD_ordered && 11203 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 11204 DepKind == OMPC_DEPEND_sink)) { 11205 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 11206 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 11207 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 11208 /*Last=*/OMPC_DEPEND_unknown, Except) 11209 << getOpenMPClauseName(OMPC_depend); 11210 return nullptr; 11211 } 11212 SmallVector<Expr *, 8> Vars; 11213 DSAStackTy::OperatorOffsetTy OpsOffs; 11214 llvm::APSInt DepCounter(/*BitWidth=*/32); 11215 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 11216 if (DepKind == OMPC_DEPEND_sink) { 11217 if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) { 11218 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 11219 TotalDepCount.setIsUnsigned(/*Val=*/true); 11220 } 11221 } 11222 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) || 11223 DSAStack->getParentOrderedRegionParam()) { 11224 for (auto &RefExpr : VarList) { 11225 assert(RefExpr && "NULL expr in OpenMP shared clause."); 11226 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 11227 // It will be analyzed later. 11228 Vars.push_back(RefExpr); 11229 continue; 11230 } 11231 11232 SourceLocation ELoc = RefExpr->getExprLoc(); 11233 auto *SimpleExpr = RefExpr->IgnoreParenCasts(); 11234 if (DepKind == OMPC_DEPEND_sink) { 11235 if (DepCounter >= TotalDepCount) { 11236 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 11237 continue; 11238 } 11239 ++DepCounter; 11240 // OpenMP [2.13.9, Summary] 11241 // depend(dependence-type : vec), where dependence-type is: 11242 // 'sink' and where vec is the iteration vector, which has the form: 11243 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 11244 // where n is the value specified by the ordered clause in the loop 11245 // directive, xi denotes the loop iteration variable of the i-th nested 11246 // loop associated with the loop directive, and di is a constant 11247 // non-negative integer. 11248 if (CurContext->isDependentContext()) { 11249 // It will be analyzed later. 11250 Vars.push_back(RefExpr); 11251 continue; 11252 } 11253 SimpleExpr = SimpleExpr->IgnoreImplicit(); 11254 OverloadedOperatorKind OOK = OO_None; 11255 SourceLocation OOLoc; 11256 Expr *LHS = SimpleExpr; 11257 Expr *RHS = nullptr; 11258 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 11259 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 11260 OOLoc = BO->getOperatorLoc(); 11261 LHS = BO->getLHS()->IgnoreParenImpCasts(); 11262 RHS = BO->getRHS()->IgnoreParenImpCasts(); 11263 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 11264 OOK = OCE->getOperator(); 11265 OOLoc = OCE->getOperatorLoc(); 11266 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 11267 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 11268 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 11269 OOK = MCE->getMethodDecl() 11270 ->getNameInfo() 11271 .getName() 11272 .getCXXOverloadedOperator(); 11273 OOLoc = MCE->getCallee()->getExprLoc(); 11274 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 11275 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 11276 } 11277 SourceLocation ELoc; 11278 SourceRange ERange; 11279 auto Res = getPrivateItem(*this, LHS, ELoc, ERange, 11280 /*AllowArraySection=*/false); 11281 if (Res.second) { 11282 // It will be analyzed later. 11283 Vars.push_back(RefExpr); 11284 } 11285 ValueDecl *D = Res.first; 11286 if (!D) 11287 continue; 11288 11289 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 11290 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 11291 continue; 11292 } 11293 if (RHS) { 11294 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 11295 RHS, OMPC_depend, /*StrictlyPositive=*/false); 11296 if (RHSRes.isInvalid()) 11297 continue; 11298 } 11299 if (!CurContext->isDependentContext() && 11300 DSAStack->getParentOrderedRegionParam() && 11301 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 11302 ValueDecl* VD = DSAStack->getParentLoopControlVariable( 11303 DepCounter.getZExtValue()); 11304 if (VD) { 11305 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 11306 << 1 << VD; 11307 } else { 11308 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 11309 } 11310 continue; 11311 } 11312 OpsOffs.push_back({RHS, OOK}); 11313 } else { 11314 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 11315 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 11316 (ASE && 11317 !ASE->getBase() 11318 ->getType() 11319 .getNonReferenceType() 11320 ->isPointerType() && 11321 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 11322 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 11323 << RefExpr->getSourceRange(); 11324 continue; 11325 } 11326 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 11327 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 11328 ExprResult Res = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, 11329 RefExpr->IgnoreParenImpCasts()); 11330 getDiagnostics().setSuppressAllDiagnostics(Suppress); 11331 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 11332 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 11333 << RefExpr->getSourceRange(); 11334 continue; 11335 } 11336 } 11337 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 11338 } 11339 11340 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 11341 TotalDepCount > VarList.size() && 11342 DSAStack->getParentOrderedRegionParam() && 11343 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 11344 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) << 1 11345 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 11346 } 11347 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 11348 Vars.empty()) 11349 return nullptr; 11350 } 11351 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11352 DepKind, DepLoc, ColonLoc, Vars); 11353 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) 11354 DSAStack->addDoacrossDependClause(C, OpsOffs); 11355 return C; 11356 } 11357 11358 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 11359 SourceLocation LParenLoc, 11360 SourceLocation EndLoc) { 11361 Expr *ValExpr = Device; 11362 Stmt *HelperValStmt = nullptr; 11363 11364 // OpenMP [2.9.1, Restrictions] 11365 // The device expression must evaluate to a non-negative integer value. 11366 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 11367 /*StrictlyPositive=*/false)) 11368 return nullptr; 11369 11370 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11371 OpenMPDirectiveKind CaptureRegion = 11372 getOpenMPCaptureRegionForClause(DKind, OMPC_device); 11373 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 11374 ValExpr = MakeFullExpr(ValExpr).get(); 11375 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 11376 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11377 HelperValStmt = buildPreInits(Context, Captures); 11378 } 11379 11380 return new (Context) 11381 OMPDeviceClause(ValExpr, HelperValStmt, StartLoc, LParenLoc, EndLoc); 11382 } 11383 11384 static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 11385 DSAStackTy *Stack, QualType QTy) { 11386 NamedDecl *ND; 11387 if (QTy->isIncompleteType(&ND)) { 11388 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 11389 return false; 11390 } 11391 return true; 11392 } 11393 11394 /// \brief Return true if it can be proven that the provided array expression 11395 /// (array section or array subscript) does NOT specify the whole size of the 11396 /// array whose base type is \a BaseQTy. 11397 static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 11398 const Expr *E, 11399 QualType BaseQTy) { 11400 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 11401 11402 // If this is an array subscript, it refers to the whole size if the size of 11403 // the dimension is constant and equals 1. Also, an array section assumes the 11404 // format of an array subscript if no colon is used. 11405 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 11406 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 11407 return ATy->getSize().getSExtValue() != 1; 11408 // Size can't be evaluated statically. 11409 return false; 11410 } 11411 11412 assert(OASE && "Expecting array section if not an array subscript."); 11413 auto *LowerBound = OASE->getLowerBound(); 11414 auto *Length = OASE->getLength(); 11415 11416 // If there is a lower bound that does not evaluates to zero, we are not 11417 // covering the whole dimension. 11418 if (LowerBound) { 11419 llvm::APSInt ConstLowerBound; 11420 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) 11421 return false; // Can't get the integer value as a constant. 11422 if (ConstLowerBound.getSExtValue()) 11423 return true; 11424 } 11425 11426 // If we don't have a length we covering the whole dimension. 11427 if (!Length) 11428 return false; 11429 11430 // If the base is a pointer, we don't have a way to get the size of the 11431 // pointee. 11432 if (BaseQTy->isPointerType()) 11433 return false; 11434 11435 // We can only check if the length is the same as the size of the dimension 11436 // if we have a constant array. 11437 auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 11438 if (!CATy) 11439 return false; 11440 11441 llvm::APSInt ConstLength; 11442 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 11443 return false; // Can't get the integer value as a constant. 11444 11445 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 11446 } 11447 11448 // Return true if it can be proven that the provided array expression (array 11449 // section or array subscript) does NOT specify a single element of the array 11450 // whose base type is \a BaseQTy. 11451 static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 11452 const Expr *E, 11453 QualType BaseQTy) { 11454 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 11455 11456 // An array subscript always refer to a single element. Also, an array section 11457 // assumes the format of an array subscript if no colon is used. 11458 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 11459 return false; 11460 11461 assert(OASE && "Expecting array section if not an array subscript."); 11462 auto *Length = OASE->getLength(); 11463 11464 // If we don't have a length we have to check if the array has unitary size 11465 // for this dimension. Also, we should always expect a length if the base type 11466 // is pointer. 11467 if (!Length) { 11468 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 11469 return ATy->getSize().getSExtValue() != 1; 11470 // We cannot assume anything. 11471 return false; 11472 } 11473 11474 // Check if the length evaluates to 1. 11475 llvm::APSInt ConstLength; 11476 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 11477 return false; // Can't get the integer value as a constant. 11478 11479 return ConstLength.getSExtValue() != 1; 11480 } 11481 11482 // Return the expression of the base of the mappable expression or null if it 11483 // cannot be determined and do all the necessary checks to see if the expression 11484 // is valid as a standalone mappable expression. In the process, record all the 11485 // components of the expression. 11486 static Expr *CheckMapClauseExpressionBase( 11487 Sema &SemaRef, Expr *E, 11488 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 11489 OpenMPClauseKind CKind, bool NoDiagnose) { 11490 SourceLocation ELoc = E->getExprLoc(); 11491 SourceRange ERange = E->getSourceRange(); 11492 11493 // The base of elements of list in a map clause have to be either: 11494 // - a reference to variable or field. 11495 // - a member expression. 11496 // - an array expression. 11497 // 11498 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 11499 // reference to 'r'. 11500 // 11501 // If we have: 11502 // 11503 // struct SS { 11504 // Bla S; 11505 // foo() { 11506 // #pragma omp target map (S.Arr[:12]); 11507 // } 11508 // } 11509 // 11510 // We want to retrieve the member expression 'this->S'; 11511 11512 Expr *RelevantExpr = nullptr; 11513 11514 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 11515 // If a list item is an array section, it must specify contiguous storage. 11516 // 11517 // For this restriction it is sufficient that we make sure only references 11518 // to variables or fields and array expressions, and that no array sections 11519 // exist except in the rightmost expression (unless they cover the whole 11520 // dimension of the array). E.g. these would be invalid: 11521 // 11522 // r.ArrS[3:5].Arr[6:7] 11523 // 11524 // r.ArrS[3:5].x 11525 // 11526 // but these would be valid: 11527 // r.ArrS[3].Arr[6:7] 11528 // 11529 // r.ArrS[3].x 11530 11531 bool AllowUnitySizeArraySection = true; 11532 bool AllowWholeSizeArraySection = true; 11533 11534 while (!RelevantExpr) { 11535 E = E->IgnoreParenImpCasts(); 11536 11537 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 11538 if (!isa<VarDecl>(CurE->getDecl())) 11539 return nullptr; 11540 11541 RelevantExpr = CurE; 11542 11543 // If we got a reference to a declaration, we should not expect any array 11544 // section before that. 11545 AllowUnitySizeArraySection = false; 11546 AllowWholeSizeArraySection = false; 11547 11548 // Record the component. 11549 CurComponents.emplace_back(CurE, CurE->getDecl()); 11550 } else if (auto *CurE = dyn_cast<MemberExpr>(E)) { 11551 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 11552 11553 if (isa<CXXThisExpr>(BaseE)) 11554 // We found a base expression: this->Val. 11555 RelevantExpr = CurE; 11556 else 11557 E = BaseE; 11558 11559 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 11560 if (!NoDiagnose) { 11561 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 11562 << CurE->getSourceRange(); 11563 return nullptr; 11564 } 11565 if (RelevantExpr) 11566 return nullptr; 11567 continue; 11568 } 11569 11570 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 11571 11572 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 11573 // A bit-field cannot appear in a map clause. 11574 // 11575 if (FD->isBitField()) { 11576 if (!NoDiagnose) { 11577 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 11578 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 11579 return nullptr; 11580 } 11581 if (RelevantExpr) 11582 return nullptr; 11583 continue; 11584 } 11585 11586 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 11587 // If the type of a list item is a reference to a type T then the type 11588 // will be considered to be T for all purposes of this clause. 11589 QualType CurType = BaseE->getType().getNonReferenceType(); 11590 11591 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 11592 // A list item cannot be a variable that is a member of a structure with 11593 // a union type. 11594 // 11595 if (auto *RT = CurType->getAs<RecordType>()) { 11596 if (RT->isUnionType()) { 11597 if (!NoDiagnose) { 11598 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 11599 << CurE->getSourceRange(); 11600 return nullptr; 11601 } 11602 continue; 11603 } 11604 } 11605 11606 // If we got a member expression, we should not expect any array section 11607 // before that: 11608 // 11609 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 11610 // If a list item is an element of a structure, only the rightmost symbol 11611 // of the variable reference can be an array section. 11612 // 11613 AllowUnitySizeArraySection = false; 11614 AllowWholeSizeArraySection = false; 11615 11616 // Record the component. 11617 CurComponents.emplace_back(CurE, FD); 11618 } else if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 11619 E = CurE->getBase()->IgnoreParenImpCasts(); 11620 11621 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 11622 if (!NoDiagnose) { 11623 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 11624 << 0 << CurE->getSourceRange(); 11625 return nullptr; 11626 } 11627 continue; 11628 } 11629 11630 // If we got an array subscript that express the whole dimension we 11631 // can have any array expressions before. If it only expressing part of 11632 // the dimension, we can only have unitary-size array expressions. 11633 if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 11634 E->getType())) 11635 AllowWholeSizeArraySection = false; 11636 11637 // Record the component - we don't have any declaration associated. 11638 CurComponents.emplace_back(CurE, nullptr); 11639 } else if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 11640 assert(!NoDiagnose && "Array sections cannot be implicitly mapped."); 11641 E = CurE->getBase()->IgnoreParenImpCasts(); 11642 11643 QualType CurType = 11644 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 11645 11646 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 11647 // If the type of a list item is a reference to a type T then the type 11648 // will be considered to be T for all purposes of this clause. 11649 if (CurType->isReferenceType()) 11650 CurType = CurType->getPointeeType(); 11651 11652 bool IsPointer = CurType->isAnyPointerType(); 11653 11654 if (!IsPointer && !CurType->isArrayType()) { 11655 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 11656 << 0 << CurE->getSourceRange(); 11657 return nullptr; 11658 } 11659 11660 bool NotWhole = 11661 CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 11662 bool NotUnity = 11663 CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 11664 11665 if (AllowWholeSizeArraySection) { 11666 // Any array section is currently allowed. Allowing a whole size array 11667 // section implies allowing a unity array section as well. 11668 // 11669 // If this array section refers to the whole dimension we can still 11670 // accept other array sections before this one, except if the base is a 11671 // pointer. Otherwise, only unitary sections are accepted. 11672 if (NotWhole || IsPointer) 11673 AllowWholeSizeArraySection = false; 11674 } else if (AllowUnitySizeArraySection && NotUnity) { 11675 // A unity or whole array section is not allowed and that is not 11676 // compatible with the properties of the current array section. 11677 SemaRef.Diag( 11678 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 11679 << CurE->getSourceRange(); 11680 return nullptr; 11681 } 11682 11683 // Record the component - we don't have any declaration associated. 11684 CurComponents.emplace_back(CurE, nullptr); 11685 } else { 11686 if (!NoDiagnose) { 11687 // If nothing else worked, this is not a valid map clause expression. 11688 SemaRef.Diag( 11689 ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 11690 << ERange; 11691 } 11692 return nullptr; 11693 } 11694 } 11695 11696 return RelevantExpr; 11697 } 11698 11699 // Return true if expression E associated with value VD has conflicts with other 11700 // map information. 11701 static bool CheckMapConflicts( 11702 Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E, 11703 bool CurrentRegionOnly, 11704 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 11705 OpenMPClauseKind CKind) { 11706 assert(VD && E); 11707 SourceLocation ELoc = E->getExprLoc(); 11708 SourceRange ERange = E->getSourceRange(); 11709 11710 // In order to easily check the conflicts we need to match each component of 11711 // the expression under test with the components of the expressions that are 11712 // already in the stack. 11713 11714 assert(!CurComponents.empty() && "Map clause expression with no components!"); 11715 assert(CurComponents.back().getAssociatedDeclaration() == VD && 11716 "Map clause expression with unexpected base!"); 11717 11718 // Variables to help detecting enclosing problems in data environment nests. 11719 bool IsEnclosedByDataEnvironmentExpr = false; 11720 const Expr *EnclosingExpr = nullptr; 11721 11722 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 11723 VD, CurrentRegionOnly, 11724 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef 11725 StackComponents, 11726 OpenMPClauseKind) -> bool { 11727 11728 assert(!StackComponents.empty() && 11729 "Map clause expression with no components!"); 11730 assert(StackComponents.back().getAssociatedDeclaration() == VD && 11731 "Map clause expression with unexpected base!"); 11732 11733 // The whole expression in the stack. 11734 auto *RE = StackComponents.front().getAssociatedExpression(); 11735 11736 // Expressions must start from the same base. Here we detect at which 11737 // point both expressions diverge from each other and see if we can 11738 // detect if the memory referred to both expressions is contiguous and 11739 // do not overlap. 11740 auto CI = CurComponents.rbegin(); 11741 auto CE = CurComponents.rend(); 11742 auto SI = StackComponents.rbegin(); 11743 auto SE = StackComponents.rend(); 11744 for (; CI != CE && SI != SE; ++CI, ++SI) { 11745 11746 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 11747 // At most one list item can be an array item derived from a given 11748 // variable in map clauses of the same construct. 11749 if (CurrentRegionOnly && 11750 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 11751 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 11752 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 11753 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 11754 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 11755 diag::err_omp_multiple_array_items_in_map_clause) 11756 << CI->getAssociatedExpression()->getSourceRange(); 11757 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 11758 diag::note_used_here) 11759 << SI->getAssociatedExpression()->getSourceRange(); 11760 return true; 11761 } 11762 11763 // Do both expressions have the same kind? 11764 if (CI->getAssociatedExpression()->getStmtClass() != 11765 SI->getAssociatedExpression()->getStmtClass()) 11766 break; 11767 11768 // Are we dealing with different variables/fields? 11769 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 11770 break; 11771 } 11772 // Check if the extra components of the expressions in the enclosing 11773 // data environment are redundant for the current base declaration. 11774 // If they are, the maps completely overlap, which is legal. 11775 for (; SI != SE; ++SI) { 11776 QualType Type; 11777 if (auto *ASE = 11778 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 11779 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 11780 } else if (auto *OASE = dyn_cast<OMPArraySectionExpr>( 11781 SI->getAssociatedExpression())) { 11782 auto *E = OASE->getBase()->IgnoreParenImpCasts(); 11783 Type = 11784 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 11785 } 11786 if (Type.isNull() || Type->isAnyPointerType() || 11787 CheckArrayExpressionDoesNotReferToWholeSize( 11788 SemaRef, SI->getAssociatedExpression(), Type)) 11789 break; 11790 } 11791 11792 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 11793 // List items of map clauses in the same construct must not share 11794 // original storage. 11795 // 11796 // If the expressions are exactly the same or one is a subset of the 11797 // other, it means they are sharing storage. 11798 if (CI == CE && SI == SE) { 11799 if (CurrentRegionOnly) { 11800 if (CKind == OMPC_map) 11801 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 11802 else { 11803 assert(CKind == OMPC_to || CKind == OMPC_from); 11804 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 11805 << ERange; 11806 } 11807 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 11808 << RE->getSourceRange(); 11809 return true; 11810 } else { 11811 // If we find the same expression in the enclosing data environment, 11812 // that is legal. 11813 IsEnclosedByDataEnvironmentExpr = true; 11814 return false; 11815 } 11816 } 11817 11818 QualType DerivedType = 11819 std::prev(CI)->getAssociatedDeclaration()->getType(); 11820 SourceLocation DerivedLoc = 11821 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 11822 11823 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 11824 // If the type of a list item is a reference to a type T then the type 11825 // will be considered to be T for all purposes of this clause. 11826 DerivedType = DerivedType.getNonReferenceType(); 11827 11828 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 11829 // A variable for which the type is pointer and an array section 11830 // derived from that variable must not appear as list items of map 11831 // clauses of the same construct. 11832 // 11833 // Also, cover one of the cases in: 11834 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 11835 // If any part of the original storage of a list item has corresponding 11836 // storage in the device data environment, all of the original storage 11837 // must have corresponding storage in the device data environment. 11838 // 11839 if (DerivedType->isAnyPointerType()) { 11840 if (CI == CE || SI == SE) { 11841 SemaRef.Diag( 11842 DerivedLoc, 11843 diag::err_omp_pointer_mapped_along_with_derived_section) 11844 << DerivedLoc; 11845 } else { 11846 assert(CI != CE && SI != SE); 11847 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced) 11848 << DerivedLoc; 11849 } 11850 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 11851 << RE->getSourceRange(); 11852 return true; 11853 } 11854 11855 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 11856 // List items of map clauses in the same construct must not share 11857 // original storage. 11858 // 11859 // An expression is a subset of the other. 11860 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 11861 if (CKind == OMPC_map) 11862 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 11863 else { 11864 assert(CKind == OMPC_to || CKind == OMPC_from); 11865 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 11866 << ERange; 11867 } 11868 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 11869 << RE->getSourceRange(); 11870 return true; 11871 } 11872 11873 // The current expression uses the same base as other expression in the 11874 // data environment but does not contain it completely. 11875 if (!CurrentRegionOnly && SI != SE) 11876 EnclosingExpr = RE; 11877 11878 // The current expression is a subset of the expression in the data 11879 // environment. 11880 IsEnclosedByDataEnvironmentExpr |= 11881 (!CurrentRegionOnly && CI != CE && SI == SE); 11882 11883 return false; 11884 }); 11885 11886 if (CurrentRegionOnly) 11887 return FoundError; 11888 11889 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 11890 // If any part of the original storage of a list item has corresponding 11891 // storage in the device data environment, all of the original storage must 11892 // have corresponding storage in the device data environment. 11893 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 11894 // If a list item is an element of a structure, and a different element of 11895 // the structure has a corresponding list item in the device data environment 11896 // prior to a task encountering the construct associated with the map clause, 11897 // then the list item must also have a corresponding list item in the device 11898 // data environment prior to the task encountering the construct. 11899 // 11900 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 11901 SemaRef.Diag(ELoc, 11902 diag::err_omp_original_storage_is_shared_and_does_not_contain) 11903 << ERange; 11904 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 11905 << EnclosingExpr->getSourceRange(); 11906 return true; 11907 } 11908 11909 return FoundError; 11910 } 11911 11912 namespace { 11913 // Utility struct that gathers all the related lists associated with a mappable 11914 // expression. 11915 struct MappableVarListInfo final { 11916 // The list of expressions. 11917 ArrayRef<Expr *> VarList; 11918 // The list of processed expressions. 11919 SmallVector<Expr *, 16> ProcessedVarList; 11920 // The mappble components for each expression. 11921 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 11922 // The base declaration of the variable. 11923 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 11924 11925 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 11926 // We have a list of components and base declarations for each entry in the 11927 // variable list. 11928 VarComponents.reserve(VarList.size()); 11929 VarBaseDeclarations.reserve(VarList.size()); 11930 } 11931 }; 11932 } 11933 11934 // Check the validity of the provided variable list for the provided clause kind 11935 // \a CKind. In the check process the valid expressions, and mappable expression 11936 // components and variables are extracted and used to fill \a Vars, 11937 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and 11938 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'. 11939 static void 11940 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, 11941 OpenMPClauseKind CKind, MappableVarListInfo &MVLI, 11942 SourceLocation StartLoc, 11943 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 11944 bool IsMapTypeImplicit = false) { 11945 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 11946 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 11947 "Unexpected clause kind with mappable expressions!"); 11948 11949 // Keep track of the mappable components and base declarations in this clause. 11950 // Each entry in the list is going to have a list of components associated. We 11951 // record each set of the components so that we can build the clause later on. 11952 // In the end we should have the same amount of declarations and component 11953 // lists. 11954 11955 for (auto &RE : MVLI.VarList) { 11956 assert(RE && "Null expr in omp to/from/map clause"); 11957 SourceLocation ELoc = RE->getExprLoc(); 11958 11959 auto *VE = RE->IgnoreParenLValueCasts(); 11960 11961 if (VE->isValueDependent() || VE->isTypeDependent() || 11962 VE->isInstantiationDependent() || 11963 VE->containsUnexpandedParameterPack()) { 11964 // We can only analyze this information once the missing information is 11965 // resolved. 11966 MVLI.ProcessedVarList.push_back(RE); 11967 continue; 11968 } 11969 11970 auto *SimpleExpr = RE->IgnoreParenCasts(); 11971 11972 if (!RE->IgnoreParenImpCasts()->isLValue()) { 11973 SemaRef.Diag(ELoc, 11974 diag::err_omp_expected_named_var_member_or_array_expression) 11975 << RE->getSourceRange(); 11976 continue; 11977 } 11978 11979 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 11980 ValueDecl *CurDeclaration = nullptr; 11981 11982 // Obtain the array or member expression bases if required. Also, fill the 11983 // components array with all the components identified in the process. 11984 auto *BE = CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, 11985 CKind, /*NoDiagnose=*/false); 11986 if (!BE) 11987 continue; 11988 11989 assert(!CurComponents.empty() && 11990 "Invalid mappable expression information."); 11991 11992 // For the following checks, we rely on the base declaration which is 11993 // expected to be associated with the last component. The declaration is 11994 // expected to be a variable or a field (if 'this' is being mapped). 11995 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 11996 assert(CurDeclaration && "Null decl on map clause."); 11997 assert( 11998 CurDeclaration->isCanonicalDecl() && 11999 "Expecting components to have associated only canonical declarations."); 12000 12001 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 12002 auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 12003 12004 assert((VD || FD) && "Only variables or fields are expected here!"); 12005 (void)FD; 12006 12007 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 12008 // threadprivate variables cannot appear in a map clause. 12009 // OpenMP 4.5 [2.10.5, target update Construct] 12010 // threadprivate variables cannot appear in a from clause. 12011 if (VD && DSAS->isThreadPrivate(VD)) { 12012 auto DVar = DSAS->getTopDSA(VD, false); 12013 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 12014 << getOpenMPClauseName(CKind); 12015 ReportOriginalDSA(SemaRef, DSAS, VD, DVar); 12016 continue; 12017 } 12018 12019 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 12020 // A list item cannot appear in both a map clause and a data-sharing 12021 // attribute clause on the same construct. 12022 12023 // Check conflicts with other map clause expressions. We check the conflicts 12024 // with the current construct separately from the enclosing data 12025 // environment, because the restrictions are different. We only have to 12026 // check conflicts across regions for the map clauses. 12027 if (CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 12028 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 12029 break; 12030 if (CKind == OMPC_map && 12031 CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 12032 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 12033 break; 12034 12035 // OpenMP 4.5 [2.10.5, target update Construct] 12036 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 12037 // If the type of a list item is a reference to a type T then the type will 12038 // be considered to be T for all purposes of this clause. 12039 QualType Type = CurDeclaration->getType().getNonReferenceType(); 12040 12041 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 12042 // A list item in a to or from clause must have a mappable type. 12043 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 12044 // A list item must have a mappable type. 12045 if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 12046 DSAS, Type)) 12047 continue; 12048 12049 if (CKind == OMPC_map) { 12050 // target enter data 12051 // OpenMP [2.10.2, Restrictions, p. 99] 12052 // A map-type must be specified in all map clauses and must be either 12053 // to or alloc. 12054 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 12055 if (DKind == OMPD_target_enter_data && 12056 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 12057 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 12058 << (IsMapTypeImplicit ? 1 : 0) 12059 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 12060 << getOpenMPDirectiveName(DKind); 12061 continue; 12062 } 12063 12064 // target exit_data 12065 // OpenMP [2.10.3, Restrictions, p. 102] 12066 // A map-type must be specified in all map clauses and must be either 12067 // from, release, or delete. 12068 if (DKind == OMPD_target_exit_data && 12069 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 12070 MapType == OMPC_MAP_delete)) { 12071 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 12072 << (IsMapTypeImplicit ? 1 : 0) 12073 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 12074 << getOpenMPDirectiveName(DKind); 12075 continue; 12076 } 12077 12078 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 12079 // A list item cannot appear in both a map clause and a data-sharing 12080 // attribute clause on the same construct 12081 if ((DKind == OMPD_target || DKind == OMPD_target_teams || 12082 DKind == OMPD_target_teams_distribute || 12083 DKind == OMPD_target_teams_distribute_parallel_for || 12084 DKind == OMPD_target_teams_distribute_parallel_for_simd || 12085 DKind == OMPD_target_teams_distribute_simd) && VD) { 12086 auto DVar = DSAS->getTopDSA(VD, false); 12087 if (isOpenMPPrivate(DVar.CKind)) { 12088 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12089 << getOpenMPClauseName(DVar.CKind) 12090 << getOpenMPClauseName(OMPC_map) 12091 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 12092 ReportOriginalDSA(SemaRef, DSAS, CurDeclaration, DVar); 12093 continue; 12094 } 12095 } 12096 } 12097 12098 // Save the current expression. 12099 MVLI.ProcessedVarList.push_back(RE); 12100 12101 // Store the components in the stack so that they can be used to check 12102 // against other clauses later on. 12103 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 12104 /*WhereFoundClauseKind=*/OMPC_map); 12105 12106 // Save the components and declaration to create the clause. For purposes of 12107 // the clause creation, any component list that has has base 'this' uses 12108 // null as base declaration. 12109 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 12110 MVLI.VarComponents.back().append(CurComponents.begin(), 12111 CurComponents.end()); 12112 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 12113 : CurDeclaration); 12114 } 12115 } 12116 12117 OMPClause * 12118 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, 12119 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 12120 SourceLocation MapLoc, SourceLocation ColonLoc, 12121 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 12122 SourceLocation LParenLoc, SourceLocation EndLoc) { 12123 MappableVarListInfo MVLI(VarList); 12124 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc, 12125 MapType, IsMapTypeImplicit); 12126 12127 // We need to produce a map clause even if we don't have variables so that 12128 // other diagnostics related with non-existing map clauses are accurate. 12129 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12130 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 12131 MVLI.VarComponents, MapTypeModifier, MapType, 12132 IsMapTypeImplicit, MapLoc); 12133 } 12134 12135 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 12136 TypeResult ParsedType) { 12137 assert(ParsedType.isUsable()); 12138 12139 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 12140 if (ReductionType.isNull()) 12141 return QualType(); 12142 12143 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 12144 // A type name in a declare reduction directive cannot be a function type, an 12145 // array type, a reference type, or a type qualified with const, volatile or 12146 // restrict. 12147 if (ReductionType.hasQualifiers()) { 12148 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 12149 return QualType(); 12150 } 12151 12152 if (ReductionType->isFunctionType()) { 12153 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 12154 return QualType(); 12155 } 12156 if (ReductionType->isReferenceType()) { 12157 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 12158 return QualType(); 12159 } 12160 if (ReductionType->isArrayType()) { 12161 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 12162 return QualType(); 12163 } 12164 return ReductionType; 12165 } 12166 12167 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 12168 Scope *S, DeclContext *DC, DeclarationName Name, 12169 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 12170 AccessSpecifier AS, Decl *PrevDeclInScope) { 12171 SmallVector<Decl *, 8> Decls; 12172 Decls.reserve(ReductionTypes.size()); 12173 12174 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 12175 forRedeclarationInCurContext()); 12176 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 12177 // A reduction-identifier may not be re-declared in the current scope for the 12178 // same type or for a type that is compatible according to the base language 12179 // rules. 12180 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 12181 OMPDeclareReductionDecl *PrevDRD = nullptr; 12182 bool InCompoundScope = true; 12183 if (S != nullptr) { 12184 // Find previous declaration with the same name not referenced in other 12185 // declarations. 12186 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 12187 InCompoundScope = 12188 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 12189 LookupName(Lookup, S); 12190 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 12191 /*AllowInlineNamespace=*/false); 12192 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 12193 auto Filter = Lookup.makeFilter(); 12194 while (Filter.hasNext()) { 12195 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 12196 if (InCompoundScope) { 12197 auto I = UsedAsPrevious.find(PrevDecl); 12198 if (I == UsedAsPrevious.end()) 12199 UsedAsPrevious[PrevDecl] = false; 12200 if (auto *D = PrevDecl->getPrevDeclInScope()) 12201 UsedAsPrevious[D] = true; 12202 } 12203 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 12204 PrevDecl->getLocation(); 12205 } 12206 Filter.done(); 12207 if (InCompoundScope) { 12208 for (auto &PrevData : UsedAsPrevious) { 12209 if (!PrevData.second) { 12210 PrevDRD = PrevData.first; 12211 break; 12212 } 12213 } 12214 } 12215 } else if (PrevDeclInScope != nullptr) { 12216 auto *PrevDRDInScope = PrevDRD = 12217 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 12218 do { 12219 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 12220 PrevDRDInScope->getLocation(); 12221 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 12222 } while (PrevDRDInScope != nullptr); 12223 } 12224 for (auto &TyData : ReductionTypes) { 12225 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 12226 bool Invalid = false; 12227 if (I != PreviousRedeclTypes.end()) { 12228 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 12229 << TyData.first; 12230 Diag(I->second, diag::note_previous_definition); 12231 Invalid = true; 12232 } 12233 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 12234 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 12235 Name, TyData.first, PrevDRD); 12236 DC->addDecl(DRD); 12237 DRD->setAccess(AS); 12238 Decls.push_back(DRD); 12239 if (Invalid) 12240 DRD->setInvalidDecl(); 12241 else 12242 PrevDRD = DRD; 12243 } 12244 12245 return DeclGroupPtrTy::make( 12246 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 12247 } 12248 12249 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 12250 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12251 12252 // Enter new function scope. 12253 PushFunctionScope(); 12254 getCurFunction()->setHasBranchProtectedScope(); 12255 getCurFunction()->setHasOMPDeclareReductionCombiner(); 12256 12257 if (S != nullptr) 12258 PushDeclContext(S, DRD); 12259 else 12260 CurContext = DRD; 12261 12262 PushExpressionEvaluationContext( 12263 ExpressionEvaluationContext::PotentiallyEvaluated); 12264 12265 QualType ReductionType = DRD->getType(); 12266 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 12267 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 12268 // uses semantics of argument handles by value, but it should be passed by 12269 // reference. C lang does not support references, so pass all parameters as 12270 // pointers. 12271 // Create 'T omp_in;' variable. 12272 auto *OmpInParm = 12273 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 12274 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 12275 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 12276 // uses semantics of argument handles by value, but it should be passed by 12277 // reference. C lang does not support references, so pass all parameters as 12278 // pointers. 12279 // Create 'T omp_out;' variable. 12280 auto *OmpOutParm = 12281 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 12282 if (S != nullptr) { 12283 PushOnScopeChains(OmpInParm, S); 12284 PushOnScopeChains(OmpOutParm, S); 12285 } else { 12286 DRD->addDecl(OmpInParm); 12287 DRD->addDecl(OmpOutParm); 12288 } 12289 } 12290 12291 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 12292 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12293 DiscardCleanupsInEvaluationContext(); 12294 PopExpressionEvaluationContext(); 12295 12296 PopDeclContext(); 12297 PopFunctionScopeInfo(); 12298 12299 if (Combiner != nullptr) 12300 DRD->setCombiner(Combiner); 12301 else 12302 DRD->setInvalidDecl(); 12303 } 12304 12305 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 12306 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12307 12308 // Enter new function scope. 12309 PushFunctionScope(); 12310 getCurFunction()->setHasBranchProtectedScope(); 12311 12312 if (S != nullptr) 12313 PushDeclContext(S, DRD); 12314 else 12315 CurContext = DRD; 12316 12317 PushExpressionEvaluationContext( 12318 ExpressionEvaluationContext::PotentiallyEvaluated); 12319 12320 QualType ReductionType = DRD->getType(); 12321 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 12322 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 12323 // uses semantics of argument handles by value, but it should be passed by 12324 // reference. C lang does not support references, so pass all parameters as 12325 // pointers. 12326 // Create 'T omp_priv;' variable. 12327 auto *OmpPrivParm = 12328 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 12329 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 12330 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 12331 // uses semantics of argument handles by value, but it should be passed by 12332 // reference. C lang does not support references, so pass all parameters as 12333 // pointers. 12334 // Create 'T omp_orig;' variable. 12335 auto *OmpOrigParm = 12336 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 12337 if (S != nullptr) { 12338 PushOnScopeChains(OmpPrivParm, S); 12339 PushOnScopeChains(OmpOrigParm, S); 12340 } else { 12341 DRD->addDecl(OmpPrivParm); 12342 DRD->addDecl(OmpOrigParm); 12343 } 12344 return OmpPrivParm; 12345 } 12346 12347 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 12348 VarDecl *OmpPrivParm) { 12349 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12350 DiscardCleanupsInEvaluationContext(); 12351 PopExpressionEvaluationContext(); 12352 12353 PopDeclContext(); 12354 PopFunctionScopeInfo(); 12355 12356 if (Initializer != nullptr) { 12357 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 12358 } else if (OmpPrivParm->hasInit()) { 12359 DRD->setInitializer(OmpPrivParm->getInit(), 12360 OmpPrivParm->isDirectInit() 12361 ? OMPDeclareReductionDecl::DirectInit 12362 : OMPDeclareReductionDecl::CopyInit); 12363 } else { 12364 DRD->setInvalidDecl(); 12365 } 12366 } 12367 12368 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 12369 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 12370 for (auto *D : DeclReductions.get()) { 12371 if (IsValid) { 12372 auto *DRD = cast<OMPDeclareReductionDecl>(D); 12373 if (S != nullptr) 12374 PushOnScopeChains(DRD, S, /*AddToContext=*/false); 12375 } else 12376 D->setInvalidDecl(); 12377 } 12378 return DeclReductions; 12379 } 12380 12381 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 12382 SourceLocation StartLoc, 12383 SourceLocation LParenLoc, 12384 SourceLocation EndLoc) { 12385 Expr *ValExpr = NumTeams; 12386 Stmt *HelperValStmt = nullptr; 12387 12388 // OpenMP [teams Constrcut, Restrictions] 12389 // The num_teams expression must evaluate to a positive integer value. 12390 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 12391 /*StrictlyPositive=*/true)) 12392 return nullptr; 12393 12394 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12395 OpenMPDirectiveKind CaptureRegion = 12396 getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 12397 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12398 ValExpr = MakeFullExpr(ValExpr).get(); 12399 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 12400 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12401 HelperValStmt = buildPreInits(Context, Captures); 12402 } 12403 12404 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 12405 StartLoc, LParenLoc, EndLoc); 12406 } 12407 12408 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 12409 SourceLocation StartLoc, 12410 SourceLocation LParenLoc, 12411 SourceLocation EndLoc) { 12412 Expr *ValExpr = ThreadLimit; 12413 Stmt *HelperValStmt = nullptr; 12414 12415 // OpenMP [teams Constrcut, Restrictions] 12416 // The thread_limit expression must evaluate to a positive integer value. 12417 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 12418 /*StrictlyPositive=*/true)) 12419 return nullptr; 12420 12421 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 12422 OpenMPDirectiveKind CaptureRegion = 12423 getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 12424 if (CaptureRegion != OMPD_unknown && !CurContext->isDependentContext()) { 12425 ValExpr = MakeFullExpr(ValExpr).get(); 12426 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 12427 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12428 HelperValStmt = buildPreInits(Context, Captures); 12429 } 12430 12431 return new (Context) OMPThreadLimitClause( 12432 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 12433 } 12434 12435 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 12436 SourceLocation StartLoc, 12437 SourceLocation LParenLoc, 12438 SourceLocation EndLoc) { 12439 Expr *ValExpr = Priority; 12440 12441 // OpenMP [2.9.1, task Constrcut] 12442 // The priority-value is a non-negative numerical scalar expression. 12443 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 12444 /*StrictlyPositive=*/false)) 12445 return nullptr; 12446 12447 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 12448 } 12449 12450 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 12451 SourceLocation StartLoc, 12452 SourceLocation LParenLoc, 12453 SourceLocation EndLoc) { 12454 Expr *ValExpr = Grainsize; 12455 12456 // OpenMP [2.9.2, taskloop Constrcut] 12457 // The parameter of the grainsize clause must be a positive integer 12458 // expression. 12459 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 12460 /*StrictlyPositive=*/true)) 12461 return nullptr; 12462 12463 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 12464 } 12465 12466 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 12467 SourceLocation StartLoc, 12468 SourceLocation LParenLoc, 12469 SourceLocation EndLoc) { 12470 Expr *ValExpr = NumTasks; 12471 12472 // OpenMP [2.9.2, taskloop Constrcut] 12473 // The parameter of the num_tasks clause must be a positive integer 12474 // expression. 12475 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 12476 /*StrictlyPositive=*/true)) 12477 return nullptr; 12478 12479 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 12480 } 12481 12482 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 12483 SourceLocation LParenLoc, 12484 SourceLocation EndLoc) { 12485 // OpenMP [2.13.2, critical construct, Description] 12486 // ... where hint-expression is an integer constant expression that evaluates 12487 // to a valid lock hint. 12488 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 12489 if (HintExpr.isInvalid()) 12490 return nullptr; 12491 return new (Context) 12492 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 12493 } 12494 12495 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 12496 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 12497 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 12498 SourceLocation EndLoc) { 12499 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 12500 std::string Values; 12501 Values += "'"; 12502 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 12503 Values += "'"; 12504 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 12505 << Values << getOpenMPClauseName(OMPC_dist_schedule); 12506 return nullptr; 12507 } 12508 Expr *ValExpr = ChunkSize; 12509 Stmt *HelperValStmt = nullptr; 12510 if (ChunkSize) { 12511 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 12512 !ChunkSize->isInstantiationDependent() && 12513 !ChunkSize->containsUnexpandedParameterPack()) { 12514 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 12515 ExprResult Val = 12516 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 12517 if (Val.isInvalid()) 12518 return nullptr; 12519 12520 ValExpr = Val.get(); 12521 12522 // OpenMP [2.7.1, Restrictions] 12523 // chunk_size must be a loop invariant integer expression with a positive 12524 // value. 12525 llvm::APSInt Result; 12526 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 12527 if (Result.isSigned() && !Result.isStrictlyPositive()) { 12528 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 12529 << "dist_schedule" << ChunkSize->getSourceRange(); 12530 return nullptr; 12531 } 12532 } else if (getOpenMPCaptureRegionForClause( 12533 DSAStack->getCurrentDirective(), OMPC_dist_schedule) != 12534 OMPD_unknown && 12535 !CurContext->isDependentContext()) { 12536 ValExpr = MakeFullExpr(ValExpr).get(); 12537 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 12538 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 12539 HelperValStmt = buildPreInits(Context, Captures); 12540 } 12541 } 12542 } 12543 12544 return new (Context) 12545 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 12546 Kind, ValExpr, HelperValStmt); 12547 } 12548 12549 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 12550 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 12551 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 12552 SourceLocation KindLoc, SourceLocation EndLoc) { 12553 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 12554 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 12555 std::string Value; 12556 SourceLocation Loc; 12557 Value += "'"; 12558 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 12559 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 12560 OMPC_DEFAULTMAP_MODIFIER_tofrom); 12561 Loc = MLoc; 12562 } else { 12563 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 12564 OMPC_DEFAULTMAP_scalar); 12565 Loc = KindLoc; 12566 } 12567 Value += "'"; 12568 Diag(Loc, diag::err_omp_unexpected_clause_value) 12569 << Value << getOpenMPClauseName(OMPC_defaultmap); 12570 return nullptr; 12571 } 12572 DSAStack->setDefaultDMAToFromScalar(StartLoc); 12573 12574 return new (Context) 12575 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 12576 } 12577 12578 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 12579 DeclContext *CurLexicalContext = getCurLexicalContext(); 12580 if (!CurLexicalContext->isFileContext() && 12581 !CurLexicalContext->isExternCContext() && 12582 !CurLexicalContext->isExternCXXContext() && 12583 !isa<CXXRecordDecl>(CurLexicalContext) && 12584 !isa<ClassTemplateDecl>(CurLexicalContext) && 12585 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 12586 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 12587 Diag(Loc, diag::err_omp_region_not_file_context); 12588 return false; 12589 } 12590 if (IsInOpenMPDeclareTargetContext) { 12591 Diag(Loc, diag::err_omp_enclosed_declare_target); 12592 return false; 12593 } 12594 12595 IsInOpenMPDeclareTargetContext = true; 12596 return true; 12597 } 12598 12599 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 12600 assert(IsInOpenMPDeclareTargetContext && 12601 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 12602 12603 IsInOpenMPDeclareTargetContext = false; 12604 } 12605 12606 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 12607 CXXScopeSpec &ScopeSpec, 12608 const DeclarationNameInfo &Id, 12609 OMPDeclareTargetDeclAttr::MapTypeTy MT, 12610 NamedDeclSetType &SameDirectiveDecls) { 12611 LookupResult Lookup(*this, Id, LookupOrdinaryName); 12612 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 12613 12614 if (Lookup.isAmbiguous()) 12615 return; 12616 Lookup.suppressDiagnostics(); 12617 12618 if (!Lookup.isSingleResult()) { 12619 if (TypoCorrection Corrected = 12620 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, 12621 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), 12622 CTK_ErrorRecovery)) { 12623 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 12624 << Id.getName()); 12625 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 12626 return; 12627 } 12628 12629 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 12630 return; 12631 } 12632 12633 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 12634 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { 12635 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 12636 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 12637 12638 if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) { 12639 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 12640 ND->addAttr(A); 12641 if (ASTMutationListener *ML = Context.getASTMutationListener()) 12642 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 12643 checkDeclIsAllowedInOpenMPTarget(nullptr, ND, Id.getLoc()); 12644 } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) { 12645 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 12646 << Id.getName(); 12647 } 12648 } else 12649 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 12650 } 12651 12652 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 12653 Sema &SemaRef, Decl *D) { 12654 if (!D) 12655 return; 12656 Decl *LD = nullptr; 12657 if (isa<TagDecl>(D)) { 12658 LD = cast<TagDecl>(D)->getDefinition(); 12659 } else if (isa<VarDecl>(D)) { 12660 LD = cast<VarDecl>(D)->getDefinition(); 12661 12662 // If this is an implicit variable that is legal and we do not need to do 12663 // anything. 12664 if (cast<VarDecl>(D)->isImplicit()) { 12665 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12666 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 12667 D->addAttr(A); 12668 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 12669 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 12670 return; 12671 } 12672 12673 } else if (isa<FunctionDecl>(D)) { 12674 const FunctionDecl *FD = nullptr; 12675 if (cast<FunctionDecl>(D)->hasBody(FD)) 12676 LD = const_cast<FunctionDecl *>(FD); 12677 12678 // If the definition is associated with the current declaration in the 12679 // target region (it can be e.g. a lambda) that is legal and we do not need 12680 // to do anything else. 12681 if (LD == D) { 12682 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12683 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 12684 D->addAttr(A); 12685 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 12686 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 12687 return; 12688 } 12689 } 12690 if (!LD) 12691 LD = D; 12692 if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() && 12693 (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) { 12694 // Outlined declaration is not declared target. 12695 if (LD->isOutOfLine()) { 12696 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 12697 SemaRef.Diag(SL, diag::note_used_here) << SR; 12698 } else { 12699 DeclContext *DC = LD->getDeclContext(); 12700 while (DC) { 12701 if (isa<FunctionDecl>(DC) && 12702 cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>()) 12703 break; 12704 DC = DC->getParent(); 12705 } 12706 if (DC) 12707 return; 12708 12709 // Is not declared in target context. 12710 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 12711 SemaRef.Diag(SL, diag::note_used_here) << SR; 12712 } 12713 // Mark decl as declared target to prevent further diagnostic. 12714 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12715 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 12716 D->addAttr(A); 12717 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 12718 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 12719 } 12720 } 12721 12722 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 12723 Sema &SemaRef, DSAStackTy *Stack, 12724 ValueDecl *VD) { 12725 if (VD->hasAttr<OMPDeclareTargetDeclAttr>()) 12726 return true; 12727 if (!CheckTypeMappable(SL, SR, SemaRef, Stack, VD->getType())) 12728 return false; 12729 return true; 12730 } 12731 12732 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D, 12733 SourceLocation IdLoc) { 12734 if (!D || D->isInvalidDecl()) 12735 return; 12736 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 12737 SourceLocation SL = E ? E->getLocStart() : D->getLocation(); 12738 // 2.10.6: threadprivate variable cannot appear in a declare target directive. 12739 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 12740 if (DSAStack->isThreadPrivate(VD)) { 12741 Diag(SL, diag::err_omp_threadprivate_in_target); 12742 ReportOriginalDSA(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 12743 return; 12744 } 12745 } 12746 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 12747 // Problem if any with var declared with incomplete type will be reported 12748 // as normal, so no need to check it here. 12749 if ((E || !VD->getType()->isIncompleteType()) && 12750 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) { 12751 // Mark decl as declared target to prevent further diagnostic. 12752 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) { 12753 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12754 Context, OMPDeclareTargetDeclAttr::MT_To); 12755 VD->addAttr(A); 12756 if (ASTMutationListener *ML = Context.getASTMutationListener()) 12757 ML->DeclarationMarkedOpenMPDeclareTarget(VD, A); 12758 } 12759 return; 12760 } 12761 } 12762 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 12763 if (FD->hasAttr<OMPDeclareTargetDeclAttr>() && 12764 (FD->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() == 12765 OMPDeclareTargetDeclAttr::MT_Link)) { 12766 assert(IdLoc.isValid() && "Source location is expected"); 12767 Diag(IdLoc, diag::err_omp_function_in_link_clause); 12768 Diag(FD->getLocation(), diag::note_defined_here) << FD; 12769 return; 12770 } 12771 } 12772 if (!E) { 12773 // Checking declaration inside declare target region. 12774 if (!D->hasAttr<OMPDeclareTargetDeclAttr>() && 12775 (isa<VarDecl>(D) || isa<FunctionDecl>(D))) { 12776 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12777 Context, OMPDeclareTargetDeclAttr::MT_To); 12778 D->addAttr(A); 12779 if (ASTMutationListener *ML = Context.getASTMutationListener()) 12780 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 12781 } 12782 return; 12783 } 12784 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 12785 } 12786 12787 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 12788 SourceLocation StartLoc, 12789 SourceLocation LParenLoc, 12790 SourceLocation EndLoc) { 12791 MappableVarListInfo MVLI(VarList); 12792 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc); 12793 if (MVLI.ProcessedVarList.empty()) 12794 return nullptr; 12795 12796 return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12797 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 12798 MVLI.VarComponents); 12799 } 12800 12801 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 12802 SourceLocation StartLoc, 12803 SourceLocation LParenLoc, 12804 SourceLocation EndLoc) { 12805 MappableVarListInfo MVLI(VarList); 12806 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc); 12807 if (MVLI.ProcessedVarList.empty()) 12808 return nullptr; 12809 12810 return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12811 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 12812 MVLI.VarComponents); 12813 } 12814 12815 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 12816 SourceLocation StartLoc, 12817 SourceLocation LParenLoc, 12818 SourceLocation EndLoc) { 12819 MappableVarListInfo MVLI(VarList); 12820 SmallVector<Expr *, 8> PrivateCopies; 12821 SmallVector<Expr *, 8> Inits; 12822 12823 for (auto &RefExpr : VarList) { 12824 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 12825 SourceLocation ELoc; 12826 SourceRange ERange; 12827 Expr *SimpleRefExpr = RefExpr; 12828 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12829 if (Res.second) { 12830 // It will be analyzed later. 12831 MVLI.ProcessedVarList.push_back(RefExpr); 12832 PrivateCopies.push_back(nullptr); 12833 Inits.push_back(nullptr); 12834 } 12835 ValueDecl *D = Res.first; 12836 if (!D) 12837 continue; 12838 12839 QualType Type = D->getType(); 12840 Type = Type.getNonReferenceType().getUnqualifiedType(); 12841 12842 auto *VD = dyn_cast<VarDecl>(D); 12843 12844 // Item should be a pointer or reference to pointer. 12845 if (!Type->isPointerType()) { 12846 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 12847 << 0 << RefExpr->getSourceRange(); 12848 continue; 12849 } 12850 12851 // Build the private variable and the expression that refers to it. 12852 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 12853 D->hasAttrs() ? &D->getAttrs() : nullptr); 12854 if (VDPrivate->isInvalidDecl()) 12855 continue; 12856 12857 CurContext->addDecl(VDPrivate); 12858 auto VDPrivateRefExpr = buildDeclRefExpr( 12859 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12860 12861 // Add temporary variable to initialize the private copy of the pointer. 12862 auto *VDInit = 12863 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 12864 auto *VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12865 RefExpr->getExprLoc()); 12866 AddInitializerToDecl(VDPrivate, 12867 DefaultLvalueConversion(VDInitRefExpr).get(), 12868 /*DirectInit=*/false); 12869 12870 // If required, build a capture to implement the privatization initialized 12871 // with the current list item value. 12872 DeclRefExpr *Ref = nullptr; 12873 if (!VD) 12874 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12875 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 12876 PrivateCopies.push_back(VDPrivateRefExpr); 12877 Inits.push_back(VDInitRefExpr); 12878 12879 // We need to add a data sharing attribute for this variable to make sure it 12880 // is correctly captured. A variable that shows up in a use_device_ptr has 12881 // similar properties of a first private variable. 12882 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12883 12884 // Create a mappable component for the list item. List items in this clause 12885 // only need a component. 12886 MVLI.VarBaseDeclarations.push_back(D); 12887 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 12888 MVLI.VarComponents.back().push_back( 12889 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 12890 } 12891 12892 if (MVLI.ProcessedVarList.empty()) 12893 return nullptr; 12894 12895 return OMPUseDevicePtrClause::Create( 12896 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 12897 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents); 12898 } 12899 12900 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 12901 SourceLocation StartLoc, 12902 SourceLocation LParenLoc, 12903 SourceLocation EndLoc) { 12904 MappableVarListInfo MVLI(VarList); 12905 for (auto &RefExpr : VarList) { 12906 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 12907 SourceLocation ELoc; 12908 SourceRange ERange; 12909 Expr *SimpleRefExpr = RefExpr; 12910 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12911 if (Res.second) { 12912 // It will be analyzed later. 12913 MVLI.ProcessedVarList.push_back(RefExpr); 12914 } 12915 ValueDecl *D = Res.first; 12916 if (!D) 12917 continue; 12918 12919 QualType Type = D->getType(); 12920 // item should be a pointer or array or reference to pointer or array 12921 if (!Type.getNonReferenceType()->isPointerType() && 12922 !Type.getNonReferenceType()->isArrayType()) { 12923 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 12924 << 0 << RefExpr->getSourceRange(); 12925 continue; 12926 } 12927 12928 // Check if the declaration in the clause does not show up in any data 12929 // sharing attribute. 12930 auto DVar = DSAStack->getTopDSA(D, false); 12931 if (isOpenMPPrivate(DVar.CKind)) { 12932 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12933 << getOpenMPClauseName(DVar.CKind) 12934 << getOpenMPClauseName(OMPC_is_device_ptr) 12935 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12936 ReportOriginalDSA(*this, DSAStack, D, DVar); 12937 continue; 12938 } 12939 12940 Expr *ConflictExpr; 12941 if (DSAStack->checkMappableExprComponentListsForDecl( 12942 D, /*CurrentRegionOnly=*/true, 12943 [&ConflictExpr]( 12944 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 12945 OpenMPClauseKind) -> bool { 12946 ConflictExpr = R.front().getAssociatedExpression(); 12947 return true; 12948 })) { 12949 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 12950 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 12951 << ConflictExpr->getSourceRange(); 12952 continue; 12953 } 12954 12955 // Store the components in the stack so that they can be used to check 12956 // against other clauses later on. 12957 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 12958 DSAStack->addMappableExpressionComponents( 12959 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 12960 12961 // Record the expression we've just processed. 12962 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 12963 12964 // Create a mappable component for the list item. List items in this clause 12965 // only need a component. We use a null declaration to signal fields in 12966 // 'this'. 12967 assert((isa<DeclRefExpr>(SimpleRefExpr) || 12968 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 12969 "Unexpected device pointer expression!"); 12970 MVLI.VarBaseDeclarations.push_back( 12971 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 12972 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 12973 MVLI.VarComponents.back().push_back(MC); 12974 } 12975 12976 if (MVLI.ProcessedVarList.empty()) 12977 return nullptr; 12978 12979 return OMPIsDevicePtrClause::Create( 12980 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 12981 MVLI.VarBaseDeclarations, MVLI.VarComponents); 12982 } 12983