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); 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 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 182 183 bool isForceVarCapturing() const { return ForceCapturing; } 184 void setForceVarCapturing(bool V) { ForceCapturing = V; } 185 186 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 187 Scope *CurScope, SourceLocation Loc) { 188 if (Stack.empty() || 189 Stack.back().second != CurrentNonCapturingFunctionScope) 190 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 191 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 192 Stack.back().first.back().DefaultAttrLoc = Loc; 193 } 194 195 void pop() { 196 assert(!Stack.back().first.empty() && 197 "Data-sharing attributes stack is empty!"); 198 Stack.back().first.pop_back(); 199 } 200 201 /// Start new OpenMP region stack in new non-capturing function. 202 void pushFunction() { 203 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 204 assert(!isa<CapturingScopeInfo>(CurFnScope)); 205 CurrentNonCapturingFunctionScope = CurFnScope; 206 } 207 /// Pop region stack for non-capturing function. 208 void popFunction(const FunctionScopeInfo *OldFSI) { 209 if (!Stack.empty() && Stack.back().second == OldFSI) { 210 assert(Stack.back().first.empty()); 211 Stack.pop_back(); 212 } 213 CurrentNonCapturingFunctionScope = nullptr; 214 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 215 if (!isa<CapturingScopeInfo>(FSI)) { 216 CurrentNonCapturingFunctionScope = FSI; 217 break; 218 } 219 } 220 } 221 222 void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) { 223 Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint); 224 } 225 const std::pair<OMPCriticalDirective *, llvm::APSInt> 226 getCriticalWithHint(const DeclarationNameInfo &Name) const { 227 auto I = Criticals.find(Name.getAsString()); 228 if (I != Criticals.end()) 229 return I->second; 230 return std::make_pair(nullptr, llvm::APSInt()); 231 } 232 /// \brief If 'aligned' declaration for given variable \a D was not seen yet, 233 /// add it and return NULL; otherwise return previous occurrence's expression 234 /// for diagnostics. 235 Expr *addUniqueAligned(ValueDecl *D, Expr *NewDE); 236 237 /// \brief Register specified variable as loop control variable. 238 void addLoopControlVariable(ValueDecl *D, VarDecl *Capture); 239 /// \brief Check if the specified variable is a loop control variable for 240 /// current region. 241 /// \return The index of the loop control variable in the list of associated 242 /// for-loops (from outer to inner). 243 LCDeclInfo isLoopControlVariable(ValueDecl *D); 244 /// \brief Check if the specified variable is a loop control variable for 245 /// parent region. 246 /// \return The index of the loop control variable in the list of associated 247 /// for-loops (from outer to inner). 248 LCDeclInfo isParentLoopControlVariable(ValueDecl *D); 249 /// \brief Get the loop control variable for the I-th loop (or nullptr) in 250 /// parent directive. 251 ValueDecl *getParentLoopControlVariable(unsigned I); 252 253 /// \brief Adds explicit data sharing attribute to the specified declaration. 254 void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 255 DeclRefExpr *PrivateCopy = nullptr); 256 257 /// Adds additional information for the reduction items with the reduction id 258 /// represented as an operator. 259 void addTaskgroupReductionData(ValueDecl *D, SourceRange SR, 260 BinaryOperatorKind BOK); 261 /// Adds additional information for the reduction items with the reduction id 262 /// represented as reduction identifier. 263 void addTaskgroupReductionData(ValueDecl *D, SourceRange SR, 264 const Expr *ReductionRef); 265 /// Returns the location and reduction operation from the innermost parent 266 /// region for the given \p D. 267 DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, 268 BinaryOperatorKind &BOK, 269 Expr *&TaskgroupDescriptor); 270 /// Returns the location and reduction operation from the innermost parent 271 /// region for the given \p D. 272 DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, 273 const Expr *&ReductionRef, 274 Expr *&TaskgroupDescriptor); 275 /// Return reduction reference expression for the current taskgroup. 276 Expr *getTaskgroupReductionRef() const { 277 assert(Stack.back().first.back().Directive == OMPD_taskgroup && 278 "taskgroup reference expression requested for non taskgroup " 279 "directive."); 280 return Stack.back().first.back().TaskgroupReductionRef; 281 } 282 /// Checks if the given \p VD declaration is actually a taskgroup reduction 283 /// descriptor variable at the \p Level of OpenMP regions. 284 bool isTaskgroupReductionRef(ValueDecl *VD, unsigned Level) const { 285 return Stack.back().first[Level].TaskgroupReductionRef && 286 cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef) 287 ->getDecl() == VD; 288 } 289 290 /// \brief Returns data sharing attributes from top of the stack for the 291 /// specified declaration. 292 DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 293 /// \brief Returns data-sharing attributes for the specified declaration. 294 DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent); 295 /// \brief Checks if the specified variables has data-sharing attributes which 296 /// match specified \a CPred predicate in any directive which matches \a DPred 297 /// predicate. 298 DSAVarData hasDSA(ValueDecl *D, 299 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 300 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 301 bool FromParent); 302 /// \brief Checks if the specified variables has data-sharing attributes which 303 /// match specified \a CPred predicate in any innermost directive which 304 /// matches \a DPred predicate. 305 DSAVarData 306 hasInnermostDSA(ValueDecl *D, 307 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 308 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 309 bool FromParent); 310 /// \brief Checks if the specified variables has explicit data-sharing 311 /// attributes which match specified \a CPred predicate at the specified 312 /// OpenMP region. 313 bool hasExplicitDSA(ValueDecl *D, 314 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 315 unsigned Level, bool NotLastprivate = false); 316 317 /// \brief Returns true if the directive at level \Level matches in the 318 /// specified \a DPred predicate. 319 bool hasExplicitDirective( 320 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 321 unsigned Level); 322 323 /// \brief Finds a directive which matches specified \a DPred predicate. 324 bool hasDirective(const llvm::function_ref<bool(OpenMPDirectiveKind, 325 const DeclarationNameInfo &, 326 SourceLocation)> &DPred, 327 bool FromParent); 328 329 /// \brief Returns currently analyzed directive. 330 OpenMPDirectiveKind getCurrentDirective() const { 331 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive; 332 } 333 /// \brief Returns parent directive. 334 OpenMPDirectiveKind getParentDirective() const { 335 if (isStackEmpty() || Stack.back().first.size() == 1) 336 return OMPD_unknown; 337 return std::next(Stack.back().first.rbegin())->Directive; 338 } 339 340 /// \brief Set default data sharing attribute to none. 341 void setDefaultDSANone(SourceLocation Loc) { 342 assert(!isStackEmpty()); 343 Stack.back().first.back().DefaultAttr = DSA_none; 344 Stack.back().first.back().DefaultAttrLoc = Loc; 345 } 346 /// \brief Set default data sharing attribute to shared. 347 void setDefaultDSAShared(SourceLocation Loc) { 348 assert(!isStackEmpty()); 349 Stack.back().first.back().DefaultAttr = DSA_shared; 350 Stack.back().first.back().DefaultAttrLoc = Loc; 351 } 352 /// Set default data mapping attribute to 'tofrom:scalar'. 353 void setDefaultDMAToFromScalar(SourceLocation Loc) { 354 assert(!isStackEmpty()); 355 Stack.back().first.back().DefaultMapAttr = DMA_tofrom_scalar; 356 Stack.back().first.back().DefaultMapAttrLoc = Loc; 357 } 358 359 DefaultDataSharingAttributes getDefaultDSA() const { 360 return isStackEmpty() ? DSA_unspecified 361 : Stack.back().first.back().DefaultAttr; 362 } 363 SourceLocation getDefaultDSALocation() const { 364 return isStackEmpty() ? SourceLocation() 365 : Stack.back().first.back().DefaultAttrLoc; 366 } 367 DefaultMapAttributes getDefaultDMA() const { 368 return isStackEmpty() ? DMA_unspecified 369 : Stack.back().first.back().DefaultMapAttr; 370 } 371 DefaultMapAttributes getDefaultDMAAtLevel(unsigned Level) const { 372 return Stack.back().first[Level].DefaultMapAttr; 373 } 374 SourceLocation getDefaultDMALocation() const { 375 return isStackEmpty() ? SourceLocation() 376 : Stack.back().first.back().DefaultMapAttrLoc; 377 } 378 379 /// \brief Checks if the specified variable is a threadprivate. 380 bool isThreadPrivate(VarDecl *D) { 381 DSAVarData DVar = getTopDSA(D, false); 382 return isOpenMPThreadPrivate(DVar.CKind); 383 } 384 385 /// \brief Marks current region as ordered (it has an 'ordered' clause). 386 void setOrderedRegion(bool IsOrdered, Expr *Param) { 387 assert(!isStackEmpty()); 388 Stack.back().first.back().OrderedRegion.setInt(IsOrdered); 389 Stack.back().first.back().OrderedRegion.setPointer(Param); 390 } 391 /// \brief Returns true, if parent region is ordered (has associated 392 /// 'ordered' clause), false - otherwise. 393 bool isParentOrderedRegion() const { 394 if (isStackEmpty() || Stack.back().first.size() == 1) 395 return false; 396 return std::next(Stack.back().first.rbegin())->OrderedRegion.getInt(); 397 } 398 /// \brief Returns optional parameter for the ordered region. 399 Expr *getParentOrderedRegionParam() const { 400 if (isStackEmpty() || Stack.back().first.size() == 1) 401 return nullptr; 402 return std::next(Stack.back().first.rbegin())->OrderedRegion.getPointer(); 403 } 404 /// \brief Marks current region as nowait (it has a 'nowait' clause). 405 void setNowaitRegion(bool IsNowait = true) { 406 assert(!isStackEmpty()); 407 Stack.back().first.back().NowaitRegion = IsNowait; 408 } 409 /// \brief Returns true, if parent region is nowait (has associated 410 /// 'nowait' clause), false - otherwise. 411 bool isParentNowaitRegion() const { 412 if (isStackEmpty() || Stack.back().first.size() == 1) 413 return false; 414 return std::next(Stack.back().first.rbegin())->NowaitRegion; 415 } 416 /// \brief Marks parent region as cancel region. 417 void setParentCancelRegion(bool Cancel = true) { 418 if (!isStackEmpty() && Stack.back().first.size() > 1) { 419 auto &StackElemRef = *std::next(Stack.back().first.rbegin()); 420 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel; 421 } 422 } 423 /// \brief Return true if current region has inner cancel construct. 424 bool isCancelRegion() const { 425 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion; 426 } 427 428 /// \brief Set collapse value for the region. 429 void setAssociatedLoops(unsigned Val) { 430 assert(!isStackEmpty()); 431 Stack.back().first.back().AssociatedLoops = Val; 432 } 433 /// \brief Return collapse value for region. 434 unsigned getAssociatedLoops() const { 435 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops; 436 } 437 438 /// \brief Marks current target region as one with closely nested teams 439 /// region. 440 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 441 if (!isStackEmpty() && Stack.back().first.size() > 1) { 442 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc = 443 TeamsRegionLoc; 444 } 445 } 446 /// \brief Returns true, if current region has closely nested teams region. 447 bool hasInnerTeamsRegion() const { 448 return getInnerTeamsRegionLoc().isValid(); 449 } 450 /// \brief Returns location of the nested teams region (if any). 451 SourceLocation getInnerTeamsRegionLoc() const { 452 return isStackEmpty() ? SourceLocation() 453 : Stack.back().first.back().InnerTeamsRegionLoc; 454 } 455 456 Scope *getCurScope() const { 457 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 458 } 459 Scope *getCurScope() { 460 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 461 } 462 SourceLocation getConstructLoc() { 463 return isStackEmpty() ? SourceLocation() 464 : Stack.back().first.back().ConstructLoc; 465 } 466 467 /// Do the check specified in \a Check to all component lists and return true 468 /// if any issue is found. 469 bool checkMappableExprComponentListsForDecl( 470 ValueDecl *VD, bool CurrentRegionOnly, 471 const llvm::function_ref< 472 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 473 OpenMPClauseKind)> &Check) { 474 if (isStackEmpty()) 475 return false; 476 auto SI = Stack.back().first.rbegin(); 477 auto SE = Stack.back().first.rend(); 478 479 if (SI == SE) 480 return false; 481 482 if (CurrentRegionOnly) { 483 SE = std::next(SI); 484 } else { 485 ++SI; 486 } 487 488 for (; SI != SE; ++SI) { 489 auto MI = SI->MappedExprComponents.find(VD); 490 if (MI != SI->MappedExprComponents.end()) 491 for (auto &L : MI->second.Components) 492 if (Check(L, MI->second.Kind)) 493 return true; 494 } 495 return false; 496 } 497 498 /// Do the check specified in \a Check to all component lists at a given level 499 /// and return true if any issue is found. 500 bool checkMappableExprComponentListsForDeclAtLevel( 501 ValueDecl *VD, unsigned Level, 502 const llvm::function_ref< 503 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 504 OpenMPClauseKind)> &Check) { 505 if (isStackEmpty()) 506 return false; 507 508 auto StartI = Stack.back().first.begin(); 509 auto EndI = Stack.back().first.end(); 510 if (std::distance(StartI, EndI) <= (int)Level) 511 return false; 512 std::advance(StartI, Level); 513 514 auto MI = StartI->MappedExprComponents.find(VD); 515 if (MI != StartI->MappedExprComponents.end()) 516 for (auto &L : MI->second.Components) 517 if (Check(L, MI->second.Kind)) 518 return true; 519 return false; 520 } 521 522 /// Create a new mappable expression component list associated with a given 523 /// declaration and initialize it with the provided list of components. 524 void addMappableExpressionComponents( 525 ValueDecl *VD, 526 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 527 OpenMPClauseKind WhereFoundClauseKind) { 528 assert(!isStackEmpty() && 529 "Not expecting to retrieve components from a empty stack!"); 530 auto &MEC = Stack.back().first.back().MappedExprComponents[VD]; 531 // Create new entry and append the new components there. 532 MEC.Components.resize(MEC.Components.size() + 1); 533 MEC.Components.back().append(Components.begin(), Components.end()); 534 MEC.Kind = WhereFoundClauseKind; 535 } 536 537 unsigned getNestingLevel() const { 538 assert(!isStackEmpty()); 539 return Stack.back().first.size() - 1; 540 } 541 void addDoacrossDependClause(OMPDependClause *C, OperatorOffsetTy &OpsOffs) { 542 assert(!isStackEmpty() && Stack.back().first.size() > 1); 543 auto &StackElem = *std::next(Stack.back().first.rbegin()); 544 assert(isOpenMPWorksharingDirective(StackElem.Directive)); 545 StackElem.DoacrossDepends.insert({C, OpsOffs}); 546 } 547 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 548 getDoacrossDependClauses() const { 549 assert(!isStackEmpty()); 550 auto &StackElem = Stack.back().first.back(); 551 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 552 auto &Ref = StackElem.DoacrossDepends; 553 return llvm::make_range(Ref.begin(), Ref.end()); 554 } 555 return llvm::make_range(StackElem.DoacrossDepends.end(), 556 StackElem.DoacrossDepends.end()); 557 } 558 }; 559 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { 560 return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) || 561 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; 562 } 563 } // namespace 564 565 static Expr *getExprAsWritten(Expr *E) { 566 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) 567 E = ExprTemp->getSubExpr(); 568 569 if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 570 E = MTE->GetTemporaryExpr(); 571 572 while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 573 E = Binder->getSubExpr(); 574 575 if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 576 E = ICE->getSubExprAsWritten(); 577 return E->IgnoreParens(); 578 } 579 580 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 581 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 582 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 583 D = ME->getMemberDecl(); 584 auto *VD = dyn_cast<VarDecl>(D); 585 auto *FD = dyn_cast<FieldDecl>(D); 586 if (VD != nullptr) { 587 VD = VD->getCanonicalDecl(); 588 D = VD; 589 } else { 590 assert(FD); 591 FD = FD->getCanonicalDecl(); 592 D = FD; 593 } 594 return D; 595 } 596 597 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter, 598 ValueDecl *D) { 599 D = getCanonicalDecl(D); 600 auto *VD = dyn_cast<VarDecl>(D); 601 auto *FD = dyn_cast<FieldDecl>(D); 602 DSAVarData DVar; 603 if (isStackEmpty() || Iter == Stack.back().first.rend()) { 604 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 605 // in a region but not in construct] 606 // File-scope or namespace-scope variables referenced in called routines 607 // in the region are shared unless they appear in a threadprivate 608 // directive. 609 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D)) 610 DVar.CKind = OMPC_shared; 611 612 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 613 // in a region but not in construct] 614 // Variables with static storage duration that are declared in called 615 // routines in the region are shared. 616 if (VD && VD->hasGlobalStorage()) 617 DVar.CKind = OMPC_shared; 618 619 // Non-static data members are shared by default. 620 if (FD) 621 DVar.CKind = OMPC_shared; 622 623 return DVar; 624 } 625 626 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 627 // in a Construct, C/C++, predetermined, p.1] 628 // Variables with automatic storage duration that are declared in a scope 629 // inside the construct are private. 630 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 631 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 632 DVar.CKind = OMPC_private; 633 return DVar; 634 } 635 636 DVar.DKind = Iter->Directive; 637 // Explicitly specified attributes and local variables with predetermined 638 // attributes. 639 if (Iter->SharingMap.count(D)) { 640 DVar.RefExpr = Iter->SharingMap[D].RefExpr.getPointer(); 641 DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy; 642 DVar.CKind = Iter->SharingMap[D].Attributes; 643 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 644 return DVar; 645 } 646 647 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 648 // in a Construct, C/C++, implicitly determined, p.1] 649 // In a parallel or task construct, the data-sharing attributes of these 650 // variables are determined by the default clause, if present. 651 switch (Iter->DefaultAttr) { 652 case DSA_shared: 653 DVar.CKind = OMPC_shared; 654 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 655 return DVar; 656 case DSA_none: 657 return DVar; 658 case DSA_unspecified: 659 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 660 // in a Construct, implicitly determined, p.2] 661 // In a parallel construct, if no default clause is present, these 662 // variables are shared. 663 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 664 if (isOpenMPParallelDirective(DVar.DKind) || 665 isOpenMPTeamsDirective(DVar.DKind)) { 666 DVar.CKind = OMPC_shared; 667 return DVar; 668 } 669 670 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 671 // in a Construct, implicitly determined, p.4] 672 // In a task construct, if no default clause is present, a variable that in 673 // the enclosing context is determined to be shared by all implicit tasks 674 // bound to the current team is shared. 675 if (isOpenMPTaskingDirective(DVar.DKind)) { 676 DSAVarData DVarTemp; 677 auto I = Iter, E = Stack.back().first.rend(); 678 do { 679 ++I; 680 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 681 // Referenced in a Construct, implicitly determined, p.6] 682 // In a task construct, if no default clause is present, a variable 683 // whose data-sharing attribute is not determined by the rules above is 684 // firstprivate. 685 DVarTemp = getDSA(I, D); 686 if (DVarTemp.CKind != OMPC_shared) { 687 DVar.RefExpr = nullptr; 688 DVar.CKind = OMPC_firstprivate; 689 return DVar; 690 } 691 } while (I != E && !isParallelOrTaskRegion(I->Directive)); 692 DVar.CKind = 693 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 694 return DVar; 695 } 696 } 697 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 698 // in a Construct, implicitly determined, p.3] 699 // For constructs other than task, if no default clause is present, these 700 // variables inherit their data-sharing attributes from the enclosing 701 // context. 702 return getDSA(++Iter, D); 703 } 704 705 Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) { 706 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 707 D = getCanonicalDecl(D); 708 auto &StackElem = Stack.back().first.back(); 709 auto It = StackElem.AlignedMap.find(D); 710 if (It == StackElem.AlignedMap.end()) { 711 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 712 StackElem.AlignedMap[D] = NewDE; 713 return nullptr; 714 } else { 715 assert(It->second && "Unexpected nullptr expr in the aligned map"); 716 return It->second; 717 } 718 return nullptr; 719 } 720 721 void DSAStackTy::addLoopControlVariable(ValueDecl *D, VarDecl *Capture) { 722 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 723 D = getCanonicalDecl(D); 724 auto &StackElem = Stack.back().first.back(); 725 StackElem.LCVMap.insert( 726 {D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)}); 727 } 728 729 DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(ValueDecl *D) { 730 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 731 D = getCanonicalDecl(D); 732 auto &StackElem = Stack.back().first.back(); 733 auto It = StackElem.LCVMap.find(D); 734 if (It != StackElem.LCVMap.end()) 735 return It->second; 736 return {0, nullptr}; 737 } 738 739 DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(ValueDecl *D) { 740 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 741 "Data-sharing attributes stack is empty"); 742 D = getCanonicalDecl(D); 743 auto &StackElem = *std::next(Stack.back().first.rbegin()); 744 auto It = StackElem.LCVMap.find(D); 745 if (It != StackElem.LCVMap.end()) 746 return It->second; 747 return {0, nullptr}; 748 } 749 750 ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) { 751 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 752 "Data-sharing attributes stack is empty"); 753 auto &StackElem = *std::next(Stack.back().first.rbegin()); 754 if (StackElem.LCVMap.size() < I) 755 return nullptr; 756 for (auto &Pair : StackElem.LCVMap) 757 if (Pair.second.first == I) 758 return Pair.first; 759 return nullptr; 760 } 761 762 void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 763 DeclRefExpr *PrivateCopy) { 764 D = getCanonicalDecl(D); 765 if (A == OMPC_threadprivate) { 766 auto &Data = Threadprivates[D]; 767 Data.Attributes = A; 768 Data.RefExpr.setPointer(E); 769 Data.PrivateCopy = nullptr; 770 } else { 771 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 772 auto &Data = Stack.back().first.back().SharingMap[D]; 773 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 774 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 775 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 776 (isLoopControlVariable(D).first && A == OMPC_private)); 777 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 778 Data.RefExpr.setInt(/*IntVal=*/true); 779 return; 780 } 781 const bool IsLastprivate = 782 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 783 Data.Attributes = A; 784 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 785 Data.PrivateCopy = PrivateCopy; 786 if (PrivateCopy) { 787 auto &Data = Stack.back().first.back().SharingMap[PrivateCopy->getDecl()]; 788 Data.Attributes = A; 789 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 790 Data.PrivateCopy = nullptr; 791 } 792 } 793 } 794 795 /// \brief Build a variable declaration for OpenMP loop iteration variable. 796 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 797 StringRef Name, const AttrVec *Attrs = nullptr) { 798 DeclContext *DC = SemaRef.CurContext; 799 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 800 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 801 VarDecl *Decl = 802 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 803 if (Attrs) { 804 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 805 I != E; ++I) 806 Decl->addAttr(*I); 807 } 808 Decl->setImplicit(); 809 return Decl; 810 } 811 812 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 813 SourceLocation Loc, 814 bool RefersToCapture = false) { 815 D->setReferenced(); 816 D->markUsed(S.Context); 817 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 818 SourceLocation(), D, RefersToCapture, Loc, Ty, 819 VK_LValue); 820 } 821 822 void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR, 823 BinaryOperatorKind BOK) { 824 D = getCanonicalDecl(D); 825 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 826 assert( 827 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 828 "Additional reduction info may be specified only for reduction items."); 829 auto &ReductionData = Stack.back().first.back().ReductionMap[D]; 830 assert(ReductionData.ReductionRange.isInvalid() && 831 Stack.back().first.back().Directive == OMPD_taskgroup && 832 "Additional reduction info may be specified only once for reduction " 833 "items."); 834 ReductionData.set(BOK, SR); 835 Expr *&TaskgroupReductionRef = 836 Stack.back().first.back().TaskgroupReductionRef; 837 if (!TaskgroupReductionRef) { 838 auto *VD = buildVarDecl(SemaRef, SourceLocation(), 839 SemaRef.Context.VoidPtrTy, ".task_red."); 840 TaskgroupReductionRef = buildDeclRefExpr( 841 SemaRef, VD, SemaRef.Context.VoidPtrTy, SourceLocation()); 842 } 843 } 844 845 void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR, 846 const Expr *ReductionRef) { 847 D = getCanonicalDecl(D); 848 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 849 assert( 850 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 851 "Additional reduction info may be specified only for reduction items."); 852 auto &ReductionData = Stack.back().first.back().ReductionMap[D]; 853 assert(ReductionData.ReductionRange.isInvalid() && 854 Stack.back().first.back().Directive == OMPD_taskgroup && 855 "Additional reduction info may be specified only once for reduction " 856 "items."); 857 ReductionData.set(ReductionRef, SR); 858 Expr *&TaskgroupReductionRef = 859 Stack.back().first.back().TaskgroupReductionRef; 860 if (!TaskgroupReductionRef) { 861 auto *VD = buildVarDecl(SemaRef, SourceLocation(), 862 SemaRef.Context.VoidPtrTy, ".task_red."); 863 TaskgroupReductionRef = buildDeclRefExpr( 864 SemaRef, VD, SemaRef.Context.VoidPtrTy, SourceLocation()); 865 } 866 } 867 868 DSAStackTy::DSAVarData 869 DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, 870 BinaryOperatorKind &BOK, 871 Expr *&TaskgroupDescriptor) { 872 D = getCanonicalDecl(D); 873 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 874 if (Stack.back().first.empty()) 875 return DSAVarData(); 876 for (auto I = std::next(Stack.back().first.rbegin(), 1), 877 E = Stack.back().first.rend(); 878 I != E; std::advance(I, 1)) { 879 auto &Data = I->SharingMap[D]; 880 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 881 continue; 882 auto &ReductionData = I->ReductionMap[D]; 883 if (!ReductionData.ReductionOp || 884 ReductionData.ReductionOp.is<const Expr *>()) 885 return DSAVarData(); 886 SR = ReductionData.ReductionRange; 887 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 888 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 889 "expression for the descriptor is not " 890 "set."); 891 TaskgroupDescriptor = I->TaskgroupReductionRef; 892 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 893 Data.PrivateCopy, I->DefaultAttrLoc); 894 } 895 return DSAVarData(); 896 } 897 898 DSAStackTy::DSAVarData 899 DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, 900 const Expr *&ReductionRef, 901 Expr *&TaskgroupDescriptor) { 902 D = getCanonicalDecl(D); 903 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 904 if (Stack.back().first.empty()) 905 return DSAVarData(); 906 for (auto I = std::next(Stack.back().first.rbegin(), 1), 907 E = Stack.back().first.rend(); 908 I != E; std::advance(I, 1)) { 909 auto &Data = I->SharingMap[D]; 910 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 911 continue; 912 auto &ReductionData = I->ReductionMap[D]; 913 if (!ReductionData.ReductionOp || 914 !ReductionData.ReductionOp.is<const Expr *>()) 915 return DSAVarData(); 916 SR = ReductionData.ReductionRange; 917 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 918 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 919 "expression for the descriptor is not " 920 "set."); 921 TaskgroupDescriptor = I->TaskgroupReductionRef; 922 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 923 Data.PrivateCopy, I->DefaultAttrLoc); 924 } 925 return DSAVarData(); 926 } 927 928 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) { 929 D = D->getCanonicalDecl(); 930 if (!isStackEmpty() && Stack.back().first.size() > 1) { 931 reverse_iterator I = Iter, E = Stack.back().first.rend(); 932 Scope *TopScope = nullptr; 933 while (I != E && !isParallelOrTaskRegion(I->Directive)) 934 ++I; 935 if (I == E) 936 return false; 937 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 938 Scope *CurScope = getCurScope(); 939 while (CurScope != TopScope && !CurScope->isDeclScope(D)) 940 CurScope = CurScope->getParent(); 941 return CurScope != TopScope; 942 } 943 return false; 944 } 945 946 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) { 947 D = getCanonicalDecl(D); 948 DSAVarData DVar; 949 950 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 951 // in a Construct, C/C++, predetermined, p.1] 952 // Variables appearing in threadprivate directives are threadprivate. 953 auto *VD = dyn_cast<VarDecl>(D); 954 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 955 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 956 SemaRef.getLangOpts().OpenMPUseTLS && 957 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 958 (VD && VD->getStorageClass() == SC_Register && 959 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 960 addDSA(D, buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 961 D->getLocation()), 962 OMPC_threadprivate); 963 } 964 auto TI = Threadprivates.find(D); 965 if (TI != Threadprivates.end()) { 966 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 967 DVar.CKind = OMPC_threadprivate; 968 return DVar; 969 } 970 971 if (isStackEmpty()) 972 // Not in OpenMP execution region and top scope was already checked. 973 return DVar; 974 975 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 976 // in a Construct, C/C++, predetermined, p.4] 977 // Static data members are shared. 978 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 979 // in a Construct, C/C++, predetermined, p.7] 980 // Variables with static storage duration that are declared in a scope 981 // inside the construct are shared. 982 auto &&MatchesAlways = [](OpenMPDirectiveKind) -> bool { return true; }; 983 if (VD && VD->isStaticDataMember()) { 984 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 985 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 986 return DVar; 987 988 DVar.CKind = OMPC_shared; 989 return DVar; 990 } 991 992 QualType Type = D->getType().getNonReferenceType().getCanonicalType(); 993 bool IsConstant = Type.isConstant(SemaRef.getASTContext()); 994 Type = SemaRef.getASTContext().getBaseElementType(Type); 995 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 996 // in a Construct, C/C++, predetermined, p.6] 997 // Variables with const qualified type having no mutable member are 998 // shared. 999 CXXRecordDecl *RD = 1000 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 1001 if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 1002 if (auto *CTD = CTSD->getSpecializedTemplate()) 1003 RD = CTD->getTemplatedDecl(); 1004 if (IsConstant && 1005 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() && 1006 RD->hasMutableFields())) { 1007 // Variables with const-qualified type having no mutable member may be 1008 // listed in a firstprivate clause, even if they are static data members. 1009 DSAVarData DVarTemp = hasDSA( 1010 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_firstprivate; }, 1011 MatchesAlways, FromParent); 1012 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 1013 return DVar; 1014 1015 DVar.CKind = OMPC_shared; 1016 return DVar; 1017 } 1018 1019 // Explicitly specified attributes and local variables with predetermined 1020 // attributes. 1021 auto I = Stack.back().first.rbegin(); 1022 auto EndI = Stack.back().first.rend(); 1023 if (FromParent && I != EndI) 1024 std::advance(I, 1); 1025 if (I->SharingMap.count(D)) { 1026 DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer(); 1027 DVar.PrivateCopy = I->SharingMap[D].PrivateCopy; 1028 DVar.CKind = I->SharingMap[D].Attributes; 1029 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1030 DVar.DKind = I->Directive; 1031 } 1032 1033 return DVar; 1034 } 1035 1036 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1037 bool FromParent) { 1038 if (isStackEmpty()) { 1039 StackTy::reverse_iterator I; 1040 return getDSA(I, D); 1041 } 1042 D = getCanonicalDecl(D); 1043 auto StartI = Stack.back().first.rbegin(); 1044 auto EndI = Stack.back().first.rend(); 1045 if (FromParent && StartI != EndI) 1046 std::advance(StartI, 1); 1047 return getDSA(StartI, D); 1048 } 1049 1050 DSAStackTy::DSAVarData 1051 DSAStackTy::hasDSA(ValueDecl *D, 1052 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 1053 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 1054 bool FromParent) { 1055 if (isStackEmpty()) 1056 return {}; 1057 D = getCanonicalDecl(D); 1058 auto I = Stack.back().first.rbegin(); 1059 auto EndI = Stack.back().first.rend(); 1060 if (FromParent && I != EndI) 1061 std::advance(I, 1); 1062 for (; I != EndI; std::advance(I, 1)) { 1063 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) 1064 continue; 1065 auto NewI = I; 1066 DSAVarData DVar = getDSA(NewI, D); 1067 if (I == NewI && CPred(DVar.CKind)) 1068 return DVar; 1069 } 1070 return {}; 1071 } 1072 1073 DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1074 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 1075 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 1076 bool FromParent) { 1077 if (isStackEmpty()) 1078 return {}; 1079 D = getCanonicalDecl(D); 1080 auto StartI = Stack.back().first.rbegin(); 1081 auto EndI = Stack.back().first.rend(); 1082 if (FromParent && StartI != EndI) 1083 std::advance(StartI, 1); 1084 if (StartI == EndI || !DPred(StartI->Directive)) 1085 return {}; 1086 auto NewI = StartI; 1087 DSAVarData DVar = getDSA(NewI, D); 1088 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1089 } 1090 1091 bool DSAStackTy::hasExplicitDSA( 1092 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 1093 unsigned Level, bool NotLastprivate) { 1094 if (CPred(ClauseKindMode)) 1095 return true; 1096 if (isStackEmpty()) 1097 return false; 1098 D = getCanonicalDecl(D); 1099 auto StartI = Stack.back().first.begin(); 1100 auto EndI = Stack.back().first.end(); 1101 if (std::distance(StartI, EndI) <= (int)Level) 1102 return false; 1103 std::advance(StartI, Level); 1104 return (StartI->SharingMap.count(D) > 0) && 1105 StartI->SharingMap[D].RefExpr.getPointer() && 1106 CPred(StartI->SharingMap[D].Attributes) && 1107 (!NotLastprivate || !StartI->SharingMap[D].RefExpr.getInt()); 1108 } 1109 1110 bool DSAStackTy::hasExplicitDirective( 1111 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 1112 unsigned Level) { 1113 if (isStackEmpty()) 1114 return false; 1115 auto StartI = Stack.back().first.begin(); 1116 auto EndI = Stack.back().first.end(); 1117 if (std::distance(StartI, EndI) <= (int)Level) 1118 return false; 1119 std::advance(StartI, Level); 1120 return DPred(StartI->Directive); 1121 } 1122 1123 bool DSAStackTy::hasDirective( 1124 const llvm::function_ref<bool(OpenMPDirectiveKind, 1125 const DeclarationNameInfo &, SourceLocation)> 1126 &DPred, 1127 bool FromParent) { 1128 // We look only in the enclosing region. 1129 if (isStackEmpty()) 1130 return false; 1131 auto StartI = std::next(Stack.back().first.rbegin()); 1132 auto EndI = Stack.back().first.rend(); 1133 if (FromParent && StartI != EndI) 1134 StartI = std::next(StartI); 1135 for (auto I = StartI, EE = EndI; I != EE; ++I) { 1136 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1137 return true; 1138 } 1139 return false; 1140 } 1141 1142 void Sema::InitDataSharingAttributesStack() { 1143 VarDataSharingAttributesStack = new DSAStackTy(*this); 1144 } 1145 1146 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1147 1148 void Sema::pushOpenMPFunctionRegion() { 1149 DSAStack->pushFunction(); 1150 } 1151 1152 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1153 DSAStack->popFunction(OldFSI); 1154 } 1155 1156 bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level) { 1157 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1158 1159 auto &Ctx = getASTContext(); 1160 bool IsByRef = true; 1161 1162 // Find the directive that is associated with the provided scope. 1163 D = cast<ValueDecl>(D->getCanonicalDecl()); 1164 auto Ty = D->getType(); 1165 1166 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1167 // This table summarizes how a given variable should be passed to the device 1168 // given its type and the clauses where it appears. This table is based on 1169 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1170 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1171 // 1172 // ========================================================================= 1173 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1174 // | |(tofrom:scalar)| | pvt | | | | 1175 // ========================================================================= 1176 // | scl | | | | - | | bycopy| 1177 // | scl | | - | x | - | - | bycopy| 1178 // | scl | | x | - | - | - | null | 1179 // | scl | x | | | - | | byref | 1180 // | scl | x | - | x | - | - | bycopy| 1181 // | scl | x | x | - | - | - | null | 1182 // | scl | | - | - | - | x | byref | 1183 // | scl | x | - | - | - | x | byref | 1184 // 1185 // | agg | n.a. | | | - | | byref | 1186 // | agg | n.a. | - | x | - | - | byref | 1187 // | agg | n.a. | x | - | - | - | null | 1188 // | agg | n.a. | - | - | - | x | byref | 1189 // | agg | n.a. | - | - | - | x[] | byref | 1190 // 1191 // | ptr | n.a. | | | - | | bycopy| 1192 // | ptr | n.a. | - | x | - | - | bycopy| 1193 // | ptr | n.a. | x | - | - | - | null | 1194 // | ptr | n.a. | - | - | - | x | byref | 1195 // | ptr | n.a. | - | - | - | x[] | bycopy| 1196 // | ptr | n.a. | - | - | x | | bycopy| 1197 // | ptr | n.a. | - | - | x | x | bycopy| 1198 // | ptr | n.a. | - | - | x | x[] | bycopy| 1199 // ========================================================================= 1200 // Legend: 1201 // scl - scalar 1202 // ptr - pointer 1203 // agg - aggregate 1204 // x - applies 1205 // - - invalid in this combination 1206 // [] - mapped with an array section 1207 // byref - should be mapped by reference 1208 // byval - should be mapped by value 1209 // null - initialize a local variable to null on the device 1210 // 1211 // Observations: 1212 // - All scalar declarations that show up in a map clause have to be passed 1213 // by reference, because they may have been mapped in the enclosing data 1214 // environment. 1215 // - If the scalar value does not fit the size of uintptr, it has to be 1216 // passed by reference, regardless the result in the table above. 1217 // - For pointers mapped by value that have either an implicit map or an 1218 // array section, the runtime library may pass the NULL value to the 1219 // device instead of the value passed to it by the compiler. 1220 1221 if (Ty->isReferenceType()) 1222 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1223 1224 // Locate map clauses and see if the variable being captured is referred to 1225 // in any of those clauses. Here we only care about variables, not fields, 1226 // because fields are part of aggregates. 1227 bool IsVariableUsedInMapClause = false; 1228 bool IsVariableAssociatedWithSection = false; 1229 1230 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1231 D, Level, [&](OMPClauseMappableExprCommon::MappableExprComponentListRef 1232 MapExprComponents, 1233 OpenMPClauseKind WhereFoundClauseKind) { 1234 // Only the map clause information influences how a variable is 1235 // captured. E.g. is_device_ptr does not require changing the default 1236 // behavior. 1237 if (WhereFoundClauseKind != OMPC_map) 1238 return false; 1239 1240 auto EI = MapExprComponents.rbegin(); 1241 auto EE = MapExprComponents.rend(); 1242 1243 assert(EI != EE && "Invalid map expression!"); 1244 1245 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1246 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1247 1248 ++EI; 1249 if (EI == EE) 1250 return false; 1251 1252 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1253 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1254 isa<MemberExpr>(EI->getAssociatedExpression())) { 1255 IsVariableAssociatedWithSection = true; 1256 // There is nothing more we need to know about this variable. 1257 return true; 1258 } 1259 1260 // Keep looking for more map info. 1261 return false; 1262 }); 1263 1264 if (IsVariableUsedInMapClause) { 1265 // If variable is identified in a map clause it is always captured by 1266 // reference except if it is a pointer that is dereferenced somehow. 1267 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1268 } else { 1269 // By default, all the data that has a scalar type is mapped by copy. 1270 IsByRef = !Ty->isScalarType() || 1271 DSAStack->getDefaultDMAAtLevel(Level) == DMA_tofrom_scalar; 1272 } 1273 } 1274 1275 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1276 IsByRef = !DSAStack->hasExplicitDSA( 1277 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1278 Level, /*NotLastprivate=*/true); 1279 } 1280 1281 // When passing data by copy, we need to make sure it fits the uintptr size 1282 // and alignment, because the runtime library only deals with uintptr types. 1283 // If it does not fit the uintptr size, we need to pass the data by reference 1284 // instead. 1285 if (!IsByRef && 1286 (Ctx.getTypeSizeInChars(Ty) > 1287 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1288 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1289 IsByRef = true; 1290 } 1291 1292 return IsByRef; 1293 } 1294 1295 unsigned Sema::getOpenMPNestingLevel() const { 1296 assert(getLangOpts().OpenMP); 1297 return DSAStack->getNestingLevel(); 1298 } 1299 1300 VarDecl *Sema::IsOpenMPCapturedDecl(ValueDecl *D) { 1301 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1302 D = getCanonicalDecl(D); 1303 1304 // If we are attempting to capture a global variable in a directive with 1305 // 'target' we return true so that this global is also mapped to the device. 1306 // 1307 // FIXME: If the declaration is enclosed in a 'declare target' directive, 1308 // then it should not be captured. Therefore, an extra check has to be 1309 // inserted here once support for 'declare target' is added. 1310 // 1311 auto *VD = dyn_cast<VarDecl>(D); 1312 if (VD && !VD->hasLocalStorage()) { 1313 if (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1314 !DSAStack->isClauseParsingMode()) 1315 return VD; 1316 if (DSAStack->hasDirective( 1317 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1318 SourceLocation) -> bool { 1319 return isOpenMPTargetExecutionDirective(K); 1320 }, 1321 false)) 1322 return VD; 1323 } 1324 1325 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1326 (!DSAStack->isClauseParsingMode() || 1327 DSAStack->getParentDirective() != OMPD_unknown)) { 1328 auto &&Info = DSAStack->isLoopControlVariable(D); 1329 if (Info.first || 1330 (VD && VD->hasLocalStorage() && 1331 isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || 1332 (VD && DSAStack->isForceVarCapturing())) 1333 return VD ? VD : Info.second; 1334 auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1335 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1336 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1337 DVarPrivate = DSAStack->hasDSA( 1338 D, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, 1339 DSAStack->isClauseParsingMode()); 1340 if (DVarPrivate.CKind != OMPC_unknown) 1341 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1342 } 1343 return nullptr; 1344 } 1345 1346 bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) { 1347 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1348 return DSAStack->hasExplicitDSA( 1349 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, 1350 Level) || 1351 // Consider taskgroup reduction descriptor variable a private to avoid 1352 // possible capture in the region. 1353 (DSAStack->hasExplicitDirective( 1354 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1355 Level) && 1356 DSAStack->isTaskgroupReductionRef(D, Level)); 1357 } 1358 1359 void Sema::setOpenMPCaptureKind(FieldDecl *FD, ValueDecl *D, unsigned Level) { 1360 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1361 D = getCanonicalDecl(D); 1362 OpenMPClauseKind OMPC = OMPC_unknown; 1363 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1364 const unsigned NewLevel = I - 1; 1365 if (DSAStack->hasExplicitDSA(D, 1366 [&OMPC](const OpenMPClauseKind K) { 1367 if (isOpenMPPrivate(K)) { 1368 OMPC = K; 1369 return true; 1370 } 1371 return false; 1372 }, 1373 NewLevel)) 1374 break; 1375 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1376 D, NewLevel, 1377 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1378 OpenMPClauseKind) { return true; })) { 1379 OMPC = OMPC_map; 1380 break; 1381 } 1382 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1383 NewLevel)) { 1384 OMPC = OMPC_firstprivate; 1385 break; 1386 } 1387 } 1388 if (OMPC != OMPC_unknown) 1389 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1390 } 1391 1392 bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) { 1393 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1394 // Return true if the current level is no longer enclosed in a target region. 1395 1396 auto *VD = dyn_cast<VarDecl>(D); 1397 return VD && !VD->hasLocalStorage() && 1398 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1399 Level); 1400 } 1401 1402 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1403 1404 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1405 const DeclarationNameInfo &DirName, 1406 Scope *CurScope, SourceLocation Loc) { 1407 DSAStack->push(DKind, DirName, CurScope, Loc); 1408 PushExpressionEvaluationContext( 1409 ExpressionEvaluationContext::PotentiallyEvaluated); 1410 } 1411 1412 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1413 DSAStack->setClauseParsingMode(K); 1414 } 1415 1416 void Sema::EndOpenMPClause() { 1417 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1418 } 1419 1420 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1421 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1422 // A variable of class type (or array thereof) that appears in a lastprivate 1423 // clause requires an accessible, unambiguous default constructor for the 1424 // class type, unless the list item is also specified in a firstprivate 1425 // clause. 1426 if (auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1427 for (auto *C : D->clauses()) { 1428 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1429 SmallVector<Expr *, 8> PrivateCopies; 1430 for (auto *DE : Clause->varlists()) { 1431 if (DE->isValueDependent() || DE->isTypeDependent()) { 1432 PrivateCopies.push_back(nullptr); 1433 continue; 1434 } 1435 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1436 VarDecl *VD = cast<VarDecl>(DRE->getDecl()); 1437 QualType Type = VD->getType().getNonReferenceType(); 1438 auto DVar = DSAStack->getTopDSA(VD, false); 1439 if (DVar.CKind == OMPC_lastprivate) { 1440 // Generate helper private variable and initialize it with the 1441 // default value. The address of the original variable is replaced 1442 // by the address of the new private variable in CodeGen. This new 1443 // variable is not added to IdResolver, so the code in the OpenMP 1444 // region uses original variable for proper diagnostics. 1445 auto *VDPrivate = buildVarDecl( 1446 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1447 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr); 1448 ActOnUninitializedDecl(VDPrivate); 1449 if (VDPrivate->isInvalidDecl()) 1450 continue; 1451 PrivateCopies.push_back(buildDeclRefExpr( 1452 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1453 } else { 1454 // The variable is also a firstprivate, so initialization sequence 1455 // for private copy is generated already. 1456 PrivateCopies.push_back(nullptr); 1457 } 1458 } 1459 // Set initializers to private copies if no errors were found. 1460 if (PrivateCopies.size() == Clause->varlist_size()) 1461 Clause->setPrivateCopies(PrivateCopies); 1462 } 1463 } 1464 } 1465 1466 DSAStack->pop(); 1467 DiscardCleanupsInEvaluationContext(); 1468 PopExpressionEvaluationContext(); 1469 } 1470 1471 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1472 Expr *NumIterations, Sema &SemaRef, 1473 Scope *S, DSAStackTy *Stack); 1474 1475 namespace { 1476 1477 class VarDeclFilterCCC : public CorrectionCandidateCallback { 1478 private: 1479 Sema &SemaRef; 1480 1481 public: 1482 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1483 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1484 NamedDecl *ND = Candidate.getCorrectionDecl(); 1485 if (auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 1486 return VD->hasGlobalStorage() && 1487 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1488 SemaRef.getCurScope()); 1489 } 1490 return false; 1491 } 1492 }; 1493 1494 class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback { 1495 private: 1496 Sema &SemaRef; 1497 1498 public: 1499 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 1500 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1501 NamedDecl *ND = Candidate.getCorrectionDecl(); 1502 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { 1503 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1504 SemaRef.getCurScope()); 1505 } 1506 return false; 1507 } 1508 }; 1509 1510 } // namespace 1511 1512 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 1513 CXXScopeSpec &ScopeSpec, 1514 const DeclarationNameInfo &Id) { 1515 LookupResult Lookup(*this, Id, LookupOrdinaryName); 1516 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 1517 1518 if (Lookup.isAmbiguous()) 1519 return ExprError(); 1520 1521 VarDecl *VD; 1522 if (!Lookup.isSingleResult()) { 1523 if (TypoCorrection Corrected = CorrectTypo( 1524 Id, LookupOrdinaryName, CurScope, nullptr, 1525 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 1526 diagnoseTypo(Corrected, 1527 PDiag(Lookup.empty() 1528 ? diag::err_undeclared_var_use_suggest 1529 : diag::err_omp_expected_var_arg_suggest) 1530 << Id.getName()); 1531 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 1532 } else { 1533 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 1534 : diag::err_omp_expected_var_arg) 1535 << Id.getName(); 1536 return ExprError(); 1537 } 1538 } else { 1539 if (!(VD = Lookup.getAsSingle<VarDecl>())) { 1540 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 1541 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 1542 return ExprError(); 1543 } 1544 } 1545 Lookup.suppressDiagnostics(); 1546 1547 // OpenMP [2.9.2, Syntax, C/C++] 1548 // Variables must be file-scope, namespace-scope, or static block-scope. 1549 if (!VD->hasGlobalStorage()) { 1550 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 1551 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); 1552 bool IsDecl = 1553 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1554 Diag(VD->getLocation(), 1555 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1556 << VD; 1557 return ExprError(); 1558 } 1559 1560 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 1561 NamedDecl *ND = cast<NamedDecl>(CanonicalVD); 1562 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 1563 // A threadprivate directive for file-scope variables must appear outside 1564 // any definition or declaration. 1565 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 1566 !getCurLexicalContext()->isTranslationUnit()) { 1567 Diag(Id.getLoc(), diag::err_omp_var_scope) 1568 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1569 bool IsDecl = 1570 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1571 Diag(VD->getLocation(), 1572 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1573 << VD; 1574 return ExprError(); 1575 } 1576 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 1577 // A threadprivate directive for static class member variables must appear 1578 // in the class definition, in the same scope in which the member 1579 // variables are declared. 1580 if (CanonicalVD->isStaticDataMember() && 1581 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 1582 Diag(Id.getLoc(), diag::err_omp_var_scope) 1583 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1584 bool IsDecl = 1585 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1586 Diag(VD->getLocation(), 1587 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1588 << VD; 1589 return ExprError(); 1590 } 1591 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 1592 // A threadprivate directive for namespace-scope variables must appear 1593 // outside any definition or declaration other than the namespace 1594 // definition itself. 1595 if (CanonicalVD->getDeclContext()->isNamespace() && 1596 (!getCurLexicalContext()->isFileContext() || 1597 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 1598 Diag(Id.getLoc(), diag::err_omp_var_scope) 1599 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1600 bool IsDecl = 1601 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1602 Diag(VD->getLocation(), 1603 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1604 << VD; 1605 return ExprError(); 1606 } 1607 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 1608 // A threadprivate directive for static block-scope variables must appear 1609 // in the scope of the variable and not in a nested scope. 1610 if (CanonicalVD->isStaticLocal() && CurScope && 1611 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 1612 Diag(Id.getLoc(), diag::err_omp_var_scope) 1613 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1614 bool IsDecl = 1615 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1616 Diag(VD->getLocation(), 1617 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1618 << VD; 1619 return ExprError(); 1620 } 1621 1622 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 1623 // A threadprivate directive must lexically precede all references to any 1624 // of the variables in its list. 1625 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { 1626 Diag(Id.getLoc(), diag::err_omp_var_used) 1627 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1628 return ExprError(); 1629 } 1630 1631 QualType ExprType = VD->getType().getNonReferenceType(); 1632 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 1633 SourceLocation(), VD, 1634 /*RefersToEnclosingVariableOrCapture=*/false, 1635 Id.getLoc(), ExprType, VK_LValue); 1636 } 1637 1638 Sema::DeclGroupPtrTy 1639 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 1640 ArrayRef<Expr *> VarList) { 1641 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 1642 CurContext->addDecl(D); 1643 return DeclGroupPtrTy::make(DeclGroupRef(D)); 1644 } 1645 return nullptr; 1646 } 1647 1648 namespace { 1649 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> { 1650 Sema &SemaRef; 1651 1652 public: 1653 bool VisitDeclRefExpr(const DeclRefExpr *E) { 1654 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1655 if (VD->hasLocalStorage()) { 1656 SemaRef.Diag(E->getLocStart(), 1657 diag::err_omp_local_var_in_threadprivate_init) 1658 << E->getSourceRange(); 1659 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 1660 << VD << VD->getSourceRange(); 1661 return true; 1662 } 1663 } 1664 return false; 1665 } 1666 bool VisitStmt(const Stmt *S) { 1667 for (auto Child : S->children()) { 1668 if (Child && Visit(Child)) 1669 return true; 1670 } 1671 return false; 1672 } 1673 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 1674 }; 1675 } // namespace 1676 1677 OMPThreadPrivateDecl * 1678 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 1679 SmallVector<Expr *, 8> Vars; 1680 for (auto &RefExpr : VarList) { 1681 DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr); 1682 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 1683 SourceLocation ILoc = DE->getExprLoc(); 1684 1685 // Mark variable as used. 1686 VD->setReferenced(); 1687 VD->markUsed(Context); 1688 1689 QualType QType = VD->getType(); 1690 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 1691 // It will be analyzed later. 1692 Vars.push_back(DE); 1693 continue; 1694 } 1695 1696 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1697 // A threadprivate variable must not have an incomplete type. 1698 if (RequireCompleteType(ILoc, VD->getType(), 1699 diag::err_omp_threadprivate_incomplete_type)) { 1700 continue; 1701 } 1702 1703 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1704 // A threadprivate variable must not have a reference type. 1705 if (VD->getType()->isReferenceType()) { 1706 Diag(ILoc, diag::err_omp_ref_type_arg) 1707 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 1708 bool IsDecl = 1709 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1710 Diag(VD->getLocation(), 1711 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1712 << VD; 1713 continue; 1714 } 1715 1716 // Check if this is a TLS variable. If TLS is not being supported, produce 1717 // the corresponding diagnostic. 1718 if ((VD->getTLSKind() != VarDecl::TLS_None && 1719 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1720 getLangOpts().OpenMPUseTLS && 1721 getASTContext().getTargetInfo().isTLSSupported())) || 1722 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 1723 !VD->isLocalVarDecl())) { 1724 Diag(ILoc, diag::err_omp_var_thread_local) 1725 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 1726 bool IsDecl = 1727 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1728 Diag(VD->getLocation(), 1729 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1730 << VD; 1731 continue; 1732 } 1733 1734 // Check if initial value of threadprivate variable reference variable with 1735 // local storage (it is not supported by runtime). 1736 if (auto Init = VD->getAnyInitializer()) { 1737 LocalVarRefChecker Checker(*this); 1738 if (Checker.Visit(Init)) 1739 continue; 1740 } 1741 1742 Vars.push_back(RefExpr); 1743 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 1744 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 1745 Context, SourceRange(Loc, Loc))); 1746 if (auto *ML = Context.getASTMutationListener()) 1747 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 1748 } 1749 OMPThreadPrivateDecl *D = nullptr; 1750 if (!Vars.empty()) { 1751 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 1752 Vars); 1753 D->setAccess(AS_public); 1754 } 1755 return D; 1756 } 1757 1758 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, 1759 const ValueDecl *D, DSAStackTy::DSAVarData DVar, 1760 bool IsLoopIterVar = false) { 1761 if (DVar.RefExpr) { 1762 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 1763 << getOpenMPClauseName(DVar.CKind); 1764 return; 1765 } 1766 enum { 1767 PDSA_StaticMemberShared, 1768 PDSA_StaticLocalVarShared, 1769 PDSA_LoopIterVarPrivate, 1770 PDSA_LoopIterVarLinear, 1771 PDSA_LoopIterVarLastprivate, 1772 PDSA_ConstVarShared, 1773 PDSA_GlobalVarShared, 1774 PDSA_TaskVarFirstprivate, 1775 PDSA_LocalVarPrivate, 1776 PDSA_Implicit 1777 } Reason = PDSA_Implicit; 1778 bool ReportHint = false; 1779 auto ReportLoc = D->getLocation(); 1780 auto *VD = dyn_cast<VarDecl>(D); 1781 if (IsLoopIterVar) { 1782 if (DVar.CKind == OMPC_private) 1783 Reason = PDSA_LoopIterVarPrivate; 1784 else if (DVar.CKind == OMPC_lastprivate) 1785 Reason = PDSA_LoopIterVarLastprivate; 1786 else 1787 Reason = PDSA_LoopIterVarLinear; 1788 } else if (isOpenMPTaskingDirective(DVar.DKind) && 1789 DVar.CKind == OMPC_firstprivate) { 1790 Reason = PDSA_TaskVarFirstprivate; 1791 ReportLoc = DVar.ImplicitDSALoc; 1792 } else if (VD && VD->isStaticLocal()) 1793 Reason = PDSA_StaticLocalVarShared; 1794 else if (VD && VD->isStaticDataMember()) 1795 Reason = PDSA_StaticMemberShared; 1796 else if (VD && VD->isFileVarDecl()) 1797 Reason = PDSA_GlobalVarShared; 1798 else if (D->getType().isConstant(SemaRef.getASTContext())) 1799 Reason = PDSA_ConstVarShared; 1800 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 1801 ReportHint = true; 1802 Reason = PDSA_LocalVarPrivate; 1803 } 1804 if (Reason != PDSA_Implicit) { 1805 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 1806 << Reason << ReportHint 1807 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 1808 } else if (DVar.ImplicitDSALoc.isValid()) { 1809 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 1810 << getOpenMPClauseName(DVar.CKind); 1811 } 1812 } 1813 1814 namespace { 1815 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> { 1816 DSAStackTy *Stack; 1817 Sema &SemaRef; 1818 bool ErrorFound; 1819 CapturedStmt *CS; 1820 llvm::SmallVector<Expr *, 8> ImplicitFirstprivate; 1821 llvm::SmallVector<Expr *, 8> ImplicitMap; 1822 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 1823 llvm::DenseSet<ValueDecl *> ImplicitDeclarations; 1824 1825 public: 1826 void VisitDeclRefExpr(DeclRefExpr *E) { 1827 if (E->isTypeDependent() || E->isValueDependent() || 1828 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 1829 return; 1830 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1831 VD = VD->getCanonicalDecl(); 1832 // Skip internally declared variables. 1833 if (VD->hasLocalStorage() && !CS->capturesVariable(VD)) 1834 return; 1835 1836 auto DVar = Stack->getTopDSA(VD, false); 1837 // Check if the variable has explicit DSA set and stop analysis if it so. 1838 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 1839 return; 1840 1841 auto ELoc = E->getExprLoc(); 1842 auto DKind = Stack->getCurrentDirective(); 1843 // The default(none) clause requires that each variable that is referenced 1844 // in the construct, and does not have a predetermined data-sharing 1845 // attribute, must have its data-sharing attribute explicitly determined 1846 // by being listed in a data-sharing attribute clause. 1847 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 1848 isParallelOrTaskRegion(DKind) && 1849 VarsWithInheritedDSA.count(VD) == 0) { 1850 VarsWithInheritedDSA[VD] = E; 1851 return; 1852 } 1853 1854 if (isOpenMPTargetExecutionDirective(DKind) && 1855 !Stack->isLoopControlVariable(VD).first) { 1856 if (!Stack->checkMappableExprComponentListsForDecl( 1857 VD, /*CurrentRegionOnly=*/true, 1858 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 1859 StackComponents, 1860 OpenMPClauseKind) { 1861 // Variable is used if it has been marked as an array, array 1862 // section or the variable iself. 1863 return StackComponents.size() == 1 || 1864 std::all_of( 1865 std::next(StackComponents.rbegin()), 1866 StackComponents.rend(), 1867 [](const OMPClauseMappableExprCommon:: 1868 MappableComponent &MC) { 1869 return MC.getAssociatedDeclaration() == 1870 nullptr && 1871 (isa<OMPArraySectionExpr>( 1872 MC.getAssociatedExpression()) || 1873 isa<ArraySubscriptExpr>( 1874 MC.getAssociatedExpression())); 1875 }); 1876 })) { 1877 bool IsFirstprivate = false; 1878 // By default lambdas are captured as firstprivates. 1879 if (const auto *RD = 1880 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 1881 IsFirstprivate = RD->isLambda(); 1882 IsFirstprivate = 1883 IsFirstprivate || 1884 (VD->getType().getNonReferenceType()->isScalarType() && 1885 Stack->getDefaultDMA() != DMA_tofrom_scalar); 1886 if (IsFirstprivate) 1887 ImplicitFirstprivate.emplace_back(E); 1888 else 1889 ImplicitMap.emplace_back(E); 1890 return; 1891 } 1892 } 1893 1894 // OpenMP [2.9.3.6, Restrictions, p.2] 1895 // A list item that appears in a reduction clause of the innermost 1896 // enclosing worksharing or parallel construct may not be accessed in an 1897 // explicit task. 1898 DVar = Stack->hasInnermostDSA( 1899 VD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 1900 [](OpenMPDirectiveKind K) -> bool { 1901 return isOpenMPParallelDirective(K) || 1902 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 1903 }, 1904 /*FromParent=*/true); 1905 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 1906 ErrorFound = true; 1907 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1908 ReportOriginalDSA(SemaRef, Stack, VD, DVar); 1909 return; 1910 } 1911 1912 // Define implicit data-sharing attributes for task. 1913 DVar = Stack->getImplicitDSA(VD, false); 1914 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 1915 !Stack->isLoopControlVariable(VD).first) 1916 ImplicitFirstprivate.push_back(E); 1917 } 1918 } 1919 void VisitMemberExpr(MemberExpr *E) { 1920 if (E->isTypeDependent() || E->isValueDependent() || 1921 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 1922 return; 1923 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 1924 if (!FD) 1925 return; 1926 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 1927 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 1928 auto DVar = Stack->getTopDSA(FD, false); 1929 // Check if the variable has explicit DSA set and stop analysis if it 1930 // so. 1931 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 1932 return; 1933 1934 if (isOpenMPTargetExecutionDirective(DKind) && 1935 !Stack->isLoopControlVariable(FD).first && 1936 !Stack->checkMappableExprComponentListsForDecl( 1937 FD, /*CurrentRegionOnly=*/true, 1938 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 1939 StackComponents, 1940 OpenMPClauseKind) { 1941 return isa<CXXThisExpr>( 1942 cast<MemberExpr>( 1943 StackComponents.back().getAssociatedExpression()) 1944 ->getBase() 1945 ->IgnoreParens()); 1946 })) { 1947 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 1948 // A bit-field cannot appear in a map clause. 1949 // 1950 if (FD->isBitField()) { 1951 SemaRef.Diag(E->getMemberLoc(), 1952 diag::err_omp_bit_fields_forbidden_in_clause) 1953 << E->getSourceRange() << getOpenMPClauseName(OMPC_map); 1954 return; 1955 } 1956 ImplicitMap.emplace_back(E); 1957 return; 1958 } 1959 1960 auto ELoc = E->getExprLoc(); 1961 // OpenMP [2.9.3.6, Restrictions, p.2] 1962 // A list item that appears in a reduction clause of the innermost 1963 // enclosing worksharing or parallel construct may not be accessed in 1964 // an explicit task. 1965 DVar = Stack->hasInnermostDSA( 1966 FD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 1967 [](OpenMPDirectiveKind K) -> bool { 1968 return isOpenMPParallelDirective(K) || 1969 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 1970 }, 1971 /*FromParent=*/true); 1972 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 1973 ErrorFound = true; 1974 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1975 ReportOriginalDSA(SemaRef, Stack, FD, DVar); 1976 return; 1977 } 1978 1979 // Define implicit data-sharing attributes for task. 1980 DVar = Stack->getImplicitDSA(FD, false); 1981 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 1982 !Stack->isLoopControlVariable(FD).first) 1983 ImplicitFirstprivate.push_back(E); 1984 return; 1985 } 1986 if (isOpenMPTargetExecutionDirective(DKind) && !FD->isBitField()) { 1987 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 1988 CheckMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map); 1989 auto *VD = cast<ValueDecl>( 1990 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 1991 if (!Stack->checkMappableExprComponentListsForDecl( 1992 VD, /*CurrentRegionOnly=*/true, 1993 [&CurComponents]( 1994 OMPClauseMappableExprCommon::MappableExprComponentListRef 1995 StackComponents, 1996 OpenMPClauseKind) { 1997 auto CCI = CurComponents.rbegin(); 1998 auto CCE = CurComponents.rend(); 1999 for (const auto &SC : llvm::reverse(StackComponents)) { 2000 // Do both expressions have the same kind? 2001 if (CCI->getAssociatedExpression()->getStmtClass() != 2002 SC.getAssociatedExpression()->getStmtClass()) 2003 if (!(isa<OMPArraySectionExpr>( 2004 SC.getAssociatedExpression()) && 2005 isa<ArraySubscriptExpr>( 2006 CCI->getAssociatedExpression()))) 2007 return false; 2008 2009 Decl *CCD = CCI->getAssociatedDeclaration(); 2010 Decl *SCD = SC.getAssociatedDeclaration(); 2011 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 2012 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 2013 if (SCD != CCD) 2014 return false; 2015 std::advance(CCI, 1); 2016 if (CCI == CCE) 2017 break; 2018 } 2019 return true; 2020 })) { 2021 Visit(E->getBase()); 2022 } 2023 } else 2024 Visit(E->getBase()); 2025 } 2026 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2027 for (auto *C : S->clauses()) { 2028 // Skip analysis of arguments of implicitly defined firstprivate clause 2029 // for task|target directives. 2030 // Skip analysis of arguments of implicitly defined map clause for target 2031 // directives. 2032 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2033 C->isImplicit())) { 2034 for (auto *CC : C->children()) { 2035 if (CC) 2036 Visit(CC); 2037 } 2038 } 2039 } 2040 } 2041 void VisitStmt(Stmt *S) { 2042 for (auto *C : S->children()) { 2043 if (C && !isa<OMPExecutableDirective>(C)) 2044 Visit(C); 2045 } 2046 } 2047 2048 bool isErrorFound() { return ErrorFound; } 2049 ArrayRef<Expr *> getImplicitFirstprivate() const { 2050 return ImplicitFirstprivate; 2051 } 2052 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2053 llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() { 2054 return VarsWithInheritedDSA; 2055 } 2056 2057 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2058 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} 2059 }; 2060 } // namespace 2061 2062 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2063 switch (DKind) { 2064 case OMPD_parallel: 2065 case OMPD_parallel_for: 2066 case OMPD_parallel_for_simd: 2067 case OMPD_parallel_sections: 2068 case OMPD_teams: 2069 case OMPD_teams_distribute: { 2070 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 2071 QualType KmpInt32PtrTy = 2072 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2073 Sema::CapturedParamNameType Params[] = { 2074 std::make_pair(".global_tid.", KmpInt32PtrTy), 2075 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2076 std::make_pair(StringRef(), QualType()) // __context with shared vars 2077 }; 2078 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2079 Params); 2080 break; 2081 } 2082 case OMPD_target_teams: 2083 case OMPD_target_parallel: { 2084 Sema::CapturedParamNameType ParamsTarget[] = { 2085 std::make_pair(StringRef(), QualType()) // __context with shared vars 2086 }; 2087 // Start a captured region for 'target' with no implicit parameters. 2088 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2089 ParamsTarget); 2090 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 2091 QualType KmpInt32PtrTy = 2092 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2093 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2094 std::make_pair(".global_tid.", KmpInt32PtrTy), 2095 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2096 std::make_pair(StringRef(), QualType()) // __context with shared vars 2097 }; 2098 // Start a captured region for 'teams' or 'parallel'. Both regions have 2099 // the same implicit parameters. 2100 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2101 ParamsTeamsOrParallel); 2102 break; 2103 } 2104 case OMPD_simd: 2105 case OMPD_for: 2106 case OMPD_for_simd: 2107 case OMPD_sections: 2108 case OMPD_section: 2109 case OMPD_single: 2110 case OMPD_master: 2111 case OMPD_critical: 2112 case OMPD_taskgroup: 2113 case OMPD_distribute: 2114 case OMPD_ordered: 2115 case OMPD_atomic: 2116 case OMPD_target_data: 2117 case OMPD_target: 2118 case OMPD_target_parallel_for: 2119 case OMPD_target_parallel_for_simd: 2120 case OMPD_target_simd: { 2121 Sema::CapturedParamNameType Params[] = { 2122 std::make_pair(StringRef(), QualType()) // __context with shared vars 2123 }; 2124 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2125 Params); 2126 break; 2127 } 2128 case OMPD_task: { 2129 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 2130 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 2131 FunctionProtoType::ExtProtoInfo EPI; 2132 EPI.Variadic = true; 2133 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2134 Sema::CapturedParamNameType Params[] = { 2135 std::make_pair(".global_tid.", KmpInt32Ty), 2136 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), 2137 std::make_pair(".privates.", Context.VoidPtrTy.withConst()), 2138 std::make_pair(".copy_fn.", 2139 Context.getPointerType(CopyFnType).withConst()), 2140 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2141 std::make_pair(StringRef(), QualType()) // __context with shared vars 2142 }; 2143 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2144 Params); 2145 // Mark this captured region as inlined, because we don't use outlined 2146 // function directly. 2147 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2148 AlwaysInlineAttr::CreateImplicit( 2149 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 2150 break; 2151 } 2152 case OMPD_taskloop: 2153 case OMPD_taskloop_simd: { 2154 QualType KmpInt32Ty = 2155 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1); 2156 QualType KmpUInt64Ty = 2157 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 2158 QualType KmpInt64Ty = 2159 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 2160 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 2161 FunctionProtoType::ExtProtoInfo EPI; 2162 EPI.Variadic = true; 2163 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2164 Sema::CapturedParamNameType Params[] = { 2165 std::make_pair(".global_tid.", KmpInt32Ty), 2166 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), 2167 std::make_pair(".privates.", 2168 Context.VoidPtrTy.withConst().withRestrict()), 2169 std::make_pair( 2170 ".copy_fn.", 2171 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2172 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2173 std::make_pair(".lb.", KmpUInt64Ty), 2174 std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty), 2175 std::make_pair(".liter.", KmpInt32Ty), 2176 std::make_pair(".reductions.", 2177 Context.VoidPtrTy.withConst().withRestrict()), 2178 std::make_pair(StringRef(), QualType()) // __context with shared vars 2179 }; 2180 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2181 Params); 2182 // Mark this captured region as inlined, because we don't use outlined 2183 // function directly. 2184 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2185 AlwaysInlineAttr::CreateImplicit( 2186 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 2187 break; 2188 } 2189 case OMPD_distribute_parallel_for_simd: 2190 case OMPD_distribute_simd: 2191 case OMPD_distribute_parallel_for: 2192 case OMPD_teams_distribute_simd: 2193 case OMPD_teams_distribute_parallel_for_simd: 2194 case OMPD_teams_distribute_parallel_for: 2195 case OMPD_target_teams_distribute: 2196 case OMPD_target_teams_distribute_parallel_for: 2197 case OMPD_target_teams_distribute_parallel_for_simd: 2198 case OMPD_target_teams_distribute_simd: { 2199 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 2200 QualType KmpInt32PtrTy = 2201 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2202 Sema::CapturedParamNameType Params[] = { 2203 std::make_pair(".global_tid.", KmpInt32PtrTy), 2204 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2205 std::make_pair(".previous.lb.", Context.getSizeType()), 2206 std::make_pair(".previous.ub.", Context.getSizeType()), 2207 std::make_pair(StringRef(), QualType()) // __context with shared vars 2208 }; 2209 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2210 Params); 2211 break; 2212 } 2213 case OMPD_threadprivate: 2214 case OMPD_taskyield: 2215 case OMPD_barrier: 2216 case OMPD_taskwait: 2217 case OMPD_cancellation_point: 2218 case OMPD_cancel: 2219 case OMPD_flush: 2220 case OMPD_target_enter_data: 2221 case OMPD_target_exit_data: 2222 case OMPD_declare_reduction: 2223 case OMPD_declare_simd: 2224 case OMPD_declare_target: 2225 case OMPD_end_declare_target: 2226 case OMPD_target_update: 2227 llvm_unreachable("OpenMP Directive is not allowed"); 2228 case OMPD_unknown: 2229 llvm_unreachable("Unknown OpenMP directive"); 2230 } 2231 } 2232 2233 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 2234 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2235 getOpenMPCaptureRegions(CaptureRegions, DKind); 2236 return CaptureRegions.size(); 2237 } 2238 2239 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 2240 Expr *CaptureExpr, bool WithInit, 2241 bool AsExpression) { 2242 assert(CaptureExpr); 2243 ASTContext &C = S.getASTContext(); 2244 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 2245 QualType Ty = Init->getType(); 2246 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 2247 if (S.getLangOpts().CPlusPlus) 2248 Ty = C.getLValueReferenceType(Ty); 2249 else { 2250 Ty = C.getPointerType(Ty); 2251 ExprResult Res = 2252 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 2253 if (!Res.isUsable()) 2254 return nullptr; 2255 Init = Res.get(); 2256 } 2257 WithInit = true; 2258 } 2259 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 2260 CaptureExpr->getLocStart()); 2261 if (!WithInit) 2262 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange())); 2263 S.CurContext->addHiddenDecl(CED); 2264 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 2265 return CED; 2266 } 2267 2268 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2269 bool WithInit) { 2270 OMPCapturedExprDecl *CD; 2271 if (auto *VD = S.IsOpenMPCapturedDecl(D)) 2272 CD = cast<OMPCapturedExprDecl>(VD); 2273 else 2274 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 2275 /*AsExpression=*/false); 2276 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 2277 CaptureExpr->getExprLoc()); 2278 } 2279 2280 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 2281 if (!Ref) { 2282 auto *CD = 2283 buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."), 2284 CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true); 2285 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 2286 CaptureExpr->getExprLoc()); 2287 } 2288 ExprResult Res = Ref; 2289 if (!S.getLangOpts().CPlusPlus && 2290 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 2291 Ref->getType()->isPointerType()) 2292 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 2293 if (!Res.isUsable()) 2294 return ExprError(); 2295 return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get()); 2296 } 2297 2298 namespace { 2299 // OpenMP directives parsed in this section are represented as a 2300 // CapturedStatement with an associated statement. If a syntax error 2301 // is detected during the parsing of the associated statement, the 2302 // compiler must abort processing and close the CapturedStatement. 2303 // 2304 // Combined directives such as 'target parallel' have more than one 2305 // nested CapturedStatements. This RAII ensures that we unwind out 2306 // of all the nested CapturedStatements when an error is found. 2307 class CaptureRegionUnwinderRAII { 2308 private: 2309 Sema &S; 2310 bool &ErrorFound; 2311 OpenMPDirectiveKind DKind; 2312 2313 public: 2314 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 2315 OpenMPDirectiveKind DKind) 2316 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 2317 ~CaptureRegionUnwinderRAII() { 2318 if (ErrorFound) { 2319 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 2320 while (--ThisCaptureLevel >= 0) 2321 S.ActOnCapturedRegionError(); 2322 } 2323 } 2324 }; 2325 } // namespace 2326 2327 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 2328 ArrayRef<OMPClause *> Clauses) { 2329 bool ErrorFound = false; 2330 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 2331 *this, ErrorFound, DSAStack->getCurrentDirective()); 2332 if (!S.isUsable()) { 2333 ErrorFound = true; 2334 return StmtError(); 2335 } 2336 2337 OMPOrderedClause *OC = nullptr; 2338 OMPScheduleClause *SC = nullptr; 2339 SmallVector<OMPLinearClause *, 4> LCs; 2340 SmallVector<OMPClauseWithPreInit *, 8> PICs; 2341 // This is required for proper codegen. 2342 for (auto *Clause : Clauses) { 2343 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 2344 Clause->getClauseKind() == OMPC_in_reduction) { 2345 // Capture taskgroup task_reduction descriptors inside the tasking regions 2346 // with the corresponding in_reduction items. 2347 auto *IRC = cast<OMPInReductionClause>(Clause); 2348 for (auto *E : IRC->taskgroup_descriptors()) 2349 if (E) 2350 MarkDeclarationsReferencedInExpr(E); 2351 } 2352 if (isOpenMPPrivate(Clause->getClauseKind()) || 2353 Clause->getClauseKind() == OMPC_copyprivate || 2354 (getLangOpts().OpenMPUseTLS && 2355 getASTContext().getTargetInfo().isTLSSupported() && 2356 Clause->getClauseKind() == OMPC_copyin)) { 2357 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 2358 // Mark all variables in private list clauses as used in inner region. 2359 for (auto *VarRef : Clause->children()) { 2360 if (auto *E = cast_or_null<Expr>(VarRef)) { 2361 MarkDeclarationsReferencedInExpr(E); 2362 } 2363 } 2364 DSAStack->setForceVarCapturing(/*V=*/false); 2365 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 2366 if (auto *C = OMPClauseWithPreInit::get(Clause)) 2367 PICs.push_back(C); 2368 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 2369 if (auto *E = C->getPostUpdateExpr()) 2370 MarkDeclarationsReferencedInExpr(E); 2371 } 2372 } 2373 if (Clause->getClauseKind() == OMPC_schedule) 2374 SC = cast<OMPScheduleClause>(Clause); 2375 else if (Clause->getClauseKind() == OMPC_ordered) 2376 OC = cast<OMPOrderedClause>(Clause); 2377 else if (Clause->getClauseKind() == OMPC_linear) 2378 LCs.push_back(cast<OMPLinearClause>(Clause)); 2379 } 2380 // OpenMP, 2.7.1 Loop Construct, Restrictions 2381 // The nonmonotonic modifier cannot be specified if an ordered clause is 2382 // specified. 2383 if (SC && 2384 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 2385 SC->getSecondScheduleModifier() == 2386 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 2387 OC) { 2388 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 2389 ? SC->getFirstScheduleModifierLoc() 2390 : SC->getSecondScheduleModifierLoc(), 2391 diag::err_omp_schedule_nonmonotonic_ordered) 2392 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 2393 ErrorFound = true; 2394 } 2395 if (!LCs.empty() && OC && OC->getNumForLoops()) { 2396 for (auto *C : LCs) { 2397 Diag(C->getLocStart(), diag::err_omp_linear_ordered) 2398 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 2399 } 2400 ErrorFound = true; 2401 } 2402 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 2403 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 2404 OC->getNumForLoops()) { 2405 Diag(OC->getLocStart(), diag::err_omp_ordered_simd) 2406 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 2407 ErrorFound = true; 2408 } 2409 if (ErrorFound) { 2410 return StmtError(); 2411 } 2412 StmtResult SR = S; 2413 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2414 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 2415 for (auto ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 2416 // Mark all variables in private list clauses as used in inner region. 2417 // Required for proper codegen of combined directives. 2418 // TODO: add processing for other clauses. 2419 if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 2420 for (auto *C : PICs) { 2421 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 2422 // Find the particular capture region for the clause if the 2423 // directive is a combined one with multiple capture regions. 2424 // If the directive is not a combined one, the capture region 2425 // associated with the clause is OMPD_unknown and is generated 2426 // only once. 2427 if (CaptureRegion == ThisCaptureRegion || 2428 CaptureRegion == OMPD_unknown) { 2429 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 2430 for (auto *D : DS->decls()) 2431 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 2432 } 2433 } 2434 } 2435 } 2436 SR = ActOnCapturedRegionEnd(SR.get()); 2437 } 2438 return SR; 2439 } 2440 2441 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 2442 OpenMPDirectiveKind CancelRegion, 2443 SourceLocation StartLoc) { 2444 // CancelRegion is only needed for cancel and cancellation_point. 2445 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 2446 return false; 2447 2448 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 2449 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 2450 return false; 2451 2452 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 2453 << getOpenMPDirectiveName(CancelRegion); 2454 return true; 2455 } 2456 2457 static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, 2458 OpenMPDirectiveKind CurrentRegion, 2459 const DeclarationNameInfo &CurrentName, 2460 OpenMPDirectiveKind CancelRegion, 2461 SourceLocation StartLoc) { 2462 if (Stack->getCurScope()) { 2463 auto ParentRegion = Stack->getParentDirective(); 2464 auto OffendingRegion = ParentRegion; 2465 bool NestingProhibited = false; 2466 bool CloseNesting = true; 2467 bool OrphanSeen = false; 2468 enum { 2469 NoRecommend, 2470 ShouldBeInParallelRegion, 2471 ShouldBeInOrderedRegion, 2472 ShouldBeInTargetRegion, 2473 ShouldBeInTeamsRegion 2474 } Recommend = NoRecommend; 2475 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 2476 // OpenMP [2.16, Nesting of Regions] 2477 // OpenMP constructs may not be nested inside a simd region. 2478 // OpenMP [2.8.1,simd Construct, Restrictions] 2479 // An ordered construct with the simd clause is the only OpenMP 2480 // construct that can appear in the simd region. 2481 // Allowing a SIMD construct nested in another SIMD construct is an 2482 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 2483 // message. 2484 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 2485 ? diag::err_omp_prohibited_region_simd 2486 : diag::warn_omp_nesting_simd); 2487 return CurrentRegion != OMPD_simd; 2488 } 2489 if (ParentRegion == OMPD_atomic) { 2490 // OpenMP [2.16, Nesting of Regions] 2491 // OpenMP constructs may not be nested inside an atomic region. 2492 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 2493 return true; 2494 } 2495 if (CurrentRegion == OMPD_section) { 2496 // OpenMP [2.7.2, sections Construct, Restrictions] 2497 // Orphaned section directives are prohibited. That is, the section 2498 // directives must appear within the sections construct and must not be 2499 // encountered elsewhere in the sections region. 2500 if (ParentRegion != OMPD_sections && 2501 ParentRegion != OMPD_parallel_sections) { 2502 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 2503 << (ParentRegion != OMPD_unknown) 2504 << getOpenMPDirectiveName(ParentRegion); 2505 return true; 2506 } 2507 return false; 2508 } 2509 // Allow some constructs (except teams) to be orphaned (they could be 2510 // used in functions, called from OpenMP regions with the required 2511 // preconditions). 2512 if (ParentRegion == OMPD_unknown && 2513 !isOpenMPNestingTeamsDirective(CurrentRegion)) 2514 return false; 2515 if (CurrentRegion == OMPD_cancellation_point || 2516 CurrentRegion == OMPD_cancel) { 2517 // OpenMP [2.16, Nesting of Regions] 2518 // A cancellation point construct for which construct-type-clause is 2519 // taskgroup must be nested inside a task construct. A cancellation 2520 // point construct for which construct-type-clause is not taskgroup must 2521 // be closely nested inside an OpenMP construct that matches the type 2522 // specified in construct-type-clause. 2523 // A cancel construct for which construct-type-clause is taskgroup must be 2524 // nested inside a task construct. A cancel construct for which 2525 // construct-type-clause is not taskgroup must be closely nested inside an 2526 // OpenMP construct that matches the type specified in 2527 // construct-type-clause. 2528 NestingProhibited = 2529 !((CancelRegion == OMPD_parallel && 2530 (ParentRegion == OMPD_parallel || 2531 ParentRegion == OMPD_target_parallel)) || 2532 (CancelRegion == OMPD_for && 2533 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 2534 ParentRegion == OMPD_target_parallel_for)) || 2535 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 2536 (CancelRegion == OMPD_sections && 2537 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 2538 ParentRegion == OMPD_parallel_sections))); 2539 } else if (CurrentRegion == OMPD_master) { 2540 // OpenMP [2.16, Nesting of Regions] 2541 // A master region may not be closely nested inside a worksharing, 2542 // atomic, or explicit task region. 2543 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2544 isOpenMPTaskingDirective(ParentRegion); 2545 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 2546 // OpenMP [2.16, Nesting of Regions] 2547 // A critical region may not be nested (closely or otherwise) inside a 2548 // critical region with the same name. Note that this restriction is not 2549 // sufficient to prevent deadlock. 2550 SourceLocation PreviousCriticalLoc; 2551 bool DeadLock = Stack->hasDirective( 2552 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 2553 const DeclarationNameInfo &DNI, 2554 SourceLocation Loc) -> bool { 2555 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 2556 PreviousCriticalLoc = Loc; 2557 return true; 2558 } else 2559 return false; 2560 }, 2561 false /* skip top directive */); 2562 if (DeadLock) { 2563 SemaRef.Diag(StartLoc, 2564 diag::err_omp_prohibited_region_critical_same_name) 2565 << CurrentName.getName(); 2566 if (PreviousCriticalLoc.isValid()) 2567 SemaRef.Diag(PreviousCriticalLoc, 2568 diag::note_omp_previous_critical_region); 2569 return true; 2570 } 2571 } else if (CurrentRegion == OMPD_barrier) { 2572 // OpenMP [2.16, Nesting of Regions] 2573 // A barrier region may not be closely nested inside a worksharing, 2574 // explicit task, critical, ordered, atomic, or master region. 2575 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2576 isOpenMPTaskingDirective(ParentRegion) || 2577 ParentRegion == OMPD_master || 2578 ParentRegion == OMPD_critical || 2579 ParentRegion == OMPD_ordered; 2580 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 2581 !isOpenMPParallelDirective(CurrentRegion) && 2582 !isOpenMPTeamsDirective(CurrentRegion)) { 2583 // OpenMP [2.16, Nesting of Regions] 2584 // A worksharing region may not be closely nested inside a worksharing, 2585 // explicit task, critical, ordered, atomic, or master region. 2586 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2587 isOpenMPTaskingDirective(ParentRegion) || 2588 ParentRegion == OMPD_master || 2589 ParentRegion == OMPD_critical || 2590 ParentRegion == OMPD_ordered; 2591 Recommend = ShouldBeInParallelRegion; 2592 } else if (CurrentRegion == OMPD_ordered) { 2593 // OpenMP [2.16, Nesting of Regions] 2594 // An ordered region may not be closely nested inside a critical, 2595 // atomic, or explicit task region. 2596 // An ordered region must be closely nested inside a loop region (or 2597 // parallel loop region) with an ordered clause. 2598 // OpenMP [2.8.1,simd Construct, Restrictions] 2599 // An ordered construct with the simd clause is the only OpenMP construct 2600 // that can appear in the simd region. 2601 NestingProhibited = ParentRegion == OMPD_critical || 2602 isOpenMPTaskingDirective(ParentRegion) || 2603 !(isOpenMPSimdDirective(ParentRegion) || 2604 Stack->isParentOrderedRegion()); 2605 Recommend = ShouldBeInOrderedRegion; 2606 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 2607 // OpenMP [2.16, Nesting of Regions] 2608 // If specified, a teams construct must be contained within a target 2609 // construct. 2610 NestingProhibited = ParentRegion != OMPD_target; 2611 OrphanSeen = ParentRegion == OMPD_unknown; 2612 Recommend = ShouldBeInTargetRegion; 2613 Stack->setParentTeamsRegionLoc(Stack->getConstructLoc()); 2614 } 2615 if (!NestingProhibited && 2616 !isOpenMPTargetExecutionDirective(CurrentRegion) && 2617 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 2618 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 2619 // OpenMP [2.16, Nesting of Regions] 2620 // distribute, parallel, parallel sections, parallel workshare, and the 2621 // parallel loop and parallel loop SIMD constructs are the only OpenMP 2622 // constructs that can be closely nested in the teams region. 2623 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 2624 !isOpenMPDistributeDirective(CurrentRegion); 2625 Recommend = ShouldBeInParallelRegion; 2626 } 2627 if (!NestingProhibited && 2628 isOpenMPNestingDistributeDirective(CurrentRegion)) { 2629 // OpenMP 4.5 [2.17 Nesting of Regions] 2630 // The region associated with the distribute construct must be strictly 2631 // nested inside a teams region 2632 NestingProhibited = 2633 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 2634 Recommend = ShouldBeInTeamsRegion; 2635 } 2636 if (!NestingProhibited && 2637 (isOpenMPTargetExecutionDirective(CurrentRegion) || 2638 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 2639 // OpenMP 4.5 [2.17 Nesting of Regions] 2640 // If a target, target update, target data, target enter data, or 2641 // target exit data construct is encountered during execution of a 2642 // target region, the behavior is unspecified. 2643 NestingProhibited = Stack->hasDirective( 2644 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2645 SourceLocation) -> bool { 2646 if (isOpenMPTargetExecutionDirective(K)) { 2647 OffendingRegion = K; 2648 return true; 2649 } else 2650 return false; 2651 }, 2652 false /* don't skip top directive */); 2653 CloseNesting = false; 2654 } 2655 if (NestingProhibited) { 2656 if (OrphanSeen) { 2657 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 2658 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 2659 } else { 2660 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 2661 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 2662 << Recommend << getOpenMPDirectiveName(CurrentRegion); 2663 } 2664 return true; 2665 } 2666 } 2667 return false; 2668 } 2669 2670 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 2671 ArrayRef<OMPClause *> Clauses, 2672 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 2673 bool ErrorFound = false; 2674 unsigned NamedModifiersNumber = 0; 2675 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 2676 OMPD_unknown + 1); 2677 SmallVector<SourceLocation, 4> NameModifierLoc; 2678 for (const auto *C : Clauses) { 2679 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 2680 // At most one if clause without a directive-name-modifier can appear on 2681 // the directive. 2682 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 2683 if (FoundNameModifiers[CurNM]) { 2684 S.Diag(C->getLocStart(), diag::err_omp_more_one_clause) 2685 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 2686 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 2687 ErrorFound = true; 2688 } else if (CurNM != OMPD_unknown) { 2689 NameModifierLoc.push_back(IC->getNameModifierLoc()); 2690 ++NamedModifiersNumber; 2691 } 2692 FoundNameModifiers[CurNM] = IC; 2693 if (CurNM == OMPD_unknown) 2694 continue; 2695 // Check if the specified name modifier is allowed for the current 2696 // directive. 2697 // At most one if clause with the particular directive-name-modifier can 2698 // appear on the directive. 2699 bool MatchFound = false; 2700 for (auto NM : AllowedNameModifiers) { 2701 if (CurNM == NM) { 2702 MatchFound = true; 2703 break; 2704 } 2705 } 2706 if (!MatchFound) { 2707 S.Diag(IC->getNameModifierLoc(), 2708 diag::err_omp_wrong_if_directive_name_modifier) 2709 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 2710 ErrorFound = true; 2711 } 2712 } 2713 } 2714 // If any if clause on the directive includes a directive-name-modifier then 2715 // all if clauses on the directive must include a directive-name-modifier. 2716 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 2717 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 2718 S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(), 2719 diag::err_omp_no_more_if_clause); 2720 } else { 2721 std::string Values; 2722 std::string Sep(", "); 2723 unsigned AllowedCnt = 0; 2724 unsigned TotalAllowedNum = 2725 AllowedNameModifiers.size() - NamedModifiersNumber; 2726 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 2727 ++Cnt) { 2728 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 2729 if (!FoundNameModifiers[NM]) { 2730 Values += "'"; 2731 Values += getOpenMPDirectiveName(NM); 2732 Values += "'"; 2733 if (AllowedCnt + 2 == TotalAllowedNum) 2734 Values += " or "; 2735 else if (AllowedCnt + 1 != TotalAllowedNum) 2736 Values += Sep; 2737 ++AllowedCnt; 2738 } 2739 } 2740 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(), 2741 diag::err_omp_unnamed_if_clause) 2742 << (TotalAllowedNum > 1) << Values; 2743 } 2744 for (auto Loc : NameModifierLoc) { 2745 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 2746 } 2747 ErrorFound = true; 2748 } 2749 return ErrorFound; 2750 } 2751 2752 StmtResult Sema::ActOnOpenMPExecutableDirective( 2753 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 2754 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 2755 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 2756 StmtResult Res = StmtError(); 2757 // First check CancelRegion which is then used in checkNestingOfRegions. 2758 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 2759 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 2760 StartLoc)) 2761 return StmtError(); 2762 2763 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 2764 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 2765 bool ErrorFound = false; 2766 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 2767 if (AStmt && !CurContext->isDependentContext()) { 2768 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 2769 2770 // Check default data sharing attributes for referenced variables. 2771 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 2772 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 2773 Stmt *S = AStmt; 2774 while (--ThisCaptureLevel >= 0) 2775 S = cast<CapturedStmt>(S)->getCapturedStmt(); 2776 DSAChecker.Visit(S); 2777 if (DSAChecker.isErrorFound()) 2778 return StmtError(); 2779 // Generate list of implicitly defined firstprivate variables. 2780 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 2781 2782 SmallVector<Expr *, 4> ImplicitFirstprivates( 2783 DSAChecker.getImplicitFirstprivate().begin(), 2784 DSAChecker.getImplicitFirstprivate().end()); 2785 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 2786 DSAChecker.getImplicitMap().end()); 2787 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 2788 for (auto *C : Clauses) { 2789 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 2790 for (auto *E : IRC->taskgroup_descriptors()) 2791 if (E) 2792 ImplicitFirstprivates.emplace_back(E); 2793 } 2794 } 2795 if (!ImplicitFirstprivates.empty()) { 2796 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 2797 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 2798 SourceLocation())) { 2799 ClausesWithImplicit.push_back(Implicit); 2800 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 2801 ImplicitFirstprivates.size(); 2802 } else 2803 ErrorFound = true; 2804 } 2805 if (!ImplicitMaps.empty()) { 2806 if (OMPClause *Implicit = ActOnOpenMPMapClause( 2807 OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, 2808 SourceLocation(), SourceLocation(), ImplicitMaps, 2809 SourceLocation(), SourceLocation(), SourceLocation())) { 2810 ClausesWithImplicit.emplace_back(Implicit); 2811 ErrorFound |= 2812 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 2813 } else 2814 ErrorFound = true; 2815 } 2816 } 2817 2818 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 2819 switch (Kind) { 2820 case OMPD_parallel: 2821 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 2822 EndLoc); 2823 AllowedNameModifiers.push_back(OMPD_parallel); 2824 break; 2825 case OMPD_simd: 2826 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 2827 VarsWithInheritedDSA); 2828 break; 2829 case OMPD_for: 2830 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 2831 VarsWithInheritedDSA); 2832 break; 2833 case OMPD_for_simd: 2834 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 2835 EndLoc, VarsWithInheritedDSA); 2836 break; 2837 case OMPD_sections: 2838 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 2839 EndLoc); 2840 break; 2841 case OMPD_section: 2842 assert(ClausesWithImplicit.empty() && 2843 "No clauses are allowed for 'omp section' directive"); 2844 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 2845 break; 2846 case OMPD_single: 2847 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 2848 EndLoc); 2849 break; 2850 case OMPD_master: 2851 assert(ClausesWithImplicit.empty() && 2852 "No clauses are allowed for 'omp master' directive"); 2853 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 2854 break; 2855 case OMPD_critical: 2856 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 2857 StartLoc, EndLoc); 2858 break; 2859 case OMPD_parallel_for: 2860 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 2861 EndLoc, VarsWithInheritedDSA); 2862 AllowedNameModifiers.push_back(OMPD_parallel); 2863 break; 2864 case OMPD_parallel_for_simd: 2865 Res = ActOnOpenMPParallelForSimdDirective( 2866 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2867 AllowedNameModifiers.push_back(OMPD_parallel); 2868 break; 2869 case OMPD_parallel_sections: 2870 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 2871 StartLoc, EndLoc); 2872 AllowedNameModifiers.push_back(OMPD_parallel); 2873 break; 2874 case OMPD_task: 2875 Res = 2876 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 2877 AllowedNameModifiers.push_back(OMPD_task); 2878 break; 2879 case OMPD_taskyield: 2880 assert(ClausesWithImplicit.empty() && 2881 "No clauses are allowed for 'omp taskyield' directive"); 2882 assert(AStmt == nullptr && 2883 "No associated statement allowed for 'omp taskyield' directive"); 2884 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 2885 break; 2886 case OMPD_barrier: 2887 assert(ClausesWithImplicit.empty() && 2888 "No clauses are allowed for 'omp barrier' directive"); 2889 assert(AStmt == nullptr && 2890 "No associated statement allowed for 'omp barrier' directive"); 2891 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 2892 break; 2893 case OMPD_taskwait: 2894 assert(ClausesWithImplicit.empty() && 2895 "No clauses are allowed for 'omp taskwait' directive"); 2896 assert(AStmt == nullptr && 2897 "No associated statement allowed for 'omp taskwait' directive"); 2898 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 2899 break; 2900 case OMPD_taskgroup: 2901 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 2902 EndLoc); 2903 break; 2904 case OMPD_flush: 2905 assert(AStmt == nullptr && 2906 "No associated statement allowed for 'omp flush' directive"); 2907 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 2908 break; 2909 case OMPD_ordered: 2910 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 2911 EndLoc); 2912 break; 2913 case OMPD_atomic: 2914 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 2915 EndLoc); 2916 break; 2917 case OMPD_teams: 2918 Res = 2919 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 2920 break; 2921 case OMPD_target: 2922 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 2923 EndLoc); 2924 AllowedNameModifiers.push_back(OMPD_target); 2925 break; 2926 case OMPD_target_parallel: 2927 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 2928 StartLoc, EndLoc); 2929 AllowedNameModifiers.push_back(OMPD_target); 2930 AllowedNameModifiers.push_back(OMPD_parallel); 2931 break; 2932 case OMPD_target_parallel_for: 2933 Res = ActOnOpenMPTargetParallelForDirective( 2934 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2935 AllowedNameModifiers.push_back(OMPD_target); 2936 AllowedNameModifiers.push_back(OMPD_parallel); 2937 break; 2938 case OMPD_cancellation_point: 2939 assert(ClausesWithImplicit.empty() && 2940 "No clauses are allowed for 'omp cancellation point' directive"); 2941 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 2942 "cancellation point' directive"); 2943 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 2944 break; 2945 case OMPD_cancel: 2946 assert(AStmt == nullptr && 2947 "No associated statement allowed for 'omp cancel' directive"); 2948 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 2949 CancelRegion); 2950 AllowedNameModifiers.push_back(OMPD_cancel); 2951 break; 2952 case OMPD_target_data: 2953 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 2954 EndLoc); 2955 AllowedNameModifiers.push_back(OMPD_target_data); 2956 break; 2957 case OMPD_target_enter_data: 2958 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 2959 EndLoc); 2960 AllowedNameModifiers.push_back(OMPD_target_enter_data); 2961 break; 2962 case OMPD_target_exit_data: 2963 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 2964 EndLoc); 2965 AllowedNameModifiers.push_back(OMPD_target_exit_data); 2966 break; 2967 case OMPD_taskloop: 2968 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 2969 EndLoc, VarsWithInheritedDSA); 2970 AllowedNameModifiers.push_back(OMPD_taskloop); 2971 break; 2972 case OMPD_taskloop_simd: 2973 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 2974 EndLoc, VarsWithInheritedDSA); 2975 AllowedNameModifiers.push_back(OMPD_taskloop); 2976 break; 2977 case OMPD_distribute: 2978 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 2979 EndLoc, VarsWithInheritedDSA); 2980 break; 2981 case OMPD_target_update: 2982 assert(!AStmt && "Statement is not allowed for target update"); 2983 Res = 2984 ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, EndLoc); 2985 AllowedNameModifiers.push_back(OMPD_target_update); 2986 break; 2987 case OMPD_distribute_parallel_for: 2988 Res = ActOnOpenMPDistributeParallelForDirective( 2989 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2990 AllowedNameModifiers.push_back(OMPD_parallel); 2991 break; 2992 case OMPD_distribute_parallel_for_simd: 2993 Res = ActOnOpenMPDistributeParallelForSimdDirective( 2994 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2995 AllowedNameModifiers.push_back(OMPD_parallel); 2996 break; 2997 case OMPD_distribute_simd: 2998 Res = ActOnOpenMPDistributeSimdDirective( 2999 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3000 break; 3001 case OMPD_target_parallel_for_simd: 3002 Res = ActOnOpenMPTargetParallelForSimdDirective( 3003 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3004 AllowedNameModifiers.push_back(OMPD_target); 3005 AllowedNameModifiers.push_back(OMPD_parallel); 3006 break; 3007 case OMPD_target_simd: 3008 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3009 EndLoc, VarsWithInheritedDSA); 3010 AllowedNameModifiers.push_back(OMPD_target); 3011 break; 3012 case OMPD_teams_distribute: 3013 Res = ActOnOpenMPTeamsDistributeDirective( 3014 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3015 break; 3016 case OMPD_teams_distribute_simd: 3017 Res = ActOnOpenMPTeamsDistributeSimdDirective( 3018 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3019 break; 3020 case OMPD_teams_distribute_parallel_for_simd: 3021 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 3022 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3023 AllowedNameModifiers.push_back(OMPD_parallel); 3024 break; 3025 case OMPD_teams_distribute_parallel_for: 3026 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 3027 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3028 AllowedNameModifiers.push_back(OMPD_parallel); 3029 break; 3030 case OMPD_target_teams: 3031 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 3032 EndLoc); 3033 AllowedNameModifiers.push_back(OMPD_target); 3034 break; 3035 case OMPD_target_teams_distribute: 3036 Res = ActOnOpenMPTargetTeamsDistributeDirective( 3037 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3038 AllowedNameModifiers.push_back(OMPD_target); 3039 break; 3040 case OMPD_target_teams_distribute_parallel_for: 3041 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 3042 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3043 AllowedNameModifiers.push_back(OMPD_target); 3044 AllowedNameModifiers.push_back(OMPD_parallel); 3045 break; 3046 case OMPD_target_teams_distribute_parallel_for_simd: 3047 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 3048 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3049 AllowedNameModifiers.push_back(OMPD_target); 3050 AllowedNameModifiers.push_back(OMPD_parallel); 3051 break; 3052 case OMPD_target_teams_distribute_simd: 3053 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 3054 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3055 AllowedNameModifiers.push_back(OMPD_target); 3056 break; 3057 case OMPD_declare_target: 3058 case OMPD_end_declare_target: 3059 case OMPD_threadprivate: 3060 case OMPD_declare_reduction: 3061 case OMPD_declare_simd: 3062 llvm_unreachable("OpenMP Directive is not allowed"); 3063 case OMPD_unknown: 3064 llvm_unreachable("Unknown OpenMP directive"); 3065 } 3066 3067 for (auto P : VarsWithInheritedDSA) { 3068 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 3069 << P.first << P.second->getSourceRange(); 3070 } 3071 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 3072 3073 if (!AllowedNameModifiers.empty()) 3074 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 3075 ErrorFound; 3076 3077 if (ErrorFound) 3078 return StmtError(); 3079 return Res; 3080 } 3081 3082 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 3083 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 3084 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 3085 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 3086 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 3087 assert(Aligneds.size() == Alignments.size()); 3088 assert(Linears.size() == LinModifiers.size()); 3089 assert(Linears.size() == Steps.size()); 3090 if (!DG || DG.get().isNull()) 3091 return DeclGroupPtrTy(); 3092 3093 if (!DG.get().isSingleDecl()) { 3094 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 3095 return DG; 3096 } 3097 auto *ADecl = DG.get().getSingleDecl(); 3098 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 3099 ADecl = FTD->getTemplatedDecl(); 3100 3101 auto *FD = dyn_cast<FunctionDecl>(ADecl); 3102 if (!FD) { 3103 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 3104 return DeclGroupPtrTy(); 3105 } 3106 3107 // OpenMP [2.8.2, declare simd construct, Description] 3108 // The parameter of the simdlen clause must be a constant positive integer 3109 // expression. 3110 ExprResult SL; 3111 if (Simdlen) 3112 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 3113 // OpenMP [2.8.2, declare simd construct, Description] 3114 // The special this pointer can be used as if was one of the arguments to the 3115 // function in any of the linear, aligned, or uniform clauses. 3116 // The uniform clause declares one or more arguments to have an invariant 3117 // value for all concurrent invocations of the function in the execution of a 3118 // single SIMD loop. 3119 llvm::DenseMap<Decl *, Expr *> UniformedArgs; 3120 Expr *UniformedLinearThis = nullptr; 3121 for (auto *E : Uniforms) { 3122 E = E->IgnoreParenImpCasts(); 3123 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3124 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 3125 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3126 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3127 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 3128 UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E)); 3129 continue; 3130 } 3131 if (isa<CXXThisExpr>(E)) { 3132 UniformedLinearThis = E; 3133 continue; 3134 } 3135 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3136 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3137 } 3138 // OpenMP [2.8.2, declare simd construct, Description] 3139 // The aligned clause declares that the object to which each list item points 3140 // is aligned to the number of bytes expressed in the optional parameter of 3141 // the aligned clause. 3142 // The special this pointer can be used as if was one of the arguments to the 3143 // function in any of the linear, aligned, or uniform clauses. 3144 // The type of list items appearing in the aligned clause must be array, 3145 // pointer, reference to array, or reference to pointer. 3146 llvm::DenseMap<Decl *, Expr *> AlignedArgs; 3147 Expr *AlignedThis = nullptr; 3148 for (auto *E : Aligneds) { 3149 E = E->IgnoreParenImpCasts(); 3150 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3151 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3152 auto *CanonPVD = PVD->getCanonicalDecl(); 3153 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3154 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3155 ->getCanonicalDecl() == CanonPVD) { 3156 // OpenMP [2.8.1, simd construct, Restrictions] 3157 // A list-item cannot appear in more than one aligned clause. 3158 if (AlignedArgs.count(CanonPVD) > 0) { 3159 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3160 << 1 << E->getSourceRange(); 3161 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 3162 diag::note_omp_explicit_dsa) 3163 << getOpenMPClauseName(OMPC_aligned); 3164 continue; 3165 } 3166 AlignedArgs[CanonPVD] = E; 3167 QualType QTy = PVD->getType() 3168 .getNonReferenceType() 3169 .getUnqualifiedType() 3170 .getCanonicalType(); 3171 const Type *Ty = QTy.getTypePtrOrNull(); 3172 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 3173 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 3174 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 3175 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 3176 } 3177 continue; 3178 } 3179 } 3180 if (isa<CXXThisExpr>(E)) { 3181 if (AlignedThis) { 3182 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3183 << 2 << E->getSourceRange(); 3184 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 3185 << getOpenMPClauseName(OMPC_aligned); 3186 } 3187 AlignedThis = E; 3188 continue; 3189 } 3190 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3191 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3192 } 3193 // The optional parameter of the aligned clause, alignment, must be a constant 3194 // positive integer expression. If no optional parameter is specified, 3195 // implementation-defined default alignments for SIMD instructions on the 3196 // target platforms are assumed. 3197 SmallVector<Expr *, 4> NewAligns; 3198 for (auto *E : Alignments) { 3199 ExprResult Align; 3200 if (E) 3201 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 3202 NewAligns.push_back(Align.get()); 3203 } 3204 // OpenMP [2.8.2, declare simd construct, Description] 3205 // The linear clause declares one or more list items to be private to a SIMD 3206 // lane and to have a linear relationship with respect to the iteration space 3207 // of a loop. 3208 // The special this pointer can be used as if was one of the arguments to the 3209 // function in any of the linear, aligned, or uniform clauses. 3210 // When a linear-step expression is specified in a linear clause it must be 3211 // either a constant integer expression or an integer-typed parameter that is 3212 // specified in a uniform clause on the directive. 3213 llvm::DenseMap<Decl *, Expr *> LinearArgs; 3214 const bool IsUniformedThis = UniformedLinearThis != nullptr; 3215 auto MI = LinModifiers.begin(); 3216 for (auto *E : Linears) { 3217 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 3218 ++MI; 3219 E = E->IgnoreParenImpCasts(); 3220 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3221 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3222 auto *CanonPVD = PVD->getCanonicalDecl(); 3223 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3224 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3225 ->getCanonicalDecl() == CanonPVD) { 3226 // OpenMP [2.15.3.7, linear Clause, Restrictions] 3227 // A list-item cannot appear in more than one linear clause. 3228 if (LinearArgs.count(CanonPVD) > 0) { 3229 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3230 << getOpenMPClauseName(OMPC_linear) 3231 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 3232 Diag(LinearArgs[CanonPVD]->getExprLoc(), 3233 diag::note_omp_explicit_dsa) 3234 << getOpenMPClauseName(OMPC_linear); 3235 continue; 3236 } 3237 // Each argument can appear in at most one uniform or linear clause. 3238 if (UniformedArgs.count(CanonPVD) > 0) { 3239 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3240 << getOpenMPClauseName(OMPC_linear) 3241 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 3242 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 3243 diag::note_omp_explicit_dsa) 3244 << getOpenMPClauseName(OMPC_uniform); 3245 continue; 3246 } 3247 LinearArgs[CanonPVD] = E; 3248 if (E->isValueDependent() || E->isTypeDependent() || 3249 E->isInstantiationDependent() || 3250 E->containsUnexpandedParameterPack()) 3251 continue; 3252 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 3253 PVD->getOriginalType()); 3254 continue; 3255 } 3256 } 3257 if (isa<CXXThisExpr>(E)) { 3258 if (UniformedLinearThis) { 3259 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3260 << getOpenMPClauseName(OMPC_linear) 3261 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 3262 << E->getSourceRange(); 3263 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 3264 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 3265 : OMPC_linear); 3266 continue; 3267 } 3268 UniformedLinearThis = E; 3269 if (E->isValueDependent() || E->isTypeDependent() || 3270 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 3271 continue; 3272 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 3273 E->getType()); 3274 continue; 3275 } 3276 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3277 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3278 } 3279 Expr *Step = nullptr; 3280 Expr *NewStep = nullptr; 3281 SmallVector<Expr *, 4> NewSteps; 3282 for (auto *E : Steps) { 3283 // Skip the same step expression, it was checked already. 3284 if (Step == E || !E) { 3285 NewSteps.push_back(E ? NewStep : nullptr); 3286 continue; 3287 } 3288 Step = E; 3289 if (auto *DRE = dyn_cast<DeclRefExpr>(Step)) 3290 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3291 auto *CanonPVD = PVD->getCanonicalDecl(); 3292 if (UniformedArgs.count(CanonPVD) == 0) { 3293 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 3294 << Step->getSourceRange(); 3295 } else if (E->isValueDependent() || E->isTypeDependent() || 3296 E->isInstantiationDependent() || 3297 E->containsUnexpandedParameterPack() || 3298 CanonPVD->getType()->hasIntegerRepresentation()) 3299 NewSteps.push_back(Step); 3300 else { 3301 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 3302 << Step->getSourceRange(); 3303 } 3304 continue; 3305 } 3306 NewStep = Step; 3307 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 3308 !Step->isInstantiationDependent() && 3309 !Step->containsUnexpandedParameterPack()) { 3310 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 3311 .get(); 3312 if (NewStep) 3313 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 3314 } 3315 NewSteps.push_back(NewStep); 3316 } 3317 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 3318 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 3319 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 3320 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 3321 const_cast<Expr **>(Linears.data()), Linears.size(), 3322 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 3323 NewSteps.data(), NewSteps.size(), SR); 3324 ADecl->addAttr(NewAttr); 3325 return ConvertDeclToDeclGroup(ADecl); 3326 } 3327 3328 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 3329 Stmt *AStmt, 3330 SourceLocation StartLoc, 3331 SourceLocation EndLoc) { 3332 if (!AStmt) 3333 return StmtError(); 3334 3335 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 3336 // 1.2.2 OpenMP Language Terminology 3337 // Structured block - An executable statement with a single entry at the 3338 // top and a single exit at the bottom. 3339 // The point of exit cannot be a branch out of the structured block. 3340 // longjmp() and throw() must not violate the entry/exit criteria. 3341 CS->getCapturedDecl()->setNothrow(); 3342 3343 getCurFunction()->setHasBranchProtectedScope(); 3344 3345 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 3346 DSAStack->isCancelRegion()); 3347 } 3348 3349 namespace { 3350 /// \brief Helper class for checking canonical form of the OpenMP loops and 3351 /// extracting iteration space of each loop in the loop nest, that will be used 3352 /// for IR generation. 3353 class OpenMPIterationSpaceChecker { 3354 /// \brief Reference to Sema. 3355 Sema &SemaRef; 3356 /// \brief A location for diagnostics (when there is no some better location). 3357 SourceLocation DefaultLoc; 3358 /// \brief A location for diagnostics (when increment is not compatible). 3359 SourceLocation ConditionLoc; 3360 /// \brief A source location for referring to loop init later. 3361 SourceRange InitSrcRange; 3362 /// \brief A source location for referring to condition later. 3363 SourceRange ConditionSrcRange; 3364 /// \brief A source location for referring to increment later. 3365 SourceRange IncrementSrcRange; 3366 /// \brief Loop variable. 3367 ValueDecl *LCDecl = nullptr; 3368 /// \brief Reference to loop variable. 3369 Expr *LCRef = nullptr; 3370 /// \brief Lower bound (initializer for the var). 3371 Expr *LB = nullptr; 3372 /// \brief Upper bound. 3373 Expr *UB = nullptr; 3374 /// \brief Loop step (increment). 3375 Expr *Step = nullptr; 3376 /// \brief This flag is true when condition is one of: 3377 /// Var < UB 3378 /// Var <= UB 3379 /// UB > Var 3380 /// UB >= Var 3381 bool TestIsLessOp = false; 3382 /// \brief This flag is true when condition is strict ( < or > ). 3383 bool TestIsStrictOp = false; 3384 /// \brief This flag is true when step is subtracted on each iteration. 3385 bool SubtractStep = false; 3386 3387 public: 3388 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 3389 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 3390 /// \brief Check init-expr for canonical loop form and save loop counter 3391 /// variable - #Var and its initialization value - #LB. 3392 bool CheckInit(Stmt *S, bool EmitDiags = true); 3393 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags 3394 /// for less/greater and for strict/non-strict comparison. 3395 bool CheckCond(Expr *S); 3396 /// \brief Check incr-expr for canonical loop form and return true if it 3397 /// does not conform, otherwise save loop step (#Step). 3398 bool CheckInc(Expr *S); 3399 /// \brief Return the loop counter variable. 3400 ValueDecl *GetLoopDecl() const { return LCDecl; } 3401 /// \brief Return the reference expression to loop counter variable. 3402 Expr *GetLoopDeclRefExpr() const { return LCRef; } 3403 /// \brief Source range of the loop init. 3404 SourceRange GetInitSrcRange() const { return InitSrcRange; } 3405 /// \brief Source range of the loop condition. 3406 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; } 3407 /// \brief Source range of the loop increment. 3408 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; } 3409 /// \brief True if the step should be subtracted. 3410 bool ShouldSubtractStep() const { return SubtractStep; } 3411 /// \brief Build the expression to calculate the number of iterations. 3412 Expr * 3413 BuildNumIterations(Scope *S, const bool LimitedType, 3414 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3415 /// \brief Build the precondition expression for the loops. 3416 Expr *BuildPreCond(Scope *S, Expr *Cond, 3417 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3418 /// \brief Build reference expression to the counter be used for codegen. 3419 DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures, 3420 DSAStackTy &DSA) const; 3421 /// \brief Build reference expression to the private counter be used for 3422 /// codegen. 3423 Expr *BuildPrivateCounterVar() const; 3424 /// \brief Build initialization of the counter be used for codegen. 3425 Expr *BuildCounterInit() const; 3426 /// \brief Build step of the counter be used for codegen. 3427 Expr *BuildCounterStep() const; 3428 /// \brief Return true if any expression is dependent. 3429 bool Dependent() const; 3430 3431 private: 3432 /// \brief Check the right-hand side of an assignment in the increment 3433 /// expression. 3434 bool CheckIncRHS(Expr *RHS); 3435 /// \brief Helper to set loop counter variable and its initializer. 3436 bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); 3437 /// \brief Helper to set upper bound. 3438 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR, 3439 SourceLocation SL); 3440 /// \brief Helper to set loop increment. 3441 bool SetStep(Expr *NewStep, bool Subtract); 3442 }; 3443 3444 bool OpenMPIterationSpaceChecker::Dependent() const { 3445 if (!LCDecl) { 3446 assert(!LB && !UB && !Step); 3447 return false; 3448 } 3449 return LCDecl->getType()->isDependentType() || 3450 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 3451 (Step && Step->isValueDependent()); 3452 } 3453 3454 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl, 3455 Expr *NewLCRefExpr, 3456 Expr *NewLB) { 3457 // State consistency checking to ensure correct usage. 3458 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 3459 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3460 if (!NewLCDecl || !NewLB) 3461 return true; 3462 LCDecl = getCanonicalDecl(NewLCDecl); 3463 LCRef = NewLCRefExpr; 3464 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 3465 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3466 if ((Ctor->isCopyOrMoveConstructor() || 3467 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3468 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3469 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 3470 LB = NewLB; 3471 return false; 3472 } 3473 3474 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp, 3475 SourceRange SR, SourceLocation SL) { 3476 // State consistency checking to ensure correct usage. 3477 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 3478 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3479 if (!NewUB) 3480 return true; 3481 UB = NewUB; 3482 TestIsLessOp = LessOp; 3483 TestIsStrictOp = StrictOp; 3484 ConditionSrcRange = SR; 3485 ConditionLoc = SL; 3486 return false; 3487 } 3488 3489 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) { 3490 // State consistency checking to ensure correct usage. 3491 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 3492 if (!NewStep) 3493 return true; 3494 if (!NewStep->isValueDependent()) { 3495 // Check that the step is integer expression. 3496 SourceLocation StepLoc = NewStep->getLocStart(); 3497 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 3498 StepLoc, getExprAsWritten(NewStep)); 3499 if (Val.isInvalid()) 3500 return true; 3501 NewStep = Val.get(); 3502 3503 // OpenMP [2.6, Canonical Loop Form, Restrictions] 3504 // If test-expr is of form var relational-op b and relational-op is < or 3505 // <= then incr-expr must cause var to increase on each iteration of the 3506 // loop. If test-expr is of form var relational-op b and relational-op is 3507 // > or >= then incr-expr must cause var to decrease on each iteration of 3508 // the loop. 3509 // If test-expr is of form b relational-op var and relational-op is < or 3510 // <= then incr-expr must cause var to decrease on each iteration of the 3511 // loop. If test-expr is of form b relational-op var and relational-op is 3512 // > or >= then incr-expr must cause var to increase on each iteration of 3513 // the loop. 3514 llvm::APSInt Result; 3515 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 3516 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 3517 bool IsConstNeg = 3518 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 3519 bool IsConstPos = 3520 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 3521 bool IsConstZero = IsConstant && !Result.getBoolValue(); 3522 if (UB && (IsConstZero || 3523 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 3524 : (IsConstPos || (IsUnsigned && !Subtract))))) { 3525 SemaRef.Diag(NewStep->getExprLoc(), 3526 diag::err_omp_loop_incr_not_compatible) 3527 << LCDecl << TestIsLessOp << NewStep->getSourceRange(); 3528 SemaRef.Diag(ConditionLoc, 3529 diag::note_omp_loop_cond_requres_compatible_incr) 3530 << TestIsLessOp << ConditionSrcRange; 3531 return true; 3532 } 3533 if (TestIsLessOp == Subtract) { 3534 NewStep = 3535 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 3536 .get(); 3537 Subtract = !Subtract; 3538 } 3539 } 3540 3541 Step = NewStep; 3542 SubtractStep = Subtract; 3543 return false; 3544 } 3545 3546 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { 3547 // Check init-expr for canonical loop form and save loop counter 3548 // variable - #Var and its initialization value - #LB. 3549 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 3550 // var = lb 3551 // integer-type var = lb 3552 // random-access-iterator-type var = lb 3553 // pointer-type var = lb 3554 // 3555 if (!S) { 3556 if (EmitDiags) { 3557 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 3558 } 3559 return true; 3560 } 3561 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 3562 if (!ExprTemp->cleanupsHaveSideEffects()) 3563 S = ExprTemp->getSubExpr(); 3564 3565 InitSrcRange = S->getSourceRange(); 3566 if (Expr *E = dyn_cast<Expr>(S)) 3567 S = E->IgnoreParens(); 3568 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 3569 if (BO->getOpcode() == BO_Assign) { 3570 auto *LHS = BO->getLHS()->IgnoreParens(); 3571 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 3572 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3573 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3574 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3575 return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); 3576 } 3577 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3578 if (ME->isArrow() && 3579 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3580 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3581 } 3582 } 3583 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 3584 if (DS->isSingleDecl()) { 3585 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 3586 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 3587 // Accept non-canonical init form here but emit ext. warning. 3588 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 3589 SemaRef.Diag(S->getLocStart(), 3590 diag::ext_omp_loop_not_canonical_init) 3591 << S->getSourceRange(); 3592 return SetLCDeclAndLB(Var, nullptr, Var->getInit()); 3593 } 3594 } 3595 } 3596 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3597 if (CE->getOperator() == OO_Equal) { 3598 auto *LHS = CE->getArg(0); 3599 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 3600 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3601 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3602 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3603 return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); 3604 } 3605 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3606 if (ME->isArrow() && 3607 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3608 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3609 } 3610 } 3611 } 3612 3613 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3614 return false; 3615 if (EmitDiags) { 3616 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init) 3617 << S->getSourceRange(); 3618 } 3619 return true; 3620 } 3621 3622 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the 3623 /// variable (which may be the loop variable) if possible. 3624 static const ValueDecl *GetInitLCDecl(Expr *E) { 3625 if (!E) 3626 return nullptr; 3627 E = getExprAsWritten(E); 3628 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 3629 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3630 if ((Ctor->isCopyOrMoveConstructor() || 3631 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3632 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3633 E = CE->getArg(0)->IgnoreParenImpCasts(); 3634 if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 3635 if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 3636 return getCanonicalDecl(VD); 3637 } 3638 if (auto *ME = dyn_cast_or_null<MemberExpr>(E)) 3639 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3640 return getCanonicalDecl(ME->getMemberDecl()); 3641 return nullptr; 3642 } 3643 3644 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { 3645 // Check test-expr for canonical form, save upper-bound UB, flags for 3646 // less/greater and for strict/non-strict comparison. 3647 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3648 // var relational-op b 3649 // b relational-op var 3650 // 3651 if (!S) { 3652 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 3653 return true; 3654 } 3655 S = getExprAsWritten(S); 3656 SourceLocation CondLoc = S->getLocStart(); 3657 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 3658 if (BO->isRelationalOp()) { 3659 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3660 return SetUB(BO->getRHS(), 3661 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 3662 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3663 BO->getSourceRange(), BO->getOperatorLoc()); 3664 if (GetInitLCDecl(BO->getRHS()) == LCDecl) 3665 return SetUB(BO->getLHS(), 3666 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 3667 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3668 BO->getSourceRange(), BO->getOperatorLoc()); 3669 } 3670 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3671 if (CE->getNumArgs() == 2) { 3672 auto Op = CE->getOperator(); 3673 switch (Op) { 3674 case OO_Greater: 3675 case OO_GreaterEqual: 3676 case OO_Less: 3677 case OO_LessEqual: 3678 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3679 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 3680 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3681 CE->getOperatorLoc()); 3682 if (GetInitLCDecl(CE->getArg(1)) == LCDecl) 3683 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 3684 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3685 CE->getOperatorLoc()); 3686 break; 3687 default: 3688 break; 3689 } 3690 } 3691 } 3692 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3693 return false; 3694 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 3695 << S->getSourceRange() << LCDecl; 3696 return true; 3697 } 3698 3699 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) { 3700 // RHS of canonical loop form increment can be: 3701 // var + incr 3702 // incr + var 3703 // var - incr 3704 // 3705 RHS = RHS->IgnoreParenImpCasts(); 3706 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 3707 if (BO->isAdditiveOp()) { 3708 bool IsAdd = BO->getOpcode() == BO_Add; 3709 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3710 return SetStep(BO->getRHS(), !IsAdd); 3711 if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl) 3712 return SetStep(BO->getLHS(), false); 3713 } 3714 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 3715 bool IsAdd = CE->getOperator() == OO_Plus; 3716 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 3717 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3718 return SetStep(CE->getArg(1), !IsAdd); 3719 if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl) 3720 return SetStep(CE->getArg(0), false); 3721 } 3722 } 3723 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3724 return false; 3725 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr) 3726 << RHS->getSourceRange() << LCDecl; 3727 return true; 3728 } 3729 3730 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { 3731 // Check incr-expr for canonical loop form and return true if it 3732 // does not conform. 3733 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3734 // ++var 3735 // var++ 3736 // --var 3737 // var-- 3738 // var += incr 3739 // var -= incr 3740 // var = var + incr 3741 // var = incr + var 3742 // var = var - incr 3743 // 3744 if (!S) { 3745 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 3746 return true; 3747 } 3748 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 3749 if (!ExprTemp->cleanupsHaveSideEffects()) 3750 S = ExprTemp->getSubExpr(); 3751 3752 IncrementSrcRange = S->getSourceRange(); 3753 S = S->IgnoreParens(); 3754 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 3755 if (UO->isIncrementDecrementOp() && 3756 GetInitLCDecl(UO->getSubExpr()) == LCDecl) 3757 return SetStep(SemaRef 3758 .ActOnIntegerConstant(UO->getLocStart(), 3759 (UO->isDecrementOp() ? -1 : 1)) 3760 .get(), 3761 false); 3762 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 3763 switch (BO->getOpcode()) { 3764 case BO_AddAssign: 3765 case BO_SubAssign: 3766 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3767 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 3768 break; 3769 case BO_Assign: 3770 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3771 return CheckIncRHS(BO->getRHS()); 3772 break; 3773 default: 3774 break; 3775 } 3776 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3777 switch (CE->getOperator()) { 3778 case OO_PlusPlus: 3779 case OO_MinusMinus: 3780 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3781 return SetStep(SemaRef 3782 .ActOnIntegerConstant( 3783 CE->getLocStart(), 3784 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 3785 .get(), 3786 false); 3787 break; 3788 case OO_PlusEqual: 3789 case OO_MinusEqual: 3790 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3791 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 3792 break; 3793 case OO_Equal: 3794 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3795 return CheckIncRHS(CE->getArg(1)); 3796 break; 3797 default: 3798 break; 3799 } 3800 } 3801 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3802 return false; 3803 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr) 3804 << S->getSourceRange() << LCDecl; 3805 return true; 3806 } 3807 3808 static ExprResult 3809 tryBuildCapture(Sema &SemaRef, Expr *Capture, 3810 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 3811 if (SemaRef.CurContext->isDependentContext()) 3812 return ExprResult(Capture); 3813 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 3814 return SemaRef.PerformImplicitConversion( 3815 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 3816 /*AllowExplicit=*/true); 3817 auto I = Captures.find(Capture); 3818 if (I != Captures.end()) 3819 return buildCapture(SemaRef, Capture, I->second); 3820 DeclRefExpr *Ref = nullptr; 3821 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 3822 Captures[Capture] = Ref; 3823 return Res; 3824 } 3825 3826 /// \brief Build the expression to calculate the number of iterations. 3827 Expr *OpenMPIterationSpaceChecker::BuildNumIterations( 3828 Scope *S, const bool LimitedType, 3829 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 3830 ExprResult Diff; 3831 auto VarType = LCDecl->getType().getNonReferenceType(); 3832 if (VarType->isIntegerType() || VarType->isPointerType() || 3833 SemaRef.getLangOpts().CPlusPlus) { 3834 // Upper - Lower 3835 auto *UBExpr = TestIsLessOp ? UB : LB; 3836 auto *LBExpr = TestIsLessOp ? LB : UB; 3837 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 3838 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 3839 if (!Upper || !Lower) 3840 return nullptr; 3841 3842 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 3843 3844 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 3845 // BuildBinOp already emitted error, this one is to point user to upper 3846 // and lower bound, and to tell what is passed to 'operator-'. 3847 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) 3848 << Upper->getSourceRange() << Lower->getSourceRange(); 3849 return nullptr; 3850 } 3851 } 3852 3853 if (!Diff.isUsable()) 3854 return nullptr; 3855 3856 // Upper - Lower [- 1] 3857 if (TestIsStrictOp) 3858 Diff = SemaRef.BuildBinOp( 3859 S, DefaultLoc, BO_Sub, Diff.get(), 3860 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 3861 if (!Diff.isUsable()) 3862 return nullptr; 3863 3864 // Upper - Lower [- 1] + Step 3865 auto NewStep = tryBuildCapture(SemaRef, Step, Captures); 3866 if (!NewStep.isUsable()) 3867 return nullptr; 3868 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 3869 if (!Diff.isUsable()) 3870 return nullptr; 3871 3872 // Parentheses (for dumping/debugging purposes only). 3873 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 3874 if (!Diff.isUsable()) 3875 return nullptr; 3876 3877 // (Upper - Lower [- 1] + Step) / Step 3878 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 3879 if (!Diff.isUsable()) 3880 return nullptr; 3881 3882 // OpenMP runtime requires 32-bit or 64-bit loop variables. 3883 QualType Type = Diff.get()->getType(); 3884 auto &C = SemaRef.Context; 3885 bool UseVarType = VarType->hasIntegerRepresentation() && 3886 C.getTypeSize(Type) > C.getTypeSize(VarType); 3887 if (!Type->isIntegerType() || UseVarType) { 3888 unsigned NewSize = 3889 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 3890 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 3891 : Type->hasSignedIntegerRepresentation(); 3892 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 3893 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 3894 Diff = SemaRef.PerformImplicitConversion( 3895 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 3896 if (!Diff.isUsable()) 3897 return nullptr; 3898 } 3899 } 3900 if (LimitedType) { 3901 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 3902 if (NewSize != C.getTypeSize(Type)) { 3903 if (NewSize < C.getTypeSize(Type)) { 3904 assert(NewSize == 64 && "incorrect loop var size"); 3905 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 3906 << InitSrcRange << ConditionSrcRange; 3907 } 3908 QualType NewType = C.getIntTypeForBitwidth( 3909 NewSize, Type->hasSignedIntegerRepresentation() || 3910 C.getTypeSize(Type) < NewSize); 3911 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 3912 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 3913 Sema::AA_Converting, true); 3914 if (!Diff.isUsable()) 3915 return nullptr; 3916 } 3917 } 3918 } 3919 3920 return Diff.get(); 3921 } 3922 3923 Expr *OpenMPIterationSpaceChecker::BuildPreCond( 3924 Scope *S, Expr *Cond, 3925 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 3926 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 3927 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 3928 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 3929 3930 auto NewLB = tryBuildCapture(SemaRef, LB, Captures); 3931 auto NewUB = tryBuildCapture(SemaRef, UB, Captures); 3932 if (!NewLB.isUsable() || !NewUB.isUsable()) 3933 return nullptr; 3934 3935 auto CondExpr = SemaRef.BuildBinOp( 3936 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) 3937 : (TestIsStrictOp ? BO_GT : BO_GE), 3938 NewLB.get(), NewUB.get()); 3939 if (CondExpr.isUsable()) { 3940 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 3941 SemaRef.Context.BoolTy)) 3942 CondExpr = SemaRef.PerformImplicitConversion( 3943 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 3944 /*AllowExplicit=*/true); 3945 } 3946 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 3947 // Otherwise use original loop conditon and evaluate it in runtime. 3948 return CondExpr.isUsable() ? CondExpr.get() : Cond; 3949 } 3950 3951 /// \brief Build reference expression to the counter be used for codegen. 3952 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar( 3953 llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const { 3954 auto *VD = dyn_cast<VarDecl>(LCDecl); 3955 if (!VD) { 3956 VD = SemaRef.IsOpenMPCapturedDecl(LCDecl); 3957 auto *Ref = buildDeclRefExpr( 3958 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 3959 DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl, /*FromParent=*/false); 3960 // If the loop control decl is explicitly marked as private, do not mark it 3961 // as captured again. 3962 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 3963 Captures.insert(std::make_pair(LCRef, Ref)); 3964 return Ref; 3965 } 3966 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(), 3967 DefaultLoc); 3968 } 3969 3970 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const { 3971 if (LCDecl && !LCDecl->isInvalidDecl()) { 3972 auto Type = LCDecl->getType().getNonReferenceType(); 3973 auto *PrivateVar = 3974 buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(), 3975 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr); 3976 if (PrivateVar->isInvalidDecl()) 3977 return nullptr; 3978 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 3979 } 3980 return nullptr; 3981 } 3982 3983 /// \brief Build initialization of the counter to be used for codegen. 3984 Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; } 3985 3986 /// \brief Build step of the counter be used for codegen. 3987 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; } 3988 3989 /// \brief Iteration space of a single for loop. 3990 struct LoopIterationSpace final { 3991 /// \brief Condition of the loop. 3992 Expr *PreCond = nullptr; 3993 /// \brief This expression calculates the number of iterations in the loop. 3994 /// It is always possible to calculate it before starting the loop. 3995 Expr *NumIterations = nullptr; 3996 /// \brief The loop counter variable. 3997 Expr *CounterVar = nullptr; 3998 /// \brief Private loop counter variable. 3999 Expr *PrivateCounterVar = nullptr; 4000 /// \brief This is initializer for the initial value of #CounterVar. 4001 Expr *CounterInit = nullptr; 4002 /// \brief This is step for the #CounterVar used to generate its update: 4003 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4004 Expr *CounterStep = nullptr; 4005 /// \brief Should step be subtracted? 4006 bool Subtract = false; 4007 /// \brief Source range of the loop init. 4008 SourceRange InitSrcRange; 4009 /// \brief Source range of the loop condition. 4010 SourceRange CondSrcRange; 4011 /// \brief Source range of the loop increment. 4012 SourceRange IncSrcRange; 4013 }; 4014 4015 } // namespace 4016 4017 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 4018 assert(getLangOpts().OpenMP && "OpenMP is not active."); 4019 assert(Init && "Expected loop in canonical form."); 4020 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 4021 if (AssociatedLoops > 0 && 4022 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 4023 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 4024 if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) { 4025 if (auto *D = ISC.GetLoopDecl()) { 4026 auto *VD = dyn_cast<VarDecl>(D); 4027 if (!VD) { 4028 if (auto *Private = IsOpenMPCapturedDecl(D)) 4029 VD = Private; 4030 else { 4031 auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(), 4032 /*WithInit=*/false); 4033 VD = cast<VarDecl>(Ref->getDecl()); 4034 } 4035 } 4036 DSAStack->addLoopControlVariable(D, VD); 4037 } 4038 } 4039 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 4040 } 4041 } 4042 4043 /// \brief Called on a for stmt to check and extract its iteration space 4044 /// for further processing (such as collapsing). 4045 static bool CheckOpenMPIterationSpace( 4046 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 4047 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 4048 Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, 4049 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 4050 LoopIterationSpace &ResultIterSpace, 4051 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4052 // OpenMP [2.6, Canonical Loop Form] 4053 // for (init-expr; test-expr; incr-expr) structured-block 4054 auto *For = dyn_cast_or_null<ForStmt>(S); 4055 if (!For) { 4056 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for) 4057 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 4058 << getOpenMPDirectiveName(DKind) << NestedLoopCount 4059 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 4060 if (NestedLoopCount > 1) { 4061 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 4062 SemaRef.Diag(DSA.getConstructLoc(), 4063 diag::note_omp_collapse_ordered_expr) 4064 << 2 << CollapseLoopCountExpr->getSourceRange() 4065 << OrderedLoopCountExpr->getSourceRange(); 4066 else if (CollapseLoopCountExpr) 4067 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4068 diag::note_omp_collapse_ordered_expr) 4069 << 0 << CollapseLoopCountExpr->getSourceRange(); 4070 else 4071 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4072 diag::note_omp_collapse_ordered_expr) 4073 << 1 << OrderedLoopCountExpr->getSourceRange(); 4074 } 4075 return true; 4076 } 4077 assert(For->getBody()); 4078 4079 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 4080 4081 // Check init. 4082 auto Init = For->getInit(); 4083 if (ISC.CheckInit(Init)) 4084 return true; 4085 4086 bool HasErrors = false; 4087 4088 // Check loop variable's type. 4089 if (auto *LCDecl = ISC.GetLoopDecl()) { 4090 auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr(); 4091 4092 // OpenMP [2.6, Canonical Loop Form] 4093 // Var is one of the following: 4094 // A variable of signed or unsigned integer type. 4095 // For C++, a variable of a random access iterator type. 4096 // For C, a variable of a pointer type. 4097 auto VarType = LCDecl->getType().getNonReferenceType(); 4098 if (!VarType->isDependentType() && !VarType->isIntegerType() && 4099 !VarType->isPointerType() && 4100 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 4101 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type) 4102 << SemaRef.getLangOpts().CPlusPlus; 4103 HasErrors = true; 4104 } 4105 4106 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 4107 // a Construct 4108 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4109 // parallel for construct is (are) private. 4110 // The loop iteration variable in the associated for-loop of a simd 4111 // construct with just one associated for-loop is linear with a 4112 // constant-linear-step that is the increment of the associated for-loop. 4113 // Exclude loop var from the list of variables with implicitly defined data 4114 // sharing attributes. 4115 VarsWithImplicitDSA.erase(LCDecl); 4116 4117 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 4118 // in a Construct, C/C++]. 4119 // The loop iteration variable in the associated for-loop of a simd 4120 // construct with just one associated for-loop may be listed in a linear 4121 // clause with a constant-linear-step that is the increment of the 4122 // associated for-loop. 4123 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4124 // parallel for construct may be listed in a private or lastprivate clause. 4125 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 4126 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 4127 // declared in the loop and it is predetermined as a private. 4128 auto PredeterminedCKind = 4129 isOpenMPSimdDirective(DKind) 4130 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 4131 : OMPC_private; 4132 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4133 DVar.CKind != PredeterminedCKind) || 4134 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 4135 isOpenMPDistributeDirective(DKind)) && 4136 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4137 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 4138 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 4139 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa) 4140 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 4141 << getOpenMPClauseName(PredeterminedCKind); 4142 if (DVar.RefExpr == nullptr) 4143 DVar.CKind = PredeterminedCKind; 4144 ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 4145 HasErrors = true; 4146 } else if (LoopDeclRefExpr != nullptr) { 4147 // Make the loop iteration variable private (for worksharing constructs), 4148 // linear (for simd directives with the only one associated loop) or 4149 // lastprivate (for simd directives with several collapsed or ordered 4150 // loops). 4151 if (DVar.CKind == OMPC_unknown) 4152 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate, 4153 [](OpenMPDirectiveKind) -> bool { return true; }, 4154 /*FromParent=*/false); 4155 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 4156 } 4157 4158 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 4159 4160 // Check test-expr. 4161 HasErrors |= ISC.CheckCond(For->getCond()); 4162 4163 // Check incr-expr. 4164 HasErrors |= ISC.CheckInc(For->getInc()); 4165 } 4166 4167 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 4168 return HasErrors; 4169 4170 // Build the loop's iteration space representation. 4171 ResultIterSpace.PreCond = 4172 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures); 4173 ResultIterSpace.NumIterations = ISC.BuildNumIterations( 4174 DSA.getCurScope(), 4175 (isOpenMPWorksharingDirective(DKind) || 4176 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 4177 Captures); 4178 ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA); 4179 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); 4180 ResultIterSpace.CounterInit = ISC.BuildCounterInit(); 4181 ResultIterSpace.CounterStep = ISC.BuildCounterStep(); 4182 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); 4183 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange(); 4184 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange(); 4185 ResultIterSpace.Subtract = ISC.ShouldSubtractStep(); 4186 4187 HasErrors |= (ResultIterSpace.PreCond == nullptr || 4188 ResultIterSpace.NumIterations == nullptr || 4189 ResultIterSpace.CounterVar == nullptr || 4190 ResultIterSpace.PrivateCounterVar == nullptr || 4191 ResultIterSpace.CounterInit == nullptr || 4192 ResultIterSpace.CounterStep == nullptr); 4193 4194 return HasErrors; 4195 } 4196 4197 /// \brief Build 'VarRef = Start. 4198 static ExprResult 4199 BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 4200 ExprResult Start, 4201 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4202 // Build 'VarRef = Start. 4203 auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 4204 if (!NewStart.isUsable()) 4205 return ExprError(); 4206 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 4207 VarRef.get()->getType())) { 4208 NewStart = SemaRef.PerformImplicitConversion( 4209 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 4210 /*AllowExplicit=*/true); 4211 if (!NewStart.isUsable()) 4212 return ExprError(); 4213 } 4214 4215 auto Init = 4216 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4217 return Init; 4218 } 4219 4220 /// \brief Build 'VarRef = Start + Iter * Step'. 4221 static ExprResult 4222 BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, 4223 ExprResult VarRef, ExprResult Start, ExprResult Iter, 4224 ExprResult Step, bool Subtract, 4225 llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) { 4226 // Add parentheses (for debugging purposes only). 4227 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 4228 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 4229 !Step.isUsable()) 4230 return ExprError(); 4231 4232 ExprResult NewStep = Step; 4233 if (Captures) 4234 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 4235 if (NewStep.isInvalid()) 4236 return ExprError(); 4237 ExprResult Update = 4238 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 4239 if (!Update.isUsable()) 4240 return ExprError(); 4241 4242 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 4243 // 'VarRef = Start (+|-) Iter * Step'. 4244 ExprResult NewStart = Start; 4245 if (Captures) 4246 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 4247 if (NewStart.isInvalid()) 4248 return ExprError(); 4249 4250 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 4251 ExprResult SavedUpdate = Update; 4252 ExprResult UpdateVal; 4253 if (VarRef.get()->getType()->isOverloadableType() || 4254 NewStart.get()->getType()->isOverloadableType() || 4255 Update.get()->getType()->isOverloadableType()) { 4256 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4257 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4258 Update = 4259 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4260 if (Update.isUsable()) { 4261 UpdateVal = 4262 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 4263 VarRef.get(), SavedUpdate.get()); 4264 if (UpdateVal.isUsable()) { 4265 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 4266 UpdateVal.get()); 4267 } 4268 } 4269 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4270 } 4271 4272 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 4273 if (!Update.isUsable() || !UpdateVal.isUsable()) { 4274 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 4275 NewStart.get(), SavedUpdate.get()); 4276 if (!Update.isUsable()) 4277 return ExprError(); 4278 4279 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 4280 VarRef.get()->getType())) { 4281 Update = SemaRef.PerformImplicitConversion( 4282 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 4283 if (!Update.isUsable()) 4284 return ExprError(); 4285 } 4286 4287 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 4288 } 4289 return Update; 4290 } 4291 4292 /// \brief Convert integer expression \a E to make it have at least \a Bits 4293 /// bits. 4294 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 4295 if (E == nullptr) 4296 return ExprError(); 4297 auto &C = SemaRef.Context; 4298 QualType OldType = E->getType(); 4299 unsigned HasBits = C.getTypeSize(OldType); 4300 if (HasBits >= Bits) 4301 return ExprResult(E); 4302 // OK to convert to signed, because new type has more bits than old. 4303 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 4304 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 4305 true); 4306 } 4307 4308 /// \brief Check if the given expression \a E is a constant integer that fits 4309 /// into \a Bits bits. 4310 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { 4311 if (E == nullptr) 4312 return false; 4313 llvm::APSInt Result; 4314 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 4315 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 4316 return false; 4317 } 4318 4319 /// Build preinits statement for the given declarations. 4320 static Stmt *buildPreInits(ASTContext &Context, 4321 SmallVectorImpl<Decl *> &PreInits) { 4322 if (!PreInits.empty()) { 4323 return new (Context) DeclStmt( 4324 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 4325 SourceLocation(), SourceLocation()); 4326 } 4327 return nullptr; 4328 } 4329 4330 /// Build preinits statement for the given declarations. 4331 static Stmt *buildPreInits(ASTContext &Context, 4332 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4333 if (!Captures.empty()) { 4334 SmallVector<Decl *, 16> PreInits; 4335 for (auto &Pair : Captures) 4336 PreInits.push_back(Pair.second->getDecl()); 4337 return buildPreInits(Context, PreInits); 4338 } 4339 return nullptr; 4340 } 4341 4342 /// Build postupdate expression for the given list of postupdates expressions. 4343 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 4344 Expr *PostUpdate = nullptr; 4345 if (!PostUpdates.empty()) { 4346 for (auto *E : PostUpdates) { 4347 Expr *ConvE = S.BuildCStyleCastExpr( 4348 E->getExprLoc(), 4349 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 4350 E->getExprLoc(), E) 4351 .get(); 4352 PostUpdate = PostUpdate 4353 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 4354 PostUpdate, ConvE) 4355 .get() 4356 : ConvE; 4357 } 4358 } 4359 return PostUpdate; 4360 } 4361 4362 /// \brief Called on a for stmt to check itself and nested loops (if any). 4363 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 4364 /// number of collapsed loops otherwise. 4365 static unsigned 4366 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 4367 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 4368 DSAStackTy &DSA, 4369 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 4370 OMPLoopDirective::HelperExprs &Built) { 4371 unsigned NestedLoopCount = 1; 4372 if (CollapseLoopCountExpr) { 4373 // Found 'collapse' clause - calculate collapse number. 4374 llvm::APSInt Result; 4375 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 4376 NestedLoopCount = Result.getLimitedValue(); 4377 } 4378 if (OrderedLoopCountExpr) { 4379 // Found 'ordered' clause - calculate collapse number. 4380 llvm::APSInt Result; 4381 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 4382 if (Result.getLimitedValue() < NestedLoopCount) { 4383 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4384 diag::err_omp_wrong_ordered_loop_count) 4385 << OrderedLoopCountExpr->getSourceRange(); 4386 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4387 diag::note_collapse_loop_count) 4388 << CollapseLoopCountExpr->getSourceRange(); 4389 } 4390 NestedLoopCount = Result.getLimitedValue(); 4391 } 4392 } 4393 // This is helper routine for loop directives (e.g., 'for', 'simd', 4394 // 'for simd', etc.). 4395 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 4396 SmallVector<LoopIterationSpace, 4> IterSpaces; 4397 IterSpaces.resize(NestedLoopCount); 4398 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 4399 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 4400 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, 4401 NestedLoopCount, CollapseLoopCountExpr, 4402 OrderedLoopCountExpr, VarsWithImplicitDSA, 4403 IterSpaces[Cnt], Captures)) 4404 return 0; 4405 // Move on to the next nested for loop, or to the loop body. 4406 // OpenMP [2.8.1, simd construct, Restrictions] 4407 // All loops associated with the construct must be perfectly nested; that 4408 // is, there must be no intervening code nor any OpenMP directive between 4409 // any two loops. 4410 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 4411 } 4412 4413 Built.clear(/* size */ NestedLoopCount); 4414 4415 if (SemaRef.CurContext->isDependentContext()) 4416 return NestedLoopCount; 4417 4418 // An example of what is generated for the following code: 4419 // 4420 // #pragma omp simd collapse(2) ordered(2) 4421 // for (i = 0; i < NI; ++i) 4422 // for (k = 0; k < NK; ++k) 4423 // for (j = J0; j < NJ; j+=2) { 4424 // <loop body> 4425 // } 4426 // 4427 // We generate the code below. 4428 // Note: the loop body may be outlined in CodeGen. 4429 // Note: some counters may be C++ classes, operator- is used to find number of 4430 // iterations and operator+= to calculate counter value. 4431 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 4432 // or i64 is currently supported). 4433 // 4434 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 4435 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 4436 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 4437 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 4438 // // similar updates for vars in clauses (e.g. 'linear') 4439 // <loop body (using local i and j)> 4440 // } 4441 // i = NI; // assign final values of counters 4442 // j = NJ; 4443 // 4444 4445 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 4446 // the iteration counts of the collapsed for loops. 4447 // Precondition tests if there is at least one iteration (all conditions are 4448 // true). 4449 auto PreCond = ExprResult(IterSpaces[0].PreCond); 4450 auto N0 = IterSpaces[0].NumIterations; 4451 ExprResult LastIteration32 = WidenIterationCount( 4452 32 /* Bits */, SemaRef 4453 .PerformImplicitConversion( 4454 N0->IgnoreImpCasts(), N0->getType(), 4455 Sema::AA_Converting, /*AllowExplicit=*/true) 4456 .get(), 4457 SemaRef); 4458 ExprResult LastIteration64 = WidenIterationCount( 4459 64 /* Bits */, SemaRef 4460 .PerformImplicitConversion( 4461 N0->IgnoreImpCasts(), N0->getType(), 4462 Sema::AA_Converting, /*AllowExplicit=*/true) 4463 .get(), 4464 SemaRef); 4465 4466 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 4467 return NestedLoopCount; 4468 4469 auto &C = SemaRef.Context; 4470 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 4471 4472 Scope *CurScope = DSA.getCurScope(); 4473 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 4474 if (PreCond.isUsable()) { 4475 PreCond = 4476 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 4477 PreCond.get(), IterSpaces[Cnt].PreCond); 4478 } 4479 auto N = IterSpaces[Cnt].NumIterations; 4480 SourceLocation Loc = N->getExprLoc(); 4481 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 4482 if (LastIteration32.isUsable()) 4483 LastIteration32 = SemaRef.BuildBinOp( 4484 CurScope, Loc, BO_Mul, LastIteration32.get(), 4485 SemaRef 4486 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4487 Sema::AA_Converting, 4488 /*AllowExplicit=*/true) 4489 .get()); 4490 if (LastIteration64.isUsable()) 4491 LastIteration64 = SemaRef.BuildBinOp( 4492 CurScope, Loc, BO_Mul, LastIteration64.get(), 4493 SemaRef 4494 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4495 Sema::AA_Converting, 4496 /*AllowExplicit=*/true) 4497 .get()); 4498 } 4499 4500 // Choose either the 32-bit or 64-bit version. 4501 ExprResult LastIteration = LastIteration64; 4502 if (LastIteration32.isUsable() && 4503 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 4504 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 4505 FitsInto( 4506 32 /* Bits */, 4507 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 4508 LastIteration64.get(), SemaRef))) 4509 LastIteration = LastIteration32; 4510 QualType VType = LastIteration.get()->getType(); 4511 QualType RealVType = VType; 4512 QualType StrideVType = VType; 4513 if (isOpenMPTaskLoopDirective(DKind)) { 4514 VType = 4515 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 4516 StrideVType = 4517 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 4518 } 4519 4520 if (!LastIteration.isUsable()) 4521 return 0; 4522 4523 // Save the number of iterations. 4524 ExprResult NumIterations = LastIteration; 4525 { 4526 LastIteration = SemaRef.BuildBinOp( 4527 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 4528 LastIteration.get(), 4529 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4530 if (!LastIteration.isUsable()) 4531 return 0; 4532 } 4533 4534 // Calculate the last iteration number beforehand instead of doing this on 4535 // each iteration. Do not do this if the number of iterations may be kfold-ed. 4536 llvm::APSInt Result; 4537 bool IsConstant = 4538 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 4539 ExprResult CalcLastIteration; 4540 if (!IsConstant) { 4541 ExprResult SaveRef = 4542 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 4543 LastIteration = SaveRef; 4544 4545 // Prepare SaveRef + 1. 4546 NumIterations = SemaRef.BuildBinOp( 4547 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 4548 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4549 if (!NumIterations.isUsable()) 4550 return 0; 4551 } 4552 4553 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 4554 4555 // Build variables passed into runtime, necessary for worksharing directives. 4556 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 4557 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4558 isOpenMPDistributeDirective(DKind)) { 4559 // Lower bound variable, initialized with zero. 4560 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 4561 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 4562 SemaRef.AddInitializerToDecl(LBDecl, 4563 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4564 /*DirectInit*/ false); 4565 4566 // Upper bound variable, initialized with last iteration number. 4567 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 4568 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 4569 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 4570 /*DirectInit*/ false); 4571 4572 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 4573 // This will be used to implement clause 'lastprivate'. 4574 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 4575 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 4576 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 4577 SemaRef.AddInitializerToDecl(ILDecl, 4578 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4579 /*DirectInit*/ false); 4580 4581 // Stride variable returned by runtime (we initialize it to 1 by default). 4582 VarDecl *STDecl = 4583 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 4584 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 4585 SemaRef.AddInitializerToDecl(STDecl, 4586 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 4587 /*DirectInit*/ false); 4588 4589 // Build expression: UB = min(UB, LastIteration) 4590 // It is necessary for CodeGen of directives with static scheduling. 4591 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 4592 UB.get(), LastIteration.get()); 4593 ExprResult CondOp = SemaRef.ActOnConditionalOp( 4594 InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get()); 4595 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 4596 CondOp.get()); 4597 EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); 4598 4599 // If we have a combined directive that combines 'distribute', 'for' or 4600 // 'simd' we need to be able to access the bounds of the schedule of the 4601 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 4602 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 4603 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4604 4605 // Lower bound variable, initialized with zero. 4606 VarDecl *CombLBDecl = 4607 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 4608 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 4609 SemaRef.AddInitializerToDecl( 4610 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4611 /*DirectInit*/ false); 4612 4613 // Upper bound variable, initialized with last iteration number. 4614 VarDecl *CombUBDecl = 4615 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 4616 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 4617 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 4618 /*DirectInit*/ false); 4619 4620 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 4621 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 4622 ExprResult CombCondOp = 4623 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 4624 LastIteration.get(), CombUB.get()); 4625 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 4626 CombCondOp.get()); 4627 CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get()); 4628 4629 auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 4630 // We expect to have at least 2 more parameters than the 'parallel' 4631 // directive does - the lower and upper bounds of the previous schedule. 4632 assert(CD->getNumParams() >= 4 && 4633 "Unexpected number of parameters in loop combined directive"); 4634 4635 // Set the proper type for the bounds given what we learned from the 4636 // enclosed loops. 4637 auto *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 4638 auto *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 4639 4640 // Previous lower and upper bounds are obtained from the region 4641 // parameters. 4642 PrevLB = 4643 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 4644 PrevUB = 4645 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 4646 } 4647 } 4648 4649 // Build the iteration variable and its initialization before loop. 4650 ExprResult IV; 4651 ExprResult Init, CombInit; 4652 { 4653 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 4654 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 4655 Expr *RHS = 4656 (isOpenMPWorksharingDirective(DKind) || 4657 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 4658 ? LB.get() 4659 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 4660 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 4661 Init = SemaRef.ActOnFinishFullExpr(Init.get()); 4662 4663 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4664 Expr *CombRHS = 4665 (isOpenMPWorksharingDirective(DKind) || 4666 isOpenMPTaskLoopDirective(DKind) || 4667 isOpenMPDistributeDirective(DKind)) 4668 ? CombLB.get() 4669 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 4670 CombInit = 4671 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 4672 CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get()); 4673 } 4674 } 4675 4676 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. 4677 SourceLocation CondLoc; 4678 ExprResult Cond = 4679 (isOpenMPWorksharingDirective(DKind) || 4680 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 4681 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) 4682 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 4683 NumIterations.get()); 4684 ExprResult CombCond; 4685 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4686 CombCond = 4687 SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get()); 4688 } 4689 // Loop increment (IV = IV + 1) 4690 SourceLocation IncLoc; 4691 ExprResult Inc = 4692 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 4693 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 4694 if (!Inc.isUsable()) 4695 return 0; 4696 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 4697 Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); 4698 if (!Inc.isUsable()) 4699 return 0; 4700 4701 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 4702 // Used for directives with static scheduling. 4703 // In combined construct, add combined version that use CombLB and CombUB 4704 // base variables for the update 4705 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 4706 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4707 isOpenMPDistributeDirective(DKind)) { 4708 // LB + ST 4709 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 4710 if (!NextLB.isUsable()) 4711 return 0; 4712 // LB = LB + ST 4713 NextLB = 4714 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 4715 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); 4716 if (!NextLB.isUsable()) 4717 return 0; 4718 // UB + ST 4719 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 4720 if (!NextUB.isUsable()) 4721 return 0; 4722 // UB = UB + ST 4723 NextUB = 4724 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 4725 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); 4726 if (!NextUB.isUsable()) 4727 return 0; 4728 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4729 CombNextLB = 4730 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 4731 if (!NextLB.isUsable()) 4732 return 0; 4733 // LB = LB + ST 4734 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 4735 CombNextLB.get()); 4736 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get()); 4737 if (!CombNextLB.isUsable()) 4738 return 0; 4739 // UB + ST 4740 CombNextUB = 4741 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 4742 if (!CombNextUB.isUsable()) 4743 return 0; 4744 // UB = UB + ST 4745 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 4746 CombNextUB.get()); 4747 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get()); 4748 if (!CombNextUB.isUsable()) 4749 return 0; 4750 } 4751 } 4752 4753 // Create increment expression for distribute loop when combined in a same 4754 // directive with for as IV = IV + ST; ensure upper bound expression based 4755 // on PrevUB instead of NumIterations - used to implement 'for' when found 4756 // in combination with 'distribute', like in 'distribute parallel for' 4757 SourceLocation DistIncLoc; 4758 ExprResult DistCond, DistInc, PrevEUB; 4759 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4760 DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()); 4761 assert(DistCond.isUsable() && "distribute cond expr was not built"); 4762 4763 DistInc = 4764 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 4765 assert(DistInc.isUsable() && "distribute inc expr was not built"); 4766 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 4767 DistInc.get()); 4768 DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get()); 4769 assert(DistInc.isUsable() && "distribute inc expr was not built"); 4770 4771 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 4772 // construct 4773 SourceLocation DistEUBLoc; 4774 ExprResult IsUBGreater = 4775 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 4776 ExprResult CondOp = SemaRef.ActOnConditionalOp( 4777 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 4778 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 4779 CondOp.get()); 4780 PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get()); 4781 } 4782 4783 // Build updates and final values of the loop counters. 4784 bool HasErrors = false; 4785 Built.Counters.resize(NestedLoopCount); 4786 Built.Inits.resize(NestedLoopCount); 4787 Built.Updates.resize(NestedLoopCount); 4788 Built.Finals.resize(NestedLoopCount); 4789 SmallVector<Expr *, 4> LoopMultipliers; 4790 { 4791 ExprResult Div; 4792 // Go from inner nested loop to outer. 4793 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 4794 LoopIterationSpace &IS = IterSpaces[Cnt]; 4795 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 4796 // Build: Iter = (IV / Div) % IS.NumIters 4797 // where Div is product of previous iterations' IS.NumIters. 4798 ExprResult Iter; 4799 if (Div.isUsable()) { 4800 Iter = 4801 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); 4802 } else { 4803 Iter = IV; 4804 assert((Cnt == (int)NestedLoopCount - 1) && 4805 "unusable div expected on first iteration only"); 4806 } 4807 4808 if (Cnt != 0 && Iter.isUsable()) 4809 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), 4810 IS.NumIterations); 4811 if (!Iter.isUsable()) { 4812 HasErrors = true; 4813 break; 4814 } 4815 4816 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 4817 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 4818 auto *CounterVar = buildDeclRefExpr(SemaRef, VD, IS.CounterVar->getType(), 4819 IS.CounterVar->getExprLoc(), 4820 /*RefersToCapture=*/true); 4821 ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 4822 IS.CounterInit, Captures); 4823 if (!Init.isUsable()) { 4824 HasErrors = true; 4825 break; 4826 } 4827 ExprResult Update = BuildCounterUpdate( 4828 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 4829 IS.CounterStep, IS.Subtract, &Captures); 4830 if (!Update.isUsable()) { 4831 HasErrors = true; 4832 break; 4833 } 4834 4835 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 4836 ExprResult Final = BuildCounterUpdate( 4837 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 4838 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 4839 if (!Final.isUsable()) { 4840 HasErrors = true; 4841 break; 4842 } 4843 4844 // Build Div for the next iteration: Div <- Div * IS.NumIters 4845 if (Cnt != 0) { 4846 if (Div.isUnset()) 4847 Div = IS.NumIterations; 4848 else 4849 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), 4850 IS.NumIterations); 4851 4852 // Add parentheses (for debugging purposes only). 4853 if (Div.isUsable()) 4854 Div = tryBuildCapture(SemaRef, Div.get(), Captures); 4855 if (!Div.isUsable()) { 4856 HasErrors = true; 4857 break; 4858 } 4859 LoopMultipliers.push_back(Div.get()); 4860 } 4861 if (!Update.isUsable() || !Final.isUsable()) { 4862 HasErrors = true; 4863 break; 4864 } 4865 // Save results 4866 Built.Counters[Cnt] = IS.CounterVar; 4867 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 4868 Built.Inits[Cnt] = Init.get(); 4869 Built.Updates[Cnt] = Update.get(); 4870 Built.Finals[Cnt] = Final.get(); 4871 } 4872 } 4873 4874 if (HasErrors) 4875 return 0; 4876 4877 // Save results 4878 Built.IterationVarRef = IV.get(); 4879 Built.LastIteration = LastIteration.get(); 4880 Built.NumIterations = NumIterations.get(); 4881 Built.CalcLastIteration = 4882 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); 4883 Built.PreCond = PreCond.get(); 4884 Built.PreInits = buildPreInits(C, Captures); 4885 Built.Cond = Cond.get(); 4886 Built.Init = Init.get(); 4887 Built.Inc = Inc.get(); 4888 Built.LB = LB.get(); 4889 Built.UB = UB.get(); 4890 Built.IL = IL.get(); 4891 Built.ST = ST.get(); 4892 Built.EUB = EUB.get(); 4893 Built.NLB = NextLB.get(); 4894 Built.NUB = NextUB.get(); 4895 Built.PrevLB = PrevLB.get(); 4896 Built.PrevUB = PrevUB.get(); 4897 Built.DistInc = DistInc.get(); 4898 Built.PrevEUB = PrevEUB.get(); 4899 Built.DistCombinedFields.LB = CombLB.get(); 4900 Built.DistCombinedFields.UB = CombUB.get(); 4901 Built.DistCombinedFields.EUB = CombEUB.get(); 4902 Built.DistCombinedFields.Init = CombInit.get(); 4903 Built.DistCombinedFields.Cond = CombCond.get(); 4904 Built.DistCombinedFields.NLB = CombNextLB.get(); 4905 Built.DistCombinedFields.NUB = CombNextUB.get(); 4906 4907 Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get(); 4908 // Fill data for doacross depend clauses. 4909 for (auto Pair : DSA.getDoacrossDependClauses()) { 4910 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 4911 Pair.first->setCounterValue(CounterVal); 4912 else { 4913 if (NestedLoopCount != Pair.second.size() || 4914 NestedLoopCount != LoopMultipliers.size() + 1) { 4915 // Erroneous case - clause has some problems. 4916 Pair.first->setCounterValue(CounterVal); 4917 continue; 4918 } 4919 assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink); 4920 auto I = Pair.second.rbegin(); 4921 auto IS = IterSpaces.rbegin(); 4922 auto ILM = LoopMultipliers.rbegin(); 4923 Expr *UpCounterVal = CounterVal; 4924 Expr *Multiplier = nullptr; 4925 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 4926 if (I->first) { 4927 assert(IS->CounterStep); 4928 Expr *NormalizedOffset = 4929 SemaRef 4930 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div, 4931 I->first, IS->CounterStep) 4932 .get(); 4933 if (Multiplier) { 4934 NormalizedOffset = 4935 SemaRef 4936 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul, 4937 NormalizedOffset, Multiplier) 4938 .get(); 4939 } 4940 assert(I->second == OO_Plus || I->second == OO_Minus); 4941 BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : BO_Sub; 4942 UpCounterVal = SemaRef 4943 .BuildBinOp(CurScope, I->first->getExprLoc(), BOK, 4944 UpCounterVal, NormalizedOffset) 4945 .get(); 4946 } 4947 Multiplier = *ILM; 4948 ++I; 4949 ++IS; 4950 ++ILM; 4951 } 4952 Pair.first->setCounterValue(UpCounterVal); 4953 } 4954 } 4955 4956 return NestedLoopCount; 4957 } 4958 4959 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 4960 auto CollapseClauses = 4961 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 4962 if (CollapseClauses.begin() != CollapseClauses.end()) 4963 return (*CollapseClauses.begin())->getNumForLoops(); 4964 return nullptr; 4965 } 4966 4967 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 4968 auto OrderedClauses = 4969 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 4970 if (OrderedClauses.begin() != OrderedClauses.end()) 4971 return (*OrderedClauses.begin())->getNumForLoops(); 4972 return nullptr; 4973 } 4974 4975 static bool checkSimdlenSafelenSpecified(Sema &S, 4976 const ArrayRef<OMPClause *> Clauses) { 4977 OMPSafelenClause *Safelen = nullptr; 4978 OMPSimdlenClause *Simdlen = nullptr; 4979 4980 for (auto *Clause : Clauses) { 4981 if (Clause->getClauseKind() == OMPC_safelen) 4982 Safelen = cast<OMPSafelenClause>(Clause); 4983 else if (Clause->getClauseKind() == OMPC_simdlen) 4984 Simdlen = cast<OMPSimdlenClause>(Clause); 4985 if (Safelen && Simdlen) 4986 break; 4987 } 4988 4989 if (Simdlen && Safelen) { 4990 llvm::APSInt SimdlenRes, SafelenRes; 4991 auto SimdlenLength = Simdlen->getSimdlen(); 4992 auto SafelenLength = Safelen->getSafelen(); 4993 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 4994 SimdlenLength->isInstantiationDependent() || 4995 SimdlenLength->containsUnexpandedParameterPack()) 4996 return false; 4997 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 4998 SafelenLength->isInstantiationDependent() || 4999 SafelenLength->containsUnexpandedParameterPack()) 5000 return false; 5001 SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context); 5002 SafelenLength->EvaluateAsInt(SafelenRes, S.Context); 5003 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 5004 // If both simdlen and safelen clauses are specified, the value of the 5005 // simdlen parameter must be less than or equal to the value of the safelen 5006 // parameter. 5007 if (SimdlenRes > SafelenRes) { 5008 S.Diag(SimdlenLength->getExprLoc(), 5009 diag::err_omp_wrong_simdlen_safelen_values) 5010 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 5011 return true; 5012 } 5013 } 5014 return false; 5015 } 5016 5017 StmtResult Sema::ActOnOpenMPSimdDirective( 5018 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5019 SourceLocation EndLoc, 5020 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5021 if (!AStmt) 5022 return StmtError(); 5023 5024 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5025 OMPLoopDirective::HelperExprs B; 5026 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5027 // define the nested loops number. 5028 unsigned NestedLoopCount = CheckOpenMPLoop( 5029 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5030 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5031 if (NestedLoopCount == 0) 5032 return StmtError(); 5033 5034 assert((CurContext->isDependentContext() || B.builtAll()) && 5035 "omp simd loop exprs were not built"); 5036 5037 if (!CurContext->isDependentContext()) { 5038 // Finalize the clauses that need pre-built expressions for CodeGen. 5039 for (auto C : Clauses) { 5040 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5041 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5042 B.NumIterations, *this, CurScope, 5043 DSAStack)) 5044 return StmtError(); 5045 } 5046 } 5047 5048 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5049 return StmtError(); 5050 5051 getCurFunction()->setHasBranchProtectedScope(); 5052 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5053 Clauses, AStmt, B); 5054 } 5055 5056 StmtResult Sema::ActOnOpenMPForDirective( 5057 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5058 SourceLocation EndLoc, 5059 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5060 if (!AStmt) 5061 return StmtError(); 5062 5063 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5064 OMPLoopDirective::HelperExprs B; 5065 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5066 // define the nested loops number. 5067 unsigned NestedLoopCount = CheckOpenMPLoop( 5068 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5069 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5070 if (NestedLoopCount == 0) 5071 return StmtError(); 5072 5073 assert((CurContext->isDependentContext() || B.builtAll()) && 5074 "omp for loop exprs were not built"); 5075 5076 if (!CurContext->isDependentContext()) { 5077 // Finalize the clauses that need pre-built expressions for CodeGen. 5078 for (auto C : Clauses) { 5079 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5080 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5081 B.NumIterations, *this, CurScope, 5082 DSAStack)) 5083 return StmtError(); 5084 } 5085 } 5086 5087 getCurFunction()->setHasBranchProtectedScope(); 5088 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5089 Clauses, AStmt, B, DSAStack->isCancelRegion()); 5090 } 5091 5092 StmtResult Sema::ActOnOpenMPForSimdDirective( 5093 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5094 SourceLocation EndLoc, 5095 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5096 if (!AStmt) 5097 return StmtError(); 5098 5099 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5100 OMPLoopDirective::HelperExprs B; 5101 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5102 // define the nested loops number. 5103 unsigned NestedLoopCount = 5104 CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 5105 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5106 VarsWithImplicitDSA, B); 5107 if (NestedLoopCount == 0) 5108 return StmtError(); 5109 5110 assert((CurContext->isDependentContext() || B.builtAll()) && 5111 "omp for simd loop exprs were not built"); 5112 5113 if (!CurContext->isDependentContext()) { 5114 // Finalize the clauses that need pre-built expressions for CodeGen. 5115 for (auto C : Clauses) { 5116 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5117 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5118 B.NumIterations, *this, CurScope, 5119 DSAStack)) 5120 return StmtError(); 5121 } 5122 } 5123 5124 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5125 return StmtError(); 5126 5127 getCurFunction()->setHasBranchProtectedScope(); 5128 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5129 Clauses, AStmt, B); 5130 } 5131 5132 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 5133 Stmt *AStmt, 5134 SourceLocation StartLoc, 5135 SourceLocation EndLoc) { 5136 if (!AStmt) 5137 return StmtError(); 5138 5139 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5140 auto BaseStmt = AStmt; 5141 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5142 BaseStmt = CS->getCapturedStmt(); 5143 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5144 auto S = C->children(); 5145 if (S.begin() == S.end()) 5146 return StmtError(); 5147 // All associated statements must be '#pragma omp section' except for 5148 // the first one. 5149 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5150 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5151 if (SectionStmt) 5152 Diag(SectionStmt->getLocStart(), 5153 diag::err_omp_sections_substmt_not_section); 5154 return StmtError(); 5155 } 5156 cast<OMPSectionDirective>(SectionStmt) 5157 ->setHasCancel(DSAStack->isCancelRegion()); 5158 } 5159 } else { 5160 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt); 5161 return StmtError(); 5162 } 5163 5164 getCurFunction()->setHasBranchProtectedScope(); 5165 5166 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5167 DSAStack->isCancelRegion()); 5168 } 5169 5170 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 5171 SourceLocation StartLoc, 5172 SourceLocation EndLoc) { 5173 if (!AStmt) 5174 return StmtError(); 5175 5176 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5177 5178 getCurFunction()->setHasBranchProtectedScope(); 5179 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 5180 5181 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 5182 DSAStack->isCancelRegion()); 5183 } 5184 5185 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 5186 Stmt *AStmt, 5187 SourceLocation StartLoc, 5188 SourceLocation EndLoc) { 5189 if (!AStmt) 5190 return StmtError(); 5191 5192 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5193 5194 getCurFunction()->setHasBranchProtectedScope(); 5195 5196 // OpenMP [2.7.3, single Construct, Restrictions] 5197 // The copyprivate clause must not be used with the nowait clause. 5198 OMPClause *Nowait = nullptr; 5199 OMPClause *Copyprivate = nullptr; 5200 for (auto *Clause : Clauses) { 5201 if (Clause->getClauseKind() == OMPC_nowait) 5202 Nowait = Clause; 5203 else if (Clause->getClauseKind() == OMPC_copyprivate) 5204 Copyprivate = Clause; 5205 if (Copyprivate && Nowait) { 5206 Diag(Copyprivate->getLocStart(), 5207 diag::err_omp_single_copyprivate_with_nowait); 5208 Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here); 5209 return StmtError(); 5210 } 5211 } 5212 5213 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5214 } 5215 5216 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 5217 SourceLocation StartLoc, 5218 SourceLocation EndLoc) { 5219 if (!AStmt) 5220 return StmtError(); 5221 5222 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5223 5224 getCurFunction()->setHasBranchProtectedScope(); 5225 5226 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 5227 } 5228 5229 StmtResult Sema::ActOnOpenMPCriticalDirective( 5230 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 5231 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5232 if (!AStmt) 5233 return StmtError(); 5234 5235 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5236 5237 bool ErrorFound = false; 5238 llvm::APSInt Hint; 5239 SourceLocation HintLoc; 5240 bool DependentHint = false; 5241 for (auto *C : Clauses) { 5242 if (C->getClauseKind() == OMPC_hint) { 5243 if (!DirName.getName()) { 5244 Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name); 5245 ErrorFound = true; 5246 } 5247 Expr *E = cast<OMPHintClause>(C)->getHint(); 5248 if (E->isTypeDependent() || E->isValueDependent() || 5249 E->isInstantiationDependent()) 5250 DependentHint = true; 5251 else { 5252 Hint = E->EvaluateKnownConstInt(Context); 5253 HintLoc = C->getLocStart(); 5254 } 5255 } 5256 } 5257 if (ErrorFound) 5258 return StmtError(); 5259 auto Pair = DSAStack->getCriticalWithHint(DirName); 5260 if (Pair.first && DirName.getName() && !DependentHint) { 5261 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 5262 Diag(StartLoc, diag::err_omp_critical_with_hint); 5263 if (HintLoc.isValid()) { 5264 Diag(HintLoc, diag::note_omp_critical_hint_here) 5265 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 5266 } else 5267 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 5268 if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 5269 Diag(C->getLocStart(), diag::note_omp_critical_hint_here) 5270 << 1 5271 << C->getHint()->EvaluateKnownConstInt(Context).toString( 5272 /*Radix=*/10, /*Signed=*/false); 5273 } else 5274 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1; 5275 } 5276 } 5277 5278 getCurFunction()->setHasBranchProtectedScope(); 5279 5280 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 5281 Clauses, AStmt); 5282 if (!Pair.first && DirName.getName() && !DependentHint) 5283 DSAStack->addCriticalWithHint(Dir, Hint); 5284 return Dir; 5285 } 5286 5287 StmtResult Sema::ActOnOpenMPParallelForDirective( 5288 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5289 SourceLocation EndLoc, 5290 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5291 if (!AStmt) 5292 return StmtError(); 5293 5294 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5295 // 1.2.2 OpenMP Language Terminology 5296 // Structured block - An executable statement with a single entry at the 5297 // top and a single exit at the bottom. 5298 // The point of exit cannot be a branch out of the structured block. 5299 // longjmp() and throw() must not violate the entry/exit criteria. 5300 CS->getCapturedDecl()->setNothrow(); 5301 5302 OMPLoopDirective::HelperExprs B; 5303 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5304 // define the nested loops number. 5305 unsigned NestedLoopCount = 5306 CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 5307 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5308 VarsWithImplicitDSA, B); 5309 if (NestedLoopCount == 0) 5310 return StmtError(); 5311 5312 assert((CurContext->isDependentContext() || B.builtAll()) && 5313 "omp parallel for loop exprs were not built"); 5314 5315 if (!CurContext->isDependentContext()) { 5316 // Finalize the clauses that need pre-built expressions for CodeGen. 5317 for (auto C : Clauses) { 5318 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5319 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5320 B.NumIterations, *this, CurScope, 5321 DSAStack)) 5322 return StmtError(); 5323 } 5324 } 5325 5326 getCurFunction()->setHasBranchProtectedScope(); 5327 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 5328 NestedLoopCount, Clauses, AStmt, B, 5329 DSAStack->isCancelRegion()); 5330 } 5331 5332 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 5333 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5334 SourceLocation EndLoc, 5335 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5336 if (!AStmt) 5337 return StmtError(); 5338 5339 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5340 // 1.2.2 OpenMP Language Terminology 5341 // Structured block - An executable statement with a single entry at the 5342 // top and a single exit at the bottom. 5343 // The point of exit cannot be a branch out of the structured block. 5344 // longjmp() and throw() must not violate the entry/exit criteria. 5345 CS->getCapturedDecl()->setNothrow(); 5346 5347 OMPLoopDirective::HelperExprs B; 5348 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5349 // define the nested loops number. 5350 unsigned NestedLoopCount = 5351 CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 5352 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5353 VarsWithImplicitDSA, B); 5354 if (NestedLoopCount == 0) 5355 return StmtError(); 5356 5357 if (!CurContext->isDependentContext()) { 5358 // Finalize the clauses that need pre-built expressions for CodeGen. 5359 for (auto C : Clauses) { 5360 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5361 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5362 B.NumIterations, *this, CurScope, 5363 DSAStack)) 5364 return StmtError(); 5365 } 5366 } 5367 5368 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5369 return StmtError(); 5370 5371 getCurFunction()->setHasBranchProtectedScope(); 5372 return OMPParallelForSimdDirective::Create( 5373 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 5374 } 5375 5376 StmtResult 5377 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 5378 Stmt *AStmt, SourceLocation StartLoc, 5379 SourceLocation EndLoc) { 5380 if (!AStmt) 5381 return StmtError(); 5382 5383 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5384 auto BaseStmt = AStmt; 5385 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5386 BaseStmt = CS->getCapturedStmt(); 5387 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5388 auto S = C->children(); 5389 if (S.begin() == S.end()) 5390 return StmtError(); 5391 // All associated statements must be '#pragma omp section' except for 5392 // the first one. 5393 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5394 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5395 if (SectionStmt) 5396 Diag(SectionStmt->getLocStart(), 5397 diag::err_omp_parallel_sections_substmt_not_section); 5398 return StmtError(); 5399 } 5400 cast<OMPSectionDirective>(SectionStmt) 5401 ->setHasCancel(DSAStack->isCancelRegion()); 5402 } 5403 } else { 5404 Diag(AStmt->getLocStart(), 5405 diag::err_omp_parallel_sections_not_compound_stmt); 5406 return StmtError(); 5407 } 5408 5409 getCurFunction()->setHasBranchProtectedScope(); 5410 5411 return OMPParallelSectionsDirective::Create( 5412 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 5413 } 5414 5415 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 5416 Stmt *AStmt, SourceLocation StartLoc, 5417 SourceLocation EndLoc) { 5418 if (!AStmt) 5419 return StmtError(); 5420 5421 auto *CS = cast<CapturedStmt>(AStmt); 5422 // 1.2.2 OpenMP Language Terminology 5423 // Structured block - An executable statement with a single entry at the 5424 // top and a single exit at the bottom. 5425 // The point of exit cannot be a branch out of the structured block. 5426 // longjmp() and throw() must not violate the entry/exit criteria. 5427 CS->getCapturedDecl()->setNothrow(); 5428 5429 getCurFunction()->setHasBranchProtectedScope(); 5430 5431 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5432 DSAStack->isCancelRegion()); 5433 } 5434 5435 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 5436 SourceLocation EndLoc) { 5437 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 5438 } 5439 5440 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 5441 SourceLocation EndLoc) { 5442 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 5443 } 5444 5445 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 5446 SourceLocation EndLoc) { 5447 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 5448 } 5449 5450 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 5451 Stmt *AStmt, 5452 SourceLocation StartLoc, 5453 SourceLocation EndLoc) { 5454 if (!AStmt) 5455 return StmtError(); 5456 5457 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5458 5459 getCurFunction()->setHasBranchProtectedScope(); 5460 5461 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 5462 AStmt, 5463 DSAStack->getTaskgroupReductionRef()); 5464 } 5465 5466 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 5467 SourceLocation StartLoc, 5468 SourceLocation EndLoc) { 5469 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 5470 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 5471 } 5472 5473 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 5474 Stmt *AStmt, 5475 SourceLocation StartLoc, 5476 SourceLocation EndLoc) { 5477 OMPClause *DependFound = nullptr; 5478 OMPClause *DependSourceClause = nullptr; 5479 OMPClause *DependSinkClause = nullptr; 5480 bool ErrorFound = false; 5481 OMPThreadsClause *TC = nullptr; 5482 OMPSIMDClause *SC = nullptr; 5483 for (auto *C : Clauses) { 5484 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 5485 DependFound = C; 5486 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 5487 if (DependSourceClause) { 5488 Diag(C->getLocStart(), diag::err_omp_more_one_clause) 5489 << getOpenMPDirectiveName(OMPD_ordered) 5490 << getOpenMPClauseName(OMPC_depend) << 2; 5491 ErrorFound = true; 5492 } else 5493 DependSourceClause = C; 5494 if (DependSinkClause) { 5495 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5496 << 0; 5497 ErrorFound = true; 5498 } 5499 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 5500 if (DependSourceClause) { 5501 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5502 << 1; 5503 ErrorFound = true; 5504 } 5505 DependSinkClause = C; 5506 } 5507 } else if (C->getClauseKind() == OMPC_threads) 5508 TC = cast<OMPThreadsClause>(C); 5509 else if (C->getClauseKind() == OMPC_simd) 5510 SC = cast<OMPSIMDClause>(C); 5511 } 5512 if (!ErrorFound && !SC && 5513 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 5514 // OpenMP [2.8.1,simd Construct, Restrictions] 5515 // An ordered construct with the simd clause is the only OpenMP construct 5516 // that can appear in the simd region. 5517 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 5518 ErrorFound = true; 5519 } else if (DependFound && (TC || SC)) { 5520 Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd) 5521 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 5522 ErrorFound = true; 5523 } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) { 5524 Diag(DependFound->getLocStart(), 5525 diag::err_omp_ordered_directive_without_param); 5526 ErrorFound = true; 5527 } else if (TC || Clauses.empty()) { 5528 if (auto *Param = DSAStack->getParentOrderedRegionParam()) { 5529 SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc; 5530 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 5531 << (TC != nullptr); 5532 Diag(Param->getLocStart(), diag::note_omp_ordered_param); 5533 ErrorFound = true; 5534 } 5535 } 5536 if ((!AStmt && !DependFound) || ErrorFound) 5537 return StmtError(); 5538 5539 if (AStmt) { 5540 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5541 5542 getCurFunction()->setHasBranchProtectedScope(); 5543 } 5544 5545 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5546 } 5547 5548 namespace { 5549 /// \brief Helper class for checking expression in 'omp atomic [update]' 5550 /// construct. 5551 class OpenMPAtomicUpdateChecker { 5552 /// \brief Error results for atomic update expressions. 5553 enum ExprAnalysisErrorCode { 5554 /// \brief A statement is not an expression statement. 5555 NotAnExpression, 5556 /// \brief Expression is not builtin binary or unary operation. 5557 NotABinaryOrUnaryExpression, 5558 /// \brief Unary operation is not post-/pre- increment/decrement operation. 5559 NotAnUnaryIncDecExpression, 5560 /// \brief An expression is not of scalar type. 5561 NotAScalarType, 5562 /// \brief A binary operation is not an assignment operation. 5563 NotAnAssignmentOp, 5564 /// \brief RHS part of the binary operation is not a binary expression. 5565 NotABinaryExpression, 5566 /// \brief RHS part is not additive/multiplicative/shift/biwise binary 5567 /// expression. 5568 NotABinaryOperator, 5569 /// \brief RHS binary operation does not have reference to the updated LHS 5570 /// part. 5571 NotAnUpdateExpression, 5572 /// \brief No errors is found. 5573 NoError 5574 }; 5575 /// \brief Reference to Sema. 5576 Sema &SemaRef; 5577 /// \brief A location for note diagnostics (when error is found). 5578 SourceLocation NoteLoc; 5579 /// \brief 'x' lvalue part of the source atomic expression. 5580 Expr *X; 5581 /// \brief 'expr' rvalue part of the source atomic expression. 5582 Expr *E; 5583 /// \brief Helper expression of the form 5584 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5585 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5586 Expr *UpdateExpr; 5587 /// \brief Is 'x' a LHS in a RHS part of full update expression. It is 5588 /// important for non-associative operations. 5589 bool IsXLHSInRHSPart; 5590 BinaryOperatorKind Op; 5591 SourceLocation OpLoc; 5592 /// \brief true if the source expression is a postfix unary operation, false 5593 /// if it is a prefix unary operation. 5594 bool IsPostfixUpdate; 5595 5596 public: 5597 OpenMPAtomicUpdateChecker(Sema &SemaRef) 5598 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 5599 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 5600 /// \brief Check specified statement that it is suitable for 'atomic update' 5601 /// constructs and extract 'x', 'expr' and Operation from the original 5602 /// expression. If DiagId and NoteId == 0, then only check is performed 5603 /// without error notification. 5604 /// \param DiagId Diagnostic which should be emitted if error is found. 5605 /// \param NoteId Diagnostic note for the main error message. 5606 /// \return true if statement is not an update expression, false otherwise. 5607 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 5608 /// \brief Return the 'x' lvalue part of the source atomic expression. 5609 Expr *getX() const { return X; } 5610 /// \brief Return the 'expr' rvalue part of the source atomic expression. 5611 Expr *getExpr() const { return E; } 5612 /// \brief Return the update expression used in calculation of the updated 5613 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5614 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5615 Expr *getUpdateExpr() const { return UpdateExpr; } 5616 /// \brief Return true if 'x' is LHS in RHS part of full update expression, 5617 /// false otherwise. 5618 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 5619 5620 /// \brief true if the source expression is a postfix unary operation, false 5621 /// if it is a prefix unary operation. 5622 bool isPostfixUpdate() const { return IsPostfixUpdate; } 5623 5624 private: 5625 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 5626 unsigned NoteId = 0); 5627 }; 5628 } // namespace 5629 5630 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 5631 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 5632 ExprAnalysisErrorCode ErrorFound = NoError; 5633 SourceLocation ErrorLoc, NoteLoc; 5634 SourceRange ErrorRange, NoteRange; 5635 // Allowed constructs are: 5636 // x = x binop expr; 5637 // x = expr binop x; 5638 if (AtomicBinOp->getOpcode() == BO_Assign) { 5639 X = AtomicBinOp->getLHS(); 5640 if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 5641 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 5642 if (AtomicInnerBinOp->isMultiplicativeOp() || 5643 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 5644 AtomicInnerBinOp->isBitwiseOp()) { 5645 Op = AtomicInnerBinOp->getOpcode(); 5646 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 5647 auto *LHS = AtomicInnerBinOp->getLHS(); 5648 auto *RHS = AtomicInnerBinOp->getRHS(); 5649 llvm::FoldingSetNodeID XId, LHSId, RHSId; 5650 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 5651 /*Canonical=*/true); 5652 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 5653 /*Canonical=*/true); 5654 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 5655 /*Canonical=*/true); 5656 if (XId == LHSId) { 5657 E = RHS; 5658 IsXLHSInRHSPart = true; 5659 } else if (XId == RHSId) { 5660 E = LHS; 5661 IsXLHSInRHSPart = false; 5662 } else { 5663 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5664 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5665 NoteLoc = X->getExprLoc(); 5666 NoteRange = X->getSourceRange(); 5667 ErrorFound = NotAnUpdateExpression; 5668 } 5669 } else { 5670 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5671 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5672 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 5673 NoteRange = SourceRange(NoteLoc, NoteLoc); 5674 ErrorFound = NotABinaryOperator; 5675 } 5676 } else { 5677 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 5678 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 5679 ErrorFound = NotABinaryExpression; 5680 } 5681 } else { 5682 ErrorLoc = AtomicBinOp->getExprLoc(); 5683 ErrorRange = AtomicBinOp->getSourceRange(); 5684 NoteLoc = AtomicBinOp->getOperatorLoc(); 5685 NoteRange = SourceRange(NoteLoc, NoteLoc); 5686 ErrorFound = NotAnAssignmentOp; 5687 } 5688 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5689 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5690 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5691 return true; 5692 } else if (SemaRef.CurContext->isDependentContext()) 5693 E = X = UpdateExpr = nullptr; 5694 return ErrorFound != NoError; 5695 } 5696 5697 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 5698 unsigned NoteId) { 5699 ExprAnalysisErrorCode ErrorFound = NoError; 5700 SourceLocation ErrorLoc, NoteLoc; 5701 SourceRange ErrorRange, NoteRange; 5702 // Allowed constructs are: 5703 // x++; 5704 // x--; 5705 // ++x; 5706 // --x; 5707 // x binop= expr; 5708 // x = x binop expr; 5709 // x = expr binop x; 5710 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 5711 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 5712 if (AtomicBody->getType()->isScalarType() || 5713 AtomicBody->isInstantiationDependent()) { 5714 if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 5715 AtomicBody->IgnoreParenImpCasts())) { 5716 // Check for Compound Assignment Operation 5717 Op = BinaryOperator::getOpForCompoundAssignment( 5718 AtomicCompAssignOp->getOpcode()); 5719 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 5720 E = AtomicCompAssignOp->getRHS(); 5721 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 5722 IsXLHSInRHSPart = true; 5723 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 5724 AtomicBody->IgnoreParenImpCasts())) { 5725 // Check for Binary Operation 5726 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 5727 return true; 5728 } else if (auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 5729 AtomicBody->IgnoreParenImpCasts())) { 5730 // Check for Unary Operation 5731 if (AtomicUnaryOp->isIncrementDecrementOp()) { 5732 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 5733 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 5734 OpLoc = AtomicUnaryOp->getOperatorLoc(); 5735 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 5736 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 5737 IsXLHSInRHSPart = true; 5738 } else { 5739 ErrorFound = NotAnUnaryIncDecExpression; 5740 ErrorLoc = AtomicUnaryOp->getExprLoc(); 5741 ErrorRange = AtomicUnaryOp->getSourceRange(); 5742 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 5743 NoteRange = SourceRange(NoteLoc, NoteLoc); 5744 } 5745 } else if (!AtomicBody->isInstantiationDependent()) { 5746 ErrorFound = NotABinaryOrUnaryExpression; 5747 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 5748 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 5749 } 5750 } else { 5751 ErrorFound = NotAScalarType; 5752 NoteLoc = ErrorLoc = AtomicBody->getLocStart(); 5753 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5754 } 5755 } else { 5756 ErrorFound = NotAnExpression; 5757 NoteLoc = ErrorLoc = S->getLocStart(); 5758 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5759 } 5760 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5761 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5762 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5763 return true; 5764 } else if (SemaRef.CurContext->isDependentContext()) 5765 E = X = UpdateExpr = nullptr; 5766 if (ErrorFound == NoError && E && X) { 5767 // Build an update expression of form 'OpaqueValueExpr(x) binop 5768 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 5769 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 5770 auto *OVEX = new (SemaRef.getASTContext()) 5771 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 5772 auto *OVEExpr = new (SemaRef.getASTContext()) 5773 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 5774 auto Update = 5775 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 5776 IsXLHSInRHSPart ? OVEExpr : OVEX); 5777 if (Update.isInvalid()) 5778 return true; 5779 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 5780 Sema::AA_Casting); 5781 if (Update.isInvalid()) 5782 return true; 5783 UpdateExpr = Update.get(); 5784 } 5785 return ErrorFound != NoError; 5786 } 5787 5788 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 5789 Stmt *AStmt, 5790 SourceLocation StartLoc, 5791 SourceLocation EndLoc) { 5792 if (!AStmt) 5793 return StmtError(); 5794 5795 auto *CS = cast<CapturedStmt>(AStmt); 5796 // 1.2.2 OpenMP Language Terminology 5797 // Structured block - An executable statement with a single entry at the 5798 // top and a single exit at the bottom. 5799 // The point of exit cannot be a branch out of the structured block. 5800 // longjmp() and throw() must not violate the entry/exit criteria. 5801 OpenMPClauseKind AtomicKind = OMPC_unknown; 5802 SourceLocation AtomicKindLoc; 5803 for (auto *C : Clauses) { 5804 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 5805 C->getClauseKind() == OMPC_update || 5806 C->getClauseKind() == OMPC_capture) { 5807 if (AtomicKind != OMPC_unknown) { 5808 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) 5809 << SourceRange(C->getLocStart(), C->getLocEnd()); 5810 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 5811 << getOpenMPClauseName(AtomicKind); 5812 } else { 5813 AtomicKind = C->getClauseKind(); 5814 AtomicKindLoc = C->getLocStart(); 5815 } 5816 } 5817 } 5818 5819 auto Body = CS->getCapturedStmt(); 5820 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 5821 Body = EWC->getSubExpr(); 5822 5823 Expr *X = nullptr; 5824 Expr *V = nullptr; 5825 Expr *E = nullptr; 5826 Expr *UE = nullptr; 5827 bool IsXLHSInRHSPart = false; 5828 bool IsPostfixUpdate = false; 5829 // OpenMP [2.12.6, atomic Construct] 5830 // In the next expressions: 5831 // * x and v (as applicable) are both l-value expressions with scalar type. 5832 // * During the execution of an atomic region, multiple syntactic 5833 // occurrences of x must designate the same storage location. 5834 // * Neither of v and expr (as applicable) may access the storage location 5835 // designated by x. 5836 // * Neither of x and expr (as applicable) may access the storage location 5837 // designated by v. 5838 // * expr is an expression with scalar type. 5839 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 5840 // * binop, binop=, ++, and -- are not overloaded operators. 5841 // * The expression x binop expr must be numerically equivalent to x binop 5842 // (expr). This requirement is satisfied if the operators in expr have 5843 // precedence greater than binop, or by using parentheses around expr or 5844 // subexpressions of expr. 5845 // * The expression expr binop x must be numerically equivalent to (expr) 5846 // binop x. This requirement is satisfied if the operators in expr have 5847 // precedence equal to or greater than binop, or by using parentheses around 5848 // expr or subexpressions of expr. 5849 // * For forms that allow multiple occurrences of x, the number of times 5850 // that x is evaluated is unspecified. 5851 if (AtomicKind == OMPC_read) { 5852 enum { 5853 NotAnExpression, 5854 NotAnAssignmentOp, 5855 NotAScalarType, 5856 NotAnLValue, 5857 NoError 5858 } ErrorFound = NoError; 5859 SourceLocation ErrorLoc, NoteLoc; 5860 SourceRange ErrorRange, NoteRange; 5861 // If clause is read: 5862 // v = x; 5863 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 5864 auto *AtomicBinOp = 5865 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5866 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5867 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 5868 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 5869 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 5870 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 5871 if (!X->isLValue() || !V->isLValue()) { 5872 auto NotLValueExpr = X->isLValue() ? V : X; 5873 ErrorFound = NotAnLValue; 5874 ErrorLoc = AtomicBinOp->getExprLoc(); 5875 ErrorRange = AtomicBinOp->getSourceRange(); 5876 NoteLoc = NotLValueExpr->getExprLoc(); 5877 NoteRange = NotLValueExpr->getSourceRange(); 5878 } 5879 } else if (!X->isInstantiationDependent() || 5880 !V->isInstantiationDependent()) { 5881 auto NotScalarExpr = 5882 (X->isInstantiationDependent() || X->getType()->isScalarType()) 5883 ? V 5884 : X; 5885 ErrorFound = NotAScalarType; 5886 ErrorLoc = AtomicBinOp->getExprLoc(); 5887 ErrorRange = AtomicBinOp->getSourceRange(); 5888 NoteLoc = NotScalarExpr->getExprLoc(); 5889 NoteRange = NotScalarExpr->getSourceRange(); 5890 } 5891 } else if (!AtomicBody->isInstantiationDependent()) { 5892 ErrorFound = NotAnAssignmentOp; 5893 ErrorLoc = AtomicBody->getExprLoc(); 5894 ErrorRange = AtomicBody->getSourceRange(); 5895 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5896 : AtomicBody->getExprLoc(); 5897 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5898 : AtomicBody->getSourceRange(); 5899 } 5900 } else { 5901 ErrorFound = NotAnExpression; 5902 NoteLoc = ErrorLoc = Body->getLocStart(); 5903 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5904 } 5905 if (ErrorFound != NoError) { 5906 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 5907 << ErrorRange; 5908 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 5909 << NoteRange; 5910 return StmtError(); 5911 } else if (CurContext->isDependentContext()) 5912 V = X = nullptr; 5913 } else if (AtomicKind == OMPC_write) { 5914 enum { 5915 NotAnExpression, 5916 NotAnAssignmentOp, 5917 NotAScalarType, 5918 NotAnLValue, 5919 NoError 5920 } ErrorFound = NoError; 5921 SourceLocation ErrorLoc, NoteLoc; 5922 SourceRange ErrorRange, NoteRange; 5923 // If clause is write: 5924 // x = expr; 5925 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 5926 auto *AtomicBinOp = 5927 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5928 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5929 X = AtomicBinOp->getLHS(); 5930 E = AtomicBinOp->getRHS(); 5931 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 5932 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 5933 if (!X->isLValue()) { 5934 ErrorFound = NotAnLValue; 5935 ErrorLoc = AtomicBinOp->getExprLoc(); 5936 ErrorRange = AtomicBinOp->getSourceRange(); 5937 NoteLoc = X->getExprLoc(); 5938 NoteRange = X->getSourceRange(); 5939 } 5940 } else if (!X->isInstantiationDependent() || 5941 !E->isInstantiationDependent()) { 5942 auto NotScalarExpr = 5943 (X->isInstantiationDependent() || X->getType()->isScalarType()) 5944 ? E 5945 : X; 5946 ErrorFound = NotAScalarType; 5947 ErrorLoc = AtomicBinOp->getExprLoc(); 5948 ErrorRange = AtomicBinOp->getSourceRange(); 5949 NoteLoc = NotScalarExpr->getExprLoc(); 5950 NoteRange = NotScalarExpr->getSourceRange(); 5951 } 5952 } else if (!AtomicBody->isInstantiationDependent()) { 5953 ErrorFound = NotAnAssignmentOp; 5954 ErrorLoc = AtomicBody->getExprLoc(); 5955 ErrorRange = AtomicBody->getSourceRange(); 5956 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5957 : AtomicBody->getExprLoc(); 5958 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5959 : AtomicBody->getSourceRange(); 5960 } 5961 } else { 5962 ErrorFound = NotAnExpression; 5963 NoteLoc = ErrorLoc = Body->getLocStart(); 5964 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5965 } 5966 if (ErrorFound != NoError) { 5967 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 5968 << ErrorRange; 5969 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 5970 << NoteRange; 5971 return StmtError(); 5972 } else if (CurContext->isDependentContext()) 5973 E = X = nullptr; 5974 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 5975 // If clause is update: 5976 // x++; 5977 // x--; 5978 // ++x; 5979 // --x; 5980 // x binop= expr; 5981 // x = x binop expr; 5982 // x = expr binop x; 5983 OpenMPAtomicUpdateChecker Checker(*this); 5984 if (Checker.checkStatement( 5985 Body, (AtomicKind == OMPC_update) 5986 ? diag::err_omp_atomic_update_not_expression_statement 5987 : diag::err_omp_atomic_not_expression_statement, 5988 diag::note_omp_atomic_update)) 5989 return StmtError(); 5990 if (!CurContext->isDependentContext()) { 5991 E = Checker.getExpr(); 5992 X = Checker.getX(); 5993 UE = Checker.getUpdateExpr(); 5994 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5995 } 5996 } else if (AtomicKind == OMPC_capture) { 5997 enum { 5998 NotAnAssignmentOp, 5999 NotACompoundStatement, 6000 NotTwoSubstatements, 6001 NotASpecificExpression, 6002 NoError 6003 } ErrorFound = NoError; 6004 SourceLocation ErrorLoc, NoteLoc; 6005 SourceRange ErrorRange, NoteRange; 6006 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 6007 // If clause is a capture: 6008 // v = x++; 6009 // v = x--; 6010 // v = ++x; 6011 // v = --x; 6012 // v = x binop= expr; 6013 // v = x = x binop expr; 6014 // v = x = expr binop x; 6015 auto *AtomicBinOp = 6016 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6017 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6018 V = AtomicBinOp->getLHS(); 6019 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6020 OpenMPAtomicUpdateChecker Checker(*this); 6021 if (Checker.checkStatement( 6022 Body, diag::err_omp_atomic_capture_not_expression_statement, 6023 diag::note_omp_atomic_update)) 6024 return StmtError(); 6025 E = Checker.getExpr(); 6026 X = Checker.getX(); 6027 UE = Checker.getUpdateExpr(); 6028 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6029 IsPostfixUpdate = Checker.isPostfixUpdate(); 6030 } else if (!AtomicBody->isInstantiationDependent()) { 6031 ErrorLoc = AtomicBody->getExprLoc(); 6032 ErrorRange = AtomicBody->getSourceRange(); 6033 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6034 : AtomicBody->getExprLoc(); 6035 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6036 : AtomicBody->getSourceRange(); 6037 ErrorFound = NotAnAssignmentOp; 6038 } 6039 if (ErrorFound != NoError) { 6040 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 6041 << ErrorRange; 6042 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6043 return StmtError(); 6044 } else if (CurContext->isDependentContext()) { 6045 UE = V = E = X = nullptr; 6046 } 6047 } else { 6048 // If clause is a capture: 6049 // { v = x; x = expr; } 6050 // { v = x; x++; } 6051 // { v = x; x--; } 6052 // { v = x; ++x; } 6053 // { v = x; --x; } 6054 // { v = x; x binop= expr; } 6055 // { v = x; x = x binop expr; } 6056 // { v = x; x = expr binop x; } 6057 // { x++; v = x; } 6058 // { x--; v = x; } 6059 // { ++x; v = x; } 6060 // { --x; v = x; } 6061 // { x binop= expr; v = x; } 6062 // { x = x binop expr; v = x; } 6063 // { x = expr binop x; v = x; } 6064 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 6065 // Check that this is { expr1; expr2; } 6066 if (CS->size() == 2) { 6067 auto *First = CS->body_front(); 6068 auto *Second = CS->body_back(); 6069 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 6070 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 6071 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 6072 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 6073 // Need to find what subexpression is 'v' and what is 'x'. 6074 OpenMPAtomicUpdateChecker Checker(*this); 6075 bool IsUpdateExprFound = !Checker.checkStatement(Second); 6076 BinaryOperator *BinOp = nullptr; 6077 if (IsUpdateExprFound) { 6078 BinOp = dyn_cast<BinaryOperator>(First); 6079 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6080 } 6081 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6082 // { v = x; x++; } 6083 // { v = x; x--; } 6084 // { v = x; ++x; } 6085 // { v = x; --x; } 6086 // { v = x; x binop= expr; } 6087 // { v = x; x = x binop expr; } 6088 // { v = x; x = expr binop x; } 6089 // Check that the first expression has form v = x. 6090 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6091 llvm::FoldingSetNodeID XId, PossibleXId; 6092 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6093 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6094 IsUpdateExprFound = XId == PossibleXId; 6095 if (IsUpdateExprFound) { 6096 V = BinOp->getLHS(); 6097 X = Checker.getX(); 6098 E = Checker.getExpr(); 6099 UE = Checker.getUpdateExpr(); 6100 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6101 IsPostfixUpdate = true; 6102 } 6103 } 6104 if (!IsUpdateExprFound) { 6105 IsUpdateExprFound = !Checker.checkStatement(First); 6106 BinOp = nullptr; 6107 if (IsUpdateExprFound) { 6108 BinOp = dyn_cast<BinaryOperator>(Second); 6109 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6110 } 6111 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6112 // { x++; v = x; } 6113 // { x--; v = x; } 6114 // { ++x; v = x; } 6115 // { --x; v = x; } 6116 // { x binop= expr; v = x; } 6117 // { x = x binop expr; v = x; } 6118 // { x = expr binop x; v = x; } 6119 // Check that the second expression has form v = x. 6120 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6121 llvm::FoldingSetNodeID XId, PossibleXId; 6122 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6123 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6124 IsUpdateExprFound = XId == PossibleXId; 6125 if (IsUpdateExprFound) { 6126 V = BinOp->getLHS(); 6127 X = Checker.getX(); 6128 E = Checker.getExpr(); 6129 UE = Checker.getUpdateExpr(); 6130 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6131 IsPostfixUpdate = false; 6132 } 6133 } 6134 } 6135 if (!IsUpdateExprFound) { 6136 // { v = x; x = expr; } 6137 auto *FirstExpr = dyn_cast<Expr>(First); 6138 auto *SecondExpr = dyn_cast<Expr>(Second); 6139 if (!FirstExpr || !SecondExpr || 6140 !(FirstExpr->isInstantiationDependent() || 6141 SecondExpr->isInstantiationDependent())) { 6142 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 6143 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 6144 ErrorFound = NotAnAssignmentOp; 6145 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 6146 : First->getLocStart(); 6147 NoteRange = ErrorRange = FirstBinOp 6148 ? FirstBinOp->getSourceRange() 6149 : SourceRange(ErrorLoc, ErrorLoc); 6150 } else { 6151 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 6152 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 6153 ErrorFound = NotAnAssignmentOp; 6154 NoteLoc = ErrorLoc = SecondBinOp 6155 ? SecondBinOp->getOperatorLoc() 6156 : Second->getLocStart(); 6157 NoteRange = ErrorRange = 6158 SecondBinOp ? SecondBinOp->getSourceRange() 6159 : SourceRange(ErrorLoc, ErrorLoc); 6160 } else { 6161 auto *PossibleXRHSInFirst = 6162 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 6163 auto *PossibleXLHSInSecond = 6164 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 6165 llvm::FoldingSetNodeID X1Id, X2Id; 6166 PossibleXRHSInFirst->Profile(X1Id, Context, 6167 /*Canonical=*/true); 6168 PossibleXLHSInSecond->Profile(X2Id, Context, 6169 /*Canonical=*/true); 6170 IsUpdateExprFound = X1Id == X2Id; 6171 if (IsUpdateExprFound) { 6172 V = FirstBinOp->getLHS(); 6173 X = SecondBinOp->getLHS(); 6174 E = SecondBinOp->getRHS(); 6175 UE = nullptr; 6176 IsXLHSInRHSPart = false; 6177 IsPostfixUpdate = true; 6178 } else { 6179 ErrorFound = NotASpecificExpression; 6180 ErrorLoc = FirstBinOp->getExprLoc(); 6181 ErrorRange = FirstBinOp->getSourceRange(); 6182 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 6183 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 6184 } 6185 } 6186 } 6187 } 6188 } 6189 } else { 6190 NoteLoc = ErrorLoc = Body->getLocStart(); 6191 NoteRange = ErrorRange = 6192 SourceRange(Body->getLocStart(), Body->getLocStart()); 6193 ErrorFound = NotTwoSubstatements; 6194 } 6195 } else { 6196 NoteLoc = ErrorLoc = Body->getLocStart(); 6197 NoteRange = ErrorRange = 6198 SourceRange(Body->getLocStart(), Body->getLocStart()); 6199 ErrorFound = NotACompoundStatement; 6200 } 6201 if (ErrorFound != NoError) { 6202 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 6203 << ErrorRange; 6204 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6205 return StmtError(); 6206 } else if (CurContext->isDependentContext()) { 6207 UE = V = E = X = nullptr; 6208 } 6209 } 6210 } 6211 6212 getCurFunction()->setHasBranchProtectedScope(); 6213 6214 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6215 X, V, E, UE, IsXLHSInRHSPart, 6216 IsPostfixUpdate); 6217 } 6218 6219 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 6220 Stmt *AStmt, 6221 SourceLocation StartLoc, 6222 SourceLocation EndLoc) { 6223 if (!AStmt) 6224 return StmtError(); 6225 6226 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6227 // 1.2.2 OpenMP Language Terminology 6228 // Structured block - An executable statement with a single entry at the 6229 // top and a single exit at the bottom. 6230 // The point of exit cannot be a branch out of the structured block. 6231 // longjmp() and throw() must not violate the entry/exit criteria. 6232 CS->getCapturedDecl()->setNothrow(); 6233 6234 // OpenMP [2.16, Nesting of Regions] 6235 // If specified, a teams construct must be contained within a target 6236 // construct. That target construct must contain no statements or directives 6237 // outside of the teams construct. 6238 if (DSAStack->hasInnerTeamsRegion()) { 6239 auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true); 6240 bool OMPTeamsFound = true; 6241 if (auto *CS = dyn_cast<CompoundStmt>(S)) { 6242 auto I = CS->body_begin(); 6243 while (I != CS->body_end()) { 6244 auto *OED = dyn_cast<OMPExecutableDirective>(*I); 6245 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { 6246 OMPTeamsFound = false; 6247 break; 6248 } 6249 ++I; 6250 } 6251 assert(I != CS->body_end() && "Not found statement"); 6252 S = *I; 6253 } else { 6254 auto *OED = dyn_cast<OMPExecutableDirective>(S); 6255 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 6256 } 6257 if (!OMPTeamsFound) { 6258 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 6259 Diag(DSAStack->getInnerTeamsRegionLoc(), 6260 diag::note_omp_nested_teams_construct_here); 6261 Diag(S->getLocStart(), diag::note_omp_nested_statement_here) 6262 << isa<OMPExecutableDirective>(S); 6263 return StmtError(); 6264 } 6265 } 6266 6267 getCurFunction()->setHasBranchProtectedScope(); 6268 6269 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6270 } 6271 6272 StmtResult 6273 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 6274 Stmt *AStmt, SourceLocation StartLoc, 6275 SourceLocation EndLoc) { 6276 if (!AStmt) 6277 return StmtError(); 6278 6279 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6280 // 1.2.2 OpenMP Language Terminology 6281 // Structured block - An executable statement with a single entry at the 6282 // top and a single exit at the bottom. 6283 // The point of exit cannot be a branch out of the structured block. 6284 // longjmp() and throw() must not violate the entry/exit criteria. 6285 CS->getCapturedDecl()->setNothrow(); 6286 6287 getCurFunction()->setHasBranchProtectedScope(); 6288 6289 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6290 AStmt); 6291 } 6292 6293 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 6294 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6295 SourceLocation EndLoc, 6296 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6297 if (!AStmt) 6298 return StmtError(); 6299 6300 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6301 // 1.2.2 OpenMP Language Terminology 6302 // Structured block - An executable statement with a single entry at the 6303 // top and a single exit at the bottom. 6304 // The point of exit cannot be a branch out of the structured block. 6305 // longjmp() and throw() must not violate the entry/exit criteria. 6306 CS->getCapturedDecl()->setNothrow(); 6307 6308 OMPLoopDirective::HelperExprs B; 6309 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6310 // define the nested loops number. 6311 unsigned NestedLoopCount = 6312 CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 6313 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6314 VarsWithImplicitDSA, B); 6315 if (NestedLoopCount == 0) 6316 return StmtError(); 6317 6318 assert((CurContext->isDependentContext() || B.builtAll()) && 6319 "omp target parallel for loop exprs were not built"); 6320 6321 if (!CurContext->isDependentContext()) { 6322 // Finalize the clauses that need pre-built expressions for CodeGen. 6323 for (auto C : Clauses) { 6324 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6325 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6326 B.NumIterations, *this, CurScope, 6327 DSAStack)) 6328 return StmtError(); 6329 } 6330 } 6331 6332 getCurFunction()->setHasBranchProtectedScope(); 6333 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 6334 NestedLoopCount, Clauses, AStmt, 6335 B, DSAStack->isCancelRegion()); 6336 } 6337 6338 /// Check for existence of a map clause in the list of clauses. 6339 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 6340 const OpenMPClauseKind K) { 6341 return llvm::any_of( 6342 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 6343 } 6344 6345 template <typename... Params> 6346 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 6347 const Params... ClauseTypes) { 6348 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 6349 } 6350 6351 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 6352 Stmt *AStmt, 6353 SourceLocation StartLoc, 6354 SourceLocation EndLoc) { 6355 if (!AStmt) 6356 return StmtError(); 6357 6358 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6359 6360 // OpenMP [2.10.1, Restrictions, p. 97] 6361 // At least one map clause must appear on the directive. 6362 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 6363 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6364 << "'map' or 'use_device_ptr'" 6365 << getOpenMPDirectiveName(OMPD_target_data); 6366 return StmtError(); 6367 } 6368 6369 getCurFunction()->setHasBranchProtectedScope(); 6370 6371 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 6372 AStmt); 6373 } 6374 6375 StmtResult 6376 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 6377 SourceLocation StartLoc, 6378 SourceLocation EndLoc) { 6379 // OpenMP [2.10.2, Restrictions, p. 99] 6380 // At least one map clause must appear on the directive. 6381 if (!hasClauses(Clauses, OMPC_map)) { 6382 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6383 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 6384 return StmtError(); 6385 } 6386 6387 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, 6388 Clauses); 6389 } 6390 6391 StmtResult 6392 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 6393 SourceLocation StartLoc, 6394 SourceLocation EndLoc) { 6395 // OpenMP [2.10.3, Restrictions, p. 102] 6396 // At least one map clause must appear on the directive. 6397 if (!hasClauses(Clauses, OMPC_map)) { 6398 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6399 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 6400 return StmtError(); 6401 } 6402 6403 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses); 6404 } 6405 6406 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 6407 SourceLocation StartLoc, 6408 SourceLocation EndLoc) { 6409 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 6410 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 6411 return StmtError(); 6412 } 6413 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses); 6414 } 6415 6416 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 6417 Stmt *AStmt, SourceLocation StartLoc, 6418 SourceLocation EndLoc) { 6419 if (!AStmt) 6420 return StmtError(); 6421 6422 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6423 // 1.2.2 OpenMP Language Terminology 6424 // Structured block - An executable statement with a single entry at the 6425 // top and a single exit at the bottom. 6426 // The point of exit cannot be a branch out of the structured block. 6427 // longjmp() and throw() must not violate the entry/exit criteria. 6428 CS->getCapturedDecl()->setNothrow(); 6429 6430 getCurFunction()->setHasBranchProtectedScope(); 6431 6432 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6433 } 6434 6435 StmtResult 6436 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 6437 SourceLocation EndLoc, 6438 OpenMPDirectiveKind CancelRegion) { 6439 if (DSAStack->isParentNowaitRegion()) { 6440 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 6441 return StmtError(); 6442 } 6443 if (DSAStack->isParentOrderedRegion()) { 6444 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 6445 return StmtError(); 6446 } 6447 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 6448 CancelRegion); 6449 } 6450 6451 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 6452 SourceLocation StartLoc, 6453 SourceLocation EndLoc, 6454 OpenMPDirectiveKind CancelRegion) { 6455 if (DSAStack->isParentNowaitRegion()) { 6456 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 6457 return StmtError(); 6458 } 6459 if (DSAStack->isParentOrderedRegion()) { 6460 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 6461 return StmtError(); 6462 } 6463 DSAStack->setParentCancelRegion(/*Cancel=*/true); 6464 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6465 CancelRegion); 6466 } 6467 6468 static bool checkGrainsizeNumTasksClauses(Sema &S, 6469 ArrayRef<OMPClause *> Clauses) { 6470 OMPClause *PrevClause = nullptr; 6471 bool ErrorFound = false; 6472 for (auto *C : Clauses) { 6473 if (C->getClauseKind() == OMPC_grainsize || 6474 C->getClauseKind() == OMPC_num_tasks) { 6475 if (!PrevClause) 6476 PrevClause = C; 6477 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 6478 S.Diag(C->getLocStart(), 6479 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 6480 << getOpenMPClauseName(C->getClauseKind()) 6481 << getOpenMPClauseName(PrevClause->getClauseKind()); 6482 S.Diag(PrevClause->getLocStart(), 6483 diag::note_omp_previous_grainsize_num_tasks) 6484 << getOpenMPClauseName(PrevClause->getClauseKind()); 6485 ErrorFound = true; 6486 } 6487 } 6488 } 6489 return ErrorFound; 6490 } 6491 6492 static bool checkReductionClauseWithNogroup(Sema &S, 6493 ArrayRef<OMPClause *> Clauses) { 6494 OMPClause *ReductionClause = nullptr; 6495 OMPClause *NogroupClause = nullptr; 6496 for (auto *C : Clauses) { 6497 if (C->getClauseKind() == OMPC_reduction) { 6498 ReductionClause = C; 6499 if (NogroupClause) 6500 break; 6501 continue; 6502 } 6503 if (C->getClauseKind() == OMPC_nogroup) { 6504 NogroupClause = C; 6505 if (ReductionClause) 6506 break; 6507 continue; 6508 } 6509 } 6510 if (ReductionClause && NogroupClause) { 6511 S.Diag(ReductionClause->getLocStart(), diag::err_omp_reduction_with_nogroup) 6512 << SourceRange(NogroupClause->getLocStart(), 6513 NogroupClause->getLocEnd()); 6514 return true; 6515 } 6516 return false; 6517 } 6518 6519 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 6520 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6521 SourceLocation EndLoc, 6522 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6523 if (!AStmt) 6524 return StmtError(); 6525 6526 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6527 OMPLoopDirective::HelperExprs B; 6528 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6529 // define the nested loops number. 6530 unsigned NestedLoopCount = 6531 CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 6532 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6533 VarsWithImplicitDSA, B); 6534 if (NestedLoopCount == 0) 6535 return StmtError(); 6536 6537 assert((CurContext->isDependentContext() || B.builtAll()) && 6538 "omp for loop exprs were not built"); 6539 6540 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6541 // The grainsize clause and num_tasks clause are mutually exclusive and may 6542 // not appear on the same taskloop directive. 6543 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6544 return StmtError(); 6545 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6546 // If a reduction clause is present on the taskloop directive, the nogroup 6547 // clause must not be specified. 6548 if (checkReductionClauseWithNogroup(*this, Clauses)) 6549 return StmtError(); 6550 6551 getCurFunction()->setHasBranchProtectedScope(); 6552 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 6553 NestedLoopCount, Clauses, AStmt, B); 6554 } 6555 6556 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 6557 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6558 SourceLocation EndLoc, 6559 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6560 if (!AStmt) 6561 return StmtError(); 6562 6563 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6564 OMPLoopDirective::HelperExprs B; 6565 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6566 // define the nested loops number. 6567 unsigned NestedLoopCount = 6568 CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 6569 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6570 VarsWithImplicitDSA, B); 6571 if (NestedLoopCount == 0) 6572 return StmtError(); 6573 6574 assert((CurContext->isDependentContext() || B.builtAll()) && 6575 "omp for loop exprs were not built"); 6576 6577 if (!CurContext->isDependentContext()) { 6578 // Finalize the clauses that need pre-built expressions for CodeGen. 6579 for (auto C : Clauses) { 6580 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6581 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6582 B.NumIterations, *this, CurScope, 6583 DSAStack)) 6584 return StmtError(); 6585 } 6586 } 6587 6588 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6589 // The grainsize clause and num_tasks clause are mutually exclusive and may 6590 // not appear on the same taskloop directive. 6591 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6592 return StmtError(); 6593 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6594 // If a reduction clause is present on the taskloop directive, the nogroup 6595 // clause must not be specified. 6596 if (checkReductionClauseWithNogroup(*this, Clauses)) 6597 return StmtError(); 6598 6599 getCurFunction()->setHasBranchProtectedScope(); 6600 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 6601 NestedLoopCount, Clauses, AStmt, B); 6602 } 6603 6604 StmtResult Sema::ActOnOpenMPDistributeDirective( 6605 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6606 SourceLocation EndLoc, 6607 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6608 if (!AStmt) 6609 return StmtError(); 6610 6611 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6612 OMPLoopDirective::HelperExprs B; 6613 // In presence of clause 'collapse' with number of loops, it will 6614 // define the nested loops number. 6615 unsigned NestedLoopCount = 6616 CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 6617 nullptr /*ordered not a clause on distribute*/, AStmt, 6618 *this, *DSAStack, VarsWithImplicitDSA, B); 6619 if (NestedLoopCount == 0) 6620 return StmtError(); 6621 6622 assert((CurContext->isDependentContext() || B.builtAll()) && 6623 "omp for loop exprs were not built"); 6624 6625 getCurFunction()->setHasBranchProtectedScope(); 6626 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 6627 NestedLoopCount, Clauses, AStmt, B); 6628 } 6629 6630 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 6631 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6632 SourceLocation EndLoc, 6633 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6634 if (!AStmt) 6635 return StmtError(); 6636 6637 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6638 // 1.2.2 OpenMP Language Terminology 6639 // Structured block - An executable statement with a single entry at the 6640 // top and a single exit at the bottom. 6641 // The point of exit cannot be a branch out of the structured block. 6642 // longjmp() and throw() must not violate the entry/exit criteria. 6643 CS->getCapturedDecl()->setNothrow(); 6644 6645 OMPLoopDirective::HelperExprs B; 6646 // In presence of clause 'collapse' with number of loops, it will 6647 // define the nested loops number. 6648 unsigned NestedLoopCount = CheckOpenMPLoop( 6649 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 6650 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6651 VarsWithImplicitDSA, B); 6652 if (NestedLoopCount == 0) 6653 return StmtError(); 6654 6655 assert((CurContext->isDependentContext() || B.builtAll()) && 6656 "omp for loop exprs were not built"); 6657 6658 getCurFunction()->setHasBranchProtectedScope(); 6659 return OMPDistributeParallelForDirective::Create( 6660 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6661 } 6662 6663 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 6664 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6665 SourceLocation EndLoc, 6666 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6667 if (!AStmt) 6668 return StmtError(); 6669 6670 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6671 // 1.2.2 OpenMP Language Terminology 6672 // Structured block - An executable statement with a single entry at the 6673 // top and a single exit at the bottom. 6674 // The point of exit cannot be a branch out of the structured block. 6675 // longjmp() and throw() must not violate the entry/exit criteria. 6676 CS->getCapturedDecl()->setNothrow(); 6677 6678 OMPLoopDirective::HelperExprs B; 6679 // In presence of clause 'collapse' with number of loops, it will 6680 // define the nested loops number. 6681 unsigned NestedLoopCount = CheckOpenMPLoop( 6682 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 6683 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6684 VarsWithImplicitDSA, B); 6685 if (NestedLoopCount == 0) 6686 return StmtError(); 6687 6688 assert((CurContext->isDependentContext() || B.builtAll()) && 6689 "omp for loop exprs were not built"); 6690 6691 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6692 return StmtError(); 6693 6694 getCurFunction()->setHasBranchProtectedScope(); 6695 return OMPDistributeParallelForSimdDirective::Create( 6696 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6697 } 6698 6699 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 6700 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6701 SourceLocation EndLoc, 6702 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6703 if (!AStmt) 6704 return StmtError(); 6705 6706 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6707 // 1.2.2 OpenMP Language Terminology 6708 // Structured block - An executable statement with a single entry at the 6709 // top and a single exit at the bottom. 6710 // The point of exit cannot be a branch out of the structured block. 6711 // longjmp() and throw() must not violate the entry/exit criteria. 6712 CS->getCapturedDecl()->setNothrow(); 6713 6714 OMPLoopDirective::HelperExprs B; 6715 // In presence of clause 'collapse' with number of loops, it will 6716 // define the nested loops number. 6717 unsigned NestedLoopCount = 6718 CheckOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 6719 nullptr /*ordered not a clause on distribute*/, AStmt, 6720 *this, *DSAStack, VarsWithImplicitDSA, B); 6721 if (NestedLoopCount == 0) 6722 return StmtError(); 6723 6724 assert((CurContext->isDependentContext() || B.builtAll()) && 6725 "omp for loop exprs were not built"); 6726 6727 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6728 return StmtError(); 6729 6730 getCurFunction()->setHasBranchProtectedScope(); 6731 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 6732 NestedLoopCount, Clauses, AStmt, B); 6733 } 6734 6735 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 6736 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6737 SourceLocation EndLoc, 6738 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6739 if (!AStmt) 6740 return StmtError(); 6741 6742 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6743 // 1.2.2 OpenMP Language Terminology 6744 // Structured block - An executable statement with a single entry at the 6745 // top and a single exit at the bottom. 6746 // The point of exit cannot be a branch out of the structured block. 6747 // longjmp() and throw() must not violate the entry/exit criteria. 6748 CS->getCapturedDecl()->setNothrow(); 6749 6750 OMPLoopDirective::HelperExprs B; 6751 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6752 // define the nested loops number. 6753 unsigned NestedLoopCount = CheckOpenMPLoop( 6754 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 6755 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6756 VarsWithImplicitDSA, B); 6757 if (NestedLoopCount == 0) 6758 return StmtError(); 6759 6760 assert((CurContext->isDependentContext() || B.builtAll()) && 6761 "omp target parallel for simd loop exprs were not built"); 6762 6763 if (!CurContext->isDependentContext()) { 6764 // Finalize the clauses that need pre-built expressions for CodeGen. 6765 for (auto C : Clauses) { 6766 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6767 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6768 B.NumIterations, *this, CurScope, 6769 DSAStack)) 6770 return StmtError(); 6771 } 6772 } 6773 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6774 return StmtError(); 6775 6776 getCurFunction()->setHasBranchProtectedScope(); 6777 return OMPTargetParallelForSimdDirective::Create( 6778 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6779 } 6780 6781 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 6782 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6783 SourceLocation EndLoc, 6784 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6785 if (!AStmt) 6786 return StmtError(); 6787 6788 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6789 // 1.2.2 OpenMP Language Terminology 6790 // Structured block - An executable statement with a single entry at the 6791 // top and a single exit at the bottom. 6792 // The point of exit cannot be a branch out of the structured block. 6793 // longjmp() and throw() must not violate the entry/exit criteria. 6794 CS->getCapturedDecl()->setNothrow(); 6795 6796 OMPLoopDirective::HelperExprs B; 6797 // In presence of clause 'collapse' with number of loops, it will define the 6798 // nested loops number. 6799 unsigned NestedLoopCount = 6800 CheckOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 6801 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6802 VarsWithImplicitDSA, B); 6803 if (NestedLoopCount == 0) 6804 return StmtError(); 6805 6806 assert((CurContext->isDependentContext() || B.builtAll()) && 6807 "omp target simd loop exprs were not built"); 6808 6809 if (!CurContext->isDependentContext()) { 6810 // Finalize the clauses that need pre-built expressions for CodeGen. 6811 for (auto C : Clauses) { 6812 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6813 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6814 B.NumIterations, *this, CurScope, 6815 DSAStack)) 6816 return StmtError(); 6817 } 6818 } 6819 6820 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6821 return StmtError(); 6822 6823 getCurFunction()->setHasBranchProtectedScope(); 6824 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 6825 NestedLoopCount, Clauses, AStmt, B); 6826 } 6827 6828 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 6829 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6830 SourceLocation EndLoc, 6831 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6832 if (!AStmt) 6833 return StmtError(); 6834 6835 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6836 // 1.2.2 OpenMP Language Terminology 6837 // Structured block - An executable statement with a single entry at the 6838 // top and a single exit at the bottom. 6839 // The point of exit cannot be a branch out of the structured block. 6840 // longjmp() and throw() must not violate the entry/exit criteria. 6841 CS->getCapturedDecl()->setNothrow(); 6842 6843 OMPLoopDirective::HelperExprs B; 6844 // In presence of clause 'collapse' with number of loops, it will 6845 // define the nested loops number. 6846 unsigned NestedLoopCount = 6847 CheckOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 6848 nullptr /*ordered not a clause on distribute*/, AStmt, 6849 *this, *DSAStack, VarsWithImplicitDSA, B); 6850 if (NestedLoopCount == 0) 6851 return StmtError(); 6852 6853 assert((CurContext->isDependentContext() || B.builtAll()) && 6854 "omp teams distribute loop exprs were not built"); 6855 6856 getCurFunction()->setHasBranchProtectedScope(); 6857 return OMPTeamsDistributeDirective::Create( 6858 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6859 } 6860 6861 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 6862 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6863 SourceLocation EndLoc, 6864 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6865 if (!AStmt) 6866 return StmtError(); 6867 6868 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6869 // 1.2.2 OpenMP Language Terminology 6870 // Structured block - An executable statement with a single entry at the 6871 // top and a single exit at the bottom. 6872 // The point of exit cannot be a branch out of the structured block. 6873 // longjmp() and throw() must not violate the entry/exit criteria. 6874 CS->getCapturedDecl()->setNothrow(); 6875 6876 OMPLoopDirective::HelperExprs B; 6877 // In presence of clause 'collapse' with number of loops, it will 6878 // define the nested loops number. 6879 unsigned NestedLoopCount = CheckOpenMPLoop( 6880 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 6881 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6882 VarsWithImplicitDSA, B); 6883 6884 if (NestedLoopCount == 0) 6885 return StmtError(); 6886 6887 assert((CurContext->isDependentContext() || B.builtAll()) && 6888 "omp teams distribute simd loop exprs were not built"); 6889 6890 if (!CurContext->isDependentContext()) { 6891 // Finalize the clauses that need pre-built expressions for CodeGen. 6892 for (auto C : Clauses) { 6893 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6894 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6895 B.NumIterations, *this, CurScope, 6896 DSAStack)) 6897 return StmtError(); 6898 } 6899 } 6900 6901 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6902 return StmtError(); 6903 6904 getCurFunction()->setHasBranchProtectedScope(); 6905 return OMPTeamsDistributeSimdDirective::Create( 6906 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6907 } 6908 6909 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 6910 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6911 SourceLocation EndLoc, 6912 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6913 if (!AStmt) 6914 return StmtError(); 6915 6916 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6917 // 1.2.2 OpenMP Language Terminology 6918 // Structured block - An executable statement with a single entry at the 6919 // top and a single exit at the bottom. 6920 // The point of exit cannot be a branch out of the structured block. 6921 // longjmp() and throw() must not violate the entry/exit criteria. 6922 CS->getCapturedDecl()->setNothrow(); 6923 6924 OMPLoopDirective::HelperExprs B; 6925 // In presence of clause 'collapse' with number of loops, it will 6926 // define the nested loops number. 6927 auto NestedLoopCount = CheckOpenMPLoop( 6928 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 6929 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6930 VarsWithImplicitDSA, B); 6931 6932 if (NestedLoopCount == 0) 6933 return StmtError(); 6934 6935 assert((CurContext->isDependentContext() || B.builtAll()) && 6936 "omp for loop exprs were not built"); 6937 6938 if (!CurContext->isDependentContext()) { 6939 // Finalize the clauses that need pre-built expressions for CodeGen. 6940 for (auto C : Clauses) { 6941 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6942 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6943 B.NumIterations, *this, CurScope, 6944 DSAStack)) 6945 return StmtError(); 6946 } 6947 } 6948 6949 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6950 return StmtError(); 6951 6952 getCurFunction()->setHasBranchProtectedScope(); 6953 return OMPTeamsDistributeParallelForSimdDirective::Create( 6954 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6955 } 6956 6957 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 6958 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6959 SourceLocation EndLoc, 6960 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6961 if (!AStmt) 6962 return StmtError(); 6963 6964 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6965 // 1.2.2 OpenMP Language Terminology 6966 // Structured block - An executable statement with a single entry at the 6967 // top and a single exit at the bottom. 6968 // The point of exit cannot be a branch out of the structured block. 6969 // longjmp() and throw() must not violate the entry/exit criteria. 6970 CS->getCapturedDecl()->setNothrow(); 6971 6972 OMPLoopDirective::HelperExprs B; 6973 // In presence of clause 'collapse' with number of loops, it will 6974 // define the nested loops number. 6975 unsigned NestedLoopCount = CheckOpenMPLoop( 6976 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 6977 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6978 VarsWithImplicitDSA, B); 6979 6980 if (NestedLoopCount == 0) 6981 return StmtError(); 6982 6983 assert((CurContext->isDependentContext() || B.builtAll()) && 6984 "omp for loop exprs were not built"); 6985 6986 if (!CurContext->isDependentContext()) { 6987 // Finalize the clauses that need pre-built expressions for CodeGen. 6988 for (auto C : Clauses) { 6989 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6990 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6991 B.NumIterations, *this, CurScope, 6992 DSAStack)) 6993 return StmtError(); 6994 } 6995 } 6996 6997 getCurFunction()->setHasBranchProtectedScope(); 6998 return OMPTeamsDistributeParallelForDirective::Create( 6999 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7000 } 7001 7002 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 7003 Stmt *AStmt, 7004 SourceLocation StartLoc, 7005 SourceLocation EndLoc) { 7006 if (!AStmt) 7007 return StmtError(); 7008 7009 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7010 // 1.2.2 OpenMP Language Terminology 7011 // Structured block - An executable statement with a single entry at the 7012 // top and a single exit at the bottom. 7013 // The point of exit cannot be a branch out of the structured block. 7014 // longjmp() and throw() must not violate the entry/exit criteria. 7015 CS->getCapturedDecl()->setNothrow(); 7016 7017 getCurFunction()->setHasBranchProtectedScope(); 7018 7019 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 7020 AStmt); 7021 } 7022 7023 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 7024 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7025 SourceLocation EndLoc, 7026 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7027 if (!AStmt) 7028 return StmtError(); 7029 7030 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7031 // 1.2.2 OpenMP Language Terminology 7032 // Structured block - An executable statement with a single entry at the 7033 // top and a single exit at the bottom. 7034 // The point of exit cannot be a branch out of the structured block. 7035 // longjmp() and throw() must not violate the entry/exit criteria. 7036 CS->getCapturedDecl()->setNothrow(); 7037 7038 OMPLoopDirective::HelperExprs B; 7039 // In presence of clause 'collapse' with number of loops, it will 7040 // define the nested loops number. 7041 auto NestedLoopCount = CheckOpenMPLoop( 7042 OMPD_target_teams_distribute, 7043 getCollapseNumberExpr(Clauses), 7044 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 7045 VarsWithImplicitDSA, B); 7046 if (NestedLoopCount == 0) 7047 return StmtError(); 7048 7049 assert((CurContext->isDependentContext() || B.builtAll()) && 7050 "omp target teams distribute loop exprs were not built"); 7051 7052 getCurFunction()->setHasBranchProtectedScope(); 7053 return OMPTargetTeamsDistributeDirective::Create( 7054 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7055 } 7056 7057 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 7058 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7059 SourceLocation EndLoc, 7060 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7061 if (!AStmt) 7062 return StmtError(); 7063 7064 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7065 // 1.2.2 OpenMP Language Terminology 7066 // Structured block - An executable statement with a single entry at the 7067 // top and a single exit at the bottom. 7068 // The point of exit cannot be a branch out of the structured block. 7069 // longjmp() and throw() must not violate the entry/exit criteria. 7070 CS->getCapturedDecl()->setNothrow(); 7071 7072 OMPLoopDirective::HelperExprs B; 7073 // In presence of clause 'collapse' with number of loops, it will 7074 // define the nested loops number. 7075 auto NestedLoopCount = CheckOpenMPLoop( 7076 OMPD_target_teams_distribute_parallel_for, 7077 getCollapseNumberExpr(Clauses), 7078 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 7079 VarsWithImplicitDSA, B); 7080 if (NestedLoopCount == 0) 7081 return StmtError(); 7082 7083 assert((CurContext->isDependentContext() || B.builtAll()) && 7084 "omp target teams distribute parallel for loop exprs were not built"); 7085 7086 if (!CurContext->isDependentContext()) { 7087 // Finalize the clauses that need pre-built expressions for CodeGen. 7088 for (auto C : Clauses) { 7089 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7090 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7091 B.NumIterations, *this, CurScope, 7092 DSAStack)) 7093 return StmtError(); 7094 } 7095 } 7096 7097 getCurFunction()->setHasBranchProtectedScope(); 7098 return OMPTargetTeamsDistributeParallelForDirective::Create( 7099 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7100 } 7101 7102 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 7103 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7104 SourceLocation EndLoc, 7105 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7106 if (!AStmt) 7107 return StmtError(); 7108 7109 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7110 // 1.2.2 OpenMP Language Terminology 7111 // Structured block - An executable statement with a single entry at the 7112 // top and a single exit at the bottom. 7113 // The point of exit cannot be a branch out of the structured block. 7114 // longjmp() and throw() must not violate the entry/exit criteria. 7115 CS->getCapturedDecl()->setNothrow(); 7116 7117 OMPLoopDirective::HelperExprs B; 7118 // In presence of clause 'collapse' with number of loops, it will 7119 // define the nested loops number. 7120 auto NestedLoopCount = CheckOpenMPLoop( 7121 OMPD_target_teams_distribute_parallel_for_simd, 7122 getCollapseNumberExpr(Clauses), 7123 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 7124 VarsWithImplicitDSA, B); 7125 if (NestedLoopCount == 0) 7126 return StmtError(); 7127 7128 assert((CurContext->isDependentContext() || B.builtAll()) && 7129 "omp target teams distribute parallel for simd loop exprs were not " 7130 "built"); 7131 7132 if (!CurContext->isDependentContext()) { 7133 // Finalize the clauses that need pre-built expressions for CodeGen. 7134 for (auto C : Clauses) { 7135 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7136 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7137 B.NumIterations, *this, CurScope, 7138 DSAStack)) 7139 return StmtError(); 7140 } 7141 } 7142 7143 getCurFunction()->setHasBranchProtectedScope(); 7144 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 7145 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7146 } 7147 7148 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 7149 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7150 SourceLocation EndLoc, 7151 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7152 if (!AStmt) 7153 return StmtError(); 7154 7155 auto *CS = cast<CapturedStmt>(AStmt); 7156 // 1.2.2 OpenMP Language Terminology 7157 // Structured block - An executable statement with a single entry at the 7158 // top and a single exit at the bottom. 7159 // The point of exit cannot be a branch out of the structured block. 7160 // longjmp() and throw() must not violate the entry/exit criteria. 7161 CS->getCapturedDecl()->setNothrow(); 7162 7163 OMPLoopDirective::HelperExprs B; 7164 // In presence of clause 'collapse' with number of loops, it will 7165 // define the nested loops number. 7166 auto NestedLoopCount = CheckOpenMPLoop( 7167 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 7168 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 7169 VarsWithImplicitDSA, B); 7170 if (NestedLoopCount == 0) 7171 return StmtError(); 7172 7173 assert((CurContext->isDependentContext() || B.builtAll()) && 7174 "omp target teams distribute simd loop exprs were not built"); 7175 7176 getCurFunction()->setHasBranchProtectedScope(); 7177 return OMPTargetTeamsDistributeSimdDirective::Create( 7178 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7179 } 7180 7181 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 7182 SourceLocation StartLoc, 7183 SourceLocation LParenLoc, 7184 SourceLocation EndLoc) { 7185 OMPClause *Res = nullptr; 7186 switch (Kind) { 7187 case OMPC_final: 7188 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 7189 break; 7190 case OMPC_num_threads: 7191 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 7192 break; 7193 case OMPC_safelen: 7194 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 7195 break; 7196 case OMPC_simdlen: 7197 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 7198 break; 7199 case OMPC_collapse: 7200 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 7201 break; 7202 case OMPC_ordered: 7203 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 7204 break; 7205 case OMPC_device: 7206 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 7207 break; 7208 case OMPC_num_teams: 7209 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 7210 break; 7211 case OMPC_thread_limit: 7212 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 7213 break; 7214 case OMPC_priority: 7215 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 7216 break; 7217 case OMPC_grainsize: 7218 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 7219 break; 7220 case OMPC_num_tasks: 7221 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 7222 break; 7223 case OMPC_hint: 7224 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 7225 break; 7226 case OMPC_if: 7227 case OMPC_default: 7228 case OMPC_proc_bind: 7229 case OMPC_schedule: 7230 case OMPC_private: 7231 case OMPC_firstprivate: 7232 case OMPC_lastprivate: 7233 case OMPC_shared: 7234 case OMPC_reduction: 7235 case OMPC_task_reduction: 7236 case OMPC_in_reduction: 7237 case OMPC_linear: 7238 case OMPC_aligned: 7239 case OMPC_copyin: 7240 case OMPC_copyprivate: 7241 case OMPC_nowait: 7242 case OMPC_untied: 7243 case OMPC_mergeable: 7244 case OMPC_threadprivate: 7245 case OMPC_flush: 7246 case OMPC_read: 7247 case OMPC_write: 7248 case OMPC_update: 7249 case OMPC_capture: 7250 case OMPC_seq_cst: 7251 case OMPC_depend: 7252 case OMPC_threads: 7253 case OMPC_simd: 7254 case OMPC_map: 7255 case OMPC_nogroup: 7256 case OMPC_dist_schedule: 7257 case OMPC_defaultmap: 7258 case OMPC_unknown: 7259 case OMPC_uniform: 7260 case OMPC_to: 7261 case OMPC_from: 7262 case OMPC_use_device_ptr: 7263 case OMPC_is_device_ptr: 7264 llvm_unreachable("Clause is not allowed."); 7265 } 7266 return Res; 7267 } 7268 7269 // An OpenMP directive such as 'target parallel' has two captured regions: 7270 // for the 'target' and 'parallel' respectively. This function returns 7271 // the region in which to capture expressions associated with a clause. 7272 // A return value of OMPD_unknown signifies that the expression should not 7273 // be captured. 7274 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 7275 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 7276 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 7277 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 7278 7279 switch (CKind) { 7280 case OMPC_if: 7281 switch (DKind) { 7282 case OMPD_target_parallel: 7283 // If this clause applies to the nested 'parallel' region, capture within 7284 // the 'target' region, otherwise do not capture. 7285 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 7286 CaptureRegion = OMPD_target; 7287 break; 7288 case OMPD_cancel: 7289 case OMPD_parallel: 7290 case OMPD_parallel_sections: 7291 case OMPD_parallel_for: 7292 case OMPD_parallel_for_simd: 7293 case OMPD_target: 7294 case OMPD_target_simd: 7295 case OMPD_target_parallel_for: 7296 case OMPD_target_parallel_for_simd: 7297 case OMPD_target_teams: 7298 case OMPD_target_teams_distribute: 7299 case OMPD_target_teams_distribute_simd: 7300 case OMPD_target_teams_distribute_parallel_for: 7301 case OMPD_target_teams_distribute_parallel_for_simd: 7302 case OMPD_teams_distribute_parallel_for: 7303 case OMPD_teams_distribute_parallel_for_simd: 7304 case OMPD_distribute_parallel_for: 7305 case OMPD_distribute_parallel_for_simd: 7306 case OMPD_task: 7307 case OMPD_taskloop: 7308 case OMPD_taskloop_simd: 7309 case OMPD_target_data: 7310 case OMPD_target_enter_data: 7311 case OMPD_target_exit_data: 7312 case OMPD_target_update: 7313 // Do not capture if-clause expressions. 7314 break; 7315 case OMPD_threadprivate: 7316 case OMPD_taskyield: 7317 case OMPD_barrier: 7318 case OMPD_taskwait: 7319 case OMPD_cancellation_point: 7320 case OMPD_flush: 7321 case OMPD_declare_reduction: 7322 case OMPD_declare_simd: 7323 case OMPD_declare_target: 7324 case OMPD_end_declare_target: 7325 case OMPD_teams: 7326 case OMPD_simd: 7327 case OMPD_for: 7328 case OMPD_for_simd: 7329 case OMPD_sections: 7330 case OMPD_section: 7331 case OMPD_single: 7332 case OMPD_master: 7333 case OMPD_critical: 7334 case OMPD_taskgroup: 7335 case OMPD_distribute: 7336 case OMPD_ordered: 7337 case OMPD_atomic: 7338 case OMPD_distribute_simd: 7339 case OMPD_teams_distribute: 7340 case OMPD_teams_distribute_simd: 7341 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 7342 case OMPD_unknown: 7343 llvm_unreachable("Unknown OpenMP directive"); 7344 } 7345 break; 7346 case OMPC_num_threads: 7347 switch (DKind) { 7348 case OMPD_target_parallel: 7349 CaptureRegion = OMPD_target; 7350 break; 7351 case OMPD_cancel: 7352 case OMPD_parallel: 7353 case OMPD_parallel_sections: 7354 case OMPD_parallel_for: 7355 case OMPD_parallel_for_simd: 7356 case OMPD_target: 7357 case OMPD_target_simd: 7358 case OMPD_target_parallel_for: 7359 case OMPD_target_parallel_for_simd: 7360 case OMPD_target_teams: 7361 case OMPD_target_teams_distribute: 7362 case OMPD_target_teams_distribute_simd: 7363 case OMPD_target_teams_distribute_parallel_for: 7364 case OMPD_target_teams_distribute_parallel_for_simd: 7365 case OMPD_teams_distribute_parallel_for: 7366 case OMPD_teams_distribute_parallel_for_simd: 7367 case OMPD_distribute_parallel_for: 7368 case OMPD_distribute_parallel_for_simd: 7369 case OMPD_task: 7370 case OMPD_taskloop: 7371 case OMPD_taskloop_simd: 7372 case OMPD_target_data: 7373 case OMPD_target_enter_data: 7374 case OMPD_target_exit_data: 7375 case OMPD_target_update: 7376 // Do not capture num_threads-clause expressions. 7377 break; 7378 case OMPD_threadprivate: 7379 case OMPD_taskyield: 7380 case OMPD_barrier: 7381 case OMPD_taskwait: 7382 case OMPD_cancellation_point: 7383 case OMPD_flush: 7384 case OMPD_declare_reduction: 7385 case OMPD_declare_simd: 7386 case OMPD_declare_target: 7387 case OMPD_end_declare_target: 7388 case OMPD_teams: 7389 case OMPD_simd: 7390 case OMPD_for: 7391 case OMPD_for_simd: 7392 case OMPD_sections: 7393 case OMPD_section: 7394 case OMPD_single: 7395 case OMPD_master: 7396 case OMPD_critical: 7397 case OMPD_taskgroup: 7398 case OMPD_distribute: 7399 case OMPD_ordered: 7400 case OMPD_atomic: 7401 case OMPD_distribute_simd: 7402 case OMPD_teams_distribute: 7403 case OMPD_teams_distribute_simd: 7404 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 7405 case OMPD_unknown: 7406 llvm_unreachable("Unknown OpenMP directive"); 7407 } 7408 break; 7409 case OMPC_num_teams: 7410 switch (DKind) { 7411 case OMPD_target_teams: 7412 CaptureRegion = OMPD_target; 7413 break; 7414 case OMPD_cancel: 7415 case OMPD_parallel: 7416 case OMPD_parallel_sections: 7417 case OMPD_parallel_for: 7418 case OMPD_parallel_for_simd: 7419 case OMPD_target: 7420 case OMPD_target_simd: 7421 case OMPD_target_parallel: 7422 case OMPD_target_parallel_for: 7423 case OMPD_target_parallel_for_simd: 7424 case OMPD_target_teams_distribute: 7425 case OMPD_target_teams_distribute_simd: 7426 case OMPD_target_teams_distribute_parallel_for: 7427 case OMPD_target_teams_distribute_parallel_for_simd: 7428 case OMPD_teams_distribute_parallel_for: 7429 case OMPD_teams_distribute_parallel_for_simd: 7430 case OMPD_distribute_parallel_for: 7431 case OMPD_distribute_parallel_for_simd: 7432 case OMPD_task: 7433 case OMPD_taskloop: 7434 case OMPD_taskloop_simd: 7435 case OMPD_target_data: 7436 case OMPD_target_enter_data: 7437 case OMPD_target_exit_data: 7438 case OMPD_target_update: 7439 case OMPD_teams: 7440 case OMPD_teams_distribute: 7441 case OMPD_teams_distribute_simd: 7442 // Do not capture num_teams-clause expressions. 7443 break; 7444 case OMPD_threadprivate: 7445 case OMPD_taskyield: 7446 case OMPD_barrier: 7447 case OMPD_taskwait: 7448 case OMPD_cancellation_point: 7449 case OMPD_flush: 7450 case OMPD_declare_reduction: 7451 case OMPD_declare_simd: 7452 case OMPD_declare_target: 7453 case OMPD_end_declare_target: 7454 case OMPD_simd: 7455 case OMPD_for: 7456 case OMPD_for_simd: 7457 case OMPD_sections: 7458 case OMPD_section: 7459 case OMPD_single: 7460 case OMPD_master: 7461 case OMPD_critical: 7462 case OMPD_taskgroup: 7463 case OMPD_distribute: 7464 case OMPD_ordered: 7465 case OMPD_atomic: 7466 case OMPD_distribute_simd: 7467 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 7468 case OMPD_unknown: 7469 llvm_unreachable("Unknown OpenMP directive"); 7470 } 7471 break; 7472 case OMPC_thread_limit: 7473 switch (DKind) { 7474 case OMPD_target_teams: 7475 CaptureRegion = OMPD_target; 7476 break; 7477 case OMPD_cancel: 7478 case OMPD_parallel: 7479 case OMPD_parallel_sections: 7480 case OMPD_parallel_for: 7481 case OMPD_parallel_for_simd: 7482 case OMPD_target: 7483 case OMPD_target_simd: 7484 case OMPD_target_parallel: 7485 case OMPD_target_parallel_for: 7486 case OMPD_target_parallel_for_simd: 7487 case OMPD_target_teams_distribute: 7488 case OMPD_target_teams_distribute_simd: 7489 case OMPD_target_teams_distribute_parallel_for: 7490 case OMPD_target_teams_distribute_parallel_for_simd: 7491 case OMPD_teams_distribute_parallel_for: 7492 case OMPD_teams_distribute_parallel_for_simd: 7493 case OMPD_distribute_parallel_for: 7494 case OMPD_distribute_parallel_for_simd: 7495 case OMPD_task: 7496 case OMPD_taskloop: 7497 case OMPD_taskloop_simd: 7498 case OMPD_target_data: 7499 case OMPD_target_enter_data: 7500 case OMPD_target_exit_data: 7501 case OMPD_target_update: 7502 case OMPD_teams: 7503 case OMPD_teams_distribute: 7504 case OMPD_teams_distribute_simd: 7505 // Do not capture thread_limit-clause expressions. 7506 break; 7507 case OMPD_threadprivate: 7508 case OMPD_taskyield: 7509 case OMPD_barrier: 7510 case OMPD_taskwait: 7511 case OMPD_cancellation_point: 7512 case OMPD_flush: 7513 case OMPD_declare_reduction: 7514 case OMPD_declare_simd: 7515 case OMPD_declare_target: 7516 case OMPD_end_declare_target: 7517 case OMPD_simd: 7518 case OMPD_for: 7519 case OMPD_for_simd: 7520 case OMPD_sections: 7521 case OMPD_section: 7522 case OMPD_single: 7523 case OMPD_master: 7524 case OMPD_critical: 7525 case OMPD_taskgroup: 7526 case OMPD_distribute: 7527 case OMPD_ordered: 7528 case OMPD_atomic: 7529 case OMPD_distribute_simd: 7530 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 7531 case OMPD_unknown: 7532 llvm_unreachable("Unknown OpenMP directive"); 7533 } 7534 break; 7535 case OMPC_schedule: 7536 case OMPC_dist_schedule: 7537 case OMPC_firstprivate: 7538 case OMPC_lastprivate: 7539 case OMPC_reduction: 7540 case OMPC_task_reduction: 7541 case OMPC_in_reduction: 7542 case OMPC_linear: 7543 case OMPC_default: 7544 case OMPC_proc_bind: 7545 case OMPC_final: 7546 case OMPC_safelen: 7547 case OMPC_simdlen: 7548 case OMPC_collapse: 7549 case OMPC_private: 7550 case OMPC_shared: 7551 case OMPC_aligned: 7552 case OMPC_copyin: 7553 case OMPC_copyprivate: 7554 case OMPC_ordered: 7555 case OMPC_nowait: 7556 case OMPC_untied: 7557 case OMPC_mergeable: 7558 case OMPC_threadprivate: 7559 case OMPC_flush: 7560 case OMPC_read: 7561 case OMPC_write: 7562 case OMPC_update: 7563 case OMPC_capture: 7564 case OMPC_seq_cst: 7565 case OMPC_depend: 7566 case OMPC_device: 7567 case OMPC_threads: 7568 case OMPC_simd: 7569 case OMPC_map: 7570 case OMPC_priority: 7571 case OMPC_grainsize: 7572 case OMPC_nogroup: 7573 case OMPC_num_tasks: 7574 case OMPC_hint: 7575 case OMPC_defaultmap: 7576 case OMPC_unknown: 7577 case OMPC_uniform: 7578 case OMPC_to: 7579 case OMPC_from: 7580 case OMPC_use_device_ptr: 7581 case OMPC_is_device_ptr: 7582 llvm_unreachable("Unexpected OpenMP clause."); 7583 } 7584 return CaptureRegion; 7585 } 7586 7587 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 7588 Expr *Condition, SourceLocation StartLoc, 7589 SourceLocation LParenLoc, 7590 SourceLocation NameModifierLoc, 7591 SourceLocation ColonLoc, 7592 SourceLocation EndLoc) { 7593 Expr *ValExpr = Condition; 7594 Stmt *HelperValStmt = nullptr; 7595 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 7596 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 7597 !Condition->isInstantiationDependent() && 7598 !Condition->containsUnexpandedParameterPack()) { 7599 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 7600 if (Val.isInvalid()) 7601 return nullptr; 7602 7603 ValExpr = MakeFullExpr(Val.get()).get(); 7604 7605 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7606 CaptureRegion = 7607 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 7608 if (CaptureRegion != OMPD_unknown) { 7609 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 7610 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 7611 HelperValStmt = buildPreInits(Context, Captures); 7612 } 7613 } 7614 7615 return new (Context) 7616 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 7617 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 7618 } 7619 7620 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 7621 SourceLocation StartLoc, 7622 SourceLocation LParenLoc, 7623 SourceLocation EndLoc) { 7624 Expr *ValExpr = Condition; 7625 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 7626 !Condition->isInstantiationDependent() && 7627 !Condition->containsUnexpandedParameterPack()) { 7628 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 7629 if (Val.isInvalid()) 7630 return nullptr; 7631 7632 ValExpr = MakeFullExpr(Val.get()).get(); 7633 } 7634 7635 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 7636 } 7637 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 7638 Expr *Op) { 7639 if (!Op) 7640 return ExprError(); 7641 7642 class IntConvertDiagnoser : public ICEConvertDiagnoser { 7643 public: 7644 IntConvertDiagnoser() 7645 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 7646 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 7647 QualType T) override { 7648 return S.Diag(Loc, diag::err_omp_not_integral) << T; 7649 } 7650 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 7651 QualType T) override { 7652 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 7653 } 7654 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 7655 QualType T, 7656 QualType ConvTy) override { 7657 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 7658 } 7659 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 7660 QualType ConvTy) override { 7661 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 7662 << ConvTy->isEnumeralType() << ConvTy; 7663 } 7664 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 7665 QualType T) override { 7666 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 7667 } 7668 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 7669 QualType ConvTy) override { 7670 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 7671 << ConvTy->isEnumeralType() << ConvTy; 7672 } 7673 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 7674 QualType) override { 7675 llvm_unreachable("conversion functions are permitted"); 7676 } 7677 } ConvertDiagnoser; 7678 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 7679 } 7680 7681 static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 7682 OpenMPClauseKind CKind, 7683 bool StrictlyPositive) { 7684 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 7685 !ValExpr->isInstantiationDependent()) { 7686 SourceLocation Loc = ValExpr->getExprLoc(); 7687 ExprResult Value = 7688 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 7689 if (Value.isInvalid()) 7690 return false; 7691 7692 ValExpr = Value.get(); 7693 // The expression must evaluate to a non-negative integer value. 7694 llvm::APSInt Result; 7695 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 7696 Result.isSigned() && 7697 !((!StrictlyPositive && Result.isNonNegative()) || 7698 (StrictlyPositive && Result.isStrictlyPositive()))) { 7699 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 7700 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 7701 << ValExpr->getSourceRange(); 7702 return false; 7703 } 7704 } 7705 return true; 7706 } 7707 7708 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 7709 SourceLocation StartLoc, 7710 SourceLocation LParenLoc, 7711 SourceLocation EndLoc) { 7712 Expr *ValExpr = NumThreads; 7713 Stmt *HelperValStmt = nullptr; 7714 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 7715 7716 // OpenMP [2.5, Restrictions] 7717 // The num_threads expression must evaluate to a positive integer value. 7718 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 7719 /*StrictlyPositive=*/true)) 7720 return nullptr; 7721 7722 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7723 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 7724 if (CaptureRegion != OMPD_unknown) { 7725 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 7726 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 7727 HelperValStmt = buildPreInits(Context, Captures); 7728 } 7729 7730 return new (Context) OMPNumThreadsClause( 7731 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 7732 } 7733 7734 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 7735 OpenMPClauseKind CKind, 7736 bool StrictlyPositive) { 7737 if (!E) 7738 return ExprError(); 7739 if (E->isValueDependent() || E->isTypeDependent() || 7740 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 7741 return E; 7742 llvm::APSInt Result; 7743 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 7744 if (ICE.isInvalid()) 7745 return ExprError(); 7746 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 7747 (!StrictlyPositive && !Result.isNonNegative())) { 7748 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 7749 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 7750 << E->getSourceRange(); 7751 return ExprError(); 7752 } 7753 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 7754 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 7755 << E->getSourceRange(); 7756 return ExprError(); 7757 } 7758 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 7759 DSAStack->setAssociatedLoops(Result.getExtValue()); 7760 else if (CKind == OMPC_ordered) 7761 DSAStack->setAssociatedLoops(Result.getExtValue()); 7762 return ICE; 7763 } 7764 7765 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 7766 SourceLocation LParenLoc, 7767 SourceLocation EndLoc) { 7768 // OpenMP [2.8.1, simd construct, Description] 7769 // The parameter of the safelen clause must be a constant 7770 // positive integer expression. 7771 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 7772 if (Safelen.isInvalid()) 7773 return nullptr; 7774 return new (Context) 7775 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 7776 } 7777 7778 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 7779 SourceLocation LParenLoc, 7780 SourceLocation EndLoc) { 7781 // OpenMP [2.8.1, simd construct, Description] 7782 // The parameter of the simdlen clause must be a constant 7783 // positive integer expression. 7784 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 7785 if (Simdlen.isInvalid()) 7786 return nullptr; 7787 return new (Context) 7788 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 7789 } 7790 7791 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 7792 SourceLocation StartLoc, 7793 SourceLocation LParenLoc, 7794 SourceLocation EndLoc) { 7795 // OpenMP [2.7.1, loop construct, Description] 7796 // OpenMP [2.8.1, simd construct, Description] 7797 // OpenMP [2.9.6, distribute construct, Description] 7798 // The parameter of the collapse clause must be a constant 7799 // positive integer expression. 7800 ExprResult NumForLoopsResult = 7801 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 7802 if (NumForLoopsResult.isInvalid()) 7803 return nullptr; 7804 return new (Context) 7805 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 7806 } 7807 7808 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 7809 SourceLocation EndLoc, 7810 SourceLocation LParenLoc, 7811 Expr *NumForLoops) { 7812 // OpenMP [2.7.1, loop construct, Description] 7813 // OpenMP [2.8.1, simd construct, Description] 7814 // OpenMP [2.9.6, distribute construct, Description] 7815 // The parameter of the ordered clause must be a constant 7816 // positive integer expression if any. 7817 if (NumForLoops && LParenLoc.isValid()) { 7818 ExprResult NumForLoopsResult = 7819 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 7820 if (NumForLoopsResult.isInvalid()) 7821 return nullptr; 7822 NumForLoops = NumForLoopsResult.get(); 7823 } else 7824 NumForLoops = nullptr; 7825 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops); 7826 return new (Context) 7827 OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc); 7828 } 7829 7830 OMPClause *Sema::ActOnOpenMPSimpleClause( 7831 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 7832 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 7833 OMPClause *Res = nullptr; 7834 switch (Kind) { 7835 case OMPC_default: 7836 Res = 7837 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 7838 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 7839 break; 7840 case OMPC_proc_bind: 7841 Res = ActOnOpenMPProcBindClause( 7842 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 7843 LParenLoc, EndLoc); 7844 break; 7845 case OMPC_if: 7846 case OMPC_final: 7847 case OMPC_num_threads: 7848 case OMPC_safelen: 7849 case OMPC_simdlen: 7850 case OMPC_collapse: 7851 case OMPC_schedule: 7852 case OMPC_private: 7853 case OMPC_firstprivate: 7854 case OMPC_lastprivate: 7855 case OMPC_shared: 7856 case OMPC_reduction: 7857 case OMPC_task_reduction: 7858 case OMPC_in_reduction: 7859 case OMPC_linear: 7860 case OMPC_aligned: 7861 case OMPC_copyin: 7862 case OMPC_copyprivate: 7863 case OMPC_ordered: 7864 case OMPC_nowait: 7865 case OMPC_untied: 7866 case OMPC_mergeable: 7867 case OMPC_threadprivate: 7868 case OMPC_flush: 7869 case OMPC_read: 7870 case OMPC_write: 7871 case OMPC_update: 7872 case OMPC_capture: 7873 case OMPC_seq_cst: 7874 case OMPC_depend: 7875 case OMPC_device: 7876 case OMPC_threads: 7877 case OMPC_simd: 7878 case OMPC_map: 7879 case OMPC_num_teams: 7880 case OMPC_thread_limit: 7881 case OMPC_priority: 7882 case OMPC_grainsize: 7883 case OMPC_nogroup: 7884 case OMPC_num_tasks: 7885 case OMPC_hint: 7886 case OMPC_dist_schedule: 7887 case OMPC_defaultmap: 7888 case OMPC_unknown: 7889 case OMPC_uniform: 7890 case OMPC_to: 7891 case OMPC_from: 7892 case OMPC_use_device_ptr: 7893 case OMPC_is_device_ptr: 7894 llvm_unreachable("Clause is not allowed."); 7895 } 7896 return Res; 7897 } 7898 7899 static std::string 7900 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 7901 ArrayRef<unsigned> Exclude = llvm::None) { 7902 std::string Values; 7903 unsigned Bound = Last >= 2 ? Last - 2 : 0; 7904 unsigned Skipped = Exclude.size(); 7905 auto S = Exclude.begin(), E = Exclude.end(); 7906 for (unsigned i = First; i < Last; ++i) { 7907 if (std::find(S, E, i) != E) { 7908 --Skipped; 7909 continue; 7910 } 7911 Values += "'"; 7912 Values += getOpenMPSimpleClauseTypeName(K, i); 7913 Values += "'"; 7914 if (i == Bound - Skipped) 7915 Values += " or "; 7916 else if (i != Bound + 1 - Skipped) 7917 Values += ", "; 7918 } 7919 return Values; 7920 } 7921 7922 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 7923 SourceLocation KindKwLoc, 7924 SourceLocation StartLoc, 7925 SourceLocation LParenLoc, 7926 SourceLocation EndLoc) { 7927 if (Kind == OMPC_DEFAULT_unknown) { 7928 static_assert(OMPC_DEFAULT_unknown > 0, 7929 "OMPC_DEFAULT_unknown not greater than 0"); 7930 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 7931 << getListOfPossibleValues(OMPC_default, /*First=*/0, 7932 /*Last=*/OMPC_DEFAULT_unknown) 7933 << getOpenMPClauseName(OMPC_default); 7934 return nullptr; 7935 } 7936 switch (Kind) { 7937 case OMPC_DEFAULT_none: 7938 DSAStack->setDefaultDSANone(KindKwLoc); 7939 break; 7940 case OMPC_DEFAULT_shared: 7941 DSAStack->setDefaultDSAShared(KindKwLoc); 7942 break; 7943 case OMPC_DEFAULT_unknown: 7944 llvm_unreachable("Clause kind is not allowed."); 7945 break; 7946 } 7947 return new (Context) 7948 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 7949 } 7950 7951 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 7952 SourceLocation KindKwLoc, 7953 SourceLocation StartLoc, 7954 SourceLocation LParenLoc, 7955 SourceLocation EndLoc) { 7956 if (Kind == OMPC_PROC_BIND_unknown) { 7957 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 7958 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 7959 /*Last=*/OMPC_PROC_BIND_unknown) 7960 << getOpenMPClauseName(OMPC_proc_bind); 7961 return nullptr; 7962 } 7963 return new (Context) 7964 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 7965 } 7966 7967 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 7968 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 7969 SourceLocation StartLoc, SourceLocation LParenLoc, 7970 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 7971 SourceLocation EndLoc) { 7972 OMPClause *Res = nullptr; 7973 switch (Kind) { 7974 case OMPC_schedule: 7975 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 7976 assert(Argument.size() == NumberOfElements && 7977 ArgumentLoc.size() == NumberOfElements); 7978 Res = ActOnOpenMPScheduleClause( 7979 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 7980 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 7981 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 7982 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 7983 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 7984 break; 7985 case OMPC_if: 7986 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 7987 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 7988 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 7989 DelimLoc, EndLoc); 7990 break; 7991 case OMPC_dist_schedule: 7992 Res = ActOnOpenMPDistScheduleClause( 7993 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 7994 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 7995 break; 7996 case OMPC_defaultmap: 7997 enum { Modifier, DefaultmapKind }; 7998 Res = ActOnOpenMPDefaultmapClause( 7999 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 8000 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 8001 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 8002 EndLoc); 8003 break; 8004 case OMPC_final: 8005 case OMPC_num_threads: 8006 case OMPC_safelen: 8007 case OMPC_simdlen: 8008 case OMPC_collapse: 8009 case OMPC_default: 8010 case OMPC_proc_bind: 8011 case OMPC_private: 8012 case OMPC_firstprivate: 8013 case OMPC_lastprivate: 8014 case OMPC_shared: 8015 case OMPC_reduction: 8016 case OMPC_task_reduction: 8017 case OMPC_in_reduction: 8018 case OMPC_linear: 8019 case OMPC_aligned: 8020 case OMPC_copyin: 8021 case OMPC_copyprivate: 8022 case OMPC_ordered: 8023 case OMPC_nowait: 8024 case OMPC_untied: 8025 case OMPC_mergeable: 8026 case OMPC_threadprivate: 8027 case OMPC_flush: 8028 case OMPC_read: 8029 case OMPC_write: 8030 case OMPC_update: 8031 case OMPC_capture: 8032 case OMPC_seq_cst: 8033 case OMPC_depend: 8034 case OMPC_device: 8035 case OMPC_threads: 8036 case OMPC_simd: 8037 case OMPC_map: 8038 case OMPC_num_teams: 8039 case OMPC_thread_limit: 8040 case OMPC_priority: 8041 case OMPC_grainsize: 8042 case OMPC_nogroup: 8043 case OMPC_num_tasks: 8044 case OMPC_hint: 8045 case OMPC_unknown: 8046 case OMPC_uniform: 8047 case OMPC_to: 8048 case OMPC_from: 8049 case OMPC_use_device_ptr: 8050 case OMPC_is_device_ptr: 8051 llvm_unreachable("Clause is not allowed."); 8052 } 8053 return Res; 8054 } 8055 8056 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 8057 OpenMPScheduleClauseModifier M2, 8058 SourceLocation M1Loc, SourceLocation M2Loc) { 8059 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 8060 SmallVector<unsigned, 2> Excluded; 8061 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 8062 Excluded.push_back(M2); 8063 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 8064 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 8065 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 8066 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 8067 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 8068 << getListOfPossibleValues(OMPC_schedule, 8069 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 8070 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 8071 Excluded) 8072 << getOpenMPClauseName(OMPC_schedule); 8073 return true; 8074 } 8075 return false; 8076 } 8077 8078 OMPClause *Sema::ActOnOpenMPScheduleClause( 8079 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 8080 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 8081 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 8082 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 8083 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 8084 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 8085 return nullptr; 8086 // OpenMP, 2.7.1, Loop Construct, Restrictions 8087 // Either the monotonic modifier or the nonmonotonic modifier can be specified 8088 // but not both. 8089 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 8090 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 8091 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 8092 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 8093 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 8094 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 8095 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 8096 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 8097 return nullptr; 8098 } 8099 if (Kind == OMPC_SCHEDULE_unknown) { 8100 std::string Values; 8101 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 8102 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 8103 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 8104 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 8105 Exclude); 8106 } else { 8107 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 8108 /*Last=*/OMPC_SCHEDULE_unknown); 8109 } 8110 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 8111 << Values << getOpenMPClauseName(OMPC_schedule); 8112 return nullptr; 8113 } 8114 // OpenMP, 2.7.1, Loop Construct, Restrictions 8115 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 8116 // schedule(guided). 8117 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 8118 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 8119 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 8120 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 8121 diag::err_omp_schedule_nonmonotonic_static); 8122 return nullptr; 8123 } 8124 Expr *ValExpr = ChunkSize; 8125 Stmt *HelperValStmt = nullptr; 8126 if (ChunkSize) { 8127 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 8128 !ChunkSize->isInstantiationDependent() && 8129 !ChunkSize->containsUnexpandedParameterPack()) { 8130 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 8131 ExprResult Val = 8132 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 8133 if (Val.isInvalid()) 8134 return nullptr; 8135 8136 ValExpr = Val.get(); 8137 8138 // OpenMP [2.7.1, Restrictions] 8139 // chunk_size must be a loop invariant integer expression with a positive 8140 // value. 8141 llvm::APSInt Result; 8142 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 8143 if (Result.isSigned() && !Result.isStrictlyPositive()) { 8144 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 8145 << "schedule" << 1 << ChunkSize->getSourceRange(); 8146 return nullptr; 8147 } 8148 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) && 8149 !CurContext->isDependentContext()) { 8150 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 8151 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 8152 HelperValStmt = buildPreInits(Context, Captures); 8153 } 8154 } 8155 } 8156 8157 return new (Context) 8158 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 8159 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 8160 } 8161 8162 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 8163 SourceLocation StartLoc, 8164 SourceLocation EndLoc) { 8165 OMPClause *Res = nullptr; 8166 switch (Kind) { 8167 case OMPC_ordered: 8168 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 8169 break; 8170 case OMPC_nowait: 8171 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 8172 break; 8173 case OMPC_untied: 8174 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 8175 break; 8176 case OMPC_mergeable: 8177 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 8178 break; 8179 case OMPC_read: 8180 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 8181 break; 8182 case OMPC_write: 8183 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 8184 break; 8185 case OMPC_update: 8186 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 8187 break; 8188 case OMPC_capture: 8189 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 8190 break; 8191 case OMPC_seq_cst: 8192 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 8193 break; 8194 case OMPC_threads: 8195 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 8196 break; 8197 case OMPC_simd: 8198 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 8199 break; 8200 case OMPC_nogroup: 8201 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 8202 break; 8203 case OMPC_if: 8204 case OMPC_final: 8205 case OMPC_num_threads: 8206 case OMPC_safelen: 8207 case OMPC_simdlen: 8208 case OMPC_collapse: 8209 case OMPC_schedule: 8210 case OMPC_private: 8211 case OMPC_firstprivate: 8212 case OMPC_lastprivate: 8213 case OMPC_shared: 8214 case OMPC_reduction: 8215 case OMPC_task_reduction: 8216 case OMPC_in_reduction: 8217 case OMPC_linear: 8218 case OMPC_aligned: 8219 case OMPC_copyin: 8220 case OMPC_copyprivate: 8221 case OMPC_default: 8222 case OMPC_proc_bind: 8223 case OMPC_threadprivate: 8224 case OMPC_flush: 8225 case OMPC_depend: 8226 case OMPC_device: 8227 case OMPC_map: 8228 case OMPC_num_teams: 8229 case OMPC_thread_limit: 8230 case OMPC_priority: 8231 case OMPC_grainsize: 8232 case OMPC_num_tasks: 8233 case OMPC_hint: 8234 case OMPC_dist_schedule: 8235 case OMPC_defaultmap: 8236 case OMPC_unknown: 8237 case OMPC_uniform: 8238 case OMPC_to: 8239 case OMPC_from: 8240 case OMPC_use_device_ptr: 8241 case OMPC_is_device_ptr: 8242 llvm_unreachable("Clause is not allowed."); 8243 } 8244 return Res; 8245 } 8246 8247 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 8248 SourceLocation EndLoc) { 8249 DSAStack->setNowaitRegion(); 8250 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 8251 } 8252 8253 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 8254 SourceLocation EndLoc) { 8255 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 8256 } 8257 8258 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 8259 SourceLocation EndLoc) { 8260 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 8261 } 8262 8263 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 8264 SourceLocation EndLoc) { 8265 return new (Context) OMPReadClause(StartLoc, EndLoc); 8266 } 8267 8268 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 8269 SourceLocation EndLoc) { 8270 return new (Context) OMPWriteClause(StartLoc, EndLoc); 8271 } 8272 8273 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 8274 SourceLocation EndLoc) { 8275 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 8276 } 8277 8278 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 8279 SourceLocation EndLoc) { 8280 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 8281 } 8282 8283 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 8284 SourceLocation EndLoc) { 8285 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 8286 } 8287 8288 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 8289 SourceLocation EndLoc) { 8290 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 8291 } 8292 8293 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 8294 SourceLocation EndLoc) { 8295 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 8296 } 8297 8298 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 8299 SourceLocation EndLoc) { 8300 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 8301 } 8302 8303 OMPClause *Sema::ActOnOpenMPVarListClause( 8304 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 8305 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 8306 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 8307 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, 8308 OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, 8309 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 8310 SourceLocation DepLinMapLoc) { 8311 OMPClause *Res = nullptr; 8312 switch (Kind) { 8313 case OMPC_private: 8314 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8315 break; 8316 case OMPC_firstprivate: 8317 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8318 break; 8319 case OMPC_lastprivate: 8320 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8321 break; 8322 case OMPC_shared: 8323 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 8324 break; 8325 case OMPC_reduction: 8326 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 8327 EndLoc, ReductionIdScopeSpec, ReductionId); 8328 break; 8329 case OMPC_task_reduction: 8330 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 8331 EndLoc, ReductionIdScopeSpec, 8332 ReductionId); 8333 break; 8334 case OMPC_in_reduction: 8335 Res = 8336 ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 8337 EndLoc, ReductionIdScopeSpec, ReductionId); 8338 break; 8339 case OMPC_linear: 8340 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 8341 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 8342 break; 8343 case OMPC_aligned: 8344 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 8345 ColonLoc, EndLoc); 8346 break; 8347 case OMPC_copyin: 8348 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 8349 break; 8350 case OMPC_copyprivate: 8351 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8352 break; 8353 case OMPC_flush: 8354 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 8355 break; 8356 case OMPC_depend: 8357 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 8358 StartLoc, LParenLoc, EndLoc); 8359 break; 8360 case OMPC_map: 8361 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, 8362 DepLinMapLoc, ColonLoc, VarList, StartLoc, 8363 LParenLoc, EndLoc); 8364 break; 8365 case OMPC_to: 8366 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc); 8367 break; 8368 case OMPC_from: 8369 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc); 8370 break; 8371 case OMPC_use_device_ptr: 8372 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); 8373 break; 8374 case OMPC_is_device_ptr: 8375 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, 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_default: 8384 case OMPC_proc_bind: 8385 case OMPC_schedule: 8386 case OMPC_ordered: 8387 case OMPC_nowait: 8388 case OMPC_untied: 8389 case OMPC_mergeable: 8390 case OMPC_threadprivate: 8391 case OMPC_read: 8392 case OMPC_write: 8393 case OMPC_update: 8394 case OMPC_capture: 8395 case OMPC_seq_cst: 8396 case OMPC_device: 8397 case OMPC_threads: 8398 case OMPC_simd: 8399 case OMPC_num_teams: 8400 case OMPC_thread_limit: 8401 case OMPC_priority: 8402 case OMPC_grainsize: 8403 case OMPC_nogroup: 8404 case OMPC_num_tasks: 8405 case OMPC_hint: 8406 case OMPC_dist_schedule: 8407 case OMPC_defaultmap: 8408 case OMPC_unknown: 8409 case OMPC_uniform: 8410 llvm_unreachable("Clause is not allowed."); 8411 } 8412 return Res; 8413 } 8414 8415 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 8416 ExprObjectKind OK, SourceLocation Loc) { 8417 ExprResult Res = BuildDeclRefExpr( 8418 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 8419 if (!Res.isUsable()) 8420 return ExprError(); 8421 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 8422 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 8423 if (!Res.isUsable()) 8424 return ExprError(); 8425 } 8426 if (VK != VK_LValue && Res.get()->isGLValue()) { 8427 Res = DefaultLvalueConversion(Res.get()); 8428 if (!Res.isUsable()) 8429 return ExprError(); 8430 } 8431 return Res; 8432 } 8433 8434 static std::pair<ValueDecl *, bool> 8435 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 8436 SourceRange &ERange, bool AllowArraySection = false) { 8437 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 8438 RefExpr->containsUnexpandedParameterPack()) 8439 return std::make_pair(nullptr, true); 8440 8441 // OpenMP [3.1, C/C++] 8442 // A list item is a variable name. 8443 // OpenMP [2.9.3.3, Restrictions, p.1] 8444 // A variable that is part of another variable (as an array or 8445 // structure element) cannot appear in a private clause. 8446 RefExpr = RefExpr->IgnoreParens(); 8447 enum { 8448 NoArrayExpr = -1, 8449 ArraySubscript = 0, 8450 OMPArraySection = 1 8451 } IsArrayExpr = NoArrayExpr; 8452 if (AllowArraySection) { 8453 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 8454 auto *Base = ASE->getBase()->IgnoreParenImpCasts(); 8455 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 8456 Base = TempASE->getBase()->IgnoreParenImpCasts(); 8457 RefExpr = Base; 8458 IsArrayExpr = ArraySubscript; 8459 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 8460 auto *Base = OASE->getBase()->IgnoreParenImpCasts(); 8461 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 8462 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 8463 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 8464 Base = TempASE->getBase()->IgnoreParenImpCasts(); 8465 RefExpr = Base; 8466 IsArrayExpr = OMPArraySection; 8467 } 8468 } 8469 ELoc = RefExpr->getExprLoc(); 8470 ERange = RefExpr->getSourceRange(); 8471 RefExpr = RefExpr->IgnoreParenImpCasts(); 8472 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 8473 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 8474 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 8475 (S.getCurrentThisType().isNull() || !ME || 8476 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 8477 !isa<FieldDecl>(ME->getMemberDecl()))) { 8478 if (IsArrayExpr != NoArrayExpr) 8479 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 8480 << ERange; 8481 else { 8482 S.Diag(ELoc, 8483 AllowArraySection 8484 ? diag::err_omp_expected_var_name_member_expr_or_array_item 8485 : diag::err_omp_expected_var_name_member_expr) 8486 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 8487 } 8488 return std::make_pair(nullptr, false); 8489 } 8490 return std::make_pair( 8491 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 8492 } 8493 8494 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 8495 SourceLocation StartLoc, 8496 SourceLocation LParenLoc, 8497 SourceLocation EndLoc) { 8498 SmallVector<Expr *, 8> Vars; 8499 SmallVector<Expr *, 8> PrivateCopies; 8500 for (auto &RefExpr : VarList) { 8501 assert(RefExpr && "NULL expr in OpenMP private clause."); 8502 SourceLocation ELoc; 8503 SourceRange ERange; 8504 Expr *SimpleRefExpr = RefExpr; 8505 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8506 if (Res.second) { 8507 // It will be analyzed later. 8508 Vars.push_back(RefExpr); 8509 PrivateCopies.push_back(nullptr); 8510 } 8511 ValueDecl *D = Res.first; 8512 if (!D) 8513 continue; 8514 8515 QualType Type = D->getType(); 8516 auto *VD = dyn_cast<VarDecl>(D); 8517 8518 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 8519 // A variable that appears in a private clause must not have an incomplete 8520 // type or a reference type. 8521 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 8522 continue; 8523 Type = Type.getNonReferenceType(); 8524 8525 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8526 // in a Construct] 8527 // Variables with the predetermined data-sharing attributes may not be 8528 // listed in data-sharing attributes clauses, except for the cases 8529 // listed below. For these exceptions only, listing a predetermined 8530 // variable in a data-sharing attribute clause is allowed and overrides 8531 // the variable's predetermined data-sharing attributes. 8532 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8533 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 8534 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 8535 << getOpenMPClauseName(OMPC_private); 8536 ReportOriginalDSA(*this, DSAStack, D, DVar); 8537 continue; 8538 } 8539 8540 auto CurrDir = DSAStack->getCurrentDirective(); 8541 // Variably modified types are not supported for tasks. 8542 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 8543 isOpenMPTaskingDirective(CurrDir)) { 8544 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 8545 << getOpenMPClauseName(OMPC_private) << Type 8546 << getOpenMPDirectiveName(CurrDir); 8547 bool IsDecl = 8548 !VD || 8549 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8550 Diag(D->getLocation(), 8551 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8552 << D; 8553 continue; 8554 } 8555 8556 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 8557 // A list item cannot appear in both a map clause and a data-sharing 8558 // attribute clause on the same construct 8559 if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel || 8560 CurrDir == OMPD_target_teams || 8561 CurrDir == OMPD_target_teams_distribute || 8562 CurrDir == OMPD_target_teams_distribute_parallel_for || 8563 CurrDir == OMPD_target_teams_distribute_parallel_for_simd || 8564 CurrDir == OMPD_target_teams_distribute_simd || 8565 CurrDir == OMPD_target_parallel_for_simd || 8566 CurrDir == OMPD_target_parallel_for) { 8567 OpenMPClauseKind ConflictKind; 8568 if (DSAStack->checkMappableExprComponentListsForDecl( 8569 VD, /*CurrentRegionOnly=*/true, 8570 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 8571 OpenMPClauseKind WhereFoundClauseKind) -> bool { 8572 ConflictKind = WhereFoundClauseKind; 8573 return true; 8574 })) { 8575 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 8576 << getOpenMPClauseName(OMPC_private) 8577 << getOpenMPClauseName(ConflictKind) 8578 << getOpenMPDirectiveName(CurrDir); 8579 ReportOriginalDSA(*this, DSAStack, D, DVar); 8580 continue; 8581 } 8582 } 8583 8584 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 8585 // A variable of class type (or array thereof) that appears in a private 8586 // clause requires an accessible, unambiguous default constructor for the 8587 // class type. 8588 // Generate helper private variable and initialize it with the default 8589 // value. The address of the original variable is replaced by the address of 8590 // the new private variable in CodeGen. This new variable is not added to 8591 // IdResolver, so the code in the OpenMP region uses original variable for 8592 // proper diagnostics. 8593 Type = Type.getUnqualifiedType(); 8594 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 8595 D->hasAttrs() ? &D->getAttrs() : nullptr); 8596 ActOnUninitializedDecl(VDPrivate); 8597 if (VDPrivate->isInvalidDecl()) 8598 continue; 8599 auto VDPrivateRefExpr = buildDeclRefExpr( 8600 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 8601 8602 DeclRefExpr *Ref = nullptr; 8603 if (!VD && !CurContext->isDependentContext()) 8604 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 8605 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 8606 Vars.push_back((VD || CurContext->isDependentContext()) 8607 ? RefExpr->IgnoreParens() 8608 : Ref); 8609 PrivateCopies.push_back(VDPrivateRefExpr); 8610 } 8611 8612 if (Vars.empty()) 8613 return nullptr; 8614 8615 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 8616 PrivateCopies); 8617 } 8618 8619 namespace { 8620 class DiagsUninitializedSeveretyRAII { 8621 private: 8622 DiagnosticsEngine &Diags; 8623 SourceLocation SavedLoc; 8624 bool IsIgnored; 8625 8626 public: 8627 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 8628 bool IsIgnored) 8629 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 8630 if (!IsIgnored) { 8631 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 8632 /*Map*/ diag::Severity::Ignored, Loc); 8633 } 8634 } 8635 ~DiagsUninitializedSeveretyRAII() { 8636 if (!IsIgnored) 8637 Diags.popMappings(SavedLoc); 8638 } 8639 }; 8640 } 8641 8642 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 8643 SourceLocation StartLoc, 8644 SourceLocation LParenLoc, 8645 SourceLocation EndLoc) { 8646 SmallVector<Expr *, 8> Vars; 8647 SmallVector<Expr *, 8> PrivateCopies; 8648 SmallVector<Expr *, 8> Inits; 8649 SmallVector<Decl *, 4> ExprCaptures; 8650 bool IsImplicitClause = 8651 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 8652 auto ImplicitClauseLoc = DSAStack->getConstructLoc(); 8653 8654 for (auto &RefExpr : VarList) { 8655 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 8656 SourceLocation ELoc; 8657 SourceRange ERange; 8658 Expr *SimpleRefExpr = RefExpr; 8659 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8660 if (Res.second) { 8661 // It will be analyzed later. 8662 Vars.push_back(RefExpr); 8663 PrivateCopies.push_back(nullptr); 8664 Inits.push_back(nullptr); 8665 } 8666 ValueDecl *D = Res.first; 8667 if (!D) 8668 continue; 8669 8670 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 8671 QualType Type = D->getType(); 8672 auto *VD = dyn_cast<VarDecl>(D); 8673 8674 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 8675 // A variable that appears in a private clause must not have an incomplete 8676 // type or a reference type. 8677 if (RequireCompleteType(ELoc, Type, 8678 diag::err_omp_firstprivate_incomplete_type)) 8679 continue; 8680 Type = Type.getNonReferenceType(); 8681 8682 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 8683 // A variable of class type (or array thereof) that appears in a private 8684 // clause requires an accessible, unambiguous copy constructor for the 8685 // class type. 8686 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 8687 8688 // If an implicit firstprivate variable found it was checked already. 8689 DSAStackTy::DSAVarData TopDVar; 8690 if (!IsImplicitClause) { 8691 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8692 TopDVar = DVar; 8693 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 8694 bool IsConstant = ElemType.isConstant(Context); 8695 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 8696 // A list item that specifies a given variable may not appear in more 8697 // than one clause on the same directive, except that a variable may be 8698 // specified in both firstprivate and lastprivate clauses. 8699 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 8700 // A list item may appear in a firstprivate or lastprivate clause but not 8701 // both. 8702 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 8703 (CurrDir == OMPD_distribute || DVar.CKind != OMPC_lastprivate) && 8704 DVar.RefExpr) { 8705 Diag(ELoc, diag::err_omp_wrong_dsa) 8706 << getOpenMPClauseName(DVar.CKind) 8707 << getOpenMPClauseName(OMPC_firstprivate); 8708 ReportOriginalDSA(*this, DSAStack, D, DVar); 8709 continue; 8710 } 8711 8712 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8713 // in a Construct] 8714 // Variables with the predetermined data-sharing attributes may not be 8715 // listed in data-sharing attributes clauses, except for the cases 8716 // listed below. For these exceptions only, listing a predetermined 8717 // variable in a data-sharing attribute clause is allowed and overrides 8718 // the variable's predetermined data-sharing attributes. 8719 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8720 // in a Construct, C/C++, p.2] 8721 // Variables with const-qualified type having no mutable member may be 8722 // listed in a firstprivate clause, even if they are static data members. 8723 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 8724 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 8725 Diag(ELoc, diag::err_omp_wrong_dsa) 8726 << getOpenMPClauseName(DVar.CKind) 8727 << getOpenMPClauseName(OMPC_firstprivate); 8728 ReportOriginalDSA(*this, DSAStack, D, DVar); 8729 continue; 8730 } 8731 8732 // OpenMP [2.9.3.4, Restrictions, p.2] 8733 // A list item that is private within a parallel region must not appear 8734 // in a firstprivate clause on a worksharing construct if any of the 8735 // worksharing regions arising from the worksharing construct ever bind 8736 // to any of the parallel regions arising from the parallel construct. 8737 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 8738 // A list item that is private within a teams region must not appear in a 8739 // firstprivate clause on a distribute construct if any of the distribute 8740 // regions arising from the distribute construct ever bind to any of the 8741 // teams regions arising from the teams construct. 8742 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 8743 // A list item that appears in a reduction clause of a teams construct 8744 // must not appear in a firstprivate clause on a distribute construct if 8745 // any of the distribute regions arising from the distribute construct 8746 // ever bind to any of the teams regions arising from the teams construct. 8747 if ((isOpenMPWorksharingDirective(CurrDir) || 8748 isOpenMPDistributeDirective(CurrDir)) && 8749 !isOpenMPParallelDirective(CurrDir) && 8750 !isOpenMPTeamsDirective(CurrDir)) { 8751 DVar = DSAStack->getImplicitDSA(D, true); 8752 if (DVar.CKind != OMPC_shared && 8753 (isOpenMPParallelDirective(DVar.DKind) || 8754 isOpenMPTeamsDirective(DVar.DKind) || 8755 DVar.DKind == OMPD_unknown)) { 8756 Diag(ELoc, diag::err_omp_required_access) 8757 << getOpenMPClauseName(OMPC_firstprivate) 8758 << getOpenMPClauseName(OMPC_shared); 8759 ReportOriginalDSA(*this, DSAStack, D, DVar); 8760 continue; 8761 } 8762 } 8763 // OpenMP [2.9.3.4, Restrictions, p.3] 8764 // A list item that appears in a reduction clause of a parallel construct 8765 // must not appear in a firstprivate clause on a worksharing or task 8766 // construct if any of the worksharing or task regions arising from the 8767 // worksharing or task construct ever bind to any of the parallel regions 8768 // arising from the parallel construct. 8769 // OpenMP [2.9.3.4, Restrictions, p.4] 8770 // A list item that appears in a reduction clause in worksharing 8771 // construct must not appear in a firstprivate clause in a task construct 8772 // encountered during execution of any of the worksharing regions arising 8773 // from the worksharing construct. 8774 if (isOpenMPTaskingDirective(CurrDir)) { 8775 DVar = DSAStack->hasInnermostDSA( 8776 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 8777 [](OpenMPDirectiveKind K) -> bool { 8778 return isOpenMPParallelDirective(K) || 8779 isOpenMPWorksharingDirective(K) || 8780 isOpenMPTeamsDirective(K); 8781 }, 8782 /*FromParent=*/true); 8783 if (DVar.CKind == OMPC_reduction && 8784 (isOpenMPParallelDirective(DVar.DKind) || 8785 isOpenMPWorksharingDirective(DVar.DKind) || 8786 isOpenMPTeamsDirective(DVar.DKind))) { 8787 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 8788 << getOpenMPDirectiveName(DVar.DKind); 8789 ReportOriginalDSA(*this, DSAStack, D, DVar); 8790 continue; 8791 } 8792 } 8793 8794 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 8795 // A list item cannot appear in both a map clause and a data-sharing 8796 // attribute clause on the same construct 8797 if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel || 8798 CurrDir == OMPD_target_teams || 8799 CurrDir == OMPD_target_teams_distribute || 8800 CurrDir == OMPD_target_teams_distribute_parallel_for || 8801 CurrDir == OMPD_target_teams_distribute_parallel_for_simd || 8802 CurrDir == OMPD_target_teams_distribute_simd || 8803 CurrDir == OMPD_target_parallel_for_simd || 8804 CurrDir == OMPD_target_parallel_for) { 8805 OpenMPClauseKind ConflictKind; 8806 if (DSAStack->checkMappableExprComponentListsForDecl( 8807 VD, /*CurrentRegionOnly=*/true, 8808 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 8809 OpenMPClauseKind WhereFoundClauseKind) -> bool { 8810 ConflictKind = WhereFoundClauseKind; 8811 return true; 8812 })) { 8813 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 8814 << getOpenMPClauseName(OMPC_firstprivate) 8815 << getOpenMPClauseName(ConflictKind) 8816 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 8817 ReportOriginalDSA(*this, DSAStack, D, DVar); 8818 continue; 8819 } 8820 } 8821 } 8822 8823 // Variably modified types are not supported for tasks. 8824 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 8825 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 8826 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 8827 << getOpenMPClauseName(OMPC_firstprivate) << Type 8828 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 8829 bool IsDecl = 8830 !VD || 8831 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8832 Diag(D->getLocation(), 8833 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8834 << D; 8835 continue; 8836 } 8837 8838 Type = Type.getUnqualifiedType(); 8839 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 8840 D->hasAttrs() ? &D->getAttrs() : nullptr); 8841 // Generate helper private variable and initialize it with the value of the 8842 // original variable. The address of the original variable is replaced by 8843 // the address of the new private variable in the CodeGen. This new variable 8844 // is not added to IdResolver, so the code in the OpenMP region uses 8845 // original variable for proper diagnostics and variable capturing. 8846 Expr *VDInitRefExpr = nullptr; 8847 // For arrays generate initializer for single element and replace it by the 8848 // original array element in CodeGen. 8849 if (Type->isArrayType()) { 8850 auto VDInit = 8851 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 8852 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 8853 auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); 8854 ElemType = ElemType.getUnqualifiedType(); 8855 auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 8856 ".firstprivate.temp"); 8857 InitializedEntity Entity = 8858 InitializedEntity::InitializeVariable(VDInitTemp); 8859 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 8860 8861 InitializationSequence InitSeq(*this, Entity, Kind, Init); 8862 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 8863 if (Result.isInvalid()) 8864 VDPrivate->setInvalidDecl(); 8865 else 8866 VDPrivate->setInit(Result.getAs<Expr>()); 8867 // Remove temp variable declaration. 8868 Context.Deallocate(VDInitTemp); 8869 } else { 8870 auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 8871 ".firstprivate.temp"); 8872 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 8873 RefExpr->getExprLoc()); 8874 AddInitializerToDecl(VDPrivate, 8875 DefaultLvalueConversion(VDInitRefExpr).get(), 8876 /*DirectInit=*/false); 8877 } 8878 if (VDPrivate->isInvalidDecl()) { 8879 if (IsImplicitClause) { 8880 Diag(RefExpr->getExprLoc(), 8881 diag::note_omp_task_predetermined_firstprivate_here); 8882 } 8883 continue; 8884 } 8885 CurContext->addDecl(VDPrivate); 8886 auto VDPrivateRefExpr = buildDeclRefExpr( 8887 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 8888 RefExpr->getExprLoc()); 8889 DeclRefExpr *Ref = nullptr; 8890 if (!VD && !CurContext->isDependentContext()) { 8891 if (TopDVar.CKind == OMPC_lastprivate) 8892 Ref = TopDVar.PrivateCopy; 8893 else { 8894 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 8895 if (!IsOpenMPCapturedDecl(D)) 8896 ExprCaptures.push_back(Ref->getDecl()); 8897 } 8898 } 8899 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 8900 Vars.push_back((VD || CurContext->isDependentContext()) 8901 ? RefExpr->IgnoreParens() 8902 : Ref); 8903 PrivateCopies.push_back(VDPrivateRefExpr); 8904 Inits.push_back(VDInitRefExpr); 8905 } 8906 8907 if (Vars.empty()) 8908 return nullptr; 8909 8910 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 8911 Vars, PrivateCopies, Inits, 8912 buildPreInits(Context, ExprCaptures)); 8913 } 8914 8915 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 8916 SourceLocation StartLoc, 8917 SourceLocation LParenLoc, 8918 SourceLocation EndLoc) { 8919 SmallVector<Expr *, 8> Vars; 8920 SmallVector<Expr *, 8> SrcExprs; 8921 SmallVector<Expr *, 8> DstExprs; 8922 SmallVector<Expr *, 8> AssignmentOps; 8923 SmallVector<Decl *, 4> ExprCaptures; 8924 SmallVector<Expr *, 4> ExprPostUpdates; 8925 for (auto &RefExpr : VarList) { 8926 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 8927 SourceLocation ELoc; 8928 SourceRange ERange; 8929 Expr *SimpleRefExpr = RefExpr; 8930 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8931 if (Res.second) { 8932 // It will be analyzed later. 8933 Vars.push_back(RefExpr); 8934 SrcExprs.push_back(nullptr); 8935 DstExprs.push_back(nullptr); 8936 AssignmentOps.push_back(nullptr); 8937 } 8938 ValueDecl *D = Res.first; 8939 if (!D) 8940 continue; 8941 8942 QualType Type = D->getType(); 8943 auto *VD = dyn_cast<VarDecl>(D); 8944 8945 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 8946 // A variable that appears in a lastprivate clause must not have an 8947 // incomplete type or a reference type. 8948 if (RequireCompleteType(ELoc, Type, 8949 diag::err_omp_lastprivate_incomplete_type)) 8950 continue; 8951 Type = Type.getNonReferenceType(); 8952 8953 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 8954 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 8955 // in a Construct] 8956 // Variables with the predetermined data-sharing attributes may not be 8957 // listed in data-sharing attributes clauses, except for the cases 8958 // listed below. 8959 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 8960 // A list item may appear in a firstprivate or lastprivate clause but not 8961 // both. 8962 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8963 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 8964 (CurrDir == OMPD_distribute || DVar.CKind != OMPC_firstprivate) && 8965 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 8966 Diag(ELoc, diag::err_omp_wrong_dsa) 8967 << getOpenMPClauseName(DVar.CKind) 8968 << getOpenMPClauseName(OMPC_lastprivate); 8969 ReportOriginalDSA(*this, DSAStack, D, DVar); 8970 continue; 8971 } 8972 8973 // OpenMP [2.14.3.5, Restrictions, p.2] 8974 // A list item that is private within a parallel region, or that appears in 8975 // the reduction clause of a parallel construct, must not appear in a 8976 // lastprivate clause on a worksharing construct if any of the corresponding 8977 // worksharing regions ever binds to any of the corresponding parallel 8978 // regions. 8979 DSAStackTy::DSAVarData TopDVar = DVar; 8980 if (isOpenMPWorksharingDirective(CurrDir) && 8981 !isOpenMPParallelDirective(CurrDir) && 8982 !isOpenMPTeamsDirective(CurrDir)) { 8983 DVar = DSAStack->getImplicitDSA(D, true); 8984 if (DVar.CKind != OMPC_shared) { 8985 Diag(ELoc, diag::err_omp_required_access) 8986 << getOpenMPClauseName(OMPC_lastprivate) 8987 << getOpenMPClauseName(OMPC_shared); 8988 ReportOriginalDSA(*this, DSAStack, D, DVar); 8989 continue; 8990 } 8991 } 8992 8993 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 8994 // A variable of class type (or array thereof) that appears in a 8995 // lastprivate clause requires an accessible, unambiguous default 8996 // constructor for the class type, unless the list item is also specified 8997 // in a firstprivate clause. 8998 // A variable of class type (or array thereof) that appears in a 8999 // lastprivate clause requires an accessible, unambiguous copy assignment 9000 // operator for the class type. 9001 Type = Context.getBaseElementType(Type).getNonReferenceType(); 9002 auto *SrcVD = buildVarDecl(*this, ERange.getBegin(), 9003 Type.getUnqualifiedType(), ".lastprivate.src", 9004 D->hasAttrs() ? &D->getAttrs() : nullptr); 9005 auto *PseudoSrcExpr = 9006 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 9007 auto *DstVD = 9008 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 9009 D->hasAttrs() ? &D->getAttrs() : nullptr); 9010 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 9011 // For arrays generate assignment operation for single element and replace 9012 // it by the original array element in CodeGen. 9013 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 9014 PseudoDstExpr, PseudoSrcExpr); 9015 if (AssignmentOp.isInvalid()) 9016 continue; 9017 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 9018 /*DiscardedValue=*/true); 9019 if (AssignmentOp.isInvalid()) 9020 continue; 9021 9022 DeclRefExpr *Ref = nullptr; 9023 if (!VD && !CurContext->isDependentContext()) { 9024 if (TopDVar.CKind == OMPC_firstprivate) 9025 Ref = TopDVar.PrivateCopy; 9026 else { 9027 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 9028 if (!IsOpenMPCapturedDecl(D)) 9029 ExprCaptures.push_back(Ref->getDecl()); 9030 } 9031 if (TopDVar.CKind == OMPC_firstprivate || 9032 (!IsOpenMPCapturedDecl(D) && 9033 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 9034 ExprResult RefRes = DefaultLvalueConversion(Ref); 9035 if (!RefRes.isUsable()) 9036 continue; 9037 ExprResult PostUpdateRes = 9038 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 9039 RefRes.get()); 9040 if (!PostUpdateRes.isUsable()) 9041 continue; 9042 ExprPostUpdates.push_back( 9043 IgnoredValueConversions(PostUpdateRes.get()).get()); 9044 } 9045 } 9046 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 9047 Vars.push_back((VD || CurContext->isDependentContext()) 9048 ? RefExpr->IgnoreParens() 9049 : Ref); 9050 SrcExprs.push_back(PseudoSrcExpr); 9051 DstExprs.push_back(PseudoDstExpr); 9052 AssignmentOps.push_back(AssignmentOp.get()); 9053 } 9054 9055 if (Vars.empty()) 9056 return nullptr; 9057 9058 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9059 Vars, SrcExprs, DstExprs, AssignmentOps, 9060 buildPreInits(Context, ExprCaptures), 9061 buildPostUpdate(*this, ExprPostUpdates)); 9062 } 9063 9064 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 9065 SourceLocation StartLoc, 9066 SourceLocation LParenLoc, 9067 SourceLocation EndLoc) { 9068 SmallVector<Expr *, 8> Vars; 9069 for (auto &RefExpr : VarList) { 9070 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 9071 SourceLocation ELoc; 9072 SourceRange ERange; 9073 Expr *SimpleRefExpr = RefExpr; 9074 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9075 if (Res.second) { 9076 // It will be analyzed later. 9077 Vars.push_back(RefExpr); 9078 } 9079 ValueDecl *D = Res.first; 9080 if (!D) 9081 continue; 9082 9083 auto *VD = dyn_cast<VarDecl>(D); 9084 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 9085 // in a Construct] 9086 // Variables with the predetermined data-sharing attributes may not be 9087 // listed in data-sharing attributes clauses, except for the cases 9088 // listed below. For these exceptions only, listing a predetermined 9089 // variable in a data-sharing attribute clause is allowed and overrides 9090 // the variable's predetermined data-sharing attributes. 9091 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 9092 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 9093 DVar.RefExpr) { 9094 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 9095 << getOpenMPClauseName(OMPC_shared); 9096 ReportOriginalDSA(*this, DSAStack, D, DVar); 9097 continue; 9098 } 9099 9100 DeclRefExpr *Ref = nullptr; 9101 if (!VD && IsOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 9102 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 9103 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 9104 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 9105 ? RefExpr->IgnoreParens() 9106 : Ref); 9107 } 9108 9109 if (Vars.empty()) 9110 return nullptr; 9111 9112 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 9113 } 9114 9115 namespace { 9116 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 9117 DSAStackTy *Stack; 9118 9119 public: 9120 bool VisitDeclRefExpr(DeclRefExpr *E) { 9121 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { 9122 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false); 9123 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 9124 return false; 9125 if (DVar.CKind != OMPC_unknown) 9126 return true; 9127 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 9128 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, 9129 /*FromParent=*/true); 9130 if (DVarPrivate.CKind != OMPC_unknown) 9131 return true; 9132 return false; 9133 } 9134 return false; 9135 } 9136 bool VisitStmt(Stmt *S) { 9137 for (auto Child : S->children()) { 9138 if (Child && Visit(Child)) 9139 return true; 9140 } 9141 return false; 9142 } 9143 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 9144 }; 9145 } // namespace 9146 9147 namespace { 9148 // Transform MemberExpression for specified FieldDecl of current class to 9149 // DeclRefExpr to specified OMPCapturedExprDecl. 9150 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 9151 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 9152 ValueDecl *Field; 9153 DeclRefExpr *CapturedExpr; 9154 9155 public: 9156 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 9157 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 9158 9159 ExprResult TransformMemberExpr(MemberExpr *E) { 9160 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 9161 E->getMemberDecl() == Field) { 9162 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 9163 return CapturedExpr; 9164 } 9165 return BaseTransform::TransformMemberExpr(E); 9166 } 9167 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 9168 }; 9169 } // namespace 9170 9171 template <typename T> 9172 static T filterLookupForUDR(SmallVectorImpl<UnresolvedSet<8>> &Lookups, 9173 const llvm::function_ref<T(ValueDecl *)> &Gen) { 9174 for (auto &Set : Lookups) { 9175 for (auto *D : Set) { 9176 if (auto Res = Gen(cast<ValueDecl>(D))) 9177 return Res; 9178 } 9179 } 9180 return T(); 9181 } 9182 9183 static ExprResult 9184 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 9185 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 9186 const DeclarationNameInfo &ReductionId, QualType Ty, 9187 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 9188 if (ReductionIdScopeSpec.isInvalid()) 9189 return ExprError(); 9190 SmallVector<UnresolvedSet<8>, 4> Lookups; 9191 if (S) { 9192 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 9193 Lookup.suppressDiagnostics(); 9194 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 9195 auto *D = Lookup.getRepresentativeDecl(); 9196 do { 9197 S = S->getParent(); 9198 } while (S && !S->isDeclScope(D)); 9199 if (S) 9200 S = S->getParent(); 9201 Lookups.push_back(UnresolvedSet<8>()); 9202 Lookups.back().append(Lookup.begin(), Lookup.end()); 9203 Lookup.clear(); 9204 } 9205 } else if (auto *ULE = 9206 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 9207 Lookups.push_back(UnresolvedSet<8>()); 9208 Decl *PrevD = nullptr; 9209 for (auto *D : ULE->decls()) { 9210 if (D == PrevD) 9211 Lookups.push_back(UnresolvedSet<8>()); 9212 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) 9213 Lookups.back().addDecl(DRD); 9214 PrevD = D; 9215 } 9216 } 9217 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 9218 Ty->isInstantiationDependentType() || 9219 Ty->containsUnexpandedParameterPack() || 9220 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool { 9221 return !D->isInvalidDecl() && 9222 (D->getType()->isDependentType() || 9223 D->getType()->isInstantiationDependentType() || 9224 D->getType()->containsUnexpandedParameterPack()); 9225 })) { 9226 UnresolvedSet<8> ResSet; 9227 for (auto &Set : Lookups) { 9228 ResSet.append(Set.begin(), Set.end()); 9229 // The last item marks the end of all declarations at the specified scope. 9230 ResSet.addDecl(Set[Set.size() - 1]); 9231 } 9232 return UnresolvedLookupExpr::Create( 9233 SemaRef.Context, /*NamingClass=*/nullptr, 9234 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 9235 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 9236 } 9237 if (auto *VD = filterLookupForUDR<ValueDecl *>( 9238 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 9239 if (!D->isInvalidDecl() && 9240 SemaRef.Context.hasSameType(D->getType(), Ty)) 9241 return D; 9242 return nullptr; 9243 })) 9244 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 9245 if (auto *VD = filterLookupForUDR<ValueDecl *>( 9246 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 9247 if (!D->isInvalidDecl() && 9248 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 9249 !Ty.isMoreQualifiedThan(D->getType())) 9250 return D; 9251 return nullptr; 9252 })) { 9253 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 9254 /*DetectVirtual=*/false); 9255 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 9256 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 9257 VD->getType().getUnqualifiedType()))) { 9258 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), 9259 /*DiagID=*/0) != 9260 Sema::AR_inaccessible) { 9261 SemaRef.BuildBasePathArray(Paths, BasePath); 9262 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 9263 } 9264 } 9265 } 9266 } 9267 if (ReductionIdScopeSpec.isSet()) { 9268 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 9269 return ExprError(); 9270 } 9271 return ExprEmpty(); 9272 } 9273 9274 namespace { 9275 /// Data for the reduction-based clauses. 9276 struct ReductionData { 9277 /// List of original reduction items. 9278 SmallVector<Expr *, 8> Vars; 9279 /// List of private copies of the reduction items. 9280 SmallVector<Expr *, 8> Privates; 9281 /// LHS expressions for the reduction_op expressions. 9282 SmallVector<Expr *, 8> LHSs; 9283 /// RHS expressions for the reduction_op expressions. 9284 SmallVector<Expr *, 8> RHSs; 9285 /// Reduction operation expression. 9286 SmallVector<Expr *, 8> ReductionOps; 9287 /// Taskgroup descriptors for the corresponding reduction items in 9288 /// in_reduction clauses. 9289 SmallVector<Expr *, 8> TaskgroupDescriptors; 9290 /// List of captures for clause. 9291 SmallVector<Decl *, 4> ExprCaptures; 9292 /// List of postupdate expressions. 9293 SmallVector<Expr *, 4> ExprPostUpdates; 9294 ReductionData() = delete; 9295 /// Reserves required memory for the reduction data. 9296 ReductionData(unsigned Size) { 9297 Vars.reserve(Size); 9298 Privates.reserve(Size); 9299 LHSs.reserve(Size); 9300 RHSs.reserve(Size); 9301 ReductionOps.reserve(Size); 9302 TaskgroupDescriptors.reserve(Size); 9303 ExprCaptures.reserve(Size); 9304 ExprPostUpdates.reserve(Size); 9305 } 9306 /// Stores reduction item and reduction operation only (required for dependent 9307 /// reduction item). 9308 void push(Expr *Item, Expr *ReductionOp) { 9309 Vars.emplace_back(Item); 9310 Privates.emplace_back(nullptr); 9311 LHSs.emplace_back(nullptr); 9312 RHSs.emplace_back(nullptr); 9313 ReductionOps.emplace_back(ReductionOp); 9314 TaskgroupDescriptors.emplace_back(nullptr); 9315 } 9316 /// Stores reduction data. 9317 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 9318 Expr *TaskgroupDescriptor) { 9319 Vars.emplace_back(Item); 9320 Privates.emplace_back(Private); 9321 LHSs.emplace_back(LHS); 9322 RHSs.emplace_back(RHS); 9323 ReductionOps.emplace_back(ReductionOp); 9324 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 9325 } 9326 }; 9327 } // namespace 9328 9329 static bool ActOnOMPReductionKindClause( 9330 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 9331 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 9332 SourceLocation ColonLoc, SourceLocation EndLoc, 9333 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 9334 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 9335 auto DN = ReductionId.getName(); 9336 auto OOK = DN.getCXXOverloadedOperator(); 9337 BinaryOperatorKind BOK = BO_Comma; 9338 9339 ASTContext &Context = S.Context; 9340 // OpenMP [2.14.3.6, reduction clause] 9341 // C 9342 // reduction-identifier is either an identifier or one of the following 9343 // operators: +, -, *, &, |, ^, && and || 9344 // C++ 9345 // reduction-identifier is either an id-expression or one of the following 9346 // operators: +, -, *, &, |, ^, && and || 9347 switch (OOK) { 9348 case OO_Plus: 9349 case OO_Minus: 9350 BOK = BO_Add; 9351 break; 9352 case OO_Star: 9353 BOK = BO_Mul; 9354 break; 9355 case OO_Amp: 9356 BOK = BO_And; 9357 break; 9358 case OO_Pipe: 9359 BOK = BO_Or; 9360 break; 9361 case OO_Caret: 9362 BOK = BO_Xor; 9363 break; 9364 case OO_AmpAmp: 9365 BOK = BO_LAnd; 9366 break; 9367 case OO_PipePipe: 9368 BOK = BO_LOr; 9369 break; 9370 case OO_New: 9371 case OO_Delete: 9372 case OO_Array_New: 9373 case OO_Array_Delete: 9374 case OO_Slash: 9375 case OO_Percent: 9376 case OO_Tilde: 9377 case OO_Exclaim: 9378 case OO_Equal: 9379 case OO_Less: 9380 case OO_Greater: 9381 case OO_LessEqual: 9382 case OO_GreaterEqual: 9383 case OO_PlusEqual: 9384 case OO_MinusEqual: 9385 case OO_StarEqual: 9386 case OO_SlashEqual: 9387 case OO_PercentEqual: 9388 case OO_CaretEqual: 9389 case OO_AmpEqual: 9390 case OO_PipeEqual: 9391 case OO_LessLess: 9392 case OO_GreaterGreater: 9393 case OO_LessLessEqual: 9394 case OO_GreaterGreaterEqual: 9395 case OO_EqualEqual: 9396 case OO_ExclaimEqual: 9397 case OO_PlusPlus: 9398 case OO_MinusMinus: 9399 case OO_Comma: 9400 case OO_ArrowStar: 9401 case OO_Arrow: 9402 case OO_Call: 9403 case OO_Subscript: 9404 case OO_Conditional: 9405 case OO_Coawait: 9406 case NUM_OVERLOADED_OPERATORS: 9407 llvm_unreachable("Unexpected reduction identifier"); 9408 case OO_None: 9409 if (auto *II = DN.getAsIdentifierInfo()) { 9410 if (II->isStr("max")) 9411 BOK = BO_GT; 9412 else if (II->isStr("min")) 9413 BOK = BO_LT; 9414 } 9415 break; 9416 } 9417 SourceRange ReductionIdRange; 9418 if (ReductionIdScopeSpec.isValid()) 9419 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 9420 else 9421 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 9422 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 9423 9424 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 9425 bool FirstIter = true; 9426 for (auto RefExpr : VarList) { 9427 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 9428 // OpenMP [2.1, C/C++] 9429 // A list item is a variable or array section, subject to the restrictions 9430 // specified in Section 2.4 on page 42 and in each of the sections 9431 // describing clauses and directives for which a list appears. 9432 // OpenMP [2.14.3.3, Restrictions, p.1] 9433 // A variable that is part of another variable (as an array or 9434 // structure element) cannot appear in a private clause. 9435 if (!FirstIter && IR != ER) 9436 ++IR; 9437 FirstIter = false; 9438 SourceLocation ELoc; 9439 SourceRange ERange; 9440 Expr *SimpleRefExpr = RefExpr; 9441 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 9442 /*AllowArraySection=*/true); 9443 if (Res.second) { 9444 // Try to find 'declare reduction' corresponding construct before using 9445 // builtin/overloaded operators. 9446 QualType Type = Context.DependentTy; 9447 CXXCastPath BasePath; 9448 ExprResult DeclareReductionRef = buildDeclareReductionRef( 9449 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 9450 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 9451 Expr *ReductionOp = nullptr; 9452 if (S.CurContext->isDependentContext() && 9453 (DeclareReductionRef.isUnset() || 9454 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 9455 ReductionOp = DeclareReductionRef.get(); 9456 // It will be analyzed later. 9457 RD.push(RefExpr, ReductionOp); 9458 } 9459 ValueDecl *D = Res.first; 9460 if (!D) 9461 continue; 9462 9463 Expr *TaskgroupDescriptor = nullptr; 9464 QualType Type; 9465 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 9466 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 9467 if (ASE) 9468 Type = ASE->getType().getNonReferenceType(); 9469 else if (OASE) { 9470 auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 9471 if (auto *ATy = BaseType->getAsArrayTypeUnsafe()) 9472 Type = ATy->getElementType(); 9473 else 9474 Type = BaseType->getPointeeType(); 9475 Type = Type.getNonReferenceType(); 9476 } else 9477 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 9478 auto *VD = dyn_cast<VarDecl>(D); 9479 9480 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 9481 // A variable that appears in a private clause must not have an incomplete 9482 // type or a reference type. 9483 if (S.RequireCompleteType(ELoc, Type, 9484 diag::err_omp_reduction_incomplete_type)) 9485 continue; 9486 // OpenMP [2.14.3.6, reduction clause, Restrictions] 9487 // A list item that appears in a reduction clause must not be 9488 // const-qualified. 9489 if (Type.getNonReferenceType().isConstant(Context)) { 9490 S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange; 9491 if (!ASE && !OASE) { 9492 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 9493 VarDecl::DeclarationOnly; 9494 S.Diag(D->getLocation(), 9495 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9496 << D; 9497 } 9498 continue; 9499 } 9500 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 9501 // If a list-item is a reference type then it must bind to the same object 9502 // for all threads of the team. 9503 if (!ASE && !OASE && VD) { 9504 VarDecl *VDDef = VD->getDefinition(); 9505 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 9506 DSARefChecker Check(Stack); 9507 if (Check.Visit(VDDef->getInit())) { 9508 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 9509 << getOpenMPClauseName(ClauseKind) << ERange; 9510 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 9511 continue; 9512 } 9513 } 9514 } 9515 9516 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 9517 // in a Construct] 9518 // Variables with the predetermined data-sharing attributes may not be 9519 // listed in data-sharing attributes clauses, except for the cases 9520 // listed below. For these exceptions only, listing a predetermined 9521 // variable in a data-sharing attribute clause is allowed and overrides 9522 // the variable's predetermined data-sharing attributes. 9523 // OpenMP [2.14.3.6, Restrictions, p.3] 9524 // Any number of reduction clauses can be specified on the directive, 9525 // but a list item can appear only once in the reduction clauses for that 9526 // directive. 9527 DSAStackTy::DSAVarData DVar; 9528 DVar = Stack->getTopDSA(D, false); 9529 if (DVar.CKind == OMPC_reduction) { 9530 S.Diag(ELoc, diag::err_omp_once_referenced) 9531 << getOpenMPClauseName(ClauseKind); 9532 if (DVar.RefExpr) 9533 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 9534 continue; 9535 } else if (DVar.CKind != OMPC_unknown) { 9536 S.Diag(ELoc, diag::err_omp_wrong_dsa) 9537 << getOpenMPClauseName(DVar.CKind) 9538 << getOpenMPClauseName(OMPC_reduction); 9539 ReportOriginalDSA(S, Stack, D, DVar); 9540 continue; 9541 } 9542 9543 // OpenMP [2.14.3.6, Restrictions, p.1] 9544 // A list item that appears in a reduction clause of a worksharing 9545 // construct must be shared in the parallel regions to which any of the 9546 // worksharing regions arising from the worksharing construct bind. 9547 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 9548 if (isOpenMPWorksharingDirective(CurrDir) && 9549 !isOpenMPParallelDirective(CurrDir) && 9550 !isOpenMPTeamsDirective(CurrDir)) { 9551 DVar = Stack->getImplicitDSA(D, true); 9552 if (DVar.CKind != OMPC_shared) { 9553 S.Diag(ELoc, diag::err_omp_required_access) 9554 << getOpenMPClauseName(OMPC_reduction) 9555 << getOpenMPClauseName(OMPC_shared); 9556 ReportOriginalDSA(S, Stack, D, DVar); 9557 continue; 9558 } 9559 } 9560 9561 // Try to find 'declare reduction' corresponding construct before using 9562 // builtin/overloaded operators. 9563 CXXCastPath BasePath; 9564 ExprResult DeclareReductionRef = buildDeclareReductionRef( 9565 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 9566 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 9567 if (DeclareReductionRef.isInvalid()) 9568 continue; 9569 if (S.CurContext->isDependentContext() && 9570 (DeclareReductionRef.isUnset() || 9571 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 9572 RD.push(RefExpr, DeclareReductionRef.get()); 9573 continue; 9574 } 9575 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 9576 // Not allowed reduction identifier is found. 9577 S.Diag(ReductionId.getLocStart(), 9578 diag::err_omp_unknown_reduction_identifier) 9579 << Type << ReductionIdRange; 9580 continue; 9581 } 9582 9583 // OpenMP [2.14.3.6, reduction clause, Restrictions] 9584 // The type of a list item that appears in a reduction clause must be valid 9585 // for the reduction-identifier. For a max or min reduction in C, the type 9586 // of the list item must be an allowed arithmetic data type: char, int, 9587 // float, double, or _Bool, possibly modified with long, short, signed, or 9588 // unsigned. For a max or min reduction in C++, the type of the list item 9589 // must be an allowed arithmetic data type: char, wchar_t, int, float, 9590 // double, or bool, possibly modified with long, short, signed, or unsigned. 9591 if (DeclareReductionRef.isUnset()) { 9592 if ((BOK == BO_GT || BOK == BO_LT) && 9593 !(Type->isScalarType() || 9594 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 9595 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 9596 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 9597 if (!ASE && !OASE) { 9598 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 9599 VarDecl::DeclarationOnly; 9600 S.Diag(D->getLocation(), 9601 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9602 << D; 9603 } 9604 continue; 9605 } 9606 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 9607 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 9608 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 9609 << getOpenMPClauseName(ClauseKind); 9610 if (!ASE && !OASE) { 9611 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 9612 VarDecl::DeclarationOnly; 9613 S.Diag(D->getLocation(), 9614 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9615 << D; 9616 } 9617 continue; 9618 } 9619 } 9620 9621 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 9622 auto *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 9623 D->hasAttrs() ? &D->getAttrs() : nullptr); 9624 auto *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 9625 D->hasAttrs() ? &D->getAttrs() : nullptr); 9626 auto PrivateTy = Type; 9627 if (OASE || 9628 (!ASE && 9629 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 9630 // For arrays/array sections only: 9631 // Create pseudo array type for private copy. The size for this array will 9632 // be generated during codegen. 9633 // For array subscripts or single variables Private Ty is the same as Type 9634 // (type of the variable or single array element). 9635 PrivateTy = Context.getVariableArrayType( 9636 Type, 9637 new (Context) OpaqueValueExpr(SourceLocation(), Context.getSizeType(), 9638 VK_RValue), 9639 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 9640 } else if (!ASE && !OASE && 9641 Context.getAsArrayType(D->getType().getNonReferenceType())) 9642 PrivateTy = D->getType().getNonReferenceType(); 9643 // Private copy. 9644 auto *PrivateVD = buildVarDecl(S, ELoc, PrivateTy, D->getName(), 9645 D->hasAttrs() ? &D->getAttrs() : nullptr); 9646 // Add initializer for private variable. 9647 Expr *Init = nullptr; 9648 auto *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 9649 auto *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 9650 if (DeclareReductionRef.isUsable()) { 9651 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 9652 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 9653 if (DRD->getInitializer()) { 9654 Init = DRDRef; 9655 RHSVD->setInit(DRDRef); 9656 RHSVD->setInitStyle(VarDecl::CallInit); 9657 } 9658 } else { 9659 switch (BOK) { 9660 case BO_Add: 9661 case BO_Xor: 9662 case BO_Or: 9663 case BO_LOr: 9664 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 9665 if (Type->isScalarType() || Type->isAnyComplexType()) 9666 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 9667 break; 9668 case BO_Mul: 9669 case BO_LAnd: 9670 if (Type->isScalarType() || Type->isAnyComplexType()) { 9671 // '*' and '&&' reduction ops - initializer is '1'. 9672 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 9673 } 9674 break; 9675 case BO_And: { 9676 // '&' reduction op - initializer is '~0'. 9677 QualType OrigType = Type; 9678 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 9679 Type = ComplexTy->getElementType(); 9680 if (Type->isRealFloatingType()) { 9681 llvm::APFloat InitValue = 9682 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 9683 /*isIEEE=*/true); 9684 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 9685 Type, ELoc); 9686 } else if (Type->isScalarType()) { 9687 auto Size = Context.getTypeSize(Type); 9688 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 9689 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 9690 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 9691 } 9692 if (Init && OrigType->isAnyComplexType()) { 9693 // Init = 0xFFFF + 0xFFFFi; 9694 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 9695 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 9696 } 9697 Type = OrigType; 9698 break; 9699 } 9700 case BO_LT: 9701 case BO_GT: { 9702 // 'min' reduction op - initializer is 'Largest representable number in 9703 // the reduction list item type'. 9704 // 'max' reduction op - initializer is 'Least representable number in 9705 // the reduction list item type'. 9706 if (Type->isIntegerType() || Type->isPointerType()) { 9707 bool IsSigned = Type->hasSignedIntegerRepresentation(); 9708 auto Size = Context.getTypeSize(Type); 9709 QualType IntTy = 9710 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 9711 llvm::APInt InitValue = 9712 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 9713 : llvm::APInt::getMinValue(Size) 9714 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 9715 : llvm::APInt::getMaxValue(Size); 9716 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 9717 if (Type->isPointerType()) { 9718 // Cast to pointer type. 9719 auto CastExpr = S.BuildCStyleCastExpr( 9720 SourceLocation(), Context.getTrivialTypeSourceInfo(Type, ELoc), 9721 SourceLocation(), Init); 9722 if (CastExpr.isInvalid()) 9723 continue; 9724 Init = CastExpr.get(); 9725 } 9726 } else if (Type->isRealFloatingType()) { 9727 llvm::APFloat InitValue = llvm::APFloat::getLargest( 9728 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 9729 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 9730 Type, ELoc); 9731 } 9732 break; 9733 } 9734 case BO_PtrMemD: 9735 case BO_PtrMemI: 9736 case BO_MulAssign: 9737 case BO_Div: 9738 case BO_Rem: 9739 case BO_Sub: 9740 case BO_Shl: 9741 case BO_Shr: 9742 case BO_LE: 9743 case BO_GE: 9744 case BO_EQ: 9745 case BO_NE: 9746 case BO_AndAssign: 9747 case BO_XorAssign: 9748 case BO_OrAssign: 9749 case BO_Assign: 9750 case BO_AddAssign: 9751 case BO_SubAssign: 9752 case BO_DivAssign: 9753 case BO_RemAssign: 9754 case BO_ShlAssign: 9755 case BO_ShrAssign: 9756 case BO_Comma: 9757 llvm_unreachable("Unexpected reduction operation"); 9758 } 9759 } 9760 if (Init && DeclareReductionRef.isUnset()) 9761 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 9762 else if (!Init) 9763 S.ActOnUninitializedDecl(RHSVD); 9764 if (RHSVD->isInvalidDecl()) 9765 continue; 9766 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 9767 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 9768 << Type << ReductionIdRange; 9769 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 9770 VarDecl::DeclarationOnly; 9771 S.Diag(D->getLocation(), 9772 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9773 << D; 9774 continue; 9775 } 9776 // Store initializer for single element in private copy. Will be used during 9777 // codegen. 9778 PrivateVD->setInit(RHSVD->getInit()); 9779 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 9780 auto *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 9781 ExprResult ReductionOp; 9782 if (DeclareReductionRef.isUsable()) { 9783 QualType RedTy = DeclareReductionRef.get()->getType(); 9784 QualType PtrRedTy = Context.getPointerType(RedTy); 9785 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 9786 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 9787 if (!BasePath.empty()) { 9788 LHS = S.DefaultLvalueConversion(LHS.get()); 9789 RHS = S.DefaultLvalueConversion(RHS.get()); 9790 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 9791 CK_UncheckedDerivedToBase, LHS.get(), 9792 &BasePath, LHS.get()->getValueKind()); 9793 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 9794 CK_UncheckedDerivedToBase, RHS.get(), 9795 &BasePath, RHS.get()->getValueKind()); 9796 } 9797 FunctionProtoType::ExtProtoInfo EPI; 9798 QualType Params[] = {PtrRedTy, PtrRedTy}; 9799 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 9800 auto *OVE = new (Context) OpaqueValueExpr( 9801 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 9802 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 9803 Expr *Args[] = {LHS.get(), RHS.get()}; 9804 ReductionOp = new (Context) 9805 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 9806 } else { 9807 ReductionOp = S.BuildBinOp( 9808 Stack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE); 9809 if (ReductionOp.isUsable()) { 9810 if (BOK != BO_LT && BOK != BO_GT) { 9811 ReductionOp = 9812 S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(), 9813 BO_Assign, LHSDRE, ReductionOp.get()); 9814 } else { 9815 auto *ConditionalOp = new (Context) ConditionalOperator( 9816 ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(), 9817 RHSDRE, Type, VK_LValue, OK_Ordinary); 9818 ReductionOp = 9819 S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(), 9820 BO_Assign, LHSDRE, ConditionalOp); 9821 } 9822 if (ReductionOp.isUsable()) 9823 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get()); 9824 } 9825 if (!ReductionOp.isUsable()) 9826 continue; 9827 } 9828 9829 // OpenMP [2.15.4.6, Restrictions, p.2] 9830 // A list item that appears in an in_reduction clause of a task construct 9831 // must appear in a task_reduction clause of a construct associated with a 9832 // taskgroup region that includes the participating task in its taskgroup 9833 // set. The construct associated with the innermost region that meets this 9834 // condition must specify the same reduction-identifier as the in_reduction 9835 // clause. 9836 if (ClauseKind == OMPC_in_reduction) { 9837 SourceRange ParentSR; 9838 BinaryOperatorKind ParentBOK; 9839 const Expr *ParentReductionOp; 9840 Expr *ParentBOKTD, *ParentReductionOpTD; 9841 DSAStackTy::DSAVarData ParentBOKDSA = 9842 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 9843 ParentBOKTD); 9844 DSAStackTy::DSAVarData ParentReductionOpDSA = 9845 Stack->getTopMostTaskgroupReductionData( 9846 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 9847 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 9848 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 9849 if (!IsParentBOK && !IsParentReductionOp) { 9850 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 9851 continue; 9852 } 9853 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 9854 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 9855 IsParentReductionOp) { 9856 bool EmitError = true; 9857 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 9858 llvm::FoldingSetNodeID RedId, ParentRedId; 9859 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 9860 DeclareReductionRef.get()->Profile(RedId, Context, 9861 /*Canonical=*/true); 9862 EmitError = RedId != ParentRedId; 9863 } 9864 if (EmitError) { 9865 S.Diag(ReductionId.getLocStart(), 9866 diag::err_omp_reduction_identifier_mismatch) 9867 << ReductionIdRange << RefExpr->getSourceRange(); 9868 S.Diag(ParentSR.getBegin(), 9869 diag::note_omp_previous_reduction_identifier) 9870 << ParentSR 9871 << (IsParentBOK ? ParentBOKDSA.RefExpr 9872 : ParentReductionOpDSA.RefExpr) 9873 ->getSourceRange(); 9874 continue; 9875 } 9876 } 9877 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 9878 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 9879 } 9880 9881 DeclRefExpr *Ref = nullptr; 9882 Expr *VarsExpr = RefExpr->IgnoreParens(); 9883 if (!VD && !S.CurContext->isDependentContext()) { 9884 if (ASE || OASE) { 9885 TransformExprToCaptures RebuildToCapture(S, D); 9886 VarsExpr = 9887 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 9888 Ref = RebuildToCapture.getCapturedExpr(); 9889 } else { 9890 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 9891 } 9892 if (!S.IsOpenMPCapturedDecl(D)) { 9893 RD.ExprCaptures.emplace_back(Ref->getDecl()); 9894 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 9895 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 9896 if (!RefRes.isUsable()) 9897 continue; 9898 ExprResult PostUpdateRes = 9899 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 9900 RefRes.get()); 9901 if (!PostUpdateRes.isUsable()) 9902 continue; 9903 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 9904 Stack->getCurrentDirective() == OMPD_taskgroup) { 9905 S.Diag(RefExpr->getExprLoc(), 9906 diag::err_omp_reduction_non_addressable_expression) 9907 << RefExpr->getSourceRange(); 9908 continue; 9909 } 9910 RD.ExprPostUpdates.emplace_back( 9911 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 9912 } 9913 } 9914 } 9915 // All reduction items are still marked as reduction (to do not increase 9916 // code base size). 9917 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 9918 if (CurrDir == OMPD_taskgroup) { 9919 if (DeclareReductionRef.isUsable()) 9920 Stack->addTaskgroupReductionData(D, ReductionIdRange, 9921 DeclareReductionRef.get()); 9922 else 9923 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 9924 } 9925 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 9926 TaskgroupDescriptor); 9927 } 9928 return RD.Vars.empty(); 9929 } 9930 9931 OMPClause *Sema::ActOnOpenMPReductionClause( 9932 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 9933 SourceLocation ColonLoc, SourceLocation EndLoc, 9934 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 9935 ArrayRef<Expr *> UnresolvedReductions) { 9936 ReductionData RD(VarList.size()); 9937 9938 if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 9939 StartLoc, LParenLoc, ColonLoc, EndLoc, 9940 ReductionIdScopeSpec, ReductionId, 9941 UnresolvedReductions, RD)) 9942 return nullptr; 9943 9944 return OMPReductionClause::Create( 9945 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 9946 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 9947 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 9948 buildPreInits(Context, RD.ExprCaptures), 9949 buildPostUpdate(*this, RD.ExprPostUpdates)); 9950 } 9951 9952 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 9953 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 9954 SourceLocation ColonLoc, SourceLocation EndLoc, 9955 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 9956 ArrayRef<Expr *> UnresolvedReductions) { 9957 ReductionData RD(VarList.size()); 9958 9959 if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, 9960 VarList, StartLoc, LParenLoc, ColonLoc, 9961 EndLoc, ReductionIdScopeSpec, ReductionId, 9962 UnresolvedReductions, RD)) 9963 return nullptr; 9964 9965 return OMPTaskReductionClause::Create( 9966 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 9967 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 9968 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 9969 buildPreInits(Context, RD.ExprCaptures), 9970 buildPostUpdate(*this, RD.ExprPostUpdates)); 9971 } 9972 9973 OMPClause *Sema::ActOnOpenMPInReductionClause( 9974 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 9975 SourceLocation ColonLoc, SourceLocation EndLoc, 9976 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 9977 ArrayRef<Expr *> UnresolvedReductions) { 9978 ReductionData RD(VarList.size()); 9979 9980 if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 9981 StartLoc, LParenLoc, ColonLoc, EndLoc, 9982 ReductionIdScopeSpec, ReductionId, 9983 UnresolvedReductions, RD)) 9984 return nullptr; 9985 9986 return OMPInReductionClause::Create( 9987 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 9988 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 9989 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 9990 buildPreInits(Context, RD.ExprCaptures), 9991 buildPostUpdate(*this, RD.ExprPostUpdates)); 9992 } 9993 9994 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 9995 SourceLocation LinLoc) { 9996 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 9997 LinKind == OMPC_LINEAR_unknown) { 9998 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 9999 return true; 10000 } 10001 return false; 10002 } 10003 10004 bool Sema::CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, 10005 OpenMPLinearClauseKind LinKind, 10006 QualType Type) { 10007 auto *VD = dyn_cast_or_null<VarDecl>(D); 10008 // A variable must not have an incomplete type or a reference type. 10009 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 10010 return true; 10011 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 10012 !Type->isReferenceType()) { 10013 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 10014 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 10015 return true; 10016 } 10017 Type = Type.getNonReferenceType(); 10018 10019 // A list item must not be const-qualified. 10020 if (Type.isConstant(Context)) { 10021 Diag(ELoc, diag::err_omp_const_variable) 10022 << getOpenMPClauseName(OMPC_linear); 10023 if (D) { 10024 bool IsDecl = 10025 !VD || 10026 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10027 Diag(D->getLocation(), 10028 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10029 << D; 10030 } 10031 return true; 10032 } 10033 10034 // A list item must be of integral or pointer type. 10035 Type = Type.getUnqualifiedType().getCanonicalType(); 10036 const auto *Ty = Type.getTypePtrOrNull(); 10037 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 10038 !Ty->isPointerType())) { 10039 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 10040 if (D) { 10041 bool IsDecl = 10042 !VD || 10043 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10044 Diag(D->getLocation(), 10045 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10046 << D; 10047 } 10048 return true; 10049 } 10050 return false; 10051 } 10052 10053 OMPClause *Sema::ActOnOpenMPLinearClause( 10054 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 10055 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 10056 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 10057 SmallVector<Expr *, 8> Vars; 10058 SmallVector<Expr *, 8> Privates; 10059 SmallVector<Expr *, 8> Inits; 10060 SmallVector<Decl *, 4> ExprCaptures; 10061 SmallVector<Expr *, 4> ExprPostUpdates; 10062 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 10063 LinKind = OMPC_LINEAR_val; 10064 for (auto &RefExpr : VarList) { 10065 assert(RefExpr && "NULL expr in OpenMP linear clause."); 10066 SourceLocation ELoc; 10067 SourceRange ERange; 10068 Expr *SimpleRefExpr = RefExpr; 10069 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 10070 /*AllowArraySection=*/false); 10071 if (Res.second) { 10072 // It will be analyzed later. 10073 Vars.push_back(RefExpr); 10074 Privates.push_back(nullptr); 10075 Inits.push_back(nullptr); 10076 } 10077 ValueDecl *D = Res.first; 10078 if (!D) 10079 continue; 10080 10081 QualType Type = D->getType(); 10082 auto *VD = dyn_cast<VarDecl>(D); 10083 10084 // OpenMP [2.14.3.7, linear clause] 10085 // A list-item cannot appear in more than one linear clause. 10086 // A list-item that appears in a linear clause cannot appear in any 10087 // other data-sharing attribute clause. 10088 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 10089 if (DVar.RefExpr) { 10090 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10091 << getOpenMPClauseName(OMPC_linear); 10092 ReportOriginalDSA(*this, DSAStack, D, DVar); 10093 continue; 10094 } 10095 10096 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 10097 continue; 10098 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 10099 10100 // Build private copy of original var. 10101 auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(), 10102 D->hasAttrs() ? &D->getAttrs() : nullptr); 10103 auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 10104 // Build var to save initial value. 10105 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 10106 Expr *InitExpr; 10107 DeclRefExpr *Ref = nullptr; 10108 if (!VD && !CurContext->isDependentContext()) { 10109 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10110 if (!IsOpenMPCapturedDecl(D)) { 10111 ExprCaptures.push_back(Ref->getDecl()); 10112 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 10113 ExprResult RefRes = DefaultLvalueConversion(Ref); 10114 if (!RefRes.isUsable()) 10115 continue; 10116 ExprResult PostUpdateRes = 10117 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 10118 SimpleRefExpr, RefRes.get()); 10119 if (!PostUpdateRes.isUsable()) 10120 continue; 10121 ExprPostUpdates.push_back( 10122 IgnoredValueConversions(PostUpdateRes.get()).get()); 10123 } 10124 } 10125 } 10126 if (LinKind == OMPC_LINEAR_uval) 10127 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 10128 else 10129 InitExpr = VD ? SimpleRefExpr : Ref; 10130 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 10131 /*DirectInit=*/false); 10132 auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 10133 10134 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 10135 Vars.push_back((VD || CurContext->isDependentContext()) 10136 ? RefExpr->IgnoreParens() 10137 : Ref); 10138 Privates.push_back(PrivateRef); 10139 Inits.push_back(InitRef); 10140 } 10141 10142 if (Vars.empty()) 10143 return nullptr; 10144 10145 Expr *StepExpr = Step; 10146 Expr *CalcStepExpr = nullptr; 10147 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 10148 !Step->isInstantiationDependent() && 10149 !Step->containsUnexpandedParameterPack()) { 10150 SourceLocation StepLoc = Step->getLocStart(); 10151 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 10152 if (Val.isInvalid()) 10153 return nullptr; 10154 StepExpr = Val.get(); 10155 10156 // Build var to save the step value. 10157 VarDecl *SaveVar = 10158 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 10159 ExprResult SaveRef = 10160 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 10161 ExprResult CalcStep = 10162 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 10163 CalcStep = ActOnFinishFullExpr(CalcStep.get()); 10164 10165 // Warn about zero linear step (it would be probably better specified as 10166 // making corresponding variables 'const'). 10167 llvm::APSInt Result; 10168 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 10169 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 10170 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 10171 << (Vars.size() > 1); 10172 if (!IsConstant && CalcStep.isUsable()) { 10173 // Calculate the step beforehand instead of doing this on each iteration. 10174 // (This is not used if the number of iterations may be kfold-ed). 10175 CalcStepExpr = CalcStep.get(); 10176 } 10177 } 10178 10179 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 10180 ColonLoc, EndLoc, Vars, Privates, Inits, 10181 StepExpr, CalcStepExpr, 10182 buildPreInits(Context, ExprCaptures), 10183 buildPostUpdate(*this, ExprPostUpdates)); 10184 } 10185 10186 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 10187 Expr *NumIterations, Sema &SemaRef, 10188 Scope *S, DSAStackTy *Stack) { 10189 // Walk the vars and build update/final expressions for the CodeGen. 10190 SmallVector<Expr *, 8> Updates; 10191 SmallVector<Expr *, 8> Finals; 10192 Expr *Step = Clause.getStep(); 10193 Expr *CalcStep = Clause.getCalcStep(); 10194 // OpenMP [2.14.3.7, linear clause] 10195 // If linear-step is not specified it is assumed to be 1. 10196 if (Step == nullptr) 10197 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 10198 else if (CalcStep) { 10199 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 10200 } 10201 bool HasErrors = false; 10202 auto CurInit = Clause.inits().begin(); 10203 auto CurPrivate = Clause.privates().begin(); 10204 auto LinKind = Clause.getModifier(); 10205 for (auto &RefExpr : Clause.varlists()) { 10206 SourceLocation ELoc; 10207 SourceRange ERange; 10208 Expr *SimpleRefExpr = RefExpr; 10209 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange, 10210 /*AllowArraySection=*/false); 10211 ValueDecl *D = Res.first; 10212 if (Res.second || !D) { 10213 Updates.push_back(nullptr); 10214 Finals.push_back(nullptr); 10215 HasErrors = true; 10216 continue; 10217 } 10218 auto &&Info = Stack->isLoopControlVariable(D); 10219 Expr *InitExpr = *CurInit; 10220 10221 // Build privatized reference to the current linear var. 10222 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 10223 Expr *CapturedRef; 10224 if (LinKind == OMPC_LINEAR_uval) 10225 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 10226 else 10227 CapturedRef = 10228 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 10229 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 10230 /*RefersToCapture=*/true); 10231 10232 // Build update: Var = InitExpr + IV * Step 10233 ExprResult Update; 10234 if (!Info.first) { 10235 Update = 10236 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 10237 InitExpr, IV, Step, /* Subtract */ false); 10238 } else 10239 Update = *CurPrivate; 10240 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(), 10241 /*DiscardedValue=*/true); 10242 10243 // Build final: Var = InitExpr + NumIterations * Step 10244 ExprResult Final; 10245 if (!Info.first) { 10246 Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 10247 InitExpr, NumIterations, Step, 10248 /* Subtract */ false); 10249 } else 10250 Final = *CurPrivate; 10251 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(), 10252 /*DiscardedValue=*/true); 10253 10254 if (!Update.isUsable() || !Final.isUsable()) { 10255 Updates.push_back(nullptr); 10256 Finals.push_back(nullptr); 10257 HasErrors = true; 10258 } else { 10259 Updates.push_back(Update.get()); 10260 Finals.push_back(Final.get()); 10261 } 10262 ++CurInit; 10263 ++CurPrivate; 10264 } 10265 Clause.setUpdates(Updates); 10266 Clause.setFinals(Finals); 10267 return HasErrors; 10268 } 10269 10270 OMPClause *Sema::ActOnOpenMPAlignedClause( 10271 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 10272 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 10273 10274 SmallVector<Expr *, 8> Vars; 10275 for (auto &RefExpr : VarList) { 10276 assert(RefExpr && "NULL expr in OpenMP linear clause."); 10277 SourceLocation ELoc; 10278 SourceRange ERange; 10279 Expr *SimpleRefExpr = RefExpr; 10280 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 10281 /*AllowArraySection=*/false); 10282 if (Res.second) { 10283 // It will be analyzed later. 10284 Vars.push_back(RefExpr); 10285 } 10286 ValueDecl *D = Res.first; 10287 if (!D) 10288 continue; 10289 10290 QualType QType = D->getType(); 10291 auto *VD = dyn_cast<VarDecl>(D); 10292 10293 // OpenMP [2.8.1, simd construct, Restrictions] 10294 // The type of list items appearing in the aligned clause must be 10295 // array, pointer, reference to array, or reference to pointer. 10296 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 10297 const Type *Ty = QType.getTypePtrOrNull(); 10298 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 10299 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 10300 << QType << getLangOpts().CPlusPlus << ERange; 10301 bool IsDecl = 10302 !VD || 10303 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10304 Diag(D->getLocation(), 10305 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10306 << D; 10307 continue; 10308 } 10309 10310 // OpenMP [2.8.1, simd construct, Restrictions] 10311 // A list-item cannot appear in more than one aligned clause. 10312 if (Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 10313 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 10314 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 10315 << getOpenMPClauseName(OMPC_aligned); 10316 continue; 10317 } 10318 10319 DeclRefExpr *Ref = nullptr; 10320 if (!VD && IsOpenMPCapturedDecl(D)) 10321 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10322 Vars.push_back(DefaultFunctionArrayConversion( 10323 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 10324 .get()); 10325 } 10326 10327 // OpenMP [2.8.1, simd construct, Description] 10328 // The parameter of the aligned clause, alignment, must be a constant 10329 // positive integer expression. 10330 // If no optional parameter is specified, implementation-defined default 10331 // alignments for SIMD instructions on the target platforms are assumed. 10332 if (Alignment != nullptr) { 10333 ExprResult AlignResult = 10334 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 10335 if (AlignResult.isInvalid()) 10336 return nullptr; 10337 Alignment = AlignResult.get(); 10338 } 10339 if (Vars.empty()) 10340 return nullptr; 10341 10342 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 10343 EndLoc, Vars, Alignment); 10344 } 10345 10346 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 10347 SourceLocation StartLoc, 10348 SourceLocation LParenLoc, 10349 SourceLocation EndLoc) { 10350 SmallVector<Expr *, 8> Vars; 10351 SmallVector<Expr *, 8> SrcExprs; 10352 SmallVector<Expr *, 8> DstExprs; 10353 SmallVector<Expr *, 8> AssignmentOps; 10354 for (auto &RefExpr : VarList) { 10355 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 10356 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 10357 // It will be analyzed later. 10358 Vars.push_back(RefExpr); 10359 SrcExprs.push_back(nullptr); 10360 DstExprs.push_back(nullptr); 10361 AssignmentOps.push_back(nullptr); 10362 continue; 10363 } 10364 10365 SourceLocation ELoc = RefExpr->getExprLoc(); 10366 // OpenMP [2.1, C/C++] 10367 // A list item is a variable name. 10368 // OpenMP [2.14.4.1, Restrictions, p.1] 10369 // A list item that appears in a copyin clause must be threadprivate. 10370 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 10371 if (!DE || !isa<VarDecl>(DE->getDecl())) { 10372 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 10373 << 0 << RefExpr->getSourceRange(); 10374 continue; 10375 } 10376 10377 Decl *D = DE->getDecl(); 10378 VarDecl *VD = cast<VarDecl>(D); 10379 10380 QualType Type = VD->getType(); 10381 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 10382 // It will be analyzed later. 10383 Vars.push_back(DE); 10384 SrcExprs.push_back(nullptr); 10385 DstExprs.push_back(nullptr); 10386 AssignmentOps.push_back(nullptr); 10387 continue; 10388 } 10389 10390 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 10391 // A list item that appears in a copyin clause must be threadprivate. 10392 if (!DSAStack->isThreadPrivate(VD)) { 10393 Diag(ELoc, diag::err_omp_required_access) 10394 << getOpenMPClauseName(OMPC_copyin) 10395 << getOpenMPDirectiveName(OMPD_threadprivate); 10396 continue; 10397 } 10398 10399 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 10400 // A variable of class type (or array thereof) that appears in a 10401 // copyin clause requires an accessible, unambiguous copy assignment 10402 // operator for the class type. 10403 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 10404 auto *SrcVD = 10405 buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(), 10406 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 10407 auto *PseudoSrcExpr = buildDeclRefExpr( 10408 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 10409 auto *DstVD = 10410 buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst", 10411 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 10412 auto *PseudoDstExpr = 10413 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 10414 // For arrays generate assignment operation for single element and replace 10415 // it by the original array element in CodeGen. 10416 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 10417 PseudoDstExpr, PseudoSrcExpr); 10418 if (AssignmentOp.isInvalid()) 10419 continue; 10420 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 10421 /*DiscardedValue=*/true); 10422 if (AssignmentOp.isInvalid()) 10423 continue; 10424 10425 DSAStack->addDSA(VD, DE, OMPC_copyin); 10426 Vars.push_back(DE); 10427 SrcExprs.push_back(PseudoSrcExpr); 10428 DstExprs.push_back(PseudoDstExpr); 10429 AssignmentOps.push_back(AssignmentOp.get()); 10430 } 10431 10432 if (Vars.empty()) 10433 return nullptr; 10434 10435 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 10436 SrcExprs, DstExprs, AssignmentOps); 10437 } 10438 10439 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 10440 SourceLocation StartLoc, 10441 SourceLocation LParenLoc, 10442 SourceLocation EndLoc) { 10443 SmallVector<Expr *, 8> Vars; 10444 SmallVector<Expr *, 8> SrcExprs; 10445 SmallVector<Expr *, 8> DstExprs; 10446 SmallVector<Expr *, 8> AssignmentOps; 10447 for (auto &RefExpr : VarList) { 10448 assert(RefExpr && "NULL expr in OpenMP linear clause."); 10449 SourceLocation ELoc; 10450 SourceRange ERange; 10451 Expr *SimpleRefExpr = RefExpr; 10452 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 10453 /*AllowArraySection=*/false); 10454 if (Res.second) { 10455 // It will be analyzed later. 10456 Vars.push_back(RefExpr); 10457 SrcExprs.push_back(nullptr); 10458 DstExprs.push_back(nullptr); 10459 AssignmentOps.push_back(nullptr); 10460 } 10461 ValueDecl *D = Res.first; 10462 if (!D) 10463 continue; 10464 10465 QualType Type = D->getType(); 10466 auto *VD = dyn_cast<VarDecl>(D); 10467 10468 // OpenMP [2.14.4.2, Restrictions, p.2] 10469 // A list item that appears in a copyprivate clause may not appear in a 10470 // private or firstprivate clause on the single construct. 10471 if (!VD || !DSAStack->isThreadPrivate(VD)) { 10472 auto DVar = DSAStack->getTopDSA(D, false); 10473 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 10474 DVar.RefExpr) { 10475 Diag(ELoc, diag::err_omp_wrong_dsa) 10476 << getOpenMPClauseName(DVar.CKind) 10477 << getOpenMPClauseName(OMPC_copyprivate); 10478 ReportOriginalDSA(*this, DSAStack, D, DVar); 10479 continue; 10480 } 10481 10482 // OpenMP [2.11.4.2, Restrictions, p.1] 10483 // All list items that appear in a copyprivate clause must be either 10484 // threadprivate or private in the enclosing context. 10485 if (DVar.CKind == OMPC_unknown) { 10486 DVar = DSAStack->getImplicitDSA(D, false); 10487 if (DVar.CKind == OMPC_shared) { 10488 Diag(ELoc, diag::err_omp_required_access) 10489 << getOpenMPClauseName(OMPC_copyprivate) 10490 << "threadprivate or private in the enclosing context"; 10491 ReportOriginalDSA(*this, DSAStack, D, DVar); 10492 continue; 10493 } 10494 } 10495 } 10496 10497 // Variably modified types are not supported. 10498 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 10499 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10500 << getOpenMPClauseName(OMPC_copyprivate) << Type 10501 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10502 bool IsDecl = 10503 !VD || 10504 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10505 Diag(D->getLocation(), 10506 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10507 << D; 10508 continue; 10509 } 10510 10511 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 10512 // A variable of class type (or array thereof) that appears in a 10513 // copyin clause requires an accessible, unambiguous copy assignment 10514 // operator for the class type. 10515 Type = Context.getBaseElementType(Type.getNonReferenceType()) 10516 .getUnqualifiedType(); 10517 auto *SrcVD = 10518 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src", 10519 D->hasAttrs() ? &D->getAttrs() : nullptr); 10520 auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 10521 auto *DstVD = 10522 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst", 10523 D->hasAttrs() ? &D->getAttrs() : nullptr); 10524 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 10525 auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 10526 PseudoDstExpr, PseudoSrcExpr); 10527 if (AssignmentOp.isInvalid()) 10528 continue; 10529 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 10530 /*DiscardedValue=*/true); 10531 if (AssignmentOp.isInvalid()) 10532 continue; 10533 10534 // No need to mark vars as copyprivate, they are already threadprivate or 10535 // implicitly private. 10536 assert(VD || IsOpenMPCapturedDecl(D)); 10537 Vars.push_back( 10538 VD ? RefExpr->IgnoreParens() 10539 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 10540 SrcExprs.push_back(PseudoSrcExpr); 10541 DstExprs.push_back(PseudoDstExpr); 10542 AssignmentOps.push_back(AssignmentOp.get()); 10543 } 10544 10545 if (Vars.empty()) 10546 return nullptr; 10547 10548 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10549 Vars, SrcExprs, DstExprs, AssignmentOps); 10550 } 10551 10552 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 10553 SourceLocation StartLoc, 10554 SourceLocation LParenLoc, 10555 SourceLocation EndLoc) { 10556 if (VarList.empty()) 10557 return nullptr; 10558 10559 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 10560 } 10561 10562 OMPClause * 10563 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 10564 SourceLocation DepLoc, SourceLocation ColonLoc, 10565 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 10566 SourceLocation LParenLoc, SourceLocation EndLoc) { 10567 if (DSAStack->getCurrentDirective() == OMPD_ordered && 10568 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 10569 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 10570 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 10571 return nullptr; 10572 } 10573 if (DSAStack->getCurrentDirective() != OMPD_ordered && 10574 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 10575 DepKind == OMPC_DEPEND_sink)) { 10576 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 10577 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 10578 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 10579 /*Last=*/OMPC_DEPEND_unknown, Except) 10580 << getOpenMPClauseName(OMPC_depend); 10581 return nullptr; 10582 } 10583 SmallVector<Expr *, 8> Vars; 10584 DSAStackTy::OperatorOffsetTy OpsOffs; 10585 llvm::APSInt DepCounter(/*BitWidth=*/32); 10586 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 10587 if (DepKind == OMPC_DEPEND_sink) { 10588 if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) { 10589 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 10590 TotalDepCount.setIsUnsigned(/*Val=*/true); 10591 } 10592 } 10593 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) || 10594 DSAStack->getParentOrderedRegionParam()) { 10595 for (auto &RefExpr : VarList) { 10596 assert(RefExpr && "NULL expr in OpenMP shared clause."); 10597 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 10598 // It will be analyzed later. 10599 Vars.push_back(RefExpr); 10600 continue; 10601 } 10602 10603 SourceLocation ELoc = RefExpr->getExprLoc(); 10604 auto *SimpleExpr = RefExpr->IgnoreParenCasts(); 10605 if (DepKind == OMPC_DEPEND_sink) { 10606 if (DepCounter >= TotalDepCount) { 10607 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 10608 continue; 10609 } 10610 ++DepCounter; 10611 // OpenMP [2.13.9, Summary] 10612 // depend(dependence-type : vec), where dependence-type is: 10613 // 'sink' and where vec is the iteration vector, which has the form: 10614 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 10615 // where n is the value specified by the ordered clause in the loop 10616 // directive, xi denotes the loop iteration variable of the i-th nested 10617 // loop associated with the loop directive, and di is a constant 10618 // non-negative integer. 10619 if (CurContext->isDependentContext()) { 10620 // It will be analyzed later. 10621 Vars.push_back(RefExpr); 10622 continue; 10623 } 10624 SimpleExpr = SimpleExpr->IgnoreImplicit(); 10625 OverloadedOperatorKind OOK = OO_None; 10626 SourceLocation OOLoc; 10627 Expr *LHS = SimpleExpr; 10628 Expr *RHS = nullptr; 10629 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 10630 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 10631 OOLoc = BO->getOperatorLoc(); 10632 LHS = BO->getLHS()->IgnoreParenImpCasts(); 10633 RHS = BO->getRHS()->IgnoreParenImpCasts(); 10634 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 10635 OOK = OCE->getOperator(); 10636 OOLoc = OCE->getOperatorLoc(); 10637 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 10638 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 10639 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 10640 OOK = MCE->getMethodDecl() 10641 ->getNameInfo() 10642 .getName() 10643 .getCXXOverloadedOperator(); 10644 OOLoc = MCE->getCallee()->getExprLoc(); 10645 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 10646 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 10647 } 10648 SourceLocation ELoc; 10649 SourceRange ERange; 10650 auto Res = getPrivateItem(*this, LHS, ELoc, ERange, 10651 /*AllowArraySection=*/false); 10652 if (Res.second) { 10653 // It will be analyzed later. 10654 Vars.push_back(RefExpr); 10655 } 10656 ValueDecl *D = Res.first; 10657 if (!D) 10658 continue; 10659 10660 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 10661 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 10662 continue; 10663 } 10664 if (RHS) { 10665 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 10666 RHS, OMPC_depend, /*StrictlyPositive=*/false); 10667 if (RHSRes.isInvalid()) 10668 continue; 10669 } 10670 if (!CurContext->isDependentContext() && 10671 DSAStack->getParentOrderedRegionParam() && 10672 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 10673 ValueDecl* VD = DSAStack->getParentLoopControlVariable( 10674 DepCounter.getZExtValue()); 10675 if (VD) { 10676 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 10677 << 1 << VD; 10678 } else { 10679 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 10680 } 10681 continue; 10682 } 10683 OpsOffs.push_back({RHS, OOK}); 10684 } else { 10685 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 10686 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 10687 (ASE && 10688 !ASE->getBase() 10689 ->getType() 10690 .getNonReferenceType() 10691 ->isPointerType() && 10692 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 10693 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 10694 << RefExpr->getSourceRange(); 10695 continue; 10696 } 10697 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 10698 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 10699 ExprResult Res = CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, 10700 RefExpr->IgnoreParenImpCasts()); 10701 getDiagnostics().setSuppressAllDiagnostics(Suppress); 10702 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 10703 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 10704 << RefExpr->getSourceRange(); 10705 continue; 10706 } 10707 } 10708 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 10709 } 10710 10711 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 10712 TotalDepCount > VarList.size() && 10713 DSAStack->getParentOrderedRegionParam() && 10714 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 10715 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) << 1 10716 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 10717 } 10718 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 10719 Vars.empty()) 10720 return nullptr; 10721 } 10722 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10723 DepKind, DepLoc, ColonLoc, Vars); 10724 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) 10725 DSAStack->addDoacrossDependClause(C, OpsOffs); 10726 return C; 10727 } 10728 10729 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 10730 SourceLocation LParenLoc, 10731 SourceLocation EndLoc) { 10732 Expr *ValExpr = Device; 10733 Stmt *HelperValStmt = nullptr; 10734 10735 // OpenMP [2.9.1, Restrictions] 10736 // The device expression must evaluate to a non-negative integer value. 10737 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 10738 /*StrictlyPositive=*/false)) 10739 return nullptr; 10740 10741 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10742 if (isOpenMPTargetExecutionDirective(DKind) && 10743 !CurContext->isDependentContext()) { 10744 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 10745 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10746 HelperValStmt = buildPreInits(Context, Captures); 10747 } 10748 10749 return new (Context) 10750 OMPDeviceClause(ValExpr, HelperValStmt, StartLoc, LParenLoc, EndLoc); 10751 } 10752 10753 static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 10754 DSAStackTy *Stack, QualType QTy) { 10755 NamedDecl *ND; 10756 if (QTy->isIncompleteType(&ND)) { 10757 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 10758 return false; 10759 } 10760 return true; 10761 } 10762 10763 /// \brief Return true if it can be proven that the provided array expression 10764 /// (array section or array subscript) does NOT specify the whole size of the 10765 /// array whose base type is \a BaseQTy. 10766 static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 10767 const Expr *E, 10768 QualType BaseQTy) { 10769 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 10770 10771 // If this is an array subscript, it refers to the whole size if the size of 10772 // the dimension is constant and equals 1. Also, an array section assumes the 10773 // format of an array subscript if no colon is used. 10774 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 10775 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 10776 return ATy->getSize().getSExtValue() != 1; 10777 // Size can't be evaluated statically. 10778 return false; 10779 } 10780 10781 assert(OASE && "Expecting array section if not an array subscript."); 10782 auto *LowerBound = OASE->getLowerBound(); 10783 auto *Length = OASE->getLength(); 10784 10785 // If there is a lower bound that does not evaluates to zero, we are not 10786 // covering the whole dimension. 10787 if (LowerBound) { 10788 llvm::APSInt ConstLowerBound; 10789 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) 10790 return false; // Can't get the integer value as a constant. 10791 if (ConstLowerBound.getSExtValue()) 10792 return true; 10793 } 10794 10795 // If we don't have a length we covering the whole dimension. 10796 if (!Length) 10797 return false; 10798 10799 // If the base is a pointer, we don't have a way to get the size of the 10800 // pointee. 10801 if (BaseQTy->isPointerType()) 10802 return false; 10803 10804 // We can only check if the length is the same as the size of the dimension 10805 // if we have a constant array. 10806 auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 10807 if (!CATy) 10808 return false; 10809 10810 llvm::APSInt ConstLength; 10811 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 10812 return false; // Can't get the integer value as a constant. 10813 10814 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 10815 } 10816 10817 // Return true if it can be proven that the provided array expression (array 10818 // section or array subscript) does NOT specify a single element of the array 10819 // whose base type is \a BaseQTy. 10820 static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 10821 const Expr *E, 10822 QualType BaseQTy) { 10823 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 10824 10825 // An array subscript always refer to a single element. Also, an array section 10826 // assumes the format of an array subscript if no colon is used. 10827 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 10828 return false; 10829 10830 assert(OASE && "Expecting array section if not an array subscript."); 10831 auto *Length = OASE->getLength(); 10832 10833 // If we don't have a length we have to check if the array has unitary size 10834 // for this dimension. Also, we should always expect a length if the base type 10835 // is pointer. 10836 if (!Length) { 10837 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 10838 return ATy->getSize().getSExtValue() != 1; 10839 // We cannot assume anything. 10840 return false; 10841 } 10842 10843 // Check if the length evaluates to 1. 10844 llvm::APSInt ConstLength; 10845 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 10846 return false; // Can't get the integer value as a constant. 10847 10848 return ConstLength.getSExtValue() != 1; 10849 } 10850 10851 // Return the expression of the base of the mappable expression or null if it 10852 // cannot be determined and do all the necessary checks to see if the expression 10853 // is valid as a standalone mappable expression. In the process, record all the 10854 // components of the expression. 10855 static Expr *CheckMapClauseExpressionBase( 10856 Sema &SemaRef, Expr *E, 10857 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 10858 OpenMPClauseKind CKind) { 10859 SourceLocation ELoc = E->getExprLoc(); 10860 SourceRange ERange = E->getSourceRange(); 10861 10862 // The base of elements of list in a map clause have to be either: 10863 // - a reference to variable or field. 10864 // - a member expression. 10865 // - an array expression. 10866 // 10867 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 10868 // reference to 'r'. 10869 // 10870 // If we have: 10871 // 10872 // struct SS { 10873 // Bla S; 10874 // foo() { 10875 // #pragma omp target map (S.Arr[:12]); 10876 // } 10877 // } 10878 // 10879 // We want to retrieve the member expression 'this->S'; 10880 10881 Expr *RelevantExpr = nullptr; 10882 10883 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 10884 // If a list item is an array section, it must specify contiguous storage. 10885 // 10886 // For this restriction it is sufficient that we make sure only references 10887 // to variables or fields and array expressions, and that no array sections 10888 // exist except in the rightmost expression (unless they cover the whole 10889 // dimension of the array). E.g. these would be invalid: 10890 // 10891 // r.ArrS[3:5].Arr[6:7] 10892 // 10893 // r.ArrS[3:5].x 10894 // 10895 // but these would be valid: 10896 // r.ArrS[3].Arr[6:7] 10897 // 10898 // r.ArrS[3].x 10899 10900 bool AllowUnitySizeArraySection = true; 10901 bool AllowWholeSizeArraySection = true; 10902 10903 while (!RelevantExpr) { 10904 E = E->IgnoreParenImpCasts(); 10905 10906 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 10907 if (!isa<VarDecl>(CurE->getDecl())) 10908 break; 10909 10910 RelevantExpr = CurE; 10911 10912 // If we got a reference to a declaration, we should not expect any array 10913 // section before that. 10914 AllowUnitySizeArraySection = false; 10915 AllowWholeSizeArraySection = false; 10916 10917 // Record the component. 10918 CurComponents.push_back(OMPClauseMappableExprCommon::MappableComponent( 10919 CurE, CurE->getDecl())); 10920 continue; 10921 } 10922 10923 if (auto *CurE = dyn_cast<MemberExpr>(E)) { 10924 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 10925 10926 if (isa<CXXThisExpr>(BaseE)) 10927 // We found a base expression: this->Val. 10928 RelevantExpr = CurE; 10929 else 10930 E = BaseE; 10931 10932 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 10933 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 10934 << CurE->getSourceRange(); 10935 break; 10936 } 10937 10938 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 10939 10940 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 10941 // A bit-field cannot appear in a map clause. 10942 // 10943 if (FD->isBitField()) { 10944 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 10945 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 10946 break; 10947 } 10948 10949 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 10950 // If the type of a list item is a reference to a type T then the type 10951 // will be considered to be T for all purposes of this clause. 10952 QualType CurType = BaseE->getType().getNonReferenceType(); 10953 10954 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 10955 // A list item cannot be a variable that is a member of a structure with 10956 // a union type. 10957 // 10958 if (auto *RT = CurType->getAs<RecordType>()) 10959 if (RT->isUnionType()) { 10960 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 10961 << CurE->getSourceRange(); 10962 break; 10963 } 10964 10965 // If we got a member expression, we should not expect any array section 10966 // before that: 10967 // 10968 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 10969 // If a list item is an element of a structure, only the rightmost symbol 10970 // of the variable reference can be an array section. 10971 // 10972 AllowUnitySizeArraySection = false; 10973 AllowWholeSizeArraySection = false; 10974 10975 // Record the component. 10976 CurComponents.push_back( 10977 OMPClauseMappableExprCommon::MappableComponent(CurE, FD)); 10978 continue; 10979 } 10980 10981 if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 10982 E = CurE->getBase()->IgnoreParenImpCasts(); 10983 10984 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 10985 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 10986 << 0 << CurE->getSourceRange(); 10987 break; 10988 } 10989 10990 // If we got an array subscript that express the whole dimension we 10991 // can have any array expressions before. If it only expressing part of 10992 // the dimension, we can only have unitary-size array expressions. 10993 if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 10994 E->getType())) 10995 AllowWholeSizeArraySection = false; 10996 10997 // Record the component - we don't have any declaration associated. 10998 CurComponents.push_back( 10999 OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); 11000 continue; 11001 } 11002 11003 if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 11004 E = CurE->getBase()->IgnoreParenImpCasts(); 11005 11006 auto CurType = 11007 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 11008 11009 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 11010 // If the type of a list item is a reference to a type T then the type 11011 // will be considered to be T for all purposes of this clause. 11012 if (CurType->isReferenceType()) 11013 CurType = CurType->getPointeeType(); 11014 11015 bool IsPointer = CurType->isAnyPointerType(); 11016 11017 if (!IsPointer && !CurType->isArrayType()) { 11018 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 11019 << 0 << CurE->getSourceRange(); 11020 break; 11021 } 11022 11023 bool NotWhole = 11024 CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 11025 bool NotUnity = 11026 CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 11027 11028 if (AllowWholeSizeArraySection) { 11029 // Any array section is currently allowed. Allowing a whole size array 11030 // section implies allowing a unity array section as well. 11031 // 11032 // If this array section refers to the whole dimension we can still 11033 // accept other array sections before this one, except if the base is a 11034 // pointer. Otherwise, only unitary sections are accepted. 11035 if (NotWhole || IsPointer) 11036 AllowWholeSizeArraySection = false; 11037 } else if (AllowUnitySizeArraySection && NotUnity) { 11038 // A unity or whole array section is not allowed and that is not 11039 // compatible with the properties of the current array section. 11040 SemaRef.Diag( 11041 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 11042 << CurE->getSourceRange(); 11043 break; 11044 } 11045 11046 // Record the component - we don't have any declaration associated. 11047 CurComponents.push_back( 11048 OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); 11049 continue; 11050 } 11051 11052 // If nothing else worked, this is not a valid map clause expression. 11053 SemaRef.Diag(ELoc, 11054 diag::err_omp_expected_named_var_member_or_array_expression) 11055 << ERange; 11056 break; 11057 } 11058 11059 return RelevantExpr; 11060 } 11061 11062 // Return true if expression E associated with value VD has conflicts with other 11063 // map information. 11064 static bool CheckMapConflicts( 11065 Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E, 11066 bool CurrentRegionOnly, 11067 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 11068 OpenMPClauseKind CKind) { 11069 assert(VD && E); 11070 SourceLocation ELoc = E->getExprLoc(); 11071 SourceRange ERange = E->getSourceRange(); 11072 11073 // In order to easily check the conflicts we need to match each component of 11074 // the expression under test with the components of the expressions that are 11075 // already in the stack. 11076 11077 assert(!CurComponents.empty() && "Map clause expression with no components!"); 11078 assert(CurComponents.back().getAssociatedDeclaration() == VD && 11079 "Map clause expression with unexpected base!"); 11080 11081 // Variables to help detecting enclosing problems in data environment nests. 11082 bool IsEnclosedByDataEnvironmentExpr = false; 11083 const Expr *EnclosingExpr = nullptr; 11084 11085 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 11086 VD, CurrentRegionOnly, 11087 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef 11088 StackComponents, 11089 OpenMPClauseKind) -> bool { 11090 11091 assert(!StackComponents.empty() && 11092 "Map clause expression with no components!"); 11093 assert(StackComponents.back().getAssociatedDeclaration() == VD && 11094 "Map clause expression with unexpected base!"); 11095 11096 // The whole expression in the stack. 11097 auto *RE = StackComponents.front().getAssociatedExpression(); 11098 11099 // Expressions must start from the same base. Here we detect at which 11100 // point both expressions diverge from each other and see if we can 11101 // detect if the memory referred to both expressions is contiguous and 11102 // do not overlap. 11103 auto CI = CurComponents.rbegin(); 11104 auto CE = CurComponents.rend(); 11105 auto SI = StackComponents.rbegin(); 11106 auto SE = StackComponents.rend(); 11107 for (; CI != CE && SI != SE; ++CI, ++SI) { 11108 11109 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 11110 // At most one list item can be an array item derived from a given 11111 // variable in map clauses of the same construct. 11112 if (CurrentRegionOnly && 11113 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 11114 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 11115 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 11116 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 11117 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 11118 diag::err_omp_multiple_array_items_in_map_clause) 11119 << CI->getAssociatedExpression()->getSourceRange(); 11120 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 11121 diag::note_used_here) 11122 << SI->getAssociatedExpression()->getSourceRange(); 11123 return true; 11124 } 11125 11126 // Do both expressions have the same kind? 11127 if (CI->getAssociatedExpression()->getStmtClass() != 11128 SI->getAssociatedExpression()->getStmtClass()) 11129 break; 11130 11131 // Are we dealing with different variables/fields? 11132 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 11133 break; 11134 } 11135 // Check if the extra components of the expressions in the enclosing 11136 // data environment are redundant for the current base declaration. 11137 // If they are, the maps completely overlap, which is legal. 11138 for (; SI != SE; ++SI) { 11139 QualType Type; 11140 if (auto *ASE = 11141 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 11142 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 11143 } else if (auto *OASE = dyn_cast<OMPArraySectionExpr>( 11144 SI->getAssociatedExpression())) { 11145 auto *E = OASE->getBase()->IgnoreParenImpCasts(); 11146 Type = 11147 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 11148 } 11149 if (Type.isNull() || Type->isAnyPointerType() || 11150 CheckArrayExpressionDoesNotReferToWholeSize( 11151 SemaRef, SI->getAssociatedExpression(), Type)) 11152 break; 11153 } 11154 11155 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 11156 // List items of map clauses in the same construct must not share 11157 // original storage. 11158 // 11159 // If the expressions are exactly the same or one is a subset of the 11160 // other, it means they are sharing storage. 11161 if (CI == CE && SI == SE) { 11162 if (CurrentRegionOnly) { 11163 if (CKind == OMPC_map) 11164 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 11165 else { 11166 assert(CKind == OMPC_to || CKind == OMPC_from); 11167 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 11168 << ERange; 11169 } 11170 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 11171 << RE->getSourceRange(); 11172 return true; 11173 } else { 11174 // If we find the same expression in the enclosing data environment, 11175 // that is legal. 11176 IsEnclosedByDataEnvironmentExpr = true; 11177 return false; 11178 } 11179 } 11180 11181 QualType DerivedType = 11182 std::prev(CI)->getAssociatedDeclaration()->getType(); 11183 SourceLocation DerivedLoc = 11184 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 11185 11186 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 11187 // If the type of a list item is a reference to a type T then the type 11188 // will be considered to be T for all purposes of this clause. 11189 DerivedType = DerivedType.getNonReferenceType(); 11190 11191 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 11192 // A variable for which the type is pointer and an array section 11193 // derived from that variable must not appear as list items of map 11194 // clauses of the same construct. 11195 // 11196 // Also, cover one of the cases in: 11197 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 11198 // If any part of the original storage of a list item has corresponding 11199 // storage in the device data environment, all of the original storage 11200 // must have corresponding storage in the device data environment. 11201 // 11202 if (DerivedType->isAnyPointerType()) { 11203 if (CI == CE || SI == SE) { 11204 SemaRef.Diag( 11205 DerivedLoc, 11206 diag::err_omp_pointer_mapped_along_with_derived_section) 11207 << DerivedLoc; 11208 } else { 11209 assert(CI != CE && SI != SE); 11210 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced) 11211 << DerivedLoc; 11212 } 11213 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 11214 << RE->getSourceRange(); 11215 return true; 11216 } 11217 11218 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 11219 // List items of map clauses in the same construct must not share 11220 // original storage. 11221 // 11222 // An expression is a subset of the other. 11223 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 11224 if (CKind == OMPC_map) 11225 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 11226 else { 11227 assert(CKind == OMPC_to || CKind == OMPC_from); 11228 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 11229 << ERange; 11230 } 11231 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 11232 << RE->getSourceRange(); 11233 return true; 11234 } 11235 11236 // The current expression uses the same base as other expression in the 11237 // data environment but does not contain it completely. 11238 if (!CurrentRegionOnly && SI != SE) 11239 EnclosingExpr = RE; 11240 11241 // The current expression is a subset of the expression in the data 11242 // environment. 11243 IsEnclosedByDataEnvironmentExpr |= 11244 (!CurrentRegionOnly && CI != CE && SI == SE); 11245 11246 return false; 11247 }); 11248 11249 if (CurrentRegionOnly) 11250 return FoundError; 11251 11252 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 11253 // If any part of the original storage of a list item has corresponding 11254 // storage in the device data environment, all of the original storage must 11255 // have corresponding storage in the device data environment. 11256 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 11257 // If a list item is an element of a structure, and a different element of 11258 // the structure has a corresponding list item in the device data environment 11259 // prior to a task encountering the construct associated with the map clause, 11260 // then the list item must also have a corresponding list item in the device 11261 // data environment prior to the task encountering the construct. 11262 // 11263 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 11264 SemaRef.Diag(ELoc, 11265 diag::err_omp_original_storage_is_shared_and_does_not_contain) 11266 << ERange; 11267 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 11268 << EnclosingExpr->getSourceRange(); 11269 return true; 11270 } 11271 11272 return FoundError; 11273 } 11274 11275 namespace { 11276 // Utility struct that gathers all the related lists associated with a mappable 11277 // expression. 11278 struct MappableVarListInfo final { 11279 // The list of expressions. 11280 ArrayRef<Expr *> VarList; 11281 // The list of processed expressions. 11282 SmallVector<Expr *, 16> ProcessedVarList; 11283 // The mappble components for each expression. 11284 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 11285 // The base declaration of the variable. 11286 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 11287 11288 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 11289 // We have a list of components and base declarations for each entry in the 11290 // variable list. 11291 VarComponents.reserve(VarList.size()); 11292 VarBaseDeclarations.reserve(VarList.size()); 11293 } 11294 }; 11295 } 11296 11297 // Check the validity of the provided variable list for the provided clause kind 11298 // \a CKind. In the check process the valid expressions, and mappable expression 11299 // components and variables are extracted and used to fill \a Vars, 11300 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and 11301 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'. 11302 static void 11303 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, 11304 OpenMPClauseKind CKind, MappableVarListInfo &MVLI, 11305 SourceLocation StartLoc, 11306 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 11307 bool IsMapTypeImplicit = false) { 11308 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 11309 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 11310 "Unexpected clause kind with mappable expressions!"); 11311 11312 // Keep track of the mappable components and base declarations in this clause. 11313 // Each entry in the list is going to have a list of components associated. We 11314 // record each set of the components so that we can build the clause later on. 11315 // In the end we should have the same amount of declarations and component 11316 // lists. 11317 11318 for (auto &RE : MVLI.VarList) { 11319 assert(RE && "Null expr in omp to/from/map clause"); 11320 SourceLocation ELoc = RE->getExprLoc(); 11321 11322 auto *VE = RE->IgnoreParenLValueCasts(); 11323 11324 if (VE->isValueDependent() || VE->isTypeDependent() || 11325 VE->isInstantiationDependent() || 11326 VE->containsUnexpandedParameterPack()) { 11327 // We can only analyze this information once the missing information is 11328 // resolved. 11329 MVLI.ProcessedVarList.push_back(RE); 11330 continue; 11331 } 11332 11333 auto *SimpleExpr = RE->IgnoreParenCasts(); 11334 11335 if (!RE->IgnoreParenImpCasts()->isLValue()) { 11336 SemaRef.Diag(ELoc, 11337 diag::err_omp_expected_named_var_member_or_array_expression) 11338 << RE->getSourceRange(); 11339 continue; 11340 } 11341 11342 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 11343 ValueDecl *CurDeclaration = nullptr; 11344 11345 // Obtain the array or member expression bases if required. Also, fill the 11346 // components array with all the components identified in the process. 11347 auto *BE = 11348 CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind); 11349 if (!BE) 11350 continue; 11351 11352 assert(!CurComponents.empty() && 11353 "Invalid mappable expression information."); 11354 11355 // For the following checks, we rely on the base declaration which is 11356 // expected to be associated with the last component. The declaration is 11357 // expected to be a variable or a field (if 'this' is being mapped). 11358 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 11359 assert(CurDeclaration && "Null decl on map clause."); 11360 assert( 11361 CurDeclaration->isCanonicalDecl() && 11362 "Expecting components to have associated only canonical declarations."); 11363 11364 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 11365 auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 11366 11367 assert((VD || FD) && "Only variables or fields are expected here!"); 11368 (void)FD; 11369 11370 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 11371 // threadprivate variables cannot appear in a map clause. 11372 // OpenMP 4.5 [2.10.5, target update Construct] 11373 // threadprivate variables cannot appear in a from clause. 11374 if (VD && DSAS->isThreadPrivate(VD)) { 11375 auto DVar = DSAS->getTopDSA(VD, false); 11376 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 11377 << getOpenMPClauseName(CKind); 11378 ReportOriginalDSA(SemaRef, DSAS, VD, DVar); 11379 continue; 11380 } 11381 11382 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 11383 // A list item cannot appear in both a map clause and a data-sharing 11384 // attribute clause on the same construct. 11385 11386 // Check conflicts with other map clause expressions. We check the conflicts 11387 // with the current construct separately from the enclosing data 11388 // environment, because the restrictions are different. We only have to 11389 // check conflicts across regions for the map clauses. 11390 if (CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 11391 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 11392 break; 11393 if (CKind == OMPC_map && 11394 CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 11395 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 11396 break; 11397 11398 // OpenMP 4.5 [2.10.5, target update Construct] 11399 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 11400 // If the type of a list item is a reference to a type T then the type will 11401 // be considered to be T for all purposes of this clause. 11402 QualType Type = CurDeclaration->getType().getNonReferenceType(); 11403 11404 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 11405 // A list item in a to or from clause must have a mappable type. 11406 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 11407 // A list item must have a mappable type. 11408 if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 11409 DSAS, Type)) 11410 continue; 11411 11412 if (CKind == OMPC_map) { 11413 // target enter data 11414 // OpenMP [2.10.2, Restrictions, p. 99] 11415 // A map-type must be specified in all map clauses and must be either 11416 // to or alloc. 11417 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 11418 if (DKind == OMPD_target_enter_data && 11419 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 11420 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 11421 << (IsMapTypeImplicit ? 1 : 0) 11422 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 11423 << getOpenMPDirectiveName(DKind); 11424 continue; 11425 } 11426 11427 // target exit_data 11428 // OpenMP [2.10.3, Restrictions, p. 102] 11429 // A map-type must be specified in all map clauses and must be either 11430 // from, release, or delete. 11431 if (DKind == OMPD_target_exit_data && 11432 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 11433 MapType == OMPC_MAP_delete)) { 11434 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 11435 << (IsMapTypeImplicit ? 1 : 0) 11436 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 11437 << getOpenMPDirectiveName(DKind); 11438 continue; 11439 } 11440 11441 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11442 // A list item cannot appear in both a map clause and a data-sharing 11443 // attribute clause on the same construct 11444 if ((DKind == OMPD_target || DKind == OMPD_target_teams || 11445 DKind == OMPD_target_teams_distribute || 11446 DKind == OMPD_target_teams_distribute_parallel_for || 11447 DKind == OMPD_target_teams_distribute_parallel_for_simd || 11448 DKind == OMPD_target_teams_distribute_simd) && VD) { 11449 auto DVar = DSAS->getTopDSA(VD, false); 11450 if (isOpenMPPrivate(DVar.CKind)) { 11451 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11452 << getOpenMPClauseName(DVar.CKind) 11453 << getOpenMPClauseName(OMPC_map) 11454 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 11455 ReportOriginalDSA(SemaRef, DSAS, CurDeclaration, DVar); 11456 continue; 11457 } 11458 } 11459 } 11460 11461 // Save the current expression. 11462 MVLI.ProcessedVarList.push_back(RE); 11463 11464 // Store the components in the stack so that they can be used to check 11465 // against other clauses later on. 11466 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 11467 /*WhereFoundClauseKind=*/OMPC_map); 11468 11469 // Save the components and declaration to create the clause. For purposes of 11470 // the clause creation, any component list that has has base 'this' uses 11471 // null as base declaration. 11472 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 11473 MVLI.VarComponents.back().append(CurComponents.begin(), 11474 CurComponents.end()); 11475 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 11476 : CurDeclaration); 11477 } 11478 } 11479 11480 OMPClause * 11481 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, 11482 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 11483 SourceLocation MapLoc, SourceLocation ColonLoc, 11484 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 11485 SourceLocation LParenLoc, SourceLocation EndLoc) { 11486 MappableVarListInfo MVLI(VarList); 11487 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc, 11488 MapType, IsMapTypeImplicit); 11489 11490 // We need to produce a map clause even if we don't have variables so that 11491 // other diagnostics related with non-existing map clauses are accurate. 11492 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11493 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 11494 MVLI.VarComponents, MapTypeModifier, MapType, 11495 IsMapTypeImplicit, MapLoc); 11496 } 11497 11498 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 11499 TypeResult ParsedType) { 11500 assert(ParsedType.isUsable()); 11501 11502 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 11503 if (ReductionType.isNull()) 11504 return QualType(); 11505 11506 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 11507 // A type name in a declare reduction directive cannot be a function type, an 11508 // array type, a reference type, or a type qualified with const, volatile or 11509 // restrict. 11510 if (ReductionType.hasQualifiers()) { 11511 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 11512 return QualType(); 11513 } 11514 11515 if (ReductionType->isFunctionType()) { 11516 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 11517 return QualType(); 11518 } 11519 if (ReductionType->isReferenceType()) { 11520 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 11521 return QualType(); 11522 } 11523 if (ReductionType->isArrayType()) { 11524 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 11525 return QualType(); 11526 } 11527 return ReductionType; 11528 } 11529 11530 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 11531 Scope *S, DeclContext *DC, DeclarationName Name, 11532 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 11533 AccessSpecifier AS, Decl *PrevDeclInScope) { 11534 SmallVector<Decl *, 8> Decls; 11535 Decls.reserve(ReductionTypes.size()); 11536 11537 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 11538 ForRedeclaration); 11539 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 11540 // A reduction-identifier may not be re-declared in the current scope for the 11541 // same type or for a type that is compatible according to the base language 11542 // rules. 11543 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 11544 OMPDeclareReductionDecl *PrevDRD = nullptr; 11545 bool InCompoundScope = true; 11546 if (S != nullptr) { 11547 // Find previous declaration with the same name not referenced in other 11548 // declarations. 11549 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 11550 InCompoundScope = 11551 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 11552 LookupName(Lookup, S); 11553 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 11554 /*AllowInlineNamespace=*/false); 11555 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 11556 auto Filter = Lookup.makeFilter(); 11557 while (Filter.hasNext()) { 11558 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 11559 if (InCompoundScope) { 11560 auto I = UsedAsPrevious.find(PrevDecl); 11561 if (I == UsedAsPrevious.end()) 11562 UsedAsPrevious[PrevDecl] = false; 11563 if (auto *D = PrevDecl->getPrevDeclInScope()) 11564 UsedAsPrevious[D] = true; 11565 } 11566 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 11567 PrevDecl->getLocation(); 11568 } 11569 Filter.done(); 11570 if (InCompoundScope) { 11571 for (auto &PrevData : UsedAsPrevious) { 11572 if (!PrevData.second) { 11573 PrevDRD = PrevData.first; 11574 break; 11575 } 11576 } 11577 } 11578 } else if (PrevDeclInScope != nullptr) { 11579 auto *PrevDRDInScope = PrevDRD = 11580 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 11581 do { 11582 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 11583 PrevDRDInScope->getLocation(); 11584 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 11585 } while (PrevDRDInScope != nullptr); 11586 } 11587 for (auto &TyData : ReductionTypes) { 11588 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 11589 bool Invalid = false; 11590 if (I != PreviousRedeclTypes.end()) { 11591 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 11592 << TyData.first; 11593 Diag(I->second, diag::note_previous_definition); 11594 Invalid = true; 11595 } 11596 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 11597 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 11598 Name, TyData.first, PrevDRD); 11599 DC->addDecl(DRD); 11600 DRD->setAccess(AS); 11601 Decls.push_back(DRD); 11602 if (Invalid) 11603 DRD->setInvalidDecl(); 11604 else 11605 PrevDRD = DRD; 11606 } 11607 11608 return DeclGroupPtrTy::make( 11609 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 11610 } 11611 11612 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 11613 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11614 11615 // Enter new function scope. 11616 PushFunctionScope(); 11617 getCurFunction()->setHasBranchProtectedScope(); 11618 getCurFunction()->setHasOMPDeclareReductionCombiner(); 11619 11620 if (S != nullptr) 11621 PushDeclContext(S, DRD); 11622 else 11623 CurContext = DRD; 11624 11625 PushExpressionEvaluationContext( 11626 ExpressionEvaluationContext::PotentiallyEvaluated); 11627 11628 QualType ReductionType = DRD->getType(); 11629 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 11630 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 11631 // uses semantics of argument handles by value, but it should be passed by 11632 // reference. C lang does not support references, so pass all parameters as 11633 // pointers. 11634 // Create 'T omp_in;' variable. 11635 auto *OmpInParm = 11636 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 11637 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 11638 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 11639 // uses semantics of argument handles by value, but it should be passed by 11640 // reference. C lang does not support references, so pass all parameters as 11641 // pointers. 11642 // Create 'T omp_out;' variable. 11643 auto *OmpOutParm = 11644 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 11645 if (S != nullptr) { 11646 PushOnScopeChains(OmpInParm, S); 11647 PushOnScopeChains(OmpOutParm, S); 11648 } else { 11649 DRD->addDecl(OmpInParm); 11650 DRD->addDecl(OmpOutParm); 11651 } 11652 } 11653 11654 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 11655 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11656 DiscardCleanupsInEvaluationContext(); 11657 PopExpressionEvaluationContext(); 11658 11659 PopDeclContext(); 11660 PopFunctionScopeInfo(); 11661 11662 if (Combiner != nullptr) 11663 DRD->setCombiner(Combiner); 11664 else 11665 DRD->setInvalidDecl(); 11666 } 11667 11668 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 11669 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11670 11671 // Enter new function scope. 11672 PushFunctionScope(); 11673 getCurFunction()->setHasBranchProtectedScope(); 11674 11675 if (S != nullptr) 11676 PushDeclContext(S, DRD); 11677 else 11678 CurContext = DRD; 11679 11680 PushExpressionEvaluationContext( 11681 ExpressionEvaluationContext::PotentiallyEvaluated); 11682 11683 QualType ReductionType = DRD->getType(); 11684 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 11685 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 11686 // uses semantics of argument handles by value, but it should be passed by 11687 // reference. C lang does not support references, so pass all parameters as 11688 // pointers. 11689 // Create 'T omp_priv;' variable. 11690 auto *OmpPrivParm = 11691 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 11692 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 11693 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 11694 // uses semantics of argument handles by value, but it should be passed by 11695 // reference. C lang does not support references, so pass all parameters as 11696 // pointers. 11697 // Create 'T omp_orig;' variable. 11698 auto *OmpOrigParm = 11699 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 11700 if (S != nullptr) { 11701 PushOnScopeChains(OmpPrivParm, S); 11702 PushOnScopeChains(OmpOrigParm, S); 11703 } else { 11704 DRD->addDecl(OmpPrivParm); 11705 DRD->addDecl(OmpOrigParm); 11706 } 11707 return OmpPrivParm; 11708 } 11709 11710 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 11711 VarDecl *OmpPrivParm) { 11712 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11713 DiscardCleanupsInEvaluationContext(); 11714 PopExpressionEvaluationContext(); 11715 11716 PopDeclContext(); 11717 PopFunctionScopeInfo(); 11718 11719 if (Initializer != nullptr) { 11720 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 11721 } else if (OmpPrivParm->hasInit()) { 11722 DRD->setInitializer(OmpPrivParm->getInit(), 11723 OmpPrivParm->isDirectInit() 11724 ? OMPDeclareReductionDecl::DirectInit 11725 : OMPDeclareReductionDecl::CopyInit); 11726 } else { 11727 DRD->setInvalidDecl(); 11728 } 11729 } 11730 11731 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 11732 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 11733 for (auto *D : DeclReductions.get()) { 11734 if (IsValid) { 11735 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11736 if (S != nullptr) 11737 PushOnScopeChains(DRD, S, /*AddToContext=*/false); 11738 } else 11739 D->setInvalidDecl(); 11740 } 11741 return DeclReductions; 11742 } 11743 11744 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 11745 SourceLocation StartLoc, 11746 SourceLocation LParenLoc, 11747 SourceLocation EndLoc) { 11748 Expr *ValExpr = NumTeams; 11749 Stmt *HelperValStmt = nullptr; 11750 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11751 11752 // OpenMP [teams Constrcut, Restrictions] 11753 // The num_teams expression must evaluate to a positive integer value. 11754 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 11755 /*StrictlyPositive=*/true)) 11756 return nullptr; 11757 11758 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11759 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 11760 if (CaptureRegion != OMPD_unknown) { 11761 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 11762 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11763 HelperValStmt = buildPreInits(Context, Captures); 11764 } 11765 11766 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 11767 StartLoc, LParenLoc, EndLoc); 11768 } 11769 11770 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 11771 SourceLocation StartLoc, 11772 SourceLocation LParenLoc, 11773 SourceLocation EndLoc) { 11774 Expr *ValExpr = ThreadLimit; 11775 Stmt *HelperValStmt = nullptr; 11776 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11777 11778 // OpenMP [teams Constrcut, Restrictions] 11779 // The thread_limit expression must evaluate to a positive integer value. 11780 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 11781 /*StrictlyPositive=*/true)) 11782 return nullptr; 11783 11784 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11785 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 11786 if (CaptureRegion != OMPD_unknown) { 11787 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 11788 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11789 HelperValStmt = buildPreInits(Context, Captures); 11790 } 11791 11792 return new (Context) OMPThreadLimitClause( 11793 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11794 } 11795 11796 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 11797 SourceLocation StartLoc, 11798 SourceLocation LParenLoc, 11799 SourceLocation EndLoc) { 11800 Expr *ValExpr = Priority; 11801 11802 // OpenMP [2.9.1, task Constrcut] 11803 // The priority-value is a non-negative numerical scalar expression. 11804 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 11805 /*StrictlyPositive=*/false)) 11806 return nullptr; 11807 11808 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 11809 } 11810 11811 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 11812 SourceLocation StartLoc, 11813 SourceLocation LParenLoc, 11814 SourceLocation EndLoc) { 11815 Expr *ValExpr = Grainsize; 11816 11817 // OpenMP [2.9.2, taskloop Constrcut] 11818 // The parameter of the grainsize clause must be a positive integer 11819 // expression. 11820 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 11821 /*StrictlyPositive=*/true)) 11822 return nullptr; 11823 11824 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 11825 } 11826 11827 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 11828 SourceLocation StartLoc, 11829 SourceLocation LParenLoc, 11830 SourceLocation EndLoc) { 11831 Expr *ValExpr = NumTasks; 11832 11833 // OpenMP [2.9.2, taskloop Constrcut] 11834 // The parameter of the num_tasks clause must be a positive integer 11835 // expression. 11836 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 11837 /*StrictlyPositive=*/true)) 11838 return nullptr; 11839 11840 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 11841 } 11842 11843 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 11844 SourceLocation LParenLoc, 11845 SourceLocation EndLoc) { 11846 // OpenMP [2.13.2, critical construct, Description] 11847 // ... where hint-expression is an integer constant expression that evaluates 11848 // to a valid lock hint. 11849 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 11850 if (HintExpr.isInvalid()) 11851 return nullptr; 11852 return new (Context) 11853 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 11854 } 11855 11856 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 11857 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11858 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 11859 SourceLocation EndLoc) { 11860 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 11861 std::string Values; 11862 Values += "'"; 11863 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 11864 Values += "'"; 11865 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11866 << Values << getOpenMPClauseName(OMPC_dist_schedule); 11867 return nullptr; 11868 } 11869 Expr *ValExpr = ChunkSize; 11870 Stmt *HelperValStmt = nullptr; 11871 if (ChunkSize) { 11872 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11873 !ChunkSize->isInstantiationDependent() && 11874 !ChunkSize->containsUnexpandedParameterPack()) { 11875 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 11876 ExprResult Val = 11877 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11878 if (Val.isInvalid()) 11879 return nullptr; 11880 11881 ValExpr = Val.get(); 11882 11883 // OpenMP [2.7.1, Restrictions] 11884 // chunk_size must be a loop invariant integer expression with a positive 11885 // value. 11886 llvm::APSInt Result; 11887 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11888 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11889 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11890 << "dist_schedule" << ChunkSize->getSourceRange(); 11891 return nullptr; 11892 } 11893 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) && 11894 !CurContext->isDependentContext()) { 11895 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 11896 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11897 HelperValStmt = buildPreInits(Context, Captures); 11898 } 11899 } 11900 } 11901 11902 return new (Context) 11903 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 11904 Kind, ValExpr, HelperValStmt); 11905 } 11906 11907 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 11908 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 11909 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 11910 SourceLocation KindLoc, SourceLocation EndLoc) { 11911 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 11912 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 11913 std::string Value; 11914 SourceLocation Loc; 11915 Value += "'"; 11916 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 11917 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 11918 OMPC_DEFAULTMAP_MODIFIER_tofrom); 11919 Loc = MLoc; 11920 } else { 11921 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 11922 OMPC_DEFAULTMAP_scalar); 11923 Loc = KindLoc; 11924 } 11925 Value += "'"; 11926 Diag(Loc, diag::err_omp_unexpected_clause_value) 11927 << Value << getOpenMPClauseName(OMPC_defaultmap); 11928 return nullptr; 11929 } 11930 DSAStack->setDefaultDMAToFromScalar(StartLoc); 11931 11932 return new (Context) 11933 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 11934 } 11935 11936 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 11937 DeclContext *CurLexicalContext = getCurLexicalContext(); 11938 if (!CurLexicalContext->isFileContext() && 11939 !CurLexicalContext->isExternCContext() && 11940 !CurLexicalContext->isExternCXXContext() && 11941 !isa<CXXRecordDecl>(CurLexicalContext) && 11942 !isa<ClassTemplateDecl>(CurLexicalContext) && 11943 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 11944 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 11945 Diag(Loc, diag::err_omp_region_not_file_context); 11946 return false; 11947 } 11948 if (IsInOpenMPDeclareTargetContext) { 11949 Diag(Loc, diag::err_omp_enclosed_declare_target); 11950 return false; 11951 } 11952 11953 IsInOpenMPDeclareTargetContext = true; 11954 return true; 11955 } 11956 11957 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 11958 assert(IsInOpenMPDeclareTargetContext && 11959 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 11960 11961 IsInOpenMPDeclareTargetContext = false; 11962 } 11963 11964 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 11965 CXXScopeSpec &ScopeSpec, 11966 const DeclarationNameInfo &Id, 11967 OMPDeclareTargetDeclAttr::MapTypeTy MT, 11968 NamedDeclSetType &SameDirectiveDecls) { 11969 LookupResult Lookup(*this, Id, LookupOrdinaryName); 11970 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 11971 11972 if (Lookup.isAmbiguous()) 11973 return; 11974 Lookup.suppressDiagnostics(); 11975 11976 if (!Lookup.isSingleResult()) { 11977 if (TypoCorrection Corrected = 11978 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, 11979 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), 11980 CTK_ErrorRecovery)) { 11981 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 11982 << Id.getName()); 11983 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 11984 return; 11985 } 11986 11987 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 11988 return; 11989 } 11990 11991 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 11992 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { 11993 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 11994 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 11995 11996 if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) { 11997 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 11998 ND->addAttr(A); 11999 if (ASTMutationListener *ML = Context.getASTMutationListener()) 12000 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 12001 checkDeclIsAllowedInOpenMPTarget(nullptr, ND); 12002 } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) { 12003 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 12004 << Id.getName(); 12005 } 12006 } else 12007 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 12008 } 12009 12010 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 12011 Sema &SemaRef, Decl *D) { 12012 if (!D) 12013 return; 12014 Decl *LD = nullptr; 12015 if (isa<TagDecl>(D)) { 12016 LD = cast<TagDecl>(D)->getDefinition(); 12017 } else if (isa<VarDecl>(D)) { 12018 LD = cast<VarDecl>(D)->getDefinition(); 12019 12020 // If this is an implicit variable that is legal and we do not need to do 12021 // anything. 12022 if (cast<VarDecl>(D)->isImplicit()) { 12023 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12024 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 12025 D->addAttr(A); 12026 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 12027 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 12028 return; 12029 } 12030 12031 } else if (isa<FunctionDecl>(D)) { 12032 const FunctionDecl *FD = nullptr; 12033 if (cast<FunctionDecl>(D)->hasBody(FD)) 12034 LD = const_cast<FunctionDecl *>(FD); 12035 12036 // If the definition is associated with the current declaration in the 12037 // target region (it can be e.g. a lambda) that is legal and we do not need 12038 // to do anything else. 12039 if (LD == D) { 12040 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12041 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 12042 D->addAttr(A); 12043 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 12044 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 12045 return; 12046 } 12047 } 12048 if (!LD) 12049 LD = D; 12050 if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() && 12051 (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) { 12052 // Outlined declaration is not declared target. 12053 if (LD->isOutOfLine()) { 12054 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 12055 SemaRef.Diag(SL, diag::note_used_here) << SR; 12056 } else { 12057 DeclContext *DC = LD->getDeclContext(); 12058 while (DC) { 12059 if (isa<FunctionDecl>(DC) && 12060 cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>()) 12061 break; 12062 DC = DC->getParent(); 12063 } 12064 if (DC) 12065 return; 12066 12067 // Is not declared in target context. 12068 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 12069 SemaRef.Diag(SL, diag::note_used_here) << SR; 12070 } 12071 // Mark decl as declared target to prevent further diagnostic. 12072 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12073 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 12074 D->addAttr(A); 12075 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 12076 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 12077 } 12078 } 12079 12080 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 12081 Sema &SemaRef, DSAStackTy *Stack, 12082 ValueDecl *VD) { 12083 if (VD->hasAttr<OMPDeclareTargetDeclAttr>()) 12084 return true; 12085 if (!CheckTypeMappable(SL, SR, SemaRef, Stack, VD->getType())) 12086 return false; 12087 return true; 12088 } 12089 12090 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D) { 12091 if (!D || D->isInvalidDecl()) 12092 return; 12093 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 12094 SourceLocation SL = E ? E->getLocStart() : D->getLocation(); 12095 // 2.10.6: threadprivate variable cannot appear in a declare target directive. 12096 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 12097 if (DSAStack->isThreadPrivate(VD)) { 12098 Diag(SL, diag::err_omp_threadprivate_in_target); 12099 ReportOriginalDSA(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 12100 return; 12101 } 12102 } 12103 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 12104 // Problem if any with var declared with incomplete type will be reported 12105 // as normal, so no need to check it here. 12106 if ((E || !VD->getType()->isIncompleteType()) && 12107 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) { 12108 // Mark decl as declared target to prevent further diagnostic. 12109 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) { 12110 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12111 Context, OMPDeclareTargetDeclAttr::MT_To); 12112 VD->addAttr(A); 12113 if (ASTMutationListener *ML = Context.getASTMutationListener()) 12114 ML->DeclarationMarkedOpenMPDeclareTarget(VD, A); 12115 } 12116 return; 12117 } 12118 } 12119 if (!E) { 12120 // Checking declaration inside declare target region. 12121 if (!D->hasAttr<OMPDeclareTargetDeclAttr>() && 12122 (isa<VarDecl>(D) || isa<FunctionDecl>(D))) { 12123 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12124 Context, OMPDeclareTargetDeclAttr::MT_To); 12125 D->addAttr(A); 12126 if (ASTMutationListener *ML = Context.getASTMutationListener()) 12127 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 12128 } 12129 return; 12130 } 12131 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 12132 } 12133 12134 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 12135 SourceLocation StartLoc, 12136 SourceLocation LParenLoc, 12137 SourceLocation EndLoc) { 12138 MappableVarListInfo MVLI(VarList); 12139 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc); 12140 if (MVLI.ProcessedVarList.empty()) 12141 return nullptr; 12142 12143 return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12144 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 12145 MVLI.VarComponents); 12146 } 12147 12148 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 12149 SourceLocation StartLoc, 12150 SourceLocation LParenLoc, 12151 SourceLocation EndLoc) { 12152 MappableVarListInfo MVLI(VarList); 12153 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc); 12154 if (MVLI.ProcessedVarList.empty()) 12155 return nullptr; 12156 12157 return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12158 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 12159 MVLI.VarComponents); 12160 } 12161 12162 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 12163 SourceLocation StartLoc, 12164 SourceLocation LParenLoc, 12165 SourceLocation EndLoc) { 12166 MappableVarListInfo MVLI(VarList); 12167 SmallVector<Expr *, 8> PrivateCopies; 12168 SmallVector<Expr *, 8> Inits; 12169 12170 for (auto &RefExpr : VarList) { 12171 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 12172 SourceLocation ELoc; 12173 SourceRange ERange; 12174 Expr *SimpleRefExpr = RefExpr; 12175 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12176 if (Res.second) { 12177 // It will be analyzed later. 12178 MVLI.ProcessedVarList.push_back(RefExpr); 12179 PrivateCopies.push_back(nullptr); 12180 Inits.push_back(nullptr); 12181 } 12182 ValueDecl *D = Res.first; 12183 if (!D) 12184 continue; 12185 12186 QualType Type = D->getType(); 12187 Type = Type.getNonReferenceType().getUnqualifiedType(); 12188 12189 auto *VD = dyn_cast<VarDecl>(D); 12190 12191 // Item should be a pointer or reference to pointer. 12192 if (!Type->isPointerType()) { 12193 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 12194 << 0 << RefExpr->getSourceRange(); 12195 continue; 12196 } 12197 12198 // Build the private variable and the expression that refers to it. 12199 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 12200 D->hasAttrs() ? &D->getAttrs() : nullptr); 12201 if (VDPrivate->isInvalidDecl()) 12202 continue; 12203 12204 CurContext->addDecl(VDPrivate); 12205 auto VDPrivateRefExpr = buildDeclRefExpr( 12206 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12207 12208 // Add temporary variable to initialize the private copy of the pointer. 12209 auto *VDInit = 12210 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 12211 auto *VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12212 RefExpr->getExprLoc()); 12213 AddInitializerToDecl(VDPrivate, 12214 DefaultLvalueConversion(VDInitRefExpr).get(), 12215 /*DirectInit=*/false); 12216 12217 // If required, build a capture to implement the privatization initialized 12218 // with the current list item value. 12219 DeclRefExpr *Ref = nullptr; 12220 if (!VD) 12221 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12222 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 12223 PrivateCopies.push_back(VDPrivateRefExpr); 12224 Inits.push_back(VDInitRefExpr); 12225 12226 // We need to add a data sharing attribute for this variable to make sure it 12227 // is correctly captured. A variable that shows up in a use_device_ptr has 12228 // similar properties of a first private variable. 12229 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12230 12231 // Create a mappable component for the list item. List items in this clause 12232 // only need a component. 12233 MVLI.VarBaseDeclarations.push_back(D); 12234 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 12235 MVLI.VarComponents.back().push_back( 12236 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 12237 } 12238 12239 if (MVLI.ProcessedVarList.empty()) 12240 return nullptr; 12241 12242 return OMPUseDevicePtrClause::Create( 12243 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 12244 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents); 12245 } 12246 12247 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 12248 SourceLocation StartLoc, 12249 SourceLocation LParenLoc, 12250 SourceLocation EndLoc) { 12251 MappableVarListInfo MVLI(VarList); 12252 for (auto &RefExpr : VarList) { 12253 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 12254 SourceLocation ELoc; 12255 SourceRange ERange; 12256 Expr *SimpleRefExpr = RefExpr; 12257 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12258 if (Res.second) { 12259 // It will be analyzed later. 12260 MVLI.ProcessedVarList.push_back(RefExpr); 12261 } 12262 ValueDecl *D = Res.first; 12263 if (!D) 12264 continue; 12265 12266 QualType Type = D->getType(); 12267 // item should be a pointer or array or reference to pointer or array 12268 if (!Type.getNonReferenceType()->isPointerType() && 12269 !Type.getNonReferenceType()->isArrayType()) { 12270 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 12271 << 0 << RefExpr->getSourceRange(); 12272 continue; 12273 } 12274 12275 // Check if the declaration in the clause does not show up in any data 12276 // sharing attribute. 12277 auto DVar = DSAStack->getTopDSA(D, false); 12278 if (isOpenMPPrivate(DVar.CKind)) { 12279 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12280 << getOpenMPClauseName(DVar.CKind) 12281 << getOpenMPClauseName(OMPC_is_device_ptr) 12282 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12283 ReportOriginalDSA(*this, DSAStack, D, DVar); 12284 continue; 12285 } 12286 12287 Expr *ConflictExpr; 12288 if (DSAStack->checkMappableExprComponentListsForDecl( 12289 D, /*CurrentRegionOnly=*/true, 12290 [&ConflictExpr]( 12291 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 12292 OpenMPClauseKind) -> bool { 12293 ConflictExpr = R.front().getAssociatedExpression(); 12294 return true; 12295 })) { 12296 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 12297 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 12298 << ConflictExpr->getSourceRange(); 12299 continue; 12300 } 12301 12302 // Store the components in the stack so that they can be used to check 12303 // against other clauses later on. 12304 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 12305 DSAStack->addMappableExpressionComponents( 12306 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 12307 12308 // Record the expression we've just processed. 12309 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 12310 12311 // Create a mappable component for the list item. List items in this clause 12312 // only need a component. We use a null declaration to signal fields in 12313 // 'this'. 12314 assert((isa<DeclRefExpr>(SimpleRefExpr) || 12315 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 12316 "Unexpected device pointer expression!"); 12317 MVLI.VarBaseDeclarations.push_back( 12318 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 12319 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 12320 MVLI.VarComponents.back().push_back(MC); 12321 } 12322 12323 if (MVLI.ProcessedVarList.empty()) 12324 return nullptr; 12325 12326 return OMPIsDevicePtrClause::Create( 12327 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 12328 MVLI.VarBaseDeclarations, MVLI.VarComponents); 12329 } 12330