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