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 /// \brief Stack for tracking declarations used in OpenMP directives and 52 /// clauses and their data-sharing attributes. 53 class DSAStackTy final { 54 public: 55 struct DSAVarData final { 56 OpenMPDirectiveKind DKind = OMPD_unknown; 57 OpenMPClauseKind CKind = OMPC_unknown; 58 Expr *RefExpr = nullptr; 59 DeclRefExpr *PrivateCopy = nullptr; 60 SourceLocation ImplicitDSALoc; 61 DSAVarData() = default; 62 DSAVarData(OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, Expr *RefExpr, 63 DeclRefExpr *PrivateCopy, SourceLocation ImplicitDSALoc) 64 : DKind(DKind), CKind(CKind), RefExpr(RefExpr), 65 PrivateCopy(PrivateCopy), ImplicitDSALoc(ImplicitDSALoc) {} 66 }; 67 typedef llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4> 68 OperatorOffsetTy; 69 70 private: 71 struct DSAInfo final { 72 OpenMPClauseKind Attributes = OMPC_unknown; 73 /// Pointer to a reference expression and a flag which shows that the 74 /// variable is marked as lastprivate(true) or not (false). 75 llvm::PointerIntPair<Expr *, 1, bool> RefExpr; 76 DeclRefExpr *PrivateCopy = nullptr; 77 }; 78 typedef llvm::DenseMap<ValueDecl *, DSAInfo> DeclSAMapTy; 79 typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy; 80 typedef std::pair<unsigned, VarDecl *> LCDeclInfo; 81 typedef llvm::DenseMap<ValueDecl *, LCDeclInfo> LoopControlVariablesMapTy; 82 /// Struct that associates a component with the clause kind where they are 83 /// found. 84 struct MappedExprComponentTy { 85 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 86 OpenMPClauseKind Kind = OMPC_unknown; 87 }; 88 typedef llvm::DenseMap<ValueDecl *, MappedExprComponentTy> 89 MappedExprComponentsTy; 90 typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>> 91 CriticalsWithHintsTy; 92 typedef llvm::DenseMap<OMPDependClause *, OperatorOffsetTy> 93 DoacrossDependMapTy; 94 struct ReductionData { 95 typedef llvm::PointerEmbeddedInt<BinaryOperatorKind, 16> BOKPtrType; 96 SourceRange ReductionRange; 97 llvm::PointerUnion<const Expr *, BOKPtrType> ReductionOp; 98 ReductionData() = default; 99 void set(BinaryOperatorKind BO, SourceRange RR) { 100 ReductionRange = RR; 101 ReductionOp = BO; 102 } 103 void set(const Expr *RefExpr, SourceRange RR) { 104 ReductionRange = RR; 105 ReductionOp = RefExpr; 106 } 107 }; 108 typedef llvm::DenseMap<ValueDecl *, ReductionData> DeclReductionMapTy; 109 110 struct SharingMapTy final { 111 DeclSAMapTy SharingMap; 112 DeclReductionMapTy ReductionMap; 113 AlignedMapTy AlignedMap; 114 MappedExprComponentsTy MappedExprComponents; 115 LoopControlVariablesMapTy LCVMap; 116 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 117 SourceLocation DefaultAttrLoc; 118 OpenMPDirectiveKind Directive = OMPD_unknown; 119 DeclarationNameInfo DirectiveName; 120 Scope *CurScope = nullptr; 121 SourceLocation ConstructLoc; 122 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 123 /// get the data (loop counters etc.) about enclosing loop-based construct. 124 /// This data is required during codegen. 125 DoacrossDependMapTy DoacrossDepends; 126 /// \brief first argument (Expr *) contains optional argument of the 127 /// 'ordered' clause, the second one is true if the regions has 'ordered' 128 /// clause, false otherwise. 129 llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion; 130 bool NowaitRegion = false; 131 bool CancelRegion = false; 132 unsigned AssociatedLoops = 1; 133 SourceLocation InnerTeamsRegionLoc; 134 /// Reference to the taskgroup task_reduction reference expression. 135 Expr *TaskgroupReductionRef = nullptr; 136 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 137 Scope *CurScope, SourceLocation Loc) 138 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 139 ConstructLoc(Loc) {} 140 SharingMapTy() = default; 141 }; 142 143 typedef SmallVector<SharingMapTy, 4> StackTy; 144 145 /// \brief Stack of used declaration and their data-sharing attributes. 146 DeclSAMapTy Threadprivates; 147 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 148 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 149 /// \brief true, if check for DSA must be from parent directive, false, if 150 /// from current directive. 151 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 152 Sema &SemaRef; 153 bool ForceCapturing = false; 154 CriticalsWithHintsTy Criticals; 155 156 typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; 157 158 DSAVarData getDSA(StackTy::reverse_iterator &Iter, ValueDecl *D); 159 160 /// \brief Checks if the variable is a local for OpenMP region. 161 bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter); 162 163 bool isStackEmpty() const { 164 return Stack.empty() || 165 Stack.back().second != CurrentNonCapturingFunctionScope || 166 Stack.back().first.empty(); 167 } 168 169 public: 170 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 171 172 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 173 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 174 175 bool isForceVarCapturing() const { return ForceCapturing; } 176 void setForceVarCapturing(bool V) { ForceCapturing = V; } 177 178 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 179 Scope *CurScope, SourceLocation Loc) { 180 if (Stack.empty() || 181 Stack.back().second != CurrentNonCapturingFunctionScope) 182 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 183 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 184 Stack.back().first.back().DefaultAttrLoc = Loc; 185 } 186 187 void pop() { 188 assert(!Stack.back().first.empty() && 189 "Data-sharing attributes stack is empty!"); 190 Stack.back().first.pop_back(); 191 } 192 193 /// Start new OpenMP region stack in new non-capturing function. 194 void pushFunction() { 195 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 196 assert(!isa<CapturingScopeInfo>(CurFnScope)); 197 CurrentNonCapturingFunctionScope = CurFnScope; 198 } 199 /// Pop region stack for non-capturing function. 200 void popFunction(const FunctionScopeInfo *OldFSI) { 201 if (!Stack.empty() && Stack.back().second == OldFSI) { 202 assert(Stack.back().first.empty()); 203 Stack.pop_back(); 204 } 205 CurrentNonCapturingFunctionScope = nullptr; 206 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 207 if (!isa<CapturingScopeInfo>(FSI)) { 208 CurrentNonCapturingFunctionScope = FSI; 209 break; 210 } 211 } 212 } 213 214 void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) { 215 Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint); 216 } 217 const std::pair<OMPCriticalDirective *, llvm::APSInt> 218 getCriticalWithHint(const DeclarationNameInfo &Name) const { 219 auto I = Criticals.find(Name.getAsString()); 220 if (I != Criticals.end()) 221 return I->second; 222 return std::make_pair(nullptr, llvm::APSInt()); 223 } 224 /// \brief If 'aligned' declaration for given variable \a D was not seen yet, 225 /// add it and return NULL; otherwise return previous occurrence's expression 226 /// for diagnostics. 227 Expr *addUniqueAligned(ValueDecl *D, Expr *NewDE); 228 229 /// \brief Register specified variable as loop control variable. 230 void addLoopControlVariable(ValueDecl *D, VarDecl *Capture); 231 /// \brief Check if the specified variable is a loop control variable for 232 /// current region. 233 /// \return The index of the loop control variable in the list of associated 234 /// for-loops (from outer to inner). 235 LCDeclInfo isLoopControlVariable(ValueDecl *D); 236 /// \brief Check if the specified variable is a loop control variable for 237 /// parent region. 238 /// \return The index of the loop control variable in the list of associated 239 /// for-loops (from outer to inner). 240 LCDeclInfo isParentLoopControlVariable(ValueDecl *D); 241 /// \brief Get the loop control variable for the I-th loop (or nullptr) in 242 /// parent directive. 243 ValueDecl *getParentLoopControlVariable(unsigned I); 244 245 /// \brief Adds explicit data sharing attribute to the specified declaration. 246 void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 247 DeclRefExpr *PrivateCopy = nullptr); 248 249 /// Adds additional information for the reduction items with the reduction id 250 /// represented as an operator. 251 void addTaskgroupReductionData(ValueDecl *D, SourceRange SR, 252 BinaryOperatorKind BOK); 253 /// Adds additional information for the reduction items with the reduction id 254 /// represented as reduction identifier. 255 void addTaskgroupReductionData(ValueDecl *D, SourceRange SR, 256 const Expr *ReductionRef); 257 /// Returns the location and reduction operation from the innermost parent 258 /// region for the given \p D. 259 DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, 260 BinaryOperatorKind &BOK, 261 Expr *&TaskgroupDescriptor); 262 /// Returns the location and reduction operation from the innermost parent 263 /// region for the given \p D. 264 DSAVarData getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, 265 const Expr *&ReductionRef, 266 Expr *&TaskgroupDescriptor); 267 /// Return reduction reference expression for the current taskgroup. 268 Expr *getTaskgroupReductionRef() const { 269 assert(Stack.back().first.back().Directive == OMPD_taskgroup && 270 "taskgroup reference expression requested for non taskgroup " 271 "directive."); 272 return Stack.back().first.back().TaskgroupReductionRef; 273 } 274 /// Checks if the given \p VD declaration is actually a taskgroup reduction 275 /// descriptor variable at the \p Level of OpenMP regions. 276 bool isTaskgroupReductionRef(ValueDecl *VD, unsigned Level) const { 277 return Stack.back().first[Level].TaskgroupReductionRef && 278 cast<DeclRefExpr>(Stack.back().first[Level].TaskgroupReductionRef) 279 ->getDecl() == VD; 280 } 281 282 /// \brief Returns data sharing attributes from top of the stack for the 283 /// specified declaration. 284 DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 285 /// \brief Returns data-sharing attributes for the specified declaration. 286 DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent); 287 /// \brief Checks if the specified variables has data-sharing attributes which 288 /// match specified \a CPred predicate in any directive which matches \a DPred 289 /// predicate. 290 DSAVarData hasDSA(ValueDecl *D, 291 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 292 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 293 bool FromParent); 294 /// \brief Checks if the specified variables has data-sharing attributes which 295 /// match specified \a CPred predicate in any innermost directive which 296 /// matches \a DPred predicate. 297 DSAVarData 298 hasInnermostDSA(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 explicit data-sharing 303 /// attributes which match specified \a CPred predicate at the specified 304 /// OpenMP region. 305 bool hasExplicitDSA(ValueDecl *D, 306 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 307 unsigned Level, bool NotLastprivate = false); 308 309 /// \brief Returns true if the directive at level \Level matches in the 310 /// specified \a DPred predicate. 311 bool hasExplicitDirective( 312 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 313 unsigned Level); 314 315 /// \brief Finds a directive which matches specified \a DPred predicate. 316 bool hasDirective(const llvm::function_ref<bool(OpenMPDirectiveKind, 317 const DeclarationNameInfo &, 318 SourceLocation)> &DPred, 319 bool FromParent); 320 321 /// \brief Returns currently analyzed directive. 322 OpenMPDirectiveKind getCurrentDirective() const { 323 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive; 324 } 325 /// \brief Returns parent directive. 326 OpenMPDirectiveKind getParentDirective() const { 327 if (isStackEmpty() || Stack.back().first.size() == 1) 328 return OMPD_unknown; 329 return std::next(Stack.back().first.rbegin())->Directive; 330 } 331 332 /// \brief Set default data sharing attribute to none. 333 void setDefaultDSANone(SourceLocation Loc) { 334 assert(!isStackEmpty()); 335 Stack.back().first.back().DefaultAttr = DSA_none; 336 Stack.back().first.back().DefaultAttrLoc = Loc; 337 } 338 /// \brief Set default data sharing attribute to shared. 339 void setDefaultDSAShared(SourceLocation Loc) { 340 assert(!isStackEmpty()); 341 Stack.back().first.back().DefaultAttr = DSA_shared; 342 Stack.back().first.back().DefaultAttrLoc = Loc; 343 } 344 345 DefaultDataSharingAttributes getDefaultDSA() const { 346 return isStackEmpty() ? DSA_unspecified 347 : Stack.back().first.back().DefaultAttr; 348 } 349 SourceLocation getDefaultDSALocation() const { 350 return isStackEmpty() ? SourceLocation() 351 : Stack.back().first.back().DefaultAttrLoc; 352 } 353 354 /// \brief Checks if the specified variable is a threadprivate. 355 bool isThreadPrivate(VarDecl *D) { 356 DSAVarData DVar = getTopDSA(D, false); 357 return isOpenMPThreadPrivate(DVar.CKind); 358 } 359 360 /// \brief Marks current region as ordered (it has an 'ordered' clause). 361 void setOrderedRegion(bool IsOrdered, Expr *Param) { 362 assert(!isStackEmpty()); 363 Stack.back().first.back().OrderedRegion.setInt(IsOrdered); 364 Stack.back().first.back().OrderedRegion.setPointer(Param); 365 } 366 /// \brief Returns true, if parent region is ordered (has associated 367 /// 'ordered' clause), false - otherwise. 368 bool isParentOrderedRegion() const { 369 if (isStackEmpty() || Stack.back().first.size() == 1) 370 return false; 371 return std::next(Stack.back().first.rbegin())->OrderedRegion.getInt(); 372 } 373 /// \brief Returns optional parameter for the ordered region. 374 Expr *getParentOrderedRegionParam() const { 375 if (isStackEmpty() || Stack.back().first.size() == 1) 376 return nullptr; 377 return std::next(Stack.back().first.rbegin())->OrderedRegion.getPointer(); 378 } 379 /// \brief Marks current region as nowait (it has a 'nowait' clause). 380 void setNowaitRegion(bool IsNowait = true) { 381 assert(!isStackEmpty()); 382 Stack.back().first.back().NowaitRegion = IsNowait; 383 } 384 /// \brief Returns true, if parent region is nowait (has associated 385 /// 'nowait' clause), false - otherwise. 386 bool isParentNowaitRegion() const { 387 if (isStackEmpty() || Stack.back().first.size() == 1) 388 return false; 389 return std::next(Stack.back().first.rbegin())->NowaitRegion; 390 } 391 /// \brief Marks parent region as cancel region. 392 void setParentCancelRegion(bool Cancel = true) { 393 if (!isStackEmpty() && Stack.back().first.size() > 1) { 394 auto &StackElemRef = *std::next(Stack.back().first.rbegin()); 395 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel; 396 } 397 } 398 /// \brief Return true if current region has inner cancel construct. 399 bool isCancelRegion() const { 400 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion; 401 } 402 403 /// \brief Set collapse value for the region. 404 void setAssociatedLoops(unsigned Val) { 405 assert(!isStackEmpty()); 406 Stack.back().first.back().AssociatedLoops = Val; 407 } 408 /// \brief Return collapse value for region. 409 unsigned getAssociatedLoops() const { 410 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops; 411 } 412 413 /// \brief Marks current target region as one with closely nested teams 414 /// region. 415 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 416 if (!isStackEmpty() && Stack.back().first.size() > 1) { 417 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc = 418 TeamsRegionLoc; 419 } 420 } 421 /// \brief Returns true, if current region has closely nested teams region. 422 bool hasInnerTeamsRegion() const { 423 return getInnerTeamsRegionLoc().isValid(); 424 } 425 /// \brief Returns location of the nested teams region (if any). 426 SourceLocation getInnerTeamsRegionLoc() const { 427 return isStackEmpty() ? SourceLocation() 428 : Stack.back().first.back().InnerTeamsRegionLoc; 429 } 430 431 Scope *getCurScope() const { 432 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 433 } 434 Scope *getCurScope() { 435 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 436 } 437 SourceLocation getConstructLoc() { 438 return isStackEmpty() ? SourceLocation() 439 : Stack.back().first.back().ConstructLoc; 440 } 441 442 /// Do the check specified in \a Check to all component lists and return true 443 /// if any issue is found. 444 bool checkMappableExprComponentListsForDecl( 445 ValueDecl *VD, bool CurrentRegionOnly, 446 const llvm::function_ref< 447 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 448 OpenMPClauseKind)> &Check) { 449 if (isStackEmpty()) 450 return false; 451 auto SI = Stack.back().first.rbegin(); 452 auto SE = Stack.back().first.rend(); 453 454 if (SI == SE) 455 return false; 456 457 if (CurrentRegionOnly) { 458 SE = std::next(SI); 459 } else { 460 ++SI; 461 } 462 463 for (; SI != SE; ++SI) { 464 auto MI = SI->MappedExprComponents.find(VD); 465 if (MI != SI->MappedExprComponents.end()) 466 for (auto &L : MI->second.Components) 467 if (Check(L, MI->second.Kind)) 468 return true; 469 } 470 return false; 471 } 472 473 /// Do the check specified in \a Check to all component lists at a given level 474 /// and return true if any issue is found. 475 bool checkMappableExprComponentListsForDeclAtLevel( 476 ValueDecl *VD, unsigned Level, 477 const llvm::function_ref< 478 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 479 OpenMPClauseKind)> &Check) { 480 if (isStackEmpty()) 481 return false; 482 483 auto StartI = Stack.back().first.begin(); 484 auto EndI = Stack.back().first.end(); 485 if (std::distance(StartI, EndI) <= (int)Level) 486 return false; 487 std::advance(StartI, Level); 488 489 auto MI = StartI->MappedExprComponents.find(VD); 490 if (MI != StartI->MappedExprComponents.end()) 491 for (auto &L : MI->second.Components) 492 if (Check(L, MI->second.Kind)) 493 return true; 494 return false; 495 } 496 497 /// Create a new mappable expression component list associated with a given 498 /// declaration and initialize it with the provided list of components. 499 void addMappableExpressionComponents( 500 ValueDecl *VD, 501 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 502 OpenMPClauseKind WhereFoundClauseKind) { 503 assert(!isStackEmpty() && 504 "Not expecting to retrieve components from a empty stack!"); 505 auto &MEC = Stack.back().first.back().MappedExprComponents[VD]; 506 // Create new entry and append the new components there. 507 MEC.Components.resize(MEC.Components.size() + 1); 508 MEC.Components.back().append(Components.begin(), Components.end()); 509 MEC.Kind = WhereFoundClauseKind; 510 } 511 512 unsigned getNestingLevel() const { 513 assert(!isStackEmpty()); 514 return Stack.back().first.size() - 1; 515 } 516 void addDoacrossDependClause(OMPDependClause *C, OperatorOffsetTy &OpsOffs) { 517 assert(!isStackEmpty() && Stack.back().first.size() > 1); 518 auto &StackElem = *std::next(Stack.back().first.rbegin()); 519 assert(isOpenMPWorksharingDirective(StackElem.Directive)); 520 StackElem.DoacrossDepends.insert({C, OpsOffs}); 521 } 522 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 523 getDoacrossDependClauses() const { 524 assert(!isStackEmpty()); 525 auto &StackElem = Stack.back().first.back(); 526 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 527 auto &Ref = StackElem.DoacrossDepends; 528 return llvm::make_range(Ref.begin(), Ref.end()); 529 } 530 return llvm::make_range(StackElem.DoacrossDepends.end(), 531 StackElem.DoacrossDepends.end()); 532 } 533 }; 534 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { 535 return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) || 536 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; 537 } 538 } // namespace 539 540 static Expr *getExprAsWritten(Expr *E) { 541 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) 542 E = ExprTemp->getSubExpr(); 543 544 if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 545 E = MTE->GetTemporaryExpr(); 546 547 while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 548 E = Binder->getSubExpr(); 549 550 if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 551 E = ICE->getSubExprAsWritten(); 552 return E->IgnoreParens(); 553 } 554 555 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 556 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) 557 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 558 D = ME->getMemberDecl(); 559 auto *VD = dyn_cast<VarDecl>(D); 560 auto *FD = dyn_cast<FieldDecl>(D); 561 if (VD != nullptr) { 562 VD = VD->getCanonicalDecl(); 563 D = VD; 564 } else { 565 assert(FD); 566 FD = FD->getCanonicalDecl(); 567 D = FD; 568 } 569 return D; 570 } 571 572 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter, 573 ValueDecl *D) { 574 D = getCanonicalDecl(D); 575 auto *VD = dyn_cast<VarDecl>(D); 576 auto *FD = dyn_cast<FieldDecl>(D); 577 DSAVarData DVar; 578 if (isStackEmpty() || Iter == Stack.back().first.rend()) { 579 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 580 // in a region but not in construct] 581 // File-scope or namespace-scope variables referenced in called routines 582 // in the region are shared unless they appear in a threadprivate 583 // directive. 584 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D)) 585 DVar.CKind = OMPC_shared; 586 587 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 588 // in a region but not in construct] 589 // Variables with static storage duration that are declared in called 590 // routines in the region are shared. 591 if (VD && VD->hasGlobalStorage()) 592 DVar.CKind = OMPC_shared; 593 594 // Non-static data members are shared by default. 595 if (FD) 596 DVar.CKind = OMPC_shared; 597 598 return DVar; 599 } 600 601 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 602 // in a Construct, C/C++, predetermined, p.1] 603 // Variables with automatic storage duration that are declared in a scope 604 // inside the construct are private. 605 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 606 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 607 DVar.CKind = OMPC_private; 608 return DVar; 609 } 610 611 DVar.DKind = Iter->Directive; 612 // Explicitly specified attributes and local variables with predetermined 613 // attributes. 614 if (Iter->SharingMap.count(D)) { 615 DVar.RefExpr = Iter->SharingMap[D].RefExpr.getPointer(); 616 DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy; 617 DVar.CKind = Iter->SharingMap[D].Attributes; 618 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 619 return DVar; 620 } 621 622 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 623 // in a Construct, C/C++, implicitly determined, p.1] 624 // In a parallel or task construct, the data-sharing attributes of these 625 // variables are determined by the default clause, if present. 626 switch (Iter->DefaultAttr) { 627 case DSA_shared: 628 DVar.CKind = OMPC_shared; 629 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 630 return DVar; 631 case DSA_none: 632 return DVar; 633 case DSA_unspecified: 634 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 635 // in a Construct, implicitly determined, p.2] 636 // In a parallel construct, if no default clause is present, these 637 // variables are shared. 638 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 639 if (isOpenMPParallelDirective(DVar.DKind) || 640 isOpenMPTeamsDirective(DVar.DKind)) { 641 DVar.CKind = OMPC_shared; 642 return DVar; 643 } 644 645 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 646 // in a Construct, implicitly determined, p.4] 647 // In a task construct, if no default clause is present, a variable that in 648 // the enclosing context is determined to be shared by all implicit tasks 649 // bound to the current team is shared. 650 if (isOpenMPTaskingDirective(DVar.DKind)) { 651 DSAVarData DVarTemp; 652 auto I = Iter, E = Stack.back().first.rend(); 653 do { 654 ++I; 655 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 656 // Referenced in a Construct, implicitly determined, p.6] 657 // In a task construct, if no default clause is present, a variable 658 // whose data-sharing attribute is not determined by the rules above is 659 // firstprivate. 660 DVarTemp = getDSA(I, D); 661 if (DVarTemp.CKind != OMPC_shared) { 662 DVar.RefExpr = nullptr; 663 DVar.CKind = OMPC_firstprivate; 664 return DVar; 665 } 666 } while (I != E && !isParallelOrTaskRegion(I->Directive)); 667 DVar.CKind = 668 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 669 return DVar; 670 } 671 } 672 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 673 // in a Construct, implicitly determined, p.3] 674 // For constructs other than task, if no default clause is present, these 675 // variables inherit their data-sharing attributes from the enclosing 676 // context. 677 return getDSA(++Iter, D); 678 } 679 680 Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) { 681 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 682 D = getCanonicalDecl(D); 683 auto &StackElem = Stack.back().first.back(); 684 auto It = StackElem.AlignedMap.find(D); 685 if (It == StackElem.AlignedMap.end()) { 686 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 687 StackElem.AlignedMap[D] = NewDE; 688 return nullptr; 689 } else { 690 assert(It->second && "Unexpected nullptr expr in the aligned map"); 691 return It->second; 692 } 693 return nullptr; 694 } 695 696 void DSAStackTy::addLoopControlVariable(ValueDecl *D, VarDecl *Capture) { 697 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 698 D = getCanonicalDecl(D); 699 auto &StackElem = Stack.back().first.back(); 700 StackElem.LCVMap.insert( 701 {D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)}); 702 } 703 704 DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(ValueDecl *D) { 705 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 706 D = getCanonicalDecl(D); 707 auto &StackElem = Stack.back().first.back(); 708 auto It = StackElem.LCVMap.find(D); 709 if (It != StackElem.LCVMap.end()) 710 return It->second; 711 return {0, nullptr}; 712 } 713 714 DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(ValueDecl *D) { 715 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 716 "Data-sharing attributes stack is empty"); 717 D = getCanonicalDecl(D); 718 auto &StackElem = *std::next(Stack.back().first.rbegin()); 719 auto It = StackElem.LCVMap.find(D); 720 if (It != StackElem.LCVMap.end()) 721 return It->second; 722 return {0, nullptr}; 723 } 724 725 ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) { 726 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 727 "Data-sharing attributes stack is empty"); 728 auto &StackElem = *std::next(Stack.back().first.rbegin()); 729 if (StackElem.LCVMap.size() < I) 730 return nullptr; 731 for (auto &Pair : StackElem.LCVMap) 732 if (Pair.second.first == I) 733 return Pair.first; 734 return nullptr; 735 } 736 737 void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 738 DeclRefExpr *PrivateCopy) { 739 D = getCanonicalDecl(D); 740 if (A == OMPC_threadprivate) { 741 auto &Data = Threadprivates[D]; 742 Data.Attributes = A; 743 Data.RefExpr.setPointer(E); 744 Data.PrivateCopy = nullptr; 745 } else { 746 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 747 auto &Data = Stack.back().first.back().SharingMap[D]; 748 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 749 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 750 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 751 (isLoopControlVariable(D).first && A == OMPC_private)); 752 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 753 Data.RefExpr.setInt(/*IntVal=*/true); 754 return; 755 } 756 const bool IsLastprivate = 757 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 758 Data.Attributes = A; 759 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 760 Data.PrivateCopy = PrivateCopy; 761 if (PrivateCopy) { 762 auto &Data = Stack.back().first.back().SharingMap[PrivateCopy->getDecl()]; 763 Data.Attributes = A; 764 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 765 Data.PrivateCopy = nullptr; 766 } 767 } 768 } 769 770 /// \brief Build a variable declaration for OpenMP loop iteration variable. 771 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 772 StringRef Name, const AttrVec *Attrs = nullptr) { 773 DeclContext *DC = SemaRef.CurContext; 774 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 775 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 776 VarDecl *Decl = 777 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 778 if (Attrs) { 779 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 780 I != E; ++I) 781 Decl->addAttr(*I); 782 } 783 Decl->setImplicit(); 784 return Decl; 785 } 786 787 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 788 SourceLocation Loc, 789 bool RefersToCapture = false) { 790 D->setReferenced(); 791 D->markUsed(S.Context); 792 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 793 SourceLocation(), D, RefersToCapture, Loc, Ty, 794 VK_LValue); 795 } 796 797 void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR, 798 BinaryOperatorKind BOK) { 799 D = getCanonicalDecl(D); 800 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 801 assert( 802 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 803 "Additional reduction info may be specified only for reduction items."); 804 auto &ReductionData = Stack.back().first.back().ReductionMap[D]; 805 assert(ReductionData.ReductionRange.isInvalid() && 806 Stack.back().first.back().Directive == OMPD_taskgroup && 807 "Additional reduction info may be specified only once for reduction " 808 "items."); 809 ReductionData.set(BOK, SR); 810 Expr *&TaskgroupReductionRef = 811 Stack.back().first.back().TaskgroupReductionRef; 812 if (!TaskgroupReductionRef) { 813 auto *VD = buildVarDecl(SemaRef, SourceLocation(), 814 SemaRef.Context.VoidPtrTy, ".task_red."); 815 TaskgroupReductionRef = buildDeclRefExpr( 816 SemaRef, VD, SemaRef.Context.VoidPtrTy, SourceLocation()); 817 } 818 } 819 820 void DSAStackTy::addTaskgroupReductionData(ValueDecl *D, SourceRange SR, 821 const Expr *ReductionRef) { 822 D = getCanonicalDecl(D); 823 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 824 assert( 825 Stack.back().first.back().SharingMap[D].Attributes == OMPC_reduction && 826 "Additional reduction info may be specified only for reduction items."); 827 auto &ReductionData = Stack.back().first.back().ReductionMap[D]; 828 assert(ReductionData.ReductionRange.isInvalid() && 829 Stack.back().first.back().Directive == OMPD_taskgroup && 830 "Additional reduction info may be specified only once for reduction " 831 "items."); 832 ReductionData.set(ReductionRef, SR); 833 Expr *&TaskgroupReductionRef = 834 Stack.back().first.back().TaskgroupReductionRef; 835 if (!TaskgroupReductionRef) { 836 auto *VD = buildVarDecl(SemaRef, SourceLocation(), 837 SemaRef.Context.VoidPtrTy, ".task_red."); 838 TaskgroupReductionRef = buildDeclRefExpr( 839 SemaRef, VD, SemaRef.Context.VoidPtrTy, SourceLocation()); 840 } 841 } 842 843 DSAStackTy::DSAVarData 844 DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, 845 BinaryOperatorKind &BOK, 846 Expr *&TaskgroupDescriptor) { 847 D = getCanonicalDecl(D); 848 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 849 if (Stack.back().first.empty()) 850 return DSAVarData(); 851 for (auto I = std::next(Stack.back().first.rbegin(), 1), 852 E = Stack.back().first.rend(); 853 I != E; std::advance(I, 1)) { 854 auto &Data = I->SharingMap[D]; 855 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 856 continue; 857 auto &ReductionData = I->ReductionMap[D]; 858 if (!ReductionData.ReductionOp || 859 ReductionData.ReductionOp.is<const Expr *>()) 860 return DSAVarData(); 861 SR = ReductionData.ReductionRange; 862 BOK = ReductionData.ReductionOp.get<ReductionData::BOKPtrType>(); 863 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 864 "expression for the descriptor is not " 865 "set."); 866 TaskgroupDescriptor = I->TaskgroupReductionRef; 867 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 868 Data.PrivateCopy, I->DefaultAttrLoc); 869 } 870 return DSAVarData(); 871 } 872 873 DSAStackTy::DSAVarData 874 DSAStackTy::getTopMostTaskgroupReductionData(ValueDecl *D, SourceRange &SR, 875 const Expr *&ReductionRef, 876 Expr *&TaskgroupDescriptor) { 877 D = getCanonicalDecl(D); 878 assert(!isStackEmpty() && "Data-sharing attributes stack is empty."); 879 if (Stack.back().first.empty()) 880 return DSAVarData(); 881 for (auto I = std::next(Stack.back().first.rbegin(), 1), 882 E = Stack.back().first.rend(); 883 I != E; std::advance(I, 1)) { 884 auto &Data = I->SharingMap[D]; 885 if (Data.Attributes != OMPC_reduction || I->Directive != OMPD_taskgroup) 886 continue; 887 auto &ReductionData = I->ReductionMap[D]; 888 if (!ReductionData.ReductionOp || 889 !ReductionData.ReductionOp.is<const Expr *>()) 890 return DSAVarData(); 891 SR = ReductionData.ReductionRange; 892 ReductionRef = ReductionData.ReductionOp.get<const Expr *>(); 893 assert(I->TaskgroupReductionRef && "taskgroup reduction reference " 894 "expression for the descriptor is not " 895 "set."); 896 TaskgroupDescriptor = I->TaskgroupReductionRef; 897 return DSAVarData(OMPD_taskgroup, OMPC_reduction, Data.RefExpr.getPointer(), 898 Data.PrivateCopy, I->DefaultAttrLoc); 899 } 900 return DSAVarData(); 901 } 902 903 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) { 904 D = D->getCanonicalDecl(); 905 if (!isStackEmpty() && Stack.back().first.size() > 1) { 906 reverse_iterator I = Iter, E = Stack.back().first.rend(); 907 Scope *TopScope = nullptr; 908 while (I != E && !isParallelOrTaskRegion(I->Directive)) 909 ++I; 910 if (I == E) 911 return false; 912 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 913 Scope *CurScope = getCurScope(); 914 while (CurScope != TopScope && !CurScope->isDeclScope(D)) 915 CurScope = CurScope->getParent(); 916 return CurScope != TopScope; 917 } 918 return false; 919 } 920 921 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) { 922 D = getCanonicalDecl(D); 923 DSAVarData DVar; 924 925 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 926 // in a Construct, C/C++, predetermined, p.1] 927 // Variables appearing in threadprivate directives are threadprivate. 928 auto *VD = dyn_cast<VarDecl>(D); 929 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 930 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 931 SemaRef.getLangOpts().OpenMPUseTLS && 932 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 933 (VD && VD->getStorageClass() == SC_Register && 934 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 935 addDSA(D, buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 936 D->getLocation()), 937 OMPC_threadprivate); 938 } 939 auto TI = Threadprivates.find(D); 940 if (TI != Threadprivates.end()) { 941 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 942 DVar.CKind = OMPC_threadprivate; 943 return DVar; 944 } 945 946 if (isStackEmpty()) 947 // Not in OpenMP execution region and top scope was already checked. 948 return DVar; 949 950 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 951 // in a Construct, C/C++, predetermined, p.4] 952 // Static data members are shared. 953 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 954 // in a Construct, C/C++, predetermined, p.7] 955 // Variables with static storage duration that are declared in a scope 956 // inside the construct are shared. 957 auto &&MatchesAlways = [](OpenMPDirectiveKind) -> bool { return true; }; 958 if (VD && VD->isStaticDataMember()) { 959 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 960 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 961 return DVar; 962 963 DVar.CKind = OMPC_shared; 964 return DVar; 965 } 966 967 QualType Type = D->getType().getNonReferenceType().getCanonicalType(); 968 bool IsConstant = Type.isConstant(SemaRef.getASTContext()); 969 Type = SemaRef.getASTContext().getBaseElementType(Type); 970 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 971 // in a Construct, C/C++, predetermined, p.6] 972 // Variables with const qualified type having no mutable member are 973 // shared. 974 CXXRecordDecl *RD = 975 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 976 if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 977 if (auto *CTD = CTSD->getSpecializedTemplate()) 978 RD = CTD->getTemplatedDecl(); 979 if (IsConstant && 980 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() && 981 RD->hasMutableFields())) { 982 // Variables with const-qualified type having no mutable member may be 983 // listed in a firstprivate clause, even if they are static data members. 984 DSAVarData DVarTemp = hasDSA( 985 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_firstprivate; }, 986 MatchesAlways, FromParent); 987 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 988 return DVar; 989 990 DVar.CKind = OMPC_shared; 991 return DVar; 992 } 993 994 // Explicitly specified attributes and local variables with predetermined 995 // attributes. 996 auto I = Stack.back().first.rbegin(); 997 auto EndI = Stack.back().first.rend(); 998 if (FromParent && I != EndI) 999 std::advance(I, 1); 1000 if (I->SharingMap.count(D)) { 1001 DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer(); 1002 DVar.PrivateCopy = I->SharingMap[D].PrivateCopy; 1003 DVar.CKind = I->SharingMap[D].Attributes; 1004 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 1005 DVar.DKind = I->Directive; 1006 } 1007 1008 return DVar; 1009 } 1010 1011 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 1012 bool FromParent) { 1013 if (isStackEmpty()) { 1014 StackTy::reverse_iterator I; 1015 return getDSA(I, D); 1016 } 1017 D = getCanonicalDecl(D); 1018 auto StartI = Stack.back().first.rbegin(); 1019 auto EndI = Stack.back().first.rend(); 1020 if (FromParent && StartI != EndI) 1021 std::advance(StartI, 1); 1022 return getDSA(StartI, D); 1023 } 1024 1025 DSAStackTy::DSAVarData 1026 DSAStackTy::hasDSA(ValueDecl *D, 1027 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 1028 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 1029 bool FromParent) { 1030 if (isStackEmpty()) 1031 return {}; 1032 D = getCanonicalDecl(D); 1033 auto I = Stack.back().first.rbegin(); 1034 auto EndI = Stack.back().first.rend(); 1035 if (FromParent && I != EndI) 1036 std::advance(I, 1); 1037 for (; I != EndI; std::advance(I, 1)) { 1038 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) 1039 continue; 1040 auto NewI = I; 1041 DSAVarData DVar = getDSA(NewI, D); 1042 if (I == NewI && CPred(DVar.CKind)) 1043 return DVar; 1044 } 1045 return {}; 1046 } 1047 1048 DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 1049 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 1050 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 1051 bool FromParent) { 1052 if (isStackEmpty()) 1053 return {}; 1054 D = getCanonicalDecl(D); 1055 auto StartI = Stack.back().first.rbegin(); 1056 auto EndI = Stack.back().first.rend(); 1057 if (FromParent && StartI != EndI) 1058 std::advance(StartI, 1); 1059 if (StartI == EndI || !DPred(StartI->Directive)) 1060 return {}; 1061 auto NewI = StartI; 1062 DSAVarData DVar = getDSA(NewI, D); 1063 return (NewI == StartI && CPred(DVar.CKind)) ? DVar : DSAVarData(); 1064 } 1065 1066 bool DSAStackTy::hasExplicitDSA( 1067 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 1068 unsigned Level, bool NotLastprivate) { 1069 if (CPred(ClauseKindMode)) 1070 return true; 1071 if (isStackEmpty()) 1072 return false; 1073 D = getCanonicalDecl(D); 1074 auto StartI = Stack.back().first.begin(); 1075 auto EndI = Stack.back().first.end(); 1076 if (std::distance(StartI, EndI) <= (int)Level) 1077 return false; 1078 std::advance(StartI, Level); 1079 return (StartI->SharingMap.count(D) > 0) && 1080 StartI->SharingMap[D].RefExpr.getPointer() && 1081 CPred(StartI->SharingMap[D].Attributes) && 1082 (!NotLastprivate || !StartI->SharingMap[D].RefExpr.getInt()); 1083 } 1084 1085 bool DSAStackTy::hasExplicitDirective( 1086 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 1087 unsigned Level) { 1088 if (isStackEmpty()) 1089 return false; 1090 auto StartI = Stack.back().first.begin(); 1091 auto EndI = Stack.back().first.end(); 1092 if (std::distance(StartI, EndI) <= (int)Level) 1093 return false; 1094 std::advance(StartI, Level); 1095 return DPred(StartI->Directive); 1096 } 1097 1098 bool DSAStackTy::hasDirective( 1099 const llvm::function_ref<bool(OpenMPDirectiveKind, 1100 const DeclarationNameInfo &, SourceLocation)> 1101 &DPred, 1102 bool FromParent) { 1103 // We look only in the enclosing region. 1104 if (isStackEmpty()) 1105 return false; 1106 auto StartI = std::next(Stack.back().first.rbegin()); 1107 auto EndI = Stack.back().first.rend(); 1108 if (FromParent && StartI != EndI) 1109 StartI = std::next(StartI); 1110 for (auto I = StartI, EE = EndI; I != EE; ++I) { 1111 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 1112 return true; 1113 } 1114 return false; 1115 } 1116 1117 void Sema::InitDataSharingAttributesStack() { 1118 VarDataSharingAttributesStack = new DSAStackTy(*this); 1119 } 1120 1121 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 1122 1123 void Sema::pushOpenMPFunctionRegion() { 1124 DSAStack->pushFunction(); 1125 } 1126 1127 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 1128 DSAStack->popFunction(OldFSI); 1129 } 1130 1131 bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level) { 1132 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1133 1134 auto &Ctx = getASTContext(); 1135 bool IsByRef = true; 1136 1137 // Find the directive that is associated with the provided scope. 1138 D = cast<ValueDecl>(D->getCanonicalDecl()); 1139 auto Ty = D->getType(); 1140 1141 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 1142 // This table summarizes how a given variable should be passed to the device 1143 // given its type and the clauses where it appears. This table is based on 1144 // the description in OpenMP 4.5 [2.10.4, target Construct] and 1145 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 1146 // 1147 // ========================================================================= 1148 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 1149 // | |(tofrom:scalar)| | pvt | | | | 1150 // ========================================================================= 1151 // | scl | | | | - | | bycopy| 1152 // | scl | | - | x | - | - | bycopy| 1153 // | scl | | x | - | - | - | null | 1154 // | scl | x | | | - | | byref | 1155 // | scl | x | - | x | - | - | bycopy| 1156 // | scl | x | x | - | - | - | null | 1157 // | scl | | - | - | - | x | byref | 1158 // | scl | x | - | - | - | x | byref | 1159 // 1160 // | agg | n.a. | | | - | | byref | 1161 // | agg | n.a. | - | x | - | - | byref | 1162 // | agg | n.a. | x | - | - | - | null | 1163 // | agg | n.a. | - | - | - | x | byref | 1164 // | agg | n.a. | - | - | - | x[] | byref | 1165 // 1166 // | ptr | n.a. | | | - | | bycopy| 1167 // | ptr | n.a. | - | x | - | - | bycopy| 1168 // | ptr | n.a. | x | - | - | - | null | 1169 // | ptr | n.a. | - | - | - | x | byref | 1170 // | ptr | n.a. | - | - | - | x[] | bycopy| 1171 // | ptr | n.a. | - | - | x | | bycopy| 1172 // | ptr | n.a. | - | - | x | x | bycopy| 1173 // | ptr | n.a. | - | - | x | x[] | bycopy| 1174 // ========================================================================= 1175 // Legend: 1176 // scl - scalar 1177 // ptr - pointer 1178 // agg - aggregate 1179 // x - applies 1180 // - - invalid in this combination 1181 // [] - mapped with an array section 1182 // byref - should be mapped by reference 1183 // byval - should be mapped by value 1184 // null - initialize a local variable to null on the device 1185 // 1186 // Observations: 1187 // - All scalar declarations that show up in a map clause have to be passed 1188 // by reference, because they may have been mapped in the enclosing data 1189 // environment. 1190 // - If the scalar value does not fit the size of uintptr, it has to be 1191 // passed by reference, regardless the result in the table above. 1192 // - For pointers mapped by value that have either an implicit map or an 1193 // array section, the runtime library may pass the NULL value to the 1194 // device instead of the value passed to it by the compiler. 1195 1196 if (Ty->isReferenceType()) 1197 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1198 1199 // Locate map clauses and see if the variable being captured is referred to 1200 // in any of those clauses. Here we only care about variables, not fields, 1201 // because fields are part of aggregates. 1202 bool IsVariableUsedInMapClause = false; 1203 bool IsVariableAssociatedWithSection = false; 1204 1205 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1206 D, Level, [&](OMPClauseMappableExprCommon::MappableExprComponentListRef 1207 MapExprComponents, 1208 OpenMPClauseKind WhereFoundClauseKind) { 1209 // Only the map clause information influences how a variable is 1210 // captured. E.g. is_device_ptr does not require changing the default 1211 // behavior. 1212 if (WhereFoundClauseKind != OMPC_map) 1213 return false; 1214 1215 auto EI = MapExprComponents.rbegin(); 1216 auto EE = MapExprComponents.rend(); 1217 1218 assert(EI != EE && "Invalid map expression!"); 1219 1220 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1221 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1222 1223 ++EI; 1224 if (EI == EE) 1225 return false; 1226 1227 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1228 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1229 isa<MemberExpr>(EI->getAssociatedExpression())) { 1230 IsVariableAssociatedWithSection = true; 1231 // There is nothing more we need to know about this variable. 1232 return true; 1233 } 1234 1235 // Keep looking for more map info. 1236 return false; 1237 }); 1238 1239 if (IsVariableUsedInMapClause) { 1240 // If variable is identified in a map clause it is always captured by 1241 // reference except if it is a pointer that is dereferenced somehow. 1242 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1243 } else { 1244 // By default, all the data that has a scalar type is mapped by copy. 1245 IsByRef = !Ty->isScalarType(); 1246 } 1247 } 1248 1249 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1250 IsByRef = !DSAStack->hasExplicitDSA( 1251 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1252 Level, /*NotLastprivate=*/true); 1253 } 1254 1255 // When passing data by copy, we need to make sure it fits the uintptr size 1256 // and alignment, because the runtime library only deals with uintptr types. 1257 // If it does not fit the uintptr size, we need to pass the data by reference 1258 // instead. 1259 if (!IsByRef && 1260 (Ctx.getTypeSizeInChars(Ty) > 1261 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1262 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1263 IsByRef = true; 1264 } 1265 1266 return IsByRef; 1267 } 1268 1269 unsigned Sema::getOpenMPNestingLevel() const { 1270 assert(getLangOpts().OpenMP); 1271 return DSAStack->getNestingLevel(); 1272 } 1273 1274 VarDecl *Sema::IsOpenMPCapturedDecl(ValueDecl *D) { 1275 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1276 D = getCanonicalDecl(D); 1277 1278 // If we are attempting to capture a global variable in a directive with 1279 // 'target' we return true so that this global is also mapped to the device. 1280 // 1281 // FIXME: If the declaration is enclosed in a 'declare target' directive, 1282 // then it should not be captured. Therefore, an extra check has to be 1283 // inserted here once support for 'declare target' is added. 1284 // 1285 auto *VD = dyn_cast<VarDecl>(D); 1286 if (VD && !VD->hasLocalStorage()) { 1287 if (isOpenMPTargetExecutionDirective(DSAStack->getCurrentDirective()) && 1288 !DSAStack->isClauseParsingMode()) 1289 return VD; 1290 if (DSAStack->hasDirective( 1291 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1292 SourceLocation) -> bool { 1293 return isOpenMPTargetExecutionDirective(K); 1294 }, 1295 false)) 1296 return VD; 1297 } 1298 1299 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1300 (!DSAStack->isClauseParsingMode() || 1301 DSAStack->getParentDirective() != OMPD_unknown)) { 1302 auto &&Info = DSAStack->isLoopControlVariable(D); 1303 if (Info.first || 1304 (VD && VD->hasLocalStorage() && 1305 isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || 1306 (VD && DSAStack->isForceVarCapturing())) 1307 return VD ? VD : Info.second; 1308 auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1309 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1310 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1311 DVarPrivate = DSAStack->hasDSA( 1312 D, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, 1313 DSAStack->isClauseParsingMode()); 1314 if (DVarPrivate.CKind != OMPC_unknown) 1315 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1316 } 1317 return nullptr; 1318 } 1319 1320 bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) { 1321 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1322 return DSAStack->hasExplicitDSA( 1323 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, 1324 Level) || 1325 // Consider taskgroup reduction descriptor variable a private to avoid 1326 // possible capture in the region. 1327 (DSAStack->hasExplicitDirective( 1328 [](OpenMPDirectiveKind K) { return K == OMPD_taskgroup; }, 1329 Level) && 1330 DSAStack->isTaskgroupReductionRef(D, Level)); 1331 } 1332 1333 void Sema::setOpenMPCaptureKind(FieldDecl *FD, ValueDecl *D, unsigned Level) { 1334 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1335 D = getCanonicalDecl(D); 1336 OpenMPClauseKind OMPC = OMPC_unknown; 1337 for (unsigned I = DSAStack->getNestingLevel() + 1; I > Level; --I) { 1338 const unsigned NewLevel = I - 1; 1339 if (DSAStack->hasExplicitDSA(D, 1340 [&OMPC](const OpenMPClauseKind K) { 1341 if (isOpenMPPrivate(K)) { 1342 OMPC = K; 1343 return true; 1344 } 1345 return false; 1346 }, 1347 NewLevel)) 1348 break; 1349 if (DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1350 D, NewLevel, 1351 [](OMPClauseMappableExprCommon::MappableExprComponentListRef, 1352 OpenMPClauseKind) { return true; })) { 1353 OMPC = OMPC_map; 1354 break; 1355 } 1356 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1357 NewLevel)) { 1358 OMPC = OMPC_firstprivate; 1359 break; 1360 } 1361 } 1362 if (OMPC != OMPC_unknown) 1363 FD->addAttr(OMPCaptureKindAttr::CreateImplicit(Context, OMPC)); 1364 } 1365 1366 bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) { 1367 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1368 // Return true if the current level is no longer enclosed in a target region. 1369 1370 auto *VD = dyn_cast<VarDecl>(D); 1371 return VD && !VD->hasLocalStorage() && 1372 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1373 Level); 1374 } 1375 1376 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1377 1378 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1379 const DeclarationNameInfo &DirName, 1380 Scope *CurScope, SourceLocation Loc) { 1381 DSAStack->push(DKind, DirName, CurScope, Loc); 1382 PushExpressionEvaluationContext( 1383 ExpressionEvaluationContext::PotentiallyEvaluated); 1384 } 1385 1386 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1387 DSAStack->setClauseParsingMode(K); 1388 } 1389 1390 void Sema::EndOpenMPClause() { 1391 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1392 } 1393 1394 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1395 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1396 // A variable of class type (or array thereof) that appears in a lastprivate 1397 // clause requires an accessible, unambiguous default constructor for the 1398 // class type, unless the list item is also specified in a firstprivate 1399 // clause. 1400 if (auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1401 for (auto *C : D->clauses()) { 1402 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1403 SmallVector<Expr *, 8> PrivateCopies; 1404 for (auto *DE : Clause->varlists()) { 1405 if (DE->isValueDependent() || DE->isTypeDependent()) { 1406 PrivateCopies.push_back(nullptr); 1407 continue; 1408 } 1409 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1410 VarDecl *VD = cast<VarDecl>(DRE->getDecl()); 1411 QualType Type = VD->getType().getNonReferenceType(); 1412 auto DVar = DSAStack->getTopDSA(VD, false); 1413 if (DVar.CKind == OMPC_lastprivate) { 1414 // Generate helper private variable and initialize it with the 1415 // default value. The address of the original variable is replaced 1416 // by the address of the new private variable in CodeGen. This new 1417 // variable is not added to IdResolver, so the code in the OpenMP 1418 // region uses original variable for proper diagnostics. 1419 auto *VDPrivate = buildVarDecl( 1420 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1421 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr); 1422 ActOnUninitializedDecl(VDPrivate); 1423 if (VDPrivate->isInvalidDecl()) 1424 continue; 1425 PrivateCopies.push_back(buildDeclRefExpr( 1426 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1427 } else { 1428 // The variable is also a firstprivate, so initialization sequence 1429 // for private copy is generated already. 1430 PrivateCopies.push_back(nullptr); 1431 } 1432 } 1433 // Set initializers to private copies if no errors were found. 1434 if (PrivateCopies.size() == Clause->varlist_size()) 1435 Clause->setPrivateCopies(PrivateCopies); 1436 } 1437 } 1438 } 1439 1440 DSAStack->pop(); 1441 DiscardCleanupsInEvaluationContext(); 1442 PopExpressionEvaluationContext(); 1443 } 1444 1445 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1446 Expr *NumIterations, Sema &SemaRef, 1447 Scope *S, DSAStackTy *Stack); 1448 1449 namespace { 1450 1451 class VarDeclFilterCCC : public CorrectionCandidateCallback { 1452 private: 1453 Sema &SemaRef; 1454 1455 public: 1456 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1457 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1458 NamedDecl *ND = Candidate.getCorrectionDecl(); 1459 if (auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 1460 return VD->hasGlobalStorage() && 1461 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1462 SemaRef.getCurScope()); 1463 } 1464 return false; 1465 } 1466 }; 1467 1468 class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback { 1469 private: 1470 Sema &SemaRef; 1471 1472 public: 1473 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 1474 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1475 NamedDecl *ND = Candidate.getCorrectionDecl(); 1476 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { 1477 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1478 SemaRef.getCurScope()); 1479 } 1480 return false; 1481 } 1482 }; 1483 1484 } // namespace 1485 1486 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 1487 CXXScopeSpec &ScopeSpec, 1488 const DeclarationNameInfo &Id) { 1489 LookupResult Lookup(*this, Id, LookupOrdinaryName); 1490 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 1491 1492 if (Lookup.isAmbiguous()) 1493 return ExprError(); 1494 1495 VarDecl *VD; 1496 if (!Lookup.isSingleResult()) { 1497 if (TypoCorrection Corrected = CorrectTypo( 1498 Id, LookupOrdinaryName, CurScope, nullptr, 1499 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 1500 diagnoseTypo(Corrected, 1501 PDiag(Lookup.empty() 1502 ? diag::err_undeclared_var_use_suggest 1503 : diag::err_omp_expected_var_arg_suggest) 1504 << Id.getName()); 1505 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 1506 } else { 1507 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 1508 : diag::err_omp_expected_var_arg) 1509 << Id.getName(); 1510 return ExprError(); 1511 } 1512 } else { 1513 if (!(VD = Lookup.getAsSingle<VarDecl>())) { 1514 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 1515 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 1516 return ExprError(); 1517 } 1518 } 1519 Lookup.suppressDiagnostics(); 1520 1521 // OpenMP [2.9.2, Syntax, C/C++] 1522 // Variables must be file-scope, namespace-scope, or static block-scope. 1523 if (!VD->hasGlobalStorage()) { 1524 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 1525 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); 1526 bool IsDecl = 1527 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1528 Diag(VD->getLocation(), 1529 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1530 << VD; 1531 return ExprError(); 1532 } 1533 1534 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 1535 NamedDecl *ND = cast<NamedDecl>(CanonicalVD); 1536 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 1537 // A threadprivate directive for file-scope variables must appear outside 1538 // any definition or declaration. 1539 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 1540 !getCurLexicalContext()->isTranslationUnit()) { 1541 Diag(Id.getLoc(), diag::err_omp_var_scope) 1542 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1543 bool IsDecl = 1544 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1545 Diag(VD->getLocation(), 1546 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1547 << VD; 1548 return ExprError(); 1549 } 1550 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 1551 // A threadprivate directive for static class member variables must appear 1552 // in the class definition, in the same scope in which the member 1553 // variables are declared. 1554 if (CanonicalVD->isStaticDataMember() && 1555 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 1556 Diag(Id.getLoc(), diag::err_omp_var_scope) 1557 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1558 bool IsDecl = 1559 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1560 Diag(VD->getLocation(), 1561 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1562 << VD; 1563 return ExprError(); 1564 } 1565 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 1566 // A threadprivate directive for namespace-scope variables must appear 1567 // outside any definition or declaration other than the namespace 1568 // definition itself. 1569 if (CanonicalVD->getDeclContext()->isNamespace() && 1570 (!getCurLexicalContext()->isFileContext() || 1571 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 1572 Diag(Id.getLoc(), diag::err_omp_var_scope) 1573 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1574 bool IsDecl = 1575 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1576 Diag(VD->getLocation(), 1577 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1578 << VD; 1579 return ExprError(); 1580 } 1581 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 1582 // A threadprivate directive for static block-scope variables must appear 1583 // in the scope of the variable and not in a nested scope. 1584 if (CanonicalVD->isStaticLocal() && CurScope && 1585 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 1586 Diag(Id.getLoc(), diag::err_omp_var_scope) 1587 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1588 bool IsDecl = 1589 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1590 Diag(VD->getLocation(), 1591 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1592 << VD; 1593 return ExprError(); 1594 } 1595 1596 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 1597 // A threadprivate directive must lexically precede all references to any 1598 // of the variables in its list. 1599 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { 1600 Diag(Id.getLoc(), diag::err_omp_var_used) 1601 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1602 return ExprError(); 1603 } 1604 1605 QualType ExprType = VD->getType().getNonReferenceType(); 1606 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 1607 SourceLocation(), VD, 1608 /*RefersToEnclosingVariableOrCapture=*/false, 1609 Id.getLoc(), ExprType, VK_LValue); 1610 } 1611 1612 Sema::DeclGroupPtrTy 1613 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 1614 ArrayRef<Expr *> VarList) { 1615 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 1616 CurContext->addDecl(D); 1617 return DeclGroupPtrTy::make(DeclGroupRef(D)); 1618 } 1619 return nullptr; 1620 } 1621 1622 namespace { 1623 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> { 1624 Sema &SemaRef; 1625 1626 public: 1627 bool VisitDeclRefExpr(const DeclRefExpr *E) { 1628 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1629 if (VD->hasLocalStorage()) { 1630 SemaRef.Diag(E->getLocStart(), 1631 diag::err_omp_local_var_in_threadprivate_init) 1632 << E->getSourceRange(); 1633 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 1634 << VD << VD->getSourceRange(); 1635 return true; 1636 } 1637 } 1638 return false; 1639 } 1640 bool VisitStmt(const Stmt *S) { 1641 for (auto Child : S->children()) { 1642 if (Child && Visit(Child)) 1643 return true; 1644 } 1645 return false; 1646 } 1647 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 1648 }; 1649 } // namespace 1650 1651 OMPThreadPrivateDecl * 1652 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 1653 SmallVector<Expr *, 8> Vars; 1654 for (auto &RefExpr : VarList) { 1655 DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr); 1656 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 1657 SourceLocation ILoc = DE->getExprLoc(); 1658 1659 // Mark variable as used. 1660 VD->setReferenced(); 1661 VD->markUsed(Context); 1662 1663 QualType QType = VD->getType(); 1664 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 1665 // It will be analyzed later. 1666 Vars.push_back(DE); 1667 continue; 1668 } 1669 1670 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1671 // A threadprivate variable must not have an incomplete type. 1672 if (RequireCompleteType(ILoc, VD->getType(), 1673 diag::err_omp_threadprivate_incomplete_type)) { 1674 continue; 1675 } 1676 1677 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1678 // A threadprivate variable must not have a reference type. 1679 if (VD->getType()->isReferenceType()) { 1680 Diag(ILoc, diag::err_omp_ref_type_arg) 1681 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 1682 bool IsDecl = 1683 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1684 Diag(VD->getLocation(), 1685 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1686 << VD; 1687 continue; 1688 } 1689 1690 // Check if this is a TLS variable. If TLS is not being supported, produce 1691 // the corresponding diagnostic. 1692 if ((VD->getTLSKind() != VarDecl::TLS_None && 1693 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1694 getLangOpts().OpenMPUseTLS && 1695 getASTContext().getTargetInfo().isTLSSupported())) || 1696 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 1697 !VD->isLocalVarDecl())) { 1698 Diag(ILoc, diag::err_omp_var_thread_local) 1699 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 1700 bool IsDecl = 1701 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1702 Diag(VD->getLocation(), 1703 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1704 << VD; 1705 continue; 1706 } 1707 1708 // Check if initial value of threadprivate variable reference variable with 1709 // local storage (it is not supported by runtime). 1710 if (auto Init = VD->getAnyInitializer()) { 1711 LocalVarRefChecker Checker(*this); 1712 if (Checker.Visit(Init)) 1713 continue; 1714 } 1715 1716 Vars.push_back(RefExpr); 1717 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 1718 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 1719 Context, SourceRange(Loc, Loc))); 1720 if (auto *ML = Context.getASTMutationListener()) 1721 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 1722 } 1723 OMPThreadPrivateDecl *D = nullptr; 1724 if (!Vars.empty()) { 1725 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 1726 Vars); 1727 D->setAccess(AS_public); 1728 } 1729 return D; 1730 } 1731 1732 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, 1733 const ValueDecl *D, DSAStackTy::DSAVarData DVar, 1734 bool IsLoopIterVar = false) { 1735 if (DVar.RefExpr) { 1736 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 1737 << getOpenMPClauseName(DVar.CKind); 1738 return; 1739 } 1740 enum { 1741 PDSA_StaticMemberShared, 1742 PDSA_StaticLocalVarShared, 1743 PDSA_LoopIterVarPrivate, 1744 PDSA_LoopIterVarLinear, 1745 PDSA_LoopIterVarLastprivate, 1746 PDSA_ConstVarShared, 1747 PDSA_GlobalVarShared, 1748 PDSA_TaskVarFirstprivate, 1749 PDSA_LocalVarPrivate, 1750 PDSA_Implicit 1751 } Reason = PDSA_Implicit; 1752 bool ReportHint = false; 1753 auto ReportLoc = D->getLocation(); 1754 auto *VD = dyn_cast<VarDecl>(D); 1755 if (IsLoopIterVar) { 1756 if (DVar.CKind == OMPC_private) 1757 Reason = PDSA_LoopIterVarPrivate; 1758 else if (DVar.CKind == OMPC_lastprivate) 1759 Reason = PDSA_LoopIterVarLastprivate; 1760 else 1761 Reason = PDSA_LoopIterVarLinear; 1762 } else if (isOpenMPTaskingDirective(DVar.DKind) && 1763 DVar.CKind == OMPC_firstprivate) { 1764 Reason = PDSA_TaskVarFirstprivate; 1765 ReportLoc = DVar.ImplicitDSALoc; 1766 } else if (VD && VD->isStaticLocal()) 1767 Reason = PDSA_StaticLocalVarShared; 1768 else if (VD && VD->isStaticDataMember()) 1769 Reason = PDSA_StaticMemberShared; 1770 else if (VD && VD->isFileVarDecl()) 1771 Reason = PDSA_GlobalVarShared; 1772 else if (D->getType().isConstant(SemaRef.getASTContext())) 1773 Reason = PDSA_ConstVarShared; 1774 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 1775 ReportHint = true; 1776 Reason = PDSA_LocalVarPrivate; 1777 } 1778 if (Reason != PDSA_Implicit) { 1779 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 1780 << Reason << ReportHint 1781 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 1782 } else if (DVar.ImplicitDSALoc.isValid()) { 1783 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 1784 << getOpenMPClauseName(DVar.CKind); 1785 } 1786 } 1787 1788 namespace { 1789 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> { 1790 DSAStackTy *Stack; 1791 Sema &SemaRef; 1792 bool ErrorFound; 1793 CapturedStmt *CS; 1794 llvm::SmallVector<Expr *, 8> ImplicitFirstprivate; 1795 llvm::SmallVector<Expr *, 8> ImplicitMap; 1796 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 1797 llvm::DenseSet<ValueDecl *> ImplicitDeclarations; 1798 1799 public: 1800 void VisitDeclRefExpr(DeclRefExpr *E) { 1801 if (E->isTypeDependent() || E->isValueDependent() || 1802 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 1803 return; 1804 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1805 VD = VD->getCanonicalDecl(); 1806 // Skip internally declared variables. 1807 if (VD->isLocalVarDecl() && !CS->capturesVariable(VD)) 1808 return; 1809 1810 auto DVar = Stack->getTopDSA(VD, false); 1811 // Check if the variable has explicit DSA set and stop analysis if it so. 1812 if (DVar.RefExpr || !ImplicitDeclarations.insert(VD).second) 1813 return; 1814 1815 auto ELoc = E->getExprLoc(); 1816 auto DKind = Stack->getCurrentDirective(); 1817 // The default(none) clause requires that each variable that is referenced 1818 // in the construct, and does not have a predetermined data-sharing 1819 // attribute, must have its data-sharing attribute explicitly determined 1820 // by being listed in a data-sharing attribute clause. 1821 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 1822 isParallelOrTaskRegion(DKind) && 1823 VarsWithInheritedDSA.count(VD) == 0) { 1824 VarsWithInheritedDSA[VD] = E; 1825 return; 1826 } 1827 1828 if (isOpenMPTargetExecutionDirective(DKind) && 1829 !Stack->isLoopControlVariable(VD).first) { 1830 if (!Stack->checkMappableExprComponentListsForDecl( 1831 VD, /*CurrentRegionOnly=*/true, 1832 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 1833 StackComponents, 1834 OpenMPClauseKind) { 1835 // Variable is used if it has been marked as an array, array 1836 // section or the variable iself. 1837 return StackComponents.size() == 1 || 1838 std::all_of( 1839 std::next(StackComponents.rbegin()), 1840 StackComponents.rend(), 1841 [](const OMPClauseMappableExprCommon:: 1842 MappableComponent &MC) { 1843 return MC.getAssociatedDeclaration() == 1844 nullptr && 1845 (isa<OMPArraySectionExpr>( 1846 MC.getAssociatedExpression()) || 1847 isa<ArraySubscriptExpr>( 1848 MC.getAssociatedExpression())); 1849 }); 1850 })) { 1851 bool CapturedByCopy = false; 1852 // By default lambdas are captured as firstprivates. 1853 if (const auto *RD = 1854 VD->getType().getNonReferenceType()->getAsCXXRecordDecl()) 1855 if (RD->isLambda()) 1856 CapturedByCopy = true; 1857 CapturedByCopy = 1858 CapturedByCopy || 1859 llvm::any_of( 1860 CS->captures(), [VD](const CapturedStmt::Capture &I) { 1861 return I.capturesVariableByCopy() && 1862 I.getCapturedVar()->getCanonicalDecl() == VD; 1863 }); 1864 if (CapturedByCopy) 1865 ImplicitFirstprivate.emplace_back(E); 1866 else 1867 ImplicitMap.emplace_back(E); 1868 return; 1869 } 1870 } 1871 1872 // OpenMP [2.9.3.6, Restrictions, p.2] 1873 // A list item that appears in a reduction clause of the innermost 1874 // enclosing worksharing or parallel construct may not be accessed in an 1875 // explicit task. 1876 DVar = Stack->hasInnermostDSA( 1877 VD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 1878 [](OpenMPDirectiveKind K) -> bool { 1879 return isOpenMPParallelDirective(K) || 1880 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 1881 }, 1882 /*FromParent=*/true); 1883 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 1884 ErrorFound = true; 1885 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1886 ReportOriginalDSA(SemaRef, Stack, VD, DVar); 1887 return; 1888 } 1889 1890 // Define implicit data-sharing attributes for task. 1891 DVar = Stack->getImplicitDSA(VD, false); 1892 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 1893 !Stack->isLoopControlVariable(VD).first) 1894 ImplicitFirstprivate.push_back(E); 1895 } 1896 } 1897 void VisitMemberExpr(MemberExpr *E) { 1898 if (E->isTypeDependent() || E->isValueDependent() || 1899 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 1900 return; 1901 auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl()); 1902 if (!FD) 1903 return; 1904 OpenMPDirectiveKind DKind = Stack->getCurrentDirective(); 1905 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 1906 auto DVar = Stack->getTopDSA(FD, false); 1907 // Check if the variable has explicit DSA set and stop analysis if it 1908 // so. 1909 if (DVar.RefExpr || !ImplicitDeclarations.insert(FD).second) 1910 return; 1911 1912 if (isOpenMPTargetExecutionDirective(DKind) && 1913 !Stack->isLoopControlVariable(FD).first && 1914 !Stack->checkMappableExprComponentListsForDecl( 1915 FD, /*CurrentRegionOnly=*/true, 1916 [](OMPClauseMappableExprCommon::MappableExprComponentListRef 1917 StackComponents, 1918 OpenMPClauseKind) { 1919 return isa<CXXThisExpr>( 1920 cast<MemberExpr>( 1921 StackComponents.back().getAssociatedExpression()) 1922 ->getBase() 1923 ->IgnoreParens()); 1924 })) { 1925 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 1926 // A bit-field cannot appear in a map clause. 1927 // 1928 if (FD->isBitField()) { 1929 SemaRef.Diag(E->getMemberLoc(), 1930 diag::err_omp_bit_fields_forbidden_in_clause) 1931 << E->getSourceRange() << getOpenMPClauseName(OMPC_map); 1932 return; 1933 } 1934 ImplicitMap.emplace_back(E); 1935 return; 1936 } 1937 1938 auto ELoc = E->getExprLoc(); 1939 // OpenMP [2.9.3.6, Restrictions, p.2] 1940 // A list item that appears in a reduction clause of the innermost 1941 // enclosing worksharing or parallel construct may not be accessed in 1942 // an explicit task. 1943 DVar = Stack->hasInnermostDSA( 1944 FD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 1945 [](OpenMPDirectiveKind K) -> bool { 1946 return isOpenMPParallelDirective(K) || 1947 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 1948 }, 1949 /*FromParent=*/true); 1950 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 1951 ErrorFound = true; 1952 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1953 ReportOriginalDSA(SemaRef, Stack, FD, DVar); 1954 return; 1955 } 1956 1957 // Define implicit data-sharing attributes for task. 1958 DVar = Stack->getImplicitDSA(FD, false); 1959 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 1960 !Stack->isLoopControlVariable(FD).first) 1961 ImplicitFirstprivate.push_back(E); 1962 return; 1963 } 1964 if (isOpenMPTargetExecutionDirective(DKind) && !FD->isBitField()) { 1965 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 1966 CheckMapClauseExpressionBase(SemaRef, E, CurComponents, OMPC_map); 1967 auto *VD = cast<ValueDecl>( 1968 CurComponents.back().getAssociatedDeclaration()->getCanonicalDecl()); 1969 if (!Stack->checkMappableExprComponentListsForDecl( 1970 VD, /*CurrentRegionOnly=*/true, 1971 [&CurComponents]( 1972 OMPClauseMappableExprCommon::MappableExprComponentListRef 1973 StackComponents, 1974 OpenMPClauseKind) { 1975 auto CCI = CurComponents.rbegin(); 1976 auto CCE = CurComponents.rend(); 1977 for (const auto &SC : llvm::reverse(StackComponents)) { 1978 // Do both expressions have the same kind? 1979 if (CCI->getAssociatedExpression()->getStmtClass() != 1980 SC.getAssociatedExpression()->getStmtClass()) 1981 if (!(isa<OMPArraySectionExpr>( 1982 SC.getAssociatedExpression()) && 1983 isa<ArraySubscriptExpr>( 1984 CCI->getAssociatedExpression()))) 1985 return false; 1986 1987 Decl *CCD = CCI->getAssociatedDeclaration(); 1988 Decl *SCD = SC.getAssociatedDeclaration(); 1989 CCD = CCD ? CCD->getCanonicalDecl() : nullptr; 1990 SCD = SCD ? SCD->getCanonicalDecl() : nullptr; 1991 if (SCD != CCD) 1992 return false; 1993 std::advance(CCI, 1); 1994 if (CCI == CCE) 1995 break; 1996 } 1997 return true; 1998 })) { 1999 Visit(E->getBase()); 2000 } 2001 } else 2002 Visit(E->getBase()); 2003 } 2004 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 2005 for (auto *C : S->clauses()) { 2006 // Skip analysis of arguments of implicitly defined firstprivate clause 2007 // for task|target directives. 2008 // Skip analysis of arguments of implicitly defined map clause for target 2009 // directives. 2010 if (C && !((isa<OMPFirstprivateClause>(C) || isa<OMPMapClause>(C)) && 2011 C->isImplicit())) { 2012 for (auto *CC : C->children()) { 2013 if (CC) 2014 Visit(CC); 2015 } 2016 } 2017 } 2018 } 2019 void VisitStmt(Stmt *S) { 2020 for (auto *C : S->children()) { 2021 if (C && !isa<OMPExecutableDirective>(C)) 2022 Visit(C); 2023 } 2024 } 2025 2026 bool isErrorFound() { return ErrorFound; } 2027 ArrayRef<Expr *> getImplicitFirstprivate() const { 2028 return ImplicitFirstprivate; 2029 } 2030 ArrayRef<Expr *> getImplicitMap() const { return ImplicitMap; } 2031 llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() { 2032 return VarsWithInheritedDSA; 2033 } 2034 2035 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 2036 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} 2037 }; 2038 } // namespace 2039 2040 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 2041 switch (DKind) { 2042 case OMPD_parallel: 2043 case OMPD_parallel_for: 2044 case OMPD_parallel_for_simd: 2045 case OMPD_parallel_sections: 2046 case OMPD_teams: 2047 case OMPD_teams_distribute: { 2048 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 2049 QualType KmpInt32PtrTy = 2050 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2051 Sema::CapturedParamNameType Params[] = { 2052 std::make_pair(".global_tid.", KmpInt32PtrTy), 2053 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2054 std::make_pair(StringRef(), QualType()) // __context with shared vars 2055 }; 2056 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2057 Params); 2058 break; 2059 } 2060 case OMPD_target_teams: 2061 case OMPD_target_parallel: { 2062 Sema::CapturedParamNameType ParamsTarget[] = { 2063 std::make_pair(StringRef(), QualType()) // __context with shared vars 2064 }; 2065 // Start a captured region for 'target' with no implicit parameters. 2066 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2067 ParamsTarget); 2068 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 2069 QualType KmpInt32PtrTy = 2070 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2071 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 2072 std::make_pair(".global_tid.", KmpInt32PtrTy), 2073 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2074 std::make_pair(StringRef(), QualType()) // __context with shared vars 2075 }; 2076 // Start a captured region for 'teams' or 'parallel'. Both regions have 2077 // the same implicit parameters. 2078 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2079 ParamsTeamsOrParallel); 2080 break; 2081 } 2082 case OMPD_simd: 2083 case OMPD_for: 2084 case OMPD_for_simd: 2085 case OMPD_sections: 2086 case OMPD_section: 2087 case OMPD_single: 2088 case OMPD_master: 2089 case OMPD_critical: 2090 case OMPD_taskgroup: 2091 case OMPD_distribute: 2092 case OMPD_ordered: 2093 case OMPD_atomic: 2094 case OMPD_target_data: 2095 case OMPD_target: 2096 case OMPD_target_parallel_for: 2097 case OMPD_target_parallel_for_simd: 2098 case OMPD_target_simd: { 2099 Sema::CapturedParamNameType Params[] = { 2100 std::make_pair(StringRef(), QualType()) // __context with shared vars 2101 }; 2102 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2103 Params); 2104 break; 2105 } 2106 case OMPD_task: { 2107 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 2108 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 2109 FunctionProtoType::ExtProtoInfo EPI; 2110 EPI.Variadic = true; 2111 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2112 Sema::CapturedParamNameType Params[] = { 2113 std::make_pair(".global_tid.", KmpInt32Ty), 2114 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), 2115 std::make_pair(".privates.", Context.VoidPtrTy.withConst()), 2116 std::make_pair(".copy_fn.", 2117 Context.getPointerType(CopyFnType).withConst()), 2118 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2119 std::make_pair(StringRef(), QualType()) // __context with shared vars 2120 }; 2121 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2122 Params); 2123 // Mark this captured region as inlined, because we don't use outlined 2124 // function directly. 2125 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2126 AlwaysInlineAttr::CreateImplicit( 2127 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 2128 break; 2129 } 2130 case OMPD_taskloop: 2131 case OMPD_taskloop_simd: { 2132 QualType KmpInt32Ty = 2133 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1); 2134 QualType KmpUInt64Ty = 2135 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 2136 QualType KmpInt64Ty = 2137 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 2138 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 2139 FunctionProtoType::ExtProtoInfo EPI; 2140 EPI.Variadic = true; 2141 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 2142 Sema::CapturedParamNameType Params[] = { 2143 std::make_pair(".global_tid.", KmpInt32Ty), 2144 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), 2145 std::make_pair(".privates.", 2146 Context.VoidPtrTy.withConst().withRestrict()), 2147 std::make_pair( 2148 ".copy_fn.", 2149 Context.getPointerType(CopyFnType).withConst().withRestrict()), 2150 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 2151 std::make_pair(".lb.", KmpUInt64Ty), 2152 std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty), 2153 std::make_pair(".liter.", KmpInt32Ty), 2154 std::make_pair(".reductions.", 2155 Context.VoidPtrTy.withConst().withRestrict()), 2156 std::make_pair(StringRef(), QualType()) // __context with shared vars 2157 }; 2158 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2159 Params); 2160 // Mark this captured region as inlined, because we don't use outlined 2161 // function directly. 2162 getCurCapturedRegion()->TheCapturedDecl->addAttr( 2163 AlwaysInlineAttr::CreateImplicit( 2164 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 2165 break; 2166 } 2167 case OMPD_distribute_parallel_for_simd: 2168 case OMPD_distribute_simd: 2169 case OMPD_distribute_parallel_for: 2170 case OMPD_teams_distribute_simd: 2171 case OMPD_teams_distribute_parallel_for_simd: 2172 case OMPD_teams_distribute_parallel_for: 2173 case OMPD_target_teams_distribute: 2174 case OMPD_target_teams_distribute_parallel_for: 2175 case OMPD_target_teams_distribute_parallel_for_simd: 2176 case OMPD_target_teams_distribute_simd: { 2177 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 2178 QualType KmpInt32PtrTy = 2179 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 2180 Sema::CapturedParamNameType Params[] = { 2181 std::make_pair(".global_tid.", KmpInt32PtrTy), 2182 std::make_pair(".bound_tid.", KmpInt32PtrTy), 2183 std::make_pair(".previous.lb.", Context.getSizeType()), 2184 std::make_pair(".previous.ub.", Context.getSizeType()), 2185 std::make_pair(StringRef(), QualType()) // __context with shared vars 2186 }; 2187 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 2188 Params); 2189 break; 2190 } 2191 case OMPD_threadprivate: 2192 case OMPD_taskyield: 2193 case OMPD_barrier: 2194 case OMPD_taskwait: 2195 case OMPD_cancellation_point: 2196 case OMPD_cancel: 2197 case OMPD_flush: 2198 case OMPD_target_enter_data: 2199 case OMPD_target_exit_data: 2200 case OMPD_declare_reduction: 2201 case OMPD_declare_simd: 2202 case OMPD_declare_target: 2203 case OMPD_end_declare_target: 2204 case OMPD_target_update: 2205 llvm_unreachable("OpenMP Directive is not allowed"); 2206 case OMPD_unknown: 2207 llvm_unreachable("Unknown OpenMP directive"); 2208 } 2209 } 2210 2211 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 2212 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2213 getOpenMPCaptureRegions(CaptureRegions, DKind); 2214 return CaptureRegions.size(); 2215 } 2216 2217 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 2218 Expr *CaptureExpr, bool WithInit, 2219 bool AsExpression) { 2220 assert(CaptureExpr); 2221 ASTContext &C = S.getASTContext(); 2222 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 2223 QualType Ty = Init->getType(); 2224 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 2225 if (S.getLangOpts().CPlusPlus) 2226 Ty = C.getLValueReferenceType(Ty); 2227 else { 2228 Ty = C.getPointerType(Ty); 2229 ExprResult Res = 2230 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 2231 if (!Res.isUsable()) 2232 return nullptr; 2233 Init = Res.get(); 2234 } 2235 WithInit = true; 2236 } 2237 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 2238 CaptureExpr->getLocStart()); 2239 if (!WithInit) 2240 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange())); 2241 S.CurContext->addHiddenDecl(CED); 2242 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 2243 return CED; 2244 } 2245 2246 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 2247 bool WithInit) { 2248 OMPCapturedExprDecl *CD; 2249 if (auto *VD = S.IsOpenMPCapturedDecl(D)) 2250 CD = cast<OMPCapturedExprDecl>(VD); 2251 else 2252 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 2253 /*AsExpression=*/false); 2254 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 2255 CaptureExpr->getExprLoc()); 2256 } 2257 2258 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 2259 if (!Ref) { 2260 auto *CD = 2261 buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."), 2262 CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true); 2263 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 2264 CaptureExpr->getExprLoc()); 2265 } 2266 ExprResult Res = Ref; 2267 if (!S.getLangOpts().CPlusPlus && 2268 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 2269 Ref->getType()->isPointerType()) 2270 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 2271 if (!Res.isUsable()) 2272 return ExprError(); 2273 return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get()); 2274 } 2275 2276 namespace { 2277 // OpenMP directives parsed in this section are represented as a 2278 // CapturedStatement with an associated statement. If a syntax error 2279 // is detected during the parsing of the associated statement, the 2280 // compiler must abort processing and close the CapturedStatement. 2281 // 2282 // Combined directives such as 'target parallel' have more than one 2283 // nested CapturedStatements. This RAII ensures that we unwind out 2284 // of all the nested CapturedStatements when an error is found. 2285 class CaptureRegionUnwinderRAII { 2286 private: 2287 Sema &S; 2288 bool &ErrorFound; 2289 OpenMPDirectiveKind DKind; 2290 2291 public: 2292 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 2293 OpenMPDirectiveKind DKind) 2294 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 2295 ~CaptureRegionUnwinderRAII() { 2296 if (ErrorFound) { 2297 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 2298 while (--ThisCaptureLevel >= 0) 2299 S.ActOnCapturedRegionError(); 2300 } 2301 } 2302 }; 2303 } // namespace 2304 2305 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 2306 ArrayRef<OMPClause *> Clauses) { 2307 bool ErrorFound = false; 2308 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 2309 *this, ErrorFound, DSAStack->getCurrentDirective()); 2310 if (!S.isUsable()) { 2311 ErrorFound = true; 2312 return StmtError(); 2313 } 2314 2315 OMPOrderedClause *OC = nullptr; 2316 OMPScheduleClause *SC = nullptr; 2317 SmallVector<OMPLinearClause *, 4> LCs; 2318 SmallVector<OMPClauseWithPreInit *, 8> PICs; 2319 // This is required for proper codegen. 2320 for (auto *Clause : Clauses) { 2321 if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective()) && 2322 Clause->getClauseKind() == OMPC_in_reduction) { 2323 // Capture taskgroup task_reduction descriptors inside the tasking regions 2324 // with the corresponding in_reduction items. 2325 auto *IRC = cast<OMPInReductionClause>(Clause); 2326 for (auto *E : IRC->taskgroup_descriptors()) 2327 if (E) 2328 MarkDeclarationsReferencedInExpr(E); 2329 } 2330 if (isOpenMPPrivate(Clause->getClauseKind()) || 2331 Clause->getClauseKind() == OMPC_copyprivate || 2332 (getLangOpts().OpenMPUseTLS && 2333 getASTContext().getTargetInfo().isTLSSupported() && 2334 Clause->getClauseKind() == OMPC_copyin)) { 2335 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 2336 // Mark all variables in private list clauses as used in inner region. 2337 for (auto *VarRef : Clause->children()) { 2338 if (auto *E = cast_or_null<Expr>(VarRef)) { 2339 MarkDeclarationsReferencedInExpr(E); 2340 } 2341 } 2342 DSAStack->setForceVarCapturing(/*V=*/false); 2343 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 2344 if (auto *C = OMPClauseWithPreInit::get(Clause)) 2345 PICs.push_back(C); 2346 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 2347 if (auto *E = C->getPostUpdateExpr()) 2348 MarkDeclarationsReferencedInExpr(E); 2349 } 2350 } 2351 if (Clause->getClauseKind() == OMPC_schedule) 2352 SC = cast<OMPScheduleClause>(Clause); 2353 else if (Clause->getClauseKind() == OMPC_ordered) 2354 OC = cast<OMPOrderedClause>(Clause); 2355 else if (Clause->getClauseKind() == OMPC_linear) 2356 LCs.push_back(cast<OMPLinearClause>(Clause)); 2357 } 2358 // OpenMP, 2.7.1 Loop Construct, Restrictions 2359 // The nonmonotonic modifier cannot be specified if an ordered clause is 2360 // specified. 2361 if (SC && 2362 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 2363 SC->getSecondScheduleModifier() == 2364 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 2365 OC) { 2366 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 2367 ? SC->getFirstScheduleModifierLoc() 2368 : SC->getSecondScheduleModifierLoc(), 2369 diag::err_omp_schedule_nonmonotonic_ordered) 2370 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 2371 ErrorFound = true; 2372 } 2373 if (!LCs.empty() && OC && OC->getNumForLoops()) { 2374 for (auto *C : LCs) { 2375 Diag(C->getLocStart(), diag::err_omp_linear_ordered) 2376 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 2377 } 2378 ErrorFound = true; 2379 } 2380 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 2381 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 2382 OC->getNumForLoops()) { 2383 Diag(OC->getLocStart(), diag::err_omp_ordered_simd) 2384 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 2385 ErrorFound = true; 2386 } 2387 if (ErrorFound) { 2388 return StmtError(); 2389 } 2390 StmtResult SR = S; 2391 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2392 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 2393 for (auto ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 2394 // Mark all variables in private list clauses as used in inner region. 2395 // Required for proper codegen of combined directives. 2396 // TODO: add processing for other clauses. 2397 if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 2398 for (auto *C : PICs) { 2399 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 2400 // Find the particular capture region for the clause if the 2401 // directive is a combined one with multiple capture regions. 2402 // If the directive is not a combined one, the capture region 2403 // associated with the clause is OMPD_unknown and is generated 2404 // only once. 2405 if (CaptureRegion == ThisCaptureRegion || 2406 CaptureRegion == OMPD_unknown) { 2407 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 2408 for (auto *D : DS->decls()) 2409 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 2410 } 2411 } 2412 } 2413 } 2414 SR = ActOnCapturedRegionEnd(SR.get()); 2415 } 2416 return SR; 2417 } 2418 2419 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 2420 OpenMPDirectiveKind CancelRegion, 2421 SourceLocation StartLoc) { 2422 // CancelRegion is only needed for cancel and cancellation_point. 2423 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 2424 return false; 2425 2426 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 2427 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 2428 return false; 2429 2430 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 2431 << getOpenMPDirectiveName(CancelRegion); 2432 return true; 2433 } 2434 2435 static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, 2436 OpenMPDirectiveKind CurrentRegion, 2437 const DeclarationNameInfo &CurrentName, 2438 OpenMPDirectiveKind CancelRegion, 2439 SourceLocation StartLoc) { 2440 if (Stack->getCurScope()) { 2441 auto ParentRegion = Stack->getParentDirective(); 2442 auto OffendingRegion = ParentRegion; 2443 bool NestingProhibited = false; 2444 bool CloseNesting = true; 2445 bool OrphanSeen = false; 2446 enum { 2447 NoRecommend, 2448 ShouldBeInParallelRegion, 2449 ShouldBeInOrderedRegion, 2450 ShouldBeInTargetRegion, 2451 ShouldBeInTeamsRegion 2452 } Recommend = NoRecommend; 2453 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 2454 // OpenMP [2.16, Nesting of Regions] 2455 // OpenMP constructs may not be nested inside a simd region. 2456 // OpenMP [2.8.1,simd Construct, Restrictions] 2457 // An ordered construct with the simd clause is the only OpenMP 2458 // construct that can appear in the simd region. 2459 // Allowing a SIMD construct nested in another SIMD construct is an 2460 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 2461 // message. 2462 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 2463 ? diag::err_omp_prohibited_region_simd 2464 : diag::warn_omp_nesting_simd); 2465 return CurrentRegion != OMPD_simd; 2466 } 2467 if (ParentRegion == OMPD_atomic) { 2468 // OpenMP [2.16, Nesting of Regions] 2469 // OpenMP constructs may not be nested inside an atomic region. 2470 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 2471 return true; 2472 } 2473 if (CurrentRegion == OMPD_section) { 2474 // OpenMP [2.7.2, sections Construct, Restrictions] 2475 // Orphaned section directives are prohibited. That is, the section 2476 // directives must appear within the sections construct and must not be 2477 // encountered elsewhere in the sections region. 2478 if (ParentRegion != OMPD_sections && 2479 ParentRegion != OMPD_parallel_sections) { 2480 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 2481 << (ParentRegion != OMPD_unknown) 2482 << getOpenMPDirectiveName(ParentRegion); 2483 return true; 2484 } 2485 return false; 2486 } 2487 // Allow some constructs (except teams) to be orphaned (they could be 2488 // used in functions, called from OpenMP regions with the required 2489 // preconditions). 2490 if (ParentRegion == OMPD_unknown && 2491 !isOpenMPNestingTeamsDirective(CurrentRegion)) 2492 return false; 2493 if (CurrentRegion == OMPD_cancellation_point || 2494 CurrentRegion == OMPD_cancel) { 2495 // OpenMP [2.16, Nesting of Regions] 2496 // A cancellation point construct for which construct-type-clause is 2497 // taskgroup must be nested inside a task construct. A cancellation 2498 // point construct for which construct-type-clause is not taskgroup must 2499 // be closely nested inside an OpenMP construct that matches the type 2500 // specified in construct-type-clause. 2501 // A cancel construct for which construct-type-clause is taskgroup must be 2502 // nested inside a task construct. A cancel construct for which 2503 // construct-type-clause is not taskgroup must be closely nested inside an 2504 // OpenMP construct that matches the type specified in 2505 // construct-type-clause. 2506 NestingProhibited = 2507 !((CancelRegion == OMPD_parallel && 2508 (ParentRegion == OMPD_parallel || 2509 ParentRegion == OMPD_target_parallel)) || 2510 (CancelRegion == OMPD_for && 2511 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 2512 ParentRegion == OMPD_target_parallel_for)) || 2513 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 2514 (CancelRegion == OMPD_sections && 2515 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 2516 ParentRegion == OMPD_parallel_sections))); 2517 } else if (CurrentRegion == OMPD_master) { 2518 // OpenMP [2.16, Nesting of Regions] 2519 // A master region may not be closely nested inside a worksharing, 2520 // atomic, or explicit task region. 2521 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2522 isOpenMPTaskingDirective(ParentRegion); 2523 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 2524 // OpenMP [2.16, Nesting of Regions] 2525 // A critical region may not be nested (closely or otherwise) inside a 2526 // critical region with the same name. Note that this restriction is not 2527 // sufficient to prevent deadlock. 2528 SourceLocation PreviousCriticalLoc; 2529 bool DeadLock = Stack->hasDirective( 2530 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 2531 const DeclarationNameInfo &DNI, 2532 SourceLocation Loc) -> bool { 2533 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 2534 PreviousCriticalLoc = Loc; 2535 return true; 2536 } else 2537 return false; 2538 }, 2539 false /* skip top directive */); 2540 if (DeadLock) { 2541 SemaRef.Diag(StartLoc, 2542 diag::err_omp_prohibited_region_critical_same_name) 2543 << CurrentName.getName(); 2544 if (PreviousCriticalLoc.isValid()) 2545 SemaRef.Diag(PreviousCriticalLoc, 2546 diag::note_omp_previous_critical_region); 2547 return true; 2548 } 2549 } else if (CurrentRegion == OMPD_barrier) { 2550 // OpenMP [2.16, Nesting of Regions] 2551 // A barrier region may not be closely nested inside a worksharing, 2552 // explicit task, critical, ordered, atomic, or master region. 2553 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2554 isOpenMPTaskingDirective(ParentRegion) || 2555 ParentRegion == OMPD_master || 2556 ParentRegion == OMPD_critical || 2557 ParentRegion == OMPD_ordered; 2558 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 2559 !isOpenMPParallelDirective(CurrentRegion) && 2560 !isOpenMPTeamsDirective(CurrentRegion)) { 2561 // OpenMP [2.16, Nesting of Regions] 2562 // A worksharing region may not be closely nested inside a worksharing, 2563 // explicit task, critical, ordered, atomic, or master region. 2564 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2565 isOpenMPTaskingDirective(ParentRegion) || 2566 ParentRegion == OMPD_master || 2567 ParentRegion == OMPD_critical || 2568 ParentRegion == OMPD_ordered; 2569 Recommend = ShouldBeInParallelRegion; 2570 } else if (CurrentRegion == OMPD_ordered) { 2571 // OpenMP [2.16, Nesting of Regions] 2572 // An ordered region may not be closely nested inside a critical, 2573 // atomic, or explicit task region. 2574 // An ordered region must be closely nested inside a loop region (or 2575 // parallel loop region) with an ordered clause. 2576 // OpenMP [2.8.1,simd Construct, Restrictions] 2577 // An ordered construct with the simd clause is the only OpenMP construct 2578 // that can appear in the simd region. 2579 NestingProhibited = ParentRegion == OMPD_critical || 2580 isOpenMPTaskingDirective(ParentRegion) || 2581 !(isOpenMPSimdDirective(ParentRegion) || 2582 Stack->isParentOrderedRegion()); 2583 Recommend = ShouldBeInOrderedRegion; 2584 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 2585 // OpenMP [2.16, Nesting of Regions] 2586 // If specified, a teams construct must be contained within a target 2587 // construct. 2588 NestingProhibited = ParentRegion != OMPD_target; 2589 OrphanSeen = ParentRegion == OMPD_unknown; 2590 Recommend = ShouldBeInTargetRegion; 2591 Stack->setParentTeamsRegionLoc(Stack->getConstructLoc()); 2592 } 2593 if (!NestingProhibited && 2594 !isOpenMPTargetExecutionDirective(CurrentRegion) && 2595 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 2596 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 2597 // OpenMP [2.16, Nesting of Regions] 2598 // distribute, parallel, parallel sections, parallel workshare, and the 2599 // parallel loop and parallel loop SIMD constructs are the only OpenMP 2600 // constructs that can be closely nested in the teams region. 2601 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 2602 !isOpenMPDistributeDirective(CurrentRegion); 2603 Recommend = ShouldBeInParallelRegion; 2604 } 2605 if (!NestingProhibited && 2606 isOpenMPNestingDistributeDirective(CurrentRegion)) { 2607 // OpenMP 4.5 [2.17 Nesting of Regions] 2608 // The region associated with the distribute construct must be strictly 2609 // nested inside a teams region 2610 NestingProhibited = 2611 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 2612 Recommend = ShouldBeInTeamsRegion; 2613 } 2614 if (!NestingProhibited && 2615 (isOpenMPTargetExecutionDirective(CurrentRegion) || 2616 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 2617 // OpenMP 4.5 [2.17 Nesting of Regions] 2618 // If a target, target update, target data, target enter data, or 2619 // target exit data construct is encountered during execution of a 2620 // target region, the behavior is unspecified. 2621 NestingProhibited = Stack->hasDirective( 2622 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2623 SourceLocation) -> bool { 2624 if (isOpenMPTargetExecutionDirective(K)) { 2625 OffendingRegion = K; 2626 return true; 2627 } else 2628 return false; 2629 }, 2630 false /* don't skip top directive */); 2631 CloseNesting = false; 2632 } 2633 if (NestingProhibited) { 2634 if (OrphanSeen) { 2635 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 2636 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 2637 } else { 2638 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 2639 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 2640 << Recommend << getOpenMPDirectiveName(CurrentRegion); 2641 } 2642 return true; 2643 } 2644 } 2645 return false; 2646 } 2647 2648 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 2649 ArrayRef<OMPClause *> Clauses, 2650 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 2651 bool ErrorFound = false; 2652 unsigned NamedModifiersNumber = 0; 2653 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 2654 OMPD_unknown + 1); 2655 SmallVector<SourceLocation, 4> NameModifierLoc; 2656 for (const auto *C : Clauses) { 2657 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 2658 // At most one if clause without a directive-name-modifier can appear on 2659 // the directive. 2660 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 2661 if (FoundNameModifiers[CurNM]) { 2662 S.Diag(C->getLocStart(), diag::err_omp_more_one_clause) 2663 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 2664 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 2665 ErrorFound = true; 2666 } else if (CurNM != OMPD_unknown) { 2667 NameModifierLoc.push_back(IC->getNameModifierLoc()); 2668 ++NamedModifiersNumber; 2669 } 2670 FoundNameModifiers[CurNM] = IC; 2671 if (CurNM == OMPD_unknown) 2672 continue; 2673 // Check if the specified name modifier is allowed for the current 2674 // directive. 2675 // At most one if clause with the particular directive-name-modifier can 2676 // appear on the directive. 2677 bool MatchFound = false; 2678 for (auto NM : AllowedNameModifiers) { 2679 if (CurNM == NM) { 2680 MatchFound = true; 2681 break; 2682 } 2683 } 2684 if (!MatchFound) { 2685 S.Diag(IC->getNameModifierLoc(), 2686 diag::err_omp_wrong_if_directive_name_modifier) 2687 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 2688 ErrorFound = true; 2689 } 2690 } 2691 } 2692 // If any if clause on the directive includes a directive-name-modifier then 2693 // all if clauses on the directive must include a directive-name-modifier. 2694 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 2695 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 2696 S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(), 2697 diag::err_omp_no_more_if_clause); 2698 } else { 2699 std::string Values; 2700 std::string Sep(", "); 2701 unsigned AllowedCnt = 0; 2702 unsigned TotalAllowedNum = 2703 AllowedNameModifiers.size() - NamedModifiersNumber; 2704 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 2705 ++Cnt) { 2706 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 2707 if (!FoundNameModifiers[NM]) { 2708 Values += "'"; 2709 Values += getOpenMPDirectiveName(NM); 2710 Values += "'"; 2711 if (AllowedCnt + 2 == TotalAllowedNum) 2712 Values += " or "; 2713 else if (AllowedCnt + 1 != TotalAllowedNum) 2714 Values += Sep; 2715 ++AllowedCnt; 2716 } 2717 } 2718 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(), 2719 diag::err_omp_unnamed_if_clause) 2720 << (TotalAllowedNum > 1) << Values; 2721 } 2722 for (auto Loc : NameModifierLoc) { 2723 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 2724 } 2725 ErrorFound = true; 2726 } 2727 return ErrorFound; 2728 } 2729 2730 StmtResult Sema::ActOnOpenMPExecutableDirective( 2731 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 2732 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 2733 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 2734 StmtResult Res = StmtError(); 2735 // First check CancelRegion which is then used in checkNestingOfRegions. 2736 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 2737 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 2738 StartLoc)) 2739 return StmtError(); 2740 2741 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 2742 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 2743 bool ErrorFound = false; 2744 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 2745 if (AStmt && !CurContext->isDependentContext()) { 2746 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 2747 2748 // Check default data sharing attributes for referenced variables. 2749 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 2750 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 2751 Stmt *S = AStmt; 2752 while (--ThisCaptureLevel >= 0) 2753 S = cast<CapturedStmt>(S)->getCapturedStmt(); 2754 DSAChecker.Visit(S); 2755 if (DSAChecker.isErrorFound()) 2756 return StmtError(); 2757 // Generate list of implicitly defined firstprivate variables. 2758 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 2759 2760 SmallVector<Expr *, 4> ImplicitFirstprivates( 2761 DSAChecker.getImplicitFirstprivate().begin(), 2762 DSAChecker.getImplicitFirstprivate().end()); 2763 SmallVector<Expr *, 4> ImplicitMaps(DSAChecker.getImplicitMap().begin(), 2764 DSAChecker.getImplicitMap().end()); 2765 // Mark taskgroup task_reduction descriptors as implicitly firstprivate. 2766 for (auto *C : Clauses) { 2767 if (auto *IRC = dyn_cast<OMPInReductionClause>(C)) { 2768 for (auto *E : IRC->taskgroup_descriptors()) 2769 if (E) 2770 ImplicitFirstprivates.emplace_back(E); 2771 } 2772 } 2773 if (!ImplicitFirstprivates.empty()) { 2774 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 2775 ImplicitFirstprivates, SourceLocation(), SourceLocation(), 2776 SourceLocation())) { 2777 ClausesWithImplicit.push_back(Implicit); 2778 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 2779 ImplicitFirstprivates.size(); 2780 } else 2781 ErrorFound = true; 2782 } 2783 if (!ImplicitMaps.empty()) { 2784 if (OMPClause *Implicit = ActOnOpenMPMapClause( 2785 OMPC_MAP_unknown, OMPC_MAP_tofrom, /*IsMapTypeImplicit=*/true, 2786 SourceLocation(), SourceLocation(), ImplicitMaps, 2787 SourceLocation(), SourceLocation(), SourceLocation())) { 2788 ClausesWithImplicit.emplace_back(Implicit); 2789 ErrorFound |= 2790 cast<OMPMapClause>(Implicit)->varlist_size() != ImplicitMaps.size(); 2791 } else 2792 ErrorFound = true; 2793 } 2794 } 2795 2796 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 2797 switch (Kind) { 2798 case OMPD_parallel: 2799 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 2800 EndLoc); 2801 AllowedNameModifiers.push_back(OMPD_parallel); 2802 break; 2803 case OMPD_simd: 2804 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 2805 VarsWithInheritedDSA); 2806 break; 2807 case OMPD_for: 2808 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 2809 VarsWithInheritedDSA); 2810 break; 2811 case OMPD_for_simd: 2812 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 2813 EndLoc, VarsWithInheritedDSA); 2814 break; 2815 case OMPD_sections: 2816 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 2817 EndLoc); 2818 break; 2819 case OMPD_section: 2820 assert(ClausesWithImplicit.empty() && 2821 "No clauses are allowed for 'omp section' directive"); 2822 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 2823 break; 2824 case OMPD_single: 2825 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 2826 EndLoc); 2827 break; 2828 case OMPD_master: 2829 assert(ClausesWithImplicit.empty() && 2830 "No clauses are allowed for 'omp master' directive"); 2831 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 2832 break; 2833 case OMPD_critical: 2834 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 2835 StartLoc, EndLoc); 2836 break; 2837 case OMPD_parallel_for: 2838 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 2839 EndLoc, VarsWithInheritedDSA); 2840 AllowedNameModifiers.push_back(OMPD_parallel); 2841 break; 2842 case OMPD_parallel_for_simd: 2843 Res = ActOnOpenMPParallelForSimdDirective( 2844 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2845 AllowedNameModifiers.push_back(OMPD_parallel); 2846 break; 2847 case OMPD_parallel_sections: 2848 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 2849 StartLoc, EndLoc); 2850 AllowedNameModifiers.push_back(OMPD_parallel); 2851 break; 2852 case OMPD_task: 2853 Res = 2854 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 2855 AllowedNameModifiers.push_back(OMPD_task); 2856 break; 2857 case OMPD_taskyield: 2858 assert(ClausesWithImplicit.empty() && 2859 "No clauses are allowed for 'omp taskyield' directive"); 2860 assert(AStmt == nullptr && 2861 "No associated statement allowed for 'omp taskyield' directive"); 2862 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 2863 break; 2864 case OMPD_barrier: 2865 assert(ClausesWithImplicit.empty() && 2866 "No clauses are allowed for 'omp barrier' directive"); 2867 assert(AStmt == nullptr && 2868 "No associated statement allowed for 'omp barrier' directive"); 2869 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 2870 break; 2871 case OMPD_taskwait: 2872 assert(ClausesWithImplicit.empty() && 2873 "No clauses are allowed for 'omp taskwait' directive"); 2874 assert(AStmt == nullptr && 2875 "No associated statement allowed for 'omp taskwait' directive"); 2876 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 2877 break; 2878 case OMPD_taskgroup: 2879 Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc, 2880 EndLoc); 2881 break; 2882 case OMPD_flush: 2883 assert(AStmt == nullptr && 2884 "No associated statement allowed for 'omp flush' directive"); 2885 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 2886 break; 2887 case OMPD_ordered: 2888 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 2889 EndLoc); 2890 break; 2891 case OMPD_atomic: 2892 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 2893 EndLoc); 2894 break; 2895 case OMPD_teams: 2896 Res = 2897 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 2898 break; 2899 case OMPD_target: 2900 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 2901 EndLoc); 2902 AllowedNameModifiers.push_back(OMPD_target); 2903 break; 2904 case OMPD_target_parallel: 2905 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 2906 StartLoc, EndLoc); 2907 AllowedNameModifiers.push_back(OMPD_target); 2908 AllowedNameModifiers.push_back(OMPD_parallel); 2909 break; 2910 case OMPD_target_parallel_for: 2911 Res = ActOnOpenMPTargetParallelForDirective( 2912 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2913 AllowedNameModifiers.push_back(OMPD_target); 2914 AllowedNameModifiers.push_back(OMPD_parallel); 2915 break; 2916 case OMPD_cancellation_point: 2917 assert(ClausesWithImplicit.empty() && 2918 "No clauses are allowed for 'omp cancellation point' directive"); 2919 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 2920 "cancellation point' directive"); 2921 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 2922 break; 2923 case OMPD_cancel: 2924 assert(AStmt == nullptr && 2925 "No associated statement allowed for 'omp cancel' directive"); 2926 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 2927 CancelRegion); 2928 AllowedNameModifiers.push_back(OMPD_cancel); 2929 break; 2930 case OMPD_target_data: 2931 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 2932 EndLoc); 2933 AllowedNameModifiers.push_back(OMPD_target_data); 2934 break; 2935 case OMPD_target_enter_data: 2936 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 2937 EndLoc); 2938 AllowedNameModifiers.push_back(OMPD_target_enter_data); 2939 break; 2940 case OMPD_target_exit_data: 2941 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 2942 EndLoc); 2943 AllowedNameModifiers.push_back(OMPD_target_exit_data); 2944 break; 2945 case OMPD_taskloop: 2946 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 2947 EndLoc, VarsWithInheritedDSA); 2948 AllowedNameModifiers.push_back(OMPD_taskloop); 2949 break; 2950 case OMPD_taskloop_simd: 2951 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 2952 EndLoc, VarsWithInheritedDSA); 2953 AllowedNameModifiers.push_back(OMPD_taskloop); 2954 break; 2955 case OMPD_distribute: 2956 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 2957 EndLoc, VarsWithInheritedDSA); 2958 break; 2959 case OMPD_target_update: 2960 assert(!AStmt && "Statement is not allowed for target update"); 2961 Res = 2962 ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, EndLoc); 2963 AllowedNameModifiers.push_back(OMPD_target_update); 2964 break; 2965 case OMPD_distribute_parallel_for: 2966 Res = ActOnOpenMPDistributeParallelForDirective( 2967 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2968 AllowedNameModifiers.push_back(OMPD_parallel); 2969 break; 2970 case OMPD_distribute_parallel_for_simd: 2971 Res = ActOnOpenMPDistributeParallelForSimdDirective( 2972 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2973 AllowedNameModifiers.push_back(OMPD_parallel); 2974 break; 2975 case OMPD_distribute_simd: 2976 Res = ActOnOpenMPDistributeSimdDirective( 2977 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2978 break; 2979 case OMPD_target_parallel_for_simd: 2980 Res = ActOnOpenMPTargetParallelForSimdDirective( 2981 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2982 AllowedNameModifiers.push_back(OMPD_target); 2983 AllowedNameModifiers.push_back(OMPD_parallel); 2984 break; 2985 case OMPD_target_simd: 2986 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 2987 EndLoc, VarsWithInheritedDSA); 2988 AllowedNameModifiers.push_back(OMPD_target); 2989 break; 2990 case OMPD_teams_distribute: 2991 Res = ActOnOpenMPTeamsDistributeDirective( 2992 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2993 break; 2994 case OMPD_teams_distribute_simd: 2995 Res = ActOnOpenMPTeamsDistributeSimdDirective( 2996 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2997 break; 2998 case OMPD_teams_distribute_parallel_for_simd: 2999 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 3000 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3001 AllowedNameModifiers.push_back(OMPD_parallel); 3002 break; 3003 case OMPD_teams_distribute_parallel_for: 3004 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 3005 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3006 AllowedNameModifiers.push_back(OMPD_parallel); 3007 break; 3008 case OMPD_target_teams: 3009 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 3010 EndLoc); 3011 AllowedNameModifiers.push_back(OMPD_target); 3012 break; 3013 case OMPD_target_teams_distribute: 3014 Res = ActOnOpenMPTargetTeamsDistributeDirective( 3015 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3016 AllowedNameModifiers.push_back(OMPD_target); 3017 break; 3018 case OMPD_target_teams_distribute_parallel_for: 3019 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 3020 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3021 AllowedNameModifiers.push_back(OMPD_target); 3022 AllowedNameModifiers.push_back(OMPD_parallel); 3023 break; 3024 case OMPD_target_teams_distribute_parallel_for_simd: 3025 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 3026 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3027 AllowedNameModifiers.push_back(OMPD_target); 3028 AllowedNameModifiers.push_back(OMPD_parallel); 3029 break; 3030 case OMPD_target_teams_distribute_simd: 3031 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 3032 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3033 AllowedNameModifiers.push_back(OMPD_target); 3034 break; 3035 case OMPD_declare_target: 3036 case OMPD_end_declare_target: 3037 case OMPD_threadprivate: 3038 case OMPD_declare_reduction: 3039 case OMPD_declare_simd: 3040 llvm_unreachable("OpenMP Directive is not allowed"); 3041 case OMPD_unknown: 3042 llvm_unreachable("Unknown OpenMP directive"); 3043 } 3044 3045 for (auto P : VarsWithInheritedDSA) { 3046 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 3047 << P.first << P.second->getSourceRange(); 3048 } 3049 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 3050 3051 if (!AllowedNameModifiers.empty()) 3052 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 3053 ErrorFound; 3054 3055 if (ErrorFound) 3056 return StmtError(); 3057 return Res; 3058 } 3059 3060 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 3061 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 3062 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 3063 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 3064 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 3065 assert(Aligneds.size() == Alignments.size()); 3066 assert(Linears.size() == LinModifiers.size()); 3067 assert(Linears.size() == Steps.size()); 3068 if (!DG || DG.get().isNull()) 3069 return DeclGroupPtrTy(); 3070 3071 if (!DG.get().isSingleDecl()) { 3072 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 3073 return DG; 3074 } 3075 auto *ADecl = DG.get().getSingleDecl(); 3076 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 3077 ADecl = FTD->getTemplatedDecl(); 3078 3079 auto *FD = dyn_cast<FunctionDecl>(ADecl); 3080 if (!FD) { 3081 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 3082 return DeclGroupPtrTy(); 3083 } 3084 3085 // OpenMP [2.8.2, declare simd construct, Description] 3086 // The parameter of the simdlen clause must be a constant positive integer 3087 // expression. 3088 ExprResult SL; 3089 if (Simdlen) 3090 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 3091 // OpenMP [2.8.2, declare simd construct, Description] 3092 // The special this pointer can be used as if was one of the arguments to the 3093 // function in any of the linear, aligned, or uniform clauses. 3094 // The uniform clause declares one or more arguments to have an invariant 3095 // value for all concurrent invocations of the function in the execution of a 3096 // single SIMD loop. 3097 llvm::DenseMap<Decl *, Expr *> UniformedArgs; 3098 Expr *UniformedLinearThis = nullptr; 3099 for (auto *E : Uniforms) { 3100 E = E->IgnoreParenImpCasts(); 3101 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3102 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 3103 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3104 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3105 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 3106 UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E)); 3107 continue; 3108 } 3109 if (isa<CXXThisExpr>(E)) { 3110 UniformedLinearThis = E; 3111 continue; 3112 } 3113 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3114 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3115 } 3116 // OpenMP [2.8.2, declare simd construct, Description] 3117 // The aligned clause declares that the object to which each list item points 3118 // is aligned to the number of bytes expressed in the optional parameter of 3119 // the aligned clause. 3120 // The special this pointer can be used as if was one of the arguments to the 3121 // function in any of the linear, aligned, or uniform clauses. 3122 // The type of list items appearing in the aligned clause must be array, 3123 // pointer, reference to array, or reference to pointer. 3124 llvm::DenseMap<Decl *, Expr *> AlignedArgs; 3125 Expr *AlignedThis = nullptr; 3126 for (auto *E : Aligneds) { 3127 E = E->IgnoreParenImpCasts(); 3128 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3129 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3130 auto *CanonPVD = PVD->getCanonicalDecl(); 3131 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3132 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3133 ->getCanonicalDecl() == CanonPVD) { 3134 // OpenMP [2.8.1, simd construct, Restrictions] 3135 // A list-item cannot appear in more than one aligned clause. 3136 if (AlignedArgs.count(CanonPVD) > 0) { 3137 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3138 << 1 << E->getSourceRange(); 3139 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 3140 diag::note_omp_explicit_dsa) 3141 << getOpenMPClauseName(OMPC_aligned); 3142 continue; 3143 } 3144 AlignedArgs[CanonPVD] = E; 3145 QualType QTy = PVD->getType() 3146 .getNonReferenceType() 3147 .getUnqualifiedType() 3148 .getCanonicalType(); 3149 const Type *Ty = QTy.getTypePtrOrNull(); 3150 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 3151 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 3152 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 3153 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 3154 } 3155 continue; 3156 } 3157 } 3158 if (isa<CXXThisExpr>(E)) { 3159 if (AlignedThis) { 3160 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3161 << 2 << E->getSourceRange(); 3162 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 3163 << getOpenMPClauseName(OMPC_aligned); 3164 } 3165 AlignedThis = E; 3166 continue; 3167 } 3168 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3169 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3170 } 3171 // The optional parameter of the aligned clause, alignment, must be a constant 3172 // positive integer expression. If no optional parameter is specified, 3173 // implementation-defined default alignments for SIMD instructions on the 3174 // target platforms are assumed. 3175 SmallVector<Expr *, 4> NewAligns; 3176 for (auto *E : Alignments) { 3177 ExprResult Align; 3178 if (E) 3179 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 3180 NewAligns.push_back(Align.get()); 3181 } 3182 // OpenMP [2.8.2, declare simd construct, Description] 3183 // The linear clause declares one or more list items to be private to a SIMD 3184 // lane and to have a linear relationship with respect to the iteration space 3185 // of a loop. 3186 // The special this pointer can be used as if was one of the arguments to the 3187 // function in any of the linear, aligned, or uniform clauses. 3188 // When a linear-step expression is specified in a linear clause it must be 3189 // either a constant integer expression or an integer-typed parameter that is 3190 // specified in a uniform clause on the directive. 3191 llvm::DenseMap<Decl *, Expr *> LinearArgs; 3192 const bool IsUniformedThis = UniformedLinearThis != nullptr; 3193 auto MI = LinModifiers.begin(); 3194 for (auto *E : Linears) { 3195 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 3196 ++MI; 3197 E = E->IgnoreParenImpCasts(); 3198 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3199 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3200 auto *CanonPVD = PVD->getCanonicalDecl(); 3201 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3202 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3203 ->getCanonicalDecl() == CanonPVD) { 3204 // OpenMP [2.15.3.7, linear Clause, Restrictions] 3205 // A list-item cannot appear in more than one linear clause. 3206 if (LinearArgs.count(CanonPVD) > 0) { 3207 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3208 << getOpenMPClauseName(OMPC_linear) 3209 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 3210 Diag(LinearArgs[CanonPVD]->getExprLoc(), 3211 diag::note_omp_explicit_dsa) 3212 << getOpenMPClauseName(OMPC_linear); 3213 continue; 3214 } 3215 // Each argument can appear in at most one uniform or linear clause. 3216 if (UniformedArgs.count(CanonPVD) > 0) { 3217 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3218 << getOpenMPClauseName(OMPC_linear) 3219 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 3220 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 3221 diag::note_omp_explicit_dsa) 3222 << getOpenMPClauseName(OMPC_uniform); 3223 continue; 3224 } 3225 LinearArgs[CanonPVD] = E; 3226 if (E->isValueDependent() || E->isTypeDependent() || 3227 E->isInstantiationDependent() || 3228 E->containsUnexpandedParameterPack()) 3229 continue; 3230 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 3231 PVD->getOriginalType()); 3232 continue; 3233 } 3234 } 3235 if (isa<CXXThisExpr>(E)) { 3236 if (UniformedLinearThis) { 3237 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3238 << getOpenMPClauseName(OMPC_linear) 3239 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 3240 << E->getSourceRange(); 3241 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 3242 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 3243 : OMPC_linear); 3244 continue; 3245 } 3246 UniformedLinearThis = E; 3247 if (E->isValueDependent() || E->isTypeDependent() || 3248 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 3249 continue; 3250 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 3251 E->getType()); 3252 continue; 3253 } 3254 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3255 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3256 } 3257 Expr *Step = nullptr; 3258 Expr *NewStep = nullptr; 3259 SmallVector<Expr *, 4> NewSteps; 3260 for (auto *E : Steps) { 3261 // Skip the same step expression, it was checked already. 3262 if (Step == E || !E) { 3263 NewSteps.push_back(E ? NewStep : nullptr); 3264 continue; 3265 } 3266 Step = E; 3267 if (auto *DRE = dyn_cast<DeclRefExpr>(Step)) 3268 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3269 auto *CanonPVD = PVD->getCanonicalDecl(); 3270 if (UniformedArgs.count(CanonPVD) == 0) { 3271 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 3272 << Step->getSourceRange(); 3273 } else if (E->isValueDependent() || E->isTypeDependent() || 3274 E->isInstantiationDependent() || 3275 E->containsUnexpandedParameterPack() || 3276 CanonPVD->getType()->hasIntegerRepresentation()) 3277 NewSteps.push_back(Step); 3278 else { 3279 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 3280 << Step->getSourceRange(); 3281 } 3282 continue; 3283 } 3284 NewStep = Step; 3285 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 3286 !Step->isInstantiationDependent() && 3287 !Step->containsUnexpandedParameterPack()) { 3288 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 3289 .get(); 3290 if (NewStep) 3291 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 3292 } 3293 NewSteps.push_back(NewStep); 3294 } 3295 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 3296 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 3297 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 3298 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 3299 const_cast<Expr **>(Linears.data()), Linears.size(), 3300 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 3301 NewSteps.data(), NewSteps.size(), SR); 3302 ADecl->addAttr(NewAttr); 3303 return ConvertDeclToDeclGroup(ADecl); 3304 } 3305 3306 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 3307 Stmt *AStmt, 3308 SourceLocation StartLoc, 3309 SourceLocation EndLoc) { 3310 if (!AStmt) 3311 return StmtError(); 3312 3313 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 3314 // 1.2.2 OpenMP Language Terminology 3315 // Structured block - An executable statement with a single entry at the 3316 // top and a single exit at the bottom. 3317 // The point of exit cannot be a branch out of the structured block. 3318 // longjmp() and throw() must not violate the entry/exit criteria. 3319 CS->getCapturedDecl()->setNothrow(); 3320 3321 getCurFunction()->setHasBranchProtectedScope(); 3322 3323 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 3324 DSAStack->isCancelRegion()); 3325 } 3326 3327 namespace { 3328 /// \brief Helper class for checking canonical form of the OpenMP loops and 3329 /// extracting iteration space of each loop in the loop nest, that will be used 3330 /// for IR generation. 3331 class OpenMPIterationSpaceChecker { 3332 /// \brief Reference to Sema. 3333 Sema &SemaRef; 3334 /// \brief A location for diagnostics (when there is no some better location). 3335 SourceLocation DefaultLoc; 3336 /// \brief A location for diagnostics (when increment is not compatible). 3337 SourceLocation ConditionLoc; 3338 /// \brief A source location for referring to loop init later. 3339 SourceRange InitSrcRange; 3340 /// \brief A source location for referring to condition later. 3341 SourceRange ConditionSrcRange; 3342 /// \brief A source location for referring to increment later. 3343 SourceRange IncrementSrcRange; 3344 /// \brief Loop variable. 3345 ValueDecl *LCDecl = nullptr; 3346 /// \brief Reference to loop variable. 3347 Expr *LCRef = nullptr; 3348 /// \brief Lower bound (initializer for the var). 3349 Expr *LB = nullptr; 3350 /// \brief Upper bound. 3351 Expr *UB = nullptr; 3352 /// \brief Loop step (increment). 3353 Expr *Step = nullptr; 3354 /// \brief This flag is true when condition is one of: 3355 /// Var < UB 3356 /// Var <= UB 3357 /// UB > Var 3358 /// UB >= Var 3359 bool TestIsLessOp = false; 3360 /// \brief This flag is true when condition is strict ( < or > ). 3361 bool TestIsStrictOp = false; 3362 /// \brief This flag is true when step is subtracted on each iteration. 3363 bool SubtractStep = false; 3364 3365 public: 3366 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 3367 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 3368 /// \brief Check init-expr for canonical loop form and save loop counter 3369 /// variable - #Var and its initialization value - #LB. 3370 bool CheckInit(Stmt *S, bool EmitDiags = true); 3371 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags 3372 /// for less/greater and for strict/non-strict comparison. 3373 bool CheckCond(Expr *S); 3374 /// \brief Check incr-expr for canonical loop form and return true if it 3375 /// does not conform, otherwise save loop step (#Step). 3376 bool CheckInc(Expr *S); 3377 /// \brief Return the loop counter variable. 3378 ValueDecl *GetLoopDecl() const { return LCDecl; } 3379 /// \brief Return the reference expression to loop counter variable. 3380 Expr *GetLoopDeclRefExpr() const { return LCRef; } 3381 /// \brief Source range of the loop init. 3382 SourceRange GetInitSrcRange() const { return InitSrcRange; } 3383 /// \brief Source range of the loop condition. 3384 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; } 3385 /// \brief Source range of the loop increment. 3386 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; } 3387 /// \brief True if the step should be subtracted. 3388 bool ShouldSubtractStep() const { return SubtractStep; } 3389 /// \brief Build the expression to calculate the number of iterations. 3390 Expr * 3391 BuildNumIterations(Scope *S, const bool LimitedType, 3392 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3393 /// \brief Build the precondition expression for the loops. 3394 Expr *BuildPreCond(Scope *S, Expr *Cond, 3395 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3396 /// \brief Build reference expression to the counter be used for codegen. 3397 DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures, 3398 DSAStackTy &DSA) const; 3399 /// \brief Build reference expression to the private counter be used for 3400 /// codegen. 3401 Expr *BuildPrivateCounterVar() const; 3402 /// \brief Build initialization of the counter be used for codegen. 3403 Expr *BuildCounterInit() const; 3404 /// \brief Build step of the counter be used for codegen. 3405 Expr *BuildCounterStep() const; 3406 /// \brief Return true if any expression is dependent. 3407 bool Dependent() const; 3408 3409 private: 3410 /// \brief Check the right-hand side of an assignment in the increment 3411 /// expression. 3412 bool CheckIncRHS(Expr *RHS); 3413 /// \brief Helper to set loop counter variable and its initializer. 3414 bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); 3415 /// \brief Helper to set upper bound. 3416 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR, 3417 SourceLocation SL); 3418 /// \brief Helper to set loop increment. 3419 bool SetStep(Expr *NewStep, bool Subtract); 3420 }; 3421 3422 bool OpenMPIterationSpaceChecker::Dependent() const { 3423 if (!LCDecl) { 3424 assert(!LB && !UB && !Step); 3425 return false; 3426 } 3427 return LCDecl->getType()->isDependentType() || 3428 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 3429 (Step && Step->isValueDependent()); 3430 } 3431 3432 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl, 3433 Expr *NewLCRefExpr, 3434 Expr *NewLB) { 3435 // State consistency checking to ensure correct usage. 3436 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 3437 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3438 if (!NewLCDecl || !NewLB) 3439 return true; 3440 LCDecl = getCanonicalDecl(NewLCDecl); 3441 LCRef = NewLCRefExpr; 3442 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 3443 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3444 if ((Ctor->isCopyOrMoveConstructor() || 3445 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3446 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3447 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 3448 LB = NewLB; 3449 return false; 3450 } 3451 3452 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp, 3453 SourceRange SR, SourceLocation SL) { 3454 // State consistency checking to ensure correct usage. 3455 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 3456 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3457 if (!NewUB) 3458 return true; 3459 UB = NewUB; 3460 TestIsLessOp = LessOp; 3461 TestIsStrictOp = StrictOp; 3462 ConditionSrcRange = SR; 3463 ConditionLoc = SL; 3464 return false; 3465 } 3466 3467 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) { 3468 // State consistency checking to ensure correct usage. 3469 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 3470 if (!NewStep) 3471 return true; 3472 if (!NewStep->isValueDependent()) { 3473 // Check that the step is integer expression. 3474 SourceLocation StepLoc = NewStep->getLocStart(); 3475 ExprResult Val = SemaRef.PerformOpenMPImplicitIntegerConversion( 3476 StepLoc, getExprAsWritten(NewStep)); 3477 if (Val.isInvalid()) 3478 return true; 3479 NewStep = Val.get(); 3480 3481 // OpenMP [2.6, Canonical Loop Form, Restrictions] 3482 // If test-expr is of form var relational-op b and relational-op is < or 3483 // <= then incr-expr must cause var to increase on each iteration of the 3484 // loop. If test-expr is of form var relational-op b and relational-op is 3485 // > or >= then incr-expr must cause var to decrease on each iteration of 3486 // the loop. 3487 // If test-expr is of form b relational-op var and relational-op is < or 3488 // <= then incr-expr must cause var to decrease on each iteration of the 3489 // loop. If test-expr is of form b relational-op var and relational-op is 3490 // > or >= then incr-expr must cause var to increase on each iteration of 3491 // the loop. 3492 llvm::APSInt Result; 3493 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 3494 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 3495 bool IsConstNeg = 3496 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 3497 bool IsConstPos = 3498 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 3499 bool IsConstZero = IsConstant && !Result.getBoolValue(); 3500 if (UB && (IsConstZero || 3501 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 3502 : (IsConstPos || (IsUnsigned && !Subtract))))) { 3503 SemaRef.Diag(NewStep->getExprLoc(), 3504 diag::err_omp_loop_incr_not_compatible) 3505 << LCDecl << TestIsLessOp << NewStep->getSourceRange(); 3506 SemaRef.Diag(ConditionLoc, 3507 diag::note_omp_loop_cond_requres_compatible_incr) 3508 << TestIsLessOp << ConditionSrcRange; 3509 return true; 3510 } 3511 if (TestIsLessOp == Subtract) { 3512 NewStep = 3513 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 3514 .get(); 3515 Subtract = !Subtract; 3516 } 3517 } 3518 3519 Step = NewStep; 3520 SubtractStep = Subtract; 3521 return false; 3522 } 3523 3524 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { 3525 // Check init-expr for canonical loop form and save loop counter 3526 // variable - #Var and its initialization value - #LB. 3527 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 3528 // var = lb 3529 // integer-type var = lb 3530 // random-access-iterator-type var = lb 3531 // pointer-type var = lb 3532 // 3533 if (!S) { 3534 if (EmitDiags) { 3535 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 3536 } 3537 return true; 3538 } 3539 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 3540 if (!ExprTemp->cleanupsHaveSideEffects()) 3541 S = ExprTemp->getSubExpr(); 3542 3543 InitSrcRange = S->getSourceRange(); 3544 if (Expr *E = dyn_cast<Expr>(S)) 3545 S = E->IgnoreParens(); 3546 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 3547 if (BO->getOpcode() == BO_Assign) { 3548 auto *LHS = BO->getLHS()->IgnoreParens(); 3549 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 3550 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3551 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3552 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3553 return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); 3554 } 3555 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3556 if (ME->isArrow() && 3557 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3558 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3559 } 3560 } 3561 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 3562 if (DS->isSingleDecl()) { 3563 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 3564 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 3565 // Accept non-canonical init form here but emit ext. warning. 3566 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 3567 SemaRef.Diag(S->getLocStart(), 3568 diag::ext_omp_loop_not_canonical_init) 3569 << S->getSourceRange(); 3570 return SetLCDeclAndLB(Var, nullptr, Var->getInit()); 3571 } 3572 } 3573 } 3574 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3575 if (CE->getOperator() == OO_Equal) { 3576 auto *LHS = CE->getArg(0); 3577 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 3578 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3579 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3580 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3581 return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); 3582 } 3583 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3584 if (ME->isArrow() && 3585 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3586 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3587 } 3588 } 3589 } 3590 3591 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3592 return false; 3593 if (EmitDiags) { 3594 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init) 3595 << S->getSourceRange(); 3596 } 3597 return true; 3598 } 3599 3600 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the 3601 /// variable (which may be the loop variable) if possible. 3602 static const ValueDecl *GetInitLCDecl(Expr *E) { 3603 if (!E) 3604 return nullptr; 3605 E = getExprAsWritten(E); 3606 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 3607 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3608 if ((Ctor->isCopyOrMoveConstructor() || 3609 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3610 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3611 E = CE->getArg(0)->IgnoreParenImpCasts(); 3612 if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 3613 if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) 3614 return getCanonicalDecl(VD); 3615 } 3616 if (auto *ME = dyn_cast_or_null<MemberExpr>(E)) 3617 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3618 return getCanonicalDecl(ME->getMemberDecl()); 3619 return nullptr; 3620 } 3621 3622 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { 3623 // Check test-expr for canonical form, save upper-bound UB, flags for 3624 // less/greater and for strict/non-strict comparison. 3625 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3626 // var relational-op b 3627 // b relational-op var 3628 // 3629 if (!S) { 3630 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 3631 return true; 3632 } 3633 S = getExprAsWritten(S); 3634 SourceLocation CondLoc = S->getLocStart(); 3635 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 3636 if (BO->isRelationalOp()) { 3637 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3638 return SetUB(BO->getRHS(), 3639 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 3640 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3641 BO->getSourceRange(), BO->getOperatorLoc()); 3642 if (GetInitLCDecl(BO->getRHS()) == LCDecl) 3643 return SetUB(BO->getLHS(), 3644 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 3645 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3646 BO->getSourceRange(), BO->getOperatorLoc()); 3647 } 3648 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3649 if (CE->getNumArgs() == 2) { 3650 auto Op = CE->getOperator(); 3651 switch (Op) { 3652 case OO_Greater: 3653 case OO_GreaterEqual: 3654 case OO_Less: 3655 case OO_LessEqual: 3656 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3657 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 3658 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3659 CE->getOperatorLoc()); 3660 if (GetInitLCDecl(CE->getArg(1)) == LCDecl) 3661 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 3662 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3663 CE->getOperatorLoc()); 3664 break; 3665 default: 3666 break; 3667 } 3668 } 3669 } 3670 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3671 return false; 3672 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 3673 << S->getSourceRange() << LCDecl; 3674 return true; 3675 } 3676 3677 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) { 3678 // RHS of canonical loop form increment can be: 3679 // var + incr 3680 // incr + var 3681 // var - incr 3682 // 3683 RHS = RHS->IgnoreParenImpCasts(); 3684 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 3685 if (BO->isAdditiveOp()) { 3686 bool IsAdd = BO->getOpcode() == BO_Add; 3687 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3688 return SetStep(BO->getRHS(), !IsAdd); 3689 if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl) 3690 return SetStep(BO->getLHS(), false); 3691 } 3692 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 3693 bool IsAdd = CE->getOperator() == OO_Plus; 3694 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 3695 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3696 return SetStep(CE->getArg(1), !IsAdd); 3697 if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl) 3698 return SetStep(CE->getArg(0), false); 3699 } 3700 } 3701 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3702 return false; 3703 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr) 3704 << RHS->getSourceRange() << LCDecl; 3705 return true; 3706 } 3707 3708 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { 3709 // Check incr-expr for canonical loop form and return true if it 3710 // does not conform. 3711 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3712 // ++var 3713 // var++ 3714 // --var 3715 // var-- 3716 // var += incr 3717 // var -= incr 3718 // var = var + incr 3719 // var = incr + var 3720 // var = var - incr 3721 // 3722 if (!S) { 3723 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 3724 return true; 3725 } 3726 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 3727 if (!ExprTemp->cleanupsHaveSideEffects()) 3728 S = ExprTemp->getSubExpr(); 3729 3730 IncrementSrcRange = S->getSourceRange(); 3731 S = S->IgnoreParens(); 3732 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 3733 if (UO->isIncrementDecrementOp() && 3734 GetInitLCDecl(UO->getSubExpr()) == LCDecl) 3735 return SetStep(SemaRef 3736 .ActOnIntegerConstant(UO->getLocStart(), 3737 (UO->isDecrementOp() ? -1 : 1)) 3738 .get(), 3739 false); 3740 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 3741 switch (BO->getOpcode()) { 3742 case BO_AddAssign: 3743 case BO_SubAssign: 3744 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3745 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 3746 break; 3747 case BO_Assign: 3748 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3749 return CheckIncRHS(BO->getRHS()); 3750 break; 3751 default: 3752 break; 3753 } 3754 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3755 switch (CE->getOperator()) { 3756 case OO_PlusPlus: 3757 case OO_MinusMinus: 3758 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3759 return SetStep(SemaRef 3760 .ActOnIntegerConstant( 3761 CE->getLocStart(), 3762 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 3763 .get(), 3764 false); 3765 break; 3766 case OO_PlusEqual: 3767 case OO_MinusEqual: 3768 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3769 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 3770 break; 3771 case OO_Equal: 3772 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3773 return CheckIncRHS(CE->getArg(1)); 3774 break; 3775 default: 3776 break; 3777 } 3778 } 3779 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3780 return false; 3781 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr) 3782 << S->getSourceRange() << LCDecl; 3783 return true; 3784 } 3785 3786 static ExprResult 3787 tryBuildCapture(Sema &SemaRef, Expr *Capture, 3788 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 3789 if (SemaRef.CurContext->isDependentContext()) 3790 return ExprResult(Capture); 3791 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 3792 return SemaRef.PerformImplicitConversion( 3793 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 3794 /*AllowExplicit=*/true); 3795 auto I = Captures.find(Capture); 3796 if (I != Captures.end()) 3797 return buildCapture(SemaRef, Capture, I->second); 3798 DeclRefExpr *Ref = nullptr; 3799 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 3800 Captures[Capture] = Ref; 3801 return Res; 3802 } 3803 3804 /// \brief Build the expression to calculate the number of iterations. 3805 Expr *OpenMPIterationSpaceChecker::BuildNumIterations( 3806 Scope *S, const bool LimitedType, 3807 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 3808 ExprResult Diff; 3809 auto VarType = LCDecl->getType().getNonReferenceType(); 3810 if (VarType->isIntegerType() || VarType->isPointerType() || 3811 SemaRef.getLangOpts().CPlusPlus) { 3812 // Upper - Lower 3813 auto *UBExpr = TestIsLessOp ? UB : LB; 3814 auto *LBExpr = TestIsLessOp ? LB : UB; 3815 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 3816 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 3817 if (!Upper || !Lower) 3818 return nullptr; 3819 3820 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 3821 3822 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 3823 // BuildBinOp already emitted error, this one is to point user to upper 3824 // and lower bound, and to tell what is passed to 'operator-'. 3825 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) 3826 << Upper->getSourceRange() << Lower->getSourceRange(); 3827 return nullptr; 3828 } 3829 } 3830 3831 if (!Diff.isUsable()) 3832 return nullptr; 3833 3834 // Upper - Lower [- 1] 3835 if (TestIsStrictOp) 3836 Diff = SemaRef.BuildBinOp( 3837 S, DefaultLoc, BO_Sub, Diff.get(), 3838 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 3839 if (!Diff.isUsable()) 3840 return nullptr; 3841 3842 // Upper - Lower [- 1] + Step 3843 auto NewStep = tryBuildCapture(SemaRef, Step, Captures); 3844 if (!NewStep.isUsable()) 3845 return nullptr; 3846 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 3847 if (!Diff.isUsable()) 3848 return nullptr; 3849 3850 // Parentheses (for dumping/debugging purposes only). 3851 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 3852 if (!Diff.isUsable()) 3853 return nullptr; 3854 3855 // (Upper - Lower [- 1] + Step) / Step 3856 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 3857 if (!Diff.isUsable()) 3858 return nullptr; 3859 3860 // OpenMP runtime requires 32-bit or 64-bit loop variables. 3861 QualType Type = Diff.get()->getType(); 3862 auto &C = SemaRef.Context; 3863 bool UseVarType = VarType->hasIntegerRepresentation() && 3864 C.getTypeSize(Type) > C.getTypeSize(VarType); 3865 if (!Type->isIntegerType() || UseVarType) { 3866 unsigned NewSize = 3867 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 3868 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 3869 : Type->hasSignedIntegerRepresentation(); 3870 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 3871 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 3872 Diff = SemaRef.PerformImplicitConversion( 3873 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 3874 if (!Diff.isUsable()) 3875 return nullptr; 3876 } 3877 } 3878 if (LimitedType) { 3879 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 3880 if (NewSize != C.getTypeSize(Type)) { 3881 if (NewSize < C.getTypeSize(Type)) { 3882 assert(NewSize == 64 && "incorrect loop var size"); 3883 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 3884 << InitSrcRange << ConditionSrcRange; 3885 } 3886 QualType NewType = C.getIntTypeForBitwidth( 3887 NewSize, Type->hasSignedIntegerRepresentation() || 3888 C.getTypeSize(Type) < NewSize); 3889 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 3890 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 3891 Sema::AA_Converting, true); 3892 if (!Diff.isUsable()) 3893 return nullptr; 3894 } 3895 } 3896 } 3897 3898 return Diff.get(); 3899 } 3900 3901 Expr *OpenMPIterationSpaceChecker::BuildPreCond( 3902 Scope *S, Expr *Cond, 3903 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 3904 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 3905 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 3906 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 3907 3908 auto NewLB = tryBuildCapture(SemaRef, LB, Captures); 3909 auto NewUB = tryBuildCapture(SemaRef, UB, Captures); 3910 if (!NewLB.isUsable() || !NewUB.isUsable()) 3911 return nullptr; 3912 3913 auto CondExpr = SemaRef.BuildBinOp( 3914 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) 3915 : (TestIsStrictOp ? BO_GT : BO_GE), 3916 NewLB.get(), NewUB.get()); 3917 if (CondExpr.isUsable()) { 3918 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 3919 SemaRef.Context.BoolTy)) 3920 CondExpr = SemaRef.PerformImplicitConversion( 3921 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 3922 /*AllowExplicit=*/true); 3923 } 3924 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 3925 // Otherwise use original loop conditon and evaluate it in runtime. 3926 return CondExpr.isUsable() ? CondExpr.get() : Cond; 3927 } 3928 3929 /// \brief Build reference expression to the counter be used for codegen. 3930 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar( 3931 llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const { 3932 auto *VD = dyn_cast<VarDecl>(LCDecl); 3933 if (!VD) { 3934 VD = SemaRef.IsOpenMPCapturedDecl(LCDecl); 3935 auto *Ref = buildDeclRefExpr( 3936 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 3937 DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl, /*FromParent=*/false); 3938 // If the loop control decl is explicitly marked as private, do not mark it 3939 // as captured again. 3940 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 3941 Captures.insert(std::make_pair(LCRef, Ref)); 3942 return Ref; 3943 } 3944 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(), 3945 DefaultLoc); 3946 } 3947 3948 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const { 3949 if (LCDecl && !LCDecl->isInvalidDecl()) { 3950 auto Type = LCDecl->getType().getNonReferenceType(); 3951 auto *PrivateVar = 3952 buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(), 3953 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr); 3954 if (PrivateVar->isInvalidDecl()) 3955 return nullptr; 3956 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 3957 } 3958 return nullptr; 3959 } 3960 3961 /// \brief Build initialization of the counter to be used for codegen. 3962 Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; } 3963 3964 /// \brief Build step of the counter be used for codegen. 3965 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; } 3966 3967 /// \brief Iteration space of a single for loop. 3968 struct LoopIterationSpace final { 3969 /// \brief Condition of the loop. 3970 Expr *PreCond = nullptr; 3971 /// \brief This expression calculates the number of iterations in the loop. 3972 /// It is always possible to calculate it before starting the loop. 3973 Expr *NumIterations = nullptr; 3974 /// \brief The loop counter variable. 3975 Expr *CounterVar = nullptr; 3976 /// \brief Private loop counter variable. 3977 Expr *PrivateCounterVar = nullptr; 3978 /// \brief This is initializer for the initial value of #CounterVar. 3979 Expr *CounterInit = nullptr; 3980 /// \brief This is step for the #CounterVar used to generate its update: 3981 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 3982 Expr *CounterStep = nullptr; 3983 /// \brief Should step be subtracted? 3984 bool Subtract = false; 3985 /// \brief Source range of the loop init. 3986 SourceRange InitSrcRange; 3987 /// \brief Source range of the loop condition. 3988 SourceRange CondSrcRange; 3989 /// \brief Source range of the loop increment. 3990 SourceRange IncSrcRange; 3991 }; 3992 3993 } // namespace 3994 3995 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 3996 assert(getLangOpts().OpenMP && "OpenMP is not active."); 3997 assert(Init && "Expected loop in canonical form."); 3998 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 3999 if (AssociatedLoops > 0 && 4000 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 4001 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 4002 if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) { 4003 if (auto *D = ISC.GetLoopDecl()) { 4004 auto *VD = dyn_cast<VarDecl>(D); 4005 if (!VD) { 4006 if (auto *Private = IsOpenMPCapturedDecl(D)) 4007 VD = Private; 4008 else { 4009 auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(), 4010 /*WithInit=*/false); 4011 VD = cast<VarDecl>(Ref->getDecl()); 4012 } 4013 } 4014 DSAStack->addLoopControlVariable(D, VD); 4015 } 4016 } 4017 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 4018 } 4019 } 4020 4021 /// \brief Called on a for stmt to check and extract its iteration space 4022 /// for further processing (such as collapsing). 4023 static bool CheckOpenMPIterationSpace( 4024 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 4025 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 4026 Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, 4027 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 4028 LoopIterationSpace &ResultIterSpace, 4029 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4030 // OpenMP [2.6, Canonical Loop Form] 4031 // for (init-expr; test-expr; incr-expr) structured-block 4032 auto *For = dyn_cast_or_null<ForStmt>(S); 4033 if (!For) { 4034 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for) 4035 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 4036 << getOpenMPDirectiveName(DKind) << NestedLoopCount 4037 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 4038 if (NestedLoopCount > 1) { 4039 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 4040 SemaRef.Diag(DSA.getConstructLoc(), 4041 diag::note_omp_collapse_ordered_expr) 4042 << 2 << CollapseLoopCountExpr->getSourceRange() 4043 << OrderedLoopCountExpr->getSourceRange(); 4044 else if (CollapseLoopCountExpr) 4045 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4046 diag::note_omp_collapse_ordered_expr) 4047 << 0 << CollapseLoopCountExpr->getSourceRange(); 4048 else 4049 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4050 diag::note_omp_collapse_ordered_expr) 4051 << 1 << OrderedLoopCountExpr->getSourceRange(); 4052 } 4053 return true; 4054 } 4055 assert(For->getBody()); 4056 4057 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 4058 4059 // Check init. 4060 auto Init = For->getInit(); 4061 if (ISC.CheckInit(Init)) 4062 return true; 4063 4064 bool HasErrors = false; 4065 4066 // Check loop variable's type. 4067 if (auto *LCDecl = ISC.GetLoopDecl()) { 4068 auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr(); 4069 4070 // OpenMP [2.6, Canonical Loop Form] 4071 // Var is one of the following: 4072 // A variable of signed or unsigned integer type. 4073 // For C++, a variable of a random access iterator type. 4074 // For C, a variable of a pointer type. 4075 auto VarType = LCDecl->getType().getNonReferenceType(); 4076 if (!VarType->isDependentType() && !VarType->isIntegerType() && 4077 !VarType->isPointerType() && 4078 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 4079 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type) 4080 << SemaRef.getLangOpts().CPlusPlus; 4081 HasErrors = true; 4082 } 4083 4084 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 4085 // a Construct 4086 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4087 // parallel for construct is (are) private. 4088 // The loop iteration variable in the associated for-loop of a simd 4089 // construct with just one associated for-loop is linear with a 4090 // constant-linear-step that is the increment of the associated for-loop. 4091 // Exclude loop var from the list of variables with implicitly defined data 4092 // sharing attributes. 4093 VarsWithImplicitDSA.erase(LCDecl); 4094 4095 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 4096 // in a Construct, C/C++]. 4097 // The loop iteration variable in the associated for-loop of a simd 4098 // construct with just one associated for-loop may be listed in a linear 4099 // clause with a constant-linear-step that is the increment of the 4100 // associated for-loop. 4101 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4102 // parallel for construct may be listed in a private or lastprivate clause. 4103 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 4104 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 4105 // declared in the loop and it is predetermined as a private. 4106 auto PredeterminedCKind = 4107 isOpenMPSimdDirective(DKind) 4108 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 4109 : OMPC_private; 4110 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4111 DVar.CKind != PredeterminedCKind) || 4112 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 4113 isOpenMPDistributeDirective(DKind)) && 4114 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4115 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 4116 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 4117 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa) 4118 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 4119 << getOpenMPClauseName(PredeterminedCKind); 4120 if (DVar.RefExpr == nullptr) 4121 DVar.CKind = PredeterminedCKind; 4122 ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 4123 HasErrors = true; 4124 } else if (LoopDeclRefExpr != nullptr) { 4125 // Make the loop iteration variable private (for worksharing constructs), 4126 // linear (for simd directives with the only one associated loop) or 4127 // lastprivate (for simd directives with several collapsed or ordered 4128 // loops). 4129 if (DVar.CKind == OMPC_unknown) 4130 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate, 4131 [](OpenMPDirectiveKind) -> bool { return true; }, 4132 /*FromParent=*/false); 4133 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 4134 } 4135 4136 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 4137 4138 // Check test-expr. 4139 HasErrors |= ISC.CheckCond(For->getCond()); 4140 4141 // Check incr-expr. 4142 HasErrors |= ISC.CheckInc(For->getInc()); 4143 } 4144 4145 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 4146 return HasErrors; 4147 4148 // Build the loop's iteration space representation. 4149 ResultIterSpace.PreCond = 4150 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures); 4151 ResultIterSpace.NumIterations = ISC.BuildNumIterations( 4152 DSA.getCurScope(), 4153 (isOpenMPWorksharingDirective(DKind) || 4154 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 4155 Captures); 4156 ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA); 4157 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); 4158 ResultIterSpace.CounterInit = ISC.BuildCounterInit(); 4159 ResultIterSpace.CounterStep = ISC.BuildCounterStep(); 4160 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); 4161 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange(); 4162 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange(); 4163 ResultIterSpace.Subtract = ISC.ShouldSubtractStep(); 4164 4165 HasErrors |= (ResultIterSpace.PreCond == nullptr || 4166 ResultIterSpace.NumIterations == nullptr || 4167 ResultIterSpace.CounterVar == nullptr || 4168 ResultIterSpace.PrivateCounterVar == nullptr || 4169 ResultIterSpace.CounterInit == nullptr || 4170 ResultIterSpace.CounterStep == nullptr); 4171 4172 return HasErrors; 4173 } 4174 4175 /// \brief Build 'VarRef = Start. 4176 static ExprResult 4177 BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 4178 ExprResult Start, 4179 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4180 // Build 'VarRef = Start. 4181 auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 4182 if (!NewStart.isUsable()) 4183 return ExprError(); 4184 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 4185 VarRef.get()->getType())) { 4186 NewStart = SemaRef.PerformImplicitConversion( 4187 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 4188 /*AllowExplicit=*/true); 4189 if (!NewStart.isUsable()) 4190 return ExprError(); 4191 } 4192 4193 auto Init = 4194 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4195 return Init; 4196 } 4197 4198 /// \brief Build 'VarRef = Start + Iter * Step'. 4199 static ExprResult 4200 BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, 4201 ExprResult VarRef, ExprResult Start, ExprResult Iter, 4202 ExprResult Step, bool Subtract, 4203 llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) { 4204 // Add parentheses (for debugging purposes only). 4205 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 4206 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 4207 !Step.isUsable()) 4208 return ExprError(); 4209 4210 ExprResult NewStep = Step; 4211 if (Captures) 4212 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 4213 if (NewStep.isInvalid()) 4214 return ExprError(); 4215 ExprResult Update = 4216 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 4217 if (!Update.isUsable()) 4218 return ExprError(); 4219 4220 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 4221 // 'VarRef = Start (+|-) Iter * Step'. 4222 ExprResult NewStart = Start; 4223 if (Captures) 4224 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 4225 if (NewStart.isInvalid()) 4226 return ExprError(); 4227 4228 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 4229 ExprResult SavedUpdate = Update; 4230 ExprResult UpdateVal; 4231 if (VarRef.get()->getType()->isOverloadableType() || 4232 NewStart.get()->getType()->isOverloadableType() || 4233 Update.get()->getType()->isOverloadableType()) { 4234 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4235 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4236 Update = 4237 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4238 if (Update.isUsable()) { 4239 UpdateVal = 4240 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 4241 VarRef.get(), SavedUpdate.get()); 4242 if (UpdateVal.isUsable()) { 4243 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 4244 UpdateVal.get()); 4245 } 4246 } 4247 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4248 } 4249 4250 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 4251 if (!Update.isUsable() || !UpdateVal.isUsable()) { 4252 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 4253 NewStart.get(), SavedUpdate.get()); 4254 if (!Update.isUsable()) 4255 return ExprError(); 4256 4257 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 4258 VarRef.get()->getType())) { 4259 Update = SemaRef.PerformImplicitConversion( 4260 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 4261 if (!Update.isUsable()) 4262 return ExprError(); 4263 } 4264 4265 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 4266 } 4267 return Update; 4268 } 4269 4270 /// \brief Convert integer expression \a E to make it have at least \a Bits 4271 /// bits. 4272 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 4273 if (E == nullptr) 4274 return ExprError(); 4275 auto &C = SemaRef.Context; 4276 QualType OldType = E->getType(); 4277 unsigned HasBits = C.getTypeSize(OldType); 4278 if (HasBits >= Bits) 4279 return ExprResult(E); 4280 // OK to convert to signed, because new type has more bits than old. 4281 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 4282 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 4283 true); 4284 } 4285 4286 /// \brief Check if the given expression \a E is a constant integer that fits 4287 /// into \a Bits bits. 4288 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { 4289 if (E == nullptr) 4290 return false; 4291 llvm::APSInt Result; 4292 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 4293 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 4294 return false; 4295 } 4296 4297 /// Build preinits statement for the given declarations. 4298 static Stmt *buildPreInits(ASTContext &Context, 4299 SmallVectorImpl<Decl *> &PreInits) { 4300 if (!PreInits.empty()) { 4301 return new (Context) DeclStmt( 4302 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 4303 SourceLocation(), SourceLocation()); 4304 } 4305 return nullptr; 4306 } 4307 4308 /// Build preinits statement for the given declarations. 4309 static Stmt *buildPreInits(ASTContext &Context, 4310 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4311 if (!Captures.empty()) { 4312 SmallVector<Decl *, 16> PreInits; 4313 for (auto &Pair : Captures) 4314 PreInits.push_back(Pair.second->getDecl()); 4315 return buildPreInits(Context, PreInits); 4316 } 4317 return nullptr; 4318 } 4319 4320 /// Build postupdate expression for the given list of postupdates expressions. 4321 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 4322 Expr *PostUpdate = nullptr; 4323 if (!PostUpdates.empty()) { 4324 for (auto *E : PostUpdates) { 4325 Expr *ConvE = S.BuildCStyleCastExpr( 4326 E->getExprLoc(), 4327 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 4328 E->getExprLoc(), E) 4329 .get(); 4330 PostUpdate = PostUpdate 4331 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 4332 PostUpdate, ConvE) 4333 .get() 4334 : ConvE; 4335 } 4336 } 4337 return PostUpdate; 4338 } 4339 4340 /// \brief Called on a for stmt to check itself and nested loops (if any). 4341 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 4342 /// number of collapsed loops otherwise. 4343 static unsigned 4344 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 4345 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 4346 DSAStackTy &DSA, 4347 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 4348 OMPLoopDirective::HelperExprs &Built) { 4349 unsigned NestedLoopCount = 1; 4350 if (CollapseLoopCountExpr) { 4351 // Found 'collapse' clause - calculate collapse number. 4352 llvm::APSInt Result; 4353 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 4354 NestedLoopCount = Result.getLimitedValue(); 4355 } 4356 if (OrderedLoopCountExpr) { 4357 // Found 'ordered' clause - calculate collapse number. 4358 llvm::APSInt Result; 4359 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 4360 if (Result.getLimitedValue() < NestedLoopCount) { 4361 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4362 diag::err_omp_wrong_ordered_loop_count) 4363 << OrderedLoopCountExpr->getSourceRange(); 4364 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4365 diag::note_collapse_loop_count) 4366 << CollapseLoopCountExpr->getSourceRange(); 4367 } 4368 NestedLoopCount = Result.getLimitedValue(); 4369 } 4370 } 4371 // This is helper routine for loop directives (e.g., 'for', 'simd', 4372 // 'for simd', etc.). 4373 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 4374 SmallVector<LoopIterationSpace, 4> IterSpaces; 4375 IterSpaces.resize(NestedLoopCount); 4376 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 4377 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 4378 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, 4379 NestedLoopCount, CollapseLoopCountExpr, 4380 OrderedLoopCountExpr, VarsWithImplicitDSA, 4381 IterSpaces[Cnt], Captures)) 4382 return 0; 4383 // Move on to the next nested for loop, or to the loop body. 4384 // OpenMP [2.8.1, simd construct, Restrictions] 4385 // All loops associated with the construct must be perfectly nested; that 4386 // is, there must be no intervening code nor any OpenMP directive between 4387 // any two loops. 4388 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 4389 } 4390 4391 Built.clear(/* size */ NestedLoopCount); 4392 4393 if (SemaRef.CurContext->isDependentContext()) 4394 return NestedLoopCount; 4395 4396 // An example of what is generated for the following code: 4397 // 4398 // #pragma omp simd collapse(2) ordered(2) 4399 // for (i = 0; i < NI; ++i) 4400 // for (k = 0; k < NK; ++k) 4401 // for (j = J0; j < NJ; j+=2) { 4402 // <loop body> 4403 // } 4404 // 4405 // We generate the code below. 4406 // Note: the loop body may be outlined in CodeGen. 4407 // Note: some counters may be C++ classes, operator- is used to find number of 4408 // iterations and operator+= to calculate counter value. 4409 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 4410 // or i64 is currently supported). 4411 // 4412 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 4413 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 4414 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 4415 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 4416 // // similar updates for vars in clauses (e.g. 'linear') 4417 // <loop body (using local i and j)> 4418 // } 4419 // i = NI; // assign final values of counters 4420 // j = NJ; 4421 // 4422 4423 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 4424 // the iteration counts of the collapsed for loops. 4425 // Precondition tests if there is at least one iteration (all conditions are 4426 // true). 4427 auto PreCond = ExprResult(IterSpaces[0].PreCond); 4428 auto N0 = IterSpaces[0].NumIterations; 4429 ExprResult LastIteration32 = WidenIterationCount( 4430 32 /* Bits */, SemaRef 4431 .PerformImplicitConversion( 4432 N0->IgnoreImpCasts(), N0->getType(), 4433 Sema::AA_Converting, /*AllowExplicit=*/true) 4434 .get(), 4435 SemaRef); 4436 ExprResult LastIteration64 = WidenIterationCount( 4437 64 /* Bits */, SemaRef 4438 .PerformImplicitConversion( 4439 N0->IgnoreImpCasts(), N0->getType(), 4440 Sema::AA_Converting, /*AllowExplicit=*/true) 4441 .get(), 4442 SemaRef); 4443 4444 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 4445 return NestedLoopCount; 4446 4447 auto &C = SemaRef.Context; 4448 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 4449 4450 Scope *CurScope = DSA.getCurScope(); 4451 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 4452 if (PreCond.isUsable()) { 4453 PreCond = 4454 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 4455 PreCond.get(), IterSpaces[Cnt].PreCond); 4456 } 4457 auto N = IterSpaces[Cnt].NumIterations; 4458 SourceLocation Loc = N->getExprLoc(); 4459 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 4460 if (LastIteration32.isUsable()) 4461 LastIteration32 = SemaRef.BuildBinOp( 4462 CurScope, Loc, BO_Mul, LastIteration32.get(), 4463 SemaRef 4464 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4465 Sema::AA_Converting, 4466 /*AllowExplicit=*/true) 4467 .get()); 4468 if (LastIteration64.isUsable()) 4469 LastIteration64 = SemaRef.BuildBinOp( 4470 CurScope, Loc, BO_Mul, LastIteration64.get(), 4471 SemaRef 4472 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4473 Sema::AA_Converting, 4474 /*AllowExplicit=*/true) 4475 .get()); 4476 } 4477 4478 // Choose either the 32-bit or 64-bit version. 4479 ExprResult LastIteration = LastIteration64; 4480 if (LastIteration32.isUsable() && 4481 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 4482 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 4483 FitsInto( 4484 32 /* Bits */, 4485 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 4486 LastIteration64.get(), SemaRef))) 4487 LastIteration = LastIteration32; 4488 QualType VType = LastIteration.get()->getType(); 4489 QualType RealVType = VType; 4490 QualType StrideVType = VType; 4491 if (isOpenMPTaskLoopDirective(DKind)) { 4492 VType = 4493 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 4494 StrideVType = 4495 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 4496 } 4497 4498 if (!LastIteration.isUsable()) 4499 return 0; 4500 4501 // Save the number of iterations. 4502 ExprResult NumIterations = LastIteration; 4503 { 4504 LastIteration = SemaRef.BuildBinOp( 4505 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 4506 LastIteration.get(), 4507 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4508 if (!LastIteration.isUsable()) 4509 return 0; 4510 } 4511 4512 // Calculate the last iteration number beforehand instead of doing this on 4513 // each iteration. Do not do this if the number of iterations may be kfold-ed. 4514 llvm::APSInt Result; 4515 bool IsConstant = 4516 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 4517 ExprResult CalcLastIteration; 4518 if (!IsConstant) { 4519 ExprResult SaveRef = 4520 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 4521 LastIteration = SaveRef; 4522 4523 // Prepare SaveRef + 1. 4524 NumIterations = SemaRef.BuildBinOp( 4525 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 4526 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4527 if (!NumIterations.isUsable()) 4528 return 0; 4529 } 4530 4531 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 4532 4533 // Build variables passed into runtime, necessary for worksharing directives. 4534 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 4535 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4536 isOpenMPDistributeDirective(DKind)) { 4537 // Lower bound variable, initialized with zero. 4538 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 4539 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 4540 SemaRef.AddInitializerToDecl(LBDecl, 4541 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4542 /*DirectInit*/ false); 4543 4544 // Upper bound variable, initialized with last iteration number. 4545 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 4546 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 4547 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 4548 /*DirectInit*/ false); 4549 4550 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 4551 // This will be used to implement clause 'lastprivate'. 4552 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 4553 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 4554 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 4555 SemaRef.AddInitializerToDecl(ILDecl, 4556 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4557 /*DirectInit*/ false); 4558 4559 // Stride variable returned by runtime (we initialize it to 1 by default). 4560 VarDecl *STDecl = 4561 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 4562 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 4563 SemaRef.AddInitializerToDecl(STDecl, 4564 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 4565 /*DirectInit*/ false); 4566 4567 // Build expression: UB = min(UB, LastIteration) 4568 // It is necessary for CodeGen of directives with static scheduling. 4569 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 4570 UB.get(), LastIteration.get()); 4571 ExprResult CondOp = SemaRef.ActOnConditionalOp( 4572 InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get()); 4573 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 4574 CondOp.get()); 4575 EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); 4576 4577 // If we have a combined directive that combines 'distribute', 'for' or 4578 // 'simd' we need to be able to access the bounds of the schedule of the 4579 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 4580 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 4581 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4582 4583 // Lower bound variable, initialized with zero. 4584 VarDecl *CombLBDecl = 4585 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 4586 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 4587 SemaRef.AddInitializerToDecl( 4588 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4589 /*DirectInit*/ false); 4590 4591 // Upper bound variable, initialized with last iteration number. 4592 VarDecl *CombUBDecl = 4593 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 4594 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 4595 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 4596 /*DirectInit*/ false); 4597 4598 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 4599 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 4600 ExprResult CombCondOp = 4601 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 4602 LastIteration.get(), CombUB.get()); 4603 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 4604 CombCondOp.get()); 4605 CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get()); 4606 4607 auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 4608 // We expect to have at least 2 more parameters than the 'parallel' 4609 // directive does - the lower and upper bounds of the previous schedule. 4610 assert(CD->getNumParams() >= 4 && 4611 "Unexpected number of parameters in loop combined directive"); 4612 4613 // Set the proper type for the bounds given what we learned from the 4614 // enclosed loops. 4615 auto *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 4616 auto *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 4617 4618 // Previous lower and upper bounds are obtained from the region 4619 // parameters. 4620 PrevLB = 4621 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 4622 PrevUB = 4623 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 4624 } 4625 } 4626 4627 // Build the iteration variable and its initialization before loop. 4628 ExprResult IV; 4629 ExprResult Init, CombInit; 4630 { 4631 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 4632 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 4633 Expr *RHS = 4634 (isOpenMPWorksharingDirective(DKind) || 4635 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 4636 ? LB.get() 4637 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 4638 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 4639 Init = SemaRef.ActOnFinishFullExpr(Init.get()); 4640 4641 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4642 Expr *CombRHS = 4643 (isOpenMPWorksharingDirective(DKind) || 4644 isOpenMPTaskLoopDirective(DKind) || 4645 isOpenMPDistributeDirective(DKind)) 4646 ? CombLB.get() 4647 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 4648 CombInit = 4649 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 4650 CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get()); 4651 } 4652 } 4653 4654 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. 4655 SourceLocation CondLoc; 4656 ExprResult Cond = 4657 (isOpenMPWorksharingDirective(DKind) || 4658 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 4659 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) 4660 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 4661 NumIterations.get()); 4662 ExprResult CombCond; 4663 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4664 CombCond = 4665 SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get()); 4666 } 4667 // Loop increment (IV = IV + 1) 4668 SourceLocation IncLoc; 4669 ExprResult Inc = 4670 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 4671 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 4672 if (!Inc.isUsable()) 4673 return 0; 4674 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 4675 Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); 4676 if (!Inc.isUsable()) 4677 return 0; 4678 4679 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 4680 // Used for directives with static scheduling. 4681 // In combined construct, add combined version that use CombLB and CombUB 4682 // base variables for the update 4683 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 4684 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4685 isOpenMPDistributeDirective(DKind)) { 4686 // LB + ST 4687 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 4688 if (!NextLB.isUsable()) 4689 return 0; 4690 // LB = LB + ST 4691 NextLB = 4692 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 4693 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); 4694 if (!NextLB.isUsable()) 4695 return 0; 4696 // UB + ST 4697 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 4698 if (!NextUB.isUsable()) 4699 return 0; 4700 // UB = UB + ST 4701 NextUB = 4702 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 4703 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); 4704 if (!NextUB.isUsable()) 4705 return 0; 4706 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4707 CombNextLB = 4708 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 4709 if (!NextLB.isUsable()) 4710 return 0; 4711 // LB = LB + ST 4712 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 4713 CombNextLB.get()); 4714 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get()); 4715 if (!CombNextLB.isUsable()) 4716 return 0; 4717 // UB + ST 4718 CombNextUB = 4719 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 4720 if (!CombNextUB.isUsable()) 4721 return 0; 4722 // UB = UB + ST 4723 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 4724 CombNextUB.get()); 4725 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get()); 4726 if (!CombNextUB.isUsable()) 4727 return 0; 4728 } 4729 } 4730 4731 // Create increment expression for distribute loop when combined in a same 4732 // directive with for as IV = IV + ST; ensure upper bound expression based 4733 // on PrevUB instead of NumIterations - used to implement 'for' when found 4734 // in combination with 'distribute', like in 'distribute parallel for' 4735 SourceLocation DistIncLoc; 4736 ExprResult DistCond, DistInc, PrevEUB; 4737 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4738 DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()); 4739 assert(DistCond.isUsable() && "distribute cond expr was not built"); 4740 4741 DistInc = 4742 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 4743 assert(DistInc.isUsable() && "distribute inc expr was not built"); 4744 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 4745 DistInc.get()); 4746 DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get()); 4747 assert(DistInc.isUsable() && "distribute inc expr was not built"); 4748 4749 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 4750 // construct 4751 SourceLocation DistEUBLoc; 4752 ExprResult IsUBGreater = 4753 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 4754 ExprResult CondOp = SemaRef.ActOnConditionalOp( 4755 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 4756 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 4757 CondOp.get()); 4758 PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get()); 4759 } 4760 4761 // Build updates and final values of the loop counters. 4762 bool HasErrors = false; 4763 Built.Counters.resize(NestedLoopCount); 4764 Built.Inits.resize(NestedLoopCount); 4765 Built.Updates.resize(NestedLoopCount); 4766 Built.Finals.resize(NestedLoopCount); 4767 SmallVector<Expr *, 4> LoopMultipliers; 4768 { 4769 ExprResult Div; 4770 // Go from inner nested loop to outer. 4771 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 4772 LoopIterationSpace &IS = IterSpaces[Cnt]; 4773 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 4774 // Build: Iter = (IV / Div) % IS.NumIters 4775 // where Div is product of previous iterations' IS.NumIters. 4776 ExprResult Iter; 4777 if (Div.isUsable()) { 4778 Iter = 4779 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); 4780 } else { 4781 Iter = IV; 4782 assert((Cnt == (int)NestedLoopCount - 1) && 4783 "unusable div expected on first iteration only"); 4784 } 4785 4786 if (Cnt != 0 && Iter.isUsable()) 4787 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), 4788 IS.NumIterations); 4789 if (!Iter.isUsable()) { 4790 HasErrors = true; 4791 break; 4792 } 4793 4794 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 4795 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 4796 auto *CounterVar = buildDeclRefExpr(SemaRef, VD, IS.CounterVar->getType(), 4797 IS.CounterVar->getExprLoc(), 4798 /*RefersToCapture=*/true); 4799 ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 4800 IS.CounterInit, Captures); 4801 if (!Init.isUsable()) { 4802 HasErrors = true; 4803 break; 4804 } 4805 ExprResult Update = BuildCounterUpdate( 4806 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 4807 IS.CounterStep, IS.Subtract, &Captures); 4808 if (!Update.isUsable()) { 4809 HasErrors = true; 4810 break; 4811 } 4812 4813 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 4814 ExprResult Final = BuildCounterUpdate( 4815 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 4816 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 4817 if (!Final.isUsable()) { 4818 HasErrors = true; 4819 break; 4820 } 4821 4822 // Build Div for the next iteration: Div <- Div * IS.NumIters 4823 if (Cnt != 0) { 4824 if (Div.isUnset()) 4825 Div = IS.NumIterations; 4826 else 4827 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), 4828 IS.NumIterations); 4829 4830 // Add parentheses (for debugging purposes only). 4831 if (Div.isUsable()) 4832 Div = tryBuildCapture(SemaRef, Div.get(), Captures); 4833 if (!Div.isUsable()) { 4834 HasErrors = true; 4835 break; 4836 } 4837 LoopMultipliers.push_back(Div.get()); 4838 } 4839 if (!Update.isUsable() || !Final.isUsable()) { 4840 HasErrors = true; 4841 break; 4842 } 4843 // Save results 4844 Built.Counters[Cnt] = IS.CounterVar; 4845 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 4846 Built.Inits[Cnt] = Init.get(); 4847 Built.Updates[Cnt] = Update.get(); 4848 Built.Finals[Cnt] = Final.get(); 4849 } 4850 } 4851 4852 if (HasErrors) 4853 return 0; 4854 4855 // Save results 4856 Built.IterationVarRef = IV.get(); 4857 Built.LastIteration = LastIteration.get(); 4858 Built.NumIterations = NumIterations.get(); 4859 Built.CalcLastIteration = 4860 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); 4861 Built.PreCond = PreCond.get(); 4862 Built.PreInits = buildPreInits(C, Captures); 4863 Built.Cond = Cond.get(); 4864 Built.Init = Init.get(); 4865 Built.Inc = Inc.get(); 4866 Built.LB = LB.get(); 4867 Built.UB = UB.get(); 4868 Built.IL = IL.get(); 4869 Built.ST = ST.get(); 4870 Built.EUB = EUB.get(); 4871 Built.NLB = NextLB.get(); 4872 Built.NUB = NextUB.get(); 4873 Built.PrevLB = PrevLB.get(); 4874 Built.PrevUB = PrevUB.get(); 4875 Built.DistInc = DistInc.get(); 4876 Built.PrevEUB = PrevEUB.get(); 4877 Built.DistCombinedFields.LB = CombLB.get(); 4878 Built.DistCombinedFields.UB = CombUB.get(); 4879 Built.DistCombinedFields.EUB = CombEUB.get(); 4880 Built.DistCombinedFields.Init = CombInit.get(); 4881 Built.DistCombinedFields.Cond = CombCond.get(); 4882 Built.DistCombinedFields.NLB = CombNextLB.get(); 4883 Built.DistCombinedFields.NUB = CombNextUB.get(); 4884 4885 Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get(); 4886 // Fill data for doacross depend clauses. 4887 for (auto Pair : DSA.getDoacrossDependClauses()) { 4888 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 4889 Pair.first->setCounterValue(CounterVal); 4890 else { 4891 if (NestedLoopCount != Pair.second.size() || 4892 NestedLoopCount != LoopMultipliers.size() + 1) { 4893 // Erroneous case - clause has some problems. 4894 Pair.first->setCounterValue(CounterVal); 4895 continue; 4896 } 4897 assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink); 4898 auto I = Pair.second.rbegin(); 4899 auto IS = IterSpaces.rbegin(); 4900 auto ILM = LoopMultipliers.rbegin(); 4901 Expr *UpCounterVal = CounterVal; 4902 Expr *Multiplier = nullptr; 4903 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 4904 if (I->first) { 4905 assert(IS->CounterStep); 4906 Expr *NormalizedOffset = 4907 SemaRef 4908 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div, 4909 I->first, IS->CounterStep) 4910 .get(); 4911 if (Multiplier) { 4912 NormalizedOffset = 4913 SemaRef 4914 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul, 4915 NormalizedOffset, Multiplier) 4916 .get(); 4917 } 4918 assert(I->second == OO_Plus || I->second == OO_Minus); 4919 BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : BO_Sub; 4920 UpCounterVal = SemaRef 4921 .BuildBinOp(CurScope, I->first->getExprLoc(), BOK, 4922 UpCounterVal, NormalizedOffset) 4923 .get(); 4924 } 4925 Multiplier = *ILM; 4926 ++I; 4927 ++IS; 4928 ++ILM; 4929 } 4930 Pair.first->setCounterValue(UpCounterVal); 4931 } 4932 } 4933 4934 return NestedLoopCount; 4935 } 4936 4937 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 4938 auto CollapseClauses = 4939 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 4940 if (CollapseClauses.begin() != CollapseClauses.end()) 4941 return (*CollapseClauses.begin())->getNumForLoops(); 4942 return nullptr; 4943 } 4944 4945 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 4946 auto OrderedClauses = 4947 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 4948 if (OrderedClauses.begin() != OrderedClauses.end()) 4949 return (*OrderedClauses.begin())->getNumForLoops(); 4950 return nullptr; 4951 } 4952 4953 static bool checkSimdlenSafelenSpecified(Sema &S, 4954 const ArrayRef<OMPClause *> Clauses) { 4955 OMPSafelenClause *Safelen = nullptr; 4956 OMPSimdlenClause *Simdlen = nullptr; 4957 4958 for (auto *Clause : Clauses) { 4959 if (Clause->getClauseKind() == OMPC_safelen) 4960 Safelen = cast<OMPSafelenClause>(Clause); 4961 else if (Clause->getClauseKind() == OMPC_simdlen) 4962 Simdlen = cast<OMPSimdlenClause>(Clause); 4963 if (Safelen && Simdlen) 4964 break; 4965 } 4966 4967 if (Simdlen && Safelen) { 4968 llvm::APSInt SimdlenRes, SafelenRes; 4969 auto SimdlenLength = Simdlen->getSimdlen(); 4970 auto SafelenLength = Safelen->getSafelen(); 4971 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 4972 SimdlenLength->isInstantiationDependent() || 4973 SimdlenLength->containsUnexpandedParameterPack()) 4974 return false; 4975 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 4976 SafelenLength->isInstantiationDependent() || 4977 SafelenLength->containsUnexpandedParameterPack()) 4978 return false; 4979 SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context); 4980 SafelenLength->EvaluateAsInt(SafelenRes, S.Context); 4981 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 4982 // If both simdlen and safelen clauses are specified, the value of the 4983 // simdlen parameter must be less than or equal to the value of the safelen 4984 // parameter. 4985 if (SimdlenRes > SafelenRes) { 4986 S.Diag(SimdlenLength->getExprLoc(), 4987 diag::err_omp_wrong_simdlen_safelen_values) 4988 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 4989 return true; 4990 } 4991 } 4992 return false; 4993 } 4994 4995 StmtResult Sema::ActOnOpenMPSimdDirective( 4996 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4997 SourceLocation EndLoc, 4998 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4999 if (!AStmt) 5000 return StmtError(); 5001 5002 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5003 OMPLoopDirective::HelperExprs B; 5004 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5005 // define the nested loops number. 5006 unsigned NestedLoopCount = CheckOpenMPLoop( 5007 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5008 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5009 if (NestedLoopCount == 0) 5010 return StmtError(); 5011 5012 assert((CurContext->isDependentContext() || B.builtAll()) && 5013 "omp simd loop exprs were not built"); 5014 5015 if (!CurContext->isDependentContext()) { 5016 // Finalize the clauses that need pre-built expressions for CodeGen. 5017 for (auto C : Clauses) { 5018 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5019 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5020 B.NumIterations, *this, CurScope, 5021 DSAStack)) 5022 return StmtError(); 5023 } 5024 } 5025 5026 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5027 return StmtError(); 5028 5029 getCurFunction()->setHasBranchProtectedScope(); 5030 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5031 Clauses, AStmt, B); 5032 } 5033 5034 StmtResult Sema::ActOnOpenMPForDirective( 5035 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5036 SourceLocation EndLoc, 5037 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5038 if (!AStmt) 5039 return StmtError(); 5040 5041 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5042 OMPLoopDirective::HelperExprs B; 5043 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5044 // define the nested loops number. 5045 unsigned NestedLoopCount = CheckOpenMPLoop( 5046 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5047 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5048 if (NestedLoopCount == 0) 5049 return StmtError(); 5050 5051 assert((CurContext->isDependentContext() || B.builtAll()) && 5052 "omp for loop exprs were not built"); 5053 5054 if (!CurContext->isDependentContext()) { 5055 // Finalize the clauses that need pre-built expressions for CodeGen. 5056 for (auto C : Clauses) { 5057 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5058 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5059 B.NumIterations, *this, CurScope, 5060 DSAStack)) 5061 return StmtError(); 5062 } 5063 } 5064 5065 getCurFunction()->setHasBranchProtectedScope(); 5066 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5067 Clauses, AStmt, B, DSAStack->isCancelRegion()); 5068 } 5069 5070 StmtResult Sema::ActOnOpenMPForSimdDirective( 5071 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5072 SourceLocation EndLoc, 5073 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5074 if (!AStmt) 5075 return StmtError(); 5076 5077 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5078 OMPLoopDirective::HelperExprs B; 5079 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5080 // define the nested loops number. 5081 unsigned NestedLoopCount = 5082 CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 5083 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5084 VarsWithImplicitDSA, B); 5085 if (NestedLoopCount == 0) 5086 return StmtError(); 5087 5088 assert((CurContext->isDependentContext() || B.builtAll()) && 5089 "omp for simd loop exprs were not built"); 5090 5091 if (!CurContext->isDependentContext()) { 5092 // Finalize the clauses that need pre-built expressions for CodeGen. 5093 for (auto C : Clauses) { 5094 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5095 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5096 B.NumIterations, *this, CurScope, 5097 DSAStack)) 5098 return StmtError(); 5099 } 5100 } 5101 5102 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5103 return StmtError(); 5104 5105 getCurFunction()->setHasBranchProtectedScope(); 5106 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5107 Clauses, AStmt, B); 5108 } 5109 5110 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 5111 Stmt *AStmt, 5112 SourceLocation StartLoc, 5113 SourceLocation EndLoc) { 5114 if (!AStmt) 5115 return StmtError(); 5116 5117 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5118 auto BaseStmt = AStmt; 5119 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5120 BaseStmt = CS->getCapturedStmt(); 5121 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5122 auto S = C->children(); 5123 if (S.begin() == S.end()) 5124 return StmtError(); 5125 // All associated statements must be '#pragma omp section' except for 5126 // the first one. 5127 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5128 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5129 if (SectionStmt) 5130 Diag(SectionStmt->getLocStart(), 5131 diag::err_omp_sections_substmt_not_section); 5132 return StmtError(); 5133 } 5134 cast<OMPSectionDirective>(SectionStmt) 5135 ->setHasCancel(DSAStack->isCancelRegion()); 5136 } 5137 } else { 5138 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt); 5139 return StmtError(); 5140 } 5141 5142 getCurFunction()->setHasBranchProtectedScope(); 5143 5144 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5145 DSAStack->isCancelRegion()); 5146 } 5147 5148 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 5149 SourceLocation StartLoc, 5150 SourceLocation EndLoc) { 5151 if (!AStmt) 5152 return StmtError(); 5153 5154 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5155 5156 getCurFunction()->setHasBranchProtectedScope(); 5157 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 5158 5159 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 5160 DSAStack->isCancelRegion()); 5161 } 5162 5163 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 5164 Stmt *AStmt, 5165 SourceLocation StartLoc, 5166 SourceLocation EndLoc) { 5167 if (!AStmt) 5168 return StmtError(); 5169 5170 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5171 5172 getCurFunction()->setHasBranchProtectedScope(); 5173 5174 // OpenMP [2.7.3, single Construct, Restrictions] 5175 // The copyprivate clause must not be used with the nowait clause. 5176 OMPClause *Nowait = nullptr; 5177 OMPClause *Copyprivate = nullptr; 5178 for (auto *Clause : Clauses) { 5179 if (Clause->getClauseKind() == OMPC_nowait) 5180 Nowait = Clause; 5181 else if (Clause->getClauseKind() == OMPC_copyprivate) 5182 Copyprivate = Clause; 5183 if (Copyprivate && Nowait) { 5184 Diag(Copyprivate->getLocStart(), 5185 diag::err_omp_single_copyprivate_with_nowait); 5186 Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here); 5187 return StmtError(); 5188 } 5189 } 5190 5191 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5192 } 5193 5194 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 5195 SourceLocation StartLoc, 5196 SourceLocation EndLoc) { 5197 if (!AStmt) 5198 return StmtError(); 5199 5200 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5201 5202 getCurFunction()->setHasBranchProtectedScope(); 5203 5204 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 5205 } 5206 5207 StmtResult Sema::ActOnOpenMPCriticalDirective( 5208 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 5209 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5210 if (!AStmt) 5211 return StmtError(); 5212 5213 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5214 5215 bool ErrorFound = false; 5216 llvm::APSInt Hint; 5217 SourceLocation HintLoc; 5218 bool DependentHint = false; 5219 for (auto *C : Clauses) { 5220 if (C->getClauseKind() == OMPC_hint) { 5221 if (!DirName.getName()) { 5222 Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name); 5223 ErrorFound = true; 5224 } 5225 Expr *E = cast<OMPHintClause>(C)->getHint(); 5226 if (E->isTypeDependent() || E->isValueDependent() || 5227 E->isInstantiationDependent()) 5228 DependentHint = true; 5229 else { 5230 Hint = E->EvaluateKnownConstInt(Context); 5231 HintLoc = C->getLocStart(); 5232 } 5233 } 5234 } 5235 if (ErrorFound) 5236 return StmtError(); 5237 auto Pair = DSAStack->getCriticalWithHint(DirName); 5238 if (Pair.first && DirName.getName() && !DependentHint) { 5239 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 5240 Diag(StartLoc, diag::err_omp_critical_with_hint); 5241 if (HintLoc.isValid()) { 5242 Diag(HintLoc, diag::note_omp_critical_hint_here) 5243 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 5244 } else 5245 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 5246 if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 5247 Diag(C->getLocStart(), diag::note_omp_critical_hint_here) 5248 << 1 5249 << C->getHint()->EvaluateKnownConstInt(Context).toString( 5250 /*Radix=*/10, /*Signed=*/false); 5251 } else 5252 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1; 5253 } 5254 } 5255 5256 getCurFunction()->setHasBranchProtectedScope(); 5257 5258 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 5259 Clauses, AStmt); 5260 if (!Pair.first && DirName.getName() && !DependentHint) 5261 DSAStack->addCriticalWithHint(Dir, Hint); 5262 return Dir; 5263 } 5264 5265 StmtResult Sema::ActOnOpenMPParallelForDirective( 5266 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5267 SourceLocation EndLoc, 5268 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5269 if (!AStmt) 5270 return StmtError(); 5271 5272 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5273 // 1.2.2 OpenMP Language Terminology 5274 // Structured block - An executable statement with a single entry at the 5275 // top and a single exit at the bottom. 5276 // The point of exit cannot be a branch out of the structured block. 5277 // longjmp() and throw() must not violate the entry/exit criteria. 5278 CS->getCapturedDecl()->setNothrow(); 5279 5280 OMPLoopDirective::HelperExprs B; 5281 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5282 // define the nested loops number. 5283 unsigned NestedLoopCount = 5284 CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 5285 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5286 VarsWithImplicitDSA, B); 5287 if (NestedLoopCount == 0) 5288 return StmtError(); 5289 5290 assert((CurContext->isDependentContext() || B.builtAll()) && 5291 "omp parallel for loop exprs were not built"); 5292 5293 if (!CurContext->isDependentContext()) { 5294 // Finalize the clauses that need pre-built expressions for CodeGen. 5295 for (auto C : Clauses) { 5296 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5297 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5298 B.NumIterations, *this, CurScope, 5299 DSAStack)) 5300 return StmtError(); 5301 } 5302 } 5303 5304 getCurFunction()->setHasBranchProtectedScope(); 5305 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 5306 NestedLoopCount, Clauses, AStmt, B, 5307 DSAStack->isCancelRegion()); 5308 } 5309 5310 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 5311 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5312 SourceLocation EndLoc, 5313 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5314 if (!AStmt) 5315 return StmtError(); 5316 5317 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5318 // 1.2.2 OpenMP Language Terminology 5319 // Structured block - An executable statement with a single entry at the 5320 // top and a single exit at the bottom. 5321 // The point of exit cannot be a branch out of the structured block. 5322 // longjmp() and throw() must not violate the entry/exit criteria. 5323 CS->getCapturedDecl()->setNothrow(); 5324 5325 OMPLoopDirective::HelperExprs B; 5326 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5327 // define the nested loops number. 5328 unsigned NestedLoopCount = 5329 CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 5330 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5331 VarsWithImplicitDSA, B); 5332 if (NestedLoopCount == 0) 5333 return StmtError(); 5334 5335 if (!CurContext->isDependentContext()) { 5336 // Finalize the clauses that need pre-built expressions for CodeGen. 5337 for (auto C : Clauses) { 5338 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5339 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5340 B.NumIterations, *this, CurScope, 5341 DSAStack)) 5342 return StmtError(); 5343 } 5344 } 5345 5346 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5347 return StmtError(); 5348 5349 getCurFunction()->setHasBranchProtectedScope(); 5350 return OMPParallelForSimdDirective::Create( 5351 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 5352 } 5353 5354 StmtResult 5355 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 5356 Stmt *AStmt, SourceLocation StartLoc, 5357 SourceLocation EndLoc) { 5358 if (!AStmt) 5359 return StmtError(); 5360 5361 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5362 auto BaseStmt = AStmt; 5363 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5364 BaseStmt = CS->getCapturedStmt(); 5365 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5366 auto S = C->children(); 5367 if (S.begin() == S.end()) 5368 return StmtError(); 5369 // All associated statements must be '#pragma omp section' except for 5370 // the first one. 5371 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5372 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5373 if (SectionStmt) 5374 Diag(SectionStmt->getLocStart(), 5375 diag::err_omp_parallel_sections_substmt_not_section); 5376 return StmtError(); 5377 } 5378 cast<OMPSectionDirective>(SectionStmt) 5379 ->setHasCancel(DSAStack->isCancelRegion()); 5380 } 5381 } else { 5382 Diag(AStmt->getLocStart(), 5383 diag::err_omp_parallel_sections_not_compound_stmt); 5384 return StmtError(); 5385 } 5386 5387 getCurFunction()->setHasBranchProtectedScope(); 5388 5389 return OMPParallelSectionsDirective::Create( 5390 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 5391 } 5392 5393 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 5394 Stmt *AStmt, SourceLocation StartLoc, 5395 SourceLocation EndLoc) { 5396 if (!AStmt) 5397 return StmtError(); 5398 5399 auto *CS = cast<CapturedStmt>(AStmt); 5400 // 1.2.2 OpenMP Language Terminology 5401 // Structured block - An executable statement with a single entry at the 5402 // top and a single exit at the bottom. 5403 // The point of exit cannot be a branch out of the structured block. 5404 // longjmp() and throw() must not violate the entry/exit criteria. 5405 CS->getCapturedDecl()->setNothrow(); 5406 5407 getCurFunction()->setHasBranchProtectedScope(); 5408 5409 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5410 DSAStack->isCancelRegion()); 5411 } 5412 5413 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 5414 SourceLocation EndLoc) { 5415 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 5416 } 5417 5418 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 5419 SourceLocation EndLoc) { 5420 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 5421 } 5422 5423 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 5424 SourceLocation EndLoc) { 5425 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 5426 } 5427 5428 StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses, 5429 Stmt *AStmt, 5430 SourceLocation StartLoc, 5431 SourceLocation EndLoc) { 5432 if (!AStmt) 5433 return StmtError(); 5434 5435 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5436 5437 getCurFunction()->setHasBranchProtectedScope(); 5438 5439 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses, 5440 AStmt, 5441 DSAStack->getTaskgroupReductionRef()); 5442 } 5443 5444 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 5445 SourceLocation StartLoc, 5446 SourceLocation EndLoc) { 5447 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 5448 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 5449 } 5450 5451 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 5452 Stmt *AStmt, 5453 SourceLocation StartLoc, 5454 SourceLocation EndLoc) { 5455 OMPClause *DependFound = nullptr; 5456 OMPClause *DependSourceClause = nullptr; 5457 OMPClause *DependSinkClause = nullptr; 5458 bool ErrorFound = false; 5459 OMPThreadsClause *TC = nullptr; 5460 OMPSIMDClause *SC = nullptr; 5461 for (auto *C : Clauses) { 5462 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 5463 DependFound = C; 5464 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 5465 if (DependSourceClause) { 5466 Diag(C->getLocStart(), diag::err_omp_more_one_clause) 5467 << getOpenMPDirectiveName(OMPD_ordered) 5468 << getOpenMPClauseName(OMPC_depend) << 2; 5469 ErrorFound = true; 5470 } else 5471 DependSourceClause = C; 5472 if (DependSinkClause) { 5473 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5474 << 0; 5475 ErrorFound = true; 5476 } 5477 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 5478 if (DependSourceClause) { 5479 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5480 << 1; 5481 ErrorFound = true; 5482 } 5483 DependSinkClause = C; 5484 } 5485 } else if (C->getClauseKind() == OMPC_threads) 5486 TC = cast<OMPThreadsClause>(C); 5487 else if (C->getClauseKind() == OMPC_simd) 5488 SC = cast<OMPSIMDClause>(C); 5489 } 5490 if (!ErrorFound && !SC && 5491 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 5492 // OpenMP [2.8.1,simd Construct, Restrictions] 5493 // An ordered construct with the simd clause is the only OpenMP construct 5494 // that can appear in the simd region. 5495 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 5496 ErrorFound = true; 5497 } else if (DependFound && (TC || SC)) { 5498 Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd) 5499 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 5500 ErrorFound = true; 5501 } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) { 5502 Diag(DependFound->getLocStart(), 5503 diag::err_omp_ordered_directive_without_param); 5504 ErrorFound = true; 5505 } else if (TC || Clauses.empty()) { 5506 if (auto *Param = DSAStack->getParentOrderedRegionParam()) { 5507 SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc; 5508 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 5509 << (TC != nullptr); 5510 Diag(Param->getLocStart(), diag::note_omp_ordered_param); 5511 ErrorFound = true; 5512 } 5513 } 5514 if ((!AStmt && !DependFound) || ErrorFound) 5515 return StmtError(); 5516 5517 if (AStmt) { 5518 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5519 5520 getCurFunction()->setHasBranchProtectedScope(); 5521 } 5522 5523 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5524 } 5525 5526 namespace { 5527 /// \brief Helper class for checking expression in 'omp atomic [update]' 5528 /// construct. 5529 class OpenMPAtomicUpdateChecker { 5530 /// \brief Error results for atomic update expressions. 5531 enum ExprAnalysisErrorCode { 5532 /// \brief A statement is not an expression statement. 5533 NotAnExpression, 5534 /// \brief Expression is not builtin binary or unary operation. 5535 NotABinaryOrUnaryExpression, 5536 /// \brief Unary operation is not post-/pre- increment/decrement operation. 5537 NotAnUnaryIncDecExpression, 5538 /// \brief An expression is not of scalar type. 5539 NotAScalarType, 5540 /// \brief A binary operation is not an assignment operation. 5541 NotAnAssignmentOp, 5542 /// \brief RHS part of the binary operation is not a binary expression. 5543 NotABinaryExpression, 5544 /// \brief RHS part is not additive/multiplicative/shift/biwise binary 5545 /// expression. 5546 NotABinaryOperator, 5547 /// \brief RHS binary operation does not have reference to the updated LHS 5548 /// part. 5549 NotAnUpdateExpression, 5550 /// \brief No errors is found. 5551 NoError 5552 }; 5553 /// \brief Reference to Sema. 5554 Sema &SemaRef; 5555 /// \brief A location for note diagnostics (when error is found). 5556 SourceLocation NoteLoc; 5557 /// \brief 'x' lvalue part of the source atomic expression. 5558 Expr *X; 5559 /// \brief 'expr' rvalue part of the source atomic expression. 5560 Expr *E; 5561 /// \brief Helper expression of the form 5562 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5563 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5564 Expr *UpdateExpr; 5565 /// \brief Is 'x' a LHS in a RHS part of full update expression. It is 5566 /// important for non-associative operations. 5567 bool IsXLHSInRHSPart; 5568 BinaryOperatorKind Op; 5569 SourceLocation OpLoc; 5570 /// \brief true if the source expression is a postfix unary operation, false 5571 /// if it is a prefix unary operation. 5572 bool IsPostfixUpdate; 5573 5574 public: 5575 OpenMPAtomicUpdateChecker(Sema &SemaRef) 5576 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 5577 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 5578 /// \brief Check specified statement that it is suitable for 'atomic update' 5579 /// constructs and extract 'x', 'expr' and Operation from the original 5580 /// expression. If DiagId and NoteId == 0, then only check is performed 5581 /// without error notification. 5582 /// \param DiagId Diagnostic which should be emitted if error is found. 5583 /// \param NoteId Diagnostic note for the main error message. 5584 /// \return true if statement is not an update expression, false otherwise. 5585 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 5586 /// \brief Return the 'x' lvalue part of the source atomic expression. 5587 Expr *getX() const { return X; } 5588 /// \brief Return the 'expr' rvalue part of the source atomic expression. 5589 Expr *getExpr() const { return E; } 5590 /// \brief Return the update expression used in calculation of the updated 5591 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5592 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5593 Expr *getUpdateExpr() const { return UpdateExpr; } 5594 /// \brief Return true if 'x' is LHS in RHS part of full update expression, 5595 /// false otherwise. 5596 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 5597 5598 /// \brief true if the source expression is a postfix unary operation, false 5599 /// if it is a prefix unary operation. 5600 bool isPostfixUpdate() const { return IsPostfixUpdate; } 5601 5602 private: 5603 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 5604 unsigned NoteId = 0); 5605 }; 5606 } // namespace 5607 5608 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 5609 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 5610 ExprAnalysisErrorCode ErrorFound = NoError; 5611 SourceLocation ErrorLoc, NoteLoc; 5612 SourceRange ErrorRange, NoteRange; 5613 // Allowed constructs are: 5614 // x = x binop expr; 5615 // x = expr binop x; 5616 if (AtomicBinOp->getOpcode() == BO_Assign) { 5617 X = AtomicBinOp->getLHS(); 5618 if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 5619 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 5620 if (AtomicInnerBinOp->isMultiplicativeOp() || 5621 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 5622 AtomicInnerBinOp->isBitwiseOp()) { 5623 Op = AtomicInnerBinOp->getOpcode(); 5624 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 5625 auto *LHS = AtomicInnerBinOp->getLHS(); 5626 auto *RHS = AtomicInnerBinOp->getRHS(); 5627 llvm::FoldingSetNodeID XId, LHSId, RHSId; 5628 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 5629 /*Canonical=*/true); 5630 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 5631 /*Canonical=*/true); 5632 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 5633 /*Canonical=*/true); 5634 if (XId == LHSId) { 5635 E = RHS; 5636 IsXLHSInRHSPart = true; 5637 } else if (XId == RHSId) { 5638 E = LHS; 5639 IsXLHSInRHSPart = false; 5640 } else { 5641 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5642 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5643 NoteLoc = X->getExprLoc(); 5644 NoteRange = X->getSourceRange(); 5645 ErrorFound = NotAnUpdateExpression; 5646 } 5647 } else { 5648 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5649 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5650 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 5651 NoteRange = SourceRange(NoteLoc, NoteLoc); 5652 ErrorFound = NotABinaryOperator; 5653 } 5654 } else { 5655 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 5656 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 5657 ErrorFound = NotABinaryExpression; 5658 } 5659 } else { 5660 ErrorLoc = AtomicBinOp->getExprLoc(); 5661 ErrorRange = AtomicBinOp->getSourceRange(); 5662 NoteLoc = AtomicBinOp->getOperatorLoc(); 5663 NoteRange = SourceRange(NoteLoc, NoteLoc); 5664 ErrorFound = NotAnAssignmentOp; 5665 } 5666 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5667 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5668 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5669 return true; 5670 } else if (SemaRef.CurContext->isDependentContext()) 5671 E = X = UpdateExpr = nullptr; 5672 return ErrorFound != NoError; 5673 } 5674 5675 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 5676 unsigned NoteId) { 5677 ExprAnalysisErrorCode ErrorFound = NoError; 5678 SourceLocation ErrorLoc, NoteLoc; 5679 SourceRange ErrorRange, NoteRange; 5680 // Allowed constructs are: 5681 // x++; 5682 // x--; 5683 // ++x; 5684 // --x; 5685 // x binop= expr; 5686 // x = x binop expr; 5687 // x = expr binop x; 5688 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 5689 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 5690 if (AtomicBody->getType()->isScalarType() || 5691 AtomicBody->isInstantiationDependent()) { 5692 if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 5693 AtomicBody->IgnoreParenImpCasts())) { 5694 // Check for Compound Assignment Operation 5695 Op = BinaryOperator::getOpForCompoundAssignment( 5696 AtomicCompAssignOp->getOpcode()); 5697 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 5698 E = AtomicCompAssignOp->getRHS(); 5699 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 5700 IsXLHSInRHSPart = true; 5701 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 5702 AtomicBody->IgnoreParenImpCasts())) { 5703 // Check for Binary Operation 5704 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 5705 return true; 5706 } else if (auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 5707 AtomicBody->IgnoreParenImpCasts())) { 5708 // Check for Unary Operation 5709 if (AtomicUnaryOp->isIncrementDecrementOp()) { 5710 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 5711 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 5712 OpLoc = AtomicUnaryOp->getOperatorLoc(); 5713 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 5714 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 5715 IsXLHSInRHSPart = true; 5716 } else { 5717 ErrorFound = NotAnUnaryIncDecExpression; 5718 ErrorLoc = AtomicUnaryOp->getExprLoc(); 5719 ErrorRange = AtomicUnaryOp->getSourceRange(); 5720 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 5721 NoteRange = SourceRange(NoteLoc, NoteLoc); 5722 } 5723 } else if (!AtomicBody->isInstantiationDependent()) { 5724 ErrorFound = NotABinaryOrUnaryExpression; 5725 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 5726 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 5727 } 5728 } else { 5729 ErrorFound = NotAScalarType; 5730 NoteLoc = ErrorLoc = AtomicBody->getLocStart(); 5731 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5732 } 5733 } else { 5734 ErrorFound = NotAnExpression; 5735 NoteLoc = ErrorLoc = S->getLocStart(); 5736 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5737 } 5738 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5739 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5740 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5741 return true; 5742 } else if (SemaRef.CurContext->isDependentContext()) 5743 E = X = UpdateExpr = nullptr; 5744 if (ErrorFound == NoError && E && X) { 5745 // Build an update expression of form 'OpaqueValueExpr(x) binop 5746 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 5747 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 5748 auto *OVEX = new (SemaRef.getASTContext()) 5749 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 5750 auto *OVEExpr = new (SemaRef.getASTContext()) 5751 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 5752 auto Update = 5753 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 5754 IsXLHSInRHSPart ? OVEExpr : OVEX); 5755 if (Update.isInvalid()) 5756 return true; 5757 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 5758 Sema::AA_Casting); 5759 if (Update.isInvalid()) 5760 return true; 5761 UpdateExpr = Update.get(); 5762 } 5763 return ErrorFound != NoError; 5764 } 5765 5766 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 5767 Stmt *AStmt, 5768 SourceLocation StartLoc, 5769 SourceLocation EndLoc) { 5770 if (!AStmt) 5771 return StmtError(); 5772 5773 auto *CS = cast<CapturedStmt>(AStmt); 5774 // 1.2.2 OpenMP Language Terminology 5775 // Structured block - An executable statement with a single entry at the 5776 // top and a single exit at the bottom. 5777 // The point of exit cannot be a branch out of the structured block. 5778 // longjmp() and throw() must not violate the entry/exit criteria. 5779 OpenMPClauseKind AtomicKind = OMPC_unknown; 5780 SourceLocation AtomicKindLoc; 5781 for (auto *C : Clauses) { 5782 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 5783 C->getClauseKind() == OMPC_update || 5784 C->getClauseKind() == OMPC_capture) { 5785 if (AtomicKind != OMPC_unknown) { 5786 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) 5787 << SourceRange(C->getLocStart(), C->getLocEnd()); 5788 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 5789 << getOpenMPClauseName(AtomicKind); 5790 } else { 5791 AtomicKind = C->getClauseKind(); 5792 AtomicKindLoc = C->getLocStart(); 5793 } 5794 } 5795 } 5796 5797 auto Body = CS->getCapturedStmt(); 5798 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 5799 Body = EWC->getSubExpr(); 5800 5801 Expr *X = nullptr; 5802 Expr *V = nullptr; 5803 Expr *E = nullptr; 5804 Expr *UE = nullptr; 5805 bool IsXLHSInRHSPart = false; 5806 bool IsPostfixUpdate = false; 5807 // OpenMP [2.12.6, atomic Construct] 5808 // In the next expressions: 5809 // * x and v (as applicable) are both l-value expressions with scalar type. 5810 // * During the execution of an atomic region, multiple syntactic 5811 // occurrences of x must designate the same storage location. 5812 // * Neither of v and expr (as applicable) may access the storage location 5813 // designated by x. 5814 // * Neither of x and expr (as applicable) may access the storage location 5815 // designated by v. 5816 // * expr is an expression with scalar type. 5817 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 5818 // * binop, binop=, ++, and -- are not overloaded operators. 5819 // * The expression x binop expr must be numerically equivalent to x binop 5820 // (expr). This requirement is satisfied if the operators in expr have 5821 // precedence greater than binop, or by using parentheses around expr or 5822 // subexpressions of expr. 5823 // * The expression expr binop x must be numerically equivalent to (expr) 5824 // binop x. This requirement is satisfied if the operators in expr have 5825 // precedence equal to or greater than binop, or by using parentheses around 5826 // expr or subexpressions of expr. 5827 // * For forms that allow multiple occurrences of x, the number of times 5828 // that x is evaluated is unspecified. 5829 if (AtomicKind == OMPC_read) { 5830 enum { 5831 NotAnExpression, 5832 NotAnAssignmentOp, 5833 NotAScalarType, 5834 NotAnLValue, 5835 NoError 5836 } ErrorFound = NoError; 5837 SourceLocation ErrorLoc, NoteLoc; 5838 SourceRange ErrorRange, NoteRange; 5839 // If clause is read: 5840 // v = x; 5841 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 5842 auto *AtomicBinOp = 5843 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5844 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5845 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 5846 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 5847 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 5848 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 5849 if (!X->isLValue() || !V->isLValue()) { 5850 auto NotLValueExpr = X->isLValue() ? V : X; 5851 ErrorFound = NotAnLValue; 5852 ErrorLoc = AtomicBinOp->getExprLoc(); 5853 ErrorRange = AtomicBinOp->getSourceRange(); 5854 NoteLoc = NotLValueExpr->getExprLoc(); 5855 NoteRange = NotLValueExpr->getSourceRange(); 5856 } 5857 } else if (!X->isInstantiationDependent() || 5858 !V->isInstantiationDependent()) { 5859 auto NotScalarExpr = 5860 (X->isInstantiationDependent() || X->getType()->isScalarType()) 5861 ? V 5862 : X; 5863 ErrorFound = NotAScalarType; 5864 ErrorLoc = AtomicBinOp->getExprLoc(); 5865 ErrorRange = AtomicBinOp->getSourceRange(); 5866 NoteLoc = NotScalarExpr->getExprLoc(); 5867 NoteRange = NotScalarExpr->getSourceRange(); 5868 } 5869 } else if (!AtomicBody->isInstantiationDependent()) { 5870 ErrorFound = NotAnAssignmentOp; 5871 ErrorLoc = AtomicBody->getExprLoc(); 5872 ErrorRange = AtomicBody->getSourceRange(); 5873 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5874 : AtomicBody->getExprLoc(); 5875 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5876 : AtomicBody->getSourceRange(); 5877 } 5878 } else { 5879 ErrorFound = NotAnExpression; 5880 NoteLoc = ErrorLoc = Body->getLocStart(); 5881 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5882 } 5883 if (ErrorFound != NoError) { 5884 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 5885 << ErrorRange; 5886 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 5887 << NoteRange; 5888 return StmtError(); 5889 } else if (CurContext->isDependentContext()) 5890 V = X = nullptr; 5891 } else if (AtomicKind == OMPC_write) { 5892 enum { 5893 NotAnExpression, 5894 NotAnAssignmentOp, 5895 NotAScalarType, 5896 NotAnLValue, 5897 NoError 5898 } ErrorFound = NoError; 5899 SourceLocation ErrorLoc, NoteLoc; 5900 SourceRange ErrorRange, NoteRange; 5901 // If clause is write: 5902 // x = expr; 5903 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 5904 auto *AtomicBinOp = 5905 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5906 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5907 X = AtomicBinOp->getLHS(); 5908 E = AtomicBinOp->getRHS(); 5909 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 5910 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 5911 if (!X->isLValue()) { 5912 ErrorFound = NotAnLValue; 5913 ErrorLoc = AtomicBinOp->getExprLoc(); 5914 ErrorRange = AtomicBinOp->getSourceRange(); 5915 NoteLoc = X->getExprLoc(); 5916 NoteRange = X->getSourceRange(); 5917 } 5918 } else if (!X->isInstantiationDependent() || 5919 !E->isInstantiationDependent()) { 5920 auto NotScalarExpr = 5921 (X->isInstantiationDependent() || X->getType()->isScalarType()) 5922 ? E 5923 : X; 5924 ErrorFound = NotAScalarType; 5925 ErrorLoc = AtomicBinOp->getExprLoc(); 5926 ErrorRange = AtomicBinOp->getSourceRange(); 5927 NoteLoc = NotScalarExpr->getExprLoc(); 5928 NoteRange = NotScalarExpr->getSourceRange(); 5929 } 5930 } else if (!AtomicBody->isInstantiationDependent()) { 5931 ErrorFound = NotAnAssignmentOp; 5932 ErrorLoc = AtomicBody->getExprLoc(); 5933 ErrorRange = AtomicBody->getSourceRange(); 5934 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5935 : AtomicBody->getExprLoc(); 5936 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5937 : AtomicBody->getSourceRange(); 5938 } 5939 } else { 5940 ErrorFound = NotAnExpression; 5941 NoteLoc = ErrorLoc = Body->getLocStart(); 5942 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5943 } 5944 if (ErrorFound != NoError) { 5945 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 5946 << ErrorRange; 5947 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 5948 << NoteRange; 5949 return StmtError(); 5950 } else if (CurContext->isDependentContext()) 5951 E = X = nullptr; 5952 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 5953 // If clause is update: 5954 // x++; 5955 // x--; 5956 // ++x; 5957 // --x; 5958 // x binop= expr; 5959 // x = x binop expr; 5960 // x = expr binop x; 5961 OpenMPAtomicUpdateChecker Checker(*this); 5962 if (Checker.checkStatement( 5963 Body, (AtomicKind == OMPC_update) 5964 ? diag::err_omp_atomic_update_not_expression_statement 5965 : diag::err_omp_atomic_not_expression_statement, 5966 diag::note_omp_atomic_update)) 5967 return StmtError(); 5968 if (!CurContext->isDependentContext()) { 5969 E = Checker.getExpr(); 5970 X = Checker.getX(); 5971 UE = Checker.getUpdateExpr(); 5972 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5973 } 5974 } else if (AtomicKind == OMPC_capture) { 5975 enum { 5976 NotAnAssignmentOp, 5977 NotACompoundStatement, 5978 NotTwoSubstatements, 5979 NotASpecificExpression, 5980 NoError 5981 } ErrorFound = NoError; 5982 SourceLocation ErrorLoc, NoteLoc; 5983 SourceRange ErrorRange, NoteRange; 5984 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 5985 // If clause is a capture: 5986 // v = x++; 5987 // v = x--; 5988 // v = ++x; 5989 // v = --x; 5990 // v = x binop= expr; 5991 // v = x = x binop expr; 5992 // v = x = expr binop x; 5993 auto *AtomicBinOp = 5994 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5995 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5996 V = AtomicBinOp->getLHS(); 5997 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 5998 OpenMPAtomicUpdateChecker Checker(*this); 5999 if (Checker.checkStatement( 6000 Body, diag::err_omp_atomic_capture_not_expression_statement, 6001 diag::note_omp_atomic_update)) 6002 return StmtError(); 6003 E = Checker.getExpr(); 6004 X = Checker.getX(); 6005 UE = Checker.getUpdateExpr(); 6006 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6007 IsPostfixUpdate = Checker.isPostfixUpdate(); 6008 } else if (!AtomicBody->isInstantiationDependent()) { 6009 ErrorLoc = AtomicBody->getExprLoc(); 6010 ErrorRange = AtomicBody->getSourceRange(); 6011 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6012 : AtomicBody->getExprLoc(); 6013 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6014 : AtomicBody->getSourceRange(); 6015 ErrorFound = NotAnAssignmentOp; 6016 } 6017 if (ErrorFound != NoError) { 6018 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 6019 << ErrorRange; 6020 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6021 return StmtError(); 6022 } else if (CurContext->isDependentContext()) { 6023 UE = V = E = X = nullptr; 6024 } 6025 } else { 6026 // If clause is a capture: 6027 // { v = x; x = expr; } 6028 // { v = x; x++; } 6029 // { v = x; x--; } 6030 // { v = x; ++x; } 6031 // { v = x; --x; } 6032 // { v = x; x binop= expr; } 6033 // { v = x; x = x binop expr; } 6034 // { v = x; x = expr binop x; } 6035 // { x++; v = x; } 6036 // { x--; v = x; } 6037 // { ++x; v = x; } 6038 // { --x; v = x; } 6039 // { x binop= expr; v = x; } 6040 // { x = x binop expr; v = x; } 6041 // { x = expr binop x; v = x; } 6042 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 6043 // Check that this is { expr1; expr2; } 6044 if (CS->size() == 2) { 6045 auto *First = CS->body_front(); 6046 auto *Second = CS->body_back(); 6047 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 6048 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 6049 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 6050 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 6051 // Need to find what subexpression is 'v' and what is 'x'. 6052 OpenMPAtomicUpdateChecker Checker(*this); 6053 bool IsUpdateExprFound = !Checker.checkStatement(Second); 6054 BinaryOperator *BinOp = nullptr; 6055 if (IsUpdateExprFound) { 6056 BinOp = dyn_cast<BinaryOperator>(First); 6057 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6058 } 6059 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6060 // { v = x; x++; } 6061 // { v = x; x--; } 6062 // { v = x; ++x; } 6063 // { v = x; --x; } 6064 // { v = x; x binop= expr; } 6065 // { v = x; x = x binop expr; } 6066 // { v = x; x = expr binop x; } 6067 // Check that the first expression has form v = x. 6068 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6069 llvm::FoldingSetNodeID XId, PossibleXId; 6070 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6071 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6072 IsUpdateExprFound = XId == PossibleXId; 6073 if (IsUpdateExprFound) { 6074 V = BinOp->getLHS(); 6075 X = Checker.getX(); 6076 E = Checker.getExpr(); 6077 UE = Checker.getUpdateExpr(); 6078 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6079 IsPostfixUpdate = true; 6080 } 6081 } 6082 if (!IsUpdateExprFound) { 6083 IsUpdateExprFound = !Checker.checkStatement(First); 6084 BinOp = nullptr; 6085 if (IsUpdateExprFound) { 6086 BinOp = dyn_cast<BinaryOperator>(Second); 6087 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6088 } 6089 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6090 // { x++; v = x; } 6091 // { x--; v = x; } 6092 // { ++x; v = x; } 6093 // { --x; v = x; } 6094 // { x binop= expr; v = x; } 6095 // { x = x binop expr; v = x; } 6096 // { x = expr binop x; v = x; } 6097 // Check that the second expression has form v = x. 6098 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6099 llvm::FoldingSetNodeID XId, PossibleXId; 6100 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6101 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6102 IsUpdateExprFound = XId == PossibleXId; 6103 if (IsUpdateExprFound) { 6104 V = BinOp->getLHS(); 6105 X = Checker.getX(); 6106 E = Checker.getExpr(); 6107 UE = Checker.getUpdateExpr(); 6108 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6109 IsPostfixUpdate = false; 6110 } 6111 } 6112 } 6113 if (!IsUpdateExprFound) { 6114 // { v = x; x = expr; } 6115 auto *FirstExpr = dyn_cast<Expr>(First); 6116 auto *SecondExpr = dyn_cast<Expr>(Second); 6117 if (!FirstExpr || !SecondExpr || 6118 !(FirstExpr->isInstantiationDependent() || 6119 SecondExpr->isInstantiationDependent())) { 6120 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 6121 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 6122 ErrorFound = NotAnAssignmentOp; 6123 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 6124 : First->getLocStart(); 6125 NoteRange = ErrorRange = FirstBinOp 6126 ? FirstBinOp->getSourceRange() 6127 : SourceRange(ErrorLoc, ErrorLoc); 6128 } else { 6129 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 6130 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 6131 ErrorFound = NotAnAssignmentOp; 6132 NoteLoc = ErrorLoc = SecondBinOp 6133 ? SecondBinOp->getOperatorLoc() 6134 : Second->getLocStart(); 6135 NoteRange = ErrorRange = 6136 SecondBinOp ? SecondBinOp->getSourceRange() 6137 : SourceRange(ErrorLoc, ErrorLoc); 6138 } else { 6139 auto *PossibleXRHSInFirst = 6140 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 6141 auto *PossibleXLHSInSecond = 6142 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 6143 llvm::FoldingSetNodeID X1Id, X2Id; 6144 PossibleXRHSInFirst->Profile(X1Id, Context, 6145 /*Canonical=*/true); 6146 PossibleXLHSInSecond->Profile(X2Id, Context, 6147 /*Canonical=*/true); 6148 IsUpdateExprFound = X1Id == X2Id; 6149 if (IsUpdateExprFound) { 6150 V = FirstBinOp->getLHS(); 6151 X = SecondBinOp->getLHS(); 6152 E = SecondBinOp->getRHS(); 6153 UE = nullptr; 6154 IsXLHSInRHSPart = false; 6155 IsPostfixUpdate = true; 6156 } else { 6157 ErrorFound = NotASpecificExpression; 6158 ErrorLoc = FirstBinOp->getExprLoc(); 6159 ErrorRange = FirstBinOp->getSourceRange(); 6160 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 6161 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 6162 } 6163 } 6164 } 6165 } 6166 } 6167 } else { 6168 NoteLoc = ErrorLoc = Body->getLocStart(); 6169 NoteRange = ErrorRange = 6170 SourceRange(Body->getLocStart(), Body->getLocStart()); 6171 ErrorFound = NotTwoSubstatements; 6172 } 6173 } else { 6174 NoteLoc = ErrorLoc = Body->getLocStart(); 6175 NoteRange = ErrorRange = 6176 SourceRange(Body->getLocStart(), Body->getLocStart()); 6177 ErrorFound = NotACompoundStatement; 6178 } 6179 if (ErrorFound != NoError) { 6180 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 6181 << ErrorRange; 6182 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6183 return StmtError(); 6184 } else if (CurContext->isDependentContext()) { 6185 UE = V = E = X = nullptr; 6186 } 6187 } 6188 } 6189 6190 getCurFunction()->setHasBranchProtectedScope(); 6191 6192 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6193 X, V, E, UE, IsXLHSInRHSPart, 6194 IsPostfixUpdate); 6195 } 6196 6197 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 6198 Stmt *AStmt, 6199 SourceLocation StartLoc, 6200 SourceLocation EndLoc) { 6201 if (!AStmt) 6202 return StmtError(); 6203 6204 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6205 // 1.2.2 OpenMP Language Terminology 6206 // Structured block - An executable statement with a single entry at the 6207 // top and a single exit at the bottom. 6208 // The point of exit cannot be a branch out of the structured block. 6209 // longjmp() and throw() must not violate the entry/exit criteria. 6210 CS->getCapturedDecl()->setNothrow(); 6211 6212 // OpenMP [2.16, Nesting of Regions] 6213 // If specified, a teams construct must be contained within a target 6214 // construct. That target construct must contain no statements or directives 6215 // outside of the teams construct. 6216 if (DSAStack->hasInnerTeamsRegion()) { 6217 auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true); 6218 bool OMPTeamsFound = true; 6219 if (auto *CS = dyn_cast<CompoundStmt>(S)) { 6220 auto I = CS->body_begin(); 6221 while (I != CS->body_end()) { 6222 auto *OED = dyn_cast<OMPExecutableDirective>(*I); 6223 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { 6224 OMPTeamsFound = false; 6225 break; 6226 } 6227 ++I; 6228 } 6229 assert(I != CS->body_end() && "Not found statement"); 6230 S = *I; 6231 } else { 6232 auto *OED = dyn_cast<OMPExecutableDirective>(S); 6233 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 6234 } 6235 if (!OMPTeamsFound) { 6236 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 6237 Diag(DSAStack->getInnerTeamsRegionLoc(), 6238 diag::note_omp_nested_teams_construct_here); 6239 Diag(S->getLocStart(), diag::note_omp_nested_statement_here) 6240 << isa<OMPExecutableDirective>(S); 6241 return StmtError(); 6242 } 6243 } 6244 6245 getCurFunction()->setHasBranchProtectedScope(); 6246 6247 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6248 } 6249 6250 StmtResult 6251 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 6252 Stmt *AStmt, SourceLocation StartLoc, 6253 SourceLocation EndLoc) { 6254 if (!AStmt) 6255 return StmtError(); 6256 6257 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6258 // 1.2.2 OpenMP Language Terminology 6259 // Structured block - An executable statement with a single entry at the 6260 // top and a single exit at the bottom. 6261 // The point of exit cannot be a branch out of the structured block. 6262 // longjmp() and throw() must not violate the entry/exit criteria. 6263 CS->getCapturedDecl()->setNothrow(); 6264 6265 getCurFunction()->setHasBranchProtectedScope(); 6266 6267 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6268 AStmt); 6269 } 6270 6271 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 6272 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6273 SourceLocation EndLoc, 6274 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6275 if (!AStmt) 6276 return StmtError(); 6277 6278 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6279 // 1.2.2 OpenMP Language Terminology 6280 // Structured block - An executable statement with a single entry at the 6281 // top and a single exit at the bottom. 6282 // The point of exit cannot be a branch out of the structured block. 6283 // longjmp() and throw() must not violate the entry/exit criteria. 6284 CS->getCapturedDecl()->setNothrow(); 6285 6286 OMPLoopDirective::HelperExprs B; 6287 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6288 // define the nested loops number. 6289 unsigned NestedLoopCount = 6290 CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 6291 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6292 VarsWithImplicitDSA, B); 6293 if (NestedLoopCount == 0) 6294 return StmtError(); 6295 6296 assert((CurContext->isDependentContext() || B.builtAll()) && 6297 "omp target parallel for loop exprs were not built"); 6298 6299 if (!CurContext->isDependentContext()) { 6300 // Finalize the clauses that need pre-built expressions for CodeGen. 6301 for (auto C : Clauses) { 6302 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6303 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6304 B.NumIterations, *this, CurScope, 6305 DSAStack)) 6306 return StmtError(); 6307 } 6308 } 6309 6310 getCurFunction()->setHasBranchProtectedScope(); 6311 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 6312 NestedLoopCount, Clauses, AStmt, 6313 B, DSAStack->isCancelRegion()); 6314 } 6315 6316 /// Check for existence of a map clause in the list of clauses. 6317 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 6318 const OpenMPClauseKind K) { 6319 return llvm::any_of( 6320 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 6321 } 6322 6323 template <typename... Params> 6324 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 6325 const Params... ClauseTypes) { 6326 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 6327 } 6328 6329 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 6330 Stmt *AStmt, 6331 SourceLocation StartLoc, 6332 SourceLocation EndLoc) { 6333 if (!AStmt) 6334 return StmtError(); 6335 6336 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6337 6338 // OpenMP [2.10.1, Restrictions, p. 97] 6339 // At least one map clause must appear on the directive. 6340 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 6341 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6342 << "'map' or 'use_device_ptr'" 6343 << getOpenMPDirectiveName(OMPD_target_data); 6344 return StmtError(); 6345 } 6346 6347 getCurFunction()->setHasBranchProtectedScope(); 6348 6349 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 6350 AStmt); 6351 } 6352 6353 StmtResult 6354 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 6355 SourceLocation StartLoc, 6356 SourceLocation EndLoc) { 6357 // OpenMP [2.10.2, Restrictions, p. 99] 6358 // At least one map clause must appear on the directive. 6359 if (!hasClauses(Clauses, OMPC_map)) { 6360 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6361 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 6362 return StmtError(); 6363 } 6364 6365 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, 6366 Clauses); 6367 } 6368 6369 StmtResult 6370 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 6371 SourceLocation StartLoc, 6372 SourceLocation EndLoc) { 6373 // OpenMP [2.10.3, Restrictions, p. 102] 6374 // At least one map clause must appear on the directive. 6375 if (!hasClauses(Clauses, OMPC_map)) { 6376 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6377 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 6378 return StmtError(); 6379 } 6380 6381 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses); 6382 } 6383 6384 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 6385 SourceLocation StartLoc, 6386 SourceLocation EndLoc) { 6387 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 6388 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 6389 return StmtError(); 6390 } 6391 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses); 6392 } 6393 6394 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 6395 Stmt *AStmt, SourceLocation StartLoc, 6396 SourceLocation EndLoc) { 6397 if (!AStmt) 6398 return StmtError(); 6399 6400 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6401 // 1.2.2 OpenMP Language Terminology 6402 // Structured block - An executable statement with a single entry at the 6403 // top and a single exit at the bottom. 6404 // The point of exit cannot be a branch out of the structured block. 6405 // longjmp() and throw() must not violate the entry/exit criteria. 6406 CS->getCapturedDecl()->setNothrow(); 6407 6408 getCurFunction()->setHasBranchProtectedScope(); 6409 6410 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6411 } 6412 6413 StmtResult 6414 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 6415 SourceLocation EndLoc, 6416 OpenMPDirectiveKind CancelRegion) { 6417 if (DSAStack->isParentNowaitRegion()) { 6418 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 6419 return StmtError(); 6420 } 6421 if (DSAStack->isParentOrderedRegion()) { 6422 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 6423 return StmtError(); 6424 } 6425 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 6426 CancelRegion); 6427 } 6428 6429 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 6430 SourceLocation StartLoc, 6431 SourceLocation EndLoc, 6432 OpenMPDirectiveKind CancelRegion) { 6433 if (DSAStack->isParentNowaitRegion()) { 6434 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 6435 return StmtError(); 6436 } 6437 if (DSAStack->isParentOrderedRegion()) { 6438 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 6439 return StmtError(); 6440 } 6441 DSAStack->setParentCancelRegion(/*Cancel=*/true); 6442 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6443 CancelRegion); 6444 } 6445 6446 static bool checkGrainsizeNumTasksClauses(Sema &S, 6447 ArrayRef<OMPClause *> Clauses) { 6448 OMPClause *PrevClause = nullptr; 6449 bool ErrorFound = false; 6450 for (auto *C : Clauses) { 6451 if (C->getClauseKind() == OMPC_grainsize || 6452 C->getClauseKind() == OMPC_num_tasks) { 6453 if (!PrevClause) 6454 PrevClause = C; 6455 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 6456 S.Diag(C->getLocStart(), 6457 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 6458 << getOpenMPClauseName(C->getClauseKind()) 6459 << getOpenMPClauseName(PrevClause->getClauseKind()); 6460 S.Diag(PrevClause->getLocStart(), 6461 diag::note_omp_previous_grainsize_num_tasks) 6462 << getOpenMPClauseName(PrevClause->getClauseKind()); 6463 ErrorFound = true; 6464 } 6465 } 6466 } 6467 return ErrorFound; 6468 } 6469 6470 static bool checkReductionClauseWithNogroup(Sema &S, 6471 ArrayRef<OMPClause *> Clauses) { 6472 OMPClause *ReductionClause = nullptr; 6473 OMPClause *NogroupClause = nullptr; 6474 for (auto *C : Clauses) { 6475 if (C->getClauseKind() == OMPC_reduction) { 6476 ReductionClause = C; 6477 if (NogroupClause) 6478 break; 6479 continue; 6480 } 6481 if (C->getClauseKind() == OMPC_nogroup) { 6482 NogroupClause = C; 6483 if (ReductionClause) 6484 break; 6485 continue; 6486 } 6487 } 6488 if (ReductionClause && NogroupClause) { 6489 S.Diag(ReductionClause->getLocStart(), diag::err_omp_reduction_with_nogroup) 6490 << SourceRange(NogroupClause->getLocStart(), 6491 NogroupClause->getLocEnd()); 6492 return true; 6493 } 6494 return false; 6495 } 6496 6497 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 6498 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6499 SourceLocation EndLoc, 6500 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6501 if (!AStmt) 6502 return StmtError(); 6503 6504 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6505 OMPLoopDirective::HelperExprs B; 6506 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6507 // define the nested loops number. 6508 unsigned NestedLoopCount = 6509 CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 6510 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6511 VarsWithImplicitDSA, B); 6512 if (NestedLoopCount == 0) 6513 return StmtError(); 6514 6515 assert((CurContext->isDependentContext() || B.builtAll()) && 6516 "omp for loop exprs were not built"); 6517 6518 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6519 // The grainsize clause and num_tasks clause are mutually exclusive and may 6520 // not appear on the same taskloop directive. 6521 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6522 return StmtError(); 6523 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6524 // If a reduction clause is present on the taskloop directive, the nogroup 6525 // clause must not be specified. 6526 if (checkReductionClauseWithNogroup(*this, Clauses)) 6527 return StmtError(); 6528 6529 getCurFunction()->setHasBranchProtectedScope(); 6530 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 6531 NestedLoopCount, Clauses, AStmt, B); 6532 } 6533 6534 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 6535 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6536 SourceLocation EndLoc, 6537 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6538 if (!AStmt) 6539 return StmtError(); 6540 6541 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6542 OMPLoopDirective::HelperExprs B; 6543 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6544 // define the nested loops number. 6545 unsigned NestedLoopCount = 6546 CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 6547 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6548 VarsWithImplicitDSA, B); 6549 if (NestedLoopCount == 0) 6550 return StmtError(); 6551 6552 assert((CurContext->isDependentContext() || B.builtAll()) && 6553 "omp for loop exprs were not built"); 6554 6555 if (!CurContext->isDependentContext()) { 6556 // Finalize the clauses that need pre-built expressions for CodeGen. 6557 for (auto C : Clauses) { 6558 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6559 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6560 B.NumIterations, *this, CurScope, 6561 DSAStack)) 6562 return StmtError(); 6563 } 6564 } 6565 6566 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6567 // The grainsize clause and num_tasks clause are mutually exclusive and may 6568 // not appear on the same taskloop directive. 6569 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6570 return StmtError(); 6571 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6572 // If a reduction clause is present on the taskloop directive, the nogroup 6573 // clause must not be specified. 6574 if (checkReductionClauseWithNogroup(*this, Clauses)) 6575 return StmtError(); 6576 6577 getCurFunction()->setHasBranchProtectedScope(); 6578 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 6579 NestedLoopCount, Clauses, AStmt, B); 6580 } 6581 6582 StmtResult Sema::ActOnOpenMPDistributeDirective( 6583 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6584 SourceLocation EndLoc, 6585 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6586 if (!AStmt) 6587 return StmtError(); 6588 6589 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6590 OMPLoopDirective::HelperExprs B; 6591 // In presence of clause 'collapse' with number of loops, it will 6592 // define the nested loops number. 6593 unsigned NestedLoopCount = 6594 CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 6595 nullptr /*ordered not a clause on distribute*/, AStmt, 6596 *this, *DSAStack, VarsWithImplicitDSA, B); 6597 if (NestedLoopCount == 0) 6598 return StmtError(); 6599 6600 assert((CurContext->isDependentContext() || B.builtAll()) && 6601 "omp for loop exprs were not built"); 6602 6603 getCurFunction()->setHasBranchProtectedScope(); 6604 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 6605 NestedLoopCount, Clauses, AStmt, B); 6606 } 6607 6608 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 6609 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6610 SourceLocation EndLoc, 6611 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6612 if (!AStmt) 6613 return StmtError(); 6614 6615 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6616 // 1.2.2 OpenMP Language Terminology 6617 // Structured block - An executable statement with a single entry at the 6618 // top and a single exit at the bottom. 6619 // The point of exit cannot be a branch out of the structured block. 6620 // longjmp() and throw() must not violate the entry/exit criteria. 6621 CS->getCapturedDecl()->setNothrow(); 6622 6623 OMPLoopDirective::HelperExprs B; 6624 // In presence of clause 'collapse' with number of loops, it will 6625 // define the nested loops number. 6626 unsigned NestedLoopCount = CheckOpenMPLoop( 6627 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 6628 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6629 VarsWithImplicitDSA, B); 6630 if (NestedLoopCount == 0) 6631 return StmtError(); 6632 6633 assert((CurContext->isDependentContext() || B.builtAll()) && 6634 "omp for loop exprs were not built"); 6635 6636 getCurFunction()->setHasBranchProtectedScope(); 6637 return OMPDistributeParallelForDirective::Create( 6638 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6639 } 6640 6641 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 6642 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6643 SourceLocation EndLoc, 6644 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6645 if (!AStmt) 6646 return StmtError(); 6647 6648 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6649 // 1.2.2 OpenMP Language Terminology 6650 // Structured block - An executable statement with a single entry at the 6651 // top and a single exit at the bottom. 6652 // The point of exit cannot be a branch out of the structured block. 6653 // longjmp() and throw() must not violate the entry/exit criteria. 6654 CS->getCapturedDecl()->setNothrow(); 6655 6656 OMPLoopDirective::HelperExprs B; 6657 // In presence of clause 'collapse' with number of loops, it will 6658 // define the nested loops number. 6659 unsigned NestedLoopCount = CheckOpenMPLoop( 6660 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 6661 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6662 VarsWithImplicitDSA, B); 6663 if (NestedLoopCount == 0) 6664 return StmtError(); 6665 6666 assert((CurContext->isDependentContext() || B.builtAll()) && 6667 "omp for loop exprs were not built"); 6668 6669 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6670 return StmtError(); 6671 6672 getCurFunction()->setHasBranchProtectedScope(); 6673 return OMPDistributeParallelForSimdDirective::Create( 6674 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6675 } 6676 6677 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 6678 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6679 SourceLocation EndLoc, 6680 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6681 if (!AStmt) 6682 return StmtError(); 6683 6684 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6685 // 1.2.2 OpenMP Language Terminology 6686 // Structured block - An executable statement with a single entry at the 6687 // top and a single exit at the bottom. 6688 // The point of exit cannot be a branch out of the structured block. 6689 // longjmp() and throw() must not violate the entry/exit criteria. 6690 CS->getCapturedDecl()->setNothrow(); 6691 6692 OMPLoopDirective::HelperExprs B; 6693 // In presence of clause 'collapse' with number of loops, it will 6694 // define the nested loops number. 6695 unsigned NestedLoopCount = 6696 CheckOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 6697 nullptr /*ordered not a clause on distribute*/, AStmt, 6698 *this, *DSAStack, VarsWithImplicitDSA, B); 6699 if (NestedLoopCount == 0) 6700 return StmtError(); 6701 6702 assert((CurContext->isDependentContext() || B.builtAll()) && 6703 "omp for loop exprs were not built"); 6704 6705 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6706 return StmtError(); 6707 6708 getCurFunction()->setHasBranchProtectedScope(); 6709 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 6710 NestedLoopCount, Clauses, AStmt, B); 6711 } 6712 6713 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 6714 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6715 SourceLocation EndLoc, 6716 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6717 if (!AStmt) 6718 return StmtError(); 6719 6720 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6721 // 1.2.2 OpenMP Language Terminology 6722 // Structured block - An executable statement with a single entry at the 6723 // top and a single exit at the bottom. 6724 // The point of exit cannot be a branch out of the structured block. 6725 // longjmp() and throw() must not violate the entry/exit criteria. 6726 CS->getCapturedDecl()->setNothrow(); 6727 6728 OMPLoopDirective::HelperExprs B; 6729 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6730 // define the nested loops number. 6731 unsigned NestedLoopCount = CheckOpenMPLoop( 6732 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 6733 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6734 VarsWithImplicitDSA, B); 6735 if (NestedLoopCount == 0) 6736 return StmtError(); 6737 6738 assert((CurContext->isDependentContext() || B.builtAll()) && 6739 "omp target parallel for simd loop exprs were not built"); 6740 6741 if (!CurContext->isDependentContext()) { 6742 // Finalize the clauses that need pre-built expressions for CodeGen. 6743 for (auto C : Clauses) { 6744 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6745 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6746 B.NumIterations, *this, CurScope, 6747 DSAStack)) 6748 return StmtError(); 6749 } 6750 } 6751 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6752 return StmtError(); 6753 6754 getCurFunction()->setHasBranchProtectedScope(); 6755 return OMPTargetParallelForSimdDirective::Create( 6756 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6757 } 6758 6759 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 6760 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6761 SourceLocation EndLoc, 6762 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6763 if (!AStmt) 6764 return StmtError(); 6765 6766 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6767 // 1.2.2 OpenMP Language Terminology 6768 // Structured block - An executable statement with a single entry at the 6769 // top and a single exit at the bottom. 6770 // The point of exit cannot be a branch out of the structured block. 6771 // longjmp() and throw() must not violate the entry/exit criteria. 6772 CS->getCapturedDecl()->setNothrow(); 6773 6774 OMPLoopDirective::HelperExprs B; 6775 // In presence of clause 'collapse' with number of loops, it will define the 6776 // nested loops number. 6777 unsigned NestedLoopCount = 6778 CheckOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 6779 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6780 VarsWithImplicitDSA, B); 6781 if (NestedLoopCount == 0) 6782 return StmtError(); 6783 6784 assert((CurContext->isDependentContext() || B.builtAll()) && 6785 "omp target simd loop exprs were not built"); 6786 6787 if (!CurContext->isDependentContext()) { 6788 // Finalize the clauses that need pre-built expressions for CodeGen. 6789 for (auto C : Clauses) { 6790 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6791 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6792 B.NumIterations, *this, CurScope, 6793 DSAStack)) 6794 return StmtError(); 6795 } 6796 } 6797 6798 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6799 return StmtError(); 6800 6801 getCurFunction()->setHasBranchProtectedScope(); 6802 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 6803 NestedLoopCount, Clauses, AStmt, B); 6804 } 6805 6806 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 6807 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6808 SourceLocation EndLoc, 6809 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6810 if (!AStmt) 6811 return StmtError(); 6812 6813 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6814 // 1.2.2 OpenMP Language Terminology 6815 // Structured block - An executable statement with a single entry at the 6816 // top and a single exit at the bottom. 6817 // The point of exit cannot be a branch out of the structured block. 6818 // longjmp() and throw() must not violate the entry/exit criteria. 6819 CS->getCapturedDecl()->setNothrow(); 6820 6821 OMPLoopDirective::HelperExprs B; 6822 // In presence of clause 'collapse' with number of loops, it will 6823 // define the nested loops number. 6824 unsigned NestedLoopCount = 6825 CheckOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 6826 nullptr /*ordered not a clause on distribute*/, AStmt, 6827 *this, *DSAStack, VarsWithImplicitDSA, B); 6828 if (NestedLoopCount == 0) 6829 return StmtError(); 6830 6831 assert((CurContext->isDependentContext() || B.builtAll()) && 6832 "omp teams distribute loop exprs were not built"); 6833 6834 getCurFunction()->setHasBranchProtectedScope(); 6835 return OMPTeamsDistributeDirective::Create( 6836 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6837 } 6838 6839 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 6840 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6841 SourceLocation EndLoc, 6842 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6843 if (!AStmt) 6844 return StmtError(); 6845 6846 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6847 // 1.2.2 OpenMP Language Terminology 6848 // Structured block - An executable statement with a single entry at the 6849 // top and a single exit at the bottom. 6850 // The point of exit cannot be a branch out of the structured block. 6851 // longjmp() and throw() must not violate the entry/exit criteria. 6852 CS->getCapturedDecl()->setNothrow(); 6853 6854 OMPLoopDirective::HelperExprs B; 6855 // In presence of clause 'collapse' with number of loops, it will 6856 // define the nested loops number. 6857 unsigned NestedLoopCount = CheckOpenMPLoop( 6858 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 6859 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6860 VarsWithImplicitDSA, B); 6861 6862 if (NestedLoopCount == 0) 6863 return StmtError(); 6864 6865 assert((CurContext->isDependentContext() || B.builtAll()) && 6866 "omp teams distribute simd loop exprs were not built"); 6867 6868 if (!CurContext->isDependentContext()) { 6869 // Finalize the clauses that need pre-built expressions for CodeGen. 6870 for (auto C : Clauses) { 6871 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6872 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6873 B.NumIterations, *this, CurScope, 6874 DSAStack)) 6875 return StmtError(); 6876 } 6877 } 6878 6879 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6880 return StmtError(); 6881 6882 getCurFunction()->setHasBranchProtectedScope(); 6883 return OMPTeamsDistributeSimdDirective::Create( 6884 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6885 } 6886 6887 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 6888 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6889 SourceLocation EndLoc, 6890 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6891 if (!AStmt) 6892 return StmtError(); 6893 6894 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6895 // 1.2.2 OpenMP Language Terminology 6896 // Structured block - An executable statement with a single entry at the 6897 // top and a single exit at the bottom. 6898 // The point of exit cannot be a branch out of the structured block. 6899 // longjmp() and throw() must not violate the entry/exit criteria. 6900 CS->getCapturedDecl()->setNothrow(); 6901 6902 OMPLoopDirective::HelperExprs B; 6903 // In presence of clause 'collapse' with number of loops, it will 6904 // define the nested loops number. 6905 auto NestedLoopCount = CheckOpenMPLoop( 6906 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 6907 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6908 VarsWithImplicitDSA, B); 6909 6910 if (NestedLoopCount == 0) 6911 return StmtError(); 6912 6913 assert((CurContext->isDependentContext() || B.builtAll()) && 6914 "omp for loop exprs were not built"); 6915 6916 if (!CurContext->isDependentContext()) { 6917 // Finalize the clauses that need pre-built expressions for CodeGen. 6918 for (auto C : Clauses) { 6919 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6920 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6921 B.NumIterations, *this, CurScope, 6922 DSAStack)) 6923 return StmtError(); 6924 } 6925 } 6926 6927 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6928 return StmtError(); 6929 6930 getCurFunction()->setHasBranchProtectedScope(); 6931 return OMPTeamsDistributeParallelForSimdDirective::Create( 6932 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6933 } 6934 6935 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 6936 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6937 SourceLocation EndLoc, 6938 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6939 if (!AStmt) 6940 return StmtError(); 6941 6942 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6943 // 1.2.2 OpenMP Language Terminology 6944 // Structured block - An executable statement with a single entry at the 6945 // top and a single exit at the bottom. 6946 // The point of exit cannot be a branch out of the structured block. 6947 // longjmp() and throw() must not violate the entry/exit criteria. 6948 CS->getCapturedDecl()->setNothrow(); 6949 6950 OMPLoopDirective::HelperExprs B; 6951 // In presence of clause 'collapse' with number of loops, it will 6952 // define the nested loops number. 6953 unsigned NestedLoopCount = CheckOpenMPLoop( 6954 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 6955 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6956 VarsWithImplicitDSA, B); 6957 6958 if (NestedLoopCount == 0) 6959 return StmtError(); 6960 6961 assert((CurContext->isDependentContext() || B.builtAll()) && 6962 "omp for loop exprs were not built"); 6963 6964 if (!CurContext->isDependentContext()) { 6965 // Finalize the clauses that need pre-built expressions for CodeGen. 6966 for (auto C : Clauses) { 6967 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6968 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6969 B.NumIterations, *this, CurScope, 6970 DSAStack)) 6971 return StmtError(); 6972 } 6973 } 6974 6975 getCurFunction()->setHasBranchProtectedScope(); 6976 return OMPTeamsDistributeParallelForDirective::Create( 6977 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6978 } 6979 6980 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 6981 Stmt *AStmt, 6982 SourceLocation StartLoc, 6983 SourceLocation EndLoc) { 6984 if (!AStmt) 6985 return StmtError(); 6986 6987 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6988 // 1.2.2 OpenMP Language Terminology 6989 // Structured block - An executable statement with a single entry at the 6990 // top and a single exit at the bottom. 6991 // The point of exit cannot be a branch out of the structured block. 6992 // longjmp() and throw() must not violate the entry/exit criteria. 6993 CS->getCapturedDecl()->setNothrow(); 6994 6995 getCurFunction()->setHasBranchProtectedScope(); 6996 6997 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 6998 AStmt); 6999 } 7000 7001 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 7002 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7003 SourceLocation EndLoc, 7004 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7005 if (!AStmt) 7006 return StmtError(); 7007 7008 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7009 // 1.2.2 OpenMP Language Terminology 7010 // Structured block - An executable statement with a single entry at the 7011 // top and a single exit at the bottom. 7012 // The point of exit cannot be a branch out of the structured block. 7013 // longjmp() and throw() must not violate the entry/exit criteria. 7014 CS->getCapturedDecl()->setNothrow(); 7015 7016 OMPLoopDirective::HelperExprs B; 7017 // In presence of clause 'collapse' with number of loops, it will 7018 // define the nested loops number. 7019 auto NestedLoopCount = CheckOpenMPLoop( 7020 OMPD_target_teams_distribute, 7021 getCollapseNumberExpr(Clauses), 7022 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 7023 VarsWithImplicitDSA, B); 7024 if (NestedLoopCount == 0) 7025 return StmtError(); 7026 7027 assert((CurContext->isDependentContext() || B.builtAll()) && 7028 "omp target teams distribute loop exprs were not built"); 7029 7030 getCurFunction()->setHasBranchProtectedScope(); 7031 return OMPTargetTeamsDistributeDirective::Create( 7032 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7033 } 7034 7035 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 7036 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7037 SourceLocation EndLoc, 7038 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7039 if (!AStmt) 7040 return StmtError(); 7041 7042 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7043 // 1.2.2 OpenMP Language Terminology 7044 // Structured block - An executable statement with a single entry at the 7045 // top and a single exit at the bottom. 7046 // The point of exit cannot be a branch out of the structured block. 7047 // longjmp() and throw() must not violate the entry/exit criteria. 7048 CS->getCapturedDecl()->setNothrow(); 7049 7050 OMPLoopDirective::HelperExprs B; 7051 // In presence of clause 'collapse' with number of loops, it will 7052 // define the nested loops number. 7053 auto NestedLoopCount = CheckOpenMPLoop( 7054 OMPD_target_teams_distribute_parallel_for, 7055 getCollapseNumberExpr(Clauses), 7056 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 7057 VarsWithImplicitDSA, B); 7058 if (NestedLoopCount == 0) 7059 return StmtError(); 7060 7061 assert((CurContext->isDependentContext() || B.builtAll()) && 7062 "omp target teams distribute parallel for loop exprs were not built"); 7063 7064 if (!CurContext->isDependentContext()) { 7065 // Finalize the clauses that need pre-built expressions for CodeGen. 7066 for (auto C : Clauses) { 7067 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7068 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7069 B.NumIterations, *this, CurScope, 7070 DSAStack)) 7071 return StmtError(); 7072 } 7073 } 7074 7075 getCurFunction()->setHasBranchProtectedScope(); 7076 return OMPTargetTeamsDistributeParallelForDirective::Create( 7077 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7078 } 7079 7080 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 7081 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7082 SourceLocation EndLoc, 7083 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7084 if (!AStmt) 7085 return StmtError(); 7086 7087 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7088 // 1.2.2 OpenMP Language Terminology 7089 // Structured block - An executable statement with a single entry at the 7090 // top and a single exit at the bottom. 7091 // The point of exit cannot be a branch out of the structured block. 7092 // longjmp() and throw() must not violate the entry/exit criteria. 7093 CS->getCapturedDecl()->setNothrow(); 7094 7095 OMPLoopDirective::HelperExprs B; 7096 // In presence of clause 'collapse' with number of loops, it will 7097 // define the nested loops number. 7098 auto NestedLoopCount = CheckOpenMPLoop( 7099 OMPD_target_teams_distribute_parallel_for_simd, 7100 getCollapseNumberExpr(Clauses), 7101 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 7102 VarsWithImplicitDSA, B); 7103 if (NestedLoopCount == 0) 7104 return StmtError(); 7105 7106 assert((CurContext->isDependentContext() || B.builtAll()) && 7107 "omp target teams distribute parallel for simd loop exprs were not " 7108 "built"); 7109 7110 if (!CurContext->isDependentContext()) { 7111 // Finalize the clauses that need pre-built expressions for CodeGen. 7112 for (auto C : Clauses) { 7113 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7114 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7115 B.NumIterations, *this, CurScope, 7116 DSAStack)) 7117 return StmtError(); 7118 } 7119 } 7120 7121 getCurFunction()->setHasBranchProtectedScope(); 7122 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 7123 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7124 } 7125 7126 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 7127 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7128 SourceLocation EndLoc, 7129 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7130 if (!AStmt) 7131 return StmtError(); 7132 7133 auto *CS = cast<CapturedStmt>(AStmt); 7134 // 1.2.2 OpenMP Language Terminology 7135 // Structured block - An executable statement with a single entry at the 7136 // top and a single exit at the bottom. 7137 // The point of exit cannot be a branch out of the structured block. 7138 // longjmp() and throw() must not violate the entry/exit criteria. 7139 CS->getCapturedDecl()->setNothrow(); 7140 7141 OMPLoopDirective::HelperExprs B; 7142 // In presence of clause 'collapse' with number of loops, it will 7143 // define the nested loops number. 7144 auto NestedLoopCount = CheckOpenMPLoop( 7145 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 7146 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 7147 VarsWithImplicitDSA, B); 7148 if (NestedLoopCount == 0) 7149 return StmtError(); 7150 7151 assert((CurContext->isDependentContext() || B.builtAll()) && 7152 "omp target teams distribute simd loop exprs were not built"); 7153 7154 getCurFunction()->setHasBranchProtectedScope(); 7155 return OMPTargetTeamsDistributeSimdDirective::Create( 7156 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7157 } 7158 7159 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 7160 SourceLocation StartLoc, 7161 SourceLocation LParenLoc, 7162 SourceLocation EndLoc) { 7163 OMPClause *Res = nullptr; 7164 switch (Kind) { 7165 case OMPC_final: 7166 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 7167 break; 7168 case OMPC_num_threads: 7169 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 7170 break; 7171 case OMPC_safelen: 7172 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 7173 break; 7174 case OMPC_simdlen: 7175 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 7176 break; 7177 case OMPC_collapse: 7178 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 7179 break; 7180 case OMPC_ordered: 7181 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 7182 break; 7183 case OMPC_device: 7184 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 7185 break; 7186 case OMPC_num_teams: 7187 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 7188 break; 7189 case OMPC_thread_limit: 7190 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 7191 break; 7192 case OMPC_priority: 7193 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 7194 break; 7195 case OMPC_grainsize: 7196 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 7197 break; 7198 case OMPC_num_tasks: 7199 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 7200 break; 7201 case OMPC_hint: 7202 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 7203 break; 7204 case OMPC_if: 7205 case OMPC_default: 7206 case OMPC_proc_bind: 7207 case OMPC_schedule: 7208 case OMPC_private: 7209 case OMPC_firstprivate: 7210 case OMPC_lastprivate: 7211 case OMPC_shared: 7212 case OMPC_reduction: 7213 case OMPC_task_reduction: 7214 case OMPC_in_reduction: 7215 case OMPC_linear: 7216 case OMPC_aligned: 7217 case OMPC_copyin: 7218 case OMPC_copyprivate: 7219 case OMPC_nowait: 7220 case OMPC_untied: 7221 case OMPC_mergeable: 7222 case OMPC_threadprivate: 7223 case OMPC_flush: 7224 case OMPC_read: 7225 case OMPC_write: 7226 case OMPC_update: 7227 case OMPC_capture: 7228 case OMPC_seq_cst: 7229 case OMPC_depend: 7230 case OMPC_threads: 7231 case OMPC_simd: 7232 case OMPC_map: 7233 case OMPC_nogroup: 7234 case OMPC_dist_schedule: 7235 case OMPC_defaultmap: 7236 case OMPC_unknown: 7237 case OMPC_uniform: 7238 case OMPC_to: 7239 case OMPC_from: 7240 case OMPC_use_device_ptr: 7241 case OMPC_is_device_ptr: 7242 llvm_unreachable("Clause is not allowed."); 7243 } 7244 return Res; 7245 } 7246 7247 // An OpenMP directive such as 'target parallel' has two captured regions: 7248 // for the 'target' and 'parallel' respectively. This function returns 7249 // the region in which to capture expressions associated with a clause. 7250 // A return value of OMPD_unknown signifies that the expression should not 7251 // be captured. 7252 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 7253 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 7254 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 7255 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 7256 7257 switch (CKind) { 7258 case OMPC_if: 7259 switch (DKind) { 7260 case OMPD_target_parallel: 7261 // If this clause applies to the nested 'parallel' region, capture within 7262 // the 'target' region, otherwise do not capture. 7263 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 7264 CaptureRegion = OMPD_target; 7265 break; 7266 case OMPD_cancel: 7267 case OMPD_parallel: 7268 case OMPD_parallel_sections: 7269 case OMPD_parallel_for: 7270 case OMPD_parallel_for_simd: 7271 case OMPD_target: 7272 case OMPD_target_simd: 7273 case OMPD_target_parallel_for: 7274 case OMPD_target_parallel_for_simd: 7275 case OMPD_target_teams: 7276 case OMPD_target_teams_distribute: 7277 case OMPD_target_teams_distribute_simd: 7278 case OMPD_target_teams_distribute_parallel_for: 7279 case OMPD_target_teams_distribute_parallel_for_simd: 7280 case OMPD_teams_distribute_parallel_for: 7281 case OMPD_teams_distribute_parallel_for_simd: 7282 case OMPD_distribute_parallel_for: 7283 case OMPD_distribute_parallel_for_simd: 7284 case OMPD_task: 7285 case OMPD_taskloop: 7286 case OMPD_taskloop_simd: 7287 case OMPD_target_data: 7288 case OMPD_target_enter_data: 7289 case OMPD_target_exit_data: 7290 case OMPD_target_update: 7291 // Do not capture if-clause expressions. 7292 break; 7293 case OMPD_threadprivate: 7294 case OMPD_taskyield: 7295 case OMPD_barrier: 7296 case OMPD_taskwait: 7297 case OMPD_cancellation_point: 7298 case OMPD_flush: 7299 case OMPD_declare_reduction: 7300 case OMPD_declare_simd: 7301 case OMPD_declare_target: 7302 case OMPD_end_declare_target: 7303 case OMPD_teams: 7304 case OMPD_simd: 7305 case OMPD_for: 7306 case OMPD_for_simd: 7307 case OMPD_sections: 7308 case OMPD_section: 7309 case OMPD_single: 7310 case OMPD_master: 7311 case OMPD_critical: 7312 case OMPD_taskgroup: 7313 case OMPD_distribute: 7314 case OMPD_ordered: 7315 case OMPD_atomic: 7316 case OMPD_distribute_simd: 7317 case OMPD_teams_distribute: 7318 case OMPD_teams_distribute_simd: 7319 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 7320 case OMPD_unknown: 7321 llvm_unreachable("Unknown OpenMP directive"); 7322 } 7323 break; 7324 case OMPC_num_threads: 7325 switch (DKind) { 7326 case OMPD_target_parallel: 7327 CaptureRegion = OMPD_target; 7328 break; 7329 case OMPD_cancel: 7330 case OMPD_parallel: 7331 case OMPD_parallel_sections: 7332 case OMPD_parallel_for: 7333 case OMPD_parallel_for_simd: 7334 case OMPD_target: 7335 case OMPD_target_simd: 7336 case OMPD_target_parallel_for: 7337 case OMPD_target_parallel_for_simd: 7338 case OMPD_target_teams: 7339 case OMPD_target_teams_distribute: 7340 case OMPD_target_teams_distribute_simd: 7341 case OMPD_target_teams_distribute_parallel_for: 7342 case OMPD_target_teams_distribute_parallel_for_simd: 7343 case OMPD_teams_distribute_parallel_for: 7344 case OMPD_teams_distribute_parallel_for_simd: 7345 case OMPD_distribute_parallel_for: 7346 case OMPD_distribute_parallel_for_simd: 7347 case OMPD_task: 7348 case OMPD_taskloop: 7349 case OMPD_taskloop_simd: 7350 case OMPD_target_data: 7351 case OMPD_target_enter_data: 7352 case OMPD_target_exit_data: 7353 case OMPD_target_update: 7354 // Do not capture num_threads-clause expressions. 7355 break; 7356 case OMPD_threadprivate: 7357 case OMPD_taskyield: 7358 case OMPD_barrier: 7359 case OMPD_taskwait: 7360 case OMPD_cancellation_point: 7361 case OMPD_flush: 7362 case OMPD_declare_reduction: 7363 case OMPD_declare_simd: 7364 case OMPD_declare_target: 7365 case OMPD_end_declare_target: 7366 case OMPD_teams: 7367 case OMPD_simd: 7368 case OMPD_for: 7369 case OMPD_for_simd: 7370 case OMPD_sections: 7371 case OMPD_section: 7372 case OMPD_single: 7373 case OMPD_master: 7374 case OMPD_critical: 7375 case OMPD_taskgroup: 7376 case OMPD_distribute: 7377 case OMPD_ordered: 7378 case OMPD_atomic: 7379 case OMPD_distribute_simd: 7380 case OMPD_teams_distribute: 7381 case OMPD_teams_distribute_simd: 7382 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 7383 case OMPD_unknown: 7384 llvm_unreachable("Unknown OpenMP directive"); 7385 } 7386 break; 7387 case OMPC_num_teams: 7388 switch (DKind) { 7389 case OMPD_target_teams: 7390 CaptureRegion = OMPD_target; 7391 break; 7392 case OMPD_cancel: 7393 case OMPD_parallel: 7394 case OMPD_parallel_sections: 7395 case OMPD_parallel_for: 7396 case OMPD_parallel_for_simd: 7397 case OMPD_target: 7398 case OMPD_target_simd: 7399 case OMPD_target_parallel: 7400 case OMPD_target_parallel_for: 7401 case OMPD_target_parallel_for_simd: 7402 case OMPD_target_teams_distribute: 7403 case OMPD_target_teams_distribute_simd: 7404 case OMPD_target_teams_distribute_parallel_for: 7405 case OMPD_target_teams_distribute_parallel_for_simd: 7406 case OMPD_teams_distribute_parallel_for: 7407 case OMPD_teams_distribute_parallel_for_simd: 7408 case OMPD_distribute_parallel_for: 7409 case OMPD_distribute_parallel_for_simd: 7410 case OMPD_task: 7411 case OMPD_taskloop: 7412 case OMPD_taskloop_simd: 7413 case OMPD_target_data: 7414 case OMPD_target_enter_data: 7415 case OMPD_target_exit_data: 7416 case OMPD_target_update: 7417 case OMPD_teams: 7418 case OMPD_teams_distribute: 7419 case OMPD_teams_distribute_simd: 7420 // Do not capture num_teams-clause expressions. 7421 break; 7422 case OMPD_threadprivate: 7423 case OMPD_taskyield: 7424 case OMPD_barrier: 7425 case OMPD_taskwait: 7426 case OMPD_cancellation_point: 7427 case OMPD_flush: 7428 case OMPD_declare_reduction: 7429 case OMPD_declare_simd: 7430 case OMPD_declare_target: 7431 case OMPD_end_declare_target: 7432 case OMPD_simd: 7433 case OMPD_for: 7434 case OMPD_for_simd: 7435 case OMPD_sections: 7436 case OMPD_section: 7437 case OMPD_single: 7438 case OMPD_master: 7439 case OMPD_critical: 7440 case OMPD_taskgroup: 7441 case OMPD_distribute: 7442 case OMPD_ordered: 7443 case OMPD_atomic: 7444 case OMPD_distribute_simd: 7445 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 7446 case OMPD_unknown: 7447 llvm_unreachable("Unknown OpenMP directive"); 7448 } 7449 break; 7450 case OMPC_thread_limit: 7451 switch (DKind) { 7452 case OMPD_target_teams: 7453 CaptureRegion = OMPD_target; 7454 break; 7455 case OMPD_cancel: 7456 case OMPD_parallel: 7457 case OMPD_parallel_sections: 7458 case OMPD_parallel_for: 7459 case OMPD_parallel_for_simd: 7460 case OMPD_target: 7461 case OMPD_target_simd: 7462 case OMPD_target_parallel: 7463 case OMPD_target_parallel_for: 7464 case OMPD_target_parallel_for_simd: 7465 case OMPD_target_teams_distribute: 7466 case OMPD_target_teams_distribute_simd: 7467 case OMPD_target_teams_distribute_parallel_for: 7468 case OMPD_target_teams_distribute_parallel_for_simd: 7469 case OMPD_teams_distribute_parallel_for: 7470 case OMPD_teams_distribute_parallel_for_simd: 7471 case OMPD_distribute_parallel_for: 7472 case OMPD_distribute_parallel_for_simd: 7473 case OMPD_task: 7474 case OMPD_taskloop: 7475 case OMPD_taskloop_simd: 7476 case OMPD_target_data: 7477 case OMPD_target_enter_data: 7478 case OMPD_target_exit_data: 7479 case OMPD_target_update: 7480 case OMPD_teams: 7481 case OMPD_teams_distribute: 7482 case OMPD_teams_distribute_simd: 7483 // Do not capture thread_limit-clause expressions. 7484 break; 7485 case OMPD_threadprivate: 7486 case OMPD_taskyield: 7487 case OMPD_barrier: 7488 case OMPD_taskwait: 7489 case OMPD_cancellation_point: 7490 case OMPD_flush: 7491 case OMPD_declare_reduction: 7492 case OMPD_declare_simd: 7493 case OMPD_declare_target: 7494 case OMPD_end_declare_target: 7495 case OMPD_simd: 7496 case OMPD_for: 7497 case OMPD_for_simd: 7498 case OMPD_sections: 7499 case OMPD_section: 7500 case OMPD_single: 7501 case OMPD_master: 7502 case OMPD_critical: 7503 case OMPD_taskgroup: 7504 case OMPD_distribute: 7505 case OMPD_ordered: 7506 case OMPD_atomic: 7507 case OMPD_distribute_simd: 7508 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 7509 case OMPD_unknown: 7510 llvm_unreachable("Unknown OpenMP directive"); 7511 } 7512 break; 7513 case OMPC_schedule: 7514 case OMPC_dist_schedule: 7515 case OMPC_firstprivate: 7516 case OMPC_lastprivate: 7517 case OMPC_reduction: 7518 case OMPC_task_reduction: 7519 case OMPC_in_reduction: 7520 case OMPC_linear: 7521 case OMPC_default: 7522 case OMPC_proc_bind: 7523 case OMPC_final: 7524 case OMPC_safelen: 7525 case OMPC_simdlen: 7526 case OMPC_collapse: 7527 case OMPC_private: 7528 case OMPC_shared: 7529 case OMPC_aligned: 7530 case OMPC_copyin: 7531 case OMPC_copyprivate: 7532 case OMPC_ordered: 7533 case OMPC_nowait: 7534 case OMPC_untied: 7535 case OMPC_mergeable: 7536 case OMPC_threadprivate: 7537 case OMPC_flush: 7538 case OMPC_read: 7539 case OMPC_write: 7540 case OMPC_update: 7541 case OMPC_capture: 7542 case OMPC_seq_cst: 7543 case OMPC_depend: 7544 case OMPC_device: 7545 case OMPC_threads: 7546 case OMPC_simd: 7547 case OMPC_map: 7548 case OMPC_priority: 7549 case OMPC_grainsize: 7550 case OMPC_nogroup: 7551 case OMPC_num_tasks: 7552 case OMPC_hint: 7553 case OMPC_defaultmap: 7554 case OMPC_unknown: 7555 case OMPC_uniform: 7556 case OMPC_to: 7557 case OMPC_from: 7558 case OMPC_use_device_ptr: 7559 case OMPC_is_device_ptr: 7560 llvm_unreachable("Unexpected OpenMP clause."); 7561 } 7562 return CaptureRegion; 7563 } 7564 7565 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 7566 Expr *Condition, SourceLocation StartLoc, 7567 SourceLocation LParenLoc, 7568 SourceLocation NameModifierLoc, 7569 SourceLocation ColonLoc, 7570 SourceLocation EndLoc) { 7571 Expr *ValExpr = Condition; 7572 Stmt *HelperValStmt = nullptr; 7573 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 7574 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 7575 !Condition->isInstantiationDependent() && 7576 !Condition->containsUnexpandedParameterPack()) { 7577 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 7578 if (Val.isInvalid()) 7579 return nullptr; 7580 7581 ValExpr = MakeFullExpr(Val.get()).get(); 7582 7583 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7584 CaptureRegion = 7585 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 7586 if (CaptureRegion != OMPD_unknown) { 7587 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 7588 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 7589 HelperValStmt = buildPreInits(Context, Captures); 7590 } 7591 } 7592 7593 return new (Context) 7594 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 7595 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 7596 } 7597 7598 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 7599 SourceLocation StartLoc, 7600 SourceLocation LParenLoc, 7601 SourceLocation EndLoc) { 7602 Expr *ValExpr = Condition; 7603 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 7604 !Condition->isInstantiationDependent() && 7605 !Condition->containsUnexpandedParameterPack()) { 7606 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 7607 if (Val.isInvalid()) 7608 return nullptr; 7609 7610 ValExpr = MakeFullExpr(Val.get()).get(); 7611 } 7612 7613 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 7614 } 7615 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 7616 Expr *Op) { 7617 if (!Op) 7618 return ExprError(); 7619 7620 class IntConvertDiagnoser : public ICEConvertDiagnoser { 7621 public: 7622 IntConvertDiagnoser() 7623 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 7624 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 7625 QualType T) override { 7626 return S.Diag(Loc, diag::err_omp_not_integral) << T; 7627 } 7628 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 7629 QualType T) override { 7630 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 7631 } 7632 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 7633 QualType T, 7634 QualType ConvTy) override { 7635 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 7636 } 7637 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 7638 QualType ConvTy) override { 7639 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 7640 << ConvTy->isEnumeralType() << ConvTy; 7641 } 7642 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 7643 QualType T) override { 7644 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 7645 } 7646 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 7647 QualType ConvTy) override { 7648 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 7649 << ConvTy->isEnumeralType() << ConvTy; 7650 } 7651 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 7652 QualType) override { 7653 llvm_unreachable("conversion functions are permitted"); 7654 } 7655 } ConvertDiagnoser; 7656 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 7657 } 7658 7659 static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 7660 OpenMPClauseKind CKind, 7661 bool StrictlyPositive) { 7662 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 7663 !ValExpr->isInstantiationDependent()) { 7664 SourceLocation Loc = ValExpr->getExprLoc(); 7665 ExprResult Value = 7666 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 7667 if (Value.isInvalid()) 7668 return false; 7669 7670 ValExpr = Value.get(); 7671 // The expression must evaluate to a non-negative integer value. 7672 llvm::APSInt Result; 7673 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 7674 Result.isSigned() && 7675 !((!StrictlyPositive && Result.isNonNegative()) || 7676 (StrictlyPositive && Result.isStrictlyPositive()))) { 7677 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 7678 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 7679 << ValExpr->getSourceRange(); 7680 return false; 7681 } 7682 } 7683 return true; 7684 } 7685 7686 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 7687 SourceLocation StartLoc, 7688 SourceLocation LParenLoc, 7689 SourceLocation EndLoc) { 7690 Expr *ValExpr = NumThreads; 7691 Stmt *HelperValStmt = nullptr; 7692 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 7693 7694 // OpenMP [2.5, Restrictions] 7695 // The num_threads expression must evaluate to a positive integer value. 7696 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 7697 /*StrictlyPositive=*/true)) 7698 return nullptr; 7699 7700 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7701 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 7702 if (CaptureRegion != OMPD_unknown) { 7703 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 7704 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 7705 HelperValStmt = buildPreInits(Context, Captures); 7706 } 7707 7708 return new (Context) OMPNumThreadsClause( 7709 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 7710 } 7711 7712 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 7713 OpenMPClauseKind CKind, 7714 bool StrictlyPositive) { 7715 if (!E) 7716 return ExprError(); 7717 if (E->isValueDependent() || E->isTypeDependent() || 7718 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 7719 return E; 7720 llvm::APSInt Result; 7721 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 7722 if (ICE.isInvalid()) 7723 return ExprError(); 7724 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 7725 (!StrictlyPositive && !Result.isNonNegative())) { 7726 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 7727 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 7728 << E->getSourceRange(); 7729 return ExprError(); 7730 } 7731 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 7732 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 7733 << E->getSourceRange(); 7734 return ExprError(); 7735 } 7736 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 7737 DSAStack->setAssociatedLoops(Result.getExtValue()); 7738 else if (CKind == OMPC_ordered) 7739 DSAStack->setAssociatedLoops(Result.getExtValue()); 7740 return ICE; 7741 } 7742 7743 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 7744 SourceLocation LParenLoc, 7745 SourceLocation EndLoc) { 7746 // OpenMP [2.8.1, simd construct, Description] 7747 // The parameter of the safelen clause must be a constant 7748 // positive integer expression. 7749 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 7750 if (Safelen.isInvalid()) 7751 return nullptr; 7752 return new (Context) 7753 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 7754 } 7755 7756 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 7757 SourceLocation LParenLoc, 7758 SourceLocation EndLoc) { 7759 // OpenMP [2.8.1, simd construct, Description] 7760 // The parameter of the simdlen clause must be a constant 7761 // positive integer expression. 7762 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 7763 if (Simdlen.isInvalid()) 7764 return nullptr; 7765 return new (Context) 7766 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 7767 } 7768 7769 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 7770 SourceLocation StartLoc, 7771 SourceLocation LParenLoc, 7772 SourceLocation EndLoc) { 7773 // OpenMP [2.7.1, loop construct, Description] 7774 // OpenMP [2.8.1, simd construct, Description] 7775 // OpenMP [2.9.6, distribute construct, Description] 7776 // The parameter of the collapse clause must be a constant 7777 // positive integer expression. 7778 ExprResult NumForLoopsResult = 7779 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 7780 if (NumForLoopsResult.isInvalid()) 7781 return nullptr; 7782 return new (Context) 7783 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 7784 } 7785 7786 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 7787 SourceLocation EndLoc, 7788 SourceLocation LParenLoc, 7789 Expr *NumForLoops) { 7790 // OpenMP [2.7.1, loop construct, Description] 7791 // OpenMP [2.8.1, simd construct, Description] 7792 // OpenMP [2.9.6, distribute construct, Description] 7793 // The parameter of the ordered clause must be a constant 7794 // positive integer expression if any. 7795 if (NumForLoops && LParenLoc.isValid()) { 7796 ExprResult NumForLoopsResult = 7797 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 7798 if (NumForLoopsResult.isInvalid()) 7799 return nullptr; 7800 NumForLoops = NumForLoopsResult.get(); 7801 } else 7802 NumForLoops = nullptr; 7803 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops); 7804 return new (Context) 7805 OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc); 7806 } 7807 7808 OMPClause *Sema::ActOnOpenMPSimpleClause( 7809 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 7810 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 7811 OMPClause *Res = nullptr; 7812 switch (Kind) { 7813 case OMPC_default: 7814 Res = 7815 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 7816 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 7817 break; 7818 case OMPC_proc_bind: 7819 Res = ActOnOpenMPProcBindClause( 7820 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 7821 LParenLoc, EndLoc); 7822 break; 7823 case OMPC_if: 7824 case OMPC_final: 7825 case OMPC_num_threads: 7826 case OMPC_safelen: 7827 case OMPC_simdlen: 7828 case OMPC_collapse: 7829 case OMPC_schedule: 7830 case OMPC_private: 7831 case OMPC_firstprivate: 7832 case OMPC_lastprivate: 7833 case OMPC_shared: 7834 case OMPC_reduction: 7835 case OMPC_task_reduction: 7836 case OMPC_in_reduction: 7837 case OMPC_linear: 7838 case OMPC_aligned: 7839 case OMPC_copyin: 7840 case OMPC_copyprivate: 7841 case OMPC_ordered: 7842 case OMPC_nowait: 7843 case OMPC_untied: 7844 case OMPC_mergeable: 7845 case OMPC_threadprivate: 7846 case OMPC_flush: 7847 case OMPC_read: 7848 case OMPC_write: 7849 case OMPC_update: 7850 case OMPC_capture: 7851 case OMPC_seq_cst: 7852 case OMPC_depend: 7853 case OMPC_device: 7854 case OMPC_threads: 7855 case OMPC_simd: 7856 case OMPC_map: 7857 case OMPC_num_teams: 7858 case OMPC_thread_limit: 7859 case OMPC_priority: 7860 case OMPC_grainsize: 7861 case OMPC_nogroup: 7862 case OMPC_num_tasks: 7863 case OMPC_hint: 7864 case OMPC_dist_schedule: 7865 case OMPC_defaultmap: 7866 case OMPC_unknown: 7867 case OMPC_uniform: 7868 case OMPC_to: 7869 case OMPC_from: 7870 case OMPC_use_device_ptr: 7871 case OMPC_is_device_ptr: 7872 llvm_unreachable("Clause is not allowed."); 7873 } 7874 return Res; 7875 } 7876 7877 static std::string 7878 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 7879 ArrayRef<unsigned> Exclude = llvm::None) { 7880 std::string Values; 7881 unsigned Bound = Last >= 2 ? Last - 2 : 0; 7882 unsigned Skipped = Exclude.size(); 7883 auto S = Exclude.begin(), E = Exclude.end(); 7884 for (unsigned i = First; i < Last; ++i) { 7885 if (std::find(S, E, i) != E) { 7886 --Skipped; 7887 continue; 7888 } 7889 Values += "'"; 7890 Values += getOpenMPSimpleClauseTypeName(K, i); 7891 Values += "'"; 7892 if (i == Bound - Skipped) 7893 Values += " or "; 7894 else if (i != Bound + 1 - Skipped) 7895 Values += ", "; 7896 } 7897 return Values; 7898 } 7899 7900 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 7901 SourceLocation KindKwLoc, 7902 SourceLocation StartLoc, 7903 SourceLocation LParenLoc, 7904 SourceLocation EndLoc) { 7905 if (Kind == OMPC_DEFAULT_unknown) { 7906 static_assert(OMPC_DEFAULT_unknown > 0, 7907 "OMPC_DEFAULT_unknown not greater than 0"); 7908 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 7909 << getListOfPossibleValues(OMPC_default, /*First=*/0, 7910 /*Last=*/OMPC_DEFAULT_unknown) 7911 << getOpenMPClauseName(OMPC_default); 7912 return nullptr; 7913 } 7914 switch (Kind) { 7915 case OMPC_DEFAULT_none: 7916 DSAStack->setDefaultDSANone(KindKwLoc); 7917 break; 7918 case OMPC_DEFAULT_shared: 7919 DSAStack->setDefaultDSAShared(KindKwLoc); 7920 break; 7921 case OMPC_DEFAULT_unknown: 7922 llvm_unreachable("Clause kind is not allowed."); 7923 break; 7924 } 7925 return new (Context) 7926 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 7927 } 7928 7929 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 7930 SourceLocation KindKwLoc, 7931 SourceLocation StartLoc, 7932 SourceLocation LParenLoc, 7933 SourceLocation EndLoc) { 7934 if (Kind == OMPC_PROC_BIND_unknown) { 7935 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 7936 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 7937 /*Last=*/OMPC_PROC_BIND_unknown) 7938 << getOpenMPClauseName(OMPC_proc_bind); 7939 return nullptr; 7940 } 7941 return new (Context) 7942 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 7943 } 7944 7945 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 7946 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 7947 SourceLocation StartLoc, SourceLocation LParenLoc, 7948 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 7949 SourceLocation EndLoc) { 7950 OMPClause *Res = nullptr; 7951 switch (Kind) { 7952 case OMPC_schedule: 7953 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 7954 assert(Argument.size() == NumberOfElements && 7955 ArgumentLoc.size() == NumberOfElements); 7956 Res = ActOnOpenMPScheduleClause( 7957 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 7958 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 7959 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 7960 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 7961 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 7962 break; 7963 case OMPC_if: 7964 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 7965 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 7966 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 7967 DelimLoc, EndLoc); 7968 break; 7969 case OMPC_dist_schedule: 7970 Res = ActOnOpenMPDistScheduleClause( 7971 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 7972 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 7973 break; 7974 case OMPC_defaultmap: 7975 enum { Modifier, DefaultmapKind }; 7976 Res = ActOnOpenMPDefaultmapClause( 7977 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 7978 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 7979 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 7980 EndLoc); 7981 break; 7982 case OMPC_final: 7983 case OMPC_num_threads: 7984 case OMPC_safelen: 7985 case OMPC_simdlen: 7986 case OMPC_collapse: 7987 case OMPC_default: 7988 case OMPC_proc_bind: 7989 case OMPC_private: 7990 case OMPC_firstprivate: 7991 case OMPC_lastprivate: 7992 case OMPC_shared: 7993 case OMPC_reduction: 7994 case OMPC_task_reduction: 7995 case OMPC_in_reduction: 7996 case OMPC_linear: 7997 case OMPC_aligned: 7998 case OMPC_copyin: 7999 case OMPC_copyprivate: 8000 case OMPC_ordered: 8001 case OMPC_nowait: 8002 case OMPC_untied: 8003 case OMPC_mergeable: 8004 case OMPC_threadprivate: 8005 case OMPC_flush: 8006 case OMPC_read: 8007 case OMPC_write: 8008 case OMPC_update: 8009 case OMPC_capture: 8010 case OMPC_seq_cst: 8011 case OMPC_depend: 8012 case OMPC_device: 8013 case OMPC_threads: 8014 case OMPC_simd: 8015 case OMPC_map: 8016 case OMPC_num_teams: 8017 case OMPC_thread_limit: 8018 case OMPC_priority: 8019 case OMPC_grainsize: 8020 case OMPC_nogroup: 8021 case OMPC_num_tasks: 8022 case OMPC_hint: 8023 case OMPC_unknown: 8024 case OMPC_uniform: 8025 case OMPC_to: 8026 case OMPC_from: 8027 case OMPC_use_device_ptr: 8028 case OMPC_is_device_ptr: 8029 llvm_unreachable("Clause is not allowed."); 8030 } 8031 return Res; 8032 } 8033 8034 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 8035 OpenMPScheduleClauseModifier M2, 8036 SourceLocation M1Loc, SourceLocation M2Loc) { 8037 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 8038 SmallVector<unsigned, 2> Excluded; 8039 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 8040 Excluded.push_back(M2); 8041 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 8042 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 8043 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 8044 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 8045 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 8046 << getListOfPossibleValues(OMPC_schedule, 8047 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 8048 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 8049 Excluded) 8050 << getOpenMPClauseName(OMPC_schedule); 8051 return true; 8052 } 8053 return false; 8054 } 8055 8056 OMPClause *Sema::ActOnOpenMPScheduleClause( 8057 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 8058 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 8059 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 8060 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 8061 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 8062 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 8063 return nullptr; 8064 // OpenMP, 2.7.1, Loop Construct, Restrictions 8065 // Either the monotonic modifier or the nonmonotonic modifier can be specified 8066 // but not both. 8067 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 8068 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 8069 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 8070 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 8071 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 8072 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 8073 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 8074 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 8075 return nullptr; 8076 } 8077 if (Kind == OMPC_SCHEDULE_unknown) { 8078 std::string Values; 8079 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 8080 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 8081 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 8082 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 8083 Exclude); 8084 } else { 8085 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 8086 /*Last=*/OMPC_SCHEDULE_unknown); 8087 } 8088 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 8089 << Values << getOpenMPClauseName(OMPC_schedule); 8090 return nullptr; 8091 } 8092 // OpenMP, 2.7.1, Loop Construct, Restrictions 8093 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 8094 // schedule(guided). 8095 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 8096 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 8097 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 8098 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 8099 diag::err_omp_schedule_nonmonotonic_static); 8100 return nullptr; 8101 } 8102 Expr *ValExpr = ChunkSize; 8103 Stmt *HelperValStmt = nullptr; 8104 if (ChunkSize) { 8105 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 8106 !ChunkSize->isInstantiationDependent() && 8107 !ChunkSize->containsUnexpandedParameterPack()) { 8108 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 8109 ExprResult Val = 8110 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 8111 if (Val.isInvalid()) 8112 return nullptr; 8113 8114 ValExpr = Val.get(); 8115 8116 // OpenMP [2.7.1, Restrictions] 8117 // chunk_size must be a loop invariant integer expression with a positive 8118 // value. 8119 llvm::APSInt Result; 8120 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 8121 if (Result.isSigned() && !Result.isStrictlyPositive()) { 8122 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 8123 << "schedule" << 1 << ChunkSize->getSourceRange(); 8124 return nullptr; 8125 } 8126 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) && 8127 !CurContext->isDependentContext()) { 8128 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 8129 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 8130 HelperValStmt = buildPreInits(Context, Captures); 8131 } 8132 } 8133 } 8134 8135 return new (Context) 8136 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 8137 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 8138 } 8139 8140 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 8141 SourceLocation StartLoc, 8142 SourceLocation EndLoc) { 8143 OMPClause *Res = nullptr; 8144 switch (Kind) { 8145 case OMPC_ordered: 8146 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 8147 break; 8148 case OMPC_nowait: 8149 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 8150 break; 8151 case OMPC_untied: 8152 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 8153 break; 8154 case OMPC_mergeable: 8155 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 8156 break; 8157 case OMPC_read: 8158 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 8159 break; 8160 case OMPC_write: 8161 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 8162 break; 8163 case OMPC_update: 8164 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 8165 break; 8166 case OMPC_capture: 8167 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 8168 break; 8169 case OMPC_seq_cst: 8170 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 8171 break; 8172 case OMPC_threads: 8173 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 8174 break; 8175 case OMPC_simd: 8176 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 8177 break; 8178 case OMPC_nogroup: 8179 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 8180 break; 8181 case OMPC_if: 8182 case OMPC_final: 8183 case OMPC_num_threads: 8184 case OMPC_safelen: 8185 case OMPC_simdlen: 8186 case OMPC_collapse: 8187 case OMPC_schedule: 8188 case OMPC_private: 8189 case OMPC_firstprivate: 8190 case OMPC_lastprivate: 8191 case OMPC_shared: 8192 case OMPC_reduction: 8193 case OMPC_task_reduction: 8194 case OMPC_in_reduction: 8195 case OMPC_linear: 8196 case OMPC_aligned: 8197 case OMPC_copyin: 8198 case OMPC_copyprivate: 8199 case OMPC_default: 8200 case OMPC_proc_bind: 8201 case OMPC_threadprivate: 8202 case OMPC_flush: 8203 case OMPC_depend: 8204 case OMPC_device: 8205 case OMPC_map: 8206 case OMPC_num_teams: 8207 case OMPC_thread_limit: 8208 case OMPC_priority: 8209 case OMPC_grainsize: 8210 case OMPC_num_tasks: 8211 case OMPC_hint: 8212 case OMPC_dist_schedule: 8213 case OMPC_defaultmap: 8214 case OMPC_unknown: 8215 case OMPC_uniform: 8216 case OMPC_to: 8217 case OMPC_from: 8218 case OMPC_use_device_ptr: 8219 case OMPC_is_device_ptr: 8220 llvm_unreachable("Clause is not allowed."); 8221 } 8222 return Res; 8223 } 8224 8225 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 8226 SourceLocation EndLoc) { 8227 DSAStack->setNowaitRegion(); 8228 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 8229 } 8230 8231 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 8232 SourceLocation EndLoc) { 8233 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 8234 } 8235 8236 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 8237 SourceLocation EndLoc) { 8238 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 8239 } 8240 8241 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 8242 SourceLocation EndLoc) { 8243 return new (Context) OMPReadClause(StartLoc, EndLoc); 8244 } 8245 8246 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 8247 SourceLocation EndLoc) { 8248 return new (Context) OMPWriteClause(StartLoc, EndLoc); 8249 } 8250 8251 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 8252 SourceLocation EndLoc) { 8253 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 8254 } 8255 8256 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 8257 SourceLocation EndLoc) { 8258 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 8259 } 8260 8261 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 8262 SourceLocation EndLoc) { 8263 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 8264 } 8265 8266 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 8267 SourceLocation EndLoc) { 8268 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 8269 } 8270 8271 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 8272 SourceLocation EndLoc) { 8273 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 8274 } 8275 8276 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 8277 SourceLocation EndLoc) { 8278 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 8279 } 8280 8281 OMPClause *Sema::ActOnOpenMPVarListClause( 8282 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 8283 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 8284 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 8285 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, 8286 OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, 8287 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 8288 SourceLocation DepLinMapLoc) { 8289 OMPClause *Res = nullptr; 8290 switch (Kind) { 8291 case OMPC_private: 8292 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8293 break; 8294 case OMPC_firstprivate: 8295 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8296 break; 8297 case OMPC_lastprivate: 8298 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8299 break; 8300 case OMPC_shared: 8301 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 8302 break; 8303 case OMPC_reduction: 8304 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 8305 EndLoc, ReductionIdScopeSpec, ReductionId); 8306 break; 8307 case OMPC_task_reduction: 8308 Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 8309 EndLoc, ReductionIdScopeSpec, 8310 ReductionId); 8311 break; 8312 case OMPC_in_reduction: 8313 Res = 8314 ActOnOpenMPInReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 8315 EndLoc, ReductionIdScopeSpec, ReductionId); 8316 break; 8317 case OMPC_linear: 8318 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 8319 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 8320 break; 8321 case OMPC_aligned: 8322 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 8323 ColonLoc, EndLoc); 8324 break; 8325 case OMPC_copyin: 8326 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 8327 break; 8328 case OMPC_copyprivate: 8329 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8330 break; 8331 case OMPC_flush: 8332 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 8333 break; 8334 case OMPC_depend: 8335 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 8336 StartLoc, LParenLoc, EndLoc); 8337 break; 8338 case OMPC_map: 8339 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, 8340 DepLinMapLoc, ColonLoc, VarList, StartLoc, 8341 LParenLoc, EndLoc); 8342 break; 8343 case OMPC_to: 8344 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc); 8345 break; 8346 case OMPC_from: 8347 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc); 8348 break; 8349 case OMPC_use_device_ptr: 8350 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); 8351 break; 8352 case OMPC_is_device_ptr: 8353 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); 8354 break; 8355 case OMPC_if: 8356 case OMPC_final: 8357 case OMPC_num_threads: 8358 case OMPC_safelen: 8359 case OMPC_simdlen: 8360 case OMPC_collapse: 8361 case OMPC_default: 8362 case OMPC_proc_bind: 8363 case OMPC_schedule: 8364 case OMPC_ordered: 8365 case OMPC_nowait: 8366 case OMPC_untied: 8367 case OMPC_mergeable: 8368 case OMPC_threadprivate: 8369 case OMPC_read: 8370 case OMPC_write: 8371 case OMPC_update: 8372 case OMPC_capture: 8373 case OMPC_seq_cst: 8374 case OMPC_device: 8375 case OMPC_threads: 8376 case OMPC_simd: 8377 case OMPC_num_teams: 8378 case OMPC_thread_limit: 8379 case OMPC_priority: 8380 case OMPC_grainsize: 8381 case OMPC_nogroup: 8382 case OMPC_num_tasks: 8383 case OMPC_hint: 8384 case OMPC_dist_schedule: 8385 case OMPC_defaultmap: 8386 case OMPC_unknown: 8387 case OMPC_uniform: 8388 llvm_unreachable("Clause is not allowed."); 8389 } 8390 return Res; 8391 } 8392 8393 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 8394 ExprObjectKind OK, SourceLocation Loc) { 8395 ExprResult Res = BuildDeclRefExpr( 8396 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 8397 if (!Res.isUsable()) 8398 return ExprError(); 8399 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 8400 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 8401 if (!Res.isUsable()) 8402 return ExprError(); 8403 } 8404 if (VK != VK_LValue && Res.get()->isGLValue()) { 8405 Res = DefaultLvalueConversion(Res.get()); 8406 if (!Res.isUsable()) 8407 return ExprError(); 8408 } 8409 return Res; 8410 } 8411 8412 static std::pair<ValueDecl *, bool> 8413 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 8414 SourceRange &ERange, bool AllowArraySection = false) { 8415 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 8416 RefExpr->containsUnexpandedParameterPack()) 8417 return std::make_pair(nullptr, true); 8418 8419 // OpenMP [3.1, C/C++] 8420 // A list item is a variable name. 8421 // OpenMP [2.9.3.3, Restrictions, p.1] 8422 // A variable that is part of another variable (as an array or 8423 // structure element) cannot appear in a private clause. 8424 RefExpr = RefExpr->IgnoreParens(); 8425 enum { 8426 NoArrayExpr = -1, 8427 ArraySubscript = 0, 8428 OMPArraySection = 1 8429 } IsArrayExpr = NoArrayExpr; 8430 if (AllowArraySection) { 8431 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 8432 auto *Base = ASE->getBase()->IgnoreParenImpCasts(); 8433 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 8434 Base = TempASE->getBase()->IgnoreParenImpCasts(); 8435 RefExpr = Base; 8436 IsArrayExpr = ArraySubscript; 8437 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 8438 auto *Base = OASE->getBase()->IgnoreParenImpCasts(); 8439 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 8440 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 8441 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 8442 Base = TempASE->getBase()->IgnoreParenImpCasts(); 8443 RefExpr = Base; 8444 IsArrayExpr = OMPArraySection; 8445 } 8446 } 8447 ELoc = RefExpr->getExprLoc(); 8448 ERange = RefExpr->getSourceRange(); 8449 RefExpr = RefExpr->IgnoreParenImpCasts(); 8450 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 8451 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 8452 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 8453 (S.getCurrentThisType().isNull() || !ME || 8454 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 8455 !isa<FieldDecl>(ME->getMemberDecl()))) { 8456 if (IsArrayExpr != NoArrayExpr) 8457 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 8458 << ERange; 8459 else { 8460 S.Diag(ELoc, 8461 AllowArraySection 8462 ? diag::err_omp_expected_var_name_member_expr_or_array_item 8463 : diag::err_omp_expected_var_name_member_expr) 8464 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 8465 } 8466 return std::make_pair(nullptr, false); 8467 } 8468 return std::make_pair( 8469 getCanonicalDecl(DE ? DE->getDecl() : ME->getMemberDecl()), false); 8470 } 8471 8472 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 8473 SourceLocation StartLoc, 8474 SourceLocation LParenLoc, 8475 SourceLocation EndLoc) { 8476 SmallVector<Expr *, 8> Vars; 8477 SmallVector<Expr *, 8> PrivateCopies; 8478 for (auto &RefExpr : VarList) { 8479 assert(RefExpr && "NULL expr in OpenMP private clause."); 8480 SourceLocation ELoc; 8481 SourceRange ERange; 8482 Expr *SimpleRefExpr = RefExpr; 8483 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8484 if (Res.second) { 8485 // It will be analyzed later. 8486 Vars.push_back(RefExpr); 8487 PrivateCopies.push_back(nullptr); 8488 } 8489 ValueDecl *D = Res.first; 8490 if (!D) 8491 continue; 8492 8493 QualType Type = D->getType(); 8494 auto *VD = dyn_cast<VarDecl>(D); 8495 8496 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 8497 // A variable that appears in a private clause must not have an incomplete 8498 // type or a reference type. 8499 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 8500 continue; 8501 Type = Type.getNonReferenceType(); 8502 8503 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8504 // in a Construct] 8505 // Variables with the predetermined data-sharing attributes may not be 8506 // listed in data-sharing attributes clauses, except for the cases 8507 // listed below. For these exceptions only, listing a predetermined 8508 // variable in a data-sharing attribute clause is allowed and overrides 8509 // the variable's predetermined data-sharing attributes. 8510 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8511 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 8512 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 8513 << getOpenMPClauseName(OMPC_private); 8514 ReportOriginalDSA(*this, DSAStack, D, DVar); 8515 continue; 8516 } 8517 8518 auto CurrDir = DSAStack->getCurrentDirective(); 8519 // Variably modified types are not supported for tasks. 8520 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 8521 isOpenMPTaskingDirective(CurrDir)) { 8522 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 8523 << getOpenMPClauseName(OMPC_private) << Type 8524 << getOpenMPDirectiveName(CurrDir); 8525 bool IsDecl = 8526 !VD || 8527 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8528 Diag(D->getLocation(), 8529 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8530 << D; 8531 continue; 8532 } 8533 8534 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 8535 // A list item cannot appear in both a map clause and a data-sharing 8536 // attribute clause on the same construct 8537 if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel || 8538 CurrDir == OMPD_target_teams || 8539 CurrDir == OMPD_target_teams_distribute || 8540 CurrDir == OMPD_target_teams_distribute_parallel_for || 8541 CurrDir == OMPD_target_teams_distribute_parallel_for_simd || 8542 CurrDir == OMPD_target_teams_distribute_simd || 8543 CurrDir == OMPD_target_parallel_for_simd || 8544 CurrDir == OMPD_target_parallel_for) { 8545 OpenMPClauseKind ConflictKind; 8546 if (DSAStack->checkMappableExprComponentListsForDecl( 8547 VD, /*CurrentRegionOnly=*/true, 8548 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 8549 OpenMPClauseKind WhereFoundClauseKind) -> bool { 8550 ConflictKind = WhereFoundClauseKind; 8551 return true; 8552 })) { 8553 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 8554 << getOpenMPClauseName(OMPC_private) 8555 << getOpenMPClauseName(ConflictKind) 8556 << getOpenMPDirectiveName(CurrDir); 8557 ReportOriginalDSA(*this, DSAStack, D, DVar); 8558 continue; 8559 } 8560 } 8561 8562 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 8563 // A variable of class type (or array thereof) that appears in a private 8564 // clause requires an accessible, unambiguous default constructor for the 8565 // class type. 8566 // Generate helper private variable and initialize it with the default 8567 // value. The address of the original variable is replaced by the address of 8568 // the new private variable in CodeGen. This new variable is not added to 8569 // IdResolver, so the code in the OpenMP region uses original variable for 8570 // proper diagnostics. 8571 Type = Type.getUnqualifiedType(); 8572 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 8573 D->hasAttrs() ? &D->getAttrs() : nullptr); 8574 ActOnUninitializedDecl(VDPrivate); 8575 if (VDPrivate->isInvalidDecl()) 8576 continue; 8577 auto VDPrivateRefExpr = buildDeclRefExpr( 8578 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 8579 8580 DeclRefExpr *Ref = nullptr; 8581 if (!VD && !CurContext->isDependentContext()) 8582 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 8583 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 8584 Vars.push_back((VD || CurContext->isDependentContext()) 8585 ? RefExpr->IgnoreParens() 8586 : Ref); 8587 PrivateCopies.push_back(VDPrivateRefExpr); 8588 } 8589 8590 if (Vars.empty()) 8591 return nullptr; 8592 8593 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 8594 PrivateCopies); 8595 } 8596 8597 namespace { 8598 class DiagsUninitializedSeveretyRAII { 8599 private: 8600 DiagnosticsEngine &Diags; 8601 SourceLocation SavedLoc; 8602 bool IsIgnored; 8603 8604 public: 8605 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 8606 bool IsIgnored) 8607 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 8608 if (!IsIgnored) { 8609 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 8610 /*Map*/ diag::Severity::Ignored, Loc); 8611 } 8612 } 8613 ~DiagsUninitializedSeveretyRAII() { 8614 if (!IsIgnored) 8615 Diags.popMappings(SavedLoc); 8616 } 8617 }; 8618 } 8619 8620 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 8621 SourceLocation StartLoc, 8622 SourceLocation LParenLoc, 8623 SourceLocation EndLoc) { 8624 SmallVector<Expr *, 8> Vars; 8625 SmallVector<Expr *, 8> PrivateCopies; 8626 SmallVector<Expr *, 8> Inits; 8627 SmallVector<Decl *, 4> ExprCaptures; 8628 bool IsImplicitClause = 8629 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 8630 auto ImplicitClauseLoc = DSAStack->getConstructLoc(); 8631 8632 for (auto &RefExpr : VarList) { 8633 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 8634 SourceLocation ELoc; 8635 SourceRange ERange; 8636 Expr *SimpleRefExpr = RefExpr; 8637 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8638 if (Res.second) { 8639 // It will be analyzed later. 8640 Vars.push_back(RefExpr); 8641 PrivateCopies.push_back(nullptr); 8642 Inits.push_back(nullptr); 8643 } 8644 ValueDecl *D = Res.first; 8645 if (!D) 8646 continue; 8647 8648 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 8649 QualType Type = D->getType(); 8650 auto *VD = dyn_cast<VarDecl>(D); 8651 8652 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 8653 // A variable that appears in a private clause must not have an incomplete 8654 // type or a reference type. 8655 if (RequireCompleteType(ELoc, Type, 8656 diag::err_omp_firstprivate_incomplete_type)) 8657 continue; 8658 Type = Type.getNonReferenceType(); 8659 8660 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 8661 // A variable of class type (or array thereof) that appears in a private 8662 // clause requires an accessible, unambiguous copy constructor for the 8663 // class type. 8664 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 8665 8666 // If an implicit firstprivate variable found it was checked already. 8667 DSAStackTy::DSAVarData TopDVar; 8668 if (!IsImplicitClause) { 8669 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8670 TopDVar = DVar; 8671 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 8672 bool IsConstant = ElemType.isConstant(Context); 8673 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 8674 // A list item that specifies a given variable may not appear in more 8675 // than one clause on the same directive, except that a variable may be 8676 // specified in both firstprivate and lastprivate clauses. 8677 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 8678 // A list item may appear in a firstprivate or lastprivate clause but not 8679 // both. 8680 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 8681 (CurrDir == OMPD_distribute || DVar.CKind != OMPC_lastprivate) && 8682 DVar.RefExpr) { 8683 Diag(ELoc, diag::err_omp_wrong_dsa) 8684 << getOpenMPClauseName(DVar.CKind) 8685 << getOpenMPClauseName(OMPC_firstprivate); 8686 ReportOriginalDSA(*this, DSAStack, D, DVar); 8687 continue; 8688 } 8689 8690 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8691 // in a Construct] 8692 // Variables with the predetermined data-sharing attributes may not be 8693 // listed in data-sharing attributes clauses, except for the cases 8694 // listed below. For these exceptions only, listing a predetermined 8695 // variable in a data-sharing attribute clause is allowed and overrides 8696 // the variable's predetermined data-sharing attributes. 8697 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8698 // in a Construct, C/C++, p.2] 8699 // Variables with const-qualified type having no mutable member may be 8700 // listed in a firstprivate clause, even if they are static data members. 8701 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 8702 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 8703 Diag(ELoc, diag::err_omp_wrong_dsa) 8704 << getOpenMPClauseName(DVar.CKind) 8705 << getOpenMPClauseName(OMPC_firstprivate); 8706 ReportOriginalDSA(*this, DSAStack, D, DVar); 8707 continue; 8708 } 8709 8710 // OpenMP [2.9.3.4, Restrictions, p.2] 8711 // A list item that is private within a parallel region must not appear 8712 // in a firstprivate clause on a worksharing construct if any of the 8713 // worksharing regions arising from the worksharing construct ever bind 8714 // to any of the parallel regions arising from the parallel construct. 8715 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 8716 // A list item that is private within a teams region must not appear in a 8717 // firstprivate clause on a distribute construct if any of the distribute 8718 // regions arising from the distribute construct ever bind to any of the 8719 // teams regions arising from the teams construct. 8720 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 8721 // A list item that appears in a reduction clause of a teams construct 8722 // must not appear in a firstprivate clause on a distribute construct if 8723 // any of the distribute regions arising from the distribute construct 8724 // ever bind to any of the teams regions arising from the teams construct. 8725 if ((isOpenMPWorksharingDirective(CurrDir) || 8726 isOpenMPDistributeDirective(CurrDir)) && 8727 !isOpenMPParallelDirective(CurrDir) && 8728 !isOpenMPTeamsDirective(CurrDir)) { 8729 DVar = DSAStack->getImplicitDSA(D, true); 8730 if (DVar.CKind != OMPC_shared && 8731 (isOpenMPParallelDirective(DVar.DKind) || 8732 isOpenMPTeamsDirective(DVar.DKind) || 8733 DVar.DKind == OMPD_unknown)) { 8734 Diag(ELoc, diag::err_omp_required_access) 8735 << getOpenMPClauseName(OMPC_firstprivate) 8736 << getOpenMPClauseName(OMPC_shared); 8737 ReportOriginalDSA(*this, DSAStack, D, DVar); 8738 continue; 8739 } 8740 } 8741 // OpenMP [2.9.3.4, Restrictions, p.3] 8742 // A list item that appears in a reduction clause of a parallel construct 8743 // must not appear in a firstprivate clause on a worksharing or task 8744 // construct if any of the worksharing or task regions arising from the 8745 // worksharing or task construct ever bind to any of the parallel regions 8746 // arising from the parallel construct. 8747 // OpenMP [2.9.3.4, Restrictions, p.4] 8748 // A list item that appears in a reduction clause in worksharing 8749 // construct must not appear in a firstprivate clause in a task construct 8750 // encountered during execution of any of the worksharing regions arising 8751 // from the worksharing construct. 8752 if (isOpenMPTaskingDirective(CurrDir)) { 8753 DVar = DSAStack->hasInnermostDSA( 8754 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 8755 [](OpenMPDirectiveKind K) -> bool { 8756 return isOpenMPParallelDirective(K) || 8757 isOpenMPWorksharingDirective(K) || 8758 isOpenMPTeamsDirective(K); 8759 }, 8760 /*FromParent=*/true); 8761 if (DVar.CKind == OMPC_reduction && 8762 (isOpenMPParallelDirective(DVar.DKind) || 8763 isOpenMPWorksharingDirective(DVar.DKind) || 8764 isOpenMPTeamsDirective(DVar.DKind))) { 8765 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 8766 << getOpenMPDirectiveName(DVar.DKind); 8767 ReportOriginalDSA(*this, DSAStack, D, DVar); 8768 continue; 8769 } 8770 } 8771 8772 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 8773 // A list item cannot appear in both a map clause and a data-sharing 8774 // attribute clause on the same construct 8775 if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel || 8776 CurrDir == OMPD_target_teams || 8777 CurrDir == OMPD_target_teams_distribute || 8778 CurrDir == OMPD_target_teams_distribute_parallel_for || 8779 CurrDir == OMPD_target_teams_distribute_parallel_for_simd || 8780 CurrDir == OMPD_target_teams_distribute_simd || 8781 CurrDir == OMPD_target_parallel_for_simd || 8782 CurrDir == OMPD_target_parallel_for) { 8783 OpenMPClauseKind ConflictKind; 8784 if (DSAStack->checkMappableExprComponentListsForDecl( 8785 VD, /*CurrentRegionOnly=*/true, 8786 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 8787 OpenMPClauseKind WhereFoundClauseKind) -> bool { 8788 ConflictKind = WhereFoundClauseKind; 8789 return true; 8790 })) { 8791 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 8792 << getOpenMPClauseName(OMPC_firstprivate) 8793 << getOpenMPClauseName(ConflictKind) 8794 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 8795 ReportOriginalDSA(*this, DSAStack, D, DVar); 8796 continue; 8797 } 8798 } 8799 } 8800 8801 // Variably modified types are not supported for tasks. 8802 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 8803 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 8804 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 8805 << getOpenMPClauseName(OMPC_firstprivate) << Type 8806 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 8807 bool IsDecl = 8808 !VD || 8809 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8810 Diag(D->getLocation(), 8811 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8812 << D; 8813 continue; 8814 } 8815 8816 Type = Type.getUnqualifiedType(); 8817 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 8818 D->hasAttrs() ? &D->getAttrs() : nullptr); 8819 // Generate helper private variable and initialize it with the value of the 8820 // original variable. The address of the original variable is replaced by 8821 // the address of the new private variable in the CodeGen. This new variable 8822 // is not added to IdResolver, so the code in the OpenMP region uses 8823 // original variable for proper diagnostics and variable capturing. 8824 Expr *VDInitRefExpr = nullptr; 8825 // For arrays generate initializer for single element and replace it by the 8826 // original array element in CodeGen. 8827 if (Type->isArrayType()) { 8828 auto VDInit = 8829 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 8830 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 8831 auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); 8832 ElemType = ElemType.getUnqualifiedType(); 8833 auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 8834 ".firstprivate.temp"); 8835 InitializedEntity Entity = 8836 InitializedEntity::InitializeVariable(VDInitTemp); 8837 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 8838 8839 InitializationSequence InitSeq(*this, Entity, Kind, Init); 8840 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 8841 if (Result.isInvalid()) 8842 VDPrivate->setInvalidDecl(); 8843 else 8844 VDPrivate->setInit(Result.getAs<Expr>()); 8845 // Remove temp variable declaration. 8846 Context.Deallocate(VDInitTemp); 8847 } else { 8848 auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 8849 ".firstprivate.temp"); 8850 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 8851 RefExpr->getExprLoc()); 8852 AddInitializerToDecl(VDPrivate, 8853 DefaultLvalueConversion(VDInitRefExpr).get(), 8854 /*DirectInit=*/false); 8855 } 8856 if (VDPrivate->isInvalidDecl()) { 8857 if (IsImplicitClause) { 8858 Diag(RefExpr->getExprLoc(), 8859 diag::note_omp_task_predetermined_firstprivate_here); 8860 } 8861 continue; 8862 } 8863 CurContext->addDecl(VDPrivate); 8864 auto VDPrivateRefExpr = buildDeclRefExpr( 8865 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 8866 RefExpr->getExprLoc()); 8867 DeclRefExpr *Ref = nullptr; 8868 if (!VD && !CurContext->isDependentContext()) { 8869 if (TopDVar.CKind == OMPC_lastprivate) 8870 Ref = TopDVar.PrivateCopy; 8871 else { 8872 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 8873 if (!IsOpenMPCapturedDecl(D)) 8874 ExprCaptures.push_back(Ref->getDecl()); 8875 } 8876 } 8877 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 8878 Vars.push_back((VD || CurContext->isDependentContext()) 8879 ? RefExpr->IgnoreParens() 8880 : Ref); 8881 PrivateCopies.push_back(VDPrivateRefExpr); 8882 Inits.push_back(VDInitRefExpr); 8883 } 8884 8885 if (Vars.empty()) 8886 return nullptr; 8887 8888 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 8889 Vars, PrivateCopies, Inits, 8890 buildPreInits(Context, ExprCaptures)); 8891 } 8892 8893 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 8894 SourceLocation StartLoc, 8895 SourceLocation LParenLoc, 8896 SourceLocation EndLoc) { 8897 SmallVector<Expr *, 8> Vars; 8898 SmallVector<Expr *, 8> SrcExprs; 8899 SmallVector<Expr *, 8> DstExprs; 8900 SmallVector<Expr *, 8> AssignmentOps; 8901 SmallVector<Decl *, 4> ExprCaptures; 8902 SmallVector<Expr *, 4> ExprPostUpdates; 8903 for (auto &RefExpr : VarList) { 8904 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 8905 SourceLocation ELoc; 8906 SourceRange ERange; 8907 Expr *SimpleRefExpr = RefExpr; 8908 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8909 if (Res.second) { 8910 // It will be analyzed later. 8911 Vars.push_back(RefExpr); 8912 SrcExprs.push_back(nullptr); 8913 DstExprs.push_back(nullptr); 8914 AssignmentOps.push_back(nullptr); 8915 } 8916 ValueDecl *D = Res.first; 8917 if (!D) 8918 continue; 8919 8920 QualType Type = D->getType(); 8921 auto *VD = dyn_cast<VarDecl>(D); 8922 8923 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 8924 // A variable that appears in a lastprivate clause must not have an 8925 // incomplete type or a reference type. 8926 if (RequireCompleteType(ELoc, Type, 8927 diag::err_omp_lastprivate_incomplete_type)) 8928 continue; 8929 Type = Type.getNonReferenceType(); 8930 8931 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 8932 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 8933 // in a Construct] 8934 // Variables with the predetermined data-sharing attributes may not be 8935 // listed in data-sharing attributes clauses, except for the cases 8936 // listed below. 8937 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 8938 // A list item may appear in a firstprivate or lastprivate clause but not 8939 // both. 8940 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8941 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 8942 (CurrDir == OMPD_distribute || DVar.CKind != OMPC_firstprivate) && 8943 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 8944 Diag(ELoc, diag::err_omp_wrong_dsa) 8945 << getOpenMPClauseName(DVar.CKind) 8946 << getOpenMPClauseName(OMPC_lastprivate); 8947 ReportOriginalDSA(*this, DSAStack, D, DVar); 8948 continue; 8949 } 8950 8951 // OpenMP [2.14.3.5, Restrictions, p.2] 8952 // A list item that is private within a parallel region, or that appears in 8953 // the reduction clause of a parallel construct, must not appear in a 8954 // lastprivate clause on a worksharing construct if any of the corresponding 8955 // worksharing regions ever binds to any of the corresponding parallel 8956 // regions. 8957 DSAStackTy::DSAVarData TopDVar = DVar; 8958 if (isOpenMPWorksharingDirective(CurrDir) && 8959 !isOpenMPParallelDirective(CurrDir) && 8960 !isOpenMPTeamsDirective(CurrDir)) { 8961 DVar = DSAStack->getImplicitDSA(D, true); 8962 if (DVar.CKind != OMPC_shared) { 8963 Diag(ELoc, diag::err_omp_required_access) 8964 << getOpenMPClauseName(OMPC_lastprivate) 8965 << getOpenMPClauseName(OMPC_shared); 8966 ReportOriginalDSA(*this, DSAStack, D, DVar); 8967 continue; 8968 } 8969 } 8970 8971 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 8972 // A variable of class type (or array thereof) that appears in a 8973 // lastprivate clause requires an accessible, unambiguous default 8974 // constructor for the class type, unless the list item is also specified 8975 // in a firstprivate clause. 8976 // A variable of class type (or array thereof) that appears in a 8977 // lastprivate clause requires an accessible, unambiguous copy assignment 8978 // operator for the class type. 8979 Type = Context.getBaseElementType(Type).getNonReferenceType(); 8980 auto *SrcVD = buildVarDecl(*this, ERange.getBegin(), 8981 Type.getUnqualifiedType(), ".lastprivate.src", 8982 D->hasAttrs() ? &D->getAttrs() : nullptr); 8983 auto *PseudoSrcExpr = 8984 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 8985 auto *DstVD = 8986 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 8987 D->hasAttrs() ? &D->getAttrs() : nullptr); 8988 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 8989 // For arrays generate assignment operation for single element and replace 8990 // it by the original array element in CodeGen. 8991 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 8992 PseudoDstExpr, PseudoSrcExpr); 8993 if (AssignmentOp.isInvalid()) 8994 continue; 8995 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 8996 /*DiscardedValue=*/true); 8997 if (AssignmentOp.isInvalid()) 8998 continue; 8999 9000 DeclRefExpr *Ref = nullptr; 9001 if (!VD && !CurContext->isDependentContext()) { 9002 if (TopDVar.CKind == OMPC_firstprivate) 9003 Ref = TopDVar.PrivateCopy; 9004 else { 9005 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 9006 if (!IsOpenMPCapturedDecl(D)) 9007 ExprCaptures.push_back(Ref->getDecl()); 9008 } 9009 if (TopDVar.CKind == OMPC_firstprivate || 9010 (!IsOpenMPCapturedDecl(D) && 9011 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 9012 ExprResult RefRes = DefaultLvalueConversion(Ref); 9013 if (!RefRes.isUsable()) 9014 continue; 9015 ExprResult PostUpdateRes = 9016 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 9017 RefRes.get()); 9018 if (!PostUpdateRes.isUsable()) 9019 continue; 9020 ExprPostUpdates.push_back( 9021 IgnoredValueConversions(PostUpdateRes.get()).get()); 9022 } 9023 } 9024 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 9025 Vars.push_back((VD || CurContext->isDependentContext()) 9026 ? RefExpr->IgnoreParens() 9027 : Ref); 9028 SrcExprs.push_back(PseudoSrcExpr); 9029 DstExprs.push_back(PseudoDstExpr); 9030 AssignmentOps.push_back(AssignmentOp.get()); 9031 } 9032 9033 if (Vars.empty()) 9034 return nullptr; 9035 9036 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9037 Vars, SrcExprs, DstExprs, AssignmentOps, 9038 buildPreInits(Context, ExprCaptures), 9039 buildPostUpdate(*this, ExprPostUpdates)); 9040 } 9041 9042 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 9043 SourceLocation StartLoc, 9044 SourceLocation LParenLoc, 9045 SourceLocation EndLoc) { 9046 SmallVector<Expr *, 8> Vars; 9047 for (auto &RefExpr : VarList) { 9048 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 9049 SourceLocation ELoc; 9050 SourceRange ERange; 9051 Expr *SimpleRefExpr = RefExpr; 9052 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9053 if (Res.second) { 9054 // It will be analyzed later. 9055 Vars.push_back(RefExpr); 9056 } 9057 ValueDecl *D = Res.first; 9058 if (!D) 9059 continue; 9060 9061 auto *VD = dyn_cast<VarDecl>(D); 9062 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 9063 // in a Construct] 9064 // Variables with the predetermined data-sharing attributes may not be 9065 // listed in data-sharing attributes clauses, except for the cases 9066 // listed below. For these exceptions only, listing a predetermined 9067 // variable in a data-sharing attribute clause is allowed and overrides 9068 // the variable's predetermined data-sharing attributes. 9069 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 9070 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 9071 DVar.RefExpr) { 9072 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 9073 << getOpenMPClauseName(OMPC_shared); 9074 ReportOriginalDSA(*this, DSAStack, D, DVar); 9075 continue; 9076 } 9077 9078 DeclRefExpr *Ref = nullptr; 9079 if (!VD && IsOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 9080 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 9081 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 9082 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 9083 ? RefExpr->IgnoreParens() 9084 : Ref); 9085 } 9086 9087 if (Vars.empty()) 9088 return nullptr; 9089 9090 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 9091 } 9092 9093 namespace { 9094 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 9095 DSAStackTy *Stack; 9096 9097 public: 9098 bool VisitDeclRefExpr(DeclRefExpr *E) { 9099 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { 9100 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false); 9101 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 9102 return false; 9103 if (DVar.CKind != OMPC_unknown) 9104 return true; 9105 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 9106 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, 9107 /*FromParent=*/true); 9108 if (DVarPrivate.CKind != OMPC_unknown) 9109 return true; 9110 return false; 9111 } 9112 return false; 9113 } 9114 bool VisitStmt(Stmt *S) { 9115 for (auto Child : S->children()) { 9116 if (Child && Visit(Child)) 9117 return true; 9118 } 9119 return false; 9120 } 9121 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 9122 }; 9123 } // namespace 9124 9125 namespace { 9126 // Transform MemberExpression for specified FieldDecl of current class to 9127 // DeclRefExpr to specified OMPCapturedExprDecl. 9128 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 9129 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 9130 ValueDecl *Field; 9131 DeclRefExpr *CapturedExpr; 9132 9133 public: 9134 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 9135 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 9136 9137 ExprResult TransformMemberExpr(MemberExpr *E) { 9138 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 9139 E->getMemberDecl() == Field) { 9140 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 9141 return CapturedExpr; 9142 } 9143 return BaseTransform::TransformMemberExpr(E); 9144 } 9145 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 9146 }; 9147 } // namespace 9148 9149 template <typename T> 9150 static T filterLookupForUDR(SmallVectorImpl<UnresolvedSet<8>> &Lookups, 9151 const llvm::function_ref<T(ValueDecl *)> &Gen) { 9152 for (auto &Set : Lookups) { 9153 for (auto *D : Set) { 9154 if (auto Res = Gen(cast<ValueDecl>(D))) 9155 return Res; 9156 } 9157 } 9158 return T(); 9159 } 9160 9161 static ExprResult 9162 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 9163 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 9164 const DeclarationNameInfo &ReductionId, QualType Ty, 9165 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 9166 if (ReductionIdScopeSpec.isInvalid()) 9167 return ExprError(); 9168 SmallVector<UnresolvedSet<8>, 4> Lookups; 9169 if (S) { 9170 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 9171 Lookup.suppressDiagnostics(); 9172 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 9173 auto *D = Lookup.getRepresentativeDecl(); 9174 do { 9175 S = S->getParent(); 9176 } while (S && !S->isDeclScope(D)); 9177 if (S) 9178 S = S->getParent(); 9179 Lookups.push_back(UnresolvedSet<8>()); 9180 Lookups.back().append(Lookup.begin(), Lookup.end()); 9181 Lookup.clear(); 9182 } 9183 } else if (auto *ULE = 9184 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 9185 Lookups.push_back(UnresolvedSet<8>()); 9186 Decl *PrevD = nullptr; 9187 for (auto *D : ULE->decls()) { 9188 if (D == PrevD) 9189 Lookups.push_back(UnresolvedSet<8>()); 9190 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) 9191 Lookups.back().addDecl(DRD); 9192 PrevD = D; 9193 } 9194 } 9195 if (SemaRef.CurContext->isDependentContext() || Ty->isDependentType() || 9196 Ty->isInstantiationDependentType() || 9197 Ty->containsUnexpandedParameterPack() || 9198 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool { 9199 return !D->isInvalidDecl() && 9200 (D->getType()->isDependentType() || 9201 D->getType()->isInstantiationDependentType() || 9202 D->getType()->containsUnexpandedParameterPack()); 9203 })) { 9204 UnresolvedSet<8> ResSet; 9205 for (auto &Set : Lookups) { 9206 ResSet.append(Set.begin(), Set.end()); 9207 // The last item marks the end of all declarations at the specified scope. 9208 ResSet.addDecl(Set[Set.size() - 1]); 9209 } 9210 return UnresolvedLookupExpr::Create( 9211 SemaRef.Context, /*NamingClass=*/nullptr, 9212 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 9213 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 9214 } 9215 if (auto *VD = filterLookupForUDR<ValueDecl *>( 9216 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 9217 if (!D->isInvalidDecl() && 9218 SemaRef.Context.hasSameType(D->getType(), Ty)) 9219 return D; 9220 return nullptr; 9221 })) 9222 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 9223 if (auto *VD = filterLookupForUDR<ValueDecl *>( 9224 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 9225 if (!D->isInvalidDecl() && 9226 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 9227 !Ty.isMoreQualifiedThan(D->getType())) 9228 return D; 9229 return nullptr; 9230 })) { 9231 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 9232 /*DetectVirtual=*/false); 9233 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 9234 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 9235 VD->getType().getUnqualifiedType()))) { 9236 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), 9237 /*DiagID=*/0) != 9238 Sema::AR_inaccessible) { 9239 SemaRef.BuildBasePathArray(Paths, BasePath); 9240 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 9241 } 9242 } 9243 } 9244 } 9245 if (ReductionIdScopeSpec.isSet()) { 9246 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 9247 return ExprError(); 9248 } 9249 return ExprEmpty(); 9250 } 9251 9252 namespace { 9253 /// Data for the reduction-based clauses. 9254 struct ReductionData { 9255 /// List of original reduction items. 9256 SmallVector<Expr *, 8> Vars; 9257 /// List of private copies of the reduction items. 9258 SmallVector<Expr *, 8> Privates; 9259 /// LHS expressions for the reduction_op expressions. 9260 SmallVector<Expr *, 8> LHSs; 9261 /// RHS expressions for the reduction_op expressions. 9262 SmallVector<Expr *, 8> RHSs; 9263 /// Reduction operation expression. 9264 SmallVector<Expr *, 8> ReductionOps; 9265 /// Taskgroup descriptors for the corresponding reduction items in 9266 /// in_reduction clauses. 9267 SmallVector<Expr *, 8> TaskgroupDescriptors; 9268 /// List of captures for clause. 9269 SmallVector<Decl *, 4> ExprCaptures; 9270 /// List of postupdate expressions. 9271 SmallVector<Expr *, 4> ExprPostUpdates; 9272 ReductionData() = delete; 9273 /// Reserves required memory for the reduction data. 9274 ReductionData(unsigned Size) { 9275 Vars.reserve(Size); 9276 Privates.reserve(Size); 9277 LHSs.reserve(Size); 9278 RHSs.reserve(Size); 9279 ReductionOps.reserve(Size); 9280 TaskgroupDescriptors.reserve(Size); 9281 ExprCaptures.reserve(Size); 9282 ExprPostUpdates.reserve(Size); 9283 } 9284 /// Stores reduction item and reduction operation only (required for dependent 9285 /// reduction item). 9286 void push(Expr *Item, Expr *ReductionOp) { 9287 Vars.emplace_back(Item); 9288 Privates.emplace_back(nullptr); 9289 LHSs.emplace_back(nullptr); 9290 RHSs.emplace_back(nullptr); 9291 ReductionOps.emplace_back(ReductionOp); 9292 TaskgroupDescriptors.emplace_back(nullptr); 9293 } 9294 /// Stores reduction data. 9295 void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS, Expr *ReductionOp, 9296 Expr *TaskgroupDescriptor) { 9297 Vars.emplace_back(Item); 9298 Privates.emplace_back(Private); 9299 LHSs.emplace_back(LHS); 9300 RHSs.emplace_back(RHS); 9301 ReductionOps.emplace_back(ReductionOp); 9302 TaskgroupDescriptors.emplace_back(TaskgroupDescriptor); 9303 } 9304 }; 9305 } // namespace 9306 9307 static bool ActOnOMPReductionKindClause( 9308 Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind, 9309 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 9310 SourceLocation ColonLoc, SourceLocation EndLoc, 9311 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 9312 ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) { 9313 auto DN = ReductionId.getName(); 9314 auto OOK = DN.getCXXOverloadedOperator(); 9315 BinaryOperatorKind BOK = BO_Comma; 9316 9317 ASTContext &Context = S.Context; 9318 // OpenMP [2.14.3.6, reduction clause] 9319 // C 9320 // reduction-identifier is either an identifier or one of the following 9321 // operators: +, -, *, &, |, ^, && and || 9322 // C++ 9323 // reduction-identifier is either an id-expression or one of the following 9324 // operators: +, -, *, &, |, ^, && and || 9325 switch (OOK) { 9326 case OO_Plus: 9327 case OO_Minus: 9328 BOK = BO_Add; 9329 break; 9330 case OO_Star: 9331 BOK = BO_Mul; 9332 break; 9333 case OO_Amp: 9334 BOK = BO_And; 9335 break; 9336 case OO_Pipe: 9337 BOK = BO_Or; 9338 break; 9339 case OO_Caret: 9340 BOK = BO_Xor; 9341 break; 9342 case OO_AmpAmp: 9343 BOK = BO_LAnd; 9344 break; 9345 case OO_PipePipe: 9346 BOK = BO_LOr; 9347 break; 9348 case OO_New: 9349 case OO_Delete: 9350 case OO_Array_New: 9351 case OO_Array_Delete: 9352 case OO_Slash: 9353 case OO_Percent: 9354 case OO_Tilde: 9355 case OO_Exclaim: 9356 case OO_Equal: 9357 case OO_Less: 9358 case OO_Greater: 9359 case OO_LessEqual: 9360 case OO_GreaterEqual: 9361 case OO_PlusEqual: 9362 case OO_MinusEqual: 9363 case OO_StarEqual: 9364 case OO_SlashEqual: 9365 case OO_PercentEqual: 9366 case OO_CaretEqual: 9367 case OO_AmpEqual: 9368 case OO_PipeEqual: 9369 case OO_LessLess: 9370 case OO_GreaterGreater: 9371 case OO_LessLessEqual: 9372 case OO_GreaterGreaterEqual: 9373 case OO_EqualEqual: 9374 case OO_ExclaimEqual: 9375 case OO_PlusPlus: 9376 case OO_MinusMinus: 9377 case OO_Comma: 9378 case OO_ArrowStar: 9379 case OO_Arrow: 9380 case OO_Call: 9381 case OO_Subscript: 9382 case OO_Conditional: 9383 case OO_Coawait: 9384 case NUM_OVERLOADED_OPERATORS: 9385 llvm_unreachable("Unexpected reduction identifier"); 9386 case OO_None: 9387 if (auto *II = DN.getAsIdentifierInfo()) { 9388 if (II->isStr("max")) 9389 BOK = BO_GT; 9390 else if (II->isStr("min")) 9391 BOK = BO_LT; 9392 } 9393 break; 9394 } 9395 SourceRange ReductionIdRange; 9396 if (ReductionIdScopeSpec.isValid()) 9397 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 9398 else 9399 ReductionIdRange.setBegin(ReductionId.getBeginLoc()); 9400 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 9401 9402 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 9403 bool FirstIter = true; 9404 for (auto RefExpr : VarList) { 9405 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 9406 // OpenMP [2.1, C/C++] 9407 // A list item is a variable or array section, subject to the restrictions 9408 // specified in Section 2.4 on page 42 and in each of the sections 9409 // describing clauses and directives for which a list appears. 9410 // OpenMP [2.14.3.3, Restrictions, p.1] 9411 // A variable that is part of another variable (as an array or 9412 // structure element) cannot appear in a private clause. 9413 if (!FirstIter && IR != ER) 9414 ++IR; 9415 FirstIter = false; 9416 SourceLocation ELoc; 9417 SourceRange ERange; 9418 Expr *SimpleRefExpr = RefExpr; 9419 auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange, 9420 /*AllowArraySection=*/true); 9421 if (Res.second) { 9422 // Try to find 'declare reduction' corresponding construct before using 9423 // builtin/overloaded operators. 9424 QualType Type = Context.DependentTy; 9425 CXXCastPath BasePath; 9426 ExprResult DeclareReductionRef = buildDeclareReductionRef( 9427 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 9428 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 9429 Expr *ReductionOp = nullptr; 9430 if (S.CurContext->isDependentContext() && 9431 (DeclareReductionRef.isUnset() || 9432 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 9433 ReductionOp = DeclareReductionRef.get(); 9434 // It will be analyzed later. 9435 RD.push(RefExpr, ReductionOp); 9436 } 9437 ValueDecl *D = Res.first; 9438 if (!D) 9439 continue; 9440 9441 Expr *TaskgroupDescriptor = nullptr; 9442 QualType Type; 9443 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 9444 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 9445 if (ASE) 9446 Type = ASE->getType().getNonReferenceType(); 9447 else if (OASE) { 9448 auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 9449 if (auto *ATy = BaseType->getAsArrayTypeUnsafe()) 9450 Type = ATy->getElementType(); 9451 else 9452 Type = BaseType->getPointeeType(); 9453 Type = Type.getNonReferenceType(); 9454 } else 9455 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 9456 auto *VD = dyn_cast<VarDecl>(D); 9457 9458 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 9459 // A variable that appears in a private clause must not have an incomplete 9460 // type or a reference type. 9461 if (S.RequireCompleteType(ELoc, Type, 9462 diag::err_omp_reduction_incomplete_type)) 9463 continue; 9464 // OpenMP [2.14.3.6, reduction clause, Restrictions] 9465 // A list item that appears in a reduction clause must not be 9466 // const-qualified. 9467 if (Type.getNonReferenceType().isConstant(Context)) { 9468 S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange; 9469 if (!ASE && !OASE) { 9470 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 9471 VarDecl::DeclarationOnly; 9472 S.Diag(D->getLocation(), 9473 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9474 << D; 9475 } 9476 continue; 9477 } 9478 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 9479 // If a list-item is a reference type then it must bind to the same object 9480 // for all threads of the team. 9481 if (!ASE && !OASE && VD) { 9482 VarDecl *VDDef = VD->getDefinition(); 9483 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 9484 DSARefChecker Check(Stack); 9485 if (Check.Visit(VDDef->getInit())) { 9486 S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg) 9487 << getOpenMPClauseName(ClauseKind) << ERange; 9488 S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 9489 continue; 9490 } 9491 } 9492 } 9493 9494 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 9495 // in a Construct] 9496 // Variables with the predetermined data-sharing attributes may not be 9497 // listed in data-sharing attributes clauses, except for the cases 9498 // listed below. For these exceptions only, listing a predetermined 9499 // variable in a data-sharing attribute clause is allowed and overrides 9500 // the variable's predetermined data-sharing attributes. 9501 // OpenMP [2.14.3.6, Restrictions, p.3] 9502 // Any number of reduction clauses can be specified on the directive, 9503 // but a list item can appear only once in the reduction clauses for that 9504 // directive. 9505 DSAStackTy::DSAVarData DVar; 9506 DVar = Stack->getTopDSA(D, false); 9507 if (DVar.CKind == OMPC_reduction) { 9508 S.Diag(ELoc, diag::err_omp_once_referenced) 9509 << getOpenMPClauseName(ClauseKind); 9510 if (DVar.RefExpr) 9511 S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 9512 continue; 9513 } else if (DVar.CKind != OMPC_unknown) { 9514 S.Diag(ELoc, diag::err_omp_wrong_dsa) 9515 << getOpenMPClauseName(DVar.CKind) 9516 << getOpenMPClauseName(OMPC_reduction); 9517 ReportOriginalDSA(S, Stack, D, DVar); 9518 continue; 9519 } 9520 9521 // OpenMP [2.14.3.6, Restrictions, p.1] 9522 // A list item that appears in a reduction clause of a worksharing 9523 // construct must be shared in the parallel regions to which any of the 9524 // worksharing regions arising from the worksharing construct bind. 9525 OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective(); 9526 if (isOpenMPWorksharingDirective(CurrDir) && 9527 !isOpenMPParallelDirective(CurrDir) && 9528 !isOpenMPTeamsDirective(CurrDir)) { 9529 DVar = Stack->getImplicitDSA(D, true); 9530 if (DVar.CKind != OMPC_shared) { 9531 S.Diag(ELoc, diag::err_omp_required_access) 9532 << getOpenMPClauseName(OMPC_reduction) 9533 << getOpenMPClauseName(OMPC_shared); 9534 ReportOriginalDSA(S, Stack, D, DVar); 9535 continue; 9536 } 9537 } 9538 9539 // Try to find 'declare reduction' corresponding construct before using 9540 // builtin/overloaded operators. 9541 CXXCastPath BasePath; 9542 ExprResult DeclareReductionRef = buildDeclareReductionRef( 9543 S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec, 9544 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 9545 if (DeclareReductionRef.isInvalid()) 9546 continue; 9547 if (S.CurContext->isDependentContext() && 9548 (DeclareReductionRef.isUnset() || 9549 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 9550 RD.push(RefExpr, DeclareReductionRef.get()); 9551 continue; 9552 } 9553 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 9554 // Not allowed reduction identifier is found. 9555 S.Diag(ReductionId.getLocStart(), 9556 diag::err_omp_unknown_reduction_identifier) 9557 << Type << ReductionIdRange; 9558 continue; 9559 } 9560 9561 // OpenMP [2.14.3.6, reduction clause, Restrictions] 9562 // The type of a list item that appears in a reduction clause must be valid 9563 // for the reduction-identifier. For a max or min reduction in C, the type 9564 // of the list item must be an allowed arithmetic data type: char, int, 9565 // float, double, or _Bool, possibly modified with long, short, signed, or 9566 // unsigned. For a max or min reduction in C++, the type of the list item 9567 // must be an allowed arithmetic data type: char, wchar_t, int, float, 9568 // double, or bool, possibly modified with long, short, signed, or unsigned. 9569 if (DeclareReductionRef.isUnset()) { 9570 if ((BOK == BO_GT || BOK == BO_LT) && 9571 !(Type->isScalarType() || 9572 (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 9573 S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 9574 << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus; 9575 if (!ASE && !OASE) { 9576 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 9577 VarDecl::DeclarationOnly; 9578 S.Diag(D->getLocation(), 9579 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9580 << D; 9581 } 9582 continue; 9583 } 9584 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 9585 !S.getLangOpts().CPlusPlus && Type->isFloatingType()) { 9586 S.Diag(ELoc, diag::err_omp_clause_floating_type_arg) 9587 << getOpenMPClauseName(ClauseKind); 9588 if (!ASE && !OASE) { 9589 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 9590 VarDecl::DeclarationOnly; 9591 S.Diag(D->getLocation(), 9592 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9593 << D; 9594 } 9595 continue; 9596 } 9597 } 9598 9599 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 9600 auto *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs", 9601 D->hasAttrs() ? &D->getAttrs() : nullptr); 9602 auto *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(), 9603 D->hasAttrs() ? &D->getAttrs() : nullptr); 9604 auto PrivateTy = Type; 9605 if (OASE || 9606 (!ASE && 9607 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 9608 // For arrays/array sections only: 9609 // Create pseudo array type for private copy. The size for this array will 9610 // be generated during codegen. 9611 // For array subscripts or single variables Private Ty is the same as Type 9612 // (type of the variable or single array element). 9613 PrivateTy = Context.getVariableArrayType( 9614 Type, 9615 new (Context) OpaqueValueExpr(SourceLocation(), Context.getSizeType(), 9616 VK_RValue), 9617 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 9618 } else if (!ASE && !OASE && 9619 Context.getAsArrayType(D->getType().getNonReferenceType())) 9620 PrivateTy = D->getType().getNonReferenceType(); 9621 // Private copy. 9622 auto *PrivateVD = buildVarDecl(S, ELoc, PrivateTy, D->getName(), 9623 D->hasAttrs() ? &D->getAttrs() : nullptr); 9624 // Add initializer for private variable. 9625 Expr *Init = nullptr; 9626 auto *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc); 9627 auto *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc); 9628 if (DeclareReductionRef.isUsable()) { 9629 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 9630 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 9631 if (DRD->getInitializer()) { 9632 Init = DRDRef; 9633 RHSVD->setInit(DRDRef); 9634 RHSVD->setInitStyle(VarDecl::CallInit); 9635 } 9636 } else { 9637 switch (BOK) { 9638 case BO_Add: 9639 case BO_Xor: 9640 case BO_Or: 9641 case BO_LOr: 9642 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 9643 if (Type->isScalarType() || Type->isAnyComplexType()) 9644 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 9645 break; 9646 case BO_Mul: 9647 case BO_LAnd: 9648 if (Type->isScalarType() || Type->isAnyComplexType()) { 9649 // '*' and '&&' reduction ops - initializer is '1'. 9650 Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 9651 } 9652 break; 9653 case BO_And: { 9654 // '&' reduction op - initializer is '~0'. 9655 QualType OrigType = Type; 9656 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 9657 Type = ComplexTy->getElementType(); 9658 if (Type->isRealFloatingType()) { 9659 llvm::APFloat InitValue = 9660 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 9661 /*isIEEE=*/true); 9662 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 9663 Type, ELoc); 9664 } else if (Type->isScalarType()) { 9665 auto Size = Context.getTypeSize(Type); 9666 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 9667 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 9668 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 9669 } 9670 if (Init && OrigType->isAnyComplexType()) { 9671 // Init = 0xFFFF + 0xFFFFi; 9672 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 9673 Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 9674 } 9675 Type = OrigType; 9676 break; 9677 } 9678 case BO_LT: 9679 case BO_GT: { 9680 // 'min' reduction op - initializer is 'Largest representable number in 9681 // the reduction list item type'. 9682 // 'max' reduction op - initializer is 'Least representable number in 9683 // the reduction list item type'. 9684 if (Type->isIntegerType() || Type->isPointerType()) { 9685 bool IsSigned = Type->hasSignedIntegerRepresentation(); 9686 auto Size = Context.getTypeSize(Type); 9687 QualType IntTy = 9688 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 9689 llvm::APInt InitValue = 9690 (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 9691 : llvm::APInt::getMinValue(Size) 9692 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 9693 : llvm::APInt::getMaxValue(Size); 9694 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 9695 if (Type->isPointerType()) { 9696 // Cast to pointer type. 9697 auto CastExpr = S.BuildCStyleCastExpr( 9698 SourceLocation(), Context.getTrivialTypeSourceInfo(Type, ELoc), 9699 SourceLocation(), Init); 9700 if (CastExpr.isInvalid()) 9701 continue; 9702 Init = CastExpr.get(); 9703 } 9704 } else if (Type->isRealFloatingType()) { 9705 llvm::APFloat InitValue = llvm::APFloat::getLargest( 9706 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 9707 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 9708 Type, ELoc); 9709 } 9710 break; 9711 } 9712 case BO_PtrMemD: 9713 case BO_PtrMemI: 9714 case BO_MulAssign: 9715 case BO_Div: 9716 case BO_Rem: 9717 case BO_Sub: 9718 case BO_Shl: 9719 case BO_Shr: 9720 case BO_LE: 9721 case BO_GE: 9722 case BO_EQ: 9723 case BO_NE: 9724 case BO_AndAssign: 9725 case BO_XorAssign: 9726 case BO_OrAssign: 9727 case BO_Assign: 9728 case BO_AddAssign: 9729 case BO_SubAssign: 9730 case BO_DivAssign: 9731 case BO_RemAssign: 9732 case BO_ShlAssign: 9733 case BO_ShrAssign: 9734 case BO_Comma: 9735 llvm_unreachable("Unexpected reduction operation"); 9736 } 9737 } 9738 if (Init && DeclareReductionRef.isUnset()) 9739 S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 9740 else if (!Init) 9741 S.ActOnUninitializedDecl(RHSVD); 9742 if (RHSVD->isInvalidDecl()) 9743 continue; 9744 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 9745 S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible) 9746 << Type << ReductionIdRange; 9747 bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) == 9748 VarDecl::DeclarationOnly; 9749 S.Diag(D->getLocation(), 9750 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9751 << D; 9752 continue; 9753 } 9754 // Store initializer for single element in private copy. Will be used during 9755 // codegen. 9756 PrivateVD->setInit(RHSVD->getInit()); 9757 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 9758 auto *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc); 9759 ExprResult ReductionOp; 9760 if (DeclareReductionRef.isUsable()) { 9761 QualType RedTy = DeclareReductionRef.get()->getType(); 9762 QualType PtrRedTy = Context.getPointerType(RedTy); 9763 ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 9764 ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 9765 if (!BasePath.empty()) { 9766 LHS = S.DefaultLvalueConversion(LHS.get()); 9767 RHS = S.DefaultLvalueConversion(RHS.get()); 9768 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 9769 CK_UncheckedDerivedToBase, LHS.get(), 9770 &BasePath, LHS.get()->getValueKind()); 9771 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 9772 CK_UncheckedDerivedToBase, RHS.get(), 9773 &BasePath, RHS.get()->getValueKind()); 9774 } 9775 FunctionProtoType::ExtProtoInfo EPI; 9776 QualType Params[] = {PtrRedTy, PtrRedTy}; 9777 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 9778 auto *OVE = new (Context) OpaqueValueExpr( 9779 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 9780 S.DefaultLvalueConversion(DeclareReductionRef.get()).get()); 9781 Expr *Args[] = {LHS.get(), RHS.get()}; 9782 ReductionOp = new (Context) 9783 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 9784 } else { 9785 ReductionOp = S.BuildBinOp( 9786 Stack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE); 9787 if (ReductionOp.isUsable()) { 9788 if (BOK != BO_LT && BOK != BO_GT) { 9789 ReductionOp = 9790 S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(), 9791 BO_Assign, LHSDRE, ReductionOp.get()); 9792 } else { 9793 auto *ConditionalOp = new (Context) ConditionalOperator( 9794 ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(), 9795 RHSDRE, Type, VK_LValue, OK_Ordinary); 9796 ReductionOp = 9797 S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(), 9798 BO_Assign, LHSDRE, ConditionalOp); 9799 } 9800 if (ReductionOp.isUsable()) 9801 ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get()); 9802 } 9803 if (!ReductionOp.isUsable()) 9804 continue; 9805 } 9806 9807 // OpenMP [2.15.4.6, Restrictions, p.2] 9808 // A list item that appears in an in_reduction clause of a task construct 9809 // must appear in a task_reduction clause of a construct associated with a 9810 // taskgroup region that includes the participating task in its taskgroup 9811 // set. The construct associated with the innermost region that meets this 9812 // condition must specify the same reduction-identifier as the in_reduction 9813 // clause. 9814 if (ClauseKind == OMPC_in_reduction) { 9815 SourceRange ParentSR; 9816 BinaryOperatorKind ParentBOK; 9817 const Expr *ParentReductionOp; 9818 Expr *ParentBOKTD, *ParentReductionOpTD; 9819 DSAStackTy::DSAVarData ParentBOKDSA = 9820 Stack->getTopMostTaskgroupReductionData(D, ParentSR, ParentBOK, 9821 ParentBOKTD); 9822 DSAStackTy::DSAVarData ParentReductionOpDSA = 9823 Stack->getTopMostTaskgroupReductionData( 9824 D, ParentSR, ParentReductionOp, ParentReductionOpTD); 9825 bool IsParentBOK = ParentBOKDSA.DKind != OMPD_unknown; 9826 bool IsParentReductionOp = ParentReductionOpDSA.DKind != OMPD_unknown; 9827 if (!IsParentBOK && !IsParentReductionOp) { 9828 S.Diag(ELoc, diag::err_omp_in_reduction_not_task_reduction); 9829 continue; 9830 } 9831 if ((DeclareReductionRef.isUnset() && IsParentReductionOp) || 9832 (DeclareReductionRef.isUsable() && IsParentBOK) || BOK != ParentBOK || 9833 IsParentReductionOp) { 9834 bool EmitError = true; 9835 if (IsParentReductionOp && DeclareReductionRef.isUsable()) { 9836 llvm::FoldingSetNodeID RedId, ParentRedId; 9837 ParentReductionOp->Profile(ParentRedId, Context, /*Canonical=*/true); 9838 DeclareReductionRef.get()->Profile(RedId, Context, 9839 /*Canonical=*/true); 9840 EmitError = RedId != ParentRedId; 9841 } 9842 if (EmitError) { 9843 S.Diag(ReductionId.getLocStart(), 9844 diag::err_omp_reduction_identifier_mismatch) 9845 << ReductionIdRange << RefExpr->getSourceRange(); 9846 S.Diag(ParentSR.getBegin(), 9847 diag::note_omp_previous_reduction_identifier) 9848 << ParentSR 9849 << (IsParentBOK ? ParentBOKDSA.RefExpr 9850 : ParentReductionOpDSA.RefExpr) 9851 ->getSourceRange(); 9852 continue; 9853 } 9854 } 9855 TaskgroupDescriptor = IsParentBOK ? ParentBOKTD : ParentReductionOpTD; 9856 assert(TaskgroupDescriptor && "Taskgroup descriptor must be defined."); 9857 } 9858 9859 DeclRefExpr *Ref = nullptr; 9860 Expr *VarsExpr = RefExpr->IgnoreParens(); 9861 if (!VD && !S.CurContext->isDependentContext()) { 9862 if (ASE || OASE) { 9863 TransformExprToCaptures RebuildToCapture(S, D); 9864 VarsExpr = 9865 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 9866 Ref = RebuildToCapture.getCapturedExpr(); 9867 } else { 9868 VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false); 9869 } 9870 if (!S.IsOpenMPCapturedDecl(D)) { 9871 RD.ExprCaptures.emplace_back(Ref->getDecl()); 9872 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 9873 ExprResult RefRes = S.DefaultLvalueConversion(Ref); 9874 if (!RefRes.isUsable()) 9875 continue; 9876 ExprResult PostUpdateRes = 9877 S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 9878 RefRes.get()); 9879 if (!PostUpdateRes.isUsable()) 9880 continue; 9881 if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) || 9882 Stack->getCurrentDirective() == OMPD_taskgroup) { 9883 S.Diag(RefExpr->getExprLoc(), 9884 diag::err_omp_reduction_non_addressable_expression) 9885 << RefExpr->getSourceRange(); 9886 continue; 9887 } 9888 RD.ExprPostUpdates.emplace_back( 9889 S.IgnoredValueConversions(PostUpdateRes.get()).get()); 9890 } 9891 } 9892 } 9893 // All reduction items are still marked as reduction (to do not increase 9894 // code base size). 9895 Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 9896 if (CurrDir == OMPD_taskgroup) { 9897 if (DeclareReductionRef.isUsable()) 9898 Stack->addTaskgroupReductionData(D, ReductionIdRange, 9899 DeclareReductionRef.get()); 9900 else 9901 Stack->addTaskgroupReductionData(D, ReductionIdRange, BOK); 9902 } 9903 RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get(), 9904 TaskgroupDescriptor); 9905 } 9906 return RD.Vars.empty(); 9907 } 9908 9909 OMPClause *Sema::ActOnOpenMPReductionClause( 9910 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 9911 SourceLocation ColonLoc, SourceLocation EndLoc, 9912 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 9913 ArrayRef<Expr *> UnresolvedReductions) { 9914 ReductionData RD(VarList.size()); 9915 9916 if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList, 9917 StartLoc, LParenLoc, ColonLoc, EndLoc, 9918 ReductionIdScopeSpec, ReductionId, 9919 UnresolvedReductions, RD)) 9920 return nullptr; 9921 9922 return OMPReductionClause::Create( 9923 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 9924 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 9925 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 9926 buildPreInits(Context, RD.ExprCaptures), 9927 buildPostUpdate(*this, RD.ExprPostUpdates)); 9928 } 9929 9930 OMPClause *Sema::ActOnOpenMPTaskReductionClause( 9931 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 9932 SourceLocation ColonLoc, SourceLocation EndLoc, 9933 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 9934 ArrayRef<Expr *> UnresolvedReductions) { 9935 ReductionData RD(VarList.size()); 9936 9937 if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction, 9938 VarList, StartLoc, LParenLoc, ColonLoc, 9939 EndLoc, ReductionIdScopeSpec, ReductionId, 9940 UnresolvedReductions, RD)) 9941 return nullptr; 9942 9943 return OMPTaskReductionClause::Create( 9944 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 9945 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 9946 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, 9947 buildPreInits(Context, RD.ExprCaptures), 9948 buildPostUpdate(*this, RD.ExprPostUpdates)); 9949 } 9950 9951 OMPClause *Sema::ActOnOpenMPInReductionClause( 9952 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 9953 SourceLocation ColonLoc, SourceLocation EndLoc, 9954 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 9955 ArrayRef<Expr *> UnresolvedReductions) { 9956 ReductionData RD(VarList.size()); 9957 9958 if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_in_reduction, VarList, 9959 StartLoc, LParenLoc, ColonLoc, EndLoc, 9960 ReductionIdScopeSpec, ReductionId, 9961 UnresolvedReductions, RD)) 9962 return nullptr; 9963 9964 return OMPInReductionClause::Create( 9965 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars, 9966 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, 9967 RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps, RD.TaskgroupDescriptors, 9968 buildPreInits(Context, RD.ExprCaptures), 9969 buildPostUpdate(*this, RD.ExprPostUpdates)); 9970 } 9971 9972 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 9973 SourceLocation LinLoc) { 9974 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 9975 LinKind == OMPC_LINEAR_unknown) { 9976 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 9977 return true; 9978 } 9979 return false; 9980 } 9981 9982 bool Sema::CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, 9983 OpenMPLinearClauseKind LinKind, 9984 QualType Type) { 9985 auto *VD = dyn_cast_or_null<VarDecl>(D); 9986 // A variable must not have an incomplete type or a reference type. 9987 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 9988 return true; 9989 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 9990 !Type->isReferenceType()) { 9991 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 9992 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 9993 return true; 9994 } 9995 Type = Type.getNonReferenceType(); 9996 9997 // A list item must not be const-qualified. 9998 if (Type.isConstant(Context)) { 9999 Diag(ELoc, diag::err_omp_const_variable) 10000 << getOpenMPClauseName(OMPC_linear); 10001 if (D) { 10002 bool IsDecl = 10003 !VD || 10004 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10005 Diag(D->getLocation(), 10006 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10007 << D; 10008 } 10009 return true; 10010 } 10011 10012 // A list item must be of integral or pointer type. 10013 Type = Type.getUnqualifiedType().getCanonicalType(); 10014 const auto *Ty = Type.getTypePtrOrNull(); 10015 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 10016 !Ty->isPointerType())) { 10017 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 10018 if (D) { 10019 bool IsDecl = 10020 !VD || 10021 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10022 Diag(D->getLocation(), 10023 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10024 << D; 10025 } 10026 return true; 10027 } 10028 return false; 10029 } 10030 10031 OMPClause *Sema::ActOnOpenMPLinearClause( 10032 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 10033 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 10034 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 10035 SmallVector<Expr *, 8> Vars; 10036 SmallVector<Expr *, 8> Privates; 10037 SmallVector<Expr *, 8> Inits; 10038 SmallVector<Decl *, 4> ExprCaptures; 10039 SmallVector<Expr *, 4> ExprPostUpdates; 10040 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 10041 LinKind = OMPC_LINEAR_val; 10042 for (auto &RefExpr : VarList) { 10043 assert(RefExpr && "NULL expr in OpenMP linear clause."); 10044 SourceLocation ELoc; 10045 SourceRange ERange; 10046 Expr *SimpleRefExpr = RefExpr; 10047 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 10048 /*AllowArraySection=*/false); 10049 if (Res.second) { 10050 // It will be analyzed later. 10051 Vars.push_back(RefExpr); 10052 Privates.push_back(nullptr); 10053 Inits.push_back(nullptr); 10054 } 10055 ValueDecl *D = Res.first; 10056 if (!D) 10057 continue; 10058 10059 QualType Type = D->getType(); 10060 auto *VD = dyn_cast<VarDecl>(D); 10061 10062 // OpenMP [2.14.3.7, linear clause] 10063 // A list-item cannot appear in more than one linear clause. 10064 // A list-item that appears in a linear clause cannot appear in any 10065 // other data-sharing attribute clause. 10066 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 10067 if (DVar.RefExpr) { 10068 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10069 << getOpenMPClauseName(OMPC_linear); 10070 ReportOriginalDSA(*this, DSAStack, D, DVar); 10071 continue; 10072 } 10073 10074 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 10075 continue; 10076 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 10077 10078 // Build private copy of original var. 10079 auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(), 10080 D->hasAttrs() ? &D->getAttrs() : nullptr); 10081 auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 10082 // Build var to save initial value. 10083 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 10084 Expr *InitExpr; 10085 DeclRefExpr *Ref = nullptr; 10086 if (!VD && !CurContext->isDependentContext()) { 10087 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10088 if (!IsOpenMPCapturedDecl(D)) { 10089 ExprCaptures.push_back(Ref->getDecl()); 10090 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 10091 ExprResult RefRes = DefaultLvalueConversion(Ref); 10092 if (!RefRes.isUsable()) 10093 continue; 10094 ExprResult PostUpdateRes = 10095 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 10096 SimpleRefExpr, RefRes.get()); 10097 if (!PostUpdateRes.isUsable()) 10098 continue; 10099 ExprPostUpdates.push_back( 10100 IgnoredValueConversions(PostUpdateRes.get()).get()); 10101 } 10102 } 10103 } 10104 if (LinKind == OMPC_LINEAR_uval) 10105 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 10106 else 10107 InitExpr = VD ? SimpleRefExpr : Ref; 10108 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 10109 /*DirectInit=*/false); 10110 auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 10111 10112 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 10113 Vars.push_back((VD || CurContext->isDependentContext()) 10114 ? RefExpr->IgnoreParens() 10115 : Ref); 10116 Privates.push_back(PrivateRef); 10117 Inits.push_back(InitRef); 10118 } 10119 10120 if (Vars.empty()) 10121 return nullptr; 10122 10123 Expr *StepExpr = Step; 10124 Expr *CalcStepExpr = nullptr; 10125 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 10126 !Step->isInstantiationDependent() && 10127 !Step->containsUnexpandedParameterPack()) { 10128 SourceLocation StepLoc = Step->getLocStart(); 10129 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 10130 if (Val.isInvalid()) 10131 return nullptr; 10132 StepExpr = Val.get(); 10133 10134 // Build var to save the step value. 10135 VarDecl *SaveVar = 10136 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 10137 ExprResult SaveRef = 10138 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 10139 ExprResult CalcStep = 10140 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 10141 CalcStep = ActOnFinishFullExpr(CalcStep.get()); 10142 10143 // Warn about zero linear step (it would be probably better specified as 10144 // making corresponding variables 'const'). 10145 llvm::APSInt Result; 10146 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 10147 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 10148 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 10149 << (Vars.size() > 1); 10150 if (!IsConstant && CalcStep.isUsable()) { 10151 // Calculate the step beforehand instead of doing this on each iteration. 10152 // (This is not used if the number of iterations may be kfold-ed). 10153 CalcStepExpr = CalcStep.get(); 10154 } 10155 } 10156 10157 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 10158 ColonLoc, EndLoc, Vars, Privates, Inits, 10159 StepExpr, CalcStepExpr, 10160 buildPreInits(Context, ExprCaptures), 10161 buildPostUpdate(*this, ExprPostUpdates)); 10162 } 10163 10164 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 10165 Expr *NumIterations, Sema &SemaRef, 10166 Scope *S, DSAStackTy *Stack) { 10167 // Walk the vars and build update/final expressions for the CodeGen. 10168 SmallVector<Expr *, 8> Updates; 10169 SmallVector<Expr *, 8> Finals; 10170 Expr *Step = Clause.getStep(); 10171 Expr *CalcStep = Clause.getCalcStep(); 10172 // OpenMP [2.14.3.7, linear clause] 10173 // If linear-step is not specified it is assumed to be 1. 10174 if (Step == nullptr) 10175 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 10176 else if (CalcStep) { 10177 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 10178 } 10179 bool HasErrors = false; 10180 auto CurInit = Clause.inits().begin(); 10181 auto CurPrivate = Clause.privates().begin(); 10182 auto LinKind = Clause.getModifier(); 10183 for (auto &RefExpr : Clause.varlists()) { 10184 SourceLocation ELoc; 10185 SourceRange ERange; 10186 Expr *SimpleRefExpr = RefExpr; 10187 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange, 10188 /*AllowArraySection=*/false); 10189 ValueDecl *D = Res.first; 10190 if (Res.second || !D) { 10191 Updates.push_back(nullptr); 10192 Finals.push_back(nullptr); 10193 HasErrors = true; 10194 continue; 10195 } 10196 auto &&Info = Stack->isLoopControlVariable(D); 10197 Expr *InitExpr = *CurInit; 10198 10199 // Build privatized reference to the current linear var. 10200 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 10201 Expr *CapturedRef; 10202 if (LinKind == OMPC_LINEAR_uval) 10203 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 10204 else 10205 CapturedRef = 10206 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 10207 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 10208 /*RefersToCapture=*/true); 10209 10210 // Build update: Var = InitExpr + IV * Step 10211 ExprResult Update; 10212 if (!Info.first) { 10213 Update = 10214 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 10215 InitExpr, IV, Step, /* Subtract */ false); 10216 } else 10217 Update = *CurPrivate; 10218 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(), 10219 /*DiscardedValue=*/true); 10220 10221 // Build final: Var = InitExpr + NumIterations * Step 10222 ExprResult Final; 10223 if (!Info.first) { 10224 Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 10225 InitExpr, NumIterations, Step, 10226 /* Subtract */ false); 10227 } else 10228 Final = *CurPrivate; 10229 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(), 10230 /*DiscardedValue=*/true); 10231 10232 if (!Update.isUsable() || !Final.isUsable()) { 10233 Updates.push_back(nullptr); 10234 Finals.push_back(nullptr); 10235 HasErrors = true; 10236 } else { 10237 Updates.push_back(Update.get()); 10238 Finals.push_back(Final.get()); 10239 } 10240 ++CurInit; 10241 ++CurPrivate; 10242 } 10243 Clause.setUpdates(Updates); 10244 Clause.setFinals(Finals); 10245 return HasErrors; 10246 } 10247 10248 OMPClause *Sema::ActOnOpenMPAlignedClause( 10249 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 10250 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 10251 10252 SmallVector<Expr *, 8> Vars; 10253 for (auto &RefExpr : VarList) { 10254 assert(RefExpr && "NULL expr in OpenMP linear clause."); 10255 SourceLocation ELoc; 10256 SourceRange ERange; 10257 Expr *SimpleRefExpr = RefExpr; 10258 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 10259 /*AllowArraySection=*/false); 10260 if (Res.second) { 10261 // It will be analyzed later. 10262 Vars.push_back(RefExpr); 10263 } 10264 ValueDecl *D = Res.first; 10265 if (!D) 10266 continue; 10267 10268 QualType QType = D->getType(); 10269 auto *VD = dyn_cast<VarDecl>(D); 10270 10271 // OpenMP [2.8.1, simd construct, Restrictions] 10272 // The type of list items appearing in the aligned clause must be 10273 // array, pointer, reference to array, or reference to pointer. 10274 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 10275 const Type *Ty = QType.getTypePtrOrNull(); 10276 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 10277 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 10278 << QType << getLangOpts().CPlusPlus << ERange; 10279 bool IsDecl = 10280 !VD || 10281 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10282 Diag(D->getLocation(), 10283 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10284 << D; 10285 continue; 10286 } 10287 10288 // OpenMP [2.8.1, simd construct, Restrictions] 10289 // A list-item cannot appear in more than one aligned clause. 10290 if (Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 10291 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 10292 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 10293 << getOpenMPClauseName(OMPC_aligned); 10294 continue; 10295 } 10296 10297 DeclRefExpr *Ref = nullptr; 10298 if (!VD && IsOpenMPCapturedDecl(D)) 10299 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10300 Vars.push_back(DefaultFunctionArrayConversion( 10301 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 10302 .get()); 10303 } 10304 10305 // OpenMP [2.8.1, simd construct, Description] 10306 // The parameter of the aligned clause, alignment, must be a constant 10307 // positive integer expression. 10308 // If no optional parameter is specified, implementation-defined default 10309 // alignments for SIMD instructions on the target platforms are assumed. 10310 if (Alignment != nullptr) { 10311 ExprResult AlignResult = 10312 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 10313 if (AlignResult.isInvalid()) 10314 return nullptr; 10315 Alignment = AlignResult.get(); 10316 } 10317 if (Vars.empty()) 10318 return nullptr; 10319 10320 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 10321 EndLoc, Vars, Alignment); 10322 } 10323 10324 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 10325 SourceLocation StartLoc, 10326 SourceLocation LParenLoc, 10327 SourceLocation EndLoc) { 10328 SmallVector<Expr *, 8> Vars; 10329 SmallVector<Expr *, 8> SrcExprs; 10330 SmallVector<Expr *, 8> DstExprs; 10331 SmallVector<Expr *, 8> AssignmentOps; 10332 for (auto &RefExpr : VarList) { 10333 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 10334 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 10335 // It will be analyzed later. 10336 Vars.push_back(RefExpr); 10337 SrcExprs.push_back(nullptr); 10338 DstExprs.push_back(nullptr); 10339 AssignmentOps.push_back(nullptr); 10340 continue; 10341 } 10342 10343 SourceLocation ELoc = RefExpr->getExprLoc(); 10344 // OpenMP [2.1, C/C++] 10345 // A list item is a variable name. 10346 // OpenMP [2.14.4.1, Restrictions, p.1] 10347 // A list item that appears in a copyin clause must be threadprivate. 10348 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 10349 if (!DE || !isa<VarDecl>(DE->getDecl())) { 10350 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 10351 << 0 << RefExpr->getSourceRange(); 10352 continue; 10353 } 10354 10355 Decl *D = DE->getDecl(); 10356 VarDecl *VD = cast<VarDecl>(D); 10357 10358 QualType Type = VD->getType(); 10359 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 10360 // It will be analyzed later. 10361 Vars.push_back(DE); 10362 SrcExprs.push_back(nullptr); 10363 DstExprs.push_back(nullptr); 10364 AssignmentOps.push_back(nullptr); 10365 continue; 10366 } 10367 10368 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 10369 // A list item that appears in a copyin clause must be threadprivate. 10370 if (!DSAStack->isThreadPrivate(VD)) { 10371 Diag(ELoc, diag::err_omp_required_access) 10372 << getOpenMPClauseName(OMPC_copyin) 10373 << getOpenMPDirectiveName(OMPD_threadprivate); 10374 continue; 10375 } 10376 10377 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 10378 // A variable of class type (or array thereof) that appears in a 10379 // copyin clause requires an accessible, unambiguous copy assignment 10380 // operator for the class type. 10381 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 10382 auto *SrcVD = 10383 buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(), 10384 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 10385 auto *PseudoSrcExpr = buildDeclRefExpr( 10386 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 10387 auto *DstVD = 10388 buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst", 10389 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 10390 auto *PseudoDstExpr = 10391 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 10392 // For arrays generate assignment operation for single element and replace 10393 // it by the original array element in CodeGen. 10394 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 10395 PseudoDstExpr, PseudoSrcExpr); 10396 if (AssignmentOp.isInvalid()) 10397 continue; 10398 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 10399 /*DiscardedValue=*/true); 10400 if (AssignmentOp.isInvalid()) 10401 continue; 10402 10403 DSAStack->addDSA(VD, DE, OMPC_copyin); 10404 Vars.push_back(DE); 10405 SrcExprs.push_back(PseudoSrcExpr); 10406 DstExprs.push_back(PseudoDstExpr); 10407 AssignmentOps.push_back(AssignmentOp.get()); 10408 } 10409 10410 if (Vars.empty()) 10411 return nullptr; 10412 10413 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 10414 SrcExprs, DstExprs, AssignmentOps); 10415 } 10416 10417 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 10418 SourceLocation StartLoc, 10419 SourceLocation LParenLoc, 10420 SourceLocation EndLoc) { 10421 SmallVector<Expr *, 8> Vars; 10422 SmallVector<Expr *, 8> SrcExprs; 10423 SmallVector<Expr *, 8> DstExprs; 10424 SmallVector<Expr *, 8> AssignmentOps; 10425 for (auto &RefExpr : VarList) { 10426 assert(RefExpr && "NULL expr in OpenMP linear clause."); 10427 SourceLocation ELoc; 10428 SourceRange ERange; 10429 Expr *SimpleRefExpr = RefExpr; 10430 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 10431 /*AllowArraySection=*/false); 10432 if (Res.second) { 10433 // It will be analyzed later. 10434 Vars.push_back(RefExpr); 10435 SrcExprs.push_back(nullptr); 10436 DstExprs.push_back(nullptr); 10437 AssignmentOps.push_back(nullptr); 10438 } 10439 ValueDecl *D = Res.first; 10440 if (!D) 10441 continue; 10442 10443 QualType Type = D->getType(); 10444 auto *VD = dyn_cast<VarDecl>(D); 10445 10446 // OpenMP [2.14.4.2, Restrictions, p.2] 10447 // A list item that appears in a copyprivate clause may not appear in a 10448 // private or firstprivate clause on the single construct. 10449 if (!VD || !DSAStack->isThreadPrivate(VD)) { 10450 auto DVar = DSAStack->getTopDSA(D, false); 10451 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 10452 DVar.RefExpr) { 10453 Diag(ELoc, diag::err_omp_wrong_dsa) 10454 << getOpenMPClauseName(DVar.CKind) 10455 << getOpenMPClauseName(OMPC_copyprivate); 10456 ReportOriginalDSA(*this, DSAStack, D, DVar); 10457 continue; 10458 } 10459 10460 // OpenMP [2.11.4.2, Restrictions, p.1] 10461 // All list items that appear in a copyprivate clause must be either 10462 // threadprivate or private in the enclosing context. 10463 if (DVar.CKind == OMPC_unknown) { 10464 DVar = DSAStack->getImplicitDSA(D, false); 10465 if (DVar.CKind == OMPC_shared) { 10466 Diag(ELoc, diag::err_omp_required_access) 10467 << getOpenMPClauseName(OMPC_copyprivate) 10468 << "threadprivate or private in the enclosing context"; 10469 ReportOriginalDSA(*this, DSAStack, D, DVar); 10470 continue; 10471 } 10472 } 10473 } 10474 10475 // Variably modified types are not supported. 10476 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 10477 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10478 << getOpenMPClauseName(OMPC_copyprivate) << Type 10479 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10480 bool IsDecl = 10481 !VD || 10482 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10483 Diag(D->getLocation(), 10484 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10485 << D; 10486 continue; 10487 } 10488 10489 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 10490 // A variable of class type (or array thereof) that appears in a 10491 // copyin clause requires an accessible, unambiguous copy assignment 10492 // operator for the class type. 10493 Type = Context.getBaseElementType(Type.getNonReferenceType()) 10494 .getUnqualifiedType(); 10495 auto *SrcVD = 10496 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src", 10497 D->hasAttrs() ? &D->getAttrs() : nullptr); 10498 auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 10499 auto *DstVD = 10500 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst", 10501 D->hasAttrs() ? &D->getAttrs() : nullptr); 10502 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 10503 auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 10504 PseudoDstExpr, PseudoSrcExpr); 10505 if (AssignmentOp.isInvalid()) 10506 continue; 10507 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 10508 /*DiscardedValue=*/true); 10509 if (AssignmentOp.isInvalid()) 10510 continue; 10511 10512 // No need to mark vars as copyprivate, they are already threadprivate or 10513 // implicitly private. 10514 assert(VD || IsOpenMPCapturedDecl(D)); 10515 Vars.push_back( 10516 VD ? RefExpr->IgnoreParens() 10517 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 10518 SrcExprs.push_back(PseudoSrcExpr); 10519 DstExprs.push_back(PseudoDstExpr); 10520 AssignmentOps.push_back(AssignmentOp.get()); 10521 } 10522 10523 if (Vars.empty()) 10524 return nullptr; 10525 10526 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10527 Vars, SrcExprs, DstExprs, AssignmentOps); 10528 } 10529 10530 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 10531 SourceLocation StartLoc, 10532 SourceLocation LParenLoc, 10533 SourceLocation EndLoc) { 10534 if (VarList.empty()) 10535 return nullptr; 10536 10537 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 10538 } 10539 10540 OMPClause * 10541 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 10542 SourceLocation DepLoc, SourceLocation ColonLoc, 10543 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 10544 SourceLocation LParenLoc, SourceLocation EndLoc) { 10545 if (DSAStack->getCurrentDirective() == OMPD_ordered && 10546 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 10547 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 10548 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 10549 return nullptr; 10550 } 10551 if (DSAStack->getCurrentDirective() != OMPD_ordered && 10552 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 10553 DepKind == OMPC_DEPEND_sink)) { 10554 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 10555 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 10556 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 10557 /*Last=*/OMPC_DEPEND_unknown, Except) 10558 << getOpenMPClauseName(OMPC_depend); 10559 return nullptr; 10560 } 10561 SmallVector<Expr *, 8> Vars; 10562 DSAStackTy::OperatorOffsetTy OpsOffs; 10563 llvm::APSInt DepCounter(/*BitWidth=*/32); 10564 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 10565 if (DepKind == OMPC_DEPEND_sink) { 10566 if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) { 10567 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 10568 TotalDepCount.setIsUnsigned(/*Val=*/true); 10569 } 10570 } 10571 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) || 10572 DSAStack->getParentOrderedRegionParam()) { 10573 for (auto &RefExpr : VarList) { 10574 assert(RefExpr && "NULL expr in OpenMP shared clause."); 10575 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 10576 // It will be analyzed later. 10577 Vars.push_back(RefExpr); 10578 continue; 10579 } 10580 10581 SourceLocation ELoc = RefExpr->getExprLoc(); 10582 auto *SimpleExpr = RefExpr->IgnoreParenCasts(); 10583 if (DepKind == OMPC_DEPEND_sink) { 10584 if (DepCounter >= TotalDepCount) { 10585 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 10586 continue; 10587 } 10588 ++DepCounter; 10589 // OpenMP [2.13.9, Summary] 10590 // depend(dependence-type : vec), where dependence-type is: 10591 // 'sink' and where vec is the iteration vector, which has the form: 10592 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 10593 // where n is the value specified by the ordered clause in the loop 10594 // directive, xi denotes the loop iteration variable of the i-th nested 10595 // loop associated with the loop directive, and di is a constant 10596 // non-negative integer. 10597 if (CurContext->isDependentContext()) { 10598 // It will be analyzed later. 10599 Vars.push_back(RefExpr); 10600 continue; 10601 } 10602 SimpleExpr = SimpleExpr->IgnoreImplicit(); 10603 OverloadedOperatorKind OOK = OO_None; 10604 SourceLocation OOLoc; 10605 Expr *LHS = SimpleExpr; 10606 Expr *RHS = nullptr; 10607 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 10608 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 10609 OOLoc = BO->getOperatorLoc(); 10610 LHS = BO->getLHS()->IgnoreParenImpCasts(); 10611 RHS = BO->getRHS()->IgnoreParenImpCasts(); 10612 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 10613 OOK = OCE->getOperator(); 10614 OOLoc = OCE->getOperatorLoc(); 10615 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 10616 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 10617 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 10618 OOK = MCE->getMethodDecl() 10619 ->getNameInfo() 10620 .getName() 10621 .getCXXOverloadedOperator(); 10622 OOLoc = MCE->getCallee()->getExprLoc(); 10623 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 10624 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 10625 } 10626 SourceLocation ELoc; 10627 SourceRange ERange; 10628 auto Res = getPrivateItem(*this, LHS, ELoc, ERange, 10629 /*AllowArraySection=*/false); 10630 if (Res.second) { 10631 // It will be analyzed later. 10632 Vars.push_back(RefExpr); 10633 } 10634 ValueDecl *D = Res.first; 10635 if (!D) 10636 continue; 10637 10638 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 10639 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 10640 continue; 10641 } 10642 if (RHS) { 10643 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 10644 RHS, OMPC_depend, /*StrictlyPositive=*/false); 10645 if (RHSRes.isInvalid()) 10646 continue; 10647 } 10648 if (!CurContext->isDependentContext() && 10649 DSAStack->getParentOrderedRegionParam() && 10650 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 10651 ValueDecl* VD = DSAStack->getParentLoopControlVariable( 10652 DepCounter.getZExtValue()); 10653 if (VD) { 10654 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 10655 << 1 << VD; 10656 } else { 10657 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) << 0; 10658 } 10659 continue; 10660 } 10661 OpsOffs.push_back({RHS, OOK}); 10662 } else { 10663 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 10664 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 10665 (ASE && 10666 !ASE->getBase() 10667 ->getType() 10668 .getNonReferenceType() 10669 ->isPointerType() && 10670 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 10671 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 10672 << RefExpr->getSourceRange(); 10673 continue; 10674 } 10675 bool Suppress = getDiagnostics().getSuppressAllDiagnostics(); 10676 getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 10677 ExprResult Res = CreateBuiltinUnaryOp(SourceLocation(), UO_AddrOf, 10678 RefExpr->IgnoreParenImpCasts()); 10679 getDiagnostics().setSuppressAllDiagnostics(Suppress); 10680 if (!Res.isUsable() && !isa<OMPArraySectionExpr>(SimpleExpr)) { 10681 Diag(ELoc, diag::err_omp_expected_addressable_lvalue_or_array_item) 10682 << RefExpr->getSourceRange(); 10683 continue; 10684 } 10685 } 10686 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 10687 } 10688 10689 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 10690 TotalDepCount > VarList.size() && 10691 DSAStack->getParentOrderedRegionParam() && 10692 DSAStack->getParentLoopControlVariable(VarList.size() + 1)) { 10693 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) << 1 10694 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 10695 } 10696 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 10697 Vars.empty()) 10698 return nullptr; 10699 } 10700 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10701 DepKind, DepLoc, ColonLoc, Vars); 10702 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) 10703 DSAStack->addDoacrossDependClause(C, OpsOffs); 10704 return C; 10705 } 10706 10707 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 10708 SourceLocation LParenLoc, 10709 SourceLocation EndLoc) { 10710 Expr *ValExpr = Device; 10711 Stmt *HelperValStmt = nullptr; 10712 10713 // OpenMP [2.9.1, Restrictions] 10714 // The device expression must evaluate to a non-negative integer value. 10715 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 10716 /*StrictlyPositive=*/false)) 10717 return nullptr; 10718 10719 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10720 if (isOpenMPTargetExecutionDirective(DKind) && 10721 !CurContext->isDependentContext()) { 10722 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 10723 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10724 HelperValStmt = buildPreInits(Context, Captures); 10725 } 10726 10727 return new (Context) 10728 OMPDeviceClause(ValExpr, HelperValStmt, StartLoc, LParenLoc, EndLoc); 10729 } 10730 10731 static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 10732 DSAStackTy *Stack, QualType QTy) { 10733 NamedDecl *ND; 10734 if (QTy->isIncompleteType(&ND)) { 10735 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 10736 return false; 10737 } 10738 return true; 10739 } 10740 10741 /// \brief Return true if it can be proven that the provided array expression 10742 /// (array section or array subscript) does NOT specify the whole size of the 10743 /// array whose base type is \a BaseQTy. 10744 static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 10745 const Expr *E, 10746 QualType BaseQTy) { 10747 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 10748 10749 // If this is an array subscript, it refers to the whole size if the size of 10750 // the dimension is constant and equals 1. Also, an array section assumes the 10751 // format of an array subscript if no colon is used. 10752 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 10753 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 10754 return ATy->getSize().getSExtValue() != 1; 10755 // Size can't be evaluated statically. 10756 return false; 10757 } 10758 10759 assert(OASE && "Expecting array section if not an array subscript."); 10760 auto *LowerBound = OASE->getLowerBound(); 10761 auto *Length = OASE->getLength(); 10762 10763 // If there is a lower bound that does not evaluates to zero, we are not 10764 // covering the whole dimension. 10765 if (LowerBound) { 10766 llvm::APSInt ConstLowerBound; 10767 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) 10768 return false; // Can't get the integer value as a constant. 10769 if (ConstLowerBound.getSExtValue()) 10770 return true; 10771 } 10772 10773 // If we don't have a length we covering the whole dimension. 10774 if (!Length) 10775 return false; 10776 10777 // If the base is a pointer, we don't have a way to get the size of the 10778 // pointee. 10779 if (BaseQTy->isPointerType()) 10780 return false; 10781 10782 // We can only check if the length is the same as the size of the dimension 10783 // if we have a constant array. 10784 auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 10785 if (!CATy) 10786 return false; 10787 10788 llvm::APSInt ConstLength; 10789 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 10790 return false; // Can't get the integer value as a constant. 10791 10792 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 10793 } 10794 10795 // Return true if it can be proven that the provided array expression (array 10796 // section or array subscript) does NOT specify a single element of the array 10797 // whose base type is \a BaseQTy. 10798 static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 10799 const Expr *E, 10800 QualType BaseQTy) { 10801 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 10802 10803 // An array subscript always refer to a single element. Also, an array section 10804 // assumes the format of an array subscript if no colon is used. 10805 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 10806 return false; 10807 10808 assert(OASE && "Expecting array section if not an array subscript."); 10809 auto *Length = OASE->getLength(); 10810 10811 // If we don't have a length we have to check if the array has unitary size 10812 // for this dimension. Also, we should always expect a length if the base type 10813 // is pointer. 10814 if (!Length) { 10815 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 10816 return ATy->getSize().getSExtValue() != 1; 10817 // We cannot assume anything. 10818 return false; 10819 } 10820 10821 // Check if the length evaluates to 1. 10822 llvm::APSInt ConstLength; 10823 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 10824 return false; // Can't get the integer value as a constant. 10825 10826 return ConstLength.getSExtValue() != 1; 10827 } 10828 10829 // Return the expression of the base of the mappable expression or null if it 10830 // cannot be determined and do all the necessary checks to see if the expression 10831 // is valid as a standalone mappable expression. In the process, record all the 10832 // components of the expression. 10833 static Expr *CheckMapClauseExpressionBase( 10834 Sema &SemaRef, Expr *E, 10835 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 10836 OpenMPClauseKind CKind) { 10837 SourceLocation ELoc = E->getExprLoc(); 10838 SourceRange ERange = E->getSourceRange(); 10839 10840 // The base of elements of list in a map clause have to be either: 10841 // - a reference to variable or field. 10842 // - a member expression. 10843 // - an array expression. 10844 // 10845 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 10846 // reference to 'r'. 10847 // 10848 // If we have: 10849 // 10850 // struct SS { 10851 // Bla S; 10852 // foo() { 10853 // #pragma omp target map (S.Arr[:12]); 10854 // } 10855 // } 10856 // 10857 // We want to retrieve the member expression 'this->S'; 10858 10859 Expr *RelevantExpr = nullptr; 10860 10861 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 10862 // If a list item is an array section, it must specify contiguous storage. 10863 // 10864 // For this restriction it is sufficient that we make sure only references 10865 // to variables or fields and array expressions, and that no array sections 10866 // exist except in the rightmost expression (unless they cover the whole 10867 // dimension of the array). E.g. these would be invalid: 10868 // 10869 // r.ArrS[3:5].Arr[6:7] 10870 // 10871 // r.ArrS[3:5].x 10872 // 10873 // but these would be valid: 10874 // r.ArrS[3].Arr[6:7] 10875 // 10876 // r.ArrS[3].x 10877 10878 bool AllowUnitySizeArraySection = true; 10879 bool AllowWholeSizeArraySection = true; 10880 10881 while (!RelevantExpr) { 10882 E = E->IgnoreParenImpCasts(); 10883 10884 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 10885 if (!isa<VarDecl>(CurE->getDecl())) 10886 break; 10887 10888 RelevantExpr = CurE; 10889 10890 // If we got a reference to a declaration, we should not expect any array 10891 // section before that. 10892 AllowUnitySizeArraySection = false; 10893 AllowWholeSizeArraySection = false; 10894 10895 // Record the component. 10896 CurComponents.push_back(OMPClauseMappableExprCommon::MappableComponent( 10897 CurE, CurE->getDecl())); 10898 continue; 10899 } 10900 10901 if (auto *CurE = dyn_cast<MemberExpr>(E)) { 10902 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 10903 10904 if (isa<CXXThisExpr>(BaseE)) 10905 // We found a base expression: this->Val. 10906 RelevantExpr = CurE; 10907 else 10908 E = BaseE; 10909 10910 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 10911 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 10912 << CurE->getSourceRange(); 10913 break; 10914 } 10915 10916 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 10917 10918 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 10919 // A bit-field cannot appear in a map clause. 10920 // 10921 if (FD->isBitField()) { 10922 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 10923 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 10924 break; 10925 } 10926 10927 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 10928 // If the type of a list item is a reference to a type T then the type 10929 // will be considered to be T for all purposes of this clause. 10930 QualType CurType = BaseE->getType().getNonReferenceType(); 10931 10932 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 10933 // A list item cannot be a variable that is a member of a structure with 10934 // a union type. 10935 // 10936 if (auto *RT = CurType->getAs<RecordType>()) 10937 if (RT->isUnionType()) { 10938 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 10939 << CurE->getSourceRange(); 10940 break; 10941 } 10942 10943 // If we got a member expression, we should not expect any array section 10944 // before that: 10945 // 10946 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 10947 // If a list item is an element of a structure, only the rightmost symbol 10948 // of the variable reference can be an array section. 10949 // 10950 AllowUnitySizeArraySection = false; 10951 AllowWholeSizeArraySection = false; 10952 10953 // Record the component. 10954 CurComponents.push_back( 10955 OMPClauseMappableExprCommon::MappableComponent(CurE, FD)); 10956 continue; 10957 } 10958 10959 if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 10960 E = CurE->getBase()->IgnoreParenImpCasts(); 10961 10962 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 10963 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 10964 << 0 << CurE->getSourceRange(); 10965 break; 10966 } 10967 10968 // If we got an array subscript that express the whole dimension we 10969 // can have any array expressions before. If it only expressing part of 10970 // the dimension, we can only have unitary-size array expressions. 10971 if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 10972 E->getType())) 10973 AllowWholeSizeArraySection = false; 10974 10975 // Record the component - we don't have any declaration associated. 10976 CurComponents.push_back( 10977 OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); 10978 continue; 10979 } 10980 10981 if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 10982 E = CurE->getBase()->IgnoreParenImpCasts(); 10983 10984 auto CurType = 10985 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 10986 10987 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 10988 // If the type of a list item is a reference to a type T then the type 10989 // will be considered to be T for all purposes of this clause. 10990 if (CurType->isReferenceType()) 10991 CurType = CurType->getPointeeType(); 10992 10993 bool IsPointer = CurType->isAnyPointerType(); 10994 10995 if (!IsPointer && !CurType->isArrayType()) { 10996 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 10997 << 0 << CurE->getSourceRange(); 10998 break; 10999 } 11000 11001 bool NotWhole = 11002 CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 11003 bool NotUnity = 11004 CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 11005 11006 if (AllowWholeSizeArraySection) { 11007 // Any array section is currently allowed. Allowing a whole size array 11008 // section implies allowing a unity array section as well. 11009 // 11010 // If this array section refers to the whole dimension we can still 11011 // accept other array sections before this one, except if the base is a 11012 // pointer. Otherwise, only unitary sections are accepted. 11013 if (NotWhole || IsPointer) 11014 AllowWholeSizeArraySection = false; 11015 } else if (AllowUnitySizeArraySection && NotUnity) { 11016 // A unity or whole array section is not allowed and that is not 11017 // compatible with the properties of the current array section. 11018 SemaRef.Diag( 11019 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 11020 << CurE->getSourceRange(); 11021 break; 11022 } 11023 11024 // Record the component - we don't have any declaration associated. 11025 CurComponents.push_back( 11026 OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); 11027 continue; 11028 } 11029 11030 // If nothing else worked, this is not a valid map clause expression. 11031 SemaRef.Diag(ELoc, 11032 diag::err_omp_expected_named_var_member_or_array_expression) 11033 << ERange; 11034 break; 11035 } 11036 11037 return RelevantExpr; 11038 } 11039 11040 // Return true if expression E associated with value VD has conflicts with other 11041 // map information. 11042 static bool CheckMapConflicts( 11043 Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E, 11044 bool CurrentRegionOnly, 11045 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 11046 OpenMPClauseKind CKind) { 11047 assert(VD && E); 11048 SourceLocation ELoc = E->getExprLoc(); 11049 SourceRange ERange = E->getSourceRange(); 11050 11051 // In order to easily check the conflicts we need to match each component of 11052 // the expression under test with the components of the expressions that are 11053 // already in the stack. 11054 11055 assert(!CurComponents.empty() && "Map clause expression with no components!"); 11056 assert(CurComponents.back().getAssociatedDeclaration() == VD && 11057 "Map clause expression with unexpected base!"); 11058 11059 // Variables to help detecting enclosing problems in data environment nests. 11060 bool IsEnclosedByDataEnvironmentExpr = false; 11061 const Expr *EnclosingExpr = nullptr; 11062 11063 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 11064 VD, CurrentRegionOnly, 11065 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef 11066 StackComponents, 11067 OpenMPClauseKind) -> bool { 11068 11069 assert(!StackComponents.empty() && 11070 "Map clause expression with no components!"); 11071 assert(StackComponents.back().getAssociatedDeclaration() == VD && 11072 "Map clause expression with unexpected base!"); 11073 11074 // The whole expression in the stack. 11075 auto *RE = StackComponents.front().getAssociatedExpression(); 11076 11077 // Expressions must start from the same base. Here we detect at which 11078 // point both expressions diverge from each other and see if we can 11079 // detect if the memory referred to both expressions is contiguous and 11080 // do not overlap. 11081 auto CI = CurComponents.rbegin(); 11082 auto CE = CurComponents.rend(); 11083 auto SI = StackComponents.rbegin(); 11084 auto SE = StackComponents.rend(); 11085 for (; CI != CE && SI != SE; ++CI, ++SI) { 11086 11087 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 11088 // At most one list item can be an array item derived from a given 11089 // variable in map clauses of the same construct. 11090 if (CurrentRegionOnly && 11091 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 11092 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 11093 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 11094 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 11095 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 11096 diag::err_omp_multiple_array_items_in_map_clause) 11097 << CI->getAssociatedExpression()->getSourceRange(); 11098 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 11099 diag::note_used_here) 11100 << SI->getAssociatedExpression()->getSourceRange(); 11101 return true; 11102 } 11103 11104 // Do both expressions have the same kind? 11105 if (CI->getAssociatedExpression()->getStmtClass() != 11106 SI->getAssociatedExpression()->getStmtClass()) 11107 break; 11108 11109 // Are we dealing with different variables/fields? 11110 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 11111 break; 11112 } 11113 // Check if the extra components of the expressions in the enclosing 11114 // data environment are redundant for the current base declaration. 11115 // If they are, the maps completely overlap, which is legal. 11116 for (; SI != SE; ++SI) { 11117 QualType Type; 11118 if (auto *ASE = 11119 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 11120 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 11121 } else if (auto *OASE = dyn_cast<OMPArraySectionExpr>( 11122 SI->getAssociatedExpression())) { 11123 auto *E = OASE->getBase()->IgnoreParenImpCasts(); 11124 Type = 11125 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 11126 } 11127 if (Type.isNull() || Type->isAnyPointerType() || 11128 CheckArrayExpressionDoesNotReferToWholeSize( 11129 SemaRef, SI->getAssociatedExpression(), Type)) 11130 break; 11131 } 11132 11133 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 11134 // List items of map clauses in the same construct must not share 11135 // original storage. 11136 // 11137 // If the expressions are exactly the same or one is a subset of the 11138 // other, it means they are sharing storage. 11139 if (CI == CE && SI == SE) { 11140 if (CurrentRegionOnly) { 11141 if (CKind == OMPC_map) 11142 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 11143 else { 11144 assert(CKind == OMPC_to || CKind == OMPC_from); 11145 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 11146 << ERange; 11147 } 11148 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 11149 << RE->getSourceRange(); 11150 return true; 11151 } else { 11152 // If we find the same expression in the enclosing data environment, 11153 // that is legal. 11154 IsEnclosedByDataEnvironmentExpr = true; 11155 return false; 11156 } 11157 } 11158 11159 QualType DerivedType = 11160 std::prev(CI)->getAssociatedDeclaration()->getType(); 11161 SourceLocation DerivedLoc = 11162 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 11163 11164 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 11165 // If the type of a list item is a reference to a type T then the type 11166 // will be considered to be T for all purposes of this clause. 11167 DerivedType = DerivedType.getNonReferenceType(); 11168 11169 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 11170 // A variable for which the type is pointer and an array section 11171 // derived from that variable must not appear as list items of map 11172 // clauses of the same construct. 11173 // 11174 // Also, cover one of the cases in: 11175 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 11176 // If any part of the original storage of a list item has corresponding 11177 // storage in the device data environment, all of the original storage 11178 // must have corresponding storage in the device data environment. 11179 // 11180 if (DerivedType->isAnyPointerType()) { 11181 if (CI == CE || SI == SE) { 11182 SemaRef.Diag( 11183 DerivedLoc, 11184 diag::err_omp_pointer_mapped_along_with_derived_section) 11185 << DerivedLoc; 11186 } else { 11187 assert(CI != CE && SI != SE); 11188 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced) 11189 << DerivedLoc; 11190 } 11191 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 11192 << RE->getSourceRange(); 11193 return true; 11194 } 11195 11196 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 11197 // List items of map clauses in the same construct must not share 11198 // original storage. 11199 // 11200 // An expression is a subset of the other. 11201 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 11202 if (CKind == OMPC_map) 11203 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 11204 else { 11205 assert(CKind == OMPC_to || CKind == OMPC_from); 11206 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 11207 << ERange; 11208 } 11209 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 11210 << RE->getSourceRange(); 11211 return true; 11212 } 11213 11214 // The current expression uses the same base as other expression in the 11215 // data environment but does not contain it completely. 11216 if (!CurrentRegionOnly && SI != SE) 11217 EnclosingExpr = RE; 11218 11219 // The current expression is a subset of the expression in the data 11220 // environment. 11221 IsEnclosedByDataEnvironmentExpr |= 11222 (!CurrentRegionOnly && CI != CE && SI == SE); 11223 11224 return false; 11225 }); 11226 11227 if (CurrentRegionOnly) 11228 return FoundError; 11229 11230 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 11231 // If any part of the original storage of a list item has corresponding 11232 // storage in the device data environment, all of the original storage must 11233 // have corresponding storage in the device data environment. 11234 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 11235 // If a list item is an element of a structure, and a different element of 11236 // the structure has a corresponding list item in the device data environment 11237 // prior to a task encountering the construct associated with the map clause, 11238 // then the list item must also have a corresponding list item in the device 11239 // data environment prior to the task encountering the construct. 11240 // 11241 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 11242 SemaRef.Diag(ELoc, 11243 diag::err_omp_original_storage_is_shared_and_does_not_contain) 11244 << ERange; 11245 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 11246 << EnclosingExpr->getSourceRange(); 11247 return true; 11248 } 11249 11250 return FoundError; 11251 } 11252 11253 namespace { 11254 // Utility struct that gathers all the related lists associated with a mappable 11255 // expression. 11256 struct MappableVarListInfo final { 11257 // The list of expressions. 11258 ArrayRef<Expr *> VarList; 11259 // The list of processed expressions. 11260 SmallVector<Expr *, 16> ProcessedVarList; 11261 // The mappble components for each expression. 11262 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 11263 // The base declaration of the variable. 11264 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 11265 11266 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 11267 // We have a list of components and base declarations for each entry in the 11268 // variable list. 11269 VarComponents.reserve(VarList.size()); 11270 VarBaseDeclarations.reserve(VarList.size()); 11271 } 11272 }; 11273 } 11274 11275 // Check the validity of the provided variable list for the provided clause kind 11276 // \a CKind. In the check process the valid expressions, and mappable expression 11277 // components and variables are extracted and used to fill \a Vars, 11278 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and 11279 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'. 11280 static void 11281 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, 11282 OpenMPClauseKind CKind, MappableVarListInfo &MVLI, 11283 SourceLocation StartLoc, 11284 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 11285 bool IsMapTypeImplicit = false) { 11286 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 11287 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 11288 "Unexpected clause kind with mappable expressions!"); 11289 11290 // Keep track of the mappable components and base declarations in this clause. 11291 // Each entry in the list is going to have a list of components associated. We 11292 // record each set of the components so that we can build the clause later on. 11293 // In the end we should have the same amount of declarations and component 11294 // lists. 11295 11296 for (auto &RE : MVLI.VarList) { 11297 assert(RE && "Null expr in omp to/from/map clause"); 11298 SourceLocation ELoc = RE->getExprLoc(); 11299 11300 auto *VE = RE->IgnoreParenLValueCasts(); 11301 11302 if (VE->isValueDependent() || VE->isTypeDependent() || 11303 VE->isInstantiationDependent() || 11304 VE->containsUnexpandedParameterPack()) { 11305 // We can only analyze this information once the missing information is 11306 // resolved. 11307 MVLI.ProcessedVarList.push_back(RE); 11308 continue; 11309 } 11310 11311 auto *SimpleExpr = RE->IgnoreParenCasts(); 11312 11313 if (!RE->IgnoreParenImpCasts()->isLValue()) { 11314 SemaRef.Diag(ELoc, 11315 diag::err_omp_expected_named_var_member_or_array_expression) 11316 << RE->getSourceRange(); 11317 continue; 11318 } 11319 11320 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 11321 ValueDecl *CurDeclaration = nullptr; 11322 11323 // Obtain the array or member expression bases if required. Also, fill the 11324 // components array with all the components identified in the process. 11325 auto *BE = 11326 CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind); 11327 if (!BE) 11328 continue; 11329 11330 assert(!CurComponents.empty() && 11331 "Invalid mappable expression information."); 11332 11333 // For the following checks, we rely on the base declaration which is 11334 // expected to be associated with the last component. The declaration is 11335 // expected to be a variable or a field (if 'this' is being mapped). 11336 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 11337 assert(CurDeclaration && "Null decl on map clause."); 11338 assert( 11339 CurDeclaration->isCanonicalDecl() && 11340 "Expecting components to have associated only canonical declarations."); 11341 11342 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 11343 auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 11344 11345 assert((VD || FD) && "Only variables or fields are expected here!"); 11346 (void)FD; 11347 11348 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 11349 // threadprivate variables cannot appear in a map clause. 11350 // OpenMP 4.5 [2.10.5, target update Construct] 11351 // threadprivate variables cannot appear in a from clause. 11352 if (VD && DSAS->isThreadPrivate(VD)) { 11353 auto DVar = DSAS->getTopDSA(VD, false); 11354 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 11355 << getOpenMPClauseName(CKind); 11356 ReportOriginalDSA(SemaRef, DSAS, VD, DVar); 11357 continue; 11358 } 11359 11360 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 11361 // A list item cannot appear in both a map clause and a data-sharing 11362 // attribute clause on the same construct. 11363 11364 // Check conflicts with other map clause expressions. We check the conflicts 11365 // with the current construct separately from the enclosing data 11366 // environment, because the restrictions are different. We only have to 11367 // check conflicts across regions for the map clauses. 11368 if (CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 11369 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 11370 break; 11371 if (CKind == OMPC_map && 11372 CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 11373 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 11374 break; 11375 11376 // OpenMP 4.5 [2.10.5, target update Construct] 11377 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 11378 // If the type of a list item is a reference to a type T then the type will 11379 // be considered to be T for all purposes of this clause. 11380 QualType Type = CurDeclaration->getType().getNonReferenceType(); 11381 11382 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 11383 // A list item in a to or from clause must have a mappable type. 11384 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 11385 // A list item must have a mappable type. 11386 if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 11387 DSAS, Type)) 11388 continue; 11389 11390 if (CKind == OMPC_map) { 11391 // target enter data 11392 // OpenMP [2.10.2, Restrictions, p. 99] 11393 // A map-type must be specified in all map clauses and must be either 11394 // to or alloc. 11395 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 11396 if (DKind == OMPD_target_enter_data && 11397 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 11398 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 11399 << (IsMapTypeImplicit ? 1 : 0) 11400 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 11401 << getOpenMPDirectiveName(DKind); 11402 continue; 11403 } 11404 11405 // target exit_data 11406 // OpenMP [2.10.3, Restrictions, p. 102] 11407 // A map-type must be specified in all map clauses and must be either 11408 // from, release, or delete. 11409 if (DKind == OMPD_target_exit_data && 11410 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 11411 MapType == OMPC_MAP_delete)) { 11412 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 11413 << (IsMapTypeImplicit ? 1 : 0) 11414 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 11415 << getOpenMPDirectiveName(DKind); 11416 continue; 11417 } 11418 11419 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11420 // A list item cannot appear in both a map clause and a data-sharing 11421 // attribute clause on the same construct 11422 if ((DKind == OMPD_target || DKind == OMPD_target_teams || 11423 DKind == OMPD_target_teams_distribute || 11424 DKind == OMPD_target_teams_distribute_parallel_for || 11425 DKind == OMPD_target_teams_distribute_parallel_for_simd || 11426 DKind == OMPD_target_teams_distribute_simd) && VD) { 11427 auto DVar = DSAS->getTopDSA(VD, false); 11428 if (isOpenMPPrivate(DVar.CKind)) { 11429 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11430 << getOpenMPClauseName(DVar.CKind) 11431 << getOpenMPClauseName(OMPC_map) 11432 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 11433 ReportOriginalDSA(SemaRef, DSAS, CurDeclaration, DVar); 11434 continue; 11435 } 11436 } 11437 } 11438 11439 // Save the current expression. 11440 MVLI.ProcessedVarList.push_back(RE); 11441 11442 // Store the components in the stack so that they can be used to check 11443 // against other clauses later on. 11444 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 11445 /*WhereFoundClauseKind=*/OMPC_map); 11446 11447 // Save the components and declaration to create the clause. For purposes of 11448 // the clause creation, any component list that has has base 'this' uses 11449 // null as base declaration. 11450 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 11451 MVLI.VarComponents.back().append(CurComponents.begin(), 11452 CurComponents.end()); 11453 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 11454 : CurDeclaration); 11455 } 11456 } 11457 11458 OMPClause * 11459 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, 11460 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 11461 SourceLocation MapLoc, SourceLocation ColonLoc, 11462 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 11463 SourceLocation LParenLoc, SourceLocation EndLoc) { 11464 MappableVarListInfo MVLI(VarList); 11465 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc, 11466 MapType, IsMapTypeImplicit); 11467 11468 // We need to produce a map clause even if we don't have variables so that 11469 // other diagnostics related with non-existing map clauses are accurate. 11470 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11471 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 11472 MVLI.VarComponents, MapTypeModifier, MapType, 11473 IsMapTypeImplicit, MapLoc); 11474 } 11475 11476 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 11477 TypeResult ParsedType) { 11478 assert(ParsedType.isUsable()); 11479 11480 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 11481 if (ReductionType.isNull()) 11482 return QualType(); 11483 11484 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 11485 // A type name in a declare reduction directive cannot be a function type, an 11486 // array type, a reference type, or a type qualified with const, volatile or 11487 // restrict. 11488 if (ReductionType.hasQualifiers()) { 11489 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 11490 return QualType(); 11491 } 11492 11493 if (ReductionType->isFunctionType()) { 11494 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 11495 return QualType(); 11496 } 11497 if (ReductionType->isReferenceType()) { 11498 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 11499 return QualType(); 11500 } 11501 if (ReductionType->isArrayType()) { 11502 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 11503 return QualType(); 11504 } 11505 return ReductionType; 11506 } 11507 11508 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 11509 Scope *S, DeclContext *DC, DeclarationName Name, 11510 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 11511 AccessSpecifier AS, Decl *PrevDeclInScope) { 11512 SmallVector<Decl *, 8> Decls; 11513 Decls.reserve(ReductionTypes.size()); 11514 11515 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 11516 ForRedeclaration); 11517 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 11518 // A reduction-identifier may not be re-declared in the current scope for the 11519 // same type or for a type that is compatible according to the base language 11520 // rules. 11521 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 11522 OMPDeclareReductionDecl *PrevDRD = nullptr; 11523 bool InCompoundScope = true; 11524 if (S != nullptr) { 11525 // Find previous declaration with the same name not referenced in other 11526 // declarations. 11527 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 11528 InCompoundScope = 11529 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 11530 LookupName(Lookup, S); 11531 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 11532 /*AllowInlineNamespace=*/false); 11533 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 11534 auto Filter = Lookup.makeFilter(); 11535 while (Filter.hasNext()) { 11536 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 11537 if (InCompoundScope) { 11538 auto I = UsedAsPrevious.find(PrevDecl); 11539 if (I == UsedAsPrevious.end()) 11540 UsedAsPrevious[PrevDecl] = false; 11541 if (auto *D = PrevDecl->getPrevDeclInScope()) 11542 UsedAsPrevious[D] = true; 11543 } 11544 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 11545 PrevDecl->getLocation(); 11546 } 11547 Filter.done(); 11548 if (InCompoundScope) { 11549 for (auto &PrevData : UsedAsPrevious) { 11550 if (!PrevData.second) { 11551 PrevDRD = PrevData.first; 11552 break; 11553 } 11554 } 11555 } 11556 } else if (PrevDeclInScope != nullptr) { 11557 auto *PrevDRDInScope = PrevDRD = 11558 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 11559 do { 11560 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 11561 PrevDRDInScope->getLocation(); 11562 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 11563 } while (PrevDRDInScope != nullptr); 11564 } 11565 for (auto &TyData : ReductionTypes) { 11566 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 11567 bool Invalid = false; 11568 if (I != PreviousRedeclTypes.end()) { 11569 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 11570 << TyData.first; 11571 Diag(I->second, diag::note_previous_definition); 11572 Invalid = true; 11573 } 11574 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 11575 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 11576 Name, TyData.first, PrevDRD); 11577 DC->addDecl(DRD); 11578 DRD->setAccess(AS); 11579 Decls.push_back(DRD); 11580 if (Invalid) 11581 DRD->setInvalidDecl(); 11582 else 11583 PrevDRD = DRD; 11584 } 11585 11586 return DeclGroupPtrTy::make( 11587 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 11588 } 11589 11590 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 11591 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11592 11593 // Enter new function scope. 11594 PushFunctionScope(); 11595 getCurFunction()->setHasBranchProtectedScope(); 11596 getCurFunction()->setHasOMPDeclareReductionCombiner(); 11597 11598 if (S != nullptr) 11599 PushDeclContext(S, DRD); 11600 else 11601 CurContext = DRD; 11602 11603 PushExpressionEvaluationContext( 11604 ExpressionEvaluationContext::PotentiallyEvaluated); 11605 11606 QualType ReductionType = DRD->getType(); 11607 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 11608 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 11609 // uses semantics of argument handles by value, but it should be passed by 11610 // reference. C lang does not support references, so pass all parameters as 11611 // pointers. 11612 // Create 'T omp_in;' variable. 11613 auto *OmpInParm = 11614 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 11615 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 11616 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 11617 // uses semantics of argument handles by value, but it should be passed by 11618 // reference. C lang does not support references, so pass all parameters as 11619 // pointers. 11620 // Create 'T omp_out;' variable. 11621 auto *OmpOutParm = 11622 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 11623 if (S != nullptr) { 11624 PushOnScopeChains(OmpInParm, S); 11625 PushOnScopeChains(OmpOutParm, S); 11626 } else { 11627 DRD->addDecl(OmpInParm); 11628 DRD->addDecl(OmpOutParm); 11629 } 11630 } 11631 11632 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 11633 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11634 DiscardCleanupsInEvaluationContext(); 11635 PopExpressionEvaluationContext(); 11636 11637 PopDeclContext(); 11638 PopFunctionScopeInfo(); 11639 11640 if (Combiner != nullptr) 11641 DRD->setCombiner(Combiner); 11642 else 11643 DRD->setInvalidDecl(); 11644 } 11645 11646 VarDecl *Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 11647 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11648 11649 // Enter new function scope. 11650 PushFunctionScope(); 11651 getCurFunction()->setHasBranchProtectedScope(); 11652 11653 if (S != nullptr) 11654 PushDeclContext(S, DRD); 11655 else 11656 CurContext = DRD; 11657 11658 PushExpressionEvaluationContext( 11659 ExpressionEvaluationContext::PotentiallyEvaluated); 11660 11661 QualType ReductionType = DRD->getType(); 11662 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 11663 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 11664 // uses semantics of argument handles by value, but it should be passed by 11665 // reference. C lang does not support references, so pass all parameters as 11666 // pointers. 11667 // Create 'T omp_priv;' variable. 11668 auto *OmpPrivParm = 11669 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 11670 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 11671 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 11672 // uses semantics of argument handles by value, but it should be passed by 11673 // reference. C lang does not support references, so pass all parameters as 11674 // pointers. 11675 // Create 'T omp_orig;' variable. 11676 auto *OmpOrigParm = 11677 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 11678 if (S != nullptr) { 11679 PushOnScopeChains(OmpPrivParm, S); 11680 PushOnScopeChains(OmpOrigParm, S); 11681 } else { 11682 DRD->addDecl(OmpPrivParm); 11683 DRD->addDecl(OmpOrigParm); 11684 } 11685 return OmpPrivParm; 11686 } 11687 11688 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, Expr *Initializer, 11689 VarDecl *OmpPrivParm) { 11690 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11691 DiscardCleanupsInEvaluationContext(); 11692 PopExpressionEvaluationContext(); 11693 11694 PopDeclContext(); 11695 PopFunctionScopeInfo(); 11696 11697 if (Initializer != nullptr) { 11698 DRD->setInitializer(Initializer, OMPDeclareReductionDecl::CallInit); 11699 } else if (OmpPrivParm->hasInit()) { 11700 DRD->setInitializer(OmpPrivParm->getInit(), 11701 OmpPrivParm->isDirectInit() 11702 ? OMPDeclareReductionDecl::DirectInit 11703 : OMPDeclareReductionDecl::CopyInit); 11704 } else { 11705 DRD->setInvalidDecl(); 11706 } 11707 } 11708 11709 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 11710 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 11711 for (auto *D : DeclReductions.get()) { 11712 if (IsValid) { 11713 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11714 if (S != nullptr) 11715 PushOnScopeChains(DRD, S, /*AddToContext=*/false); 11716 } else 11717 D->setInvalidDecl(); 11718 } 11719 return DeclReductions; 11720 } 11721 11722 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 11723 SourceLocation StartLoc, 11724 SourceLocation LParenLoc, 11725 SourceLocation EndLoc) { 11726 Expr *ValExpr = NumTeams; 11727 Stmt *HelperValStmt = nullptr; 11728 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11729 11730 // OpenMP [teams Constrcut, Restrictions] 11731 // The num_teams expression must evaluate to a positive integer value. 11732 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 11733 /*StrictlyPositive=*/true)) 11734 return nullptr; 11735 11736 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11737 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 11738 if (CaptureRegion != OMPD_unknown) { 11739 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 11740 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11741 HelperValStmt = buildPreInits(Context, Captures); 11742 } 11743 11744 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 11745 StartLoc, LParenLoc, EndLoc); 11746 } 11747 11748 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 11749 SourceLocation StartLoc, 11750 SourceLocation LParenLoc, 11751 SourceLocation EndLoc) { 11752 Expr *ValExpr = ThreadLimit; 11753 Stmt *HelperValStmt = nullptr; 11754 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11755 11756 // OpenMP [teams Constrcut, Restrictions] 11757 // The thread_limit expression must evaluate to a positive integer value. 11758 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 11759 /*StrictlyPositive=*/true)) 11760 return nullptr; 11761 11762 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11763 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 11764 if (CaptureRegion != OMPD_unknown) { 11765 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 11766 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11767 HelperValStmt = buildPreInits(Context, Captures); 11768 } 11769 11770 return new (Context) OMPThreadLimitClause( 11771 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11772 } 11773 11774 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 11775 SourceLocation StartLoc, 11776 SourceLocation LParenLoc, 11777 SourceLocation EndLoc) { 11778 Expr *ValExpr = Priority; 11779 11780 // OpenMP [2.9.1, task Constrcut] 11781 // The priority-value is a non-negative numerical scalar expression. 11782 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 11783 /*StrictlyPositive=*/false)) 11784 return nullptr; 11785 11786 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 11787 } 11788 11789 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 11790 SourceLocation StartLoc, 11791 SourceLocation LParenLoc, 11792 SourceLocation EndLoc) { 11793 Expr *ValExpr = Grainsize; 11794 11795 // OpenMP [2.9.2, taskloop Constrcut] 11796 // The parameter of the grainsize clause must be a positive integer 11797 // expression. 11798 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 11799 /*StrictlyPositive=*/true)) 11800 return nullptr; 11801 11802 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 11803 } 11804 11805 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 11806 SourceLocation StartLoc, 11807 SourceLocation LParenLoc, 11808 SourceLocation EndLoc) { 11809 Expr *ValExpr = NumTasks; 11810 11811 // OpenMP [2.9.2, taskloop Constrcut] 11812 // The parameter of the num_tasks clause must be a positive integer 11813 // expression. 11814 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 11815 /*StrictlyPositive=*/true)) 11816 return nullptr; 11817 11818 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 11819 } 11820 11821 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 11822 SourceLocation LParenLoc, 11823 SourceLocation EndLoc) { 11824 // OpenMP [2.13.2, critical construct, Description] 11825 // ... where hint-expression is an integer constant expression that evaluates 11826 // to a valid lock hint. 11827 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 11828 if (HintExpr.isInvalid()) 11829 return nullptr; 11830 return new (Context) 11831 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 11832 } 11833 11834 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 11835 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11836 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 11837 SourceLocation EndLoc) { 11838 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 11839 std::string Values; 11840 Values += "'"; 11841 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 11842 Values += "'"; 11843 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11844 << Values << getOpenMPClauseName(OMPC_dist_schedule); 11845 return nullptr; 11846 } 11847 Expr *ValExpr = ChunkSize; 11848 Stmt *HelperValStmt = nullptr; 11849 if (ChunkSize) { 11850 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11851 !ChunkSize->isInstantiationDependent() && 11852 !ChunkSize->containsUnexpandedParameterPack()) { 11853 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 11854 ExprResult Val = 11855 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11856 if (Val.isInvalid()) 11857 return nullptr; 11858 11859 ValExpr = Val.get(); 11860 11861 // OpenMP [2.7.1, Restrictions] 11862 // chunk_size must be a loop invariant integer expression with a positive 11863 // value. 11864 llvm::APSInt Result; 11865 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11866 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11867 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11868 << "dist_schedule" << ChunkSize->getSourceRange(); 11869 return nullptr; 11870 } 11871 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) && 11872 !CurContext->isDependentContext()) { 11873 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 11874 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11875 HelperValStmt = buildPreInits(Context, Captures); 11876 } 11877 } 11878 } 11879 11880 return new (Context) 11881 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 11882 Kind, ValExpr, HelperValStmt); 11883 } 11884 11885 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 11886 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 11887 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 11888 SourceLocation KindLoc, SourceLocation EndLoc) { 11889 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 11890 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 11891 std::string Value; 11892 SourceLocation Loc; 11893 Value += "'"; 11894 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 11895 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 11896 OMPC_DEFAULTMAP_MODIFIER_tofrom); 11897 Loc = MLoc; 11898 } else { 11899 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 11900 OMPC_DEFAULTMAP_scalar); 11901 Loc = KindLoc; 11902 } 11903 Value += "'"; 11904 Diag(Loc, diag::err_omp_unexpected_clause_value) 11905 << Value << getOpenMPClauseName(OMPC_defaultmap); 11906 return nullptr; 11907 } 11908 11909 return new (Context) 11910 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 11911 } 11912 11913 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 11914 DeclContext *CurLexicalContext = getCurLexicalContext(); 11915 if (!CurLexicalContext->isFileContext() && 11916 !CurLexicalContext->isExternCContext() && 11917 !CurLexicalContext->isExternCXXContext() && 11918 !isa<CXXRecordDecl>(CurLexicalContext) && 11919 !isa<ClassTemplateDecl>(CurLexicalContext) && 11920 !isa<ClassTemplatePartialSpecializationDecl>(CurLexicalContext) && 11921 !isa<ClassTemplateSpecializationDecl>(CurLexicalContext)) { 11922 Diag(Loc, diag::err_omp_region_not_file_context); 11923 return false; 11924 } 11925 if (IsInOpenMPDeclareTargetContext) { 11926 Diag(Loc, diag::err_omp_enclosed_declare_target); 11927 return false; 11928 } 11929 11930 IsInOpenMPDeclareTargetContext = true; 11931 return true; 11932 } 11933 11934 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 11935 assert(IsInOpenMPDeclareTargetContext && 11936 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 11937 11938 IsInOpenMPDeclareTargetContext = false; 11939 } 11940 11941 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 11942 CXXScopeSpec &ScopeSpec, 11943 const DeclarationNameInfo &Id, 11944 OMPDeclareTargetDeclAttr::MapTypeTy MT, 11945 NamedDeclSetType &SameDirectiveDecls) { 11946 LookupResult Lookup(*this, Id, LookupOrdinaryName); 11947 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 11948 11949 if (Lookup.isAmbiguous()) 11950 return; 11951 Lookup.suppressDiagnostics(); 11952 11953 if (!Lookup.isSingleResult()) { 11954 if (TypoCorrection Corrected = 11955 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, 11956 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), 11957 CTK_ErrorRecovery)) { 11958 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 11959 << Id.getName()); 11960 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 11961 return; 11962 } 11963 11964 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 11965 return; 11966 } 11967 11968 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 11969 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { 11970 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 11971 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 11972 11973 if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) { 11974 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 11975 ND->addAttr(A); 11976 if (ASTMutationListener *ML = Context.getASTMutationListener()) 11977 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 11978 checkDeclIsAllowedInOpenMPTarget(nullptr, ND); 11979 } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) { 11980 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 11981 << Id.getName(); 11982 } 11983 } else 11984 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 11985 } 11986 11987 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 11988 Sema &SemaRef, Decl *D) { 11989 if (!D) 11990 return; 11991 Decl *LD = nullptr; 11992 if (isa<TagDecl>(D)) { 11993 LD = cast<TagDecl>(D)->getDefinition(); 11994 } else if (isa<VarDecl>(D)) { 11995 LD = cast<VarDecl>(D)->getDefinition(); 11996 11997 // If this is an implicit variable that is legal and we do not need to do 11998 // anything. 11999 if (cast<VarDecl>(D)->isImplicit()) { 12000 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12001 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 12002 D->addAttr(A); 12003 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 12004 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 12005 return; 12006 } 12007 12008 } else if (isa<FunctionDecl>(D)) { 12009 const FunctionDecl *FD = nullptr; 12010 if (cast<FunctionDecl>(D)->hasBody(FD)) 12011 LD = const_cast<FunctionDecl *>(FD); 12012 12013 // If the definition is associated with the current declaration in the 12014 // target region (it can be e.g. a lambda) that is legal and we do not need 12015 // to do anything else. 12016 if (LD == D) { 12017 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12018 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 12019 D->addAttr(A); 12020 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 12021 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 12022 return; 12023 } 12024 } 12025 if (!LD) 12026 LD = D; 12027 if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() && 12028 (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) { 12029 // Outlined declaration is not declared target. 12030 if (LD->isOutOfLine()) { 12031 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 12032 SemaRef.Diag(SL, diag::note_used_here) << SR; 12033 } else { 12034 DeclContext *DC = LD->getDeclContext(); 12035 while (DC) { 12036 if (isa<FunctionDecl>(DC) && 12037 cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>()) 12038 break; 12039 DC = DC->getParent(); 12040 } 12041 if (DC) 12042 return; 12043 12044 // Is not declared in target context. 12045 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 12046 SemaRef.Diag(SL, diag::note_used_here) << SR; 12047 } 12048 // Mark decl as declared target to prevent further diagnostic. 12049 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12050 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 12051 D->addAttr(A); 12052 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 12053 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 12054 } 12055 } 12056 12057 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 12058 Sema &SemaRef, DSAStackTy *Stack, 12059 ValueDecl *VD) { 12060 if (VD->hasAttr<OMPDeclareTargetDeclAttr>()) 12061 return true; 12062 if (!CheckTypeMappable(SL, SR, SemaRef, Stack, VD->getType())) 12063 return false; 12064 return true; 12065 } 12066 12067 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D) { 12068 if (!D || D->isInvalidDecl()) 12069 return; 12070 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 12071 SourceLocation SL = E ? E->getLocStart() : D->getLocation(); 12072 // 2.10.6: threadprivate variable cannot appear in a declare target directive. 12073 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 12074 if (DSAStack->isThreadPrivate(VD)) { 12075 Diag(SL, diag::err_omp_threadprivate_in_target); 12076 ReportOriginalDSA(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 12077 return; 12078 } 12079 } 12080 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 12081 // Problem if any with var declared with incomplete type will be reported 12082 // as normal, so no need to check it here. 12083 if ((E || !VD->getType()->isIncompleteType()) && 12084 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) { 12085 // Mark decl as declared target to prevent further diagnostic. 12086 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) { 12087 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12088 Context, OMPDeclareTargetDeclAttr::MT_To); 12089 VD->addAttr(A); 12090 if (ASTMutationListener *ML = Context.getASTMutationListener()) 12091 ML->DeclarationMarkedOpenMPDeclareTarget(VD, A); 12092 } 12093 return; 12094 } 12095 } 12096 if (!E) { 12097 // Checking declaration inside declare target region. 12098 if (!D->hasAttr<OMPDeclareTargetDeclAttr>() && 12099 (isa<VarDecl>(D) || isa<FunctionDecl>(D))) { 12100 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12101 Context, OMPDeclareTargetDeclAttr::MT_To); 12102 D->addAttr(A); 12103 if (ASTMutationListener *ML = Context.getASTMutationListener()) 12104 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 12105 } 12106 return; 12107 } 12108 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 12109 } 12110 12111 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 12112 SourceLocation StartLoc, 12113 SourceLocation LParenLoc, 12114 SourceLocation EndLoc) { 12115 MappableVarListInfo MVLI(VarList); 12116 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc); 12117 if (MVLI.ProcessedVarList.empty()) 12118 return nullptr; 12119 12120 return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12121 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 12122 MVLI.VarComponents); 12123 } 12124 12125 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 12126 SourceLocation StartLoc, 12127 SourceLocation LParenLoc, 12128 SourceLocation EndLoc) { 12129 MappableVarListInfo MVLI(VarList); 12130 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc); 12131 if (MVLI.ProcessedVarList.empty()) 12132 return nullptr; 12133 12134 return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12135 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 12136 MVLI.VarComponents); 12137 } 12138 12139 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 12140 SourceLocation StartLoc, 12141 SourceLocation LParenLoc, 12142 SourceLocation EndLoc) { 12143 MappableVarListInfo MVLI(VarList); 12144 SmallVector<Expr *, 8> PrivateCopies; 12145 SmallVector<Expr *, 8> Inits; 12146 12147 for (auto &RefExpr : VarList) { 12148 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 12149 SourceLocation ELoc; 12150 SourceRange ERange; 12151 Expr *SimpleRefExpr = RefExpr; 12152 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12153 if (Res.second) { 12154 // It will be analyzed later. 12155 MVLI.ProcessedVarList.push_back(RefExpr); 12156 PrivateCopies.push_back(nullptr); 12157 Inits.push_back(nullptr); 12158 } 12159 ValueDecl *D = Res.first; 12160 if (!D) 12161 continue; 12162 12163 QualType Type = D->getType(); 12164 Type = Type.getNonReferenceType().getUnqualifiedType(); 12165 12166 auto *VD = dyn_cast<VarDecl>(D); 12167 12168 // Item should be a pointer or reference to pointer. 12169 if (!Type->isPointerType()) { 12170 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 12171 << 0 << RefExpr->getSourceRange(); 12172 continue; 12173 } 12174 12175 // Build the private variable and the expression that refers to it. 12176 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 12177 D->hasAttrs() ? &D->getAttrs() : nullptr); 12178 if (VDPrivate->isInvalidDecl()) 12179 continue; 12180 12181 CurContext->addDecl(VDPrivate); 12182 auto VDPrivateRefExpr = buildDeclRefExpr( 12183 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12184 12185 // Add temporary variable to initialize the private copy of the pointer. 12186 auto *VDInit = 12187 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 12188 auto *VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12189 RefExpr->getExprLoc()); 12190 AddInitializerToDecl(VDPrivate, 12191 DefaultLvalueConversion(VDInitRefExpr).get(), 12192 /*DirectInit=*/false); 12193 12194 // If required, build a capture to implement the privatization initialized 12195 // with the current list item value. 12196 DeclRefExpr *Ref = nullptr; 12197 if (!VD) 12198 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12199 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 12200 PrivateCopies.push_back(VDPrivateRefExpr); 12201 Inits.push_back(VDInitRefExpr); 12202 12203 // We need to add a data sharing attribute for this variable to make sure it 12204 // is correctly captured. A variable that shows up in a use_device_ptr has 12205 // similar properties of a first private variable. 12206 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12207 12208 // Create a mappable component for the list item. List items in this clause 12209 // only need a component. 12210 MVLI.VarBaseDeclarations.push_back(D); 12211 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 12212 MVLI.VarComponents.back().push_back( 12213 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 12214 } 12215 12216 if (MVLI.ProcessedVarList.empty()) 12217 return nullptr; 12218 12219 return OMPUseDevicePtrClause::Create( 12220 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 12221 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents); 12222 } 12223 12224 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 12225 SourceLocation StartLoc, 12226 SourceLocation LParenLoc, 12227 SourceLocation EndLoc) { 12228 MappableVarListInfo MVLI(VarList); 12229 for (auto &RefExpr : VarList) { 12230 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 12231 SourceLocation ELoc; 12232 SourceRange ERange; 12233 Expr *SimpleRefExpr = RefExpr; 12234 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12235 if (Res.second) { 12236 // It will be analyzed later. 12237 MVLI.ProcessedVarList.push_back(RefExpr); 12238 } 12239 ValueDecl *D = Res.first; 12240 if (!D) 12241 continue; 12242 12243 QualType Type = D->getType(); 12244 // item should be a pointer or array or reference to pointer or array 12245 if (!Type.getNonReferenceType()->isPointerType() && 12246 !Type.getNonReferenceType()->isArrayType()) { 12247 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 12248 << 0 << RefExpr->getSourceRange(); 12249 continue; 12250 } 12251 12252 // Check if the declaration in the clause does not show up in any data 12253 // sharing attribute. 12254 auto DVar = DSAStack->getTopDSA(D, false); 12255 if (isOpenMPPrivate(DVar.CKind)) { 12256 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12257 << getOpenMPClauseName(DVar.CKind) 12258 << getOpenMPClauseName(OMPC_is_device_ptr) 12259 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12260 ReportOriginalDSA(*this, DSAStack, D, DVar); 12261 continue; 12262 } 12263 12264 Expr *ConflictExpr; 12265 if (DSAStack->checkMappableExprComponentListsForDecl( 12266 D, /*CurrentRegionOnly=*/true, 12267 [&ConflictExpr]( 12268 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 12269 OpenMPClauseKind) -> bool { 12270 ConflictExpr = R.front().getAssociatedExpression(); 12271 return true; 12272 })) { 12273 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 12274 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 12275 << ConflictExpr->getSourceRange(); 12276 continue; 12277 } 12278 12279 // Store the components in the stack so that they can be used to check 12280 // against other clauses later on. 12281 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 12282 DSAStack->addMappableExpressionComponents( 12283 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 12284 12285 // Record the expression we've just processed. 12286 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 12287 12288 // Create a mappable component for the list item. List items in this clause 12289 // only need a component. We use a null declaration to signal fields in 12290 // 'this'. 12291 assert((isa<DeclRefExpr>(SimpleRefExpr) || 12292 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 12293 "Unexpected device pointer expression!"); 12294 MVLI.VarBaseDeclarations.push_back( 12295 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 12296 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 12297 MVLI.VarComponents.back().push_back(MC); 12298 } 12299 12300 if (MVLI.ProcessedVarList.empty()) 12301 return nullptr; 12302 12303 return OMPIsDevicePtrClause::Create( 12304 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 12305 MVLI.VarBaseDeclarations, MVLI.VarComponents); 12306 } 12307