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/AST/TypeOrdering.h" 26 #include "clang/Basic/OpenMPKinds.h" 27 #include "clang/Basic/TargetInfo.h" 28 #include "clang/Lex/Preprocessor.h" 29 #include "clang/Sema/Initialization.h" 30 #include "clang/Sema/Lookup.h" 31 #include "clang/Sema/Scope.h" 32 #include "clang/Sema/ScopeInfo.h" 33 #include "clang/Sema/SemaInternal.h" 34 using namespace clang; 35 36 //===----------------------------------------------------------------------===// 37 // Stack of data-sharing attributes for variables 38 //===----------------------------------------------------------------------===// 39 40 namespace { 41 /// \brief Default data sharing attributes, which can be applied to directive. 42 enum DefaultDataSharingAttributes { 43 DSA_unspecified = 0, /// \brief Data sharing attribute not specified. 44 DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'. 45 DSA_shared = 1 << 1 /// \brief Default data sharing attribute 'shared'. 46 }; 47 48 template <class T> struct MatchesAny { 49 explicit MatchesAny(ArrayRef<T> Arr) : Arr(std::move(Arr)) {} 50 bool operator()(T Kind) { 51 for (auto KindEl : Arr) 52 if (KindEl == Kind) 53 return true; 54 return false; 55 } 56 57 private: 58 ArrayRef<T> Arr; 59 }; 60 struct MatchesAlways { 61 MatchesAlways() {} 62 template <class T> bool operator()(T) { return true; } 63 }; 64 65 typedef MatchesAny<OpenMPClauseKind> MatchesAnyClause; 66 typedef MatchesAny<OpenMPDirectiveKind> MatchesAnyDirective; 67 68 /// \brief Stack for tracking declarations used in OpenMP directives and 69 /// clauses and their data-sharing attributes. 70 class DSAStackTy { 71 public: 72 struct DSAVarData { 73 OpenMPDirectiveKind DKind; 74 OpenMPClauseKind CKind; 75 Expr *RefExpr; 76 DeclRefExpr *PrivateCopy; 77 SourceLocation ImplicitDSALoc; 78 DSAVarData() 79 : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr), 80 PrivateCopy(nullptr), ImplicitDSALoc() {} 81 }; 82 83 private: 84 typedef SmallVector<Expr *, 4> MapInfo; 85 86 struct DSAInfo { 87 OpenMPClauseKind Attributes; 88 Expr *RefExpr; 89 DeclRefExpr *PrivateCopy; 90 }; 91 typedef llvm::DenseMap<ValueDecl *, DSAInfo> DeclSAMapTy; 92 typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy; 93 typedef llvm::DenseMap<ValueDecl *, unsigned> LoopControlVariablesMapTy; 94 typedef llvm::DenseMap<ValueDecl *, MapInfo> MappedDeclsTy; 95 typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>> 96 CriticalsWithHintsTy; 97 98 struct SharingMapTy { 99 DeclSAMapTy SharingMap; 100 AlignedMapTy AlignedMap; 101 MappedDeclsTy MappedDecls; 102 LoopControlVariablesMapTy LCVMap; 103 DefaultDataSharingAttributes DefaultAttr; 104 SourceLocation DefaultAttrLoc; 105 OpenMPDirectiveKind Directive; 106 DeclarationNameInfo DirectiveName; 107 Scope *CurScope; 108 SourceLocation ConstructLoc; 109 /// \brief first argument (Expr *) contains optional argument of the 110 /// 'ordered' clause, the second one is true if the regions has 'ordered' 111 /// clause, false otherwise. 112 llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion; 113 bool NowaitRegion; 114 bool CancelRegion; 115 unsigned AssociatedLoops; 116 SourceLocation InnerTeamsRegionLoc; 117 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 118 Scope *CurScope, SourceLocation Loc) 119 : SharingMap(), AlignedMap(), LCVMap(), DefaultAttr(DSA_unspecified), 120 Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope), 121 ConstructLoc(Loc), OrderedRegion(), NowaitRegion(false), 122 CancelRegion(false), AssociatedLoops(1), InnerTeamsRegionLoc() {} 123 SharingMapTy() 124 : SharingMap(), AlignedMap(), LCVMap(), DefaultAttr(DSA_unspecified), 125 Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr), 126 ConstructLoc(), OrderedRegion(), NowaitRegion(false), 127 CancelRegion(false), AssociatedLoops(1), InnerTeamsRegionLoc() {} 128 }; 129 130 typedef SmallVector<SharingMapTy, 4> StackTy; 131 132 /// \brief Stack of used declaration and their data-sharing attributes. 133 StackTy Stack; 134 /// \brief true, if check for DSA must be from parent directive, false, if 135 /// from current directive. 136 OpenMPClauseKind ClauseKindMode; 137 Sema &SemaRef; 138 bool ForceCapturing; 139 CriticalsWithHintsTy Criticals; 140 141 typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; 142 143 DSAVarData getDSA(StackTy::reverse_iterator Iter, ValueDecl *D); 144 145 /// \brief Checks if the variable is a local for OpenMP region. 146 bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter); 147 148 public: 149 explicit DSAStackTy(Sema &S) 150 : Stack(1), ClauseKindMode(OMPC_unknown), SemaRef(S), 151 ForceCapturing(false) {} 152 153 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 154 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 155 156 bool isForceVarCapturing() const { return ForceCapturing; } 157 void setForceVarCapturing(bool V) { ForceCapturing = V; } 158 159 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 160 Scope *CurScope, SourceLocation Loc) { 161 Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc)); 162 Stack.back().DefaultAttrLoc = Loc; 163 } 164 165 void pop() { 166 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!"); 167 Stack.pop_back(); 168 } 169 170 void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) { 171 Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint); 172 } 173 const std::pair<OMPCriticalDirective *, llvm::APSInt> 174 getCriticalWithHint(const DeclarationNameInfo &Name) const { 175 auto I = Criticals.find(Name.getAsString()); 176 if (I != Criticals.end()) 177 return I->second; 178 return std::make_pair(nullptr, llvm::APSInt()); 179 } 180 /// \brief If 'aligned' declaration for given variable \a D was not seen yet, 181 /// add it and return NULL; otherwise return previous occurrence's expression 182 /// for diagnostics. 183 Expr *addUniqueAligned(ValueDecl *D, Expr *NewDE); 184 185 /// \brief Register specified variable as loop control variable. 186 void addLoopControlVariable(ValueDecl *D); 187 /// \brief Check if the specified variable is a loop control variable for 188 /// current region. 189 /// \return The index of the loop control variable in the list of associated 190 /// for-loops (from outer to inner). 191 unsigned isLoopControlVariable(ValueDecl *D); 192 /// \brief Check if the specified variable is a loop control variable for 193 /// parent region. 194 /// \return The index of the loop control variable in the list of associated 195 /// for-loops (from outer to inner). 196 unsigned isParentLoopControlVariable(ValueDecl *D); 197 /// \brief Get the loop control variable for the I-th loop (or nullptr) in 198 /// parent directive. 199 ValueDecl *getParentLoopControlVariable(unsigned I); 200 201 /// \brief Adds explicit data sharing attribute to the specified declaration. 202 void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 203 DeclRefExpr *PrivateCopy = nullptr); 204 205 /// \brief Returns data sharing attributes from top of the stack for the 206 /// specified declaration. 207 DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 208 /// \brief Returns data-sharing attributes for the specified declaration. 209 DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent); 210 /// \brief Checks if the specified variables has data-sharing attributes which 211 /// match specified \a CPred predicate in any directive which matches \a DPred 212 /// predicate. 213 template <class ClausesPredicate, class DirectivesPredicate> 214 DSAVarData hasDSA(ValueDecl *D, ClausesPredicate CPred, 215 DirectivesPredicate DPred, bool FromParent); 216 /// \brief Checks if the specified variables has data-sharing attributes which 217 /// match specified \a CPred predicate in any innermost directive which 218 /// matches \a DPred predicate. 219 template <class ClausesPredicate, class DirectivesPredicate> 220 DSAVarData hasInnermostDSA(ValueDecl *D, ClausesPredicate CPred, 221 DirectivesPredicate DPred, bool FromParent); 222 /// \brief Checks if the specified variables has explicit data-sharing 223 /// attributes which match specified \a CPred predicate at the specified 224 /// OpenMP region. 225 bool hasExplicitDSA(ValueDecl *D, 226 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 227 unsigned Level); 228 229 /// \brief Returns true if the directive at level \Level matches in the 230 /// specified \a DPred predicate. 231 bool hasExplicitDirective( 232 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 233 unsigned Level); 234 235 /// \brief Finds a directive which matches specified \a DPred predicate. 236 template <class NamedDirectivesPredicate> 237 bool hasDirective(NamedDirectivesPredicate DPred, bool FromParent); 238 239 /// \brief Returns currently analyzed directive. 240 OpenMPDirectiveKind getCurrentDirective() const { 241 return Stack.back().Directive; 242 } 243 /// \brief Returns parent directive. 244 OpenMPDirectiveKind getParentDirective() const { 245 if (Stack.size() > 2) 246 return Stack[Stack.size() - 2].Directive; 247 return OMPD_unknown; 248 } 249 /// \brief Return the directive associated with the provided scope. 250 OpenMPDirectiveKind getDirectiveForScope(const Scope *S) const; 251 252 /// \brief Set default data sharing attribute to none. 253 void setDefaultDSANone(SourceLocation Loc) { 254 Stack.back().DefaultAttr = DSA_none; 255 Stack.back().DefaultAttrLoc = Loc; 256 } 257 /// \brief Set default data sharing attribute to shared. 258 void setDefaultDSAShared(SourceLocation Loc) { 259 Stack.back().DefaultAttr = DSA_shared; 260 Stack.back().DefaultAttrLoc = Loc; 261 } 262 263 DefaultDataSharingAttributes getDefaultDSA() const { 264 return Stack.back().DefaultAttr; 265 } 266 SourceLocation getDefaultDSALocation() const { 267 return Stack.back().DefaultAttrLoc; 268 } 269 270 /// \brief Checks if the specified variable is a threadprivate. 271 bool isThreadPrivate(VarDecl *D) { 272 DSAVarData DVar = getTopDSA(D, false); 273 return isOpenMPThreadPrivate(DVar.CKind); 274 } 275 276 /// \brief Marks current region as ordered (it has an 'ordered' clause). 277 void setOrderedRegion(bool IsOrdered, Expr *Param) { 278 Stack.back().OrderedRegion.setInt(IsOrdered); 279 Stack.back().OrderedRegion.setPointer(Param); 280 } 281 /// \brief Returns true, if parent region is ordered (has associated 282 /// 'ordered' clause), false - otherwise. 283 bool isParentOrderedRegion() const { 284 if (Stack.size() > 2) 285 return Stack[Stack.size() - 2].OrderedRegion.getInt(); 286 return false; 287 } 288 /// \brief Returns optional parameter for the ordered region. 289 Expr *getParentOrderedRegionParam() const { 290 if (Stack.size() > 2) 291 return Stack[Stack.size() - 2].OrderedRegion.getPointer(); 292 return nullptr; 293 } 294 /// \brief Marks current region as nowait (it has a 'nowait' clause). 295 void setNowaitRegion(bool IsNowait = true) { 296 Stack.back().NowaitRegion = IsNowait; 297 } 298 /// \brief Returns true, if parent region is nowait (has associated 299 /// 'nowait' clause), false - otherwise. 300 bool isParentNowaitRegion() const { 301 if (Stack.size() > 2) 302 return Stack[Stack.size() - 2].NowaitRegion; 303 return false; 304 } 305 /// \brief Marks parent region as cancel region. 306 void setParentCancelRegion(bool Cancel = true) { 307 if (Stack.size() > 2) 308 Stack[Stack.size() - 2].CancelRegion = 309 Stack[Stack.size() - 2].CancelRegion || Cancel; 310 } 311 /// \brief Return true if current region has inner cancel construct. 312 bool isCancelRegion() const { 313 return Stack.back().CancelRegion; 314 } 315 316 /// \brief Set collapse value for the region. 317 void setAssociatedLoops(unsigned Val) { Stack.back().AssociatedLoops = Val; } 318 /// \brief Return collapse value for region. 319 unsigned getAssociatedLoops() const { return Stack.back().AssociatedLoops; } 320 321 /// \brief Marks current target region as one with closely nested teams 322 /// region. 323 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 324 if (Stack.size() > 2) 325 Stack[Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc; 326 } 327 /// \brief Returns true, if current region has closely nested teams region. 328 bool hasInnerTeamsRegion() const { 329 return getInnerTeamsRegionLoc().isValid(); 330 } 331 /// \brief Returns location of the nested teams region (if any). 332 SourceLocation getInnerTeamsRegionLoc() const { 333 if (Stack.size() > 1) 334 return Stack.back().InnerTeamsRegionLoc; 335 return SourceLocation(); 336 } 337 338 Scope *getCurScope() const { return Stack.back().CurScope; } 339 Scope *getCurScope() { return Stack.back().CurScope; } 340 SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; } 341 342 // Do the check specified in MapInfoCheck and return true if any issue is 343 // found. 344 template <class MapInfoCheck> 345 bool checkMapInfoForVar(ValueDecl *VD, bool CurrentRegionOnly, 346 MapInfoCheck Check) { 347 auto SI = Stack.rbegin(); 348 auto SE = Stack.rend(); 349 350 if (SI == SE) 351 return false; 352 353 if (CurrentRegionOnly) { 354 SE = std::next(SI); 355 } else { 356 ++SI; 357 } 358 359 for (; SI != SE; ++SI) { 360 auto MI = SI->MappedDecls.find(VD); 361 if (MI != SI->MappedDecls.end()) { 362 for (Expr *E : MI->second) { 363 if (Check(E)) 364 return true; 365 } 366 } 367 } 368 return false; 369 } 370 371 void addExprToVarMapInfo(ValueDecl *VD, Expr *E) { 372 if (Stack.size() > 1) { 373 Stack.back().MappedDecls[VD].push_back(E); 374 } 375 } 376 }; 377 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { 378 return isOpenMPParallelDirective(DKind) || DKind == OMPD_task || 379 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown || 380 isOpenMPTaskLoopDirective(DKind); 381 } 382 } // namespace 383 384 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 385 auto *VD = dyn_cast<VarDecl>(D); 386 auto *FD = dyn_cast<FieldDecl>(D); 387 if (VD != nullptr) { 388 VD = VD->getCanonicalDecl(); 389 D = VD; 390 } else { 391 assert(FD); 392 FD = FD->getCanonicalDecl(); 393 D = FD; 394 } 395 return D; 396 } 397 398 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter, 399 ValueDecl *D) { 400 D = getCanonicalDecl(D); 401 auto *VD = dyn_cast<VarDecl>(D); 402 auto *FD = dyn_cast<FieldDecl>(D); 403 DSAVarData DVar; 404 if (Iter == std::prev(Stack.rend())) { 405 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 406 // in a region but not in construct] 407 // File-scope or namespace-scope variables referenced in called routines 408 // in the region are shared unless they appear in a threadprivate 409 // directive. 410 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D)) 411 DVar.CKind = OMPC_shared; 412 413 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 414 // in a region but not in construct] 415 // Variables with static storage duration that are declared in called 416 // routines in the region are shared. 417 if (VD && VD->hasGlobalStorage()) 418 DVar.CKind = OMPC_shared; 419 420 // Non-static data members are shared by default. 421 if (FD) 422 DVar.CKind = OMPC_shared; 423 424 return DVar; 425 } 426 427 DVar.DKind = Iter->Directive; 428 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 429 // in a Construct, C/C++, predetermined, p.1] 430 // Variables with automatic storage duration that are declared in a scope 431 // inside the construct are private. 432 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 433 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 434 DVar.CKind = OMPC_private; 435 return DVar; 436 } 437 438 // Explicitly specified attributes and local variables with predetermined 439 // attributes. 440 if (Iter->SharingMap.count(D)) { 441 DVar.RefExpr = Iter->SharingMap[D].RefExpr; 442 DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy; 443 DVar.CKind = Iter->SharingMap[D].Attributes; 444 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 445 return DVar; 446 } 447 448 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 449 // in a Construct, C/C++, implicitly determined, p.1] 450 // In a parallel or task construct, the data-sharing attributes of these 451 // variables are determined by the default clause, if present. 452 switch (Iter->DefaultAttr) { 453 case DSA_shared: 454 DVar.CKind = OMPC_shared; 455 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 456 return DVar; 457 case DSA_none: 458 return DVar; 459 case DSA_unspecified: 460 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 461 // in a Construct, implicitly determined, p.2] 462 // In a parallel construct, if no default clause is present, these 463 // variables are shared. 464 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 465 if (isOpenMPParallelDirective(DVar.DKind) || 466 isOpenMPTeamsDirective(DVar.DKind)) { 467 DVar.CKind = OMPC_shared; 468 return DVar; 469 } 470 471 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 472 // in a Construct, implicitly determined, p.4] 473 // In a task construct, if no default clause is present, a variable that in 474 // the enclosing context is determined to be shared by all implicit tasks 475 // bound to the current team is shared. 476 if (DVar.DKind == OMPD_task) { 477 DSAVarData DVarTemp; 478 for (StackTy::reverse_iterator I = std::next(Iter), EE = Stack.rend(); 479 I != EE; ++I) { 480 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 481 // Referenced 482 // in a Construct, implicitly determined, p.6] 483 // In a task construct, if no default clause is present, a variable 484 // whose data-sharing attribute is not determined by the rules above is 485 // firstprivate. 486 DVarTemp = getDSA(I, D); 487 if (DVarTemp.CKind != OMPC_shared) { 488 DVar.RefExpr = nullptr; 489 DVar.DKind = OMPD_task; 490 DVar.CKind = OMPC_firstprivate; 491 return DVar; 492 } 493 if (isParallelOrTaskRegion(I->Directive)) 494 break; 495 } 496 DVar.DKind = OMPD_task; 497 DVar.CKind = 498 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 499 return DVar; 500 } 501 } 502 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 503 // in a Construct, implicitly determined, p.3] 504 // For constructs other than task, if no default clause is present, these 505 // variables inherit their data-sharing attributes from the enclosing 506 // context. 507 return getDSA(std::next(Iter), D); 508 } 509 510 Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) { 511 assert(Stack.size() > 1 && "Data sharing attributes stack is empty"); 512 D = getCanonicalDecl(D); 513 auto It = Stack.back().AlignedMap.find(D); 514 if (It == Stack.back().AlignedMap.end()) { 515 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 516 Stack.back().AlignedMap[D] = NewDE; 517 return nullptr; 518 } else { 519 assert(It->second && "Unexpected nullptr expr in the aligned map"); 520 return It->second; 521 } 522 return nullptr; 523 } 524 525 void DSAStackTy::addLoopControlVariable(ValueDecl *D) { 526 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 527 D = getCanonicalDecl(D); 528 Stack.back().LCVMap.insert(std::make_pair(D, Stack.back().LCVMap.size() + 1)); 529 } 530 531 unsigned DSAStackTy::isLoopControlVariable(ValueDecl *D) { 532 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 533 D = getCanonicalDecl(D); 534 return Stack.back().LCVMap.count(D) > 0 ? Stack.back().LCVMap[D] : 0; 535 } 536 537 unsigned DSAStackTy::isParentLoopControlVariable(ValueDecl *D) { 538 assert(Stack.size() > 2 && "Data-sharing attributes stack is empty"); 539 D = getCanonicalDecl(D); 540 return Stack[Stack.size() - 2].LCVMap.count(D) > 0 541 ? Stack[Stack.size() - 2].LCVMap[D] 542 : 0; 543 } 544 545 ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) { 546 assert(Stack.size() > 2 && "Data-sharing attributes stack is empty"); 547 if (Stack[Stack.size() - 2].LCVMap.size() < I) 548 return nullptr; 549 for (auto &Pair : Stack[Stack.size() - 2].LCVMap) { 550 if (Pair.second == I) 551 return Pair.first; 552 } 553 return nullptr; 554 } 555 556 void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 557 DeclRefExpr *PrivateCopy) { 558 D = getCanonicalDecl(D); 559 if (A == OMPC_threadprivate) { 560 Stack[0].SharingMap[D].Attributes = A; 561 Stack[0].SharingMap[D].RefExpr = E; 562 Stack[0].SharingMap[D].PrivateCopy = nullptr; 563 } else { 564 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 565 Stack.back().SharingMap[D].Attributes = A; 566 Stack.back().SharingMap[D].RefExpr = E; 567 Stack.back().SharingMap[D].PrivateCopy = PrivateCopy; 568 if (PrivateCopy) 569 addDSA(PrivateCopy->getDecl(), PrivateCopy, A); 570 } 571 } 572 573 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) { 574 D = D->getCanonicalDecl(); 575 if (Stack.size() > 2) { 576 reverse_iterator I = Iter, E = std::prev(Stack.rend()); 577 Scope *TopScope = nullptr; 578 while (I != E && !isParallelOrTaskRegion(I->Directive)) { 579 ++I; 580 } 581 if (I == E) 582 return false; 583 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 584 Scope *CurScope = getCurScope(); 585 while (CurScope != TopScope && !CurScope->isDeclScope(D)) { 586 CurScope = CurScope->getParent(); 587 } 588 return CurScope != TopScope; 589 } 590 return false; 591 } 592 593 /// \brief Build a variable declaration for OpenMP loop iteration variable. 594 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 595 StringRef Name, const AttrVec *Attrs = nullptr) { 596 DeclContext *DC = SemaRef.CurContext; 597 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 598 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 599 VarDecl *Decl = 600 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 601 if (Attrs) { 602 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 603 I != E; ++I) 604 Decl->addAttr(*I); 605 } 606 Decl->setImplicit(); 607 return Decl; 608 } 609 610 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 611 SourceLocation Loc, 612 bool RefersToCapture = false) { 613 D->setReferenced(); 614 D->markUsed(S.Context); 615 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 616 SourceLocation(), D, RefersToCapture, Loc, Ty, 617 VK_LValue); 618 } 619 620 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) { 621 D = getCanonicalDecl(D); 622 DSAVarData DVar; 623 624 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 625 // in a Construct, C/C++, predetermined, p.1] 626 // Variables appearing in threadprivate directives are threadprivate. 627 auto *VD = dyn_cast<VarDecl>(D); 628 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 629 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 630 SemaRef.getLangOpts().OpenMPUseTLS && 631 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 632 (VD && VD->getStorageClass() == SC_Register && 633 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 634 addDSA(D, buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 635 D->getLocation()), 636 OMPC_threadprivate); 637 } 638 if (Stack[0].SharingMap.count(D)) { 639 DVar.RefExpr = Stack[0].SharingMap[D].RefExpr; 640 DVar.CKind = OMPC_threadprivate; 641 return DVar; 642 } 643 644 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 645 // in a Construct, C/C++, predetermined, p.4] 646 // Static data members are shared. 647 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 648 // in a Construct, C/C++, predetermined, p.7] 649 // Variables with static storage duration that are declared in a scope 650 // inside the construct are shared. 651 if (VD && VD->isStaticDataMember()) { 652 DSAVarData DVarTemp = 653 hasDSA(D, isOpenMPPrivate, MatchesAlways(), FromParent); 654 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 655 return DVar; 656 657 DVar.CKind = OMPC_shared; 658 return DVar; 659 } 660 661 QualType Type = D->getType().getNonReferenceType().getCanonicalType(); 662 bool IsConstant = Type.isConstant(SemaRef.getASTContext()); 663 Type = SemaRef.getASTContext().getBaseElementType(Type); 664 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 665 // in a Construct, C/C++, predetermined, p.6] 666 // Variables with const qualified type having no mutable member are 667 // shared. 668 CXXRecordDecl *RD = 669 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 670 if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 671 if (auto *CTD = CTSD->getSpecializedTemplate()) 672 RD = CTD->getTemplatedDecl(); 673 if (IsConstant && 674 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() && 675 RD->hasMutableFields())) { 676 // Variables with const-qualified type having no mutable member may be 677 // listed in a firstprivate clause, even if they are static data members. 678 DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate), 679 MatchesAlways(), FromParent); 680 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 681 return DVar; 682 683 DVar.CKind = OMPC_shared; 684 return DVar; 685 } 686 687 // Explicitly specified attributes and local variables with predetermined 688 // attributes. 689 auto StartI = std::next(Stack.rbegin()); 690 auto EndI = std::prev(Stack.rend()); 691 if (FromParent && StartI != EndI) { 692 StartI = std::next(StartI); 693 } 694 auto I = std::prev(StartI); 695 if (I->SharingMap.count(D)) { 696 DVar.RefExpr = I->SharingMap[D].RefExpr; 697 DVar.PrivateCopy = I->SharingMap[D].PrivateCopy; 698 DVar.CKind = I->SharingMap[D].Attributes; 699 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 700 } 701 702 return DVar; 703 } 704 705 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 706 bool FromParent) { 707 D = getCanonicalDecl(D); 708 auto StartI = Stack.rbegin(); 709 auto EndI = std::prev(Stack.rend()); 710 if (FromParent && StartI != EndI) { 711 StartI = std::next(StartI); 712 } 713 return getDSA(StartI, D); 714 } 715 716 template <class ClausesPredicate, class DirectivesPredicate> 717 DSAStackTy::DSAVarData DSAStackTy::hasDSA(ValueDecl *D, ClausesPredicate CPred, 718 DirectivesPredicate DPred, 719 bool FromParent) { 720 D = getCanonicalDecl(D); 721 auto StartI = std::next(Stack.rbegin()); 722 auto EndI = std::prev(Stack.rend()); 723 if (FromParent && StartI != EndI) { 724 StartI = std::next(StartI); 725 } 726 for (auto I = StartI, EE = EndI; I != EE; ++I) { 727 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) 728 continue; 729 DSAVarData DVar = getDSA(I, D); 730 if (CPred(DVar.CKind)) 731 return DVar; 732 } 733 return DSAVarData(); 734 } 735 736 template <class ClausesPredicate, class DirectivesPredicate> 737 DSAStackTy::DSAVarData 738 DSAStackTy::hasInnermostDSA(ValueDecl *D, ClausesPredicate CPred, 739 DirectivesPredicate DPred, bool FromParent) { 740 D = getCanonicalDecl(D); 741 auto StartI = std::next(Stack.rbegin()); 742 auto EndI = std::prev(Stack.rend()); 743 if (FromParent && StartI != EndI) { 744 StartI = std::next(StartI); 745 } 746 for (auto I = StartI, EE = EndI; I != EE; ++I) { 747 if (!DPred(I->Directive)) 748 break; 749 DSAVarData DVar = getDSA(I, D); 750 if (CPred(DVar.CKind)) 751 return DVar; 752 return DSAVarData(); 753 } 754 return DSAVarData(); 755 } 756 757 bool DSAStackTy::hasExplicitDSA( 758 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 759 unsigned Level) { 760 if (CPred(ClauseKindMode)) 761 return true; 762 if (isClauseParsingMode()) 763 ++Level; 764 D = getCanonicalDecl(D); 765 auto StartI = Stack.rbegin(); 766 auto EndI = std::prev(Stack.rend()); 767 if (std::distance(StartI, EndI) <= (int)Level) 768 return false; 769 std::advance(StartI, Level); 770 return (StartI->SharingMap.count(D) > 0) && StartI->SharingMap[D].RefExpr && 771 CPred(StartI->SharingMap[D].Attributes); 772 } 773 774 bool DSAStackTy::hasExplicitDirective( 775 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 776 unsigned Level) { 777 if (isClauseParsingMode()) 778 ++Level; 779 auto StartI = Stack.rbegin(); 780 auto EndI = std::prev(Stack.rend()); 781 if (std::distance(StartI, EndI) <= (int)Level) 782 return false; 783 std::advance(StartI, Level); 784 return DPred(StartI->Directive); 785 } 786 787 template <class NamedDirectivesPredicate> 788 bool DSAStackTy::hasDirective(NamedDirectivesPredicate DPred, bool FromParent) { 789 auto StartI = std::next(Stack.rbegin()); 790 auto EndI = std::prev(Stack.rend()); 791 if (FromParent && StartI != EndI) { 792 StartI = std::next(StartI); 793 } 794 for (auto I = StartI, EE = EndI; I != EE; ++I) { 795 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 796 return true; 797 } 798 return false; 799 } 800 801 OpenMPDirectiveKind DSAStackTy::getDirectiveForScope(const Scope *S) const { 802 for (auto I = Stack.rbegin(), EE = Stack.rend(); I != EE; ++I) 803 if (I->CurScope == S) 804 return I->Directive; 805 return OMPD_unknown; 806 } 807 808 void Sema::InitDataSharingAttributesStack() { 809 VarDataSharingAttributesStack = new DSAStackTy(*this); 810 } 811 812 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 813 814 bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, 815 const CapturedRegionScopeInfo *RSI) { 816 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 817 818 auto &Ctx = getASTContext(); 819 bool IsByRef = true; 820 821 // Find the directive that is associated with the provided scope. 822 auto DKind = DSAStack->getDirectiveForScope(RSI->TheScope); 823 auto Ty = D->getType(); 824 825 if (isOpenMPTargetExecutionDirective(DKind)) { 826 // This table summarizes how a given variable should be passed to the device 827 // given its type and the clauses where it appears. This table is based on 828 // the description in OpenMP 4.5 [2.10.4, target Construct] and 829 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 830 // 831 // ========================================================================= 832 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 833 // | |(tofrom:scalar)| | pvt | | | | 834 // ========================================================================= 835 // | scl | | | | - | | bycopy| 836 // | scl | | - | x | - | - | bycopy| 837 // | scl | | x | - | - | - | null | 838 // | scl | x | | | - | | byref | 839 // | scl | x | - | x | - | - | bycopy| 840 // | scl | x | x | - | - | - | null | 841 // | scl | | - | - | - | x | byref | 842 // | scl | x | - | - | - | x | byref | 843 // 844 // | agg | n.a. | | | - | | byref | 845 // | agg | n.a. | - | x | - | - | byref | 846 // | agg | n.a. | x | - | - | - | null | 847 // | agg | n.a. | - | - | - | x | byref | 848 // | agg | n.a. | - | - | - | x[] | byref | 849 // 850 // | ptr | n.a. | | | - | | bycopy| 851 // | ptr | n.a. | - | x | - | - | bycopy| 852 // | ptr | n.a. | x | - | - | - | null | 853 // | ptr | n.a. | - | - | - | x | byref | 854 // | ptr | n.a. | - | - | - | x[] | bycopy| 855 // | ptr | n.a. | - | - | x | | bycopy| 856 // | ptr | n.a. | - | - | x | x | bycopy| 857 // | ptr | n.a. | - | - | x | x[] | bycopy| 858 // ========================================================================= 859 // Legend: 860 // scl - scalar 861 // ptr - pointer 862 // agg - aggregate 863 // x - applies 864 // - - invalid in this combination 865 // [] - mapped with an array section 866 // byref - should be mapped by reference 867 // byval - should be mapped by value 868 // null - initialize a local variable to null on the device 869 // 870 // Observations: 871 // - All scalar declarations that show up in a map clause have to be passed 872 // by reference, because they may have been mapped in the enclosing data 873 // environment. 874 // - If the scalar value does not fit the size of uintptr, it has to be 875 // passed by reference, regardless the result in the table above. 876 // - For pointers mapped by value that have either an implicit map or an 877 // array section, the runtime library may pass the NULL value to the 878 // device instead of the value passed to it by the compiler. 879 880 // FIXME: Right now, only implicit maps are implemented. Properly mapping 881 // values requires having the map, private, and firstprivate clauses SEMA 882 // and parsing in place, which we don't yet. 883 884 if (Ty->isReferenceType()) 885 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 886 IsByRef = !Ty->isScalarType(); 887 } 888 889 // When passing data by value, we need to make sure it fits the uintptr size 890 // and alignment, because the runtime library only deals with uintptr types. 891 // If it does not fit the uintptr size, we need to pass the data by reference 892 // instead. 893 if (!IsByRef && 894 (Ctx.getTypeSizeInChars(Ty) > 895 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 896 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) 897 IsByRef = true; 898 899 return IsByRef; 900 } 901 902 VarDecl *Sema::IsOpenMPCapturedDecl(ValueDecl *D) { 903 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 904 D = getCanonicalDecl(D); 905 906 // If we are attempting to capture a global variable in a directive with 907 // 'target' we return true so that this global is also mapped to the device. 908 // 909 // FIXME: If the declaration is enclosed in a 'declare target' directive, 910 // then it should not be captured. Therefore, an extra check has to be 911 // inserted here once support for 'declare target' is added. 912 // 913 auto *VD = dyn_cast<VarDecl>(D); 914 if (VD && !VD->hasLocalStorage()) { 915 if (DSAStack->getCurrentDirective() == OMPD_target && 916 !DSAStack->isClauseParsingMode()) 917 return VD; 918 if (DSAStack->getCurScope() && 919 DSAStack->hasDirective( 920 [](OpenMPDirectiveKind K, const DeclarationNameInfo &DNI, 921 SourceLocation Loc) -> bool { 922 return isOpenMPTargetExecutionDirective(K); 923 }, 924 false)) 925 return VD; 926 } 927 928 if (DSAStack->getCurrentDirective() != OMPD_unknown && 929 (!DSAStack->isClauseParsingMode() || 930 DSAStack->getParentDirective() != OMPD_unknown)) { 931 if (DSAStack->isLoopControlVariable(D) || 932 (VD && VD->hasLocalStorage() && 933 isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || 934 (VD && DSAStack->isForceVarCapturing())) 935 return VD; 936 auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 937 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 938 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 939 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, MatchesAlways(), 940 DSAStack->isClauseParsingMode()); 941 if (DVarPrivate.CKind != OMPC_unknown) 942 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 943 } 944 return nullptr; 945 } 946 947 bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) { 948 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 949 return DSAStack->hasExplicitDSA( 950 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, Level); 951 } 952 953 bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) { 954 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 955 // Return true if the current level is no longer enclosed in a target region. 956 957 auto *VD = dyn_cast<VarDecl>(D); 958 return VD && !VD->hasLocalStorage() && 959 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 960 Level); 961 } 962 963 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 964 965 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 966 const DeclarationNameInfo &DirName, 967 Scope *CurScope, SourceLocation Loc) { 968 DSAStack->push(DKind, DirName, CurScope, Loc); 969 PushExpressionEvaluationContext(PotentiallyEvaluated); 970 } 971 972 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 973 DSAStack->setClauseParsingMode(K); 974 } 975 976 void Sema::EndOpenMPClause() { 977 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 978 } 979 980 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 981 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 982 // A variable of class type (or array thereof) that appears in a lastprivate 983 // clause requires an accessible, unambiguous default constructor for the 984 // class type, unless the list item is also specified in a firstprivate 985 // clause. 986 if (auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 987 for (auto *C : D->clauses()) { 988 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 989 SmallVector<Expr *, 8> PrivateCopies; 990 for (auto *DE : Clause->varlists()) { 991 if (DE->isValueDependent() || DE->isTypeDependent()) { 992 PrivateCopies.push_back(nullptr); 993 continue; 994 } 995 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 996 VarDecl *VD = cast<VarDecl>(DRE->getDecl()); 997 QualType Type = VD->getType().getNonReferenceType(); 998 auto DVar = DSAStack->getTopDSA(VD, false); 999 if (DVar.CKind == OMPC_lastprivate) { 1000 // Generate helper private variable and initialize it with the 1001 // default value. The address of the original variable is replaced 1002 // by the address of the new private variable in CodeGen. This new 1003 // variable is not added to IdResolver, so the code in the OpenMP 1004 // region uses original variable for proper diagnostics. 1005 auto *VDPrivate = buildVarDecl( 1006 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1007 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr); 1008 ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); 1009 if (VDPrivate->isInvalidDecl()) 1010 continue; 1011 PrivateCopies.push_back(buildDeclRefExpr( 1012 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1013 } else { 1014 // The variable is also a firstprivate, so initialization sequence 1015 // for private copy is generated already. 1016 PrivateCopies.push_back(nullptr); 1017 } 1018 } 1019 // Set initializers to private copies if no errors were found. 1020 if (PrivateCopies.size() == Clause->varlist_size()) 1021 Clause->setPrivateCopies(PrivateCopies); 1022 } 1023 } 1024 } 1025 1026 DSAStack->pop(); 1027 DiscardCleanupsInEvaluationContext(); 1028 PopExpressionEvaluationContext(); 1029 } 1030 1031 static bool 1032 FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1033 Expr *NumIterations, Sema &SemaRef, Scope *S); 1034 1035 namespace { 1036 1037 class VarDeclFilterCCC : public CorrectionCandidateCallback { 1038 private: 1039 Sema &SemaRef; 1040 1041 public: 1042 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1043 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1044 NamedDecl *ND = Candidate.getCorrectionDecl(); 1045 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) { 1046 return VD->hasGlobalStorage() && 1047 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1048 SemaRef.getCurScope()); 1049 } 1050 return false; 1051 } 1052 }; 1053 } // namespace 1054 1055 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 1056 CXXScopeSpec &ScopeSpec, 1057 const DeclarationNameInfo &Id) { 1058 LookupResult Lookup(*this, Id, LookupOrdinaryName); 1059 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 1060 1061 if (Lookup.isAmbiguous()) 1062 return ExprError(); 1063 1064 VarDecl *VD; 1065 if (!Lookup.isSingleResult()) { 1066 if (TypoCorrection Corrected = CorrectTypo( 1067 Id, LookupOrdinaryName, CurScope, nullptr, 1068 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 1069 diagnoseTypo(Corrected, 1070 PDiag(Lookup.empty() 1071 ? diag::err_undeclared_var_use_suggest 1072 : diag::err_omp_expected_var_arg_suggest) 1073 << Id.getName()); 1074 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 1075 } else { 1076 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 1077 : diag::err_omp_expected_var_arg) 1078 << Id.getName(); 1079 return ExprError(); 1080 } 1081 } else { 1082 if (!(VD = Lookup.getAsSingle<VarDecl>())) { 1083 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 1084 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 1085 return ExprError(); 1086 } 1087 } 1088 Lookup.suppressDiagnostics(); 1089 1090 // OpenMP [2.9.2, Syntax, C/C++] 1091 // Variables must be file-scope, namespace-scope, or static block-scope. 1092 if (!VD->hasGlobalStorage()) { 1093 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 1094 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); 1095 bool IsDecl = 1096 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1097 Diag(VD->getLocation(), 1098 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1099 << VD; 1100 return ExprError(); 1101 } 1102 1103 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 1104 NamedDecl *ND = cast<NamedDecl>(CanonicalVD); 1105 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 1106 // A threadprivate directive for file-scope variables must appear outside 1107 // any definition or declaration. 1108 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 1109 !getCurLexicalContext()->isTranslationUnit()) { 1110 Diag(Id.getLoc(), diag::err_omp_var_scope) 1111 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1112 bool IsDecl = 1113 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1114 Diag(VD->getLocation(), 1115 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1116 << VD; 1117 return ExprError(); 1118 } 1119 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 1120 // A threadprivate directive for static class member variables must appear 1121 // in the class definition, in the same scope in which the member 1122 // variables are declared. 1123 if (CanonicalVD->isStaticDataMember() && 1124 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 1125 Diag(Id.getLoc(), diag::err_omp_var_scope) 1126 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1127 bool IsDecl = 1128 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1129 Diag(VD->getLocation(), 1130 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1131 << VD; 1132 return ExprError(); 1133 } 1134 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 1135 // A threadprivate directive for namespace-scope variables must appear 1136 // outside any definition or declaration other than the namespace 1137 // definition itself. 1138 if (CanonicalVD->getDeclContext()->isNamespace() && 1139 (!getCurLexicalContext()->isFileContext() || 1140 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 1141 Diag(Id.getLoc(), diag::err_omp_var_scope) 1142 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1143 bool IsDecl = 1144 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1145 Diag(VD->getLocation(), 1146 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1147 << VD; 1148 return ExprError(); 1149 } 1150 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 1151 // A threadprivate directive for static block-scope variables must appear 1152 // in the scope of the variable and not in a nested scope. 1153 if (CanonicalVD->isStaticLocal() && CurScope && 1154 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 1155 Diag(Id.getLoc(), diag::err_omp_var_scope) 1156 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1157 bool IsDecl = 1158 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1159 Diag(VD->getLocation(), 1160 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1161 << VD; 1162 return ExprError(); 1163 } 1164 1165 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 1166 // A threadprivate directive must lexically precede all references to any 1167 // of the variables in its list. 1168 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { 1169 Diag(Id.getLoc(), diag::err_omp_var_used) 1170 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1171 return ExprError(); 1172 } 1173 1174 QualType ExprType = VD->getType().getNonReferenceType(); 1175 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 1176 SourceLocation(), VD, 1177 /*RefersToEnclosingVariableOrCapture=*/false, 1178 Id.getLoc(), ExprType, VK_LValue); 1179 } 1180 1181 Sema::DeclGroupPtrTy 1182 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 1183 ArrayRef<Expr *> VarList) { 1184 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 1185 CurContext->addDecl(D); 1186 return DeclGroupPtrTy::make(DeclGroupRef(D)); 1187 } 1188 return nullptr; 1189 } 1190 1191 namespace { 1192 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> { 1193 Sema &SemaRef; 1194 1195 public: 1196 bool VisitDeclRefExpr(const DeclRefExpr *E) { 1197 if (auto VD = dyn_cast<VarDecl>(E->getDecl())) { 1198 if (VD->hasLocalStorage()) { 1199 SemaRef.Diag(E->getLocStart(), 1200 diag::err_omp_local_var_in_threadprivate_init) 1201 << E->getSourceRange(); 1202 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 1203 << VD << VD->getSourceRange(); 1204 return true; 1205 } 1206 } 1207 return false; 1208 } 1209 bool VisitStmt(const Stmt *S) { 1210 for (auto Child : S->children()) { 1211 if (Child && Visit(Child)) 1212 return true; 1213 } 1214 return false; 1215 } 1216 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 1217 }; 1218 } // namespace 1219 1220 OMPThreadPrivateDecl * 1221 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 1222 SmallVector<Expr *, 8> Vars; 1223 for (auto &RefExpr : VarList) { 1224 DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr); 1225 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 1226 SourceLocation ILoc = DE->getExprLoc(); 1227 1228 // Mark variable as used. 1229 VD->setReferenced(); 1230 VD->markUsed(Context); 1231 1232 QualType QType = VD->getType(); 1233 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 1234 // It will be analyzed later. 1235 Vars.push_back(DE); 1236 continue; 1237 } 1238 1239 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1240 // A threadprivate variable must not have an incomplete type. 1241 if (RequireCompleteType(ILoc, VD->getType(), 1242 diag::err_omp_threadprivate_incomplete_type)) { 1243 continue; 1244 } 1245 1246 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1247 // A threadprivate variable must not have a reference type. 1248 if (VD->getType()->isReferenceType()) { 1249 Diag(ILoc, diag::err_omp_ref_type_arg) 1250 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 1251 bool IsDecl = 1252 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1253 Diag(VD->getLocation(), 1254 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1255 << VD; 1256 continue; 1257 } 1258 1259 // Check if this is a TLS variable. If TLS is not being supported, produce 1260 // the corresponding diagnostic. 1261 if ((VD->getTLSKind() != VarDecl::TLS_None && 1262 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1263 getLangOpts().OpenMPUseTLS && 1264 getASTContext().getTargetInfo().isTLSSupported())) || 1265 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 1266 !VD->isLocalVarDecl())) { 1267 Diag(ILoc, diag::err_omp_var_thread_local) 1268 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 1269 bool IsDecl = 1270 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1271 Diag(VD->getLocation(), 1272 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1273 << VD; 1274 continue; 1275 } 1276 1277 // Check if initial value of threadprivate variable reference variable with 1278 // local storage (it is not supported by runtime). 1279 if (auto Init = VD->getAnyInitializer()) { 1280 LocalVarRefChecker Checker(*this); 1281 if (Checker.Visit(Init)) 1282 continue; 1283 } 1284 1285 Vars.push_back(RefExpr); 1286 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 1287 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 1288 Context, SourceRange(Loc, Loc))); 1289 if (auto *ML = Context.getASTMutationListener()) 1290 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 1291 } 1292 OMPThreadPrivateDecl *D = nullptr; 1293 if (!Vars.empty()) { 1294 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 1295 Vars); 1296 D->setAccess(AS_public); 1297 } 1298 return D; 1299 } 1300 1301 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, 1302 const ValueDecl *D, DSAStackTy::DSAVarData DVar, 1303 bool IsLoopIterVar = false) { 1304 if (DVar.RefExpr) { 1305 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 1306 << getOpenMPClauseName(DVar.CKind); 1307 return; 1308 } 1309 enum { 1310 PDSA_StaticMemberShared, 1311 PDSA_StaticLocalVarShared, 1312 PDSA_LoopIterVarPrivate, 1313 PDSA_LoopIterVarLinear, 1314 PDSA_LoopIterVarLastprivate, 1315 PDSA_ConstVarShared, 1316 PDSA_GlobalVarShared, 1317 PDSA_TaskVarFirstprivate, 1318 PDSA_LocalVarPrivate, 1319 PDSA_Implicit 1320 } Reason = PDSA_Implicit; 1321 bool ReportHint = false; 1322 auto ReportLoc = D->getLocation(); 1323 auto *VD = dyn_cast<VarDecl>(D); 1324 if (IsLoopIterVar) { 1325 if (DVar.CKind == OMPC_private) 1326 Reason = PDSA_LoopIterVarPrivate; 1327 else if (DVar.CKind == OMPC_lastprivate) 1328 Reason = PDSA_LoopIterVarLastprivate; 1329 else 1330 Reason = PDSA_LoopIterVarLinear; 1331 } else if (DVar.DKind == OMPD_task && DVar.CKind == OMPC_firstprivate) { 1332 Reason = PDSA_TaskVarFirstprivate; 1333 ReportLoc = DVar.ImplicitDSALoc; 1334 } else if (VD && VD->isStaticLocal()) 1335 Reason = PDSA_StaticLocalVarShared; 1336 else if (VD && VD->isStaticDataMember()) 1337 Reason = PDSA_StaticMemberShared; 1338 else if (VD && VD->isFileVarDecl()) 1339 Reason = PDSA_GlobalVarShared; 1340 else if (D->getType().isConstant(SemaRef.getASTContext())) 1341 Reason = PDSA_ConstVarShared; 1342 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 1343 ReportHint = true; 1344 Reason = PDSA_LocalVarPrivate; 1345 } 1346 if (Reason != PDSA_Implicit) { 1347 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 1348 << Reason << ReportHint 1349 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 1350 } else if (DVar.ImplicitDSALoc.isValid()) { 1351 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 1352 << getOpenMPClauseName(DVar.CKind); 1353 } 1354 } 1355 1356 namespace { 1357 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> { 1358 DSAStackTy *Stack; 1359 Sema &SemaRef; 1360 bool ErrorFound; 1361 CapturedStmt *CS; 1362 llvm::SmallVector<Expr *, 8> ImplicitFirstprivate; 1363 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 1364 1365 public: 1366 void VisitDeclRefExpr(DeclRefExpr *E) { 1367 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1368 // Skip internally declared variables. 1369 if (VD->isLocalVarDecl() && !CS->capturesVariable(VD)) 1370 return; 1371 1372 auto DVar = Stack->getTopDSA(VD, false); 1373 // Check if the variable has explicit DSA set and stop analysis if it so. 1374 if (DVar.RefExpr) return; 1375 1376 auto ELoc = E->getExprLoc(); 1377 auto DKind = Stack->getCurrentDirective(); 1378 // The default(none) clause requires that each variable that is referenced 1379 // in the construct, and does not have a predetermined data-sharing 1380 // attribute, must have its data-sharing attribute explicitly determined 1381 // by being listed in a data-sharing attribute clause. 1382 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 1383 isParallelOrTaskRegion(DKind) && 1384 VarsWithInheritedDSA.count(VD) == 0) { 1385 VarsWithInheritedDSA[VD] = E; 1386 return; 1387 } 1388 1389 // OpenMP [2.9.3.6, Restrictions, p.2] 1390 // A list item that appears in a reduction clause of the innermost 1391 // enclosing worksharing or parallel construct may not be accessed in an 1392 // explicit task. 1393 DVar = Stack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction), 1394 [](OpenMPDirectiveKind K) -> bool { 1395 return isOpenMPParallelDirective(K) || 1396 isOpenMPWorksharingDirective(K) || 1397 isOpenMPTeamsDirective(K); 1398 }, 1399 false); 1400 if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) { 1401 ErrorFound = true; 1402 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1403 ReportOriginalDSA(SemaRef, Stack, VD, DVar); 1404 return; 1405 } 1406 1407 // Define implicit data-sharing attributes for task. 1408 DVar = Stack->getImplicitDSA(VD, false); 1409 if (DKind == OMPD_task && DVar.CKind != OMPC_shared) 1410 ImplicitFirstprivate.push_back(E); 1411 } 1412 } 1413 void VisitMemberExpr(MemberExpr *E) { 1414 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 1415 if (auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl())) { 1416 auto DVar = Stack->getTopDSA(FD, false); 1417 // Check if the variable has explicit DSA set and stop analysis if it 1418 // so. 1419 if (DVar.RefExpr) 1420 return; 1421 1422 auto ELoc = E->getExprLoc(); 1423 auto DKind = Stack->getCurrentDirective(); 1424 // OpenMP [2.9.3.6, Restrictions, p.2] 1425 // A list item that appears in a reduction clause of the innermost 1426 // enclosing worksharing or parallel construct may not be accessed in 1427 // an explicit task. 1428 DVar = 1429 Stack->hasInnermostDSA(FD, MatchesAnyClause(OMPC_reduction), 1430 [](OpenMPDirectiveKind K) -> bool { 1431 return isOpenMPParallelDirective(K) || 1432 isOpenMPWorksharingDirective(K) || 1433 isOpenMPTeamsDirective(K); 1434 }, 1435 false); 1436 if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) { 1437 ErrorFound = true; 1438 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1439 ReportOriginalDSA(SemaRef, Stack, FD, DVar); 1440 return; 1441 } 1442 1443 // Define implicit data-sharing attributes for task. 1444 DVar = Stack->getImplicitDSA(FD, false); 1445 if (DKind == OMPD_task && DVar.CKind != OMPC_shared) 1446 ImplicitFirstprivate.push_back(E); 1447 } 1448 } 1449 } 1450 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 1451 for (auto *C : S->clauses()) { 1452 // Skip analysis of arguments of implicitly defined firstprivate clause 1453 // for task directives. 1454 if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid())) 1455 for (auto *CC : C->children()) { 1456 if (CC) 1457 Visit(CC); 1458 } 1459 } 1460 } 1461 void VisitStmt(Stmt *S) { 1462 for (auto *C : S->children()) { 1463 if (C && !isa<OMPExecutableDirective>(C)) 1464 Visit(C); 1465 } 1466 } 1467 1468 bool isErrorFound() { return ErrorFound; } 1469 ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; } 1470 llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() { 1471 return VarsWithInheritedDSA; 1472 } 1473 1474 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 1475 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} 1476 }; 1477 } // namespace 1478 1479 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 1480 switch (DKind) { 1481 case OMPD_parallel: { 1482 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1483 QualType KmpInt32PtrTy = 1484 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1485 Sema::CapturedParamNameType Params[] = { 1486 std::make_pair(".global_tid.", KmpInt32PtrTy), 1487 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1488 std::make_pair(StringRef(), QualType()) // __context with shared vars 1489 }; 1490 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1491 Params); 1492 break; 1493 } 1494 case OMPD_simd: { 1495 Sema::CapturedParamNameType Params[] = { 1496 std::make_pair(StringRef(), QualType()) // __context with shared vars 1497 }; 1498 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1499 Params); 1500 break; 1501 } 1502 case OMPD_for: { 1503 Sema::CapturedParamNameType Params[] = { 1504 std::make_pair(StringRef(), QualType()) // __context with shared vars 1505 }; 1506 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1507 Params); 1508 break; 1509 } 1510 case OMPD_for_simd: { 1511 Sema::CapturedParamNameType Params[] = { 1512 std::make_pair(StringRef(), QualType()) // __context with shared vars 1513 }; 1514 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1515 Params); 1516 break; 1517 } 1518 case OMPD_sections: { 1519 Sema::CapturedParamNameType Params[] = { 1520 std::make_pair(StringRef(), QualType()) // __context with shared vars 1521 }; 1522 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1523 Params); 1524 break; 1525 } 1526 case OMPD_section: { 1527 Sema::CapturedParamNameType Params[] = { 1528 std::make_pair(StringRef(), QualType()) // __context with shared vars 1529 }; 1530 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1531 Params); 1532 break; 1533 } 1534 case OMPD_single: { 1535 Sema::CapturedParamNameType Params[] = { 1536 std::make_pair(StringRef(), QualType()) // __context with shared vars 1537 }; 1538 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1539 Params); 1540 break; 1541 } 1542 case OMPD_master: { 1543 Sema::CapturedParamNameType Params[] = { 1544 std::make_pair(StringRef(), QualType()) // __context with shared vars 1545 }; 1546 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1547 Params); 1548 break; 1549 } 1550 case OMPD_critical: { 1551 Sema::CapturedParamNameType Params[] = { 1552 std::make_pair(StringRef(), QualType()) // __context with shared vars 1553 }; 1554 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1555 Params); 1556 break; 1557 } 1558 case OMPD_parallel_for: { 1559 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1560 QualType KmpInt32PtrTy = 1561 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1562 Sema::CapturedParamNameType Params[] = { 1563 std::make_pair(".global_tid.", KmpInt32PtrTy), 1564 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1565 std::make_pair(StringRef(), QualType()) // __context with shared vars 1566 }; 1567 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1568 Params); 1569 break; 1570 } 1571 case OMPD_parallel_for_simd: { 1572 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1573 QualType KmpInt32PtrTy = 1574 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1575 Sema::CapturedParamNameType Params[] = { 1576 std::make_pair(".global_tid.", KmpInt32PtrTy), 1577 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1578 std::make_pair(StringRef(), QualType()) // __context with shared vars 1579 }; 1580 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1581 Params); 1582 break; 1583 } 1584 case OMPD_parallel_sections: { 1585 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1586 QualType KmpInt32PtrTy = 1587 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1588 Sema::CapturedParamNameType Params[] = { 1589 std::make_pair(".global_tid.", KmpInt32PtrTy), 1590 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1591 std::make_pair(StringRef(), QualType()) // __context with shared vars 1592 }; 1593 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1594 Params); 1595 break; 1596 } 1597 case OMPD_task: { 1598 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1599 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 1600 FunctionProtoType::ExtProtoInfo EPI; 1601 EPI.Variadic = true; 1602 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 1603 Sema::CapturedParamNameType Params[] = { 1604 std::make_pair(".global_tid.", KmpInt32Ty), 1605 std::make_pair(".part_id.", KmpInt32Ty), 1606 std::make_pair(".privates.", 1607 Context.VoidPtrTy.withConst().withRestrict()), 1608 std::make_pair( 1609 ".copy_fn.", 1610 Context.getPointerType(CopyFnType).withConst().withRestrict()), 1611 std::make_pair(StringRef(), QualType()) // __context with shared vars 1612 }; 1613 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1614 Params); 1615 // Mark this captured region as inlined, because we don't use outlined 1616 // function directly. 1617 getCurCapturedRegion()->TheCapturedDecl->addAttr( 1618 AlwaysInlineAttr::CreateImplicit( 1619 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 1620 break; 1621 } 1622 case OMPD_ordered: { 1623 Sema::CapturedParamNameType Params[] = { 1624 std::make_pair(StringRef(), QualType()) // __context with shared vars 1625 }; 1626 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1627 Params); 1628 break; 1629 } 1630 case OMPD_atomic: { 1631 Sema::CapturedParamNameType Params[] = { 1632 std::make_pair(StringRef(), QualType()) // __context with shared vars 1633 }; 1634 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1635 Params); 1636 break; 1637 } 1638 case OMPD_target_data: 1639 case OMPD_target: 1640 case OMPD_target_parallel: 1641 case OMPD_target_parallel_for: { 1642 Sema::CapturedParamNameType Params[] = { 1643 std::make_pair(StringRef(), QualType()) // __context with shared vars 1644 }; 1645 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1646 Params); 1647 break; 1648 } 1649 case OMPD_teams: { 1650 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1651 QualType KmpInt32PtrTy = 1652 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1653 Sema::CapturedParamNameType Params[] = { 1654 std::make_pair(".global_tid.", KmpInt32PtrTy), 1655 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1656 std::make_pair(StringRef(), QualType()) // __context with shared vars 1657 }; 1658 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1659 Params); 1660 break; 1661 } 1662 case OMPD_taskgroup: { 1663 Sema::CapturedParamNameType Params[] = { 1664 std::make_pair(StringRef(), QualType()) // __context with shared vars 1665 }; 1666 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1667 Params); 1668 break; 1669 } 1670 case OMPD_taskloop: { 1671 Sema::CapturedParamNameType Params[] = { 1672 std::make_pair(StringRef(), QualType()) // __context with shared vars 1673 }; 1674 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1675 Params); 1676 break; 1677 } 1678 case OMPD_taskloop_simd: { 1679 Sema::CapturedParamNameType Params[] = { 1680 std::make_pair(StringRef(), QualType()) // __context with shared vars 1681 }; 1682 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1683 Params); 1684 break; 1685 } 1686 case OMPD_distribute: { 1687 Sema::CapturedParamNameType Params[] = { 1688 std::make_pair(StringRef(), QualType()) // __context with shared vars 1689 }; 1690 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1691 Params); 1692 break; 1693 } 1694 case OMPD_threadprivate: 1695 case OMPD_taskyield: 1696 case OMPD_barrier: 1697 case OMPD_taskwait: 1698 case OMPD_cancellation_point: 1699 case OMPD_cancel: 1700 case OMPD_flush: 1701 case OMPD_target_enter_data: 1702 case OMPD_target_exit_data: 1703 case OMPD_declare_reduction: 1704 case OMPD_declare_simd: 1705 llvm_unreachable("OpenMP Directive is not allowed"); 1706 case OMPD_unknown: 1707 llvm_unreachable("Unknown OpenMP directive"); 1708 } 1709 } 1710 1711 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 1712 Expr *CaptureExpr, bool WithInit, 1713 bool AsExpression) { 1714 assert(CaptureExpr); 1715 ASTContext &C = S.getASTContext(); 1716 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 1717 QualType Ty = Init->getType(); 1718 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 1719 if (S.getLangOpts().CPlusPlus) 1720 Ty = C.getLValueReferenceType(Ty); 1721 else { 1722 Ty = C.getPointerType(Ty); 1723 ExprResult Res = 1724 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 1725 if (!Res.isUsable()) 1726 return nullptr; 1727 Init = Res.get(); 1728 } 1729 WithInit = true; 1730 } 1731 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty); 1732 if (!WithInit) 1733 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange())); 1734 S.CurContext->addHiddenDecl(CED); 1735 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false, 1736 /*TypeMayContainAuto=*/true); 1737 return CED; 1738 } 1739 1740 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 1741 bool WithInit) { 1742 OMPCapturedExprDecl *CD; 1743 if (auto *VD = S.IsOpenMPCapturedDecl(D)) 1744 CD = cast<OMPCapturedExprDecl>(VD); 1745 else 1746 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 1747 /*AsExpression=*/false); 1748 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 1749 CaptureExpr->getExprLoc()); 1750 } 1751 1752 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 1753 if (!Ref) { 1754 auto *CD = 1755 buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."), 1756 CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true); 1757 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 1758 CaptureExpr->getExprLoc()); 1759 } 1760 ExprResult Res = Ref; 1761 if (!S.getLangOpts().CPlusPlus && 1762 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 1763 Ref->getType()->isPointerType()) 1764 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 1765 if (!Res.isUsable()) 1766 return ExprError(); 1767 return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get()); 1768 } 1769 1770 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 1771 ArrayRef<OMPClause *> Clauses) { 1772 if (!S.isUsable()) { 1773 ActOnCapturedRegionError(); 1774 return StmtError(); 1775 } 1776 1777 OMPOrderedClause *OC = nullptr; 1778 OMPScheduleClause *SC = nullptr; 1779 SmallVector<OMPLinearClause *, 4> LCs; 1780 // This is required for proper codegen. 1781 for (auto *Clause : Clauses) { 1782 if (isOpenMPPrivate(Clause->getClauseKind()) || 1783 Clause->getClauseKind() == OMPC_copyprivate || 1784 (getLangOpts().OpenMPUseTLS && 1785 getASTContext().getTargetInfo().isTLSSupported() && 1786 Clause->getClauseKind() == OMPC_copyin)) { 1787 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 1788 // Mark all variables in private list clauses as used in inner region. 1789 for (auto *VarRef : Clause->children()) { 1790 if (auto *E = cast_or_null<Expr>(VarRef)) { 1791 MarkDeclarationsReferencedInExpr(E); 1792 } 1793 } 1794 DSAStack->setForceVarCapturing(/*V=*/false); 1795 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 1796 // Mark all variables in private list clauses as used in inner region. 1797 // Required for proper codegen of combined directives. 1798 // TODO: add processing for other clauses. 1799 if (auto *C = OMPClauseWithPreInit::get(Clause)) { 1800 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 1801 for (auto *D : DS->decls()) 1802 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 1803 } 1804 } 1805 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 1806 if (auto *E = C->getPostUpdateExpr()) 1807 MarkDeclarationsReferencedInExpr(E); 1808 } 1809 } 1810 if (Clause->getClauseKind() == OMPC_schedule) 1811 SC = cast<OMPScheduleClause>(Clause); 1812 else if (Clause->getClauseKind() == OMPC_ordered) 1813 OC = cast<OMPOrderedClause>(Clause); 1814 else if (Clause->getClauseKind() == OMPC_linear) 1815 LCs.push_back(cast<OMPLinearClause>(Clause)); 1816 } 1817 bool ErrorFound = false; 1818 // OpenMP, 2.7.1 Loop Construct, Restrictions 1819 // The nonmonotonic modifier cannot be specified if an ordered clause is 1820 // specified. 1821 if (SC && 1822 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 1823 SC->getSecondScheduleModifier() == 1824 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 1825 OC) { 1826 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 1827 ? SC->getFirstScheduleModifierLoc() 1828 : SC->getSecondScheduleModifierLoc(), 1829 diag::err_omp_schedule_nonmonotonic_ordered) 1830 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 1831 ErrorFound = true; 1832 } 1833 if (!LCs.empty() && OC && OC->getNumForLoops()) { 1834 for (auto *C : LCs) { 1835 Diag(C->getLocStart(), diag::err_omp_linear_ordered) 1836 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 1837 } 1838 ErrorFound = true; 1839 } 1840 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 1841 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 1842 OC->getNumForLoops()) { 1843 Diag(OC->getLocStart(), diag::err_omp_ordered_simd) 1844 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 1845 ErrorFound = true; 1846 } 1847 if (ErrorFound) { 1848 ActOnCapturedRegionError(); 1849 return StmtError(); 1850 } 1851 return ActOnCapturedRegionEnd(S.get()); 1852 } 1853 1854 static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, 1855 OpenMPDirectiveKind CurrentRegion, 1856 const DeclarationNameInfo &CurrentName, 1857 OpenMPDirectiveKind CancelRegion, 1858 SourceLocation StartLoc) { 1859 // Allowed nesting of constructs 1860 // +------------------+-----------------+------------------------------------+ 1861 // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)| 1862 // +------------------+-----------------+------------------------------------+ 1863 // | parallel | parallel | * | 1864 // | parallel | for | * | 1865 // | parallel | for simd | * | 1866 // | parallel | master | * | 1867 // | parallel | critical | * | 1868 // | parallel | simd | * | 1869 // | parallel | sections | * | 1870 // | parallel | section | + | 1871 // | parallel | single | * | 1872 // | parallel | parallel for | * | 1873 // | parallel |parallel for simd| * | 1874 // | parallel |parallel sections| * | 1875 // | parallel | task | * | 1876 // | parallel | taskyield | * | 1877 // | parallel | barrier | * | 1878 // | parallel | taskwait | * | 1879 // | parallel | taskgroup | * | 1880 // | parallel | flush | * | 1881 // | parallel | ordered | + | 1882 // | parallel | atomic | * | 1883 // | parallel | target | * | 1884 // | parallel | target parallel | * | 1885 // | parallel | target parallel | * | 1886 // | | for | | 1887 // | parallel | target enter | * | 1888 // | | data | | 1889 // | parallel | target exit | * | 1890 // | | data | | 1891 // | parallel | teams | + | 1892 // | parallel | cancellation | | 1893 // | | point | ! | 1894 // | parallel | cancel | ! | 1895 // | parallel | taskloop | * | 1896 // | parallel | taskloop simd | * | 1897 // | parallel | distribute | | 1898 // +------------------+-----------------+------------------------------------+ 1899 // | for | parallel | * | 1900 // | for | for | + | 1901 // | for | for simd | + | 1902 // | for | master | + | 1903 // | for | critical | * | 1904 // | for | simd | * | 1905 // | for | sections | + | 1906 // | for | section | + | 1907 // | for | single | + | 1908 // | for | parallel for | * | 1909 // | for |parallel for simd| * | 1910 // | for |parallel sections| * | 1911 // | for | task | * | 1912 // | for | taskyield | * | 1913 // | for | barrier | + | 1914 // | for | taskwait | * | 1915 // | for | taskgroup | * | 1916 // | for | flush | * | 1917 // | for | ordered | * (if construct is ordered) | 1918 // | for | atomic | * | 1919 // | for | target | * | 1920 // | for | target parallel | * | 1921 // | for | target parallel | * | 1922 // | | for | | 1923 // | for | target enter | * | 1924 // | | data | | 1925 // | for | target exit | * | 1926 // | | data | | 1927 // | for | teams | + | 1928 // | for | cancellation | | 1929 // | | point | ! | 1930 // | for | cancel | ! | 1931 // | for | taskloop | * | 1932 // | for | taskloop simd | * | 1933 // | for | distribute | | 1934 // +------------------+-----------------+------------------------------------+ 1935 // | master | parallel | * | 1936 // | master | for | + | 1937 // | master | for simd | + | 1938 // | master | master | * | 1939 // | master | critical | * | 1940 // | master | simd | * | 1941 // | master | sections | + | 1942 // | master | section | + | 1943 // | master | single | + | 1944 // | master | parallel for | * | 1945 // | master |parallel for simd| * | 1946 // | master |parallel sections| * | 1947 // | master | task | * | 1948 // | master | taskyield | * | 1949 // | master | barrier | + | 1950 // | master | taskwait | * | 1951 // | master | taskgroup | * | 1952 // | master | flush | * | 1953 // | master | ordered | + | 1954 // | master | atomic | * | 1955 // | master | target | * | 1956 // | master | target parallel | * | 1957 // | master | target parallel | * | 1958 // | | for | | 1959 // | master | target enter | * | 1960 // | | data | | 1961 // | master | target exit | * | 1962 // | | data | | 1963 // | master | teams | + | 1964 // | master | cancellation | | 1965 // | | point | | 1966 // | master | cancel | | 1967 // | master | taskloop | * | 1968 // | master | taskloop simd | * | 1969 // | master | distribute | | 1970 // +------------------+-----------------+------------------------------------+ 1971 // | critical | parallel | * | 1972 // | critical | for | + | 1973 // | critical | for simd | + | 1974 // | critical | master | * | 1975 // | critical | critical | * (should have different names) | 1976 // | critical | simd | * | 1977 // | critical | sections | + | 1978 // | critical | section | + | 1979 // | critical | single | + | 1980 // | critical | parallel for | * | 1981 // | critical |parallel for simd| * | 1982 // | critical |parallel sections| * | 1983 // | critical | task | * | 1984 // | critical | taskyield | * | 1985 // | critical | barrier | + | 1986 // | critical | taskwait | * | 1987 // | critical | taskgroup | * | 1988 // | critical | ordered | + | 1989 // | critical | atomic | * | 1990 // | critical | target | * | 1991 // | critical | target parallel | * | 1992 // | critical | target parallel | * | 1993 // | | for | | 1994 // | critical | target enter | * | 1995 // | | data | | 1996 // | critical | target exit | * | 1997 // | | data | | 1998 // | critical | teams | + | 1999 // | critical | cancellation | | 2000 // | | point | | 2001 // | critical | cancel | | 2002 // | critical | taskloop | * | 2003 // | critical | taskloop simd | * | 2004 // | critical | distribute | | 2005 // +------------------+-----------------+------------------------------------+ 2006 // | simd | parallel | | 2007 // | simd | for | | 2008 // | simd | for simd | | 2009 // | simd | master | | 2010 // | simd | critical | | 2011 // | simd | simd | * | 2012 // | simd | sections | | 2013 // | simd | section | | 2014 // | simd | single | | 2015 // | simd | parallel for | | 2016 // | simd |parallel for simd| | 2017 // | simd |parallel sections| | 2018 // | simd | task | | 2019 // | simd | taskyield | | 2020 // | simd | barrier | | 2021 // | simd | taskwait | | 2022 // | simd | taskgroup | | 2023 // | simd | flush | | 2024 // | simd | ordered | + (with simd clause) | 2025 // | simd | atomic | | 2026 // | simd | target | | 2027 // | simd | target parallel | | 2028 // | simd | target parallel | | 2029 // | | for | | 2030 // | simd | target enter | | 2031 // | | data | | 2032 // | simd | target exit | | 2033 // | | data | | 2034 // | simd | teams | | 2035 // | simd | cancellation | | 2036 // | | point | | 2037 // | simd | cancel | | 2038 // | simd | taskloop | | 2039 // | simd | taskloop simd | | 2040 // | simd | distribute | | 2041 // +------------------+-----------------+------------------------------------+ 2042 // | for simd | parallel | | 2043 // | for simd | for | | 2044 // | for simd | for simd | | 2045 // | for simd | master | | 2046 // | for simd | critical | | 2047 // | for simd | simd | * | 2048 // | for simd | sections | | 2049 // | for simd | section | | 2050 // | for simd | single | | 2051 // | for simd | parallel for | | 2052 // | for simd |parallel for simd| | 2053 // | for simd |parallel sections| | 2054 // | for simd | task | | 2055 // | for simd | taskyield | | 2056 // | for simd | barrier | | 2057 // | for simd | taskwait | | 2058 // | for simd | taskgroup | | 2059 // | for simd | flush | | 2060 // | for simd | ordered | + (with simd clause) | 2061 // | for simd | atomic | | 2062 // | for simd | target | | 2063 // | for simd | target parallel | | 2064 // | for simd | target parallel | | 2065 // | | for | | 2066 // | for simd | target enter | | 2067 // | | data | | 2068 // | for simd | target exit | | 2069 // | | data | | 2070 // | for simd | teams | | 2071 // | for simd | cancellation | | 2072 // | | point | | 2073 // | for simd | cancel | | 2074 // | for simd | taskloop | | 2075 // | for simd | taskloop simd | | 2076 // | for simd | distribute | | 2077 // +------------------+-----------------+------------------------------------+ 2078 // | parallel for simd| parallel | | 2079 // | parallel for simd| for | | 2080 // | parallel for simd| for simd | | 2081 // | parallel for simd| master | | 2082 // | parallel for simd| critical | | 2083 // | parallel for simd| simd | * | 2084 // | parallel for simd| sections | | 2085 // | parallel for simd| section | | 2086 // | parallel for simd| single | | 2087 // | parallel for simd| parallel for | | 2088 // | parallel for simd|parallel for simd| | 2089 // | parallel for simd|parallel sections| | 2090 // | parallel for simd| task | | 2091 // | parallel for simd| taskyield | | 2092 // | parallel for simd| barrier | | 2093 // | parallel for simd| taskwait | | 2094 // | parallel for simd| taskgroup | | 2095 // | parallel for simd| flush | | 2096 // | parallel for simd| ordered | + (with simd clause) | 2097 // | parallel for simd| atomic | | 2098 // | parallel for simd| target | | 2099 // | parallel for simd| target parallel | | 2100 // | parallel for simd| target parallel | | 2101 // | | for | | 2102 // | parallel for simd| target enter | | 2103 // | | data | | 2104 // | parallel for simd| target exit | | 2105 // | | data | | 2106 // | parallel for simd| teams | | 2107 // | parallel for simd| cancellation | | 2108 // | | point | | 2109 // | parallel for simd| cancel | | 2110 // | parallel for simd| taskloop | | 2111 // | parallel for simd| taskloop simd | | 2112 // | parallel for simd| distribute | | 2113 // +------------------+-----------------+------------------------------------+ 2114 // | sections | parallel | * | 2115 // | sections | for | + | 2116 // | sections | for simd | + | 2117 // | sections | master | + | 2118 // | sections | critical | * | 2119 // | sections | simd | * | 2120 // | sections | sections | + | 2121 // | sections | section | * | 2122 // | sections | single | + | 2123 // | sections | parallel for | * | 2124 // | sections |parallel for simd| * | 2125 // | sections |parallel sections| * | 2126 // | sections | task | * | 2127 // | sections | taskyield | * | 2128 // | sections | barrier | + | 2129 // | sections | taskwait | * | 2130 // | sections | taskgroup | * | 2131 // | sections | flush | * | 2132 // | sections | ordered | + | 2133 // | sections | atomic | * | 2134 // | sections | target | * | 2135 // | sections | target parallel | * | 2136 // | sections | target parallel | * | 2137 // | | for | | 2138 // | sections | target enter | * | 2139 // | | data | | 2140 // | sections | target exit | * | 2141 // | | data | | 2142 // | sections | teams | + | 2143 // | sections | cancellation | | 2144 // | | point | ! | 2145 // | sections | cancel | ! | 2146 // | sections | taskloop | * | 2147 // | sections | taskloop simd | * | 2148 // | sections | distribute | | 2149 // +------------------+-----------------+------------------------------------+ 2150 // | section | parallel | * | 2151 // | section | for | + | 2152 // | section | for simd | + | 2153 // | section | master | + | 2154 // | section | critical | * | 2155 // | section | simd | * | 2156 // | section | sections | + | 2157 // | section | section | + | 2158 // | section | single | + | 2159 // | section | parallel for | * | 2160 // | section |parallel for simd| * | 2161 // | section |parallel sections| * | 2162 // | section | task | * | 2163 // | section | taskyield | * | 2164 // | section | barrier | + | 2165 // | section | taskwait | * | 2166 // | section | taskgroup | * | 2167 // | section | flush | * | 2168 // | section | ordered | + | 2169 // | section | atomic | * | 2170 // | section | target | * | 2171 // | section | target parallel | * | 2172 // | section | target parallel | * | 2173 // | | for | | 2174 // | section | target enter | * | 2175 // | | data | | 2176 // | section | target exit | * | 2177 // | | data | | 2178 // | section | teams | + | 2179 // | section | cancellation | | 2180 // | | point | ! | 2181 // | section | cancel | ! | 2182 // | section | taskloop | * | 2183 // | section | taskloop simd | * | 2184 // | section | distribute | | 2185 // +------------------+-----------------+------------------------------------+ 2186 // | single | parallel | * | 2187 // | single | for | + | 2188 // | single | for simd | + | 2189 // | single | master | + | 2190 // | single | critical | * | 2191 // | single | simd | * | 2192 // | single | sections | + | 2193 // | single | section | + | 2194 // | single | single | + | 2195 // | single | parallel for | * | 2196 // | single |parallel for simd| * | 2197 // | single |parallel sections| * | 2198 // | single | task | * | 2199 // | single | taskyield | * | 2200 // | single | barrier | + | 2201 // | single | taskwait | * | 2202 // | single | taskgroup | * | 2203 // | single | flush | * | 2204 // | single | ordered | + | 2205 // | single | atomic | * | 2206 // | single | target | * | 2207 // | single | target parallel | * | 2208 // | single | target parallel | * | 2209 // | | for | | 2210 // | single | target enter | * | 2211 // | | data | | 2212 // | single | target exit | * | 2213 // | | data | | 2214 // | single | teams | + | 2215 // | single | cancellation | | 2216 // | | point | | 2217 // | single | cancel | | 2218 // | single | taskloop | * | 2219 // | single | taskloop simd | * | 2220 // | single | distribute | | 2221 // +------------------+-----------------+------------------------------------+ 2222 // | parallel for | parallel | * | 2223 // | parallel for | for | + | 2224 // | parallel for | for simd | + | 2225 // | parallel for | master | + | 2226 // | parallel for | critical | * | 2227 // | parallel for | simd | * | 2228 // | parallel for | sections | + | 2229 // | parallel for | section | + | 2230 // | parallel for | single | + | 2231 // | parallel for | parallel for | * | 2232 // | parallel for |parallel for simd| * | 2233 // | parallel for |parallel sections| * | 2234 // | parallel for | task | * | 2235 // | parallel for | taskyield | * | 2236 // | parallel for | barrier | + | 2237 // | parallel for | taskwait | * | 2238 // | parallel for | taskgroup | * | 2239 // | parallel for | flush | * | 2240 // | parallel for | ordered | * (if construct is ordered) | 2241 // | parallel for | atomic | * | 2242 // | parallel for | target | * | 2243 // | parallel for | target parallel | * | 2244 // | parallel for | target parallel | * | 2245 // | | for | | 2246 // | parallel for | target enter | * | 2247 // | | data | | 2248 // | parallel for | target exit | * | 2249 // | | data | | 2250 // | parallel for | teams | + | 2251 // | parallel for | cancellation | | 2252 // | | point | ! | 2253 // | parallel for | cancel | ! | 2254 // | parallel for | taskloop | * | 2255 // | parallel for | taskloop simd | * | 2256 // | parallel for | distribute | | 2257 // +------------------+-----------------+------------------------------------+ 2258 // | parallel sections| parallel | * | 2259 // | parallel sections| for | + | 2260 // | parallel sections| for simd | + | 2261 // | parallel sections| master | + | 2262 // | parallel sections| critical | + | 2263 // | parallel sections| simd | * | 2264 // | parallel sections| sections | + | 2265 // | parallel sections| section | * | 2266 // | parallel sections| single | + | 2267 // | parallel sections| parallel for | * | 2268 // | parallel sections|parallel for simd| * | 2269 // | parallel sections|parallel sections| * | 2270 // | parallel sections| task | * | 2271 // | parallel sections| taskyield | * | 2272 // | parallel sections| barrier | + | 2273 // | parallel sections| taskwait | * | 2274 // | parallel sections| taskgroup | * | 2275 // | parallel sections| flush | * | 2276 // | parallel sections| ordered | + | 2277 // | parallel sections| atomic | * | 2278 // | parallel sections| target | * | 2279 // | parallel sections| target parallel | * | 2280 // | parallel sections| target parallel | * | 2281 // | | for | | 2282 // | parallel sections| target enter | * | 2283 // | | data | | 2284 // | parallel sections| target exit | * | 2285 // | | data | | 2286 // | parallel sections| teams | + | 2287 // | parallel sections| cancellation | | 2288 // | | point | ! | 2289 // | parallel sections| cancel | ! | 2290 // | parallel sections| taskloop | * | 2291 // | parallel sections| taskloop simd | * | 2292 // | parallel sections| distribute | | 2293 // +------------------+-----------------+------------------------------------+ 2294 // | task | parallel | * | 2295 // | task | for | + | 2296 // | task | for simd | + | 2297 // | task | master | + | 2298 // | task | critical | * | 2299 // | task | simd | * | 2300 // | task | sections | + | 2301 // | task | section | + | 2302 // | task | single | + | 2303 // | task | parallel for | * | 2304 // | task |parallel for simd| * | 2305 // | task |parallel sections| * | 2306 // | task | task | * | 2307 // | task | taskyield | * | 2308 // | task | barrier | + | 2309 // | task | taskwait | * | 2310 // | task | taskgroup | * | 2311 // | task | flush | * | 2312 // | task | ordered | + | 2313 // | task | atomic | * | 2314 // | task | target | * | 2315 // | task | target parallel | * | 2316 // | task | target parallel | * | 2317 // | | for | | 2318 // | task | target enter | * | 2319 // | | data | | 2320 // | task | target exit | * | 2321 // | | data | | 2322 // | task | teams | + | 2323 // | task | cancellation | | 2324 // | | point | ! | 2325 // | task | cancel | ! | 2326 // | task | taskloop | * | 2327 // | task | taskloop simd | * | 2328 // | task | distribute | | 2329 // +------------------+-----------------+------------------------------------+ 2330 // | ordered | parallel | * | 2331 // | ordered | for | + | 2332 // | ordered | for simd | + | 2333 // | ordered | master | * | 2334 // | ordered | critical | * | 2335 // | ordered | simd | * | 2336 // | ordered | sections | + | 2337 // | ordered | section | + | 2338 // | ordered | single | + | 2339 // | ordered | parallel for | * | 2340 // | ordered |parallel for simd| * | 2341 // | ordered |parallel sections| * | 2342 // | ordered | task | * | 2343 // | ordered | taskyield | * | 2344 // | ordered | barrier | + | 2345 // | ordered | taskwait | * | 2346 // | ordered | taskgroup | * | 2347 // | ordered | flush | * | 2348 // | ordered | ordered | + | 2349 // | ordered | atomic | * | 2350 // | ordered | target | * | 2351 // | ordered | target parallel | * | 2352 // | ordered | target parallel | * | 2353 // | | for | | 2354 // | ordered | target enter | * | 2355 // | | data | | 2356 // | ordered | target exit | * | 2357 // | | data | | 2358 // | ordered | teams | + | 2359 // | ordered | cancellation | | 2360 // | | point | | 2361 // | ordered | cancel | | 2362 // | ordered | taskloop | * | 2363 // | ordered | taskloop simd | * | 2364 // | ordered | distribute | | 2365 // +------------------+-----------------+------------------------------------+ 2366 // | atomic | parallel | | 2367 // | atomic | for | | 2368 // | atomic | for simd | | 2369 // | atomic | master | | 2370 // | atomic | critical | | 2371 // | atomic | simd | | 2372 // | atomic | sections | | 2373 // | atomic | section | | 2374 // | atomic | single | | 2375 // | atomic | parallel for | | 2376 // | atomic |parallel for simd| | 2377 // | atomic |parallel sections| | 2378 // | atomic | task | | 2379 // | atomic | taskyield | | 2380 // | atomic | barrier | | 2381 // | atomic | taskwait | | 2382 // | atomic | taskgroup | | 2383 // | atomic | flush | | 2384 // | atomic | ordered | | 2385 // | atomic | atomic | | 2386 // | atomic | target | | 2387 // | atomic | target parallel | | 2388 // | atomic | target parallel | | 2389 // | | for | | 2390 // | atomic | target enter | | 2391 // | | data | | 2392 // | atomic | target exit | | 2393 // | | data | | 2394 // | atomic | teams | | 2395 // | atomic | cancellation | | 2396 // | | point | | 2397 // | atomic | cancel | | 2398 // | atomic | taskloop | | 2399 // | atomic | taskloop simd | | 2400 // | atomic | distribute | | 2401 // +------------------+-----------------+------------------------------------+ 2402 // | target | parallel | * | 2403 // | target | for | * | 2404 // | target | for simd | * | 2405 // | target | master | * | 2406 // | target | critical | * | 2407 // | target | simd | * | 2408 // | target | sections | * | 2409 // | target | section | * | 2410 // | target | single | * | 2411 // | target | parallel for | * | 2412 // | target |parallel for simd| * | 2413 // | target |parallel sections| * | 2414 // | target | task | * | 2415 // | target | taskyield | * | 2416 // | target | barrier | * | 2417 // | target | taskwait | * | 2418 // | target | taskgroup | * | 2419 // | target | flush | * | 2420 // | target | ordered | * | 2421 // | target | atomic | * | 2422 // | target | target | | 2423 // | target | target parallel | | 2424 // | target | target parallel | | 2425 // | | for | | 2426 // | target | target enter | | 2427 // | | data | | 2428 // | target | target exit | | 2429 // | | data | | 2430 // | target | teams | * | 2431 // | target | cancellation | | 2432 // | | point | | 2433 // | target | cancel | | 2434 // | target | taskloop | * | 2435 // | target | taskloop simd | * | 2436 // | target | distribute | | 2437 // +------------------+-----------------+------------------------------------+ 2438 // | target parallel | parallel | * | 2439 // | target parallel | for | * | 2440 // | target parallel | for simd | * | 2441 // | target parallel | master | * | 2442 // | target parallel | critical | * | 2443 // | target parallel | simd | * | 2444 // | target parallel | sections | * | 2445 // | target parallel | section | * | 2446 // | target parallel | single | * | 2447 // | target parallel | parallel for | * | 2448 // | target parallel |parallel for simd| * | 2449 // | target parallel |parallel sections| * | 2450 // | target parallel | task | * | 2451 // | target parallel | taskyield | * | 2452 // | target parallel | barrier | * | 2453 // | target parallel | taskwait | * | 2454 // | target parallel | taskgroup | * | 2455 // | target parallel | flush | * | 2456 // | target parallel | ordered | * | 2457 // | target parallel | atomic | * | 2458 // | target parallel | target | | 2459 // | target parallel | target parallel | | 2460 // | target parallel | target parallel | | 2461 // | | for | | 2462 // | target parallel | target enter | | 2463 // | | data | | 2464 // | target parallel | target exit | | 2465 // | | data | | 2466 // | target parallel | teams | | 2467 // | target parallel | cancellation | | 2468 // | | point | ! | 2469 // | target parallel | cancel | ! | 2470 // | target parallel | taskloop | * | 2471 // | target parallel | taskloop simd | * | 2472 // | target parallel | distribute | | 2473 // +------------------+-----------------+------------------------------------+ 2474 // | target parallel | parallel | * | 2475 // | for | | | 2476 // | target parallel | for | * | 2477 // | for | | | 2478 // | target parallel | for simd | * | 2479 // | for | | | 2480 // | target parallel | master | * | 2481 // | for | | | 2482 // | target parallel | critical | * | 2483 // | for | | | 2484 // | target parallel | simd | * | 2485 // | for | | | 2486 // | target parallel | sections | * | 2487 // | for | | | 2488 // | target parallel | section | * | 2489 // | for | | | 2490 // | target parallel | single | * | 2491 // | for | | | 2492 // | target parallel | parallel for | * | 2493 // | for | | | 2494 // | target parallel |parallel for simd| * | 2495 // | for | | | 2496 // | target parallel |parallel sections| * | 2497 // | for | | | 2498 // | target parallel | task | * | 2499 // | for | | | 2500 // | target parallel | taskyield | * | 2501 // | for | | | 2502 // | target parallel | barrier | * | 2503 // | for | | | 2504 // | target parallel | taskwait | * | 2505 // | for | | | 2506 // | target parallel | taskgroup | * | 2507 // | for | | | 2508 // | target parallel | flush | * | 2509 // | for | | | 2510 // | target parallel | ordered | * | 2511 // | for | | | 2512 // | target parallel | atomic | * | 2513 // | for | | | 2514 // | target parallel | target | | 2515 // | for | | | 2516 // | target parallel | target parallel | | 2517 // | for | | | 2518 // | target parallel | target parallel | | 2519 // | for | for | | 2520 // | target parallel | target enter | | 2521 // | for | data | | 2522 // | target parallel | target exit | | 2523 // | for | data | | 2524 // | target parallel | teams | | 2525 // | for | | | 2526 // | target parallel | cancellation | | 2527 // | for | point | ! | 2528 // | target parallel | cancel | ! | 2529 // | for | | | 2530 // | target parallel | taskloop | * | 2531 // | for | | | 2532 // | target parallel | taskloop simd | * | 2533 // | for | | | 2534 // | target parallel | distribute | | 2535 // | for | | | 2536 // +------------------+-----------------+------------------------------------+ 2537 // | teams | parallel | * | 2538 // | teams | for | + | 2539 // | teams | for simd | + | 2540 // | teams | master | + | 2541 // | teams | critical | + | 2542 // | teams | simd | + | 2543 // | teams | sections | + | 2544 // | teams | section | + | 2545 // | teams | single | + | 2546 // | teams | parallel for | * | 2547 // | teams |parallel for simd| * | 2548 // | teams |parallel sections| * | 2549 // | teams | task | + | 2550 // | teams | taskyield | + | 2551 // | teams | barrier | + | 2552 // | teams | taskwait | + | 2553 // | teams | taskgroup | + | 2554 // | teams | flush | + | 2555 // | teams | ordered | + | 2556 // | teams | atomic | + | 2557 // | teams | target | + | 2558 // | teams | target parallel | + | 2559 // | teams | target parallel | + | 2560 // | | for | | 2561 // | teams | target enter | + | 2562 // | | data | | 2563 // | teams | target exit | + | 2564 // | | data | | 2565 // | teams | teams | + | 2566 // | teams | cancellation | | 2567 // | | point | | 2568 // | teams | cancel | | 2569 // | teams | taskloop | + | 2570 // | teams | taskloop simd | + | 2571 // | teams | distribute | ! | 2572 // +------------------+-----------------+------------------------------------+ 2573 // | taskloop | parallel | * | 2574 // | taskloop | for | + | 2575 // | taskloop | for simd | + | 2576 // | taskloop | master | + | 2577 // | taskloop | critical | * | 2578 // | taskloop | simd | * | 2579 // | taskloop | sections | + | 2580 // | taskloop | section | + | 2581 // | taskloop | single | + | 2582 // | taskloop | parallel for | * | 2583 // | taskloop |parallel for simd| * | 2584 // | taskloop |parallel sections| * | 2585 // | taskloop | task | * | 2586 // | taskloop | taskyield | * | 2587 // | taskloop | barrier | + | 2588 // | taskloop | taskwait | * | 2589 // | taskloop | taskgroup | * | 2590 // | taskloop | flush | * | 2591 // | taskloop | ordered | + | 2592 // | taskloop | atomic | * | 2593 // | taskloop | target | * | 2594 // | taskloop | target parallel | * | 2595 // | taskloop | target parallel | * | 2596 // | | for | | 2597 // | taskloop | target enter | * | 2598 // | | data | | 2599 // | taskloop | target exit | * | 2600 // | | data | | 2601 // | taskloop | teams | + | 2602 // | taskloop | cancellation | | 2603 // | | point | | 2604 // | taskloop | cancel | | 2605 // | taskloop | taskloop | * | 2606 // | taskloop | distribute | | 2607 // +------------------+-----------------+------------------------------------+ 2608 // | taskloop simd | parallel | | 2609 // | taskloop simd | for | | 2610 // | taskloop simd | for simd | | 2611 // | taskloop simd | master | | 2612 // | taskloop simd | critical | | 2613 // | taskloop simd | simd | * | 2614 // | taskloop simd | sections | | 2615 // | taskloop simd | section | | 2616 // | taskloop simd | single | | 2617 // | taskloop simd | parallel for | | 2618 // | taskloop simd |parallel for simd| | 2619 // | taskloop simd |parallel sections| | 2620 // | taskloop simd | task | | 2621 // | taskloop simd | taskyield | | 2622 // | taskloop simd | barrier | | 2623 // | taskloop simd | taskwait | | 2624 // | taskloop simd | taskgroup | | 2625 // | taskloop simd | flush | | 2626 // | taskloop simd | ordered | + (with simd clause) | 2627 // | taskloop simd | atomic | | 2628 // | taskloop simd | target | | 2629 // | taskloop simd | target parallel | | 2630 // | taskloop simd | target parallel | | 2631 // | | for | | 2632 // | taskloop simd | target enter | | 2633 // | | data | | 2634 // | taskloop simd | target exit | | 2635 // | | data | | 2636 // | taskloop simd | teams | | 2637 // | taskloop simd | cancellation | | 2638 // | | point | | 2639 // | taskloop simd | cancel | | 2640 // | taskloop simd | taskloop | | 2641 // | taskloop simd | taskloop simd | | 2642 // | taskloop simd | distribute | | 2643 // +------------------+-----------------+------------------------------------+ 2644 // | distribute | parallel | * | 2645 // | distribute | for | * | 2646 // | distribute | for simd | * | 2647 // | distribute | master | * | 2648 // | distribute | critical | * | 2649 // | distribute | simd | * | 2650 // | distribute | sections | * | 2651 // | distribute | section | * | 2652 // | distribute | single | * | 2653 // | distribute | parallel for | * | 2654 // | distribute |parallel for simd| * | 2655 // | distribute |parallel sections| * | 2656 // | distribute | task | * | 2657 // | distribute | taskyield | * | 2658 // | distribute | barrier | * | 2659 // | distribute | taskwait | * | 2660 // | distribute | taskgroup | * | 2661 // | distribute | flush | * | 2662 // | distribute | ordered | + | 2663 // | distribute | atomic | * | 2664 // | distribute | target | | 2665 // | distribute | target parallel | | 2666 // | distribute | target parallel | | 2667 // | | for | | 2668 // | distribute | target enter | | 2669 // | | data | | 2670 // | distribute | target exit | | 2671 // | | data | | 2672 // | distribute | teams | | 2673 // | distribute | cancellation | + | 2674 // | | point | | 2675 // | distribute | cancel | + | 2676 // | distribute | taskloop | * | 2677 // | distribute | taskloop simd | * | 2678 // | distribute | distribute | | 2679 // +------------------+-----------------+------------------------------------+ 2680 if (Stack->getCurScope()) { 2681 auto ParentRegion = Stack->getParentDirective(); 2682 auto OffendingRegion = ParentRegion; 2683 bool NestingProhibited = false; 2684 bool CloseNesting = true; 2685 enum { 2686 NoRecommend, 2687 ShouldBeInParallelRegion, 2688 ShouldBeInOrderedRegion, 2689 ShouldBeInTargetRegion, 2690 ShouldBeInTeamsRegion 2691 } Recommend = NoRecommend; 2692 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered && 2693 CurrentRegion != OMPD_simd) { 2694 // OpenMP [2.16, Nesting of Regions] 2695 // OpenMP constructs may not be nested inside a simd region. 2696 // OpenMP [2.8.1,simd Construct, Restrictions] 2697 // An ordered construct with the simd clause is the only OpenMP construct 2698 // that can appear in the simd region. 2699 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd); 2700 return true; 2701 } 2702 if (ParentRegion == OMPD_atomic) { 2703 // OpenMP [2.16, Nesting of Regions] 2704 // OpenMP constructs may not be nested inside an atomic region. 2705 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 2706 return true; 2707 } 2708 if (CurrentRegion == OMPD_section) { 2709 // OpenMP [2.7.2, sections Construct, Restrictions] 2710 // Orphaned section directives are prohibited. That is, the section 2711 // directives must appear within the sections construct and must not be 2712 // encountered elsewhere in the sections region. 2713 if (ParentRegion != OMPD_sections && 2714 ParentRegion != OMPD_parallel_sections) { 2715 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 2716 << (ParentRegion != OMPD_unknown) 2717 << getOpenMPDirectiveName(ParentRegion); 2718 return true; 2719 } 2720 return false; 2721 } 2722 // Allow some constructs to be orphaned (they could be used in functions, 2723 // called from OpenMP regions with the required preconditions). 2724 if (ParentRegion == OMPD_unknown) 2725 return false; 2726 if (CurrentRegion == OMPD_cancellation_point || 2727 CurrentRegion == OMPD_cancel) { 2728 // OpenMP [2.16, Nesting of Regions] 2729 // A cancellation point construct for which construct-type-clause is 2730 // taskgroup must be nested inside a task construct. A cancellation 2731 // point construct for which construct-type-clause is not taskgroup must 2732 // be closely nested inside an OpenMP construct that matches the type 2733 // specified in construct-type-clause. 2734 // A cancel construct for which construct-type-clause is taskgroup must be 2735 // nested inside a task construct. A cancel construct for which 2736 // construct-type-clause is not taskgroup must be closely nested inside an 2737 // OpenMP construct that matches the type specified in 2738 // construct-type-clause. 2739 NestingProhibited = 2740 !((CancelRegion == OMPD_parallel && 2741 (ParentRegion == OMPD_parallel || 2742 ParentRegion == OMPD_target_parallel)) || 2743 (CancelRegion == OMPD_for && 2744 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 2745 ParentRegion == OMPD_target_parallel_for)) || 2746 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 2747 (CancelRegion == OMPD_sections && 2748 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 2749 ParentRegion == OMPD_parallel_sections))); 2750 } else if (CurrentRegion == OMPD_master) { 2751 // OpenMP [2.16, Nesting of Regions] 2752 // A master region may not be closely nested inside a worksharing, 2753 // atomic, or explicit task region. 2754 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2755 ParentRegion == OMPD_task || 2756 isOpenMPTaskLoopDirective(ParentRegion); 2757 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 2758 // OpenMP [2.16, Nesting of Regions] 2759 // A critical region may not be nested (closely or otherwise) inside a 2760 // critical region with the same name. Note that this restriction is not 2761 // sufficient to prevent deadlock. 2762 SourceLocation PreviousCriticalLoc; 2763 bool DeadLock = 2764 Stack->hasDirective([CurrentName, &PreviousCriticalLoc]( 2765 OpenMPDirectiveKind K, 2766 const DeclarationNameInfo &DNI, 2767 SourceLocation Loc) 2768 ->bool { 2769 if (K == OMPD_critical && 2770 DNI.getName() == CurrentName.getName()) { 2771 PreviousCriticalLoc = Loc; 2772 return true; 2773 } else 2774 return false; 2775 }, 2776 false /* skip top directive */); 2777 if (DeadLock) { 2778 SemaRef.Diag(StartLoc, 2779 diag::err_omp_prohibited_region_critical_same_name) 2780 << CurrentName.getName(); 2781 if (PreviousCriticalLoc.isValid()) 2782 SemaRef.Diag(PreviousCriticalLoc, 2783 diag::note_omp_previous_critical_region); 2784 return true; 2785 } 2786 } else if (CurrentRegion == OMPD_barrier) { 2787 // OpenMP [2.16, Nesting of Regions] 2788 // A barrier region may not be closely nested inside a worksharing, 2789 // explicit task, critical, ordered, atomic, or master region. 2790 NestingProhibited = 2791 isOpenMPWorksharingDirective(ParentRegion) || 2792 ParentRegion == OMPD_task || ParentRegion == OMPD_master || 2793 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered || 2794 isOpenMPTaskLoopDirective(ParentRegion); 2795 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 2796 !isOpenMPParallelDirective(CurrentRegion)) { 2797 // OpenMP [2.16, Nesting of Regions] 2798 // A worksharing region may not be closely nested inside a worksharing, 2799 // explicit task, critical, ordered, atomic, or master region. 2800 NestingProhibited = 2801 isOpenMPWorksharingDirective(ParentRegion) || 2802 ParentRegion == OMPD_task || ParentRegion == OMPD_master || 2803 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered || 2804 isOpenMPTaskLoopDirective(ParentRegion); 2805 Recommend = ShouldBeInParallelRegion; 2806 } else if (CurrentRegion == OMPD_ordered) { 2807 // OpenMP [2.16, Nesting of Regions] 2808 // An ordered region may not be closely nested inside a critical, 2809 // atomic, or explicit task region. 2810 // An ordered region must be closely nested inside a loop region (or 2811 // parallel loop region) with an ordered clause. 2812 // OpenMP [2.8.1,simd Construct, Restrictions] 2813 // An ordered construct with the simd clause is the only OpenMP construct 2814 // that can appear in the simd region. 2815 NestingProhibited = ParentRegion == OMPD_critical || 2816 ParentRegion == OMPD_task || 2817 isOpenMPTaskLoopDirective(ParentRegion) || 2818 !(isOpenMPSimdDirective(ParentRegion) || 2819 Stack->isParentOrderedRegion()); 2820 Recommend = ShouldBeInOrderedRegion; 2821 } else if (isOpenMPTeamsDirective(CurrentRegion)) { 2822 // OpenMP [2.16, Nesting of Regions] 2823 // If specified, a teams construct must be contained within a target 2824 // construct. 2825 NestingProhibited = ParentRegion != OMPD_target; 2826 Recommend = ShouldBeInTargetRegion; 2827 Stack->setParentTeamsRegionLoc(Stack->getConstructLoc()); 2828 } 2829 if (!NestingProhibited && isOpenMPTeamsDirective(ParentRegion)) { 2830 // OpenMP [2.16, Nesting of Regions] 2831 // distribute, parallel, parallel sections, parallel workshare, and the 2832 // parallel loop and parallel loop SIMD constructs are the only OpenMP 2833 // constructs that can be closely nested in the teams region. 2834 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 2835 !isOpenMPDistributeDirective(CurrentRegion); 2836 Recommend = ShouldBeInParallelRegion; 2837 } 2838 if (!NestingProhibited && isOpenMPDistributeDirective(CurrentRegion)) { 2839 // OpenMP 4.5 [2.17 Nesting of Regions] 2840 // The region associated with the distribute construct must be strictly 2841 // nested inside a teams region 2842 NestingProhibited = !isOpenMPTeamsDirective(ParentRegion); 2843 Recommend = ShouldBeInTeamsRegion; 2844 } 2845 if (!NestingProhibited && 2846 (isOpenMPTargetExecutionDirective(CurrentRegion) || 2847 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 2848 // OpenMP 4.5 [2.17 Nesting of Regions] 2849 // If a target, target update, target data, target enter data, or 2850 // target exit data construct is encountered during execution of a 2851 // target region, the behavior is unspecified. 2852 NestingProhibited = Stack->hasDirective( 2853 [&OffendingRegion](OpenMPDirectiveKind K, 2854 const DeclarationNameInfo &DNI, 2855 SourceLocation Loc) -> bool { 2856 if (isOpenMPTargetExecutionDirective(K)) { 2857 OffendingRegion = K; 2858 return true; 2859 } else 2860 return false; 2861 }, 2862 false /* don't skip top directive */); 2863 CloseNesting = false; 2864 } 2865 if (NestingProhibited) { 2866 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 2867 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 2868 << Recommend << getOpenMPDirectiveName(CurrentRegion); 2869 return true; 2870 } 2871 } 2872 return false; 2873 } 2874 2875 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 2876 ArrayRef<OMPClause *> Clauses, 2877 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 2878 bool ErrorFound = false; 2879 unsigned NamedModifiersNumber = 0; 2880 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 2881 OMPD_unknown + 1); 2882 SmallVector<SourceLocation, 4> NameModifierLoc; 2883 for (const auto *C : Clauses) { 2884 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 2885 // At most one if clause without a directive-name-modifier can appear on 2886 // the directive. 2887 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 2888 if (FoundNameModifiers[CurNM]) { 2889 S.Diag(C->getLocStart(), diag::err_omp_more_one_clause) 2890 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 2891 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 2892 ErrorFound = true; 2893 } else if (CurNM != OMPD_unknown) { 2894 NameModifierLoc.push_back(IC->getNameModifierLoc()); 2895 ++NamedModifiersNumber; 2896 } 2897 FoundNameModifiers[CurNM] = IC; 2898 if (CurNM == OMPD_unknown) 2899 continue; 2900 // Check if the specified name modifier is allowed for the current 2901 // directive. 2902 // At most one if clause with the particular directive-name-modifier can 2903 // appear on the directive. 2904 bool MatchFound = false; 2905 for (auto NM : AllowedNameModifiers) { 2906 if (CurNM == NM) { 2907 MatchFound = true; 2908 break; 2909 } 2910 } 2911 if (!MatchFound) { 2912 S.Diag(IC->getNameModifierLoc(), 2913 diag::err_omp_wrong_if_directive_name_modifier) 2914 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 2915 ErrorFound = true; 2916 } 2917 } 2918 } 2919 // If any if clause on the directive includes a directive-name-modifier then 2920 // all if clauses on the directive must include a directive-name-modifier. 2921 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 2922 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 2923 S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(), 2924 diag::err_omp_no_more_if_clause); 2925 } else { 2926 std::string Values; 2927 std::string Sep(", "); 2928 unsigned AllowedCnt = 0; 2929 unsigned TotalAllowedNum = 2930 AllowedNameModifiers.size() - NamedModifiersNumber; 2931 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 2932 ++Cnt) { 2933 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 2934 if (!FoundNameModifiers[NM]) { 2935 Values += "'"; 2936 Values += getOpenMPDirectiveName(NM); 2937 Values += "'"; 2938 if (AllowedCnt + 2 == TotalAllowedNum) 2939 Values += " or "; 2940 else if (AllowedCnt + 1 != TotalAllowedNum) 2941 Values += Sep; 2942 ++AllowedCnt; 2943 } 2944 } 2945 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(), 2946 diag::err_omp_unnamed_if_clause) 2947 << (TotalAllowedNum > 1) << Values; 2948 } 2949 for (auto Loc : NameModifierLoc) { 2950 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 2951 } 2952 ErrorFound = true; 2953 } 2954 return ErrorFound; 2955 } 2956 2957 StmtResult Sema::ActOnOpenMPExecutableDirective( 2958 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 2959 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 2960 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 2961 StmtResult Res = StmtError(); 2962 if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 2963 StartLoc)) 2964 return StmtError(); 2965 2966 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 2967 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 2968 bool ErrorFound = false; 2969 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 2970 if (AStmt) { 2971 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 2972 2973 // Check default data sharing attributes for referenced variables. 2974 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 2975 DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt()); 2976 if (DSAChecker.isErrorFound()) 2977 return StmtError(); 2978 // Generate list of implicitly defined firstprivate variables. 2979 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 2980 2981 if (!DSAChecker.getImplicitFirstprivate().empty()) { 2982 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 2983 DSAChecker.getImplicitFirstprivate(), SourceLocation(), 2984 SourceLocation(), SourceLocation())) { 2985 ClausesWithImplicit.push_back(Implicit); 2986 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 2987 DSAChecker.getImplicitFirstprivate().size(); 2988 } else 2989 ErrorFound = true; 2990 } 2991 } 2992 2993 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 2994 switch (Kind) { 2995 case OMPD_parallel: 2996 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 2997 EndLoc); 2998 AllowedNameModifiers.push_back(OMPD_parallel); 2999 break; 3000 case OMPD_simd: 3001 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3002 VarsWithInheritedDSA); 3003 break; 3004 case OMPD_for: 3005 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3006 VarsWithInheritedDSA); 3007 break; 3008 case OMPD_for_simd: 3009 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3010 EndLoc, VarsWithInheritedDSA); 3011 break; 3012 case OMPD_sections: 3013 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 3014 EndLoc); 3015 break; 3016 case OMPD_section: 3017 assert(ClausesWithImplicit.empty() && 3018 "No clauses are allowed for 'omp section' directive"); 3019 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 3020 break; 3021 case OMPD_single: 3022 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 3023 EndLoc); 3024 break; 3025 case OMPD_master: 3026 assert(ClausesWithImplicit.empty() && 3027 "No clauses are allowed for 'omp master' directive"); 3028 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 3029 break; 3030 case OMPD_critical: 3031 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 3032 StartLoc, EndLoc); 3033 break; 3034 case OMPD_parallel_for: 3035 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 3036 EndLoc, VarsWithInheritedDSA); 3037 AllowedNameModifiers.push_back(OMPD_parallel); 3038 break; 3039 case OMPD_parallel_for_simd: 3040 Res = ActOnOpenMPParallelForSimdDirective( 3041 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3042 AllowedNameModifiers.push_back(OMPD_parallel); 3043 break; 3044 case OMPD_parallel_sections: 3045 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 3046 StartLoc, EndLoc); 3047 AllowedNameModifiers.push_back(OMPD_parallel); 3048 break; 3049 case OMPD_task: 3050 Res = 3051 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3052 AllowedNameModifiers.push_back(OMPD_task); 3053 break; 3054 case OMPD_taskyield: 3055 assert(ClausesWithImplicit.empty() && 3056 "No clauses are allowed for 'omp taskyield' directive"); 3057 assert(AStmt == nullptr && 3058 "No associated statement allowed for 'omp taskyield' directive"); 3059 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 3060 break; 3061 case OMPD_barrier: 3062 assert(ClausesWithImplicit.empty() && 3063 "No clauses are allowed for 'omp barrier' directive"); 3064 assert(AStmt == nullptr && 3065 "No associated statement allowed for 'omp barrier' directive"); 3066 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 3067 break; 3068 case OMPD_taskwait: 3069 assert(ClausesWithImplicit.empty() && 3070 "No clauses are allowed for 'omp taskwait' directive"); 3071 assert(AStmt == nullptr && 3072 "No associated statement allowed for 'omp taskwait' directive"); 3073 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 3074 break; 3075 case OMPD_taskgroup: 3076 assert(ClausesWithImplicit.empty() && 3077 "No clauses are allowed for 'omp taskgroup' directive"); 3078 Res = ActOnOpenMPTaskgroupDirective(AStmt, StartLoc, EndLoc); 3079 break; 3080 case OMPD_flush: 3081 assert(AStmt == nullptr && 3082 "No associated statement allowed for 'omp flush' directive"); 3083 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 3084 break; 3085 case OMPD_ordered: 3086 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 3087 EndLoc); 3088 break; 3089 case OMPD_atomic: 3090 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 3091 EndLoc); 3092 break; 3093 case OMPD_teams: 3094 Res = 3095 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3096 break; 3097 case OMPD_target: 3098 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 3099 EndLoc); 3100 AllowedNameModifiers.push_back(OMPD_target); 3101 break; 3102 case OMPD_target_parallel: 3103 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 3104 StartLoc, EndLoc); 3105 AllowedNameModifiers.push_back(OMPD_target); 3106 AllowedNameModifiers.push_back(OMPD_parallel); 3107 break; 3108 case OMPD_target_parallel_for: 3109 Res = ActOnOpenMPTargetParallelForDirective( 3110 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3111 AllowedNameModifiers.push_back(OMPD_target); 3112 AllowedNameModifiers.push_back(OMPD_parallel); 3113 break; 3114 case OMPD_cancellation_point: 3115 assert(ClausesWithImplicit.empty() && 3116 "No clauses are allowed for 'omp cancellation point' directive"); 3117 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 3118 "cancellation point' directive"); 3119 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 3120 break; 3121 case OMPD_cancel: 3122 assert(AStmt == nullptr && 3123 "No associated statement allowed for 'omp cancel' directive"); 3124 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 3125 CancelRegion); 3126 AllowedNameModifiers.push_back(OMPD_cancel); 3127 break; 3128 case OMPD_target_data: 3129 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 3130 EndLoc); 3131 AllowedNameModifiers.push_back(OMPD_target_data); 3132 break; 3133 case OMPD_target_enter_data: 3134 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 3135 EndLoc); 3136 AllowedNameModifiers.push_back(OMPD_target_enter_data); 3137 break; 3138 case OMPD_target_exit_data: 3139 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 3140 EndLoc); 3141 AllowedNameModifiers.push_back(OMPD_target_exit_data); 3142 break; 3143 case OMPD_taskloop: 3144 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 3145 EndLoc, VarsWithInheritedDSA); 3146 AllowedNameModifiers.push_back(OMPD_taskloop); 3147 break; 3148 case OMPD_taskloop_simd: 3149 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3150 EndLoc, VarsWithInheritedDSA); 3151 AllowedNameModifiers.push_back(OMPD_taskloop); 3152 break; 3153 case OMPD_distribute: 3154 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 3155 EndLoc, VarsWithInheritedDSA); 3156 break; 3157 case OMPD_threadprivate: 3158 case OMPD_declare_reduction: 3159 case OMPD_declare_simd: 3160 llvm_unreachable("OpenMP Directive is not allowed"); 3161 case OMPD_unknown: 3162 llvm_unreachable("Unknown OpenMP directive"); 3163 } 3164 3165 for (auto P : VarsWithInheritedDSA) { 3166 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 3167 << P.first << P.second->getSourceRange(); 3168 } 3169 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 3170 3171 if (!AllowedNameModifiers.empty()) 3172 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 3173 ErrorFound; 3174 3175 if (ErrorFound) 3176 return StmtError(); 3177 return Res; 3178 } 3179 3180 Sema::DeclGroupPtrTy 3181 Sema::ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, 3182 SourceLocation StartLoc) { 3183 if (!DG || DG.get().isNull()) 3184 return DeclGroupPtrTy(); 3185 3186 if (!DG.get().isSingleDecl()) { 3187 Diag(StartLoc, diag::err_omp_single_decl_in_declare_simd); 3188 return DG; 3189 } 3190 auto *ADecl = DG.get().getSingleDecl(); 3191 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 3192 ADecl = FTD->getTemplatedDecl(); 3193 3194 if (!isa<FunctionDecl>(ADecl)) { 3195 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 3196 << ADecl->getDeclContext()->isFileContext(); 3197 return DeclGroupPtrTy(); 3198 } 3199 3200 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 3201 Context, SourceRange(StartLoc, StartLoc)); 3202 ADecl->addAttr(NewAttr); 3203 return ConvertDeclToDeclGroup(ADecl); 3204 } 3205 3206 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 3207 Stmt *AStmt, 3208 SourceLocation StartLoc, 3209 SourceLocation EndLoc) { 3210 if (!AStmt) 3211 return StmtError(); 3212 3213 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 3214 // 1.2.2 OpenMP Language Terminology 3215 // Structured block - An executable statement with a single entry at the 3216 // top and a single exit at the bottom. 3217 // The point of exit cannot be a branch out of the structured block. 3218 // longjmp() and throw() must not violate the entry/exit criteria. 3219 CS->getCapturedDecl()->setNothrow(); 3220 3221 getCurFunction()->setHasBranchProtectedScope(); 3222 3223 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 3224 DSAStack->isCancelRegion()); 3225 } 3226 3227 namespace { 3228 /// \brief Helper class for checking canonical form of the OpenMP loops and 3229 /// extracting iteration space of each loop in the loop nest, that will be used 3230 /// for IR generation. 3231 class OpenMPIterationSpaceChecker { 3232 /// \brief Reference to Sema. 3233 Sema &SemaRef; 3234 /// \brief A location for diagnostics (when there is no some better location). 3235 SourceLocation DefaultLoc; 3236 /// \brief A location for diagnostics (when increment is not compatible). 3237 SourceLocation ConditionLoc; 3238 /// \brief A source location for referring to loop init later. 3239 SourceRange InitSrcRange; 3240 /// \brief A source location for referring to condition later. 3241 SourceRange ConditionSrcRange; 3242 /// \brief A source location for referring to increment later. 3243 SourceRange IncrementSrcRange; 3244 /// \brief Loop variable. 3245 VarDecl *Var; 3246 /// \brief Reference to loop variable. 3247 DeclRefExpr *VarRef; 3248 /// \brief Lower bound (initializer for the var). 3249 Expr *LB; 3250 /// \brief Upper bound. 3251 Expr *UB; 3252 /// \brief Loop step (increment). 3253 Expr *Step; 3254 /// \brief This flag is true when condition is one of: 3255 /// Var < UB 3256 /// Var <= UB 3257 /// UB > Var 3258 /// UB >= Var 3259 bool TestIsLessOp; 3260 /// \brief This flag is true when condition is strict ( < or > ). 3261 bool TestIsStrictOp; 3262 /// \brief This flag is true when step is subtracted on each iteration. 3263 bool SubtractStep; 3264 3265 public: 3266 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 3267 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc), 3268 InitSrcRange(SourceRange()), ConditionSrcRange(SourceRange()), 3269 IncrementSrcRange(SourceRange()), Var(nullptr), VarRef(nullptr), 3270 LB(nullptr), UB(nullptr), Step(nullptr), TestIsLessOp(false), 3271 TestIsStrictOp(false), SubtractStep(false) {} 3272 /// \brief Check init-expr for canonical loop form and save loop counter 3273 /// variable - #Var and its initialization value - #LB. 3274 bool CheckInit(Stmt *S, bool EmitDiags = true); 3275 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags 3276 /// for less/greater and for strict/non-strict comparison. 3277 bool CheckCond(Expr *S); 3278 /// \brief Check incr-expr for canonical loop form and return true if it 3279 /// does not conform, otherwise save loop step (#Step). 3280 bool CheckInc(Expr *S); 3281 /// \brief Return the loop counter variable. 3282 VarDecl *GetLoopVar() const { return Var; } 3283 /// \brief Return the reference expression to loop counter variable. 3284 DeclRefExpr *GetLoopVarRefExpr() const { return VarRef; } 3285 /// \brief Source range of the loop init. 3286 SourceRange GetInitSrcRange() const { return InitSrcRange; } 3287 /// \brief Source range of the loop condition. 3288 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; } 3289 /// \brief Source range of the loop increment. 3290 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; } 3291 /// \brief True if the step should be subtracted. 3292 bool ShouldSubtractStep() const { return SubtractStep; } 3293 /// \brief Build the expression to calculate the number of iterations. 3294 Expr * 3295 BuildNumIterations(Scope *S, const bool LimitedType, 3296 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3297 /// \brief Build the precondition expression for the loops. 3298 Expr *BuildPreCond(Scope *S, Expr *Cond, 3299 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3300 /// \brief Build reference expression to the counter be used for codegen. 3301 Expr *BuildCounterVar() const; 3302 /// \brief Build reference expression to the private counter be used for 3303 /// codegen. 3304 Expr *BuildPrivateCounterVar() const; 3305 /// \brief Build initization of the counter be used for codegen. 3306 Expr *BuildCounterInit() const; 3307 /// \brief Build step of the counter be used for codegen. 3308 Expr *BuildCounterStep() const; 3309 /// \brief Return true if any expression is dependent. 3310 bool Dependent() const; 3311 3312 private: 3313 /// \brief Check the right-hand side of an assignment in the increment 3314 /// expression. 3315 bool CheckIncRHS(Expr *RHS); 3316 /// \brief Helper to set loop counter variable and its initializer. 3317 bool SetVarAndLB(VarDecl *NewVar, DeclRefExpr *NewVarRefExpr, Expr *NewLB); 3318 /// \brief Helper to set upper bound. 3319 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR, 3320 SourceLocation SL); 3321 /// \brief Helper to set loop increment. 3322 bool SetStep(Expr *NewStep, bool Subtract); 3323 }; 3324 3325 bool OpenMPIterationSpaceChecker::Dependent() const { 3326 if (!Var) { 3327 assert(!LB && !UB && !Step); 3328 return false; 3329 } 3330 return Var->getType()->isDependentType() || (LB && LB->isValueDependent()) || 3331 (UB && UB->isValueDependent()) || (Step && Step->isValueDependent()); 3332 } 3333 3334 template <typename T> 3335 static T *getExprAsWritten(T *E) { 3336 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) 3337 E = ExprTemp->getSubExpr(); 3338 3339 if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 3340 E = MTE->GetTemporaryExpr(); 3341 3342 while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 3343 E = Binder->getSubExpr(); 3344 3345 if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 3346 E = ICE->getSubExprAsWritten(); 3347 return E->IgnoreParens(); 3348 } 3349 3350 bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar, 3351 DeclRefExpr *NewVarRefExpr, 3352 Expr *NewLB) { 3353 // State consistency checking to ensure correct usage. 3354 assert(Var == nullptr && LB == nullptr && VarRef == nullptr && 3355 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3356 if (!NewVar || !NewLB) 3357 return true; 3358 Var = NewVar; 3359 VarRef = NewVarRefExpr; 3360 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 3361 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3362 if ((Ctor->isCopyOrMoveConstructor() || 3363 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3364 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3365 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 3366 LB = NewLB; 3367 return false; 3368 } 3369 3370 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp, 3371 SourceRange SR, SourceLocation SL) { 3372 // State consistency checking to ensure correct usage. 3373 assert(Var != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && 3374 !TestIsLessOp && !TestIsStrictOp); 3375 if (!NewUB) 3376 return true; 3377 UB = NewUB; 3378 TestIsLessOp = LessOp; 3379 TestIsStrictOp = StrictOp; 3380 ConditionSrcRange = SR; 3381 ConditionLoc = SL; 3382 return false; 3383 } 3384 3385 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) { 3386 // State consistency checking to ensure correct usage. 3387 assert(Var != nullptr && LB != nullptr && Step == nullptr); 3388 if (!NewStep) 3389 return true; 3390 if (!NewStep->isValueDependent()) { 3391 // Check that the step is integer expression. 3392 SourceLocation StepLoc = NewStep->getLocStart(); 3393 ExprResult Val = 3394 SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep); 3395 if (Val.isInvalid()) 3396 return true; 3397 NewStep = Val.get(); 3398 3399 // OpenMP [2.6, Canonical Loop Form, Restrictions] 3400 // If test-expr is of form var relational-op b and relational-op is < or 3401 // <= then incr-expr must cause var to increase on each iteration of the 3402 // loop. If test-expr is of form var relational-op b and relational-op is 3403 // > or >= then incr-expr must cause var to decrease on each iteration of 3404 // the loop. 3405 // If test-expr is of form b relational-op var and relational-op is < or 3406 // <= then incr-expr must cause var to decrease on each iteration of the 3407 // loop. If test-expr is of form b relational-op var and relational-op is 3408 // > or >= then incr-expr must cause var to increase on each iteration of 3409 // the loop. 3410 llvm::APSInt Result; 3411 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 3412 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 3413 bool IsConstNeg = 3414 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 3415 bool IsConstPos = 3416 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 3417 bool IsConstZero = IsConstant && !Result.getBoolValue(); 3418 if (UB && (IsConstZero || 3419 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 3420 : (IsConstPos || (IsUnsigned && !Subtract))))) { 3421 SemaRef.Diag(NewStep->getExprLoc(), 3422 diag::err_omp_loop_incr_not_compatible) 3423 << Var << TestIsLessOp << NewStep->getSourceRange(); 3424 SemaRef.Diag(ConditionLoc, 3425 diag::note_omp_loop_cond_requres_compatible_incr) 3426 << TestIsLessOp << ConditionSrcRange; 3427 return true; 3428 } 3429 if (TestIsLessOp == Subtract) { 3430 NewStep = SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, 3431 NewStep).get(); 3432 Subtract = !Subtract; 3433 } 3434 } 3435 3436 Step = NewStep; 3437 SubtractStep = Subtract; 3438 return false; 3439 } 3440 3441 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { 3442 // Check init-expr for canonical loop form and save loop counter 3443 // variable - #Var and its initialization value - #LB. 3444 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 3445 // var = lb 3446 // integer-type var = lb 3447 // random-access-iterator-type var = lb 3448 // pointer-type var = lb 3449 // 3450 if (!S) { 3451 if (EmitDiags) { 3452 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 3453 } 3454 return true; 3455 } 3456 InitSrcRange = S->getSourceRange(); 3457 if (Expr *E = dyn_cast<Expr>(S)) 3458 S = E->IgnoreParens(); 3459 if (auto BO = dyn_cast<BinaryOperator>(S)) { 3460 if (BO->getOpcode() == BO_Assign) 3461 if (auto DRE = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens())) 3462 return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE, 3463 BO->getRHS()); 3464 } else if (auto DS = dyn_cast<DeclStmt>(S)) { 3465 if (DS->isSingleDecl()) { 3466 if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 3467 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 3468 // Accept non-canonical init form here but emit ext. warning. 3469 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 3470 SemaRef.Diag(S->getLocStart(), 3471 diag::ext_omp_loop_not_canonical_init) 3472 << S->getSourceRange(); 3473 return SetVarAndLB(Var, nullptr, Var->getInit()); 3474 } 3475 } 3476 } 3477 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) 3478 if (CE->getOperator() == OO_Equal) 3479 if (auto DRE = dyn_cast<DeclRefExpr>(CE->getArg(0))) 3480 return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE, 3481 CE->getArg(1)); 3482 3483 if (EmitDiags) { 3484 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init) 3485 << S->getSourceRange(); 3486 } 3487 return true; 3488 } 3489 3490 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the 3491 /// variable (which may be the loop variable) if possible. 3492 static const VarDecl *GetInitVarDecl(const Expr *E) { 3493 if (!E) 3494 return nullptr; 3495 E = getExprAsWritten(E); 3496 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 3497 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3498 if ((Ctor->isCopyOrMoveConstructor() || 3499 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3500 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3501 E = CE->getArg(0)->IgnoreParenImpCasts(); 3502 auto DRE = dyn_cast_or_null<DeclRefExpr>(E); 3503 if (!DRE) 3504 return nullptr; 3505 return dyn_cast<VarDecl>(DRE->getDecl()); 3506 } 3507 3508 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { 3509 // Check test-expr for canonical form, save upper-bound UB, flags for 3510 // less/greater and for strict/non-strict comparison. 3511 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3512 // var relational-op b 3513 // b relational-op var 3514 // 3515 if (!S) { 3516 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << Var; 3517 return true; 3518 } 3519 S = getExprAsWritten(S); 3520 SourceLocation CondLoc = S->getLocStart(); 3521 if (auto BO = dyn_cast<BinaryOperator>(S)) { 3522 if (BO->isRelationalOp()) { 3523 if (GetInitVarDecl(BO->getLHS()) == Var) 3524 return SetUB(BO->getRHS(), 3525 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 3526 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3527 BO->getSourceRange(), BO->getOperatorLoc()); 3528 if (GetInitVarDecl(BO->getRHS()) == Var) 3529 return SetUB(BO->getLHS(), 3530 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 3531 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3532 BO->getSourceRange(), BO->getOperatorLoc()); 3533 } 3534 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3535 if (CE->getNumArgs() == 2) { 3536 auto Op = CE->getOperator(); 3537 switch (Op) { 3538 case OO_Greater: 3539 case OO_GreaterEqual: 3540 case OO_Less: 3541 case OO_LessEqual: 3542 if (GetInitVarDecl(CE->getArg(0)) == Var) 3543 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 3544 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3545 CE->getOperatorLoc()); 3546 if (GetInitVarDecl(CE->getArg(1)) == Var) 3547 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 3548 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3549 CE->getOperatorLoc()); 3550 break; 3551 default: 3552 break; 3553 } 3554 } 3555 } 3556 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 3557 << S->getSourceRange() << Var; 3558 return true; 3559 } 3560 3561 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) { 3562 // RHS of canonical loop form increment can be: 3563 // var + incr 3564 // incr + var 3565 // var - incr 3566 // 3567 RHS = RHS->IgnoreParenImpCasts(); 3568 if (auto BO = dyn_cast<BinaryOperator>(RHS)) { 3569 if (BO->isAdditiveOp()) { 3570 bool IsAdd = BO->getOpcode() == BO_Add; 3571 if (GetInitVarDecl(BO->getLHS()) == Var) 3572 return SetStep(BO->getRHS(), !IsAdd); 3573 if (IsAdd && GetInitVarDecl(BO->getRHS()) == Var) 3574 return SetStep(BO->getLHS(), false); 3575 } 3576 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 3577 bool IsAdd = CE->getOperator() == OO_Plus; 3578 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 3579 if (GetInitVarDecl(CE->getArg(0)) == Var) 3580 return SetStep(CE->getArg(1), !IsAdd); 3581 if (IsAdd && GetInitVarDecl(CE->getArg(1)) == Var) 3582 return SetStep(CE->getArg(0), false); 3583 } 3584 } 3585 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr) 3586 << RHS->getSourceRange() << Var; 3587 return true; 3588 } 3589 3590 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { 3591 // Check incr-expr for canonical loop form and return true if it 3592 // does not conform. 3593 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3594 // ++var 3595 // var++ 3596 // --var 3597 // var-- 3598 // var += incr 3599 // var -= incr 3600 // var = var + incr 3601 // var = incr + var 3602 // var = var - incr 3603 // 3604 if (!S) { 3605 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << Var; 3606 return true; 3607 } 3608 IncrementSrcRange = S->getSourceRange(); 3609 S = S->IgnoreParens(); 3610 if (auto UO = dyn_cast<UnaryOperator>(S)) { 3611 if (UO->isIncrementDecrementOp() && GetInitVarDecl(UO->getSubExpr()) == Var) 3612 return SetStep( 3613 SemaRef.ActOnIntegerConstant(UO->getLocStart(), 3614 (UO->isDecrementOp() ? -1 : 1)).get(), 3615 false); 3616 } else if (auto BO = dyn_cast<BinaryOperator>(S)) { 3617 switch (BO->getOpcode()) { 3618 case BO_AddAssign: 3619 case BO_SubAssign: 3620 if (GetInitVarDecl(BO->getLHS()) == Var) 3621 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 3622 break; 3623 case BO_Assign: 3624 if (GetInitVarDecl(BO->getLHS()) == Var) 3625 return CheckIncRHS(BO->getRHS()); 3626 break; 3627 default: 3628 break; 3629 } 3630 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3631 switch (CE->getOperator()) { 3632 case OO_PlusPlus: 3633 case OO_MinusMinus: 3634 if (GetInitVarDecl(CE->getArg(0)) == Var) 3635 return SetStep( 3636 SemaRef.ActOnIntegerConstant( 3637 CE->getLocStart(), 3638 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).get(), 3639 false); 3640 break; 3641 case OO_PlusEqual: 3642 case OO_MinusEqual: 3643 if (GetInitVarDecl(CE->getArg(0)) == Var) 3644 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 3645 break; 3646 case OO_Equal: 3647 if (GetInitVarDecl(CE->getArg(0)) == Var) 3648 return CheckIncRHS(CE->getArg(1)); 3649 break; 3650 default: 3651 break; 3652 } 3653 } 3654 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr) 3655 << S->getSourceRange() << Var; 3656 return true; 3657 } 3658 3659 static ExprResult 3660 tryBuildCapture(Sema &SemaRef, Expr *Capture, 3661 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 3662 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 3663 return SemaRef.PerformImplicitConversion( 3664 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 3665 /*AllowExplicit=*/true); 3666 auto I = Captures.find(Capture); 3667 if (I != Captures.end()) 3668 return buildCapture(SemaRef, Capture, I->second); 3669 DeclRefExpr *Ref = nullptr; 3670 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 3671 Captures[Capture] = Ref; 3672 return Res; 3673 } 3674 3675 /// \brief Build the expression to calculate the number of iterations. 3676 Expr *OpenMPIterationSpaceChecker::BuildNumIterations( 3677 Scope *S, const bool LimitedType, 3678 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 3679 ExprResult Diff; 3680 auto VarType = Var->getType().getNonReferenceType(); 3681 if (VarType->isIntegerType() || VarType->isPointerType() || 3682 SemaRef.getLangOpts().CPlusPlus) { 3683 // Upper - Lower 3684 auto *UBExpr = TestIsLessOp ? UB : LB; 3685 auto *LBExpr = TestIsLessOp ? LB : UB; 3686 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 3687 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 3688 if (!Upper || !Lower) 3689 return nullptr; 3690 3691 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 3692 3693 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 3694 // BuildBinOp already emitted error, this one is to point user to upper 3695 // and lower bound, and to tell what is passed to 'operator-'. 3696 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) 3697 << Upper->getSourceRange() << Lower->getSourceRange(); 3698 return nullptr; 3699 } 3700 } 3701 3702 if (!Diff.isUsable()) 3703 return nullptr; 3704 3705 // Upper - Lower [- 1] 3706 if (TestIsStrictOp) 3707 Diff = SemaRef.BuildBinOp( 3708 S, DefaultLoc, BO_Sub, Diff.get(), 3709 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 3710 if (!Diff.isUsable()) 3711 return nullptr; 3712 3713 // Upper - Lower [- 1] + Step 3714 auto NewStep = tryBuildCapture(SemaRef, Step, Captures); 3715 if (!NewStep.isUsable()) 3716 return nullptr; 3717 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 3718 if (!Diff.isUsable()) 3719 return nullptr; 3720 3721 // Parentheses (for dumping/debugging purposes only). 3722 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 3723 if (!Diff.isUsable()) 3724 return nullptr; 3725 3726 // (Upper - Lower [- 1] + Step) / Step 3727 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 3728 if (!Diff.isUsable()) 3729 return nullptr; 3730 3731 // OpenMP runtime requires 32-bit or 64-bit loop variables. 3732 QualType Type = Diff.get()->getType(); 3733 auto &C = SemaRef.Context; 3734 bool UseVarType = VarType->hasIntegerRepresentation() && 3735 C.getTypeSize(Type) > C.getTypeSize(VarType); 3736 if (!Type->isIntegerType() || UseVarType) { 3737 unsigned NewSize = 3738 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 3739 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 3740 : Type->hasSignedIntegerRepresentation(); 3741 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 3742 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 3743 Diff = SemaRef.PerformImplicitConversion( 3744 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 3745 if (!Diff.isUsable()) 3746 return nullptr; 3747 } 3748 } 3749 if (LimitedType) { 3750 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 3751 if (NewSize != C.getTypeSize(Type)) { 3752 if (NewSize < C.getTypeSize(Type)) { 3753 assert(NewSize == 64 && "incorrect loop var size"); 3754 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 3755 << InitSrcRange << ConditionSrcRange; 3756 } 3757 QualType NewType = C.getIntTypeForBitwidth( 3758 NewSize, Type->hasSignedIntegerRepresentation() || 3759 C.getTypeSize(Type) < NewSize); 3760 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 3761 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 3762 Sema::AA_Converting, true); 3763 if (!Diff.isUsable()) 3764 return nullptr; 3765 } 3766 } 3767 } 3768 3769 return Diff.get(); 3770 } 3771 3772 Expr *OpenMPIterationSpaceChecker::BuildPreCond( 3773 Scope *S, Expr *Cond, 3774 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 3775 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 3776 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 3777 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 3778 3779 auto NewLB = tryBuildCapture(SemaRef, LB, Captures); 3780 auto NewUB = tryBuildCapture(SemaRef, UB, Captures); 3781 if (!NewLB.isUsable() || !NewUB.isUsable()) 3782 return nullptr; 3783 3784 auto CondExpr = SemaRef.BuildBinOp( 3785 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) 3786 : (TestIsStrictOp ? BO_GT : BO_GE), 3787 NewLB.get(), NewUB.get()); 3788 if (CondExpr.isUsable()) { 3789 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 3790 SemaRef.Context.BoolTy)) 3791 CondExpr = SemaRef.PerformImplicitConversion( 3792 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 3793 /*AllowExplicit=*/true); 3794 } 3795 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 3796 // Otherwise use original loop conditon and evaluate it in runtime. 3797 return CondExpr.isUsable() ? CondExpr.get() : Cond; 3798 } 3799 3800 /// \brief Build reference expression to the counter be used for codegen. 3801 Expr *OpenMPIterationSpaceChecker::BuildCounterVar() const { 3802 return buildDeclRefExpr(SemaRef, Var, Var->getType().getNonReferenceType(), 3803 DefaultLoc); 3804 } 3805 3806 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const { 3807 if (Var && !Var->isInvalidDecl()) { 3808 auto Type = Var->getType().getNonReferenceType(); 3809 auto *PrivateVar = 3810 buildVarDecl(SemaRef, DefaultLoc, Type, Var->getName(), 3811 Var->hasAttrs() ? &Var->getAttrs() : nullptr); 3812 if (PrivateVar->isInvalidDecl()) 3813 return nullptr; 3814 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 3815 } 3816 return nullptr; 3817 } 3818 3819 /// \brief Build initization of the counter be used for codegen. 3820 Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; } 3821 3822 /// \brief Build step of the counter be used for codegen. 3823 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; } 3824 3825 /// \brief Iteration space of a single for loop. 3826 struct LoopIterationSpace { 3827 /// \brief Condition of the loop. 3828 Expr *PreCond; 3829 /// \brief This expression calculates the number of iterations in the loop. 3830 /// It is always possible to calculate it before starting the loop. 3831 Expr *NumIterations; 3832 /// \brief The loop counter variable. 3833 Expr *CounterVar; 3834 /// \brief Private loop counter variable. 3835 Expr *PrivateCounterVar; 3836 /// \brief This is initializer for the initial value of #CounterVar. 3837 Expr *CounterInit; 3838 /// \brief This is step for the #CounterVar used to generate its update: 3839 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 3840 Expr *CounterStep; 3841 /// \brief Should step be subtracted? 3842 bool Subtract; 3843 /// \brief Source range of the loop init. 3844 SourceRange InitSrcRange; 3845 /// \brief Source range of the loop condition. 3846 SourceRange CondSrcRange; 3847 /// \brief Source range of the loop increment. 3848 SourceRange IncSrcRange; 3849 }; 3850 3851 } // namespace 3852 3853 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 3854 assert(getLangOpts().OpenMP && "OpenMP is not active."); 3855 assert(Init && "Expected loop in canonical form."); 3856 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 3857 if (AssociatedLoops > 0 && 3858 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 3859 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 3860 if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) 3861 DSAStack->addLoopControlVariable(ISC.GetLoopVar()); 3862 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 3863 } 3864 } 3865 3866 /// \brief Called on a for stmt to check and extract its iteration space 3867 /// for further processing (such as collapsing). 3868 static bool CheckOpenMPIterationSpace( 3869 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 3870 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 3871 Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, 3872 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 3873 LoopIterationSpace &ResultIterSpace, 3874 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 3875 // OpenMP [2.6, Canonical Loop Form] 3876 // for (init-expr; test-expr; incr-expr) structured-block 3877 auto For = dyn_cast_or_null<ForStmt>(S); 3878 if (!For) { 3879 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for) 3880 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 3881 << getOpenMPDirectiveName(DKind) << NestedLoopCount 3882 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 3883 if (NestedLoopCount > 1) { 3884 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 3885 SemaRef.Diag(DSA.getConstructLoc(), 3886 diag::note_omp_collapse_ordered_expr) 3887 << 2 << CollapseLoopCountExpr->getSourceRange() 3888 << OrderedLoopCountExpr->getSourceRange(); 3889 else if (CollapseLoopCountExpr) 3890 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 3891 diag::note_omp_collapse_ordered_expr) 3892 << 0 << CollapseLoopCountExpr->getSourceRange(); 3893 else 3894 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 3895 diag::note_omp_collapse_ordered_expr) 3896 << 1 << OrderedLoopCountExpr->getSourceRange(); 3897 } 3898 return true; 3899 } 3900 assert(For->getBody()); 3901 3902 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 3903 3904 // Check init. 3905 auto Init = For->getInit(); 3906 if (ISC.CheckInit(Init)) { 3907 return true; 3908 } 3909 3910 bool HasErrors = false; 3911 3912 // Check loop variable's type. 3913 auto Var = ISC.GetLoopVar(); 3914 3915 // OpenMP [2.6, Canonical Loop Form] 3916 // Var is one of the following: 3917 // A variable of signed or unsigned integer type. 3918 // For C++, a variable of a random access iterator type. 3919 // For C, a variable of a pointer type. 3920 auto VarType = Var->getType().getNonReferenceType(); 3921 if (!VarType->isDependentType() && !VarType->isIntegerType() && 3922 !VarType->isPointerType() && 3923 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 3924 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type) 3925 << SemaRef.getLangOpts().CPlusPlus; 3926 HasErrors = true; 3927 } 3928 3929 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in a 3930 // Construct 3931 // The loop iteration variable(s) in the associated for-loop(s) of a for or 3932 // parallel for construct is (are) private. 3933 // The loop iteration variable in the associated for-loop of a simd construct 3934 // with just one associated for-loop is linear with a constant-linear-step 3935 // that is the increment of the associated for-loop. 3936 // Exclude loop var from the list of variables with implicitly defined data 3937 // sharing attributes. 3938 VarsWithImplicitDSA.erase(Var); 3939 3940 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced in 3941 // a Construct, C/C++]. 3942 // The loop iteration variable in the associated for-loop of a simd construct 3943 // with just one associated for-loop may be listed in a linear clause with a 3944 // constant-linear-step that is the increment of the associated for-loop. 3945 // The loop iteration variable(s) in the associated for-loop(s) of a for or 3946 // parallel for construct may be listed in a private or lastprivate clause. 3947 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(Var, false); 3948 auto LoopVarRefExpr = ISC.GetLoopVarRefExpr(); 3949 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 3950 // declared in the loop and it is predetermined as a private. 3951 auto PredeterminedCKind = 3952 isOpenMPSimdDirective(DKind) 3953 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 3954 : OMPC_private; 3955 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 3956 DVar.CKind != PredeterminedCKind) || 3957 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 3958 isOpenMPDistributeDirective(DKind)) && 3959 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 3960 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 3961 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 3962 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa) 3963 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 3964 << getOpenMPClauseName(PredeterminedCKind); 3965 if (DVar.RefExpr == nullptr) 3966 DVar.CKind = PredeterminedCKind; 3967 ReportOriginalDSA(SemaRef, &DSA, Var, DVar, /*IsLoopIterVar=*/true); 3968 HasErrors = true; 3969 } else if (LoopVarRefExpr != nullptr) { 3970 // Make the loop iteration variable private (for worksharing constructs), 3971 // linear (for simd directives with the only one associated loop) or 3972 // lastprivate (for simd directives with several collapsed or ordered 3973 // loops). 3974 if (DVar.CKind == OMPC_unknown) 3975 DVar = DSA.hasDSA(Var, isOpenMPPrivate, MatchesAlways(), 3976 /*FromParent=*/false); 3977 DSA.addDSA(Var, LoopVarRefExpr, PredeterminedCKind); 3978 } 3979 3980 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 3981 3982 // Check test-expr. 3983 HasErrors |= ISC.CheckCond(For->getCond()); 3984 3985 // Check incr-expr. 3986 HasErrors |= ISC.CheckInc(For->getInc()); 3987 3988 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 3989 return HasErrors; 3990 3991 // Build the loop's iteration space representation. 3992 ResultIterSpace.PreCond = 3993 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures); 3994 ResultIterSpace.NumIterations = ISC.BuildNumIterations( 3995 DSA.getCurScope(), 3996 (isOpenMPWorksharingDirective(DKind) || 3997 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 3998 Captures); 3999 ResultIterSpace.CounterVar = ISC.BuildCounterVar(); 4000 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); 4001 ResultIterSpace.CounterInit = ISC.BuildCounterInit(); 4002 ResultIterSpace.CounterStep = ISC.BuildCounterStep(); 4003 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); 4004 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange(); 4005 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange(); 4006 ResultIterSpace.Subtract = ISC.ShouldSubtractStep(); 4007 4008 HasErrors |= (ResultIterSpace.PreCond == nullptr || 4009 ResultIterSpace.NumIterations == nullptr || 4010 ResultIterSpace.CounterVar == nullptr || 4011 ResultIterSpace.PrivateCounterVar == nullptr || 4012 ResultIterSpace.CounterInit == nullptr || 4013 ResultIterSpace.CounterStep == nullptr); 4014 4015 return HasErrors; 4016 } 4017 4018 /// \brief Build 'VarRef = Start. 4019 static ExprResult 4020 BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 4021 ExprResult Start, 4022 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4023 // Build 'VarRef = Start. 4024 auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 4025 if (!NewStart.isUsable()) 4026 return ExprError(); 4027 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 4028 VarRef.get()->getType())) { 4029 NewStart = SemaRef.PerformImplicitConversion( 4030 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 4031 /*AllowExplicit=*/true); 4032 if (!NewStart.isUsable()) 4033 return ExprError(); 4034 } 4035 4036 auto Init = 4037 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4038 return Init; 4039 } 4040 4041 /// \brief Build 'VarRef = Start + Iter * Step'. 4042 static ExprResult 4043 BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, 4044 ExprResult VarRef, ExprResult Start, ExprResult Iter, 4045 ExprResult Step, bool Subtract, 4046 llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) { 4047 // Add parentheses (for debugging purposes only). 4048 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 4049 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 4050 !Step.isUsable()) 4051 return ExprError(); 4052 4053 ExprResult NewStep = Step; 4054 if (Captures) 4055 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 4056 if (NewStep.isInvalid()) 4057 return ExprError(); 4058 ExprResult Update = 4059 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 4060 if (!Update.isUsable()) 4061 return ExprError(); 4062 4063 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 4064 // 'VarRef = Start (+|-) Iter * Step'. 4065 ExprResult NewStart = Start; 4066 if (Captures) 4067 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 4068 if (NewStart.isInvalid()) 4069 return ExprError(); 4070 4071 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 4072 ExprResult SavedUpdate = Update; 4073 ExprResult UpdateVal; 4074 if (VarRef.get()->getType()->isOverloadableType() || 4075 NewStart.get()->getType()->isOverloadableType() || 4076 Update.get()->getType()->isOverloadableType()) { 4077 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4078 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4079 Update = 4080 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4081 if (Update.isUsable()) { 4082 UpdateVal = 4083 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 4084 VarRef.get(), SavedUpdate.get()); 4085 if (UpdateVal.isUsable()) { 4086 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 4087 UpdateVal.get()); 4088 } 4089 } 4090 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4091 } 4092 4093 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 4094 if (!Update.isUsable() || !UpdateVal.isUsable()) { 4095 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 4096 NewStart.get(), SavedUpdate.get()); 4097 if (!Update.isUsable()) 4098 return ExprError(); 4099 4100 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 4101 VarRef.get()->getType())) { 4102 Update = SemaRef.PerformImplicitConversion( 4103 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 4104 if (!Update.isUsable()) 4105 return ExprError(); 4106 } 4107 4108 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 4109 } 4110 return Update; 4111 } 4112 4113 /// \brief Convert integer expression \a E to make it have at least \a Bits 4114 /// bits. 4115 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, 4116 Sema &SemaRef) { 4117 if (E == nullptr) 4118 return ExprError(); 4119 auto &C = SemaRef.Context; 4120 QualType OldType = E->getType(); 4121 unsigned HasBits = C.getTypeSize(OldType); 4122 if (HasBits >= Bits) 4123 return ExprResult(E); 4124 // OK to convert to signed, because new type has more bits than old. 4125 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 4126 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 4127 true); 4128 } 4129 4130 /// \brief Check if the given expression \a E is a constant integer that fits 4131 /// into \a Bits bits. 4132 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { 4133 if (E == nullptr) 4134 return false; 4135 llvm::APSInt Result; 4136 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 4137 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 4138 return false; 4139 } 4140 4141 /// Build preinits statement for the given declarations. 4142 static Stmt *buildPreInits(ASTContext &Context, 4143 SmallVectorImpl<Decl *> &PreInits) { 4144 if (!PreInits.empty()) { 4145 return new (Context) DeclStmt( 4146 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 4147 SourceLocation(), SourceLocation()); 4148 } 4149 return nullptr; 4150 } 4151 4152 /// Build preinits statement for the given declarations. 4153 static Stmt *buildPreInits(ASTContext &Context, 4154 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4155 if (!Captures.empty()) { 4156 SmallVector<Decl *, 16> PreInits; 4157 for (auto &Pair : Captures) 4158 PreInits.push_back(Pair.second->getDecl()); 4159 return buildPreInits(Context, PreInits); 4160 } 4161 return nullptr; 4162 } 4163 4164 /// Build postupdate expression for the given list of postupdates expressions. 4165 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 4166 Expr *PostUpdate = nullptr; 4167 if (!PostUpdates.empty()) { 4168 for (auto *E : PostUpdates) { 4169 Expr *ConvE = S.BuildCStyleCastExpr( 4170 E->getExprLoc(), 4171 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 4172 E->getExprLoc(), E) 4173 .get(); 4174 PostUpdate = PostUpdate 4175 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 4176 PostUpdate, ConvE) 4177 .get() 4178 : ConvE; 4179 } 4180 } 4181 return PostUpdate; 4182 } 4183 4184 /// \brief Called on a for stmt to check itself and nested loops (if any). 4185 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 4186 /// number of collapsed loops otherwise. 4187 static unsigned 4188 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 4189 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 4190 DSAStackTy &DSA, 4191 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 4192 OMPLoopDirective::HelperExprs &Built) { 4193 unsigned NestedLoopCount = 1; 4194 if (CollapseLoopCountExpr) { 4195 // Found 'collapse' clause - calculate collapse number. 4196 llvm::APSInt Result; 4197 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 4198 NestedLoopCount = Result.getLimitedValue(); 4199 } 4200 if (OrderedLoopCountExpr) { 4201 // Found 'ordered' clause - calculate collapse number. 4202 llvm::APSInt Result; 4203 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 4204 if (Result.getLimitedValue() < NestedLoopCount) { 4205 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4206 diag::err_omp_wrong_ordered_loop_count) 4207 << OrderedLoopCountExpr->getSourceRange(); 4208 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4209 diag::note_collapse_loop_count) 4210 << CollapseLoopCountExpr->getSourceRange(); 4211 } 4212 NestedLoopCount = Result.getLimitedValue(); 4213 } 4214 } 4215 // This is helper routine for loop directives (e.g., 'for', 'simd', 4216 // 'for simd', etc.). 4217 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 4218 SmallVector<LoopIterationSpace, 4> IterSpaces; 4219 IterSpaces.resize(NestedLoopCount); 4220 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 4221 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 4222 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, 4223 NestedLoopCount, CollapseLoopCountExpr, 4224 OrderedLoopCountExpr, VarsWithImplicitDSA, 4225 IterSpaces[Cnt], Captures)) 4226 return 0; 4227 // Move on to the next nested for loop, or to the loop body. 4228 // OpenMP [2.8.1, simd construct, Restrictions] 4229 // All loops associated with the construct must be perfectly nested; that 4230 // is, there must be no intervening code nor any OpenMP directive between 4231 // any two loops. 4232 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 4233 } 4234 4235 Built.clear(/* size */ NestedLoopCount); 4236 4237 if (SemaRef.CurContext->isDependentContext()) 4238 return NestedLoopCount; 4239 4240 // An example of what is generated for the following code: 4241 // 4242 // #pragma omp simd collapse(2) ordered(2) 4243 // for (i = 0; i < NI; ++i) 4244 // for (k = 0; k < NK; ++k) 4245 // for (j = J0; j < NJ; j+=2) { 4246 // <loop body> 4247 // } 4248 // 4249 // We generate the code below. 4250 // Note: the loop body may be outlined in CodeGen. 4251 // Note: some counters may be C++ classes, operator- is used to find number of 4252 // iterations and operator+= to calculate counter value. 4253 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 4254 // or i64 is currently supported). 4255 // 4256 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 4257 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 4258 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 4259 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 4260 // // similar updates for vars in clauses (e.g. 'linear') 4261 // <loop body (using local i and j)> 4262 // } 4263 // i = NI; // assign final values of counters 4264 // j = NJ; 4265 // 4266 4267 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 4268 // the iteration counts of the collapsed for loops. 4269 // Precondition tests if there is at least one iteration (all conditions are 4270 // true). 4271 auto PreCond = ExprResult(IterSpaces[0].PreCond); 4272 auto N0 = IterSpaces[0].NumIterations; 4273 ExprResult LastIteration32 = WidenIterationCount( 4274 32 /* Bits */, SemaRef.PerformImplicitConversion( 4275 N0->IgnoreImpCasts(), N0->getType(), 4276 Sema::AA_Converting, /*AllowExplicit=*/true) 4277 .get(), 4278 SemaRef); 4279 ExprResult LastIteration64 = WidenIterationCount( 4280 64 /* Bits */, SemaRef.PerformImplicitConversion( 4281 N0->IgnoreImpCasts(), N0->getType(), 4282 Sema::AA_Converting, /*AllowExplicit=*/true) 4283 .get(), 4284 SemaRef); 4285 4286 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 4287 return NestedLoopCount; 4288 4289 auto &C = SemaRef.Context; 4290 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 4291 4292 Scope *CurScope = DSA.getCurScope(); 4293 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 4294 if (PreCond.isUsable()) { 4295 PreCond = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_LAnd, 4296 PreCond.get(), IterSpaces[Cnt].PreCond); 4297 } 4298 auto N = IterSpaces[Cnt].NumIterations; 4299 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 4300 if (LastIteration32.isUsable()) 4301 LastIteration32 = SemaRef.BuildBinOp( 4302 CurScope, SourceLocation(), BO_Mul, LastIteration32.get(), 4303 SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4304 Sema::AA_Converting, 4305 /*AllowExplicit=*/true) 4306 .get()); 4307 if (LastIteration64.isUsable()) 4308 LastIteration64 = SemaRef.BuildBinOp( 4309 CurScope, SourceLocation(), BO_Mul, LastIteration64.get(), 4310 SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4311 Sema::AA_Converting, 4312 /*AllowExplicit=*/true) 4313 .get()); 4314 } 4315 4316 // Choose either the 32-bit or 64-bit version. 4317 ExprResult LastIteration = LastIteration64; 4318 if (LastIteration32.isUsable() && 4319 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 4320 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 4321 FitsInto( 4322 32 /* Bits */, 4323 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 4324 LastIteration64.get(), SemaRef))) 4325 LastIteration = LastIteration32; 4326 4327 if (!LastIteration.isUsable()) 4328 return 0; 4329 4330 // Save the number of iterations. 4331 ExprResult NumIterations = LastIteration; 4332 { 4333 LastIteration = SemaRef.BuildBinOp( 4334 CurScope, SourceLocation(), BO_Sub, LastIteration.get(), 4335 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4336 if (!LastIteration.isUsable()) 4337 return 0; 4338 } 4339 4340 // Calculate the last iteration number beforehand instead of doing this on 4341 // each iteration. Do not do this if the number of iterations may be kfold-ed. 4342 llvm::APSInt Result; 4343 bool IsConstant = 4344 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 4345 ExprResult CalcLastIteration; 4346 if (!IsConstant) { 4347 ExprResult SaveRef = 4348 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 4349 LastIteration = SaveRef; 4350 4351 // Prepare SaveRef + 1. 4352 NumIterations = SemaRef.BuildBinOp( 4353 CurScope, SourceLocation(), BO_Add, SaveRef.get(), 4354 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4355 if (!NumIterations.isUsable()) 4356 return 0; 4357 } 4358 4359 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 4360 4361 QualType VType = LastIteration.get()->getType(); 4362 // Build variables passed into runtime, nesessary for worksharing directives. 4363 ExprResult LB, UB, IL, ST, EUB; 4364 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4365 isOpenMPDistributeDirective(DKind)) { 4366 // Lower bound variable, initialized with zero. 4367 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 4368 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 4369 SemaRef.AddInitializerToDecl( 4370 LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4371 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 4372 4373 // Upper bound variable, initialized with last iteration number. 4374 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 4375 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 4376 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 4377 /*DirectInit*/ false, 4378 /*TypeMayContainAuto*/ false); 4379 4380 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 4381 // This will be used to implement clause 'lastprivate'. 4382 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 4383 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 4384 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 4385 SemaRef.AddInitializerToDecl( 4386 ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4387 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 4388 4389 // Stride variable returned by runtime (we initialize it to 1 by default). 4390 VarDecl *STDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.stride"); 4391 ST = buildDeclRefExpr(SemaRef, STDecl, VType, InitLoc); 4392 SemaRef.AddInitializerToDecl( 4393 STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 4394 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 4395 4396 // Build expression: UB = min(UB, LastIteration) 4397 // It is nesessary for CodeGen of directives with static scheduling. 4398 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 4399 UB.get(), LastIteration.get()); 4400 ExprResult CondOp = SemaRef.ActOnConditionalOp( 4401 InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get()); 4402 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 4403 CondOp.get()); 4404 EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); 4405 } 4406 4407 // Build the iteration variable and its initialization before loop. 4408 ExprResult IV; 4409 ExprResult Init; 4410 { 4411 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.iv"); 4412 IV = buildDeclRefExpr(SemaRef, IVDecl, VType, InitLoc); 4413 Expr *RHS = (isOpenMPWorksharingDirective(DKind) || 4414 isOpenMPTaskLoopDirective(DKind) || 4415 isOpenMPDistributeDirective(DKind)) 4416 ? LB.get() 4417 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 4418 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 4419 Init = SemaRef.ActOnFinishFullExpr(Init.get()); 4420 } 4421 4422 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. 4423 SourceLocation CondLoc; 4424 ExprResult Cond = 4425 (isOpenMPWorksharingDirective(DKind) || 4426 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 4427 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) 4428 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 4429 NumIterations.get()); 4430 4431 // Loop increment (IV = IV + 1) 4432 SourceLocation IncLoc; 4433 ExprResult Inc = 4434 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 4435 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 4436 if (!Inc.isUsable()) 4437 return 0; 4438 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 4439 Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); 4440 if (!Inc.isUsable()) 4441 return 0; 4442 4443 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 4444 // Used for directives with static scheduling. 4445 ExprResult NextLB, NextUB; 4446 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4447 isOpenMPDistributeDirective(DKind)) { 4448 // LB + ST 4449 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 4450 if (!NextLB.isUsable()) 4451 return 0; 4452 // LB = LB + ST 4453 NextLB = 4454 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 4455 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); 4456 if (!NextLB.isUsable()) 4457 return 0; 4458 // UB + ST 4459 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 4460 if (!NextUB.isUsable()) 4461 return 0; 4462 // UB = UB + ST 4463 NextUB = 4464 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 4465 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); 4466 if (!NextUB.isUsable()) 4467 return 0; 4468 } 4469 4470 // Build updates and final values of the loop counters. 4471 bool HasErrors = false; 4472 Built.Counters.resize(NestedLoopCount); 4473 Built.Inits.resize(NestedLoopCount); 4474 Built.Updates.resize(NestedLoopCount); 4475 Built.Finals.resize(NestedLoopCount); 4476 { 4477 ExprResult Div; 4478 // Go from inner nested loop to outer. 4479 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 4480 LoopIterationSpace &IS = IterSpaces[Cnt]; 4481 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 4482 // Build: Iter = (IV / Div) % IS.NumIters 4483 // where Div is product of previous iterations' IS.NumIters. 4484 ExprResult Iter; 4485 if (Div.isUsable()) { 4486 Iter = 4487 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); 4488 } else { 4489 Iter = IV; 4490 assert((Cnt == (int)NestedLoopCount - 1) && 4491 "unusable div expected on first iteration only"); 4492 } 4493 4494 if (Cnt != 0 && Iter.isUsable()) 4495 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), 4496 IS.NumIterations); 4497 if (!Iter.isUsable()) { 4498 HasErrors = true; 4499 break; 4500 } 4501 4502 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 4503 auto *CounterVar = buildDeclRefExpr( 4504 SemaRef, cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()), 4505 IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 4506 /*RefersToCapture=*/true); 4507 ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 4508 IS.CounterInit, Captures); 4509 if (!Init.isUsable()) { 4510 HasErrors = true; 4511 break; 4512 } 4513 ExprResult Update = BuildCounterUpdate( 4514 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 4515 IS.CounterStep, IS.Subtract, &Captures); 4516 if (!Update.isUsable()) { 4517 HasErrors = true; 4518 break; 4519 } 4520 4521 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 4522 ExprResult Final = BuildCounterUpdate( 4523 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 4524 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 4525 if (!Final.isUsable()) { 4526 HasErrors = true; 4527 break; 4528 } 4529 4530 // Build Div for the next iteration: Div <- Div * IS.NumIters 4531 if (Cnt != 0) { 4532 if (Div.isUnset()) 4533 Div = IS.NumIterations; 4534 else 4535 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), 4536 IS.NumIterations); 4537 4538 // Add parentheses (for debugging purposes only). 4539 if (Div.isUsable()) 4540 Div = SemaRef.ActOnParenExpr(UpdLoc, UpdLoc, Div.get()); 4541 if (!Div.isUsable()) { 4542 HasErrors = true; 4543 break; 4544 } 4545 } 4546 if (!Update.isUsable() || !Final.isUsable()) { 4547 HasErrors = true; 4548 break; 4549 } 4550 // Save results 4551 Built.Counters[Cnt] = IS.CounterVar; 4552 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 4553 Built.Inits[Cnt] = Init.get(); 4554 Built.Updates[Cnt] = Update.get(); 4555 Built.Finals[Cnt] = Final.get(); 4556 } 4557 } 4558 4559 if (HasErrors) 4560 return 0; 4561 4562 // Save results 4563 Built.IterationVarRef = IV.get(); 4564 Built.LastIteration = LastIteration.get(); 4565 Built.NumIterations = NumIterations.get(); 4566 Built.CalcLastIteration = 4567 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); 4568 Built.PreCond = PreCond.get(); 4569 Built.PreInits = buildPreInits(C, Captures); 4570 Built.Cond = Cond.get(); 4571 Built.Init = Init.get(); 4572 Built.Inc = Inc.get(); 4573 Built.LB = LB.get(); 4574 Built.UB = UB.get(); 4575 Built.IL = IL.get(); 4576 Built.ST = ST.get(); 4577 Built.EUB = EUB.get(); 4578 Built.NLB = NextLB.get(); 4579 Built.NUB = NextUB.get(); 4580 4581 return NestedLoopCount; 4582 } 4583 4584 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 4585 auto CollapseClauses = 4586 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 4587 if (CollapseClauses.begin() != CollapseClauses.end()) 4588 return (*CollapseClauses.begin())->getNumForLoops(); 4589 return nullptr; 4590 } 4591 4592 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 4593 auto OrderedClauses = 4594 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 4595 if (OrderedClauses.begin() != OrderedClauses.end()) 4596 return (*OrderedClauses.begin())->getNumForLoops(); 4597 return nullptr; 4598 } 4599 4600 static bool checkSimdlenSafelenValues(Sema &S, const Expr *Simdlen, 4601 const Expr *Safelen) { 4602 llvm::APSInt SimdlenRes, SafelenRes; 4603 if (Simdlen->isValueDependent() || Simdlen->isTypeDependent() || 4604 Simdlen->isInstantiationDependent() || 4605 Simdlen->containsUnexpandedParameterPack()) 4606 return false; 4607 if (Safelen->isValueDependent() || Safelen->isTypeDependent() || 4608 Safelen->isInstantiationDependent() || 4609 Safelen->containsUnexpandedParameterPack()) 4610 return false; 4611 Simdlen->EvaluateAsInt(SimdlenRes, S.Context); 4612 Safelen->EvaluateAsInt(SafelenRes, S.Context); 4613 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 4614 // If both simdlen and safelen clauses are specified, the value of the simdlen 4615 // parameter must be less than or equal to the value of the safelen parameter. 4616 if (SimdlenRes > SafelenRes) { 4617 S.Diag(Simdlen->getExprLoc(), diag::err_omp_wrong_simdlen_safelen_values) 4618 << Simdlen->getSourceRange() << Safelen->getSourceRange(); 4619 return true; 4620 } 4621 return false; 4622 } 4623 4624 StmtResult Sema::ActOnOpenMPSimdDirective( 4625 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4626 SourceLocation EndLoc, 4627 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4628 if (!AStmt) 4629 return StmtError(); 4630 4631 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4632 OMPLoopDirective::HelperExprs B; 4633 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 4634 // define the nested loops number. 4635 unsigned NestedLoopCount = CheckOpenMPLoop( 4636 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 4637 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 4638 if (NestedLoopCount == 0) 4639 return StmtError(); 4640 4641 assert((CurContext->isDependentContext() || B.builtAll()) && 4642 "omp simd loop exprs were not built"); 4643 4644 if (!CurContext->isDependentContext()) { 4645 // Finalize the clauses that need pre-built expressions for CodeGen. 4646 for (auto C : Clauses) { 4647 if (auto LC = dyn_cast<OMPLinearClause>(C)) 4648 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 4649 B.NumIterations, *this, CurScope)) 4650 return StmtError(); 4651 } 4652 } 4653 4654 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 4655 // If both simdlen and safelen clauses are specified, the value of the simdlen 4656 // parameter must be less than or equal to the value of the safelen parameter. 4657 OMPSafelenClause *Safelen = nullptr; 4658 OMPSimdlenClause *Simdlen = nullptr; 4659 for (auto *Clause : Clauses) { 4660 if (Clause->getClauseKind() == OMPC_safelen) 4661 Safelen = cast<OMPSafelenClause>(Clause); 4662 else if (Clause->getClauseKind() == OMPC_simdlen) 4663 Simdlen = cast<OMPSimdlenClause>(Clause); 4664 if (Safelen && Simdlen) 4665 break; 4666 } 4667 if (Simdlen && Safelen && 4668 checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), 4669 Safelen->getSafelen())) 4670 return StmtError(); 4671 4672 getCurFunction()->setHasBranchProtectedScope(); 4673 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 4674 Clauses, AStmt, B); 4675 } 4676 4677 StmtResult Sema::ActOnOpenMPForDirective( 4678 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4679 SourceLocation EndLoc, 4680 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4681 if (!AStmt) 4682 return StmtError(); 4683 4684 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4685 OMPLoopDirective::HelperExprs B; 4686 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 4687 // define the nested loops number. 4688 unsigned NestedLoopCount = CheckOpenMPLoop( 4689 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 4690 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 4691 if (NestedLoopCount == 0) 4692 return StmtError(); 4693 4694 assert((CurContext->isDependentContext() || B.builtAll()) && 4695 "omp for loop exprs were not built"); 4696 4697 if (!CurContext->isDependentContext()) { 4698 // Finalize the clauses that need pre-built expressions for CodeGen. 4699 for (auto C : Clauses) { 4700 if (auto LC = dyn_cast<OMPLinearClause>(C)) 4701 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 4702 B.NumIterations, *this, CurScope)) 4703 return StmtError(); 4704 } 4705 } 4706 4707 getCurFunction()->setHasBranchProtectedScope(); 4708 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 4709 Clauses, AStmt, B, DSAStack->isCancelRegion()); 4710 } 4711 4712 StmtResult Sema::ActOnOpenMPForSimdDirective( 4713 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4714 SourceLocation EndLoc, 4715 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4716 if (!AStmt) 4717 return StmtError(); 4718 4719 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4720 OMPLoopDirective::HelperExprs B; 4721 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 4722 // define the nested loops number. 4723 unsigned NestedLoopCount = 4724 CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 4725 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 4726 VarsWithImplicitDSA, B); 4727 if (NestedLoopCount == 0) 4728 return StmtError(); 4729 4730 assert((CurContext->isDependentContext() || B.builtAll()) && 4731 "omp for simd loop exprs were not built"); 4732 4733 if (!CurContext->isDependentContext()) { 4734 // Finalize the clauses that need pre-built expressions for CodeGen. 4735 for (auto C : Clauses) { 4736 if (auto LC = dyn_cast<OMPLinearClause>(C)) 4737 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 4738 B.NumIterations, *this, CurScope)) 4739 return StmtError(); 4740 } 4741 } 4742 4743 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 4744 // If both simdlen and safelen clauses are specified, the value of the simdlen 4745 // parameter must be less than or equal to the value of the safelen parameter. 4746 OMPSafelenClause *Safelen = nullptr; 4747 OMPSimdlenClause *Simdlen = nullptr; 4748 for (auto *Clause : Clauses) { 4749 if (Clause->getClauseKind() == OMPC_safelen) 4750 Safelen = cast<OMPSafelenClause>(Clause); 4751 else if (Clause->getClauseKind() == OMPC_simdlen) 4752 Simdlen = cast<OMPSimdlenClause>(Clause); 4753 if (Safelen && Simdlen) 4754 break; 4755 } 4756 if (Simdlen && Safelen && 4757 checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), 4758 Safelen->getSafelen())) 4759 return StmtError(); 4760 4761 getCurFunction()->setHasBranchProtectedScope(); 4762 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 4763 Clauses, AStmt, B); 4764 } 4765 4766 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 4767 Stmt *AStmt, 4768 SourceLocation StartLoc, 4769 SourceLocation EndLoc) { 4770 if (!AStmt) 4771 return StmtError(); 4772 4773 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4774 auto BaseStmt = AStmt; 4775 while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 4776 BaseStmt = CS->getCapturedStmt(); 4777 if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 4778 auto S = C->children(); 4779 if (S.begin() == S.end()) 4780 return StmtError(); 4781 // All associated statements must be '#pragma omp section' except for 4782 // the first one. 4783 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 4784 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 4785 if (SectionStmt) 4786 Diag(SectionStmt->getLocStart(), 4787 diag::err_omp_sections_substmt_not_section); 4788 return StmtError(); 4789 } 4790 cast<OMPSectionDirective>(SectionStmt) 4791 ->setHasCancel(DSAStack->isCancelRegion()); 4792 } 4793 } else { 4794 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt); 4795 return StmtError(); 4796 } 4797 4798 getCurFunction()->setHasBranchProtectedScope(); 4799 4800 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4801 DSAStack->isCancelRegion()); 4802 } 4803 4804 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 4805 SourceLocation StartLoc, 4806 SourceLocation EndLoc) { 4807 if (!AStmt) 4808 return StmtError(); 4809 4810 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4811 4812 getCurFunction()->setHasBranchProtectedScope(); 4813 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 4814 4815 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 4816 DSAStack->isCancelRegion()); 4817 } 4818 4819 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 4820 Stmt *AStmt, 4821 SourceLocation StartLoc, 4822 SourceLocation EndLoc) { 4823 if (!AStmt) 4824 return StmtError(); 4825 4826 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4827 4828 getCurFunction()->setHasBranchProtectedScope(); 4829 4830 // OpenMP [2.7.3, single Construct, Restrictions] 4831 // The copyprivate clause must not be used with the nowait clause. 4832 OMPClause *Nowait = nullptr; 4833 OMPClause *Copyprivate = nullptr; 4834 for (auto *Clause : Clauses) { 4835 if (Clause->getClauseKind() == OMPC_nowait) 4836 Nowait = Clause; 4837 else if (Clause->getClauseKind() == OMPC_copyprivate) 4838 Copyprivate = Clause; 4839 if (Copyprivate && Nowait) { 4840 Diag(Copyprivate->getLocStart(), 4841 diag::err_omp_single_copyprivate_with_nowait); 4842 Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here); 4843 return StmtError(); 4844 } 4845 } 4846 4847 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 4848 } 4849 4850 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 4851 SourceLocation StartLoc, 4852 SourceLocation EndLoc) { 4853 if (!AStmt) 4854 return StmtError(); 4855 4856 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4857 4858 getCurFunction()->setHasBranchProtectedScope(); 4859 4860 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 4861 } 4862 4863 StmtResult Sema::ActOnOpenMPCriticalDirective( 4864 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 4865 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4866 if (!AStmt) 4867 return StmtError(); 4868 4869 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4870 4871 bool ErrorFound = false; 4872 llvm::APSInt Hint; 4873 SourceLocation HintLoc; 4874 bool DependentHint = false; 4875 for (auto *C : Clauses) { 4876 if (C->getClauseKind() == OMPC_hint) { 4877 if (!DirName.getName()) { 4878 Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name); 4879 ErrorFound = true; 4880 } 4881 Expr *E = cast<OMPHintClause>(C)->getHint(); 4882 if (E->isTypeDependent() || E->isValueDependent() || 4883 E->isInstantiationDependent()) 4884 DependentHint = true; 4885 else { 4886 Hint = E->EvaluateKnownConstInt(Context); 4887 HintLoc = C->getLocStart(); 4888 } 4889 } 4890 } 4891 if (ErrorFound) 4892 return StmtError(); 4893 auto Pair = DSAStack->getCriticalWithHint(DirName); 4894 if (Pair.first && DirName.getName() && !DependentHint) { 4895 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 4896 Diag(StartLoc, diag::err_omp_critical_with_hint); 4897 if (HintLoc.isValid()) { 4898 Diag(HintLoc, diag::note_omp_critical_hint_here) 4899 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 4900 } else 4901 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 4902 if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 4903 Diag(C->getLocStart(), diag::note_omp_critical_hint_here) 4904 << 1 4905 << C->getHint()->EvaluateKnownConstInt(Context).toString( 4906 /*Radix=*/10, /*Signed=*/false); 4907 } else 4908 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1; 4909 } 4910 } 4911 4912 getCurFunction()->setHasBranchProtectedScope(); 4913 4914 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 4915 Clauses, AStmt); 4916 if (!Pair.first && DirName.getName() && !DependentHint) 4917 DSAStack->addCriticalWithHint(Dir, Hint); 4918 return Dir; 4919 } 4920 4921 StmtResult Sema::ActOnOpenMPParallelForDirective( 4922 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4923 SourceLocation EndLoc, 4924 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4925 if (!AStmt) 4926 return StmtError(); 4927 4928 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 4929 // 1.2.2 OpenMP Language Terminology 4930 // Structured block - An executable statement with a single entry at the 4931 // top and a single exit at the bottom. 4932 // The point of exit cannot be a branch out of the structured block. 4933 // longjmp() and throw() must not violate the entry/exit criteria. 4934 CS->getCapturedDecl()->setNothrow(); 4935 4936 OMPLoopDirective::HelperExprs B; 4937 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 4938 // define the nested loops number. 4939 unsigned NestedLoopCount = 4940 CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 4941 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 4942 VarsWithImplicitDSA, B); 4943 if (NestedLoopCount == 0) 4944 return StmtError(); 4945 4946 assert((CurContext->isDependentContext() || B.builtAll()) && 4947 "omp parallel for loop exprs were not built"); 4948 4949 if (!CurContext->isDependentContext()) { 4950 // Finalize the clauses that need pre-built expressions for CodeGen. 4951 for (auto C : Clauses) { 4952 if (auto LC = dyn_cast<OMPLinearClause>(C)) 4953 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 4954 B.NumIterations, *this, CurScope)) 4955 return StmtError(); 4956 } 4957 } 4958 4959 getCurFunction()->setHasBranchProtectedScope(); 4960 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 4961 NestedLoopCount, Clauses, AStmt, B, 4962 DSAStack->isCancelRegion()); 4963 } 4964 4965 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 4966 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4967 SourceLocation EndLoc, 4968 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4969 if (!AStmt) 4970 return StmtError(); 4971 4972 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 4973 // 1.2.2 OpenMP Language Terminology 4974 // Structured block - An executable statement with a single entry at the 4975 // top and a single exit at the bottom. 4976 // The point of exit cannot be a branch out of the structured block. 4977 // longjmp() and throw() must not violate the entry/exit criteria. 4978 CS->getCapturedDecl()->setNothrow(); 4979 4980 OMPLoopDirective::HelperExprs B; 4981 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 4982 // define the nested loops number. 4983 unsigned NestedLoopCount = 4984 CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 4985 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 4986 VarsWithImplicitDSA, B); 4987 if (NestedLoopCount == 0) 4988 return StmtError(); 4989 4990 if (!CurContext->isDependentContext()) { 4991 // Finalize the clauses that need pre-built expressions for CodeGen. 4992 for (auto C : Clauses) { 4993 if (auto LC = dyn_cast<OMPLinearClause>(C)) 4994 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 4995 B.NumIterations, *this, CurScope)) 4996 return StmtError(); 4997 } 4998 } 4999 5000 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 5001 // If both simdlen and safelen clauses are specified, the value of the simdlen 5002 // parameter must be less than or equal to the value of the safelen parameter. 5003 OMPSafelenClause *Safelen = nullptr; 5004 OMPSimdlenClause *Simdlen = nullptr; 5005 for (auto *Clause : Clauses) { 5006 if (Clause->getClauseKind() == OMPC_safelen) 5007 Safelen = cast<OMPSafelenClause>(Clause); 5008 else if (Clause->getClauseKind() == OMPC_simdlen) 5009 Simdlen = cast<OMPSimdlenClause>(Clause); 5010 if (Safelen && Simdlen) 5011 break; 5012 } 5013 if (Simdlen && Safelen && 5014 checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), 5015 Safelen->getSafelen())) 5016 return StmtError(); 5017 5018 getCurFunction()->setHasBranchProtectedScope(); 5019 return OMPParallelForSimdDirective::Create( 5020 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 5021 } 5022 5023 StmtResult 5024 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 5025 Stmt *AStmt, SourceLocation StartLoc, 5026 SourceLocation EndLoc) { 5027 if (!AStmt) 5028 return StmtError(); 5029 5030 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5031 auto BaseStmt = AStmt; 5032 while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5033 BaseStmt = CS->getCapturedStmt(); 5034 if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5035 auto S = C->children(); 5036 if (S.begin() == S.end()) 5037 return StmtError(); 5038 // All associated statements must be '#pragma omp section' except for 5039 // the first one. 5040 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5041 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5042 if (SectionStmt) 5043 Diag(SectionStmt->getLocStart(), 5044 diag::err_omp_parallel_sections_substmt_not_section); 5045 return StmtError(); 5046 } 5047 cast<OMPSectionDirective>(SectionStmt) 5048 ->setHasCancel(DSAStack->isCancelRegion()); 5049 } 5050 } else { 5051 Diag(AStmt->getLocStart(), 5052 diag::err_omp_parallel_sections_not_compound_stmt); 5053 return StmtError(); 5054 } 5055 5056 getCurFunction()->setHasBranchProtectedScope(); 5057 5058 return OMPParallelSectionsDirective::Create( 5059 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 5060 } 5061 5062 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 5063 Stmt *AStmt, SourceLocation StartLoc, 5064 SourceLocation EndLoc) { 5065 if (!AStmt) 5066 return StmtError(); 5067 5068 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5069 // 1.2.2 OpenMP Language Terminology 5070 // Structured block - An executable statement with a single entry at the 5071 // top and a single exit at the bottom. 5072 // The point of exit cannot be a branch out of the structured block. 5073 // longjmp() and throw() must not violate the entry/exit criteria. 5074 CS->getCapturedDecl()->setNothrow(); 5075 5076 getCurFunction()->setHasBranchProtectedScope(); 5077 5078 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5079 DSAStack->isCancelRegion()); 5080 } 5081 5082 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 5083 SourceLocation EndLoc) { 5084 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 5085 } 5086 5087 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 5088 SourceLocation EndLoc) { 5089 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 5090 } 5091 5092 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 5093 SourceLocation EndLoc) { 5094 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 5095 } 5096 5097 StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt, 5098 SourceLocation StartLoc, 5099 SourceLocation EndLoc) { 5100 if (!AStmt) 5101 return StmtError(); 5102 5103 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5104 5105 getCurFunction()->setHasBranchProtectedScope(); 5106 5107 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, AStmt); 5108 } 5109 5110 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 5111 SourceLocation StartLoc, 5112 SourceLocation EndLoc) { 5113 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 5114 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 5115 } 5116 5117 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 5118 Stmt *AStmt, 5119 SourceLocation StartLoc, 5120 SourceLocation EndLoc) { 5121 OMPClause *DependFound = nullptr; 5122 OMPClause *DependSourceClause = nullptr; 5123 OMPClause *DependSinkClause = nullptr; 5124 bool ErrorFound = false; 5125 OMPThreadsClause *TC = nullptr; 5126 OMPSIMDClause *SC = nullptr; 5127 for (auto *C : Clauses) { 5128 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 5129 DependFound = C; 5130 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 5131 if (DependSourceClause) { 5132 Diag(C->getLocStart(), diag::err_omp_more_one_clause) 5133 << getOpenMPDirectiveName(OMPD_ordered) 5134 << getOpenMPClauseName(OMPC_depend) << 2; 5135 ErrorFound = true; 5136 } else 5137 DependSourceClause = C; 5138 if (DependSinkClause) { 5139 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5140 << 0; 5141 ErrorFound = true; 5142 } 5143 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 5144 if (DependSourceClause) { 5145 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5146 << 1; 5147 ErrorFound = true; 5148 } 5149 DependSinkClause = C; 5150 } 5151 } else if (C->getClauseKind() == OMPC_threads) 5152 TC = cast<OMPThreadsClause>(C); 5153 else if (C->getClauseKind() == OMPC_simd) 5154 SC = cast<OMPSIMDClause>(C); 5155 } 5156 if (!ErrorFound && !SC && 5157 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 5158 // OpenMP [2.8.1,simd Construct, Restrictions] 5159 // An ordered construct with the simd clause is the only OpenMP construct 5160 // that can appear in the simd region. 5161 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 5162 ErrorFound = true; 5163 } else if (DependFound && (TC || SC)) { 5164 Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd) 5165 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 5166 ErrorFound = true; 5167 } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) { 5168 Diag(DependFound->getLocStart(), 5169 diag::err_omp_ordered_directive_without_param); 5170 ErrorFound = true; 5171 } else if (TC || Clauses.empty()) { 5172 if (auto *Param = DSAStack->getParentOrderedRegionParam()) { 5173 SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc; 5174 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 5175 << (TC != nullptr); 5176 Diag(Param->getLocStart(), diag::note_omp_ordered_param); 5177 ErrorFound = true; 5178 } 5179 } 5180 if ((!AStmt && !DependFound) || ErrorFound) 5181 return StmtError(); 5182 5183 if (AStmt) { 5184 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5185 5186 getCurFunction()->setHasBranchProtectedScope(); 5187 } 5188 5189 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5190 } 5191 5192 namespace { 5193 /// \brief Helper class for checking expression in 'omp atomic [update]' 5194 /// construct. 5195 class OpenMPAtomicUpdateChecker { 5196 /// \brief Error results for atomic update expressions. 5197 enum ExprAnalysisErrorCode { 5198 /// \brief A statement is not an expression statement. 5199 NotAnExpression, 5200 /// \brief Expression is not builtin binary or unary operation. 5201 NotABinaryOrUnaryExpression, 5202 /// \brief Unary operation is not post-/pre- increment/decrement operation. 5203 NotAnUnaryIncDecExpression, 5204 /// \brief An expression is not of scalar type. 5205 NotAScalarType, 5206 /// \brief A binary operation is not an assignment operation. 5207 NotAnAssignmentOp, 5208 /// \brief RHS part of the binary operation is not a binary expression. 5209 NotABinaryExpression, 5210 /// \brief RHS part is not additive/multiplicative/shift/biwise binary 5211 /// expression. 5212 NotABinaryOperator, 5213 /// \brief RHS binary operation does not have reference to the updated LHS 5214 /// part. 5215 NotAnUpdateExpression, 5216 /// \brief No errors is found. 5217 NoError 5218 }; 5219 /// \brief Reference to Sema. 5220 Sema &SemaRef; 5221 /// \brief A location for note diagnostics (when error is found). 5222 SourceLocation NoteLoc; 5223 /// \brief 'x' lvalue part of the source atomic expression. 5224 Expr *X; 5225 /// \brief 'expr' rvalue part of the source atomic expression. 5226 Expr *E; 5227 /// \brief Helper expression of the form 5228 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5229 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5230 Expr *UpdateExpr; 5231 /// \brief Is 'x' a LHS in a RHS part of full update expression. It is 5232 /// important for non-associative operations. 5233 bool IsXLHSInRHSPart; 5234 BinaryOperatorKind Op; 5235 SourceLocation OpLoc; 5236 /// \brief true if the source expression is a postfix unary operation, false 5237 /// if it is a prefix unary operation. 5238 bool IsPostfixUpdate; 5239 5240 public: 5241 OpenMPAtomicUpdateChecker(Sema &SemaRef) 5242 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 5243 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 5244 /// \brief Check specified statement that it is suitable for 'atomic update' 5245 /// constructs and extract 'x', 'expr' and Operation from the original 5246 /// expression. If DiagId and NoteId == 0, then only check is performed 5247 /// without error notification. 5248 /// \param DiagId Diagnostic which should be emitted if error is found. 5249 /// \param NoteId Diagnostic note for the main error message. 5250 /// \return true if statement is not an update expression, false otherwise. 5251 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 5252 /// \brief Return the 'x' lvalue part of the source atomic expression. 5253 Expr *getX() const { return X; } 5254 /// \brief Return the 'expr' rvalue part of the source atomic expression. 5255 Expr *getExpr() const { return E; } 5256 /// \brief Return the update expression used in calculation of the updated 5257 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5258 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5259 Expr *getUpdateExpr() const { return UpdateExpr; } 5260 /// \brief Return true if 'x' is LHS in RHS part of full update expression, 5261 /// false otherwise. 5262 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 5263 5264 /// \brief true if the source expression is a postfix unary operation, false 5265 /// if it is a prefix unary operation. 5266 bool isPostfixUpdate() const { return IsPostfixUpdate; } 5267 5268 private: 5269 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 5270 unsigned NoteId = 0); 5271 }; 5272 } // namespace 5273 5274 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 5275 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 5276 ExprAnalysisErrorCode ErrorFound = NoError; 5277 SourceLocation ErrorLoc, NoteLoc; 5278 SourceRange ErrorRange, NoteRange; 5279 // Allowed constructs are: 5280 // x = x binop expr; 5281 // x = expr binop x; 5282 if (AtomicBinOp->getOpcode() == BO_Assign) { 5283 X = AtomicBinOp->getLHS(); 5284 if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 5285 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 5286 if (AtomicInnerBinOp->isMultiplicativeOp() || 5287 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 5288 AtomicInnerBinOp->isBitwiseOp()) { 5289 Op = AtomicInnerBinOp->getOpcode(); 5290 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 5291 auto *LHS = AtomicInnerBinOp->getLHS(); 5292 auto *RHS = AtomicInnerBinOp->getRHS(); 5293 llvm::FoldingSetNodeID XId, LHSId, RHSId; 5294 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 5295 /*Canonical=*/true); 5296 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 5297 /*Canonical=*/true); 5298 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 5299 /*Canonical=*/true); 5300 if (XId == LHSId) { 5301 E = RHS; 5302 IsXLHSInRHSPart = true; 5303 } else if (XId == RHSId) { 5304 E = LHS; 5305 IsXLHSInRHSPart = false; 5306 } else { 5307 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5308 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5309 NoteLoc = X->getExprLoc(); 5310 NoteRange = X->getSourceRange(); 5311 ErrorFound = NotAnUpdateExpression; 5312 } 5313 } else { 5314 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5315 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5316 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 5317 NoteRange = SourceRange(NoteLoc, NoteLoc); 5318 ErrorFound = NotABinaryOperator; 5319 } 5320 } else { 5321 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 5322 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 5323 ErrorFound = NotABinaryExpression; 5324 } 5325 } else { 5326 ErrorLoc = AtomicBinOp->getExprLoc(); 5327 ErrorRange = AtomicBinOp->getSourceRange(); 5328 NoteLoc = AtomicBinOp->getOperatorLoc(); 5329 NoteRange = SourceRange(NoteLoc, NoteLoc); 5330 ErrorFound = NotAnAssignmentOp; 5331 } 5332 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5333 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5334 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5335 return true; 5336 } else if (SemaRef.CurContext->isDependentContext()) 5337 E = X = UpdateExpr = nullptr; 5338 return ErrorFound != NoError; 5339 } 5340 5341 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 5342 unsigned NoteId) { 5343 ExprAnalysisErrorCode ErrorFound = NoError; 5344 SourceLocation ErrorLoc, NoteLoc; 5345 SourceRange ErrorRange, NoteRange; 5346 // Allowed constructs are: 5347 // x++; 5348 // x--; 5349 // ++x; 5350 // --x; 5351 // x binop= expr; 5352 // x = x binop expr; 5353 // x = expr binop x; 5354 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 5355 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 5356 if (AtomicBody->getType()->isScalarType() || 5357 AtomicBody->isInstantiationDependent()) { 5358 if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 5359 AtomicBody->IgnoreParenImpCasts())) { 5360 // Check for Compound Assignment Operation 5361 Op = BinaryOperator::getOpForCompoundAssignment( 5362 AtomicCompAssignOp->getOpcode()); 5363 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 5364 E = AtomicCompAssignOp->getRHS(); 5365 X = AtomicCompAssignOp->getLHS(); 5366 IsXLHSInRHSPart = true; 5367 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 5368 AtomicBody->IgnoreParenImpCasts())) { 5369 // Check for Binary Operation 5370 if(checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 5371 return true; 5372 } else if (auto *AtomicUnaryOp = 5373 dyn_cast<UnaryOperator>(AtomicBody->IgnoreParenImpCasts())) { 5374 // Check for Unary Operation 5375 if (AtomicUnaryOp->isIncrementDecrementOp()) { 5376 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 5377 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 5378 OpLoc = AtomicUnaryOp->getOperatorLoc(); 5379 X = AtomicUnaryOp->getSubExpr(); 5380 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 5381 IsXLHSInRHSPart = true; 5382 } else { 5383 ErrorFound = NotAnUnaryIncDecExpression; 5384 ErrorLoc = AtomicUnaryOp->getExprLoc(); 5385 ErrorRange = AtomicUnaryOp->getSourceRange(); 5386 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 5387 NoteRange = SourceRange(NoteLoc, NoteLoc); 5388 } 5389 } else if (!AtomicBody->isInstantiationDependent()) { 5390 ErrorFound = NotABinaryOrUnaryExpression; 5391 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 5392 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 5393 } 5394 } else { 5395 ErrorFound = NotAScalarType; 5396 NoteLoc = ErrorLoc = AtomicBody->getLocStart(); 5397 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5398 } 5399 } else { 5400 ErrorFound = NotAnExpression; 5401 NoteLoc = ErrorLoc = S->getLocStart(); 5402 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5403 } 5404 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5405 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5406 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5407 return true; 5408 } else if (SemaRef.CurContext->isDependentContext()) 5409 E = X = UpdateExpr = nullptr; 5410 if (ErrorFound == NoError && E && X) { 5411 // Build an update expression of form 'OpaqueValueExpr(x) binop 5412 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 5413 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 5414 auto *OVEX = new (SemaRef.getASTContext()) 5415 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 5416 auto *OVEExpr = new (SemaRef.getASTContext()) 5417 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 5418 auto Update = 5419 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 5420 IsXLHSInRHSPart ? OVEExpr : OVEX); 5421 if (Update.isInvalid()) 5422 return true; 5423 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 5424 Sema::AA_Casting); 5425 if (Update.isInvalid()) 5426 return true; 5427 UpdateExpr = Update.get(); 5428 } 5429 return ErrorFound != NoError; 5430 } 5431 5432 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 5433 Stmt *AStmt, 5434 SourceLocation StartLoc, 5435 SourceLocation EndLoc) { 5436 if (!AStmt) 5437 return StmtError(); 5438 5439 auto CS = cast<CapturedStmt>(AStmt); 5440 // 1.2.2 OpenMP Language Terminology 5441 // Structured block - An executable statement with a single entry at the 5442 // top and a single exit at the bottom. 5443 // The point of exit cannot be a branch out of the structured block. 5444 // longjmp() and throw() must not violate the entry/exit criteria. 5445 OpenMPClauseKind AtomicKind = OMPC_unknown; 5446 SourceLocation AtomicKindLoc; 5447 for (auto *C : Clauses) { 5448 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 5449 C->getClauseKind() == OMPC_update || 5450 C->getClauseKind() == OMPC_capture) { 5451 if (AtomicKind != OMPC_unknown) { 5452 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) 5453 << SourceRange(C->getLocStart(), C->getLocEnd()); 5454 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 5455 << getOpenMPClauseName(AtomicKind); 5456 } else { 5457 AtomicKind = C->getClauseKind(); 5458 AtomicKindLoc = C->getLocStart(); 5459 } 5460 } 5461 } 5462 5463 auto Body = CS->getCapturedStmt(); 5464 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 5465 Body = EWC->getSubExpr(); 5466 5467 Expr *X = nullptr; 5468 Expr *V = nullptr; 5469 Expr *E = nullptr; 5470 Expr *UE = nullptr; 5471 bool IsXLHSInRHSPart = false; 5472 bool IsPostfixUpdate = false; 5473 // OpenMP [2.12.6, atomic Construct] 5474 // In the next expressions: 5475 // * x and v (as applicable) are both l-value expressions with scalar type. 5476 // * During the execution of an atomic region, multiple syntactic 5477 // occurrences of x must designate the same storage location. 5478 // * Neither of v and expr (as applicable) may access the storage location 5479 // designated by x. 5480 // * Neither of x and expr (as applicable) may access the storage location 5481 // designated by v. 5482 // * expr is an expression with scalar type. 5483 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 5484 // * binop, binop=, ++, and -- are not overloaded operators. 5485 // * The expression x binop expr must be numerically equivalent to x binop 5486 // (expr). This requirement is satisfied if the operators in expr have 5487 // precedence greater than binop, or by using parentheses around expr or 5488 // subexpressions of expr. 5489 // * The expression expr binop x must be numerically equivalent to (expr) 5490 // binop x. This requirement is satisfied if the operators in expr have 5491 // precedence equal to or greater than binop, or by using parentheses around 5492 // expr or subexpressions of expr. 5493 // * For forms that allow multiple occurrences of x, the number of times 5494 // that x is evaluated is unspecified. 5495 if (AtomicKind == OMPC_read) { 5496 enum { 5497 NotAnExpression, 5498 NotAnAssignmentOp, 5499 NotAScalarType, 5500 NotAnLValue, 5501 NoError 5502 } ErrorFound = NoError; 5503 SourceLocation ErrorLoc, NoteLoc; 5504 SourceRange ErrorRange, NoteRange; 5505 // If clause is read: 5506 // v = x; 5507 if (auto AtomicBody = dyn_cast<Expr>(Body)) { 5508 auto AtomicBinOp = 5509 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5510 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5511 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 5512 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 5513 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 5514 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 5515 if (!X->isLValue() || !V->isLValue()) { 5516 auto NotLValueExpr = X->isLValue() ? V : X; 5517 ErrorFound = NotAnLValue; 5518 ErrorLoc = AtomicBinOp->getExprLoc(); 5519 ErrorRange = AtomicBinOp->getSourceRange(); 5520 NoteLoc = NotLValueExpr->getExprLoc(); 5521 NoteRange = NotLValueExpr->getSourceRange(); 5522 } 5523 } else if (!X->isInstantiationDependent() || 5524 !V->isInstantiationDependent()) { 5525 auto NotScalarExpr = 5526 (X->isInstantiationDependent() || X->getType()->isScalarType()) 5527 ? V 5528 : X; 5529 ErrorFound = NotAScalarType; 5530 ErrorLoc = AtomicBinOp->getExprLoc(); 5531 ErrorRange = AtomicBinOp->getSourceRange(); 5532 NoteLoc = NotScalarExpr->getExprLoc(); 5533 NoteRange = NotScalarExpr->getSourceRange(); 5534 } 5535 } else if (!AtomicBody->isInstantiationDependent()) { 5536 ErrorFound = NotAnAssignmentOp; 5537 ErrorLoc = AtomicBody->getExprLoc(); 5538 ErrorRange = AtomicBody->getSourceRange(); 5539 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5540 : AtomicBody->getExprLoc(); 5541 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5542 : AtomicBody->getSourceRange(); 5543 } 5544 } else { 5545 ErrorFound = NotAnExpression; 5546 NoteLoc = ErrorLoc = Body->getLocStart(); 5547 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5548 } 5549 if (ErrorFound != NoError) { 5550 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 5551 << ErrorRange; 5552 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 5553 << NoteRange; 5554 return StmtError(); 5555 } else if (CurContext->isDependentContext()) 5556 V = X = nullptr; 5557 } else if (AtomicKind == OMPC_write) { 5558 enum { 5559 NotAnExpression, 5560 NotAnAssignmentOp, 5561 NotAScalarType, 5562 NotAnLValue, 5563 NoError 5564 } ErrorFound = NoError; 5565 SourceLocation ErrorLoc, NoteLoc; 5566 SourceRange ErrorRange, NoteRange; 5567 // If clause is write: 5568 // x = expr; 5569 if (auto AtomicBody = dyn_cast<Expr>(Body)) { 5570 auto AtomicBinOp = 5571 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5572 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5573 X = AtomicBinOp->getLHS(); 5574 E = AtomicBinOp->getRHS(); 5575 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 5576 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 5577 if (!X->isLValue()) { 5578 ErrorFound = NotAnLValue; 5579 ErrorLoc = AtomicBinOp->getExprLoc(); 5580 ErrorRange = AtomicBinOp->getSourceRange(); 5581 NoteLoc = X->getExprLoc(); 5582 NoteRange = X->getSourceRange(); 5583 } 5584 } else if (!X->isInstantiationDependent() || 5585 !E->isInstantiationDependent()) { 5586 auto NotScalarExpr = 5587 (X->isInstantiationDependent() || X->getType()->isScalarType()) 5588 ? E 5589 : X; 5590 ErrorFound = NotAScalarType; 5591 ErrorLoc = AtomicBinOp->getExprLoc(); 5592 ErrorRange = AtomicBinOp->getSourceRange(); 5593 NoteLoc = NotScalarExpr->getExprLoc(); 5594 NoteRange = NotScalarExpr->getSourceRange(); 5595 } 5596 } else if (!AtomicBody->isInstantiationDependent()) { 5597 ErrorFound = NotAnAssignmentOp; 5598 ErrorLoc = AtomicBody->getExprLoc(); 5599 ErrorRange = AtomicBody->getSourceRange(); 5600 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5601 : AtomicBody->getExprLoc(); 5602 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5603 : AtomicBody->getSourceRange(); 5604 } 5605 } else { 5606 ErrorFound = NotAnExpression; 5607 NoteLoc = ErrorLoc = Body->getLocStart(); 5608 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5609 } 5610 if (ErrorFound != NoError) { 5611 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 5612 << ErrorRange; 5613 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 5614 << NoteRange; 5615 return StmtError(); 5616 } else if (CurContext->isDependentContext()) 5617 E = X = nullptr; 5618 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 5619 // If clause is update: 5620 // x++; 5621 // x--; 5622 // ++x; 5623 // --x; 5624 // x binop= expr; 5625 // x = x binop expr; 5626 // x = expr binop x; 5627 OpenMPAtomicUpdateChecker Checker(*this); 5628 if (Checker.checkStatement( 5629 Body, (AtomicKind == OMPC_update) 5630 ? diag::err_omp_atomic_update_not_expression_statement 5631 : diag::err_omp_atomic_not_expression_statement, 5632 diag::note_omp_atomic_update)) 5633 return StmtError(); 5634 if (!CurContext->isDependentContext()) { 5635 E = Checker.getExpr(); 5636 X = Checker.getX(); 5637 UE = Checker.getUpdateExpr(); 5638 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5639 } 5640 } else if (AtomicKind == OMPC_capture) { 5641 enum { 5642 NotAnAssignmentOp, 5643 NotACompoundStatement, 5644 NotTwoSubstatements, 5645 NotASpecificExpression, 5646 NoError 5647 } ErrorFound = NoError; 5648 SourceLocation ErrorLoc, NoteLoc; 5649 SourceRange ErrorRange, NoteRange; 5650 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 5651 // If clause is a capture: 5652 // v = x++; 5653 // v = x--; 5654 // v = ++x; 5655 // v = --x; 5656 // v = x binop= expr; 5657 // v = x = x binop expr; 5658 // v = x = expr binop x; 5659 auto *AtomicBinOp = 5660 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5661 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5662 V = AtomicBinOp->getLHS(); 5663 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 5664 OpenMPAtomicUpdateChecker Checker(*this); 5665 if (Checker.checkStatement( 5666 Body, diag::err_omp_atomic_capture_not_expression_statement, 5667 diag::note_omp_atomic_update)) 5668 return StmtError(); 5669 E = Checker.getExpr(); 5670 X = Checker.getX(); 5671 UE = Checker.getUpdateExpr(); 5672 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5673 IsPostfixUpdate = Checker.isPostfixUpdate(); 5674 } else if (!AtomicBody->isInstantiationDependent()) { 5675 ErrorLoc = AtomicBody->getExprLoc(); 5676 ErrorRange = AtomicBody->getSourceRange(); 5677 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5678 : AtomicBody->getExprLoc(); 5679 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5680 : AtomicBody->getSourceRange(); 5681 ErrorFound = NotAnAssignmentOp; 5682 } 5683 if (ErrorFound != NoError) { 5684 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 5685 << ErrorRange; 5686 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 5687 return StmtError(); 5688 } else if (CurContext->isDependentContext()) { 5689 UE = V = E = X = nullptr; 5690 } 5691 } else { 5692 // If clause is a capture: 5693 // { v = x; x = expr; } 5694 // { v = x; x++; } 5695 // { v = x; x--; } 5696 // { v = x; ++x; } 5697 // { v = x; --x; } 5698 // { v = x; x binop= expr; } 5699 // { v = x; x = x binop expr; } 5700 // { v = x; x = expr binop x; } 5701 // { x++; v = x; } 5702 // { x--; v = x; } 5703 // { ++x; v = x; } 5704 // { --x; v = x; } 5705 // { x binop= expr; v = x; } 5706 // { x = x binop expr; v = x; } 5707 // { x = expr binop x; v = x; } 5708 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 5709 // Check that this is { expr1; expr2; } 5710 if (CS->size() == 2) { 5711 auto *First = CS->body_front(); 5712 auto *Second = CS->body_back(); 5713 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 5714 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 5715 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 5716 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 5717 // Need to find what subexpression is 'v' and what is 'x'. 5718 OpenMPAtomicUpdateChecker Checker(*this); 5719 bool IsUpdateExprFound = !Checker.checkStatement(Second); 5720 BinaryOperator *BinOp = nullptr; 5721 if (IsUpdateExprFound) { 5722 BinOp = dyn_cast<BinaryOperator>(First); 5723 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 5724 } 5725 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 5726 // { v = x; x++; } 5727 // { v = x; x--; } 5728 // { v = x; ++x; } 5729 // { v = x; --x; } 5730 // { v = x; x binop= expr; } 5731 // { v = x; x = x binop expr; } 5732 // { v = x; x = expr binop x; } 5733 // Check that the first expression has form v = x. 5734 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 5735 llvm::FoldingSetNodeID XId, PossibleXId; 5736 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 5737 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 5738 IsUpdateExprFound = XId == PossibleXId; 5739 if (IsUpdateExprFound) { 5740 V = BinOp->getLHS(); 5741 X = Checker.getX(); 5742 E = Checker.getExpr(); 5743 UE = Checker.getUpdateExpr(); 5744 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5745 IsPostfixUpdate = true; 5746 } 5747 } 5748 if (!IsUpdateExprFound) { 5749 IsUpdateExprFound = !Checker.checkStatement(First); 5750 BinOp = nullptr; 5751 if (IsUpdateExprFound) { 5752 BinOp = dyn_cast<BinaryOperator>(Second); 5753 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 5754 } 5755 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 5756 // { x++; v = x; } 5757 // { x--; v = x; } 5758 // { ++x; v = x; } 5759 // { --x; v = x; } 5760 // { x binop= expr; v = x; } 5761 // { x = x binop expr; v = x; } 5762 // { x = expr binop x; v = x; } 5763 // Check that the second expression has form v = x. 5764 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 5765 llvm::FoldingSetNodeID XId, PossibleXId; 5766 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 5767 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 5768 IsUpdateExprFound = XId == PossibleXId; 5769 if (IsUpdateExprFound) { 5770 V = BinOp->getLHS(); 5771 X = Checker.getX(); 5772 E = Checker.getExpr(); 5773 UE = Checker.getUpdateExpr(); 5774 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5775 IsPostfixUpdate = false; 5776 } 5777 } 5778 } 5779 if (!IsUpdateExprFound) { 5780 // { v = x; x = expr; } 5781 auto *FirstExpr = dyn_cast<Expr>(First); 5782 auto *SecondExpr = dyn_cast<Expr>(Second); 5783 if (!FirstExpr || !SecondExpr || 5784 !(FirstExpr->isInstantiationDependent() || 5785 SecondExpr->isInstantiationDependent())) { 5786 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 5787 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 5788 ErrorFound = NotAnAssignmentOp; 5789 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 5790 : First->getLocStart(); 5791 NoteRange = ErrorRange = FirstBinOp 5792 ? FirstBinOp->getSourceRange() 5793 : SourceRange(ErrorLoc, ErrorLoc); 5794 } else { 5795 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 5796 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 5797 ErrorFound = NotAnAssignmentOp; 5798 NoteLoc = ErrorLoc = SecondBinOp 5799 ? SecondBinOp->getOperatorLoc() 5800 : Second->getLocStart(); 5801 NoteRange = ErrorRange = 5802 SecondBinOp ? SecondBinOp->getSourceRange() 5803 : SourceRange(ErrorLoc, ErrorLoc); 5804 } else { 5805 auto *PossibleXRHSInFirst = 5806 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 5807 auto *PossibleXLHSInSecond = 5808 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 5809 llvm::FoldingSetNodeID X1Id, X2Id; 5810 PossibleXRHSInFirst->Profile(X1Id, Context, 5811 /*Canonical=*/true); 5812 PossibleXLHSInSecond->Profile(X2Id, Context, 5813 /*Canonical=*/true); 5814 IsUpdateExprFound = X1Id == X2Id; 5815 if (IsUpdateExprFound) { 5816 V = FirstBinOp->getLHS(); 5817 X = SecondBinOp->getLHS(); 5818 E = SecondBinOp->getRHS(); 5819 UE = nullptr; 5820 IsXLHSInRHSPart = false; 5821 IsPostfixUpdate = true; 5822 } else { 5823 ErrorFound = NotASpecificExpression; 5824 ErrorLoc = FirstBinOp->getExprLoc(); 5825 ErrorRange = FirstBinOp->getSourceRange(); 5826 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 5827 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 5828 } 5829 } 5830 } 5831 } 5832 } 5833 } else { 5834 NoteLoc = ErrorLoc = Body->getLocStart(); 5835 NoteRange = ErrorRange = 5836 SourceRange(Body->getLocStart(), Body->getLocStart()); 5837 ErrorFound = NotTwoSubstatements; 5838 } 5839 } else { 5840 NoteLoc = ErrorLoc = Body->getLocStart(); 5841 NoteRange = ErrorRange = 5842 SourceRange(Body->getLocStart(), Body->getLocStart()); 5843 ErrorFound = NotACompoundStatement; 5844 } 5845 if (ErrorFound != NoError) { 5846 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 5847 << ErrorRange; 5848 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 5849 return StmtError(); 5850 } else if (CurContext->isDependentContext()) { 5851 UE = V = E = X = nullptr; 5852 } 5853 } 5854 } 5855 5856 getCurFunction()->setHasBranchProtectedScope(); 5857 5858 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5859 X, V, E, UE, IsXLHSInRHSPart, 5860 IsPostfixUpdate); 5861 } 5862 5863 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 5864 Stmt *AStmt, 5865 SourceLocation StartLoc, 5866 SourceLocation EndLoc) { 5867 if (!AStmt) 5868 return StmtError(); 5869 5870 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5871 // 1.2.2 OpenMP Language Terminology 5872 // Structured block - An executable statement with a single entry at the 5873 // top and a single exit at the bottom. 5874 // The point of exit cannot be a branch out of the structured block. 5875 // longjmp() and throw() must not violate the entry/exit criteria. 5876 CS->getCapturedDecl()->setNothrow(); 5877 5878 // OpenMP [2.16, Nesting of Regions] 5879 // If specified, a teams construct must be contained within a target 5880 // construct. That target construct must contain no statements or directives 5881 // outside of the teams construct. 5882 if (DSAStack->hasInnerTeamsRegion()) { 5883 auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true); 5884 bool OMPTeamsFound = true; 5885 if (auto *CS = dyn_cast<CompoundStmt>(S)) { 5886 auto I = CS->body_begin(); 5887 while (I != CS->body_end()) { 5888 auto OED = dyn_cast<OMPExecutableDirective>(*I); 5889 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { 5890 OMPTeamsFound = false; 5891 break; 5892 } 5893 ++I; 5894 } 5895 assert(I != CS->body_end() && "Not found statement"); 5896 S = *I; 5897 } 5898 if (!OMPTeamsFound) { 5899 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 5900 Diag(DSAStack->getInnerTeamsRegionLoc(), 5901 diag::note_omp_nested_teams_construct_here); 5902 Diag(S->getLocStart(), diag::note_omp_nested_statement_here) 5903 << isa<OMPExecutableDirective>(S); 5904 return StmtError(); 5905 } 5906 } 5907 5908 getCurFunction()->setHasBranchProtectedScope(); 5909 5910 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5911 } 5912 5913 StmtResult 5914 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 5915 Stmt *AStmt, SourceLocation StartLoc, 5916 SourceLocation EndLoc) { 5917 if (!AStmt) 5918 return StmtError(); 5919 5920 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5921 // 1.2.2 OpenMP Language Terminology 5922 // Structured block - An executable statement with a single entry at the 5923 // top and a single exit at the bottom. 5924 // The point of exit cannot be a branch out of the structured block. 5925 // longjmp() and throw() must not violate the entry/exit criteria. 5926 CS->getCapturedDecl()->setNothrow(); 5927 5928 getCurFunction()->setHasBranchProtectedScope(); 5929 5930 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 5931 AStmt); 5932 } 5933 5934 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 5935 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5936 SourceLocation EndLoc, 5937 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5938 if (!AStmt) 5939 return StmtError(); 5940 5941 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5942 // 1.2.2 OpenMP Language Terminology 5943 // Structured block - An executable statement with a single entry at the 5944 // top and a single exit at the bottom. 5945 // The point of exit cannot be a branch out of the structured block. 5946 // longjmp() and throw() must not violate the entry/exit criteria. 5947 CS->getCapturedDecl()->setNothrow(); 5948 5949 OMPLoopDirective::HelperExprs B; 5950 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5951 // define the nested loops number. 5952 unsigned NestedLoopCount = 5953 CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 5954 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5955 VarsWithImplicitDSA, B); 5956 if (NestedLoopCount == 0) 5957 return StmtError(); 5958 5959 assert((CurContext->isDependentContext() || B.builtAll()) && 5960 "omp target parallel for loop exprs were not built"); 5961 5962 if (!CurContext->isDependentContext()) { 5963 // Finalize the clauses that need pre-built expressions for CodeGen. 5964 for (auto C : Clauses) { 5965 if (auto LC = dyn_cast<OMPLinearClause>(C)) 5966 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5967 B.NumIterations, *this, CurScope)) 5968 return StmtError(); 5969 } 5970 } 5971 5972 getCurFunction()->setHasBranchProtectedScope(); 5973 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 5974 NestedLoopCount, Clauses, AStmt, 5975 B, DSAStack->isCancelRegion()); 5976 } 5977 5978 /// \brief Check for existence of a map clause in the list of clauses. 5979 static bool HasMapClause(ArrayRef<OMPClause *> Clauses) { 5980 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end(); 5981 I != E; ++I) { 5982 if (*I != nullptr && (*I)->getClauseKind() == OMPC_map) { 5983 return true; 5984 } 5985 } 5986 5987 return false; 5988 } 5989 5990 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 5991 Stmt *AStmt, 5992 SourceLocation StartLoc, 5993 SourceLocation EndLoc) { 5994 if (!AStmt) 5995 return StmtError(); 5996 5997 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5998 5999 // OpenMP [2.10.1, Restrictions, p. 97] 6000 // At least one map clause must appear on the directive. 6001 if (!HasMapClause(Clauses)) { 6002 Diag(StartLoc, diag::err_omp_no_map_for_directive) << 6003 getOpenMPDirectiveName(OMPD_target_data); 6004 return StmtError(); 6005 } 6006 6007 getCurFunction()->setHasBranchProtectedScope(); 6008 6009 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 6010 AStmt); 6011 } 6012 6013 StmtResult 6014 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 6015 SourceLocation StartLoc, 6016 SourceLocation EndLoc) { 6017 // OpenMP [2.10.2, Restrictions, p. 99] 6018 // At least one map clause must appear on the directive. 6019 if (!HasMapClause(Clauses)) { 6020 Diag(StartLoc, diag::err_omp_no_map_for_directive) 6021 << getOpenMPDirectiveName(OMPD_target_enter_data); 6022 return StmtError(); 6023 } 6024 6025 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, 6026 Clauses); 6027 } 6028 6029 StmtResult 6030 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 6031 SourceLocation StartLoc, 6032 SourceLocation EndLoc) { 6033 // OpenMP [2.10.3, Restrictions, p. 102] 6034 // At least one map clause must appear on the directive. 6035 if (!HasMapClause(Clauses)) { 6036 Diag(StartLoc, diag::err_omp_no_map_for_directive) 6037 << getOpenMPDirectiveName(OMPD_target_exit_data); 6038 return StmtError(); 6039 } 6040 6041 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses); 6042 } 6043 6044 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 6045 Stmt *AStmt, SourceLocation StartLoc, 6046 SourceLocation EndLoc) { 6047 if (!AStmt) 6048 return StmtError(); 6049 6050 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6051 // 1.2.2 OpenMP Language Terminology 6052 // Structured block - An executable statement with a single entry at the 6053 // top and a single exit at the bottom. 6054 // The point of exit cannot be a branch out of the structured block. 6055 // longjmp() and throw() must not violate the entry/exit criteria. 6056 CS->getCapturedDecl()->setNothrow(); 6057 6058 getCurFunction()->setHasBranchProtectedScope(); 6059 6060 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6061 } 6062 6063 StmtResult 6064 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 6065 SourceLocation EndLoc, 6066 OpenMPDirectiveKind CancelRegion) { 6067 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for && 6068 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) { 6069 Diag(StartLoc, diag::err_omp_wrong_cancel_region) 6070 << getOpenMPDirectiveName(CancelRegion); 6071 return StmtError(); 6072 } 6073 if (DSAStack->isParentNowaitRegion()) { 6074 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 6075 return StmtError(); 6076 } 6077 if (DSAStack->isParentOrderedRegion()) { 6078 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 6079 return StmtError(); 6080 } 6081 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 6082 CancelRegion); 6083 } 6084 6085 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 6086 SourceLocation StartLoc, 6087 SourceLocation EndLoc, 6088 OpenMPDirectiveKind CancelRegion) { 6089 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for && 6090 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) { 6091 Diag(StartLoc, diag::err_omp_wrong_cancel_region) 6092 << getOpenMPDirectiveName(CancelRegion); 6093 return StmtError(); 6094 } 6095 if (DSAStack->isParentNowaitRegion()) { 6096 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 6097 return StmtError(); 6098 } 6099 if (DSAStack->isParentOrderedRegion()) { 6100 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 6101 return StmtError(); 6102 } 6103 DSAStack->setParentCancelRegion(/*Cancel=*/true); 6104 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6105 CancelRegion); 6106 } 6107 6108 static bool checkGrainsizeNumTasksClauses(Sema &S, 6109 ArrayRef<OMPClause *> Clauses) { 6110 OMPClause *PrevClause = nullptr; 6111 bool ErrorFound = false; 6112 for (auto *C : Clauses) { 6113 if (C->getClauseKind() == OMPC_grainsize || 6114 C->getClauseKind() == OMPC_num_tasks) { 6115 if (!PrevClause) 6116 PrevClause = C; 6117 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 6118 S.Diag(C->getLocStart(), 6119 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 6120 << getOpenMPClauseName(C->getClauseKind()) 6121 << getOpenMPClauseName(PrevClause->getClauseKind()); 6122 S.Diag(PrevClause->getLocStart(), 6123 diag::note_omp_previous_grainsize_num_tasks) 6124 << getOpenMPClauseName(PrevClause->getClauseKind()); 6125 ErrorFound = true; 6126 } 6127 } 6128 } 6129 return ErrorFound; 6130 } 6131 6132 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 6133 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6134 SourceLocation EndLoc, 6135 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6136 if (!AStmt) 6137 return StmtError(); 6138 6139 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6140 OMPLoopDirective::HelperExprs B; 6141 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6142 // define the nested loops number. 6143 unsigned NestedLoopCount = 6144 CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 6145 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6146 VarsWithImplicitDSA, B); 6147 if (NestedLoopCount == 0) 6148 return StmtError(); 6149 6150 assert((CurContext->isDependentContext() || B.builtAll()) && 6151 "omp for loop exprs were not built"); 6152 6153 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6154 // The grainsize clause and num_tasks clause are mutually exclusive and may 6155 // not appear on the same taskloop directive. 6156 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6157 return StmtError(); 6158 6159 getCurFunction()->setHasBranchProtectedScope(); 6160 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 6161 NestedLoopCount, Clauses, AStmt, B); 6162 } 6163 6164 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 6165 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6166 SourceLocation EndLoc, 6167 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6168 if (!AStmt) 6169 return StmtError(); 6170 6171 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6172 OMPLoopDirective::HelperExprs B; 6173 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6174 // define the nested loops number. 6175 unsigned NestedLoopCount = 6176 CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 6177 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6178 VarsWithImplicitDSA, B); 6179 if (NestedLoopCount == 0) 6180 return StmtError(); 6181 6182 assert((CurContext->isDependentContext() || B.builtAll()) && 6183 "omp for loop exprs were not built"); 6184 6185 if (!CurContext->isDependentContext()) { 6186 // Finalize the clauses that need pre-built expressions for CodeGen. 6187 for (auto C : Clauses) { 6188 if (auto LC = dyn_cast<OMPLinearClause>(C)) 6189 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6190 B.NumIterations, *this, CurScope)) 6191 return StmtError(); 6192 } 6193 } 6194 6195 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6196 // The grainsize clause and num_tasks clause are mutually exclusive and may 6197 // not appear on the same taskloop directive. 6198 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6199 return StmtError(); 6200 6201 getCurFunction()->setHasBranchProtectedScope(); 6202 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 6203 NestedLoopCount, Clauses, AStmt, B); 6204 } 6205 6206 StmtResult Sema::ActOnOpenMPDistributeDirective( 6207 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6208 SourceLocation EndLoc, 6209 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6210 if (!AStmt) 6211 return StmtError(); 6212 6213 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6214 OMPLoopDirective::HelperExprs B; 6215 // In presence of clause 'collapse' with number of loops, it will 6216 // define the nested loops number. 6217 unsigned NestedLoopCount = 6218 CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 6219 nullptr /*ordered not a clause on distribute*/, AStmt, 6220 *this, *DSAStack, VarsWithImplicitDSA, B); 6221 if (NestedLoopCount == 0) 6222 return StmtError(); 6223 6224 assert((CurContext->isDependentContext() || B.builtAll()) && 6225 "omp for loop exprs were not built"); 6226 6227 getCurFunction()->setHasBranchProtectedScope(); 6228 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 6229 NestedLoopCount, Clauses, AStmt, B); 6230 } 6231 6232 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 6233 SourceLocation StartLoc, 6234 SourceLocation LParenLoc, 6235 SourceLocation EndLoc) { 6236 OMPClause *Res = nullptr; 6237 switch (Kind) { 6238 case OMPC_final: 6239 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 6240 break; 6241 case OMPC_num_threads: 6242 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 6243 break; 6244 case OMPC_safelen: 6245 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 6246 break; 6247 case OMPC_simdlen: 6248 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 6249 break; 6250 case OMPC_collapse: 6251 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 6252 break; 6253 case OMPC_ordered: 6254 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 6255 break; 6256 case OMPC_device: 6257 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 6258 break; 6259 case OMPC_num_teams: 6260 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 6261 break; 6262 case OMPC_thread_limit: 6263 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 6264 break; 6265 case OMPC_priority: 6266 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 6267 break; 6268 case OMPC_grainsize: 6269 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 6270 break; 6271 case OMPC_num_tasks: 6272 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 6273 break; 6274 case OMPC_hint: 6275 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 6276 break; 6277 case OMPC_if: 6278 case OMPC_default: 6279 case OMPC_proc_bind: 6280 case OMPC_schedule: 6281 case OMPC_private: 6282 case OMPC_firstprivate: 6283 case OMPC_lastprivate: 6284 case OMPC_shared: 6285 case OMPC_reduction: 6286 case OMPC_linear: 6287 case OMPC_aligned: 6288 case OMPC_copyin: 6289 case OMPC_copyprivate: 6290 case OMPC_nowait: 6291 case OMPC_untied: 6292 case OMPC_mergeable: 6293 case OMPC_threadprivate: 6294 case OMPC_flush: 6295 case OMPC_read: 6296 case OMPC_write: 6297 case OMPC_update: 6298 case OMPC_capture: 6299 case OMPC_seq_cst: 6300 case OMPC_depend: 6301 case OMPC_threads: 6302 case OMPC_simd: 6303 case OMPC_map: 6304 case OMPC_nogroup: 6305 case OMPC_dist_schedule: 6306 case OMPC_defaultmap: 6307 case OMPC_unknown: 6308 llvm_unreachable("Clause is not allowed."); 6309 } 6310 return Res; 6311 } 6312 6313 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 6314 Expr *Condition, SourceLocation StartLoc, 6315 SourceLocation LParenLoc, 6316 SourceLocation NameModifierLoc, 6317 SourceLocation ColonLoc, 6318 SourceLocation EndLoc) { 6319 Expr *ValExpr = Condition; 6320 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 6321 !Condition->isInstantiationDependent() && 6322 !Condition->containsUnexpandedParameterPack()) { 6323 ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(), 6324 Condition->getExprLoc(), Condition); 6325 if (Val.isInvalid()) 6326 return nullptr; 6327 6328 ValExpr = Val.get(); 6329 } 6330 6331 return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc, 6332 NameModifierLoc, ColonLoc, EndLoc); 6333 } 6334 6335 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 6336 SourceLocation StartLoc, 6337 SourceLocation LParenLoc, 6338 SourceLocation EndLoc) { 6339 Expr *ValExpr = Condition; 6340 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 6341 !Condition->isInstantiationDependent() && 6342 !Condition->containsUnexpandedParameterPack()) { 6343 ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(), 6344 Condition->getExprLoc(), Condition); 6345 if (Val.isInvalid()) 6346 return nullptr; 6347 6348 ValExpr = Val.get(); 6349 } 6350 6351 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 6352 } 6353 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 6354 Expr *Op) { 6355 if (!Op) 6356 return ExprError(); 6357 6358 class IntConvertDiagnoser : public ICEConvertDiagnoser { 6359 public: 6360 IntConvertDiagnoser() 6361 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 6362 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 6363 QualType T) override { 6364 return S.Diag(Loc, diag::err_omp_not_integral) << T; 6365 } 6366 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 6367 QualType T) override { 6368 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 6369 } 6370 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 6371 QualType T, 6372 QualType ConvTy) override { 6373 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 6374 } 6375 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 6376 QualType ConvTy) override { 6377 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 6378 << ConvTy->isEnumeralType() << ConvTy; 6379 } 6380 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 6381 QualType T) override { 6382 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 6383 } 6384 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 6385 QualType ConvTy) override { 6386 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 6387 << ConvTy->isEnumeralType() << ConvTy; 6388 } 6389 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 6390 QualType) override { 6391 llvm_unreachable("conversion functions are permitted"); 6392 } 6393 } ConvertDiagnoser; 6394 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 6395 } 6396 6397 static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 6398 OpenMPClauseKind CKind, 6399 bool StrictlyPositive) { 6400 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 6401 !ValExpr->isInstantiationDependent()) { 6402 SourceLocation Loc = ValExpr->getExprLoc(); 6403 ExprResult Value = 6404 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 6405 if (Value.isInvalid()) 6406 return false; 6407 6408 ValExpr = Value.get(); 6409 // The expression must evaluate to a non-negative integer value. 6410 llvm::APSInt Result; 6411 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 6412 Result.isSigned() && 6413 !((!StrictlyPositive && Result.isNonNegative()) || 6414 (StrictlyPositive && Result.isStrictlyPositive()))) { 6415 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 6416 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 6417 << ValExpr->getSourceRange(); 6418 return false; 6419 } 6420 } 6421 return true; 6422 } 6423 6424 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 6425 SourceLocation StartLoc, 6426 SourceLocation LParenLoc, 6427 SourceLocation EndLoc) { 6428 Expr *ValExpr = NumThreads; 6429 6430 // OpenMP [2.5, Restrictions] 6431 // The num_threads expression must evaluate to a positive integer value. 6432 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 6433 /*StrictlyPositive=*/true)) 6434 return nullptr; 6435 6436 return new (Context) 6437 OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc); 6438 } 6439 6440 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 6441 OpenMPClauseKind CKind, 6442 bool StrictlyPositive) { 6443 if (!E) 6444 return ExprError(); 6445 if (E->isValueDependent() || E->isTypeDependent() || 6446 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 6447 return E; 6448 llvm::APSInt Result; 6449 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 6450 if (ICE.isInvalid()) 6451 return ExprError(); 6452 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 6453 (!StrictlyPositive && !Result.isNonNegative())) { 6454 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 6455 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 6456 << E->getSourceRange(); 6457 return ExprError(); 6458 } 6459 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 6460 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 6461 << E->getSourceRange(); 6462 return ExprError(); 6463 } 6464 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 6465 DSAStack->setAssociatedLoops(Result.getExtValue()); 6466 else if (CKind == OMPC_ordered) 6467 DSAStack->setAssociatedLoops(Result.getExtValue()); 6468 return ICE; 6469 } 6470 6471 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 6472 SourceLocation LParenLoc, 6473 SourceLocation EndLoc) { 6474 // OpenMP [2.8.1, simd construct, Description] 6475 // The parameter of the safelen clause must be a constant 6476 // positive integer expression. 6477 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 6478 if (Safelen.isInvalid()) 6479 return nullptr; 6480 return new (Context) 6481 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 6482 } 6483 6484 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 6485 SourceLocation LParenLoc, 6486 SourceLocation EndLoc) { 6487 // OpenMP [2.8.1, simd construct, Description] 6488 // The parameter of the simdlen clause must be a constant 6489 // positive integer expression. 6490 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 6491 if (Simdlen.isInvalid()) 6492 return nullptr; 6493 return new (Context) 6494 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 6495 } 6496 6497 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 6498 SourceLocation StartLoc, 6499 SourceLocation LParenLoc, 6500 SourceLocation EndLoc) { 6501 // OpenMP [2.7.1, loop construct, Description] 6502 // OpenMP [2.8.1, simd construct, Description] 6503 // OpenMP [2.9.6, distribute construct, Description] 6504 // The parameter of the collapse clause must be a constant 6505 // positive integer expression. 6506 ExprResult NumForLoopsResult = 6507 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 6508 if (NumForLoopsResult.isInvalid()) 6509 return nullptr; 6510 return new (Context) 6511 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 6512 } 6513 6514 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 6515 SourceLocation EndLoc, 6516 SourceLocation LParenLoc, 6517 Expr *NumForLoops) { 6518 // OpenMP [2.7.1, loop construct, Description] 6519 // OpenMP [2.8.1, simd construct, Description] 6520 // OpenMP [2.9.6, distribute construct, Description] 6521 // The parameter of the ordered clause must be a constant 6522 // positive integer expression if any. 6523 if (NumForLoops && LParenLoc.isValid()) { 6524 ExprResult NumForLoopsResult = 6525 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 6526 if (NumForLoopsResult.isInvalid()) 6527 return nullptr; 6528 NumForLoops = NumForLoopsResult.get(); 6529 } else 6530 NumForLoops = nullptr; 6531 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops); 6532 return new (Context) 6533 OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc); 6534 } 6535 6536 OMPClause *Sema::ActOnOpenMPSimpleClause( 6537 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 6538 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 6539 OMPClause *Res = nullptr; 6540 switch (Kind) { 6541 case OMPC_default: 6542 Res = 6543 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 6544 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 6545 break; 6546 case OMPC_proc_bind: 6547 Res = ActOnOpenMPProcBindClause( 6548 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 6549 LParenLoc, EndLoc); 6550 break; 6551 case OMPC_if: 6552 case OMPC_final: 6553 case OMPC_num_threads: 6554 case OMPC_safelen: 6555 case OMPC_simdlen: 6556 case OMPC_collapse: 6557 case OMPC_schedule: 6558 case OMPC_private: 6559 case OMPC_firstprivate: 6560 case OMPC_lastprivate: 6561 case OMPC_shared: 6562 case OMPC_reduction: 6563 case OMPC_linear: 6564 case OMPC_aligned: 6565 case OMPC_copyin: 6566 case OMPC_copyprivate: 6567 case OMPC_ordered: 6568 case OMPC_nowait: 6569 case OMPC_untied: 6570 case OMPC_mergeable: 6571 case OMPC_threadprivate: 6572 case OMPC_flush: 6573 case OMPC_read: 6574 case OMPC_write: 6575 case OMPC_update: 6576 case OMPC_capture: 6577 case OMPC_seq_cst: 6578 case OMPC_depend: 6579 case OMPC_device: 6580 case OMPC_threads: 6581 case OMPC_simd: 6582 case OMPC_map: 6583 case OMPC_num_teams: 6584 case OMPC_thread_limit: 6585 case OMPC_priority: 6586 case OMPC_grainsize: 6587 case OMPC_nogroup: 6588 case OMPC_num_tasks: 6589 case OMPC_hint: 6590 case OMPC_dist_schedule: 6591 case OMPC_defaultmap: 6592 case OMPC_unknown: 6593 llvm_unreachable("Clause is not allowed."); 6594 } 6595 return Res; 6596 } 6597 6598 static std::string 6599 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 6600 ArrayRef<unsigned> Exclude = llvm::None) { 6601 std::string Values; 6602 unsigned Bound = Last >= 2 ? Last - 2 : 0; 6603 unsigned Skipped = Exclude.size(); 6604 auto S = Exclude.begin(), E = Exclude.end(); 6605 for (unsigned i = First; i < Last; ++i) { 6606 if (std::find(S, E, i) != E) { 6607 --Skipped; 6608 continue; 6609 } 6610 Values += "'"; 6611 Values += getOpenMPSimpleClauseTypeName(K, i); 6612 Values += "'"; 6613 if (i == Bound - Skipped) 6614 Values += " or "; 6615 else if (i != Bound + 1 - Skipped) 6616 Values += ", "; 6617 } 6618 return Values; 6619 } 6620 6621 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 6622 SourceLocation KindKwLoc, 6623 SourceLocation StartLoc, 6624 SourceLocation LParenLoc, 6625 SourceLocation EndLoc) { 6626 if (Kind == OMPC_DEFAULT_unknown) { 6627 static_assert(OMPC_DEFAULT_unknown > 0, 6628 "OMPC_DEFAULT_unknown not greater than 0"); 6629 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 6630 << getListOfPossibleValues(OMPC_default, /*First=*/0, 6631 /*Last=*/OMPC_DEFAULT_unknown) 6632 << getOpenMPClauseName(OMPC_default); 6633 return nullptr; 6634 } 6635 switch (Kind) { 6636 case OMPC_DEFAULT_none: 6637 DSAStack->setDefaultDSANone(KindKwLoc); 6638 break; 6639 case OMPC_DEFAULT_shared: 6640 DSAStack->setDefaultDSAShared(KindKwLoc); 6641 break; 6642 case OMPC_DEFAULT_unknown: 6643 llvm_unreachable("Clause kind is not allowed."); 6644 break; 6645 } 6646 return new (Context) 6647 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 6648 } 6649 6650 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 6651 SourceLocation KindKwLoc, 6652 SourceLocation StartLoc, 6653 SourceLocation LParenLoc, 6654 SourceLocation EndLoc) { 6655 if (Kind == OMPC_PROC_BIND_unknown) { 6656 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 6657 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 6658 /*Last=*/OMPC_PROC_BIND_unknown) 6659 << getOpenMPClauseName(OMPC_proc_bind); 6660 return nullptr; 6661 } 6662 return new (Context) 6663 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 6664 } 6665 6666 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 6667 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 6668 SourceLocation StartLoc, SourceLocation LParenLoc, 6669 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 6670 SourceLocation EndLoc) { 6671 OMPClause *Res = nullptr; 6672 switch (Kind) { 6673 case OMPC_schedule: 6674 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 6675 assert(Argument.size() == NumberOfElements && 6676 ArgumentLoc.size() == NumberOfElements); 6677 Res = ActOnOpenMPScheduleClause( 6678 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 6679 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 6680 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 6681 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 6682 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 6683 break; 6684 case OMPC_if: 6685 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 6686 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 6687 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 6688 DelimLoc, EndLoc); 6689 break; 6690 case OMPC_dist_schedule: 6691 Res = ActOnOpenMPDistScheduleClause( 6692 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 6693 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 6694 break; 6695 case OMPC_defaultmap: 6696 enum { Modifier, DefaultmapKind }; 6697 Res = ActOnOpenMPDefaultmapClause( 6698 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 6699 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 6700 StartLoc, LParenLoc, ArgumentLoc[Modifier], 6701 ArgumentLoc[DefaultmapKind], EndLoc); 6702 break; 6703 case OMPC_final: 6704 case OMPC_num_threads: 6705 case OMPC_safelen: 6706 case OMPC_simdlen: 6707 case OMPC_collapse: 6708 case OMPC_default: 6709 case OMPC_proc_bind: 6710 case OMPC_private: 6711 case OMPC_firstprivate: 6712 case OMPC_lastprivate: 6713 case OMPC_shared: 6714 case OMPC_reduction: 6715 case OMPC_linear: 6716 case OMPC_aligned: 6717 case OMPC_copyin: 6718 case OMPC_copyprivate: 6719 case OMPC_ordered: 6720 case OMPC_nowait: 6721 case OMPC_untied: 6722 case OMPC_mergeable: 6723 case OMPC_threadprivate: 6724 case OMPC_flush: 6725 case OMPC_read: 6726 case OMPC_write: 6727 case OMPC_update: 6728 case OMPC_capture: 6729 case OMPC_seq_cst: 6730 case OMPC_depend: 6731 case OMPC_device: 6732 case OMPC_threads: 6733 case OMPC_simd: 6734 case OMPC_map: 6735 case OMPC_num_teams: 6736 case OMPC_thread_limit: 6737 case OMPC_priority: 6738 case OMPC_grainsize: 6739 case OMPC_nogroup: 6740 case OMPC_num_tasks: 6741 case OMPC_hint: 6742 case OMPC_unknown: 6743 llvm_unreachable("Clause is not allowed."); 6744 } 6745 return Res; 6746 } 6747 6748 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 6749 OpenMPScheduleClauseModifier M2, 6750 SourceLocation M1Loc, SourceLocation M2Loc) { 6751 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 6752 SmallVector<unsigned, 2> Excluded; 6753 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 6754 Excluded.push_back(M2); 6755 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 6756 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 6757 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 6758 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 6759 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 6760 << getListOfPossibleValues(OMPC_schedule, 6761 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 6762 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 6763 Excluded) 6764 << getOpenMPClauseName(OMPC_schedule); 6765 return true; 6766 } 6767 return false; 6768 } 6769 6770 OMPClause *Sema::ActOnOpenMPScheduleClause( 6771 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 6772 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 6773 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 6774 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 6775 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 6776 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 6777 return nullptr; 6778 // OpenMP, 2.7.1, Loop Construct, Restrictions 6779 // Either the monotonic modifier or the nonmonotonic modifier can be specified 6780 // but not both. 6781 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 6782 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 6783 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 6784 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 6785 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 6786 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 6787 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 6788 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 6789 return nullptr; 6790 } 6791 if (Kind == OMPC_SCHEDULE_unknown) { 6792 std::string Values; 6793 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 6794 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 6795 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 6796 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 6797 Exclude); 6798 } else { 6799 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 6800 /*Last=*/OMPC_SCHEDULE_unknown); 6801 } 6802 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 6803 << Values << getOpenMPClauseName(OMPC_schedule); 6804 return nullptr; 6805 } 6806 // OpenMP, 2.7.1, Loop Construct, Restrictions 6807 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 6808 // schedule(guided). 6809 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 6810 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 6811 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 6812 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 6813 diag::err_omp_schedule_nonmonotonic_static); 6814 return nullptr; 6815 } 6816 Expr *ValExpr = ChunkSize; 6817 Stmt *HelperValStmt = nullptr; 6818 if (ChunkSize) { 6819 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 6820 !ChunkSize->isInstantiationDependent() && 6821 !ChunkSize->containsUnexpandedParameterPack()) { 6822 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 6823 ExprResult Val = 6824 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 6825 if (Val.isInvalid()) 6826 return nullptr; 6827 6828 ValExpr = Val.get(); 6829 6830 // OpenMP [2.7.1, Restrictions] 6831 // chunk_size must be a loop invariant integer expression with a positive 6832 // value. 6833 llvm::APSInt Result; 6834 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 6835 if (Result.isSigned() && !Result.isStrictlyPositive()) { 6836 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 6837 << "schedule" << 1 << ChunkSize->getSourceRange(); 6838 return nullptr; 6839 } 6840 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 6841 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 6842 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 6843 HelperValStmt = buildPreInits(Context, Captures); 6844 } 6845 } 6846 } 6847 6848 return new (Context) 6849 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 6850 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 6851 } 6852 6853 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 6854 SourceLocation StartLoc, 6855 SourceLocation EndLoc) { 6856 OMPClause *Res = nullptr; 6857 switch (Kind) { 6858 case OMPC_ordered: 6859 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 6860 break; 6861 case OMPC_nowait: 6862 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 6863 break; 6864 case OMPC_untied: 6865 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 6866 break; 6867 case OMPC_mergeable: 6868 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 6869 break; 6870 case OMPC_read: 6871 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 6872 break; 6873 case OMPC_write: 6874 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 6875 break; 6876 case OMPC_update: 6877 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 6878 break; 6879 case OMPC_capture: 6880 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 6881 break; 6882 case OMPC_seq_cst: 6883 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 6884 break; 6885 case OMPC_threads: 6886 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 6887 break; 6888 case OMPC_simd: 6889 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 6890 break; 6891 case OMPC_nogroup: 6892 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 6893 break; 6894 case OMPC_if: 6895 case OMPC_final: 6896 case OMPC_num_threads: 6897 case OMPC_safelen: 6898 case OMPC_simdlen: 6899 case OMPC_collapse: 6900 case OMPC_schedule: 6901 case OMPC_private: 6902 case OMPC_firstprivate: 6903 case OMPC_lastprivate: 6904 case OMPC_shared: 6905 case OMPC_reduction: 6906 case OMPC_linear: 6907 case OMPC_aligned: 6908 case OMPC_copyin: 6909 case OMPC_copyprivate: 6910 case OMPC_default: 6911 case OMPC_proc_bind: 6912 case OMPC_threadprivate: 6913 case OMPC_flush: 6914 case OMPC_depend: 6915 case OMPC_device: 6916 case OMPC_map: 6917 case OMPC_num_teams: 6918 case OMPC_thread_limit: 6919 case OMPC_priority: 6920 case OMPC_grainsize: 6921 case OMPC_num_tasks: 6922 case OMPC_hint: 6923 case OMPC_dist_schedule: 6924 case OMPC_defaultmap: 6925 case OMPC_unknown: 6926 llvm_unreachable("Clause is not allowed."); 6927 } 6928 return Res; 6929 } 6930 6931 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 6932 SourceLocation EndLoc) { 6933 DSAStack->setNowaitRegion(); 6934 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 6935 } 6936 6937 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 6938 SourceLocation EndLoc) { 6939 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 6940 } 6941 6942 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 6943 SourceLocation EndLoc) { 6944 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 6945 } 6946 6947 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 6948 SourceLocation EndLoc) { 6949 return new (Context) OMPReadClause(StartLoc, EndLoc); 6950 } 6951 6952 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 6953 SourceLocation EndLoc) { 6954 return new (Context) OMPWriteClause(StartLoc, EndLoc); 6955 } 6956 6957 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 6958 SourceLocation EndLoc) { 6959 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 6960 } 6961 6962 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 6963 SourceLocation EndLoc) { 6964 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 6965 } 6966 6967 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 6968 SourceLocation EndLoc) { 6969 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 6970 } 6971 6972 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 6973 SourceLocation EndLoc) { 6974 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 6975 } 6976 6977 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 6978 SourceLocation EndLoc) { 6979 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 6980 } 6981 6982 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 6983 SourceLocation EndLoc) { 6984 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 6985 } 6986 6987 OMPClause *Sema::ActOnOpenMPVarListClause( 6988 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 6989 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 6990 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 6991 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, 6992 OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, 6993 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 6994 SourceLocation DepLinMapLoc) { 6995 OMPClause *Res = nullptr; 6996 switch (Kind) { 6997 case OMPC_private: 6998 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 6999 break; 7000 case OMPC_firstprivate: 7001 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7002 break; 7003 case OMPC_lastprivate: 7004 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7005 break; 7006 case OMPC_shared: 7007 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 7008 break; 7009 case OMPC_reduction: 7010 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 7011 EndLoc, ReductionIdScopeSpec, ReductionId); 7012 break; 7013 case OMPC_linear: 7014 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 7015 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 7016 break; 7017 case OMPC_aligned: 7018 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 7019 ColonLoc, EndLoc); 7020 break; 7021 case OMPC_copyin: 7022 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 7023 break; 7024 case OMPC_copyprivate: 7025 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7026 break; 7027 case OMPC_flush: 7028 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 7029 break; 7030 case OMPC_depend: 7031 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 7032 StartLoc, LParenLoc, EndLoc); 7033 break; 7034 case OMPC_map: 7035 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, 7036 DepLinMapLoc, ColonLoc, VarList, StartLoc, 7037 LParenLoc, EndLoc); 7038 break; 7039 case OMPC_if: 7040 case OMPC_final: 7041 case OMPC_num_threads: 7042 case OMPC_safelen: 7043 case OMPC_simdlen: 7044 case OMPC_collapse: 7045 case OMPC_default: 7046 case OMPC_proc_bind: 7047 case OMPC_schedule: 7048 case OMPC_ordered: 7049 case OMPC_nowait: 7050 case OMPC_untied: 7051 case OMPC_mergeable: 7052 case OMPC_threadprivate: 7053 case OMPC_read: 7054 case OMPC_write: 7055 case OMPC_update: 7056 case OMPC_capture: 7057 case OMPC_seq_cst: 7058 case OMPC_device: 7059 case OMPC_threads: 7060 case OMPC_simd: 7061 case OMPC_num_teams: 7062 case OMPC_thread_limit: 7063 case OMPC_priority: 7064 case OMPC_grainsize: 7065 case OMPC_nogroup: 7066 case OMPC_num_tasks: 7067 case OMPC_hint: 7068 case OMPC_dist_schedule: 7069 case OMPC_defaultmap: 7070 case OMPC_unknown: 7071 llvm_unreachable("Clause is not allowed."); 7072 } 7073 return Res; 7074 } 7075 7076 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 7077 ExprObjectKind OK, SourceLocation Loc) { 7078 ExprResult Res = BuildDeclRefExpr( 7079 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 7080 if (!Res.isUsable()) 7081 return ExprError(); 7082 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 7083 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 7084 if (!Res.isUsable()) 7085 return ExprError(); 7086 } 7087 if (VK != VK_LValue && Res.get()->isGLValue()) { 7088 Res = DefaultLvalueConversion(Res.get()); 7089 if (!Res.isUsable()) 7090 return ExprError(); 7091 } 7092 return Res; 7093 } 7094 7095 static std::pair<ValueDecl *, bool> 7096 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 7097 SourceRange &ERange, bool AllowArraySection = false) { 7098 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 7099 RefExpr->containsUnexpandedParameterPack()) 7100 return std::make_pair(nullptr, true); 7101 7102 // OpenMP [3.1, C/C++] 7103 // A list item is a variable name. 7104 // OpenMP [2.9.3.3, Restrictions, p.1] 7105 // A variable that is part of another variable (as an array or 7106 // structure element) cannot appear in a private clause. 7107 RefExpr = RefExpr->IgnoreParens(); 7108 enum { 7109 NoArrayExpr = -1, 7110 ArraySubscript = 0, 7111 OMPArraySection = 1 7112 } IsArrayExpr = NoArrayExpr; 7113 if (AllowArraySection) { 7114 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 7115 auto *Base = ASE->getBase()->IgnoreParenImpCasts(); 7116 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 7117 Base = TempASE->getBase()->IgnoreParenImpCasts(); 7118 RefExpr = Base; 7119 IsArrayExpr = ArraySubscript; 7120 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 7121 auto *Base = OASE->getBase()->IgnoreParenImpCasts(); 7122 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 7123 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 7124 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 7125 Base = TempASE->getBase()->IgnoreParenImpCasts(); 7126 RefExpr = Base; 7127 IsArrayExpr = OMPArraySection; 7128 } 7129 } 7130 ELoc = RefExpr->getExprLoc(); 7131 ERange = RefExpr->getSourceRange(); 7132 RefExpr = RefExpr->IgnoreParenImpCasts(); 7133 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 7134 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 7135 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 7136 (S.getCurrentThisType().isNull() || !ME || 7137 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 7138 !isa<FieldDecl>(ME->getMemberDecl()))) { 7139 if (IsArrayExpr != NoArrayExpr) 7140 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 7141 << ERange; 7142 else { 7143 S.Diag(ELoc, 7144 AllowArraySection 7145 ? diag::err_omp_expected_var_name_member_expr_or_array_item 7146 : diag::err_omp_expected_var_name_member_expr) 7147 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 7148 } 7149 return std::make_pair(nullptr, false); 7150 } 7151 return std::make_pair(DE ? DE->getDecl() : ME->getMemberDecl(), false); 7152 } 7153 7154 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 7155 SourceLocation StartLoc, 7156 SourceLocation LParenLoc, 7157 SourceLocation EndLoc) { 7158 SmallVector<Expr *, 8> Vars; 7159 SmallVector<Expr *, 8> PrivateCopies; 7160 for (auto &RefExpr : VarList) { 7161 assert(RefExpr && "NULL expr in OpenMP private clause."); 7162 SourceLocation ELoc; 7163 SourceRange ERange; 7164 Expr *SimpleRefExpr = RefExpr; 7165 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 7166 if (Res.second) { 7167 // It will be analyzed later. 7168 Vars.push_back(RefExpr); 7169 PrivateCopies.push_back(nullptr); 7170 } 7171 ValueDecl *D = Res.first; 7172 if (!D) 7173 continue; 7174 7175 QualType Type = D->getType(); 7176 auto *VD = dyn_cast<VarDecl>(D); 7177 7178 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 7179 // A variable that appears in a private clause must not have an incomplete 7180 // type or a reference type. 7181 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 7182 continue; 7183 Type = Type.getNonReferenceType(); 7184 7185 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7186 // in a Construct] 7187 // Variables with the predetermined data-sharing attributes may not be 7188 // listed in data-sharing attributes clauses, except for the cases 7189 // listed below. For these exceptions only, listing a predetermined 7190 // variable in a data-sharing attribute clause is allowed and overrides 7191 // the variable's predetermined data-sharing attributes. 7192 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7193 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 7194 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 7195 << getOpenMPClauseName(OMPC_private); 7196 ReportOriginalDSA(*this, DSAStack, D, DVar); 7197 continue; 7198 } 7199 7200 // Variably modified types are not supported for tasks. 7201 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 7202 DSAStack->getCurrentDirective() == OMPD_task) { 7203 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 7204 << getOpenMPClauseName(OMPC_private) << Type 7205 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7206 bool IsDecl = 7207 !VD || 7208 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 7209 Diag(D->getLocation(), 7210 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 7211 << D; 7212 continue; 7213 } 7214 7215 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 7216 // A list item cannot appear in both a map clause and a data-sharing 7217 // attribute clause on the same construct 7218 if (DSAStack->getCurrentDirective() == OMPD_target) { 7219 if(DSAStack->checkMapInfoForVar(VD, /* CurrentRegionOnly = */ true, 7220 [&](Expr *RE) -> bool {return true;})) { 7221 Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) 7222 << getOpenMPClauseName(OMPC_private) 7223 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7224 ReportOriginalDSA(*this, DSAStack, D, DVar); 7225 continue; 7226 } 7227 } 7228 7229 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 7230 // A variable of class type (or array thereof) that appears in a private 7231 // clause requires an accessible, unambiguous default constructor for the 7232 // class type. 7233 // Generate helper private variable and initialize it with the default 7234 // value. The address of the original variable is replaced by the address of 7235 // the new private variable in CodeGen. This new variable is not added to 7236 // IdResolver, so the code in the OpenMP region uses original variable for 7237 // proper diagnostics. 7238 Type = Type.getUnqualifiedType(); 7239 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 7240 D->hasAttrs() ? &D->getAttrs() : nullptr); 7241 ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); 7242 if (VDPrivate->isInvalidDecl()) 7243 continue; 7244 auto VDPrivateRefExpr = buildDeclRefExpr( 7245 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 7246 7247 DeclRefExpr *Ref = nullptr; 7248 if (!VD) 7249 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 7250 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 7251 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 7252 PrivateCopies.push_back(VDPrivateRefExpr); 7253 } 7254 7255 if (Vars.empty()) 7256 return nullptr; 7257 7258 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 7259 PrivateCopies); 7260 } 7261 7262 namespace { 7263 class DiagsUninitializedSeveretyRAII { 7264 private: 7265 DiagnosticsEngine &Diags; 7266 SourceLocation SavedLoc; 7267 bool IsIgnored; 7268 7269 public: 7270 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 7271 bool IsIgnored) 7272 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 7273 if (!IsIgnored) { 7274 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 7275 /*Map*/ diag::Severity::Ignored, Loc); 7276 } 7277 } 7278 ~DiagsUninitializedSeveretyRAII() { 7279 if (!IsIgnored) 7280 Diags.popMappings(SavedLoc); 7281 } 7282 }; 7283 } 7284 7285 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 7286 SourceLocation StartLoc, 7287 SourceLocation LParenLoc, 7288 SourceLocation EndLoc) { 7289 SmallVector<Expr *, 8> Vars; 7290 SmallVector<Expr *, 8> PrivateCopies; 7291 SmallVector<Expr *, 8> Inits; 7292 SmallVector<Decl *, 4> ExprCaptures; 7293 bool IsImplicitClause = 7294 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 7295 auto ImplicitClauseLoc = DSAStack->getConstructLoc(); 7296 7297 for (auto &RefExpr : VarList) { 7298 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 7299 SourceLocation ELoc; 7300 SourceRange ERange; 7301 Expr *SimpleRefExpr = RefExpr; 7302 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 7303 if (Res.second) { 7304 // It will be analyzed later. 7305 Vars.push_back(RefExpr); 7306 PrivateCopies.push_back(nullptr); 7307 Inits.push_back(nullptr); 7308 } 7309 ValueDecl *D = Res.first; 7310 if (!D) 7311 continue; 7312 7313 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 7314 QualType Type = D->getType(); 7315 auto *VD = dyn_cast<VarDecl>(D); 7316 7317 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 7318 // A variable that appears in a private clause must not have an incomplete 7319 // type or a reference type. 7320 if (RequireCompleteType(ELoc, Type, 7321 diag::err_omp_firstprivate_incomplete_type)) 7322 continue; 7323 Type = Type.getNonReferenceType(); 7324 7325 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 7326 // A variable of class type (or array thereof) that appears in a private 7327 // clause requires an accessible, unambiguous copy constructor for the 7328 // class type. 7329 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 7330 7331 // If an implicit firstprivate variable found it was checked already. 7332 DSAStackTy::DSAVarData TopDVar; 7333 if (!IsImplicitClause) { 7334 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7335 TopDVar = DVar; 7336 bool IsConstant = ElemType.isConstant(Context); 7337 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 7338 // A list item that specifies a given variable may not appear in more 7339 // than one clause on the same directive, except that a variable may be 7340 // specified in both firstprivate and lastprivate clauses. 7341 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 7342 DVar.CKind != OMPC_lastprivate && DVar.RefExpr) { 7343 Diag(ELoc, diag::err_omp_wrong_dsa) 7344 << getOpenMPClauseName(DVar.CKind) 7345 << getOpenMPClauseName(OMPC_firstprivate); 7346 ReportOriginalDSA(*this, DSAStack, D, DVar); 7347 continue; 7348 } 7349 7350 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7351 // in a Construct] 7352 // Variables with the predetermined data-sharing attributes may not be 7353 // listed in data-sharing attributes clauses, except for the cases 7354 // listed below. For these exceptions only, listing a predetermined 7355 // variable in a data-sharing attribute clause is allowed and overrides 7356 // the variable's predetermined data-sharing attributes. 7357 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7358 // in a Construct, C/C++, p.2] 7359 // Variables with const-qualified type having no mutable member may be 7360 // listed in a firstprivate clause, even if they are static data members. 7361 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 7362 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 7363 Diag(ELoc, diag::err_omp_wrong_dsa) 7364 << getOpenMPClauseName(DVar.CKind) 7365 << getOpenMPClauseName(OMPC_firstprivate); 7366 ReportOriginalDSA(*this, DSAStack, D, DVar); 7367 continue; 7368 } 7369 7370 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 7371 // OpenMP [2.9.3.4, Restrictions, p.2] 7372 // A list item that is private within a parallel region must not appear 7373 // in a firstprivate clause on a worksharing construct if any of the 7374 // worksharing regions arising from the worksharing construct ever bind 7375 // to any of the parallel regions arising from the parallel construct. 7376 if (isOpenMPWorksharingDirective(CurrDir) && 7377 !isOpenMPParallelDirective(CurrDir)) { 7378 DVar = DSAStack->getImplicitDSA(D, true); 7379 if (DVar.CKind != OMPC_shared && 7380 (isOpenMPParallelDirective(DVar.DKind) || 7381 DVar.DKind == OMPD_unknown)) { 7382 Diag(ELoc, diag::err_omp_required_access) 7383 << getOpenMPClauseName(OMPC_firstprivate) 7384 << getOpenMPClauseName(OMPC_shared); 7385 ReportOriginalDSA(*this, DSAStack, D, DVar); 7386 continue; 7387 } 7388 } 7389 // OpenMP [2.9.3.4, Restrictions, p.3] 7390 // A list item that appears in a reduction clause of a parallel construct 7391 // must not appear in a firstprivate clause on a worksharing or task 7392 // construct if any of the worksharing or task regions arising from the 7393 // worksharing or task construct ever bind to any of the parallel regions 7394 // arising from the parallel construct. 7395 // OpenMP [2.9.3.4, Restrictions, p.4] 7396 // A list item that appears in a reduction clause in worksharing 7397 // construct must not appear in a firstprivate clause in a task construct 7398 // encountered during execution of any of the worksharing regions arising 7399 // from the worksharing construct. 7400 if (CurrDir == OMPD_task) { 7401 DVar = 7402 DSAStack->hasInnermostDSA(D, MatchesAnyClause(OMPC_reduction), 7403 [](OpenMPDirectiveKind K) -> bool { 7404 return isOpenMPParallelDirective(K) || 7405 isOpenMPWorksharingDirective(K); 7406 }, 7407 false); 7408 if (DVar.CKind == OMPC_reduction && 7409 (isOpenMPParallelDirective(DVar.DKind) || 7410 isOpenMPWorksharingDirective(DVar.DKind))) { 7411 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 7412 << getOpenMPDirectiveName(DVar.DKind); 7413 ReportOriginalDSA(*this, DSAStack, D, DVar); 7414 continue; 7415 } 7416 } 7417 7418 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 7419 // A list item that is private within a teams region must not appear in a 7420 // firstprivate clause on a distribute construct if any of the distribute 7421 // regions arising from the distribute construct ever bind to any of the 7422 // teams regions arising from the teams construct. 7423 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 7424 // A list item that appears in a reduction clause of a teams construct 7425 // must not appear in a firstprivate clause on a distribute construct if 7426 // any of the distribute regions arising from the distribute construct 7427 // ever bind to any of the teams regions arising from the teams construct. 7428 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 7429 // A list item may appear in a firstprivate or lastprivate clause but not 7430 // both. 7431 if (CurrDir == OMPD_distribute) { 7432 DVar = DSAStack->hasInnermostDSA(D, MatchesAnyClause(OMPC_private), 7433 [](OpenMPDirectiveKind K) -> bool { 7434 return isOpenMPTeamsDirective(K); 7435 }, 7436 false); 7437 if (DVar.CKind == OMPC_private && isOpenMPTeamsDirective(DVar.DKind)) { 7438 Diag(ELoc, diag::err_omp_firstprivate_distribute_private_teams); 7439 ReportOriginalDSA(*this, DSAStack, D, DVar); 7440 continue; 7441 } 7442 DVar = DSAStack->hasInnermostDSA(D, MatchesAnyClause(OMPC_reduction), 7443 [](OpenMPDirectiveKind K) -> bool { 7444 return isOpenMPTeamsDirective(K); 7445 }, 7446 false); 7447 if (DVar.CKind == OMPC_reduction && 7448 isOpenMPTeamsDirective(DVar.DKind)) { 7449 Diag(ELoc, diag::err_omp_firstprivate_distribute_in_teams_reduction); 7450 ReportOriginalDSA(*this, DSAStack, D, DVar); 7451 continue; 7452 } 7453 DVar = DSAStack->getTopDSA(D, false); 7454 if (DVar.CKind == OMPC_lastprivate) { 7455 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); 7456 ReportOriginalDSA(*this, DSAStack, D, DVar); 7457 continue; 7458 } 7459 } 7460 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 7461 // A list item cannot appear in both a map clause and a data-sharing 7462 // attribute clause on the same construct 7463 if (CurrDir == OMPD_target) { 7464 if(DSAStack->checkMapInfoForVar(VD, /* CurrentRegionOnly = */ true, 7465 [&](Expr *RE) -> bool {return true;})) { 7466 Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) 7467 << getOpenMPClauseName(OMPC_firstprivate) 7468 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7469 ReportOriginalDSA(*this, DSAStack, D, DVar); 7470 continue; 7471 } 7472 } 7473 } 7474 7475 // Variably modified types are not supported for tasks. 7476 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 7477 DSAStack->getCurrentDirective() == OMPD_task) { 7478 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 7479 << getOpenMPClauseName(OMPC_firstprivate) << Type 7480 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7481 bool IsDecl = 7482 !VD || 7483 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 7484 Diag(D->getLocation(), 7485 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 7486 << D; 7487 continue; 7488 } 7489 7490 Type = Type.getUnqualifiedType(); 7491 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 7492 D->hasAttrs() ? &D->getAttrs() : nullptr); 7493 // Generate helper private variable and initialize it with the value of the 7494 // original variable. The address of the original variable is replaced by 7495 // the address of the new private variable in the CodeGen. This new variable 7496 // is not added to IdResolver, so the code in the OpenMP region uses 7497 // original variable for proper diagnostics and variable capturing. 7498 Expr *VDInitRefExpr = nullptr; 7499 // For arrays generate initializer for single element and replace it by the 7500 // original array element in CodeGen. 7501 if (Type->isArrayType()) { 7502 auto VDInit = 7503 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 7504 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 7505 auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); 7506 ElemType = ElemType.getUnqualifiedType(); 7507 auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 7508 ".firstprivate.temp"); 7509 InitializedEntity Entity = 7510 InitializedEntity::InitializeVariable(VDInitTemp); 7511 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 7512 7513 InitializationSequence InitSeq(*this, Entity, Kind, Init); 7514 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 7515 if (Result.isInvalid()) 7516 VDPrivate->setInvalidDecl(); 7517 else 7518 VDPrivate->setInit(Result.getAs<Expr>()); 7519 // Remove temp variable declaration. 7520 Context.Deallocate(VDInitTemp); 7521 } else { 7522 auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 7523 ".firstprivate.temp"); 7524 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 7525 RefExpr->getExprLoc()); 7526 AddInitializerToDecl(VDPrivate, 7527 DefaultLvalueConversion(VDInitRefExpr).get(), 7528 /*DirectInit=*/false, /*TypeMayContainAuto=*/false); 7529 } 7530 if (VDPrivate->isInvalidDecl()) { 7531 if (IsImplicitClause) { 7532 Diag(RefExpr->getExprLoc(), 7533 diag::note_omp_task_predetermined_firstprivate_here); 7534 } 7535 continue; 7536 } 7537 CurContext->addDecl(VDPrivate); 7538 auto VDPrivateRefExpr = buildDeclRefExpr( 7539 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 7540 RefExpr->getExprLoc()); 7541 DeclRefExpr *Ref = nullptr; 7542 if (!VD) { 7543 if (TopDVar.CKind == OMPC_lastprivate) 7544 Ref = TopDVar.PrivateCopy; 7545 else { 7546 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 7547 if (!IsOpenMPCapturedDecl(D)) 7548 ExprCaptures.push_back(Ref->getDecl()); 7549 } 7550 } 7551 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 7552 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 7553 PrivateCopies.push_back(VDPrivateRefExpr); 7554 Inits.push_back(VDInitRefExpr); 7555 } 7556 7557 if (Vars.empty()) 7558 return nullptr; 7559 7560 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 7561 Vars, PrivateCopies, Inits, 7562 buildPreInits(Context, ExprCaptures)); 7563 } 7564 7565 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 7566 SourceLocation StartLoc, 7567 SourceLocation LParenLoc, 7568 SourceLocation EndLoc) { 7569 SmallVector<Expr *, 8> Vars; 7570 SmallVector<Expr *, 8> SrcExprs; 7571 SmallVector<Expr *, 8> DstExprs; 7572 SmallVector<Expr *, 8> AssignmentOps; 7573 SmallVector<Decl *, 4> ExprCaptures; 7574 SmallVector<Expr *, 4> ExprPostUpdates; 7575 for (auto &RefExpr : VarList) { 7576 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 7577 SourceLocation ELoc; 7578 SourceRange ERange; 7579 Expr *SimpleRefExpr = RefExpr; 7580 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 7581 if (Res.second) { 7582 // It will be analyzed later. 7583 Vars.push_back(RefExpr); 7584 SrcExprs.push_back(nullptr); 7585 DstExprs.push_back(nullptr); 7586 AssignmentOps.push_back(nullptr); 7587 } 7588 ValueDecl *D = Res.first; 7589 if (!D) 7590 continue; 7591 7592 QualType Type = D->getType(); 7593 auto *VD = dyn_cast<VarDecl>(D); 7594 7595 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 7596 // A variable that appears in a lastprivate clause must not have an 7597 // incomplete type or a reference type. 7598 if (RequireCompleteType(ELoc, Type, 7599 diag::err_omp_lastprivate_incomplete_type)) 7600 continue; 7601 Type = Type.getNonReferenceType(); 7602 7603 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 7604 // in a Construct] 7605 // Variables with the predetermined data-sharing attributes may not be 7606 // listed in data-sharing attributes clauses, except for the cases 7607 // listed below. 7608 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7609 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 7610 DVar.CKind != OMPC_firstprivate && 7611 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 7612 Diag(ELoc, diag::err_omp_wrong_dsa) 7613 << getOpenMPClauseName(DVar.CKind) 7614 << getOpenMPClauseName(OMPC_lastprivate); 7615 ReportOriginalDSA(*this, DSAStack, D, DVar); 7616 continue; 7617 } 7618 7619 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 7620 // OpenMP [2.14.3.5, Restrictions, p.2] 7621 // A list item that is private within a parallel region, or that appears in 7622 // the reduction clause of a parallel construct, must not appear in a 7623 // lastprivate clause on a worksharing construct if any of the corresponding 7624 // worksharing regions ever binds to any of the corresponding parallel 7625 // regions. 7626 DSAStackTy::DSAVarData TopDVar = DVar; 7627 if (isOpenMPWorksharingDirective(CurrDir) && 7628 !isOpenMPParallelDirective(CurrDir)) { 7629 DVar = DSAStack->getImplicitDSA(D, true); 7630 if (DVar.CKind != OMPC_shared) { 7631 Diag(ELoc, diag::err_omp_required_access) 7632 << getOpenMPClauseName(OMPC_lastprivate) 7633 << getOpenMPClauseName(OMPC_shared); 7634 ReportOriginalDSA(*this, DSAStack, D, DVar); 7635 continue; 7636 } 7637 } 7638 7639 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 7640 // A list item may appear in a firstprivate or lastprivate clause but not 7641 // both. 7642 if (CurrDir == OMPD_distribute) { 7643 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7644 if (DVar.CKind == OMPC_firstprivate) { 7645 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); 7646 ReportOriginalDSA(*this, DSAStack, D, DVar); 7647 continue; 7648 } 7649 } 7650 7651 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 7652 // A variable of class type (or array thereof) that appears in a 7653 // lastprivate clause requires an accessible, unambiguous default 7654 // constructor for the class type, unless the list item is also specified 7655 // in a firstprivate clause. 7656 // A variable of class type (or array thereof) that appears in a 7657 // lastprivate clause requires an accessible, unambiguous copy assignment 7658 // operator for the class type. 7659 Type = Context.getBaseElementType(Type).getNonReferenceType(); 7660 auto *SrcVD = buildVarDecl(*this, ERange.getBegin(), 7661 Type.getUnqualifiedType(), ".lastprivate.src", 7662 D->hasAttrs() ? &D->getAttrs() : nullptr); 7663 auto *PseudoSrcExpr = 7664 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 7665 auto *DstVD = 7666 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 7667 D->hasAttrs() ? &D->getAttrs() : nullptr); 7668 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 7669 // For arrays generate assignment operation for single element and replace 7670 // it by the original array element in CodeGen. 7671 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 7672 PseudoDstExpr, PseudoSrcExpr); 7673 if (AssignmentOp.isInvalid()) 7674 continue; 7675 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 7676 /*DiscardedValue=*/true); 7677 if (AssignmentOp.isInvalid()) 7678 continue; 7679 7680 DeclRefExpr *Ref = nullptr; 7681 if (!VD) { 7682 if (TopDVar.CKind == OMPC_firstprivate) 7683 Ref = TopDVar.PrivateCopy; 7684 else { 7685 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 7686 if (!IsOpenMPCapturedDecl(D)) 7687 ExprCaptures.push_back(Ref->getDecl()); 7688 } 7689 if (TopDVar.CKind == OMPC_firstprivate || 7690 (!IsOpenMPCapturedDecl(D) && 7691 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 7692 ExprResult RefRes = DefaultLvalueConversion(Ref); 7693 if (!RefRes.isUsable()) 7694 continue; 7695 ExprResult PostUpdateRes = 7696 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 7697 RefRes.get()); 7698 if (!PostUpdateRes.isUsable()) 7699 continue; 7700 ExprPostUpdates.push_back( 7701 IgnoredValueConversions(PostUpdateRes.get()).get()); 7702 } 7703 } 7704 if (TopDVar.CKind != OMPC_firstprivate) 7705 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 7706 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 7707 SrcExprs.push_back(PseudoSrcExpr); 7708 DstExprs.push_back(PseudoDstExpr); 7709 AssignmentOps.push_back(AssignmentOp.get()); 7710 } 7711 7712 if (Vars.empty()) 7713 return nullptr; 7714 7715 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 7716 Vars, SrcExprs, DstExprs, AssignmentOps, 7717 buildPreInits(Context, ExprCaptures), 7718 buildPostUpdate(*this, ExprPostUpdates)); 7719 } 7720 7721 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 7722 SourceLocation StartLoc, 7723 SourceLocation LParenLoc, 7724 SourceLocation EndLoc) { 7725 SmallVector<Expr *, 8> Vars; 7726 for (auto &RefExpr : VarList) { 7727 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 7728 SourceLocation ELoc; 7729 SourceRange ERange; 7730 Expr *SimpleRefExpr = RefExpr; 7731 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 7732 if (Res.second) { 7733 // It will be analyzed later. 7734 Vars.push_back(RefExpr); 7735 } 7736 ValueDecl *D = Res.first; 7737 if (!D) 7738 continue; 7739 7740 auto *VD = dyn_cast<VarDecl>(D); 7741 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7742 // in a Construct] 7743 // Variables with the predetermined data-sharing attributes may not be 7744 // listed in data-sharing attributes clauses, except for the cases 7745 // listed below. For these exceptions only, listing a predetermined 7746 // variable in a data-sharing attribute clause is allowed and overrides 7747 // the variable's predetermined data-sharing attributes. 7748 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7749 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 7750 DVar.RefExpr) { 7751 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 7752 << getOpenMPClauseName(OMPC_shared); 7753 ReportOriginalDSA(*this, DSAStack, D, DVar); 7754 continue; 7755 } 7756 7757 DeclRefExpr *Ref = nullptr; 7758 if (!VD && IsOpenMPCapturedDecl(D)) 7759 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 7760 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 7761 Vars.push_back((VD || !Ref) ? RefExpr->IgnoreParens() : Ref); 7762 } 7763 7764 if (Vars.empty()) 7765 return nullptr; 7766 7767 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 7768 } 7769 7770 namespace { 7771 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 7772 DSAStackTy *Stack; 7773 7774 public: 7775 bool VisitDeclRefExpr(DeclRefExpr *E) { 7776 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { 7777 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false); 7778 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 7779 return false; 7780 if (DVar.CKind != OMPC_unknown) 7781 return true; 7782 DSAStackTy::DSAVarData DVarPrivate = 7783 Stack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), false); 7784 if (DVarPrivate.CKind != OMPC_unknown) 7785 return true; 7786 return false; 7787 } 7788 return false; 7789 } 7790 bool VisitStmt(Stmt *S) { 7791 for (auto Child : S->children()) { 7792 if (Child && Visit(Child)) 7793 return true; 7794 } 7795 return false; 7796 } 7797 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 7798 }; 7799 } // namespace 7800 7801 namespace { 7802 // Transform MemberExpression for specified FieldDecl of current class to 7803 // DeclRefExpr to specified OMPCapturedExprDecl. 7804 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 7805 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 7806 ValueDecl *Field; 7807 DeclRefExpr *CapturedExpr; 7808 7809 public: 7810 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 7811 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 7812 7813 ExprResult TransformMemberExpr(MemberExpr *E) { 7814 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 7815 E->getMemberDecl() == Field) { 7816 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 7817 return CapturedExpr; 7818 } 7819 return BaseTransform::TransformMemberExpr(E); 7820 } 7821 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 7822 }; 7823 } // namespace 7824 7825 template <typename T> 7826 static T filterLookupForUDR(SmallVectorImpl<UnresolvedSet<8>> &Lookups, 7827 const llvm::function_ref<T(ValueDecl *)> &Gen) { 7828 for (auto &Set : Lookups) { 7829 for (auto *D : Set) { 7830 if (auto Res = Gen(cast<ValueDecl>(D))) 7831 return Res; 7832 } 7833 } 7834 return T(); 7835 } 7836 7837 static ExprResult 7838 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 7839 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 7840 const DeclarationNameInfo &ReductionId, QualType Ty, 7841 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 7842 if (ReductionIdScopeSpec.isInvalid()) 7843 return ExprError(); 7844 SmallVector<UnresolvedSet<8>, 4> Lookups; 7845 if (S) { 7846 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 7847 Lookup.suppressDiagnostics(); 7848 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 7849 auto *D = Lookup.getRepresentativeDecl(); 7850 do { 7851 S = S->getParent(); 7852 } while (S && !S->isDeclScope(D)); 7853 if (S) 7854 S = S->getParent(); 7855 Lookups.push_back(UnresolvedSet<8>()); 7856 Lookups.back().append(Lookup.begin(), Lookup.end()); 7857 Lookup.clear(); 7858 } 7859 } else if (auto *ULE = 7860 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 7861 Lookups.push_back(UnresolvedSet<8>()); 7862 Decl *PrevD = nullptr; 7863 for(auto *D : ULE->decls()) { 7864 if (D == PrevD) 7865 Lookups.push_back(UnresolvedSet<8>()); 7866 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) 7867 Lookups.back().addDecl(DRD); 7868 PrevD = D; 7869 } 7870 } 7871 if (Ty->isDependentType() || Ty->isInstantiationDependentType() || 7872 Ty->containsUnexpandedParameterPack() || 7873 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool { 7874 return !D->isInvalidDecl() && 7875 (D->getType()->isDependentType() || 7876 D->getType()->isInstantiationDependentType() || 7877 D->getType()->containsUnexpandedParameterPack()); 7878 })) { 7879 UnresolvedSet<8> ResSet; 7880 for (auto &Set : Lookups) { 7881 ResSet.append(Set.begin(), Set.end()); 7882 // The last item marks the end of all declarations at the specified scope. 7883 ResSet.addDecl(Set[Set.size() - 1]); 7884 } 7885 return UnresolvedLookupExpr::Create( 7886 SemaRef.Context, /*NamingClass=*/nullptr, 7887 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 7888 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 7889 } 7890 if (auto *VD = filterLookupForUDR<ValueDecl *>( 7891 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 7892 if (!D->isInvalidDecl() && 7893 SemaRef.Context.hasSameType(D->getType(), Ty)) 7894 return D; 7895 return nullptr; 7896 })) 7897 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 7898 if (auto *VD = filterLookupForUDR<ValueDecl *>( 7899 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 7900 if (!D->isInvalidDecl() && 7901 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 7902 !Ty.isMoreQualifiedThan(D->getType())) 7903 return D; 7904 return nullptr; 7905 })) { 7906 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 7907 /*DetectVirtual=*/false); 7908 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 7909 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 7910 VD->getType().getUnqualifiedType()))) { 7911 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), 7912 /*DiagID=*/0) != 7913 Sema::AR_inaccessible) { 7914 SemaRef.BuildBasePathArray(Paths, BasePath); 7915 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 7916 } 7917 } 7918 } 7919 } 7920 if (ReductionIdScopeSpec.isSet()) { 7921 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 7922 return ExprError(); 7923 } 7924 return ExprEmpty(); 7925 } 7926 7927 OMPClause *Sema::ActOnOpenMPReductionClause( 7928 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 7929 SourceLocation ColonLoc, SourceLocation EndLoc, 7930 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 7931 ArrayRef<Expr *> UnresolvedReductions) { 7932 auto DN = ReductionId.getName(); 7933 auto OOK = DN.getCXXOverloadedOperator(); 7934 BinaryOperatorKind BOK = BO_Comma; 7935 7936 // OpenMP [2.14.3.6, reduction clause] 7937 // C 7938 // reduction-identifier is either an identifier or one of the following 7939 // operators: +, -, *, &, |, ^, && and || 7940 // C++ 7941 // reduction-identifier is either an id-expression or one of the following 7942 // operators: +, -, *, &, |, ^, && and || 7943 // FIXME: Only 'min' and 'max' identifiers are supported for now. 7944 switch (OOK) { 7945 case OO_Plus: 7946 case OO_Minus: 7947 BOK = BO_Add; 7948 break; 7949 case OO_Star: 7950 BOK = BO_Mul; 7951 break; 7952 case OO_Amp: 7953 BOK = BO_And; 7954 break; 7955 case OO_Pipe: 7956 BOK = BO_Or; 7957 break; 7958 case OO_Caret: 7959 BOK = BO_Xor; 7960 break; 7961 case OO_AmpAmp: 7962 BOK = BO_LAnd; 7963 break; 7964 case OO_PipePipe: 7965 BOK = BO_LOr; 7966 break; 7967 case OO_New: 7968 case OO_Delete: 7969 case OO_Array_New: 7970 case OO_Array_Delete: 7971 case OO_Slash: 7972 case OO_Percent: 7973 case OO_Tilde: 7974 case OO_Exclaim: 7975 case OO_Equal: 7976 case OO_Less: 7977 case OO_Greater: 7978 case OO_LessEqual: 7979 case OO_GreaterEqual: 7980 case OO_PlusEqual: 7981 case OO_MinusEqual: 7982 case OO_StarEqual: 7983 case OO_SlashEqual: 7984 case OO_PercentEqual: 7985 case OO_CaretEqual: 7986 case OO_AmpEqual: 7987 case OO_PipeEqual: 7988 case OO_LessLess: 7989 case OO_GreaterGreater: 7990 case OO_LessLessEqual: 7991 case OO_GreaterGreaterEqual: 7992 case OO_EqualEqual: 7993 case OO_ExclaimEqual: 7994 case OO_PlusPlus: 7995 case OO_MinusMinus: 7996 case OO_Comma: 7997 case OO_ArrowStar: 7998 case OO_Arrow: 7999 case OO_Call: 8000 case OO_Subscript: 8001 case OO_Conditional: 8002 case OO_Coawait: 8003 case NUM_OVERLOADED_OPERATORS: 8004 llvm_unreachable("Unexpected reduction identifier"); 8005 case OO_None: 8006 if (auto II = DN.getAsIdentifierInfo()) { 8007 if (II->isStr("max")) 8008 BOK = BO_GT; 8009 else if (II->isStr("min")) 8010 BOK = BO_LT; 8011 } 8012 break; 8013 } 8014 SourceRange ReductionIdRange; 8015 if (ReductionIdScopeSpec.isValid()) 8016 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 8017 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 8018 8019 SmallVector<Expr *, 8> Vars; 8020 SmallVector<Expr *, 8> Privates; 8021 SmallVector<Expr *, 8> LHSs; 8022 SmallVector<Expr *, 8> RHSs; 8023 SmallVector<Expr *, 8> ReductionOps; 8024 SmallVector<Decl *, 4> ExprCaptures; 8025 SmallVector<Expr *, 4> ExprPostUpdates; 8026 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 8027 bool FirstIter = true; 8028 for (auto RefExpr : VarList) { 8029 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 8030 // OpenMP [2.1, C/C++] 8031 // A list item is a variable or array section, subject to the restrictions 8032 // specified in Section 2.4 on page 42 and in each of the sections 8033 // describing clauses and directives for which a list appears. 8034 // OpenMP [2.14.3.3, Restrictions, p.1] 8035 // A variable that is part of another variable (as an array or 8036 // structure element) cannot appear in a private clause. 8037 if (!FirstIter && IR != ER) 8038 ++IR; 8039 FirstIter = false; 8040 SourceLocation ELoc; 8041 SourceRange ERange; 8042 Expr *SimpleRefExpr = RefExpr; 8043 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 8044 /*AllowArraySection=*/true); 8045 if (Res.second) { 8046 // It will be analyzed later. 8047 Vars.push_back(RefExpr); 8048 Privates.push_back(nullptr); 8049 LHSs.push_back(nullptr); 8050 RHSs.push_back(nullptr); 8051 // Try to find 'declare reduction' corresponding construct before using 8052 // builtin/overloaded operators. 8053 QualType Type = Context.DependentTy; 8054 CXXCastPath BasePath; 8055 ExprResult DeclareReductionRef = buildDeclareReductionRef( 8056 *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, 8057 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 8058 if (CurContext->isDependentContext() && 8059 (DeclareReductionRef.isUnset() || 8060 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 8061 ReductionOps.push_back(DeclareReductionRef.get()); 8062 else 8063 ReductionOps.push_back(nullptr); 8064 } 8065 ValueDecl *D = Res.first; 8066 if (!D) 8067 continue; 8068 8069 QualType Type; 8070 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 8071 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 8072 if (ASE) 8073 Type = ASE->getType().getNonReferenceType(); 8074 else if (OASE) { 8075 auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 8076 if (auto *ATy = BaseType->getAsArrayTypeUnsafe()) 8077 Type = ATy->getElementType(); 8078 else 8079 Type = BaseType->getPointeeType(); 8080 Type = Type.getNonReferenceType(); 8081 } else 8082 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 8083 auto *VD = dyn_cast<VarDecl>(D); 8084 8085 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 8086 // A variable that appears in a private clause must not have an incomplete 8087 // type or a reference type. 8088 if (RequireCompleteType(ELoc, Type, 8089 diag::err_omp_reduction_incomplete_type)) 8090 continue; 8091 // OpenMP [2.14.3.6, reduction clause, Restrictions] 8092 // A list item that appears in a reduction clause must not be 8093 // const-qualified. 8094 if (Type.getNonReferenceType().isConstant(Context)) { 8095 Diag(ELoc, diag::err_omp_const_reduction_list_item) 8096 << getOpenMPClauseName(OMPC_reduction) << Type << ERange; 8097 if (!ASE && !OASE) { 8098 bool IsDecl = !VD || 8099 VD->isThisDeclarationADefinition(Context) == 8100 VarDecl::DeclarationOnly; 8101 Diag(D->getLocation(), 8102 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8103 << D; 8104 } 8105 continue; 8106 } 8107 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 8108 // If a list-item is a reference type then it must bind to the same object 8109 // for all threads of the team. 8110 if (!ASE && !OASE && VD) { 8111 VarDecl *VDDef = VD->getDefinition(); 8112 if (VD->getType()->isReferenceType() && VDDef) { 8113 DSARefChecker Check(DSAStack); 8114 if (Check.Visit(VDDef->getInit())) { 8115 Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; 8116 Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 8117 continue; 8118 } 8119 } 8120 } 8121 8122 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 8123 // in a Construct] 8124 // Variables with the predetermined data-sharing attributes may not be 8125 // listed in data-sharing attributes clauses, except for the cases 8126 // listed below. For these exceptions only, listing a predetermined 8127 // variable in a data-sharing attribute clause is allowed and overrides 8128 // the variable's predetermined data-sharing attributes. 8129 // OpenMP [2.14.3.6, Restrictions, p.3] 8130 // Any number of reduction clauses can be specified on the directive, 8131 // but a list item can appear only once in the reduction clauses for that 8132 // directive. 8133 DSAStackTy::DSAVarData DVar; 8134 DVar = DSAStack->getTopDSA(D, false); 8135 if (DVar.CKind == OMPC_reduction) { 8136 Diag(ELoc, diag::err_omp_once_referenced) 8137 << getOpenMPClauseName(OMPC_reduction); 8138 if (DVar.RefExpr) 8139 Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 8140 } else if (DVar.CKind != OMPC_unknown) { 8141 Diag(ELoc, diag::err_omp_wrong_dsa) 8142 << getOpenMPClauseName(DVar.CKind) 8143 << getOpenMPClauseName(OMPC_reduction); 8144 ReportOriginalDSA(*this, DSAStack, D, DVar); 8145 continue; 8146 } 8147 8148 // OpenMP [2.14.3.6, Restrictions, p.1] 8149 // A list item that appears in a reduction clause of a worksharing 8150 // construct must be shared in the parallel regions to which any of the 8151 // worksharing regions arising from the worksharing construct bind. 8152 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 8153 if (isOpenMPWorksharingDirective(CurrDir) && 8154 !isOpenMPParallelDirective(CurrDir)) { 8155 DVar = DSAStack->getImplicitDSA(D, true); 8156 if (DVar.CKind != OMPC_shared) { 8157 Diag(ELoc, diag::err_omp_required_access) 8158 << getOpenMPClauseName(OMPC_reduction) 8159 << getOpenMPClauseName(OMPC_shared); 8160 ReportOriginalDSA(*this, DSAStack, D, DVar); 8161 continue; 8162 } 8163 } 8164 8165 // Try to find 'declare reduction' corresponding construct before using 8166 // builtin/overloaded operators. 8167 CXXCastPath BasePath; 8168 ExprResult DeclareReductionRef = buildDeclareReductionRef( 8169 *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, 8170 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 8171 if (DeclareReductionRef.isInvalid()) 8172 continue; 8173 if (CurContext->isDependentContext() && 8174 (DeclareReductionRef.isUnset() || 8175 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 8176 Vars.push_back(RefExpr); 8177 Privates.push_back(nullptr); 8178 LHSs.push_back(nullptr); 8179 RHSs.push_back(nullptr); 8180 ReductionOps.push_back(DeclareReductionRef.get()); 8181 continue; 8182 } 8183 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 8184 // Not allowed reduction identifier is found. 8185 Diag(ReductionId.getLocStart(), 8186 diag::err_omp_unknown_reduction_identifier) 8187 << Type << ReductionIdRange; 8188 continue; 8189 } 8190 8191 // OpenMP [2.14.3.6, reduction clause, Restrictions] 8192 // The type of a list item that appears in a reduction clause must be valid 8193 // for the reduction-identifier. For a max or min reduction in C, the type 8194 // of the list item must be an allowed arithmetic data type: char, int, 8195 // float, double, or _Bool, possibly modified with long, short, signed, or 8196 // unsigned. For a max or min reduction in C++, the type of the list item 8197 // must be an allowed arithmetic data type: char, wchar_t, int, float, 8198 // double, or bool, possibly modified with long, short, signed, or unsigned. 8199 if (DeclareReductionRef.isUnset()) { 8200 if ((BOK == BO_GT || BOK == BO_LT) && 8201 !(Type->isScalarType() || 8202 (getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 8203 Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 8204 << getLangOpts().CPlusPlus; 8205 if (!ASE && !OASE) { 8206 bool IsDecl = !VD || 8207 VD->isThisDeclarationADefinition(Context) == 8208 VarDecl::DeclarationOnly; 8209 Diag(D->getLocation(), 8210 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8211 << D; 8212 } 8213 continue; 8214 } 8215 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 8216 !getLangOpts().CPlusPlus && Type->isFloatingType()) { 8217 Diag(ELoc, diag::err_omp_clause_floating_type_arg); 8218 if (!ASE && !OASE) { 8219 bool IsDecl = !VD || 8220 VD->isThisDeclarationADefinition(Context) == 8221 VarDecl::DeclarationOnly; 8222 Diag(D->getLocation(), 8223 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8224 << D; 8225 } 8226 continue; 8227 } 8228 } 8229 8230 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 8231 auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs", 8232 D->hasAttrs() ? &D->getAttrs() : nullptr); 8233 auto *RHSVD = buildVarDecl(*this, ELoc, Type, D->getName(), 8234 D->hasAttrs() ? &D->getAttrs() : nullptr); 8235 auto PrivateTy = Type; 8236 if (OASE || 8237 (!ASE && 8238 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 8239 // For arays/array sections only: 8240 // Create pseudo array type for private copy. The size for this array will 8241 // be generated during codegen. 8242 // For array subscripts or single variables Private Ty is the same as Type 8243 // (type of the variable or single array element). 8244 PrivateTy = Context.getVariableArrayType( 8245 Type, new (Context) OpaqueValueExpr(SourceLocation(), 8246 Context.getSizeType(), VK_RValue), 8247 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 8248 } else if (!ASE && !OASE && 8249 Context.getAsArrayType(D->getType().getNonReferenceType())) 8250 PrivateTy = D->getType().getNonReferenceType(); 8251 // Private copy. 8252 auto *PrivateVD = buildVarDecl(*this, ELoc, PrivateTy, D->getName(), 8253 D->hasAttrs() ? &D->getAttrs() : nullptr); 8254 // Add initializer for private variable. 8255 Expr *Init = nullptr; 8256 auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc); 8257 auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc); 8258 if (DeclareReductionRef.isUsable()) { 8259 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 8260 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 8261 if (DRD->getInitializer()) { 8262 Init = DRDRef; 8263 RHSVD->setInit(DRDRef); 8264 RHSVD->setInitStyle(VarDecl::CallInit); 8265 } 8266 } else { 8267 switch (BOK) { 8268 case BO_Add: 8269 case BO_Xor: 8270 case BO_Or: 8271 case BO_LOr: 8272 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 8273 if (Type->isScalarType() || Type->isAnyComplexType()) 8274 Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 8275 break; 8276 case BO_Mul: 8277 case BO_LAnd: 8278 if (Type->isScalarType() || Type->isAnyComplexType()) { 8279 // '*' and '&&' reduction ops - initializer is '1'. 8280 Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 8281 } 8282 break; 8283 case BO_And: { 8284 // '&' reduction op - initializer is '~0'. 8285 QualType OrigType = Type; 8286 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 8287 Type = ComplexTy->getElementType(); 8288 if (Type->isRealFloatingType()) { 8289 llvm::APFloat InitValue = 8290 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 8291 /*isIEEE=*/true); 8292 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 8293 Type, ELoc); 8294 } else if (Type->isScalarType()) { 8295 auto Size = Context.getTypeSize(Type); 8296 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 8297 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 8298 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 8299 } 8300 if (Init && OrigType->isAnyComplexType()) { 8301 // Init = 0xFFFF + 0xFFFFi; 8302 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 8303 Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 8304 } 8305 Type = OrigType; 8306 break; 8307 } 8308 case BO_LT: 8309 case BO_GT: { 8310 // 'min' reduction op - initializer is 'Largest representable number in 8311 // the reduction list item type'. 8312 // 'max' reduction op - initializer is 'Least representable number in 8313 // the reduction list item type'. 8314 if (Type->isIntegerType() || Type->isPointerType()) { 8315 bool IsSigned = Type->hasSignedIntegerRepresentation(); 8316 auto Size = Context.getTypeSize(Type); 8317 QualType IntTy = 8318 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 8319 llvm::APInt InitValue = 8320 (BOK != BO_LT) 8321 ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 8322 : llvm::APInt::getMinValue(Size) 8323 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 8324 : llvm::APInt::getMaxValue(Size); 8325 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 8326 if (Type->isPointerType()) { 8327 // Cast to pointer type. 8328 auto CastExpr = BuildCStyleCastExpr( 8329 SourceLocation(), Context.getTrivialTypeSourceInfo(Type, ELoc), 8330 SourceLocation(), Init); 8331 if (CastExpr.isInvalid()) 8332 continue; 8333 Init = CastExpr.get(); 8334 } 8335 } else if (Type->isRealFloatingType()) { 8336 llvm::APFloat InitValue = llvm::APFloat::getLargest( 8337 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 8338 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 8339 Type, ELoc); 8340 } 8341 break; 8342 } 8343 case BO_PtrMemD: 8344 case BO_PtrMemI: 8345 case BO_MulAssign: 8346 case BO_Div: 8347 case BO_Rem: 8348 case BO_Sub: 8349 case BO_Shl: 8350 case BO_Shr: 8351 case BO_LE: 8352 case BO_GE: 8353 case BO_EQ: 8354 case BO_NE: 8355 case BO_AndAssign: 8356 case BO_XorAssign: 8357 case BO_OrAssign: 8358 case BO_Assign: 8359 case BO_AddAssign: 8360 case BO_SubAssign: 8361 case BO_DivAssign: 8362 case BO_RemAssign: 8363 case BO_ShlAssign: 8364 case BO_ShrAssign: 8365 case BO_Comma: 8366 llvm_unreachable("Unexpected reduction operation"); 8367 } 8368 } 8369 if (Init && DeclareReductionRef.isUnset()) { 8370 AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false, 8371 /*TypeMayContainAuto=*/false); 8372 } else if (!Init) 8373 ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false); 8374 if (RHSVD->isInvalidDecl()) 8375 continue; 8376 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 8377 Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type 8378 << ReductionIdRange; 8379 bool IsDecl = 8380 !VD || 8381 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8382 Diag(D->getLocation(), 8383 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8384 << D; 8385 continue; 8386 } 8387 // Store initializer for single element in private copy. Will be used during 8388 // codegen. 8389 PrivateVD->setInit(RHSVD->getInit()); 8390 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 8391 auto *PrivateDRE = buildDeclRefExpr(*this, PrivateVD, PrivateTy, ELoc); 8392 ExprResult ReductionOp; 8393 if (DeclareReductionRef.isUsable()) { 8394 QualType RedTy = DeclareReductionRef.get()->getType(); 8395 QualType PtrRedTy = Context.getPointerType(RedTy); 8396 ExprResult LHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 8397 ExprResult RHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 8398 if (!BasePath.empty()) { 8399 LHS = DefaultLvalueConversion(LHS.get()); 8400 RHS = DefaultLvalueConversion(RHS.get()); 8401 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 8402 CK_UncheckedDerivedToBase, LHS.get(), 8403 &BasePath, LHS.get()->getValueKind()); 8404 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 8405 CK_UncheckedDerivedToBase, RHS.get(), 8406 &BasePath, RHS.get()->getValueKind()); 8407 } 8408 FunctionProtoType::ExtProtoInfo EPI; 8409 QualType Params[] = {PtrRedTy, PtrRedTy}; 8410 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 8411 auto *OVE = new (Context) OpaqueValueExpr( 8412 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 8413 DefaultLvalueConversion(DeclareReductionRef.get()).get()); 8414 Expr *Args[] = {LHS.get(), RHS.get()}; 8415 ReductionOp = new (Context) 8416 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 8417 } else { 8418 ReductionOp = BuildBinOp(DSAStack->getCurScope(), 8419 ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE); 8420 if (ReductionOp.isUsable()) { 8421 if (BOK != BO_LT && BOK != BO_GT) { 8422 ReductionOp = 8423 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 8424 BO_Assign, LHSDRE, ReductionOp.get()); 8425 } else { 8426 auto *ConditionalOp = new (Context) ConditionalOperator( 8427 ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(), 8428 RHSDRE, Type, VK_LValue, OK_Ordinary); 8429 ReductionOp = 8430 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 8431 BO_Assign, LHSDRE, ConditionalOp); 8432 } 8433 ReductionOp = ActOnFinishFullExpr(ReductionOp.get()); 8434 } 8435 if (ReductionOp.isInvalid()) 8436 continue; 8437 } 8438 8439 DeclRefExpr *Ref = nullptr; 8440 Expr *VarsExpr = RefExpr->IgnoreParens(); 8441 if (!VD) { 8442 if (ASE || OASE) { 8443 TransformExprToCaptures RebuildToCapture(*this, D); 8444 VarsExpr = 8445 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 8446 Ref = RebuildToCapture.getCapturedExpr(); 8447 } else { 8448 VarsExpr = Ref = 8449 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 8450 } 8451 if (!IsOpenMPCapturedDecl(D)) { 8452 ExprCaptures.push_back(Ref->getDecl()); 8453 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 8454 ExprResult RefRes = DefaultLvalueConversion(Ref); 8455 if (!RefRes.isUsable()) 8456 continue; 8457 ExprResult PostUpdateRes = 8458 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 8459 SimpleRefExpr, RefRes.get()); 8460 if (!PostUpdateRes.isUsable()) 8461 continue; 8462 ExprPostUpdates.push_back( 8463 IgnoredValueConversions(PostUpdateRes.get()).get()); 8464 } 8465 } 8466 } 8467 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 8468 Vars.push_back(VarsExpr); 8469 Privates.push_back(PrivateDRE); 8470 LHSs.push_back(LHSDRE); 8471 RHSs.push_back(RHSDRE); 8472 ReductionOps.push_back(ReductionOp.get()); 8473 } 8474 8475 if (Vars.empty()) 8476 return nullptr; 8477 8478 return OMPReductionClause::Create( 8479 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars, 8480 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates, 8481 LHSs, RHSs, ReductionOps, buildPreInits(Context, ExprCaptures), 8482 buildPostUpdate(*this, ExprPostUpdates)); 8483 } 8484 8485 OMPClause *Sema::ActOnOpenMPLinearClause( 8486 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 8487 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 8488 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 8489 SmallVector<Expr *, 8> Vars; 8490 SmallVector<Expr *, 8> Privates; 8491 SmallVector<Expr *, 8> Inits; 8492 SmallVector<Decl *, 4> ExprCaptures; 8493 SmallVector<Expr *, 4> ExprPostUpdates; 8494 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 8495 LinKind == OMPC_LINEAR_unknown) { 8496 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 8497 LinKind = OMPC_LINEAR_val; 8498 } 8499 for (auto &RefExpr : VarList) { 8500 assert(RefExpr && "NULL expr in OpenMP linear clause."); 8501 SourceLocation ELoc; 8502 SourceRange ERange; 8503 Expr *SimpleRefExpr = RefExpr; 8504 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 8505 /*AllowArraySection=*/false); 8506 if (Res.second) { 8507 // It will be analyzed later. 8508 Vars.push_back(RefExpr); 8509 Privates.push_back(nullptr); 8510 Inits.push_back(nullptr); 8511 } 8512 ValueDecl *D = Res.first; 8513 if (!D) 8514 continue; 8515 8516 QualType Type = D->getType(); 8517 auto *VD = dyn_cast<VarDecl>(D); 8518 8519 // OpenMP [2.14.3.7, linear clause] 8520 // A list-item cannot appear in more than one linear clause. 8521 // A list-item that appears in a linear clause cannot appear in any 8522 // other data-sharing attribute clause. 8523 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8524 if (DVar.RefExpr) { 8525 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 8526 << getOpenMPClauseName(OMPC_linear); 8527 ReportOriginalDSA(*this, DSAStack, D, DVar); 8528 continue; 8529 } 8530 8531 // A variable must not have an incomplete type or a reference type. 8532 if (RequireCompleteType(ELoc, Type, 8533 diag::err_omp_linear_incomplete_type)) 8534 continue; 8535 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 8536 !Type->isReferenceType()) { 8537 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 8538 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 8539 continue; 8540 } 8541 Type = Type.getNonReferenceType(); 8542 8543 // A list item must not be const-qualified. 8544 if (Type.isConstant(Context)) { 8545 Diag(ELoc, diag::err_omp_const_variable) 8546 << getOpenMPClauseName(OMPC_linear); 8547 bool IsDecl = 8548 !VD || 8549 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8550 Diag(D->getLocation(), 8551 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8552 << D; 8553 continue; 8554 } 8555 8556 // A list item must be of integral or pointer type. 8557 Type = Type.getUnqualifiedType().getCanonicalType(); 8558 const auto *Ty = Type.getTypePtrOrNull(); 8559 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 8560 !Ty->isPointerType())) { 8561 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 8562 bool IsDecl = 8563 !VD || 8564 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8565 Diag(D->getLocation(), 8566 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8567 << D; 8568 continue; 8569 } 8570 8571 // Build private copy of original var. 8572 auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(), 8573 D->hasAttrs() ? &D->getAttrs() : nullptr); 8574 auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 8575 // Build var to save initial value. 8576 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 8577 Expr *InitExpr; 8578 DeclRefExpr *Ref = nullptr; 8579 if (!VD) { 8580 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 8581 if (!IsOpenMPCapturedDecl(D)) { 8582 ExprCaptures.push_back(Ref->getDecl()); 8583 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 8584 ExprResult RefRes = DefaultLvalueConversion(Ref); 8585 if (!RefRes.isUsable()) 8586 continue; 8587 ExprResult PostUpdateRes = 8588 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 8589 SimpleRefExpr, RefRes.get()); 8590 if (!PostUpdateRes.isUsable()) 8591 continue; 8592 ExprPostUpdates.push_back( 8593 IgnoredValueConversions(PostUpdateRes.get()).get()); 8594 } 8595 } 8596 } 8597 if (LinKind == OMPC_LINEAR_uval) 8598 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 8599 else 8600 InitExpr = VD ? SimpleRefExpr : Ref; 8601 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 8602 /*DirectInit=*/false, /*TypeMayContainAuto=*/false); 8603 auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 8604 8605 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 8606 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 8607 Privates.push_back(PrivateRef); 8608 Inits.push_back(InitRef); 8609 } 8610 8611 if (Vars.empty()) 8612 return nullptr; 8613 8614 Expr *StepExpr = Step; 8615 Expr *CalcStepExpr = nullptr; 8616 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 8617 !Step->isInstantiationDependent() && 8618 !Step->containsUnexpandedParameterPack()) { 8619 SourceLocation StepLoc = Step->getLocStart(); 8620 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 8621 if (Val.isInvalid()) 8622 return nullptr; 8623 StepExpr = Val.get(); 8624 8625 // Build var to save the step value. 8626 VarDecl *SaveVar = 8627 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 8628 ExprResult SaveRef = 8629 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 8630 ExprResult CalcStep = 8631 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 8632 CalcStep = ActOnFinishFullExpr(CalcStep.get()); 8633 8634 // Warn about zero linear step (it would be probably better specified as 8635 // making corresponding variables 'const'). 8636 llvm::APSInt Result; 8637 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 8638 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 8639 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 8640 << (Vars.size() > 1); 8641 if (!IsConstant && CalcStep.isUsable()) { 8642 // Calculate the step beforehand instead of doing this on each iteration. 8643 // (This is not used if the number of iterations may be kfold-ed). 8644 CalcStepExpr = CalcStep.get(); 8645 } 8646 } 8647 8648 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 8649 ColonLoc, EndLoc, Vars, Privates, Inits, 8650 StepExpr, CalcStepExpr, 8651 buildPreInits(Context, ExprCaptures), 8652 buildPostUpdate(*this, ExprPostUpdates)); 8653 } 8654 8655 static bool 8656 FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 8657 Expr *NumIterations, Sema &SemaRef, Scope *S) { 8658 // Walk the vars and build update/final expressions for the CodeGen. 8659 SmallVector<Expr *, 8> Updates; 8660 SmallVector<Expr *, 8> Finals; 8661 Expr *Step = Clause.getStep(); 8662 Expr *CalcStep = Clause.getCalcStep(); 8663 // OpenMP [2.14.3.7, linear clause] 8664 // If linear-step is not specified it is assumed to be 1. 8665 if (Step == nullptr) 8666 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 8667 else if (CalcStep) { 8668 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 8669 } 8670 bool HasErrors = false; 8671 auto CurInit = Clause.inits().begin(); 8672 auto CurPrivate = Clause.privates().begin(); 8673 auto LinKind = Clause.getModifier(); 8674 for (auto &RefExpr : Clause.varlists()) { 8675 Expr *InitExpr = *CurInit; 8676 8677 // Build privatized reference to the current linear var. 8678 auto DE = cast<DeclRefExpr>(RefExpr); 8679 Expr *CapturedRef; 8680 if (LinKind == OMPC_LINEAR_uval) 8681 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 8682 else 8683 CapturedRef = 8684 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 8685 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 8686 /*RefersToCapture=*/true); 8687 8688 // Build update: Var = InitExpr + IV * Step 8689 ExprResult Update = 8690 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 8691 InitExpr, IV, Step, /* Subtract */ false); 8692 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(), 8693 /*DiscardedValue=*/true); 8694 8695 // Build final: Var = InitExpr + NumIterations * Step 8696 ExprResult Final = 8697 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 8698 InitExpr, NumIterations, Step, /* Subtract */ false); 8699 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(), 8700 /*DiscardedValue=*/true); 8701 if (!Update.isUsable() || !Final.isUsable()) { 8702 Updates.push_back(nullptr); 8703 Finals.push_back(nullptr); 8704 HasErrors = true; 8705 } else { 8706 Updates.push_back(Update.get()); 8707 Finals.push_back(Final.get()); 8708 } 8709 ++CurInit; 8710 ++CurPrivate; 8711 } 8712 Clause.setUpdates(Updates); 8713 Clause.setFinals(Finals); 8714 return HasErrors; 8715 } 8716 8717 OMPClause *Sema::ActOnOpenMPAlignedClause( 8718 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 8719 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 8720 8721 SmallVector<Expr *, 8> Vars; 8722 for (auto &RefExpr : VarList) { 8723 assert(RefExpr && "NULL expr in OpenMP linear clause."); 8724 SourceLocation ELoc; 8725 SourceRange ERange; 8726 Expr *SimpleRefExpr = RefExpr; 8727 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 8728 /*AllowArraySection=*/false); 8729 if (Res.second) { 8730 // It will be analyzed later. 8731 Vars.push_back(RefExpr); 8732 } 8733 ValueDecl *D = Res.first; 8734 if (!D) 8735 continue; 8736 8737 QualType QType = D->getType(); 8738 auto *VD = dyn_cast<VarDecl>(D); 8739 8740 // OpenMP [2.8.1, simd construct, Restrictions] 8741 // The type of list items appearing in the aligned clause must be 8742 // array, pointer, reference to array, or reference to pointer. 8743 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 8744 const Type *Ty = QType.getTypePtrOrNull(); 8745 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 8746 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 8747 << QType << getLangOpts().CPlusPlus << ERange; 8748 bool IsDecl = 8749 !VD || 8750 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8751 Diag(D->getLocation(), 8752 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8753 << D; 8754 continue; 8755 } 8756 8757 // OpenMP [2.8.1, simd construct, Restrictions] 8758 // A list-item cannot appear in more than one aligned clause. 8759 if (Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 8760 Diag(ELoc, diag::err_omp_aligned_twice) << ERange; 8761 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 8762 << getOpenMPClauseName(OMPC_aligned); 8763 continue; 8764 } 8765 8766 DeclRefExpr *Ref = nullptr; 8767 if (!VD && IsOpenMPCapturedDecl(D)) 8768 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 8769 Vars.push_back(DefaultFunctionArrayConversion( 8770 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 8771 .get()); 8772 } 8773 8774 // OpenMP [2.8.1, simd construct, Description] 8775 // The parameter of the aligned clause, alignment, must be a constant 8776 // positive integer expression. 8777 // If no optional parameter is specified, implementation-defined default 8778 // alignments for SIMD instructions on the target platforms are assumed. 8779 if (Alignment != nullptr) { 8780 ExprResult AlignResult = 8781 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 8782 if (AlignResult.isInvalid()) 8783 return nullptr; 8784 Alignment = AlignResult.get(); 8785 } 8786 if (Vars.empty()) 8787 return nullptr; 8788 8789 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 8790 EndLoc, Vars, Alignment); 8791 } 8792 8793 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 8794 SourceLocation StartLoc, 8795 SourceLocation LParenLoc, 8796 SourceLocation EndLoc) { 8797 SmallVector<Expr *, 8> Vars; 8798 SmallVector<Expr *, 8> SrcExprs; 8799 SmallVector<Expr *, 8> DstExprs; 8800 SmallVector<Expr *, 8> AssignmentOps; 8801 for (auto &RefExpr : VarList) { 8802 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 8803 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 8804 // It will be analyzed later. 8805 Vars.push_back(RefExpr); 8806 SrcExprs.push_back(nullptr); 8807 DstExprs.push_back(nullptr); 8808 AssignmentOps.push_back(nullptr); 8809 continue; 8810 } 8811 8812 SourceLocation ELoc = RefExpr->getExprLoc(); 8813 // OpenMP [2.1, C/C++] 8814 // A list item is a variable name. 8815 // OpenMP [2.14.4.1, Restrictions, p.1] 8816 // A list item that appears in a copyin clause must be threadprivate. 8817 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 8818 if (!DE || !isa<VarDecl>(DE->getDecl())) { 8819 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 8820 << 0 << RefExpr->getSourceRange(); 8821 continue; 8822 } 8823 8824 Decl *D = DE->getDecl(); 8825 VarDecl *VD = cast<VarDecl>(D); 8826 8827 QualType Type = VD->getType(); 8828 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 8829 // It will be analyzed later. 8830 Vars.push_back(DE); 8831 SrcExprs.push_back(nullptr); 8832 DstExprs.push_back(nullptr); 8833 AssignmentOps.push_back(nullptr); 8834 continue; 8835 } 8836 8837 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 8838 // A list item that appears in a copyin clause must be threadprivate. 8839 if (!DSAStack->isThreadPrivate(VD)) { 8840 Diag(ELoc, diag::err_omp_required_access) 8841 << getOpenMPClauseName(OMPC_copyin) 8842 << getOpenMPDirectiveName(OMPD_threadprivate); 8843 continue; 8844 } 8845 8846 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 8847 // A variable of class type (or array thereof) that appears in a 8848 // copyin clause requires an accessible, unambiguous copy assignment 8849 // operator for the class type. 8850 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 8851 auto *SrcVD = 8852 buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(), 8853 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 8854 auto *PseudoSrcExpr = buildDeclRefExpr( 8855 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 8856 auto *DstVD = 8857 buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst", 8858 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 8859 auto *PseudoDstExpr = 8860 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 8861 // For arrays generate assignment operation for single element and replace 8862 // it by the original array element in CodeGen. 8863 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 8864 PseudoDstExpr, PseudoSrcExpr); 8865 if (AssignmentOp.isInvalid()) 8866 continue; 8867 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 8868 /*DiscardedValue=*/true); 8869 if (AssignmentOp.isInvalid()) 8870 continue; 8871 8872 DSAStack->addDSA(VD, DE, OMPC_copyin); 8873 Vars.push_back(DE); 8874 SrcExprs.push_back(PseudoSrcExpr); 8875 DstExprs.push_back(PseudoDstExpr); 8876 AssignmentOps.push_back(AssignmentOp.get()); 8877 } 8878 8879 if (Vars.empty()) 8880 return nullptr; 8881 8882 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 8883 SrcExprs, DstExprs, AssignmentOps); 8884 } 8885 8886 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 8887 SourceLocation StartLoc, 8888 SourceLocation LParenLoc, 8889 SourceLocation EndLoc) { 8890 SmallVector<Expr *, 8> Vars; 8891 SmallVector<Expr *, 8> SrcExprs; 8892 SmallVector<Expr *, 8> DstExprs; 8893 SmallVector<Expr *, 8> AssignmentOps; 8894 for (auto &RefExpr : VarList) { 8895 assert(RefExpr && "NULL expr in OpenMP linear clause."); 8896 SourceLocation ELoc; 8897 SourceRange ERange; 8898 Expr *SimpleRefExpr = RefExpr; 8899 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 8900 /*AllowArraySection=*/false); 8901 if (Res.second) { 8902 // It will be analyzed later. 8903 Vars.push_back(RefExpr); 8904 SrcExprs.push_back(nullptr); 8905 DstExprs.push_back(nullptr); 8906 AssignmentOps.push_back(nullptr); 8907 } 8908 ValueDecl *D = Res.first; 8909 if (!D) 8910 continue; 8911 8912 QualType Type = D->getType(); 8913 auto *VD = dyn_cast<VarDecl>(D); 8914 8915 // OpenMP [2.14.4.2, Restrictions, p.2] 8916 // A list item that appears in a copyprivate clause may not appear in a 8917 // private or firstprivate clause on the single construct. 8918 if (!VD || !DSAStack->isThreadPrivate(VD)) { 8919 auto DVar = DSAStack->getTopDSA(D, false); 8920 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 8921 DVar.RefExpr) { 8922 Diag(ELoc, diag::err_omp_wrong_dsa) 8923 << getOpenMPClauseName(DVar.CKind) 8924 << getOpenMPClauseName(OMPC_copyprivate); 8925 ReportOriginalDSA(*this, DSAStack, D, DVar); 8926 continue; 8927 } 8928 8929 // OpenMP [2.11.4.2, Restrictions, p.1] 8930 // All list items that appear in a copyprivate clause must be either 8931 // threadprivate or private in the enclosing context. 8932 if (DVar.CKind == OMPC_unknown) { 8933 DVar = DSAStack->getImplicitDSA(D, false); 8934 if (DVar.CKind == OMPC_shared) { 8935 Diag(ELoc, diag::err_omp_required_access) 8936 << getOpenMPClauseName(OMPC_copyprivate) 8937 << "threadprivate or private in the enclosing context"; 8938 ReportOriginalDSA(*this, DSAStack, D, DVar); 8939 continue; 8940 } 8941 } 8942 } 8943 8944 // Variably modified types are not supported. 8945 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 8946 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 8947 << getOpenMPClauseName(OMPC_copyprivate) << Type 8948 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 8949 bool IsDecl = 8950 !VD || 8951 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8952 Diag(D->getLocation(), 8953 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8954 << D; 8955 continue; 8956 } 8957 8958 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 8959 // A variable of class type (or array thereof) that appears in a 8960 // copyin clause requires an accessible, unambiguous copy assignment 8961 // operator for the class type. 8962 Type = Context.getBaseElementType(Type.getNonReferenceType()) 8963 .getUnqualifiedType(); 8964 auto *SrcVD = 8965 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src", 8966 D->hasAttrs() ? &D->getAttrs() : nullptr); 8967 auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 8968 auto *DstVD = 8969 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst", 8970 D->hasAttrs() ? &D->getAttrs() : nullptr); 8971 auto *PseudoDstExpr = 8972 buildDeclRefExpr(*this, DstVD, Type, ELoc); 8973 auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 8974 PseudoDstExpr, PseudoSrcExpr); 8975 if (AssignmentOp.isInvalid()) 8976 continue; 8977 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 8978 /*DiscardedValue=*/true); 8979 if (AssignmentOp.isInvalid()) 8980 continue; 8981 8982 // No need to mark vars as copyprivate, they are already threadprivate or 8983 // implicitly private. 8984 assert(VD || IsOpenMPCapturedDecl(D)); 8985 Vars.push_back( 8986 VD ? RefExpr->IgnoreParens() 8987 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 8988 SrcExprs.push_back(PseudoSrcExpr); 8989 DstExprs.push_back(PseudoDstExpr); 8990 AssignmentOps.push_back(AssignmentOp.get()); 8991 } 8992 8993 if (Vars.empty()) 8994 return nullptr; 8995 8996 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 8997 Vars, SrcExprs, DstExprs, AssignmentOps); 8998 } 8999 9000 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 9001 SourceLocation StartLoc, 9002 SourceLocation LParenLoc, 9003 SourceLocation EndLoc) { 9004 if (VarList.empty()) 9005 return nullptr; 9006 9007 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 9008 } 9009 9010 OMPClause * 9011 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 9012 SourceLocation DepLoc, SourceLocation ColonLoc, 9013 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 9014 SourceLocation LParenLoc, SourceLocation EndLoc) { 9015 if (DSAStack->getCurrentDirective() == OMPD_ordered && 9016 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 9017 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 9018 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 9019 return nullptr; 9020 } 9021 if (DSAStack->getCurrentDirective() != OMPD_ordered && 9022 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 9023 DepKind == OMPC_DEPEND_sink)) { 9024 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 9025 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 9026 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 9027 /*Last=*/OMPC_DEPEND_unknown, Except) 9028 << getOpenMPClauseName(OMPC_depend); 9029 return nullptr; 9030 } 9031 SmallVector<Expr *, 8> Vars; 9032 llvm::APSInt DepCounter(/*BitWidth=*/32); 9033 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 9034 if (DepKind == OMPC_DEPEND_sink) { 9035 if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) { 9036 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 9037 TotalDepCount.setIsUnsigned(/*Val=*/true); 9038 } 9039 } 9040 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) || 9041 DSAStack->getParentOrderedRegionParam()) { 9042 for (auto &RefExpr : VarList) { 9043 assert(RefExpr && "NULL expr in OpenMP shared clause."); 9044 if (isa<DependentScopeDeclRefExpr>(RefExpr) || 9045 (DepKind == OMPC_DEPEND_sink && CurContext->isDependentContext())) { 9046 // It will be analyzed later. 9047 Vars.push_back(RefExpr); 9048 continue; 9049 } 9050 9051 SourceLocation ELoc = RefExpr->getExprLoc(); 9052 auto *SimpleExpr = RefExpr->IgnoreParenCasts(); 9053 if (DepKind == OMPC_DEPEND_sink) { 9054 if (DepCounter >= TotalDepCount) { 9055 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 9056 continue; 9057 } 9058 ++DepCounter; 9059 // OpenMP [2.13.9, Summary] 9060 // depend(dependence-type : vec), where dependence-type is: 9061 // 'sink' and where vec is the iteration vector, which has the form: 9062 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 9063 // where n is the value specified by the ordered clause in the loop 9064 // directive, xi denotes the loop iteration variable of the i-th nested 9065 // loop associated with the loop directive, and di is a constant 9066 // non-negative integer. 9067 SimpleExpr = SimpleExpr->IgnoreImplicit(); 9068 auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr); 9069 if (!DE) { 9070 OverloadedOperatorKind OOK = OO_None; 9071 SourceLocation OOLoc; 9072 Expr *LHS, *RHS; 9073 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 9074 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 9075 OOLoc = BO->getOperatorLoc(); 9076 LHS = BO->getLHS()->IgnoreParenImpCasts(); 9077 RHS = BO->getRHS()->IgnoreParenImpCasts(); 9078 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 9079 OOK = OCE->getOperator(); 9080 OOLoc = OCE->getOperatorLoc(); 9081 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 9082 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 9083 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 9084 OOK = MCE->getMethodDecl() 9085 ->getNameInfo() 9086 .getName() 9087 .getCXXOverloadedOperator(); 9088 OOLoc = MCE->getCallee()->getExprLoc(); 9089 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 9090 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 9091 } else { 9092 Diag(ELoc, diag::err_omp_depend_sink_wrong_expr); 9093 continue; 9094 } 9095 DE = dyn_cast<DeclRefExpr>(LHS); 9096 if (!DE) { 9097 Diag(LHS->getExprLoc(), 9098 diag::err_omp_depend_sink_expected_loop_iteration) 9099 << DSAStack->getParentLoopControlVariable( 9100 DepCounter.getZExtValue()); 9101 continue; 9102 } 9103 if (OOK != OO_Plus && OOK != OO_Minus) { 9104 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 9105 continue; 9106 } 9107 ExprResult Res = VerifyPositiveIntegerConstantInClause( 9108 RHS, OMPC_depend, /*StrictlyPositive=*/false); 9109 if (Res.isInvalid()) 9110 continue; 9111 } 9112 auto *VD = dyn_cast<VarDecl>(DE->getDecl()); 9113 if (!CurContext->isDependentContext() && 9114 DSAStack->getParentOrderedRegionParam() && 9115 (!VD || DepCounter != DSAStack->isParentLoopControlVariable(VD))) { 9116 Diag(DE->getExprLoc(), 9117 diag::err_omp_depend_sink_expected_loop_iteration) 9118 << DSAStack->getParentLoopControlVariable( 9119 DepCounter.getZExtValue()); 9120 continue; 9121 } 9122 } else { 9123 // OpenMP [2.11.1.1, Restrictions, p.3] 9124 // A variable that is part of another variable (such as a field of a 9125 // structure) but is not an array element or an array section cannot 9126 // appear in a depend clause. 9127 auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr); 9128 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 9129 auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 9130 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 9131 (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) || 9132 (ASE && 9133 !ASE->getBase() 9134 ->getType() 9135 .getNonReferenceType() 9136 ->isPointerType() && 9137 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 9138 Diag(ELoc, diag::err_omp_expected_var_name_member_expr_or_array_item) 9139 << 0 << RefExpr->getSourceRange(); 9140 continue; 9141 } 9142 } 9143 9144 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 9145 } 9146 9147 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 9148 TotalDepCount > VarList.size() && 9149 DSAStack->getParentOrderedRegionParam()) { 9150 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 9151 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 9152 } 9153 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 9154 Vars.empty()) 9155 return nullptr; 9156 } 9157 9158 return OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, DepKind, 9159 DepLoc, ColonLoc, Vars); 9160 } 9161 9162 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 9163 SourceLocation LParenLoc, 9164 SourceLocation EndLoc) { 9165 Expr *ValExpr = Device; 9166 9167 // OpenMP [2.9.1, Restrictions] 9168 // The device expression must evaluate to a non-negative integer value. 9169 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 9170 /*StrictlyPositive=*/false)) 9171 return nullptr; 9172 9173 return new (Context) OMPDeviceClause(ValExpr, StartLoc, LParenLoc, EndLoc); 9174 } 9175 9176 static bool IsCXXRecordForMappable(Sema &SemaRef, SourceLocation Loc, 9177 DSAStackTy *Stack, CXXRecordDecl *RD) { 9178 if (!RD || RD->isInvalidDecl()) 9179 return true; 9180 9181 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) 9182 if (auto *CTD = CTSD->getSpecializedTemplate()) 9183 RD = CTD->getTemplatedDecl(); 9184 auto QTy = SemaRef.Context.getRecordType(RD); 9185 if (RD->isDynamicClass()) { 9186 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 9187 SemaRef.Diag(RD->getLocation(), diag::note_omp_polymorphic_in_target); 9188 return false; 9189 } 9190 auto *DC = RD; 9191 bool IsCorrect = true; 9192 for (auto *I : DC->decls()) { 9193 if (I) { 9194 if (auto *MD = dyn_cast<CXXMethodDecl>(I)) { 9195 if (MD->isStatic()) { 9196 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 9197 SemaRef.Diag(MD->getLocation(), 9198 diag::note_omp_static_member_in_target); 9199 IsCorrect = false; 9200 } 9201 } else if (auto *VD = dyn_cast<VarDecl>(I)) { 9202 if (VD->isStaticDataMember()) { 9203 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 9204 SemaRef.Diag(VD->getLocation(), 9205 diag::note_omp_static_member_in_target); 9206 IsCorrect = false; 9207 } 9208 } 9209 } 9210 } 9211 9212 for (auto &I : RD->bases()) { 9213 if (!IsCXXRecordForMappable(SemaRef, I.getLocStart(), Stack, 9214 I.getType()->getAsCXXRecordDecl())) 9215 IsCorrect = false; 9216 } 9217 return IsCorrect; 9218 } 9219 9220 static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 9221 DSAStackTy *Stack, QualType QTy) { 9222 NamedDecl *ND; 9223 if (QTy->isIncompleteType(&ND)) { 9224 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 9225 return false; 9226 } else if (CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(ND)) { 9227 if (!RD->isInvalidDecl() && 9228 !IsCXXRecordForMappable(SemaRef, SL, Stack, RD)) 9229 return false; 9230 } 9231 return true; 9232 } 9233 9234 /// \brief Return true if it can be proven that the provided array expression 9235 /// (array section or array subscript) does NOT specify the whole size of the 9236 /// array whose base type is \a BaseQTy. 9237 static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 9238 const Expr *E, 9239 QualType BaseQTy) { 9240 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 9241 9242 // If this is an array subscript, it refers to the whole size if the size of 9243 // the dimension is constant and equals 1. Also, an array section assumes the 9244 // format of an array subscript if no colon is used. 9245 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 9246 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 9247 return ATy->getSize().getSExtValue() != 1; 9248 // Size can't be evaluated statically. 9249 return false; 9250 } 9251 9252 assert(OASE && "Expecting array section if not an array subscript."); 9253 auto *LowerBound = OASE->getLowerBound(); 9254 auto *Length = OASE->getLength(); 9255 9256 // If there is a lower bound that does not evaluates to zero, we are not 9257 // convering the whole dimension. 9258 if (LowerBound) { 9259 llvm::APSInt ConstLowerBound; 9260 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) 9261 return false; // Can't get the integer value as a constant. 9262 if (ConstLowerBound.getSExtValue()) 9263 return true; 9264 } 9265 9266 // If we don't have a length we covering the whole dimension. 9267 if (!Length) 9268 return false; 9269 9270 // If the base is a pointer, we don't have a way to get the size of the 9271 // pointee. 9272 if (BaseQTy->isPointerType()) 9273 return false; 9274 9275 // We can only check if the length is the same as the size of the dimension 9276 // if we have a constant array. 9277 auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 9278 if (!CATy) 9279 return false; 9280 9281 llvm::APSInt ConstLength; 9282 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 9283 return false; // Can't get the integer value as a constant. 9284 9285 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 9286 } 9287 9288 // Return true if it can be proven that the provided array expression (array 9289 // section or array subscript) does NOT specify a single element of the array 9290 // whose base type is \a BaseQTy. 9291 static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 9292 const Expr *E, 9293 QualType BaseQTy) { 9294 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 9295 9296 // An array subscript always refer to a single element. Also, an array section 9297 // assumes the format of an array subscript if no colon is used. 9298 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 9299 return false; 9300 9301 assert(OASE && "Expecting array section if not an array subscript."); 9302 auto *Length = OASE->getLength(); 9303 9304 // If we don't have a length we have to check if the array has unitary size 9305 // for this dimension. Also, we should always expect a length if the base type 9306 // is pointer. 9307 if (!Length) { 9308 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 9309 return ATy->getSize().getSExtValue() != 1; 9310 // We cannot assume anything. 9311 return false; 9312 } 9313 9314 // Check if the length evaluates to 1. 9315 llvm::APSInt ConstLength; 9316 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 9317 return false; // Can't get the integer value as a constant. 9318 9319 return ConstLength.getSExtValue() != 1; 9320 } 9321 9322 // Return the expression of the base of the map clause or null if it cannot 9323 // be determined and do all the necessary checks to see if the expression is 9324 // valid as a standalone map clause expression. 9325 static Expr *CheckMapClauseExpressionBase(Sema &SemaRef, Expr *E) { 9326 SourceLocation ELoc = E->getExprLoc(); 9327 SourceRange ERange = E->getSourceRange(); 9328 9329 // The base of elements of list in a map clause have to be either: 9330 // - a reference to variable or field. 9331 // - a member expression. 9332 // - an array expression. 9333 // 9334 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 9335 // reference to 'r'. 9336 // 9337 // If we have: 9338 // 9339 // struct SS { 9340 // Bla S; 9341 // foo() { 9342 // #pragma omp target map (S.Arr[:12]); 9343 // } 9344 // } 9345 // 9346 // We want to retrieve the member expression 'this->S'; 9347 9348 Expr *RelevantExpr = nullptr; 9349 9350 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 9351 // If a list item is an array section, it must specify contiguous storage. 9352 // 9353 // For this restriction it is sufficient that we make sure only references 9354 // to variables or fields and array expressions, and that no array sections 9355 // exist except in the rightmost expression (unless they cover the whole 9356 // dimension of the array). E.g. these would be invalid: 9357 // 9358 // r.ArrS[3:5].Arr[6:7] 9359 // 9360 // r.ArrS[3:5].x 9361 // 9362 // but these would be valid: 9363 // r.ArrS[3].Arr[6:7] 9364 // 9365 // r.ArrS[3].x 9366 9367 bool AllowUnitySizeArraySection = true; 9368 bool AllowWholeSizeArraySection = true; 9369 9370 while (!RelevantExpr) { 9371 E = E->IgnoreParenImpCasts(); 9372 9373 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 9374 if (!isa<VarDecl>(CurE->getDecl())) 9375 break; 9376 9377 RelevantExpr = CurE; 9378 9379 // If we got a reference to a declaration, we should not expect any array 9380 // section before that. 9381 AllowUnitySizeArraySection = false; 9382 AllowWholeSizeArraySection = false; 9383 continue; 9384 } 9385 9386 if (auto *CurE = dyn_cast<MemberExpr>(E)) { 9387 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 9388 9389 if (isa<CXXThisExpr>(BaseE)) 9390 // We found a base expression: this->Val. 9391 RelevantExpr = CurE; 9392 else 9393 E = BaseE; 9394 9395 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 9396 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 9397 << CurE->getSourceRange(); 9398 break; 9399 } 9400 9401 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 9402 9403 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 9404 // A bit-field cannot appear in a map clause. 9405 // 9406 if (FD->isBitField()) { 9407 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_map_clause) 9408 << CurE->getSourceRange(); 9409 break; 9410 } 9411 9412 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 9413 // If the type of a list item is a reference to a type T then the type 9414 // will be considered to be T for all purposes of this clause. 9415 QualType CurType = BaseE->getType().getNonReferenceType(); 9416 9417 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 9418 // A list item cannot be a variable that is a member of a structure with 9419 // a union type. 9420 // 9421 if (auto *RT = CurType->getAs<RecordType>()) 9422 if (RT->isUnionType()) { 9423 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 9424 << CurE->getSourceRange(); 9425 break; 9426 } 9427 9428 // If we got a member expression, we should not expect any array section 9429 // before that: 9430 // 9431 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 9432 // If a list item is an element of a structure, only the rightmost symbol 9433 // of the variable reference can be an array section. 9434 // 9435 AllowUnitySizeArraySection = false; 9436 AllowWholeSizeArraySection = false; 9437 continue; 9438 } 9439 9440 if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 9441 E = CurE->getBase()->IgnoreParenImpCasts(); 9442 9443 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 9444 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 9445 << 0 << CurE->getSourceRange(); 9446 break; 9447 } 9448 9449 // If we got an array subscript that express the whole dimension we 9450 // can have any array expressions before. If it only expressing part of 9451 // the dimension, we can only have unitary-size array expressions. 9452 if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 9453 E->getType())) 9454 AllowWholeSizeArraySection = false; 9455 continue; 9456 } 9457 9458 if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 9459 E = CurE->getBase()->IgnoreParenImpCasts(); 9460 9461 auto CurType = 9462 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 9463 9464 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 9465 // If the type of a list item is a reference to a type T then the type 9466 // will be considered to be T for all purposes of this clause. 9467 if (CurType->isReferenceType()) 9468 CurType = CurType->getPointeeType(); 9469 9470 bool IsPointer = CurType->isAnyPointerType(); 9471 9472 if (!IsPointer && !CurType->isArrayType()) { 9473 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 9474 << 0 << CurE->getSourceRange(); 9475 break; 9476 } 9477 9478 bool NotWhole = 9479 CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 9480 bool NotUnity = 9481 CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 9482 9483 if (AllowWholeSizeArraySection && AllowUnitySizeArraySection) { 9484 // Any array section is currently allowed. 9485 // 9486 // If this array section refers to the whole dimension we can still 9487 // accept other array sections before this one, except if the base is a 9488 // pointer. Otherwise, only unitary sections are accepted. 9489 if (NotWhole || IsPointer) 9490 AllowWholeSizeArraySection = false; 9491 } else if ((AllowUnitySizeArraySection && NotUnity) || 9492 (AllowWholeSizeArraySection && NotWhole)) { 9493 // A unity or whole array section is not allowed and that is not 9494 // compatible with the properties of the current array section. 9495 SemaRef.Diag( 9496 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 9497 << CurE->getSourceRange(); 9498 break; 9499 } 9500 continue; 9501 } 9502 9503 // If nothing else worked, this is not a valid map clause expression. 9504 SemaRef.Diag(ELoc, 9505 diag::err_omp_expected_named_var_member_or_array_expression) 9506 << ERange; 9507 break; 9508 } 9509 9510 return RelevantExpr; 9511 } 9512 9513 // Return true if expression E associated with value VD has conflicts with other 9514 // map information. 9515 static bool CheckMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, 9516 Expr *E, bool CurrentRegionOnly) { 9517 assert(VD && E); 9518 9519 // Types used to organize the components of a valid map clause. 9520 typedef std::pair<Expr *, ValueDecl *> MapExpressionComponent; 9521 typedef SmallVector<MapExpressionComponent, 4> MapExpressionComponents; 9522 9523 // Helper to extract the components in the map clause expression E and store 9524 // them into MEC. This assumes that E is a valid map clause expression, i.e. 9525 // it has already passed the single clause checks. 9526 auto ExtractMapExpressionComponents = [](Expr *TE, 9527 MapExpressionComponents &MEC) { 9528 while (true) { 9529 TE = TE->IgnoreParenImpCasts(); 9530 9531 if (auto *CurE = dyn_cast<DeclRefExpr>(TE)) { 9532 MEC.push_back( 9533 MapExpressionComponent(CurE, cast<VarDecl>(CurE->getDecl()))); 9534 break; 9535 } 9536 9537 if (auto *CurE = dyn_cast<MemberExpr>(TE)) { 9538 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 9539 9540 MEC.push_back(MapExpressionComponent( 9541 CurE, cast<FieldDecl>(CurE->getMemberDecl()))); 9542 if (isa<CXXThisExpr>(BaseE)) 9543 break; 9544 9545 TE = BaseE; 9546 continue; 9547 } 9548 9549 if (auto *CurE = dyn_cast<ArraySubscriptExpr>(TE)) { 9550 MEC.push_back(MapExpressionComponent(CurE, nullptr)); 9551 TE = CurE->getBase()->IgnoreParenImpCasts(); 9552 continue; 9553 } 9554 9555 if (auto *CurE = dyn_cast<OMPArraySectionExpr>(TE)) { 9556 MEC.push_back(MapExpressionComponent(CurE, nullptr)); 9557 TE = CurE->getBase()->IgnoreParenImpCasts(); 9558 continue; 9559 } 9560 9561 llvm_unreachable( 9562 "Expecting only valid map clause expressions at this point!"); 9563 } 9564 }; 9565 9566 SourceLocation ELoc = E->getExprLoc(); 9567 SourceRange ERange = E->getSourceRange(); 9568 9569 // In order to easily check the conflicts we need to match each component of 9570 // the expression under test with the components of the expressions that are 9571 // already in the stack. 9572 9573 MapExpressionComponents CurComponents; 9574 ExtractMapExpressionComponents(E, CurComponents); 9575 9576 assert(!CurComponents.empty() && "Map clause expression with no components!"); 9577 assert(CurComponents.back().second == VD && 9578 "Map clause expression with unexpected base!"); 9579 9580 // Variables to help detecting enclosing problems in data environment nests. 9581 bool IsEnclosedByDataEnvironmentExpr = false; 9582 Expr *EnclosingExpr = nullptr; 9583 9584 bool FoundError = 9585 DSAS->checkMapInfoForVar(VD, CurrentRegionOnly, [&](Expr *RE) -> bool { 9586 MapExpressionComponents StackComponents; 9587 ExtractMapExpressionComponents(RE, StackComponents); 9588 assert(!StackComponents.empty() && 9589 "Map clause expression with no components!"); 9590 assert(StackComponents.back().second == VD && 9591 "Map clause expression with unexpected base!"); 9592 9593 // Expressions must start from the same base. Here we detect at which 9594 // point both expressions diverge from each other and see if we can 9595 // detect if the memory referred to both expressions is contiguous and 9596 // do not overlap. 9597 auto CI = CurComponents.rbegin(); 9598 auto CE = CurComponents.rend(); 9599 auto SI = StackComponents.rbegin(); 9600 auto SE = StackComponents.rend(); 9601 for (; CI != CE && SI != SE; ++CI, ++SI) { 9602 9603 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 9604 // At most one list item can be an array item derived from a given 9605 // variable in map clauses of the same construct. 9606 if (CurrentRegionOnly && (isa<ArraySubscriptExpr>(CI->first) || 9607 isa<OMPArraySectionExpr>(CI->first)) && 9608 (isa<ArraySubscriptExpr>(SI->first) || 9609 isa<OMPArraySectionExpr>(SI->first))) { 9610 SemaRef.Diag(CI->first->getExprLoc(), 9611 diag::err_omp_multiple_array_items_in_map_clause) 9612 << CI->first->getSourceRange(); 9613 ; 9614 SemaRef.Diag(SI->first->getExprLoc(), diag::note_used_here) 9615 << SI->first->getSourceRange(); 9616 return true; 9617 } 9618 9619 // Do both expressions have the same kind? 9620 if (CI->first->getStmtClass() != SI->first->getStmtClass()) 9621 break; 9622 9623 // Are we dealing with different variables/fields? 9624 if (CI->second != SI->second) 9625 break; 9626 } 9627 9628 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 9629 // List items of map clauses in the same construct must not share 9630 // original storage. 9631 // 9632 // If the expressions are exactly the same or one is a subset of the 9633 // other, it means they are sharing storage. 9634 if (CI == CE && SI == SE) { 9635 if (CurrentRegionOnly) { 9636 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 9637 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 9638 << RE->getSourceRange(); 9639 return true; 9640 } else { 9641 // If we find the same expression in the enclosing data environment, 9642 // that is legal. 9643 IsEnclosedByDataEnvironmentExpr = true; 9644 return false; 9645 } 9646 } 9647 9648 QualType DerivedType = std::prev(CI)->first->getType(); 9649 SourceLocation DerivedLoc = std::prev(CI)->first->getExprLoc(); 9650 9651 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 9652 // If the type of a list item is a reference to a type T then the type 9653 // will be considered to be T for all purposes of this clause. 9654 if (DerivedType->isReferenceType()) 9655 DerivedType = DerivedType->getPointeeType(); 9656 9657 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 9658 // A variable for which the type is pointer and an array section 9659 // derived from that variable must not appear as list items of map 9660 // clauses of the same construct. 9661 // 9662 // Also, cover one of the cases in: 9663 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 9664 // If any part of the original storage of a list item has corresponding 9665 // storage in the device data environment, all of the original storage 9666 // must have corresponding storage in the device data environment. 9667 // 9668 if (DerivedType->isAnyPointerType()) { 9669 if (CI == CE || SI == SE) { 9670 SemaRef.Diag( 9671 DerivedLoc, 9672 diag::err_omp_pointer_mapped_along_with_derived_section) 9673 << DerivedLoc; 9674 } else { 9675 assert(CI != CE && SI != SE); 9676 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced) 9677 << DerivedLoc; 9678 } 9679 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 9680 << RE->getSourceRange(); 9681 return true; 9682 } 9683 9684 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 9685 // List items of map clauses in the same construct must not share 9686 // original storage. 9687 // 9688 // An expression is a subset of the other. 9689 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 9690 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 9691 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 9692 << RE->getSourceRange(); 9693 return true; 9694 } 9695 9696 // The current expression uses the same base as other expression in the 9697 // data environment but does not contain it completelly. 9698 if (!CurrentRegionOnly && SI != SE) 9699 EnclosingExpr = RE; 9700 9701 // The current expression is a subset of the expression in the data 9702 // environment. 9703 IsEnclosedByDataEnvironmentExpr |= 9704 (!CurrentRegionOnly && CI != CE && SI == SE); 9705 9706 return false; 9707 }); 9708 9709 if (CurrentRegionOnly) 9710 return FoundError; 9711 9712 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 9713 // If any part of the original storage of a list item has corresponding 9714 // storage in the device data environment, all of the original storage must 9715 // have corresponding storage in the device data environment. 9716 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 9717 // If a list item is an element of a structure, and a different element of 9718 // the structure has a corresponding list item in the device data environment 9719 // prior to a task encountering the construct associated with the map clause, 9720 // then the list item must also have a correspnding list item in the device 9721 // data environment prior to the task encountering the construct. 9722 // 9723 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 9724 SemaRef.Diag(ELoc, 9725 diag::err_omp_original_storage_is_shared_and_does_not_contain) 9726 << ERange; 9727 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 9728 << EnclosingExpr->getSourceRange(); 9729 return true; 9730 } 9731 9732 return FoundError; 9733 } 9734 9735 OMPClause * 9736 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, 9737 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 9738 SourceLocation MapLoc, SourceLocation ColonLoc, 9739 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 9740 SourceLocation LParenLoc, SourceLocation EndLoc) { 9741 SmallVector<Expr *, 4> Vars; 9742 9743 for (auto &RE : VarList) { 9744 assert(RE && "Null expr in omp map"); 9745 if (isa<DependentScopeDeclRefExpr>(RE)) { 9746 // It will be analyzed later. 9747 Vars.push_back(RE); 9748 continue; 9749 } 9750 SourceLocation ELoc = RE->getExprLoc(); 9751 9752 auto *VE = RE->IgnoreParenLValueCasts(); 9753 9754 if (VE->isValueDependent() || VE->isTypeDependent() || 9755 VE->isInstantiationDependent() || 9756 VE->containsUnexpandedParameterPack()) { 9757 // We can only analyze this information once the missing information is 9758 // resolved. 9759 Vars.push_back(RE); 9760 continue; 9761 } 9762 9763 auto *SimpleExpr = RE->IgnoreParenCasts(); 9764 9765 if (!RE->IgnoreParenImpCasts()->isLValue()) { 9766 Diag(ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 9767 << RE->getSourceRange(); 9768 continue; 9769 } 9770 9771 // Obtain the array or member expression bases if required. 9772 auto *BE = CheckMapClauseExpressionBase(*this, SimpleExpr); 9773 if (!BE) 9774 continue; 9775 9776 // If the base is a reference to a variable, we rely on that variable for 9777 // the following checks. If it is a 'this' expression we rely on the field. 9778 ValueDecl *D = nullptr; 9779 if (auto *DRE = dyn_cast<DeclRefExpr>(BE)) { 9780 D = DRE->getDecl(); 9781 } else { 9782 auto *ME = cast<MemberExpr>(BE); 9783 assert(isa<CXXThisExpr>(ME->getBase()) && "Unexpected expression!"); 9784 D = ME->getMemberDecl(); 9785 } 9786 assert(D && "Null decl on map clause."); 9787 9788 auto *VD = dyn_cast<VarDecl>(D); 9789 auto *FD = dyn_cast<FieldDecl>(D); 9790 9791 assert((VD || FD) && "Only variables or fields are expected here!"); 9792 (void)FD; 9793 9794 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 9795 // threadprivate variables cannot appear in a map clause. 9796 if (VD && DSAStack->isThreadPrivate(VD)) { 9797 auto DVar = DSAStack->getTopDSA(VD, false); 9798 Diag(ELoc, diag::err_omp_threadprivate_in_map); 9799 ReportOriginalDSA(*this, DSAStack, VD, DVar); 9800 continue; 9801 } 9802 9803 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 9804 // A list item cannot appear in both a map clause and a data-sharing 9805 // attribute clause on the same construct. 9806 // 9807 // TODO: Implement this check - it cannot currently be tested because of 9808 // missing implementation of the other data sharing clauses in target 9809 // directives. 9810 9811 // Check conflicts with other map clause expressions. We check the conflicts 9812 // with the current construct separately from the enclosing data 9813 // environment, because the restrictions are different. 9814 if (CheckMapConflicts(*this, DSAStack, D, SimpleExpr, 9815 /*CurrentRegionOnly=*/true)) 9816 break; 9817 if (CheckMapConflicts(*this, DSAStack, D, SimpleExpr, 9818 /*CurrentRegionOnly=*/false)) 9819 break; 9820 9821 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 9822 // If the type of a list item is a reference to a type T then the type will 9823 // be considered to be T for all purposes of this clause. 9824 QualType Type = D->getType(); 9825 if (Type->isReferenceType()) 9826 Type = Type->getPointeeType(); 9827 9828 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 9829 // A list item must have a mappable type. 9830 if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), *this, 9831 DSAStack, Type)) 9832 continue; 9833 9834 // target enter data 9835 // OpenMP [2.10.2, Restrictions, p. 99] 9836 // A map-type must be specified in all map clauses and must be either 9837 // to or alloc. 9838 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9839 if (DKind == OMPD_target_enter_data && 9840 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 9841 Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 9842 << (IsMapTypeImplicit ? 1 : 0) 9843 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 9844 << getOpenMPDirectiveName(DKind); 9845 continue; 9846 } 9847 9848 // target exit_data 9849 // OpenMP [2.10.3, Restrictions, p. 102] 9850 // A map-type must be specified in all map clauses and must be either 9851 // from, release, or delete. 9852 DKind = DSAStack->getCurrentDirective(); 9853 if (DKind == OMPD_target_exit_data && 9854 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 9855 MapType == OMPC_MAP_delete)) { 9856 Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 9857 << (IsMapTypeImplicit ? 1 : 0) 9858 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 9859 << getOpenMPDirectiveName(DKind); 9860 continue; 9861 } 9862 9863 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 9864 // A list item cannot appear in both a map clause and a data-sharing 9865 // attribute clause on the same construct 9866 if (DKind == OMPD_target && VD) { 9867 auto DVar = DSAStack->getTopDSA(VD, false); 9868 if (isOpenMPPrivate(DVar.CKind)) { 9869 Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) 9870 << getOpenMPClauseName(DVar.CKind) 9871 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 9872 ReportOriginalDSA(*this, DSAStack, D, DVar); 9873 continue; 9874 } 9875 } 9876 9877 Vars.push_back(RE); 9878 DSAStack->addExprToVarMapInfo(D, RE); 9879 } 9880 9881 // We need to produce a map clause even if we don't have variables so that 9882 // other diagnostics related with non-existing map clauses are accurate. 9883 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 9884 MapTypeModifier, MapType, IsMapTypeImplicit, 9885 MapLoc); 9886 } 9887 9888 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 9889 TypeResult ParsedType) { 9890 assert(ParsedType.isUsable()); 9891 9892 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 9893 if (ReductionType.isNull()) 9894 return QualType(); 9895 9896 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 9897 // A type name in a declare reduction directive cannot be a function type, an 9898 // array type, a reference type, or a type qualified with const, volatile or 9899 // restrict. 9900 if (ReductionType.hasQualifiers()) { 9901 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 9902 return QualType(); 9903 } 9904 9905 if (ReductionType->isFunctionType()) { 9906 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 9907 return QualType(); 9908 } 9909 if (ReductionType->isReferenceType()) { 9910 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 9911 return QualType(); 9912 } 9913 if (ReductionType->isArrayType()) { 9914 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 9915 return QualType(); 9916 } 9917 return ReductionType; 9918 } 9919 9920 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 9921 Scope *S, DeclContext *DC, DeclarationName Name, 9922 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 9923 AccessSpecifier AS, Decl *PrevDeclInScope) { 9924 SmallVector<Decl *, 8> Decls; 9925 Decls.reserve(ReductionTypes.size()); 9926 9927 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 9928 ForRedeclaration); 9929 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 9930 // A reduction-identifier may not be re-declared in the current scope for the 9931 // same type or for a type that is compatible according to the base language 9932 // rules. 9933 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 9934 OMPDeclareReductionDecl *PrevDRD = nullptr; 9935 bool InCompoundScope = true; 9936 if (S != nullptr) { 9937 // Find previous declaration with the same name not referenced in other 9938 // declarations. 9939 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 9940 InCompoundScope = 9941 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 9942 LookupName(Lookup, S); 9943 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 9944 /*AllowInlineNamespace=*/false); 9945 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 9946 auto Filter = Lookup.makeFilter(); 9947 while (Filter.hasNext()) { 9948 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 9949 if (InCompoundScope) { 9950 auto I = UsedAsPrevious.find(PrevDecl); 9951 if (I == UsedAsPrevious.end()) 9952 UsedAsPrevious[PrevDecl] = false; 9953 if (auto *D = PrevDecl->getPrevDeclInScope()) 9954 UsedAsPrevious[D] = true; 9955 } 9956 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 9957 PrevDecl->getLocation(); 9958 } 9959 Filter.done(); 9960 if (InCompoundScope) { 9961 for (auto &PrevData : UsedAsPrevious) { 9962 if (!PrevData.second) { 9963 PrevDRD = PrevData.first; 9964 break; 9965 } 9966 } 9967 } 9968 } else if (PrevDeclInScope != nullptr) { 9969 auto *PrevDRDInScope = PrevDRD = 9970 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 9971 do { 9972 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 9973 PrevDRDInScope->getLocation(); 9974 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 9975 } while (PrevDRDInScope != nullptr); 9976 } 9977 for (auto &TyData : ReductionTypes) { 9978 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 9979 bool Invalid = false; 9980 if (I != PreviousRedeclTypes.end()) { 9981 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 9982 << TyData.first; 9983 Diag(I->second, diag::note_previous_definition); 9984 Invalid = true; 9985 } 9986 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 9987 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 9988 Name, TyData.first, PrevDRD); 9989 DC->addDecl(DRD); 9990 DRD->setAccess(AS); 9991 Decls.push_back(DRD); 9992 if (Invalid) 9993 DRD->setInvalidDecl(); 9994 else 9995 PrevDRD = DRD; 9996 } 9997 9998 return DeclGroupPtrTy::make( 9999 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 10000 } 10001 10002 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 10003 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10004 10005 // Enter new function scope. 10006 PushFunctionScope(); 10007 getCurFunction()->setHasBranchProtectedScope(); 10008 getCurFunction()->setHasOMPDeclareReductionCombiner(); 10009 10010 if (S != nullptr) 10011 PushDeclContext(S, DRD); 10012 else 10013 CurContext = DRD; 10014 10015 PushExpressionEvaluationContext(PotentiallyEvaluated); 10016 10017 QualType ReductionType = DRD->getType(); 10018 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 10019 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 10020 // uses semantics of argument handles by value, but it should be passed by 10021 // reference. C lang does not support references, so pass all parameters as 10022 // pointers. 10023 // Create 'T omp_in;' variable. 10024 auto *OmpInParm = 10025 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 10026 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 10027 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 10028 // uses semantics of argument handles by value, but it should be passed by 10029 // reference. C lang does not support references, so pass all parameters as 10030 // pointers. 10031 // Create 'T omp_out;' variable. 10032 auto *OmpOutParm = 10033 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 10034 if (S != nullptr) { 10035 PushOnScopeChains(OmpInParm, S); 10036 PushOnScopeChains(OmpOutParm, S); 10037 } else { 10038 DRD->addDecl(OmpInParm); 10039 DRD->addDecl(OmpOutParm); 10040 } 10041 } 10042 10043 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 10044 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10045 DiscardCleanupsInEvaluationContext(); 10046 PopExpressionEvaluationContext(); 10047 10048 PopDeclContext(); 10049 PopFunctionScopeInfo(); 10050 10051 if (Combiner != nullptr) 10052 DRD->setCombiner(Combiner); 10053 else 10054 DRD->setInvalidDecl(); 10055 } 10056 10057 void Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 10058 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10059 10060 // Enter new function scope. 10061 PushFunctionScope(); 10062 getCurFunction()->setHasBranchProtectedScope(); 10063 10064 if (S != nullptr) 10065 PushDeclContext(S, DRD); 10066 else 10067 CurContext = DRD; 10068 10069 PushExpressionEvaluationContext(PotentiallyEvaluated); 10070 10071 QualType ReductionType = DRD->getType(); 10072 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 10073 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 10074 // uses semantics of argument handles by value, but it should be passed by 10075 // reference. C lang does not support references, so pass all parameters as 10076 // pointers. 10077 // Create 'T omp_priv;' variable. 10078 auto *OmpPrivParm = 10079 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 10080 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 10081 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 10082 // uses semantics of argument handles by value, but it should be passed by 10083 // reference. C lang does not support references, so pass all parameters as 10084 // pointers. 10085 // Create 'T omp_orig;' variable. 10086 auto *OmpOrigParm = 10087 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 10088 if (S != nullptr) { 10089 PushOnScopeChains(OmpPrivParm, S); 10090 PushOnScopeChains(OmpOrigParm, S); 10091 } else { 10092 DRD->addDecl(OmpPrivParm); 10093 DRD->addDecl(OmpOrigParm); 10094 } 10095 } 10096 10097 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, 10098 Expr *Initializer) { 10099 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10100 DiscardCleanupsInEvaluationContext(); 10101 PopExpressionEvaluationContext(); 10102 10103 PopDeclContext(); 10104 PopFunctionScopeInfo(); 10105 10106 if (Initializer != nullptr) 10107 DRD->setInitializer(Initializer); 10108 else 10109 DRD->setInvalidDecl(); 10110 } 10111 10112 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 10113 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 10114 for (auto *D : DeclReductions.get()) { 10115 if (IsValid) { 10116 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10117 if (S != nullptr) 10118 PushOnScopeChains(DRD, S, /*AddToContext=*/false); 10119 } else 10120 D->setInvalidDecl(); 10121 } 10122 return DeclReductions; 10123 } 10124 10125 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 10126 SourceLocation StartLoc, 10127 SourceLocation LParenLoc, 10128 SourceLocation EndLoc) { 10129 Expr *ValExpr = NumTeams; 10130 10131 // OpenMP [teams Constrcut, Restrictions] 10132 // The num_teams expression must evaluate to a positive integer value. 10133 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 10134 /*StrictlyPositive=*/true)) 10135 return nullptr; 10136 10137 return new (Context) OMPNumTeamsClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10138 } 10139 10140 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 10141 SourceLocation StartLoc, 10142 SourceLocation LParenLoc, 10143 SourceLocation EndLoc) { 10144 Expr *ValExpr = ThreadLimit; 10145 10146 // OpenMP [teams Constrcut, Restrictions] 10147 // The thread_limit expression must evaluate to a positive integer value. 10148 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 10149 /*StrictlyPositive=*/true)) 10150 return nullptr; 10151 10152 return new (Context) OMPThreadLimitClause(ValExpr, StartLoc, LParenLoc, 10153 EndLoc); 10154 } 10155 10156 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 10157 SourceLocation StartLoc, 10158 SourceLocation LParenLoc, 10159 SourceLocation EndLoc) { 10160 Expr *ValExpr = Priority; 10161 10162 // OpenMP [2.9.1, task Constrcut] 10163 // The priority-value is a non-negative numerical scalar expression. 10164 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 10165 /*StrictlyPositive=*/false)) 10166 return nullptr; 10167 10168 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10169 } 10170 10171 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 10172 SourceLocation StartLoc, 10173 SourceLocation LParenLoc, 10174 SourceLocation EndLoc) { 10175 Expr *ValExpr = Grainsize; 10176 10177 // OpenMP [2.9.2, taskloop Constrcut] 10178 // The parameter of the grainsize clause must be a positive integer 10179 // expression. 10180 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 10181 /*StrictlyPositive=*/true)) 10182 return nullptr; 10183 10184 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10185 } 10186 10187 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 10188 SourceLocation StartLoc, 10189 SourceLocation LParenLoc, 10190 SourceLocation EndLoc) { 10191 Expr *ValExpr = NumTasks; 10192 10193 // OpenMP [2.9.2, taskloop Constrcut] 10194 // The parameter of the num_tasks clause must be a positive integer 10195 // expression. 10196 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 10197 /*StrictlyPositive=*/true)) 10198 return nullptr; 10199 10200 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10201 } 10202 10203 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 10204 SourceLocation LParenLoc, 10205 SourceLocation EndLoc) { 10206 // OpenMP [2.13.2, critical construct, Description] 10207 // ... where hint-expression is an integer constant expression that evaluates 10208 // to a valid lock hint. 10209 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 10210 if (HintExpr.isInvalid()) 10211 return nullptr; 10212 return new (Context) 10213 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 10214 } 10215 10216 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 10217 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10218 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 10219 SourceLocation EndLoc) { 10220 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 10221 std::string Values; 10222 Values += "'"; 10223 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 10224 Values += "'"; 10225 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 10226 << Values << getOpenMPClauseName(OMPC_dist_schedule); 10227 return nullptr; 10228 } 10229 Expr *ValExpr = ChunkSize; 10230 Stmt *HelperValStmt = nullptr; 10231 if (ChunkSize) { 10232 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 10233 !ChunkSize->isInstantiationDependent() && 10234 !ChunkSize->containsUnexpandedParameterPack()) { 10235 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 10236 ExprResult Val = 10237 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 10238 if (Val.isInvalid()) 10239 return nullptr; 10240 10241 ValExpr = Val.get(); 10242 10243 // OpenMP [2.7.1, Restrictions] 10244 // chunk_size must be a loop invariant integer expression with a positive 10245 // value. 10246 llvm::APSInt Result; 10247 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 10248 if (Result.isSigned() && !Result.isStrictlyPositive()) { 10249 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 10250 << "dist_schedule" << ChunkSize->getSourceRange(); 10251 return nullptr; 10252 } 10253 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 10254 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 10255 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10256 HelperValStmt = buildPreInits(Context, Captures); 10257 } 10258 } 10259 } 10260 10261 return new (Context) 10262 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 10263 Kind, ValExpr, HelperValStmt); 10264 } 10265 10266 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 10267 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 10268 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 10269 SourceLocation KindLoc, SourceLocation EndLoc) { 10270 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 10271 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 10272 Kind != OMPC_DEFAULTMAP_scalar) { 10273 std::string Value; 10274 SourceLocation Loc; 10275 Value += "'"; 10276 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 10277 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 10278 OMPC_DEFAULTMAP_MODIFIER_tofrom); 10279 Loc = MLoc; 10280 } else { 10281 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 10282 OMPC_DEFAULTMAP_scalar); 10283 Loc = KindLoc; 10284 } 10285 Value += "'"; 10286 Diag(Loc, diag::err_omp_unexpected_clause_value) 10287 << Value << getOpenMPClauseName(OMPC_defaultmap); 10288 return nullptr; 10289 } 10290 10291 return new (Context) 10292 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 10293 } 10294