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