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 "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/Decl.h" 18 #include "clang/AST/DeclCXX.h" 19 #include "clang/AST/DeclOpenMP.h" 20 #include "clang/AST/StmtCXX.h" 21 #include "clang/AST/StmtOpenMP.h" 22 #include "clang/AST/StmtVisitor.h" 23 #include "clang/Basic/OpenMPKinds.h" 24 #include "clang/Lex/Preprocessor.h" 25 #include "clang/Sema/Initialization.h" 26 #include "clang/Sema/Lookup.h" 27 #include "clang/Sema/Scope.h" 28 #include "clang/Sema/ScopeInfo.h" 29 #include "clang/Sema/SemaInternal.h" 30 using namespace clang; 31 32 //===----------------------------------------------------------------------===// 33 // Stack of data-sharing attributes for variables 34 //===----------------------------------------------------------------------===// 35 36 namespace { 37 /// \brief Default data sharing attributes, which can be applied to directive. 38 enum DefaultDataSharingAttributes { 39 DSA_unspecified = 0, /// \brief Data sharing attribute not specified. 40 DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'. 41 DSA_shared = 1 << 1 /// \brief Default data sharing attribute 'shared'. 42 }; 43 44 template <class T> struct MatchesAny { 45 explicit MatchesAny(ArrayRef<T> Arr) : Arr(std::move(Arr)) {} 46 bool operator()(T Kind) { 47 for (auto KindEl : Arr) 48 if (KindEl == Kind) 49 return true; 50 return false; 51 } 52 53 private: 54 ArrayRef<T> Arr; 55 }; 56 struct MatchesAlways { 57 MatchesAlways() {} 58 template <class T> bool operator()(T) { return true; } 59 }; 60 61 typedef MatchesAny<OpenMPClauseKind> MatchesAnyClause; 62 typedef MatchesAny<OpenMPDirectiveKind> MatchesAnyDirective; 63 64 /// \brief Stack for tracking declarations used in OpenMP directives and 65 /// clauses and their data-sharing attributes. 66 class DSAStackTy { 67 public: 68 struct DSAVarData { 69 OpenMPDirectiveKind DKind; 70 OpenMPClauseKind CKind; 71 DeclRefExpr *RefExpr; 72 SourceLocation ImplicitDSALoc; 73 DSAVarData() 74 : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr), 75 ImplicitDSALoc() {} 76 }; 77 78 private: 79 struct DSAInfo { 80 OpenMPClauseKind Attributes; 81 DeclRefExpr *RefExpr; 82 }; 83 typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy; 84 typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy; 85 typedef llvm::DenseSet<VarDecl *> LoopControlVariablesSetTy; 86 87 struct SharingMapTy { 88 DeclSAMapTy SharingMap; 89 AlignedMapTy AlignedMap; 90 LoopControlVariablesSetTy LCVSet; 91 DefaultDataSharingAttributes DefaultAttr; 92 SourceLocation DefaultAttrLoc; 93 OpenMPDirectiveKind Directive; 94 DeclarationNameInfo DirectiveName; 95 Scope *CurScope; 96 SourceLocation ConstructLoc; 97 bool OrderedRegion; 98 unsigned CollapseNumber; 99 SourceLocation InnerTeamsRegionLoc; 100 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 101 Scope *CurScope, SourceLocation Loc) 102 : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified), 103 Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope), 104 ConstructLoc(Loc), OrderedRegion(false), CollapseNumber(1), 105 InnerTeamsRegionLoc() {} 106 SharingMapTy() 107 : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified), 108 Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr), 109 ConstructLoc(), OrderedRegion(false), CollapseNumber(1), 110 InnerTeamsRegionLoc() {} 111 }; 112 113 typedef SmallVector<SharingMapTy, 64> StackTy; 114 115 /// \brief Stack of used declaration and their data-sharing attributes. 116 StackTy Stack; 117 Sema &SemaRef; 118 119 typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; 120 121 DSAVarData getDSA(StackTy::reverse_iterator Iter, VarDecl *D); 122 123 /// \brief Checks if the variable is a local for OpenMP region. 124 bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter); 125 126 public: 127 explicit DSAStackTy(Sema &S) : Stack(1), SemaRef(S) {} 128 129 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 130 Scope *CurScope, SourceLocation Loc) { 131 Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc)); 132 Stack.back().DefaultAttrLoc = Loc; 133 } 134 135 void pop() { 136 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!"); 137 Stack.pop_back(); 138 } 139 140 /// \brief If 'aligned' declaration for given variable \a D was not seen yet, 141 /// add it and return NULL; otherwise return previous occurrence's expression 142 /// for diagnostics. 143 DeclRefExpr *addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE); 144 145 /// \brief Register specified variable as loop control variable. 146 void addLoopControlVariable(VarDecl *D); 147 /// \brief Check if the specified variable is a loop control variable for 148 /// current region. 149 bool isLoopControlVariable(VarDecl *D); 150 151 /// \brief Adds explicit data sharing attribute to the specified declaration. 152 void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A); 153 154 /// \brief Returns data sharing attributes from top of the stack for the 155 /// specified declaration. 156 DSAVarData getTopDSA(VarDecl *D, bool FromParent); 157 /// \brief Returns data-sharing attributes for the specified declaration. 158 DSAVarData getImplicitDSA(VarDecl *D, bool FromParent); 159 /// \brief Checks if the specified variables has data-sharing attributes which 160 /// match specified \a CPred predicate in any directive which matches \a DPred 161 /// predicate. 162 template <class ClausesPredicate, class DirectivesPredicate> 163 DSAVarData hasDSA(VarDecl *D, ClausesPredicate CPred, 164 DirectivesPredicate DPred, bool FromParent); 165 /// \brief Checks if the specified variables has data-sharing attributes which 166 /// match specified \a CPred predicate in any innermost directive which 167 /// matches \a DPred predicate. 168 template <class ClausesPredicate, class DirectivesPredicate> 169 DSAVarData hasInnermostDSA(VarDecl *D, ClausesPredicate CPred, 170 DirectivesPredicate DPred, 171 bool FromParent); 172 /// \brief Finds a directive which matches specified \a DPred predicate. 173 template <class NamedDirectivesPredicate> 174 bool hasDirective(NamedDirectivesPredicate DPred, bool FromParent); 175 176 /// \brief Returns currently analyzed directive. 177 OpenMPDirectiveKind getCurrentDirective() const { 178 return Stack.back().Directive; 179 } 180 /// \brief Returns parent directive. 181 OpenMPDirectiveKind getParentDirective() const { 182 if (Stack.size() > 2) 183 return Stack[Stack.size() - 2].Directive; 184 return OMPD_unknown; 185 } 186 187 /// \brief Set default data sharing attribute to none. 188 void setDefaultDSANone(SourceLocation Loc) { 189 Stack.back().DefaultAttr = DSA_none; 190 Stack.back().DefaultAttrLoc = Loc; 191 } 192 /// \brief Set default data sharing attribute to shared. 193 void setDefaultDSAShared(SourceLocation Loc) { 194 Stack.back().DefaultAttr = DSA_shared; 195 Stack.back().DefaultAttrLoc = Loc; 196 } 197 198 DefaultDataSharingAttributes getDefaultDSA() const { 199 return Stack.back().DefaultAttr; 200 } 201 SourceLocation getDefaultDSALocation() const { 202 return Stack.back().DefaultAttrLoc; 203 } 204 205 /// \brief Checks if the specified variable is a threadprivate. 206 bool isThreadPrivate(VarDecl *D) { 207 DSAVarData DVar = getTopDSA(D, false); 208 return isOpenMPThreadPrivate(DVar.CKind); 209 } 210 211 /// \brief Marks current region as ordered (it has an 'ordered' clause). 212 void setOrderedRegion(bool IsOrdered = true) { 213 Stack.back().OrderedRegion = IsOrdered; 214 } 215 /// \brief Returns true, if parent region is ordered (has associated 216 /// 'ordered' clause), false - otherwise. 217 bool isParentOrderedRegion() const { 218 if (Stack.size() > 2) 219 return Stack[Stack.size() - 2].OrderedRegion; 220 return false; 221 } 222 223 /// \brief Set collapse value for the region. 224 void setCollapseNumber(unsigned Val) { Stack.back().CollapseNumber = Val; } 225 /// \brief Return collapse value for region. 226 unsigned getCollapseNumber() const { 227 return Stack.back().CollapseNumber; 228 } 229 230 /// \brief Marks current target region as one with closely nested teams 231 /// region. 232 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 233 if (Stack.size() > 2) 234 Stack[Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc; 235 } 236 /// \brief Returns true, if current region has closely nested teams region. 237 bool hasInnerTeamsRegion() const { 238 return getInnerTeamsRegionLoc().isValid(); 239 } 240 /// \brief Returns location of the nested teams region (if any). 241 SourceLocation getInnerTeamsRegionLoc() const { 242 if (Stack.size() > 1) 243 return Stack.back().InnerTeamsRegionLoc; 244 return SourceLocation(); 245 } 246 247 Scope *getCurScope() const { return Stack.back().CurScope; } 248 Scope *getCurScope() { return Stack.back().CurScope; } 249 SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; } 250 }; 251 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { 252 return isOpenMPParallelDirective(DKind) || DKind == OMPD_task || 253 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; 254 } 255 } // namespace 256 257 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter, 258 VarDecl *D) { 259 D = D->getCanonicalDecl(); 260 DSAVarData DVar; 261 if (Iter == std::prev(Stack.rend())) { 262 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 263 // in a region but not in construct] 264 // File-scope or namespace-scope variables referenced in called routines 265 // in the region are shared unless they appear in a threadprivate 266 // directive. 267 if (!D->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D)) 268 DVar.CKind = OMPC_shared; 269 270 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 271 // in a region but not in construct] 272 // Variables with static storage duration that are declared in called 273 // routines in the region are shared. 274 if (D->hasGlobalStorage()) 275 DVar.CKind = OMPC_shared; 276 277 return DVar; 278 } 279 280 DVar.DKind = Iter->Directive; 281 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 282 // in a Construct, C/C++, predetermined, p.1] 283 // Variables with automatic storage duration that are declared in a scope 284 // inside the construct are private. 285 if (isOpenMPLocal(D, Iter) && D->isLocalVarDecl() && 286 (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) { 287 DVar.CKind = OMPC_private; 288 return DVar; 289 } 290 291 // Explicitly specified attributes and local variables with predetermined 292 // attributes. 293 if (Iter->SharingMap.count(D)) { 294 DVar.RefExpr = Iter->SharingMap[D].RefExpr; 295 DVar.CKind = Iter->SharingMap[D].Attributes; 296 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 297 return DVar; 298 } 299 300 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 301 // in a Construct, C/C++, implicitly determined, p.1] 302 // In a parallel or task construct, the data-sharing attributes of these 303 // variables are determined by the default clause, if present. 304 switch (Iter->DefaultAttr) { 305 case DSA_shared: 306 DVar.CKind = OMPC_shared; 307 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 308 return DVar; 309 case DSA_none: 310 return DVar; 311 case DSA_unspecified: 312 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 313 // in a Construct, implicitly determined, p.2] 314 // In a parallel construct, if no default clause is present, these 315 // variables are shared. 316 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 317 if (isOpenMPParallelDirective(DVar.DKind) || 318 isOpenMPTeamsDirective(DVar.DKind)) { 319 DVar.CKind = OMPC_shared; 320 return DVar; 321 } 322 323 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 324 // in a Construct, implicitly determined, p.4] 325 // In a task construct, if no default clause is present, a variable that in 326 // the enclosing context is determined to be shared by all implicit tasks 327 // bound to the current team is shared. 328 if (DVar.DKind == OMPD_task) { 329 DSAVarData DVarTemp; 330 for (StackTy::reverse_iterator I = std::next(Iter), EE = Stack.rend(); 331 I != EE; ++I) { 332 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 333 // Referenced 334 // in a Construct, implicitly determined, p.6] 335 // In a task construct, if no default clause is present, a variable 336 // whose data-sharing attribute is not determined by the rules above is 337 // firstprivate. 338 DVarTemp = getDSA(I, D); 339 if (DVarTemp.CKind != OMPC_shared) { 340 DVar.RefExpr = nullptr; 341 DVar.DKind = OMPD_task; 342 DVar.CKind = OMPC_firstprivate; 343 return DVar; 344 } 345 if (isParallelOrTaskRegion(I->Directive)) 346 break; 347 } 348 DVar.DKind = OMPD_task; 349 DVar.CKind = 350 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 351 return DVar; 352 } 353 } 354 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 355 // in a Construct, implicitly determined, p.3] 356 // For constructs other than task, if no default clause is present, these 357 // variables inherit their data-sharing attributes from the enclosing 358 // context. 359 return getDSA(std::next(Iter), D); 360 } 361 362 DeclRefExpr *DSAStackTy::addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE) { 363 assert(Stack.size() > 1 && "Data sharing attributes stack is empty"); 364 D = D->getCanonicalDecl(); 365 auto It = Stack.back().AlignedMap.find(D); 366 if (It == Stack.back().AlignedMap.end()) { 367 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 368 Stack.back().AlignedMap[D] = NewDE; 369 return nullptr; 370 } else { 371 assert(It->second && "Unexpected nullptr expr in the aligned map"); 372 return It->second; 373 } 374 return nullptr; 375 } 376 377 void DSAStackTy::addLoopControlVariable(VarDecl *D) { 378 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 379 D = D->getCanonicalDecl(); 380 Stack.back().LCVSet.insert(D); 381 } 382 383 bool DSAStackTy::isLoopControlVariable(VarDecl *D) { 384 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 385 D = D->getCanonicalDecl(); 386 return Stack.back().LCVSet.count(D) > 0; 387 } 388 389 void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) { 390 D = D->getCanonicalDecl(); 391 if (A == OMPC_threadprivate) { 392 Stack[0].SharingMap[D].Attributes = A; 393 Stack[0].SharingMap[D].RefExpr = E; 394 } else { 395 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 396 Stack.back().SharingMap[D].Attributes = A; 397 Stack.back().SharingMap[D].RefExpr = E; 398 } 399 } 400 401 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) { 402 D = D->getCanonicalDecl(); 403 if (Stack.size() > 2) { 404 reverse_iterator I = Iter, E = std::prev(Stack.rend()); 405 Scope *TopScope = nullptr; 406 while (I != E && !isParallelOrTaskRegion(I->Directive)) { 407 ++I; 408 } 409 if (I == E) 410 return false; 411 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 412 Scope *CurScope = getCurScope(); 413 while (CurScope != TopScope && !CurScope->isDeclScope(D)) { 414 CurScope = CurScope->getParent(); 415 } 416 return CurScope != TopScope; 417 } 418 return false; 419 } 420 421 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) { 422 D = D->getCanonicalDecl(); 423 DSAVarData DVar; 424 425 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 426 // in a Construct, C/C++, predetermined, p.1] 427 // Variables appearing in threadprivate directives are threadprivate. 428 if (D->getTLSKind() != VarDecl::TLS_None || 429 D->getStorageClass() == SC_Register) { 430 DVar.CKind = OMPC_threadprivate; 431 return DVar; 432 } 433 if (Stack[0].SharingMap.count(D)) { 434 DVar.RefExpr = Stack[0].SharingMap[D].RefExpr; 435 DVar.CKind = OMPC_threadprivate; 436 return DVar; 437 } 438 439 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 440 // in a Construct, C/C++, predetermined, p.1] 441 // Variables with automatic storage duration that are declared in a scope 442 // inside the construct are private. 443 OpenMPDirectiveKind Kind = 444 FromParent ? getParentDirective() : getCurrentDirective(); 445 auto StartI = std::next(Stack.rbegin()); 446 auto EndI = std::prev(Stack.rend()); 447 if (FromParent && StartI != EndI) { 448 StartI = std::next(StartI); 449 } 450 if (!isParallelOrTaskRegion(Kind)) { 451 if (isOpenMPLocal(D, StartI) && 452 ((D->isLocalVarDecl() && (D->getStorageClass() == SC_Auto || 453 D->getStorageClass() == SC_None)) || 454 isa<ParmVarDecl>(D))) { 455 DVar.CKind = OMPC_private; 456 return DVar; 457 } 458 459 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 460 // in a Construct, C/C++, predetermined, p.4] 461 // Static data members are shared. 462 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 463 // in a Construct, C/C++, predetermined, p.7] 464 // Variables with static storage duration that are declared in a scope 465 // inside the construct are shared. 466 if (D->isStaticDataMember() || D->isStaticLocal()) { 467 DSAVarData DVarTemp = 468 hasDSA(D, isOpenMPPrivate, MatchesAlways(), FromParent); 469 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 470 return DVar; 471 472 DVar.CKind = OMPC_shared; 473 return DVar; 474 } 475 } 476 477 QualType Type = D->getType().getNonReferenceType().getCanonicalType(); 478 bool IsConstant = Type.isConstant(SemaRef.getASTContext()); 479 while (Type->isArrayType()) { 480 QualType ElemType = cast<ArrayType>(Type.getTypePtr())->getElementType(); 481 Type = ElemType.getNonReferenceType().getCanonicalType(); 482 } 483 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 484 // in a Construct, C/C++, predetermined, p.6] 485 // Variables with const qualified type having no mutable member are 486 // shared. 487 CXXRecordDecl *RD = 488 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 489 if (IsConstant && 490 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) { 491 // Variables with const-qualified type having no mutable member may be 492 // listed in a firstprivate clause, even if they are static data members. 493 DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate), 494 MatchesAlways(), FromParent); 495 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 496 return DVar; 497 498 DVar.CKind = OMPC_shared; 499 return DVar; 500 } 501 502 // Explicitly specified attributes and local variables with predetermined 503 // attributes. 504 auto I = std::prev(StartI); 505 if (I->SharingMap.count(D)) { 506 DVar.RefExpr = I->SharingMap[D].RefExpr; 507 DVar.CKind = I->SharingMap[D].Attributes; 508 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 509 } 510 511 return DVar; 512 } 513 514 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(VarDecl *D, bool FromParent) { 515 D = D->getCanonicalDecl(); 516 auto StartI = Stack.rbegin(); 517 auto EndI = std::prev(Stack.rend()); 518 if (FromParent && StartI != EndI) { 519 StartI = std::next(StartI); 520 } 521 return getDSA(StartI, D); 522 } 523 524 template <class ClausesPredicate, class DirectivesPredicate> 525 DSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, ClausesPredicate CPred, 526 DirectivesPredicate DPred, 527 bool FromParent) { 528 D = D->getCanonicalDecl(); 529 auto StartI = std::next(Stack.rbegin()); 530 auto EndI = std::prev(Stack.rend()); 531 if (FromParent && StartI != EndI) { 532 StartI = std::next(StartI); 533 } 534 for (auto I = StartI, EE = EndI; I != EE; ++I) { 535 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) 536 continue; 537 DSAVarData DVar = getDSA(I, D); 538 if (CPred(DVar.CKind)) 539 return DVar; 540 } 541 return DSAVarData(); 542 } 543 544 template <class ClausesPredicate, class DirectivesPredicate> 545 DSAStackTy::DSAVarData 546 DSAStackTy::hasInnermostDSA(VarDecl *D, ClausesPredicate CPred, 547 DirectivesPredicate DPred, bool FromParent) { 548 D = D->getCanonicalDecl(); 549 auto StartI = std::next(Stack.rbegin()); 550 auto EndI = std::prev(Stack.rend()); 551 if (FromParent && StartI != EndI) { 552 StartI = std::next(StartI); 553 } 554 for (auto I = StartI, EE = EndI; I != EE; ++I) { 555 if (!DPred(I->Directive)) 556 break; 557 DSAVarData DVar = getDSA(I, D); 558 if (CPred(DVar.CKind)) 559 return DVar; 560 return DSAVarData(); 561 } 562 return DSAVarData(); 563 } 564 565 template <class NamedDirectivesPredicate> 566 bool DSAStackTy::hasDirective(NamedDirectivesPredicate DPred, bool FromParent) { 567 auto StartI = std::next(Stack.rbegin()); 568 auto EndI = std::prev(Stack.rend()); 569 if (FromParent && StartI != EndI) { 570 StartI = std::next(StartI); 571 } 572 for (auto I = StartI, EE = EndI; I != EE; ++I) { 573 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 574 return true; 575 } 576 return false; 577 } 578 579 void Sema::InitDataSharingAttributesStack() { 580 VarDataSharingAttributesStack = new DSAStackTy(*this); 581 } 582 583 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 584 585 bool Sema::IsOpenMPCapturedVar(VarDecl *VD) { 586 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 587 VD = VD->getCanonicalDecl(); 588 if (DSAStack->getCurrentDirective() != OMPD_unknown) { 589 if (DSAStack->isLoopControlVariable(VD)) 590 return true; 591 auto DVarPrivate = DSAStack->getTopDSA(VD, /*FromParent=*/false); 592 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 593 return true; 594 DVarPrivate = DSAStack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), 595 /*FromParent=*/false); 596 return DVarPrivate.CKind != OMPC_unknown; 597 } 598 return false; 599 } 600 601 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 602 603 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 604 const DeclarationNameInfo &DirName, 605 Scope *CurScope, SourceLocation Loc) { 606 DSAStack->push(DKind, DirName, CurScope, Loc); 607 PushExpressionEvaluationContext(PotentiallyEvaluated); 608 } 609 610 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 611 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 612 // A variable of class type (or array thereof) that appears in a lastprivate 613 // clause requires an accessible, unambiguous default constructor for the 614 // class type, unless the list item is also specified in a firstprivate 615 // clause. 616 if (auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 617 for (auto *C : D->clauses()) { 618 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 619 SmallVector<Expr *, 8> PrivateCopies; 620 for (auto *DE : Clause->varlists()) { 621 if (DE->isValueDependent() || DE->isTypeDependent()) { 622 PrivateCopies.push_back(nullptr); 623 continue; 624 } 625 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(DE)->getDecl()); 626 auto DVar = DSAStack->getTopDSA(VD, false); 627 if (DVar.CKind == OMPC_lastprivate) { 628 // Generate helper private variable and initialize it with the 629 // default value. The address of the original variable is replaced 630 // by the address of the new private variable in CodeGen. This new 631 // variable is not added to IdResolver, so the code in the OpenMP 632 // region uses original variable for proper diagnostics. 633 auto *VDPrivate = VarDecl::Create( 634 Context, CurContext, DE->getLocStart(), DE->getExprLoc(), 635 VD->getIdentifier(), VD->getType(), VD->getTypeSourceInfo(), 636 SC_Auto); 637 ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); 638 if (VDPrivate->isInvalidDecl()) 639 continue; 640 CurContext->addDecl(VDPrivate); 641 PrivateCopies.push_back(DeclRefExpr::Create( 642 Context, NestedNameSpecifierLoc(), SourceLocation(), VDPrivate, 643 /*RefersToEnclosingVariableOrCapture=*/false, SourceLocation(), 644 DE->getType(), VK_LValue)); 645 } else { 646 // The variable is also a firstprivate, so initialization sequence 647 // for private copy is generated already. 648 PrivateCopies.push_back(nullptr); 649 } 650 } 651 // Set initializers to private copies if no errors were found. 652 if (PrivateCopies.size() == Clause->varlist_size()) { 653 Clause->setPrivateCopies(PrivateCopies); 654 } 655 } 656 } 657 } 658 659 DSAStack->pop(); 660 DiscardCleanupsInEvaluationContext(); 661 PopExpressionEvaluationContext(); 662 } 663 664 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 665 Expr *NumIterations, Sema &SemaRef, 666 Scope *S); 667 668 namespace { 669 670 class VarDeclFilterCCC : public CorrectionCandidateCallback { 671 private: 672 Sema &SemaRef; 673 674 public: 675 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 676 bool ValidateCandidate(const TypoCorrection &Candidate) override { 677 NamedDecl *ND = Candidate.getCorrectionDecl(); 678 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) { 679 return VD->hasGlobalStorage() && 680 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 681 SemaRef.getCurScope()); 682 } 683 return false; 684 } 685 }; 686 } // namespace 687 688 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 689 CXXScopeSpec &ScopeSpec, 690 const DeclarationNameInfo &Id) { 691 LookupResult Lookup(*this, Id, LookupOrdinaryName); 692 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 693 694 if (Lookup.isAmbiguous()) 695 return ExprError(); 696 697 VarDecl *VD; 698 if (!Lookup.isSingleResult()) { 699 if (TypoCorrection Corrected = CorrectTypo( 700 Id, LookupOrdinaryName, CurScope, nullptr, 701 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 702 diagnoseTypo(Corrected, 703 PDiag(Lookup.empty() 704 ? diag::err_undeclared_var_use_suggest 705 : diag::err_omp_expected_var_arg_suggest) 706 << Id.getName()); 707 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 708 } else { 709 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 710 : diag::err_omp_expected_var_arg) 711 << Id.getName(); 712 return ExprError(); 713 } 714 } else { 715 if (!(VD = Lookup.getAsSingle<VarDecl>())) { 716 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 717 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 718 return ExprError(); 719 } 720 } 721 Lookup.suppressDiagnostics(); 722 723 // OpenMP [2.9.2, Syntax, C/C++] 724 // Variables must be file-scope, namespace-scope, or static block-scope. 725 if (!VD->hasGlobalStorage()) { 726 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 727 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); 728 bool IsDecl = 729 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 730 Diag(VD->getLocation(), 731 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 732 << VD; 733 return ExprError(); 734 } 735 736 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 737 NamedDecl *ND = cast<NamedDecl>(CanonicalVD); 738 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 739 // A threadprivate directive for file-scope variables must appear outside 740 // any definition or declaration. 741 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 742 !getCurLexicalContext()->isTranslationUnit()) { 743 Diag(Id.getLoc(), diag::err_omp_var_scope) 744 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 745 bool IsDecl = 746 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 747 Diag(VD->getLocation(), 748 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 749 << VD; 750 return ExprError(); 751 } 752 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 753 // A threadprivate directive for static class member variables must appear 754 // in the class definition, in the same scope in which the member 755 // variables are declared. 756 if (CanonicalVD->isStaticDataMember() && 757 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 758 Diag(Id.getLoc(), diag::err_omp_var_scope) 759 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 760 bool IsDecl = 761 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 762 Diag(VD->getLocation(), 763 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 764 << VD; 765 return ExprError(); 766 } 767 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 768 // A threadprivate directive for namespace-scope variables must appear 769 // outside any definition or declaration other than the namespace 770 // definition itself. 771 if (CanonicalVD->getDeclContext()->isNamespace() && 772 (!getCurLexicalContext()->isFileContext() || 773 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 774 Diag(Id.getLoc(), diag::err_omp_var_scope) 775 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 776 bool IsDecl = 777 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 778 Diag(VD->getLocation(), 779 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 780 << VD; 781 return ExprError(); 782 } 783 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 784 // A threadprivate directive for static block-scope variables must appear 785 // in the scope of the variable and not in a nested scope. 786 if (CanonicalVD->isStaticLocal() && CurScope && 787 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 788 Diag(Id.getLoc(), diag::err_omp_var_scope) 789 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 790 bool IsDecl = 791 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 792 Diag(VD->getLocation(), 793 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 794 << VD; 795 return ExprError(); 796 } 797 798 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 799 // A threadprivate directive must lexically precede all references to any 800 // of the variables in its list. 801 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { 802 Diag(Id.getLoc(), diag::err_omp_var_used) 803 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 804 return ExprError(); 805 } 806 807 QualType ExprType = VD->getType().getNonReferenceType(); 808 ExprResult DE = BuildDeclRefExpr(VD, ExprType, VK_LValue, Id.getLoc()); 809 return DE; 810 } 811 812 Sema::DeclGroupPtrTy 813 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 814 ArrayRef<Expr *> VarList) { 815 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 816 CurContext->addDecl(D); 817 return DeclGroupPtrTy::make(DeclGroupRef(D)); 818 } 819 return DeclGroupPtrTy(); 820 } 821 822 namespace { 823 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> { 824 Sema &SemaRef; 825 826 public: 827 bool VisitDeclRefExpr(const DeclRefExpr *E) { 828 if (auto VD = dyn_cast<VarDecl>(E->getDecl())) { 829 if (VD->hasLocalStorage()) { 830 SemaRef.Diag(E->getLocStart(), 831 diag::err_omp_local_var_in_threadprivate_init) 832 << E->getSourceRange(); 833 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 834 << VD << VD->getSourceRange(); 835 return true; 836 } 837 } 838 return false; 839 } 840 bool VisitStmt(const Stmt *S) { 841 for (auto Child : S->children()) { 842 if (Child && Visit(Child)) 843 return true; 844 } 845 return false; 846 } 847 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 848 }; 849 } // namespace 850 851 OMPThreadPrivateDecl * 852 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 853 SmallVector<Expr *, 8> Vars; 854 for (auto &RefExpr : VarList) { 855 DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr); 856 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 857 SourceLocation ILoc = DE->getExprLoc(); 858 859 QualType QType = VD->getType(); 860 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 861 // It will be analyzed later. 862 Vars.push_back(DE); 863 continue; 864 } 865 866 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 867 // A threadprivate variable must not have an incomplete type. 868 if (RequireCompleteType(ILoc, VD->getType(), 869 diag::err_omp_threadprivate_incomplete_type)) { 870 continue; 871 } 872 873 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 874 // A threadprivate variable must not have a reference type. 875 if (VD->getType()->isReferenceType()) { 876 Diag(ILoc, diag::err_omp_ref_type_arg) 877 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 878 bool IsDecl = 879 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 880 Diag(VD->getLocation(), 881 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 882 << VD; 883 continue; 884 } 885 886 // Check if this is a TLS variable. 887 if (VD->getTLSKind() != VarDecl::TLS_None || 888 VD->getStorageClass() == SC_Register) { 889 Diag(ILoc, diag::err_omp_var_thread_local) 890 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 891 bool IsDecl = 892 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 893 Diag(VD->getLocation(), 894 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 895 << VD; 896 continue; 897 } 898 899 // Check if initial value of threadprivate variable reference variable with 900 // local storage (it is not supported by runtime). 901 if (auto Init = VD->getAnyInitializer()) { 902 LocalVarRefChecker Checker(*this); 903 if (Checker.Visit(Init)) 904 continue; 905 } 906 907 Vars.push_back(RefExpr); 908 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 909 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 910 Context, SourceRange(Loc, Loc))); 911 if (auto *ML = Context.getASTMutationListener()) 912 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 913 } 914 OMPThreadPrivateDecl *D = nullptr; 915 if (!Vars.empty()) { 916 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 917 Vars); 918 D->setAccess(AS_public); 919 } 920 return D; 921 } 922 923 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, 924 const VarDecl *VD, DSAStackTy::DSAVarData DVar, 925 bool IsLoopIterVar = false) { 926 if (DVar.RefExpr) { 927 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 928 << getOpenMPClauseName(DVar.CKind); 929 return; 930 } 931 enum { 932 PDSA_StaticMemberShared, 933 PDSA_StaticLocalVarShared, 934 PDSA_LoopIterVarPrivate, 935 PDSA_LoopIterVarLinear, 936 PDSA_LoopIterVarLastprivate, 937 PDSA_ConstVarShared, 938 PDSA_GlobalVarShared, 939 PDSA_TaskVarFirstprivate, 940 PDSA_LocalVarPrivate, 941 PDSA_Implicit 942 } Reason = PDSA_Implicit; 943 bool ReportHint = false; 944 auto ReportLoc = VD->getLocation(); 945 if (IsLoopIterVar) { 946 if (DVar.CKind == OMPC_private) 947 Reason = PDSA_LoopIterVarPrivate; 948 else if (DVar.CKind == OMPC_lastprivate) 949 Reason = PDSA_LoopIterVarLastprivate; 950 else 951 Reason = PDSA_LoopIterVarLinear; 952 } else if (DVar.DKind == OMPD_task && DVar.CKind == OMPC_firstprivate) { 953 Reason = PDSA_TaskVarFirstprivate; 954 ReportLoc = DVar.ImplicitDSALoc; 955 } else if (VD->isStaticLocal()) 956 Reason = PDSA_StaticLocalVarShared; 957 else if (VD->isStaticDataMember()) 958 Reason = PDSA_StaticMemberShared; 959 else if (VD->isFileVarDecl()) 960 Reason = PDSA_GlobalVarShared; 961 else if (VD->getType().isConstant(SemaRef.getASTContext())) 962 Reason = PDSA_ConstVarShared; 963 else if (VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 964 ReportHint = true; 965 Reason = PDSA_LocalVarPrivate; 966 } 967 if (Reason != PDSA_Implicit) { 968 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 969 << Reason << ReportHint 970 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 971 } else if (DVar.ImplicitDSALoc.isValid()) { 972 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 973 << getOpenMPClauseName(DVar.CKind); 974 } 975 } 976 977 namespace { 978 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> { 979 DSAStackTy *Stack; 980 Sema &SemaRef; 981 bool ErrorFound; 982 CapturedStmt *CS; 983 llvm::SmallVector<Expr *, 8> ImplicitFirstprivate; 984 llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA; 985 986 public: 987 void VisitDeclRefExpr(DeclRefExpr *E) { 988 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 989 // Skip internally declared variables. 990 if (VD->isLocalVarDecl() && !CS->capturesVariable(VD)) 991 return; 992 993 auto DVar = Stack->getTopDSA(VD, false); 994 // Check if the variable has explicit DSA set and stop analysis if it so. 995 if (DVar.RefExpr) return; 996 997 auto ELoc = E->getExprLoc(); 998 auto DKind = Stack->getCurrentDirective(); 999 // The default(none) clause requires that each variable that is referenced 1000 // in the construct, and does not have a predetermined data-sharing 1001 // attribute, must have its data-sharing attribute explicitly determined 1002 // by being listed in a data-sharing attribute clause. 1003 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 1004 isParallelOrTaskRegion(DKind) && 1005 VarsWithInheritedDSA.count(VD) == 0) { 1006 VarsWithInheritedDSA[VD] = E; 1007 return; 1008 } 1009 1010 // OpenMP [2.9.3.6, Restrictions, p.2] 1011 // A list item that appears in a reduction clause of the innermost 1012 // enclosing worksharing or parallel construct may not be accessed in an 1013 // explicit task. 1014 DVar = Stack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction), 1015 [](OpenMPDirectiveKind K) -> bool { 1016 return isOpenMPParallelDirective(K) || 1017 isOpenMPWorksharingDirective(K) || 1018 isOpenMPTeamsDirective(K); 1019 }, 1020 false); 1021 if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) { 1022 ErrorFound = true; 1023 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1024 ReportOriginalDSA(SemaRef, Stack, VD, DVar); 1025 return; 1026 } 1027 1028 // Define implicit data-sharing attributes for task. 1029 DVar = Stack->getImplicitDSA(VD, false); 1030 if (DKind == OMPD_task && DVar.CKind != OMPC_shared) 1031 ImplicitFirstprivate.push_back(E); 1032 } 1033 } 1034 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 1035 for (auto *C : S->clauses()) { 1036 // Skip analysis of arguments of implicitly defined firstprivate clause 1037 // for task directives. 1038 if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid())) 1039 for (auto *CC : C->children()) { 1040 if (CC) 1041 Visit(CC); 1042 } 1043 } 1044 } 1045 void VisitStmt(Stmt *S) { 1046 for (auto *C : S->children()) { 1047 if (C && !isa<OMPExecutableDirective>(C)) 1048 Visit(C); 1049 } 1050 } 1051 1052 bool isErrorFound() { return ErrorFound; } 1053 ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; } 1054 llvm::DenseMap<VarDecl *, Expr *> &getVarsWithInheritedDSA() { 1055 return VarsWithInheritedDSA; 1056 } 1057 1058 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 1059 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} 1060 }; 1061 } // namespace 1062 1063 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 1064 switch (DKind) { 1065 case OMPD_parallel: { 1066 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1067 QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); 1068 Sema::CapturedParamNameType Params[] = { 1069 std::make_pair(".global_tid.", KmpInt32PtrTy), 1070 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1071 std::make_pair(StringRef(), QualType()) // __context with shared vars 1072 }; 1073 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1074 Params); 1075 break; 1076 } 1077 case OMPD_simd: { 1078 Sema::CapturedParamNameType Params[] = { 1079 std::make_pair(StringRef(), QualType()) // __context with shared vars 1080 }; 1081 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1082 Params); 1083 break; 1084 } 1085 case OMPD_for: { 1086 Sema::CapturedParamNameType Params[] = { 1087 std::make_pair(StringRef(), QualType()) // __context with shared vars 1088 }; 1089 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1090 Params); 1091 break; 1092 } 1093 case OMPD_for_simd: { 1094 Sema::CapturedParamNameType Params[] = { 1095 std::make_pair(StringRef(), QualType()) // __context with shared vars 1096 }; 1097 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1098 Params); 1099 break; 1100 } 1101 case OMPD_sections: { 1102 Sema::CapturedParamNameType Params[] = { 1103 std::make_pair(StringRef(), QualType()) // __context with shared vars 1104 }; 1105 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1106 Params); 1107 break; 1108 } 1109 case OMPD_section: { 1110 Sema::CapturedParamNameType Params[] = { 1111 std::make_pair(StringRef(), QualType()) // __context with shared vars 1112 }; 1113 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1114 Params); 1115 break; 1116 } 1117 case OMPD_single: { 1118 Sema::CapturedParamNameType Params[] = { 1119 std::make_pair(StringRef(), QualType()) // __context with shared vars 1120 }; 1121 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1122 Params); 1123 break; 1124 } 1125 case OMPD_master: { 1126 Sema::CapturedParamNameType Params[] = { 1127 std::make_pair(StringRef(), QualType()) // __context with shared vars 1128 }; 1129 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1130 Params); 1131 break; 1132 } 1133 case OMPD_critical: { 1134 Sema::CapturedParamNameType Params[] = { 1135 std::make_pair(StringRef(), QualType()) // __context with shared vars 1136 }; 1137 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1138 Params); 1139 break; 1140 } 1141 case OMPD_parallel_for: { 1142 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1143 QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); 1144 Sema::CapturedParamNameType Params[] = { 1145 std::make_pair(".global_tid.", KmpInt32PtrTy), 1146 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1147 std::make_pair(StringRef(), QualType()) // __context with shared vars 1148 }; 1149 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1150 Params); 1151 break; 1152 } 1153 case OMPD_parallel_for_simd: { 1154 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1155 QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); 1156 Sema::CapturedParamNameType Params[] = { 1157 std::make_pair(".global_tid.", KmpInt32PtrTy), 1158 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1159 std::make_pair(StringRef(), QualType()) // __context with shared vars 1160 }; 1161 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1162 Params); 1163 break; 1164 } 1165 case OMPD_parallel_sections: { 1166 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1167 QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); 1168 Sema::CapturedParamNameType Params[] = { 1169 std::make_pair(".global_tid.", KmpInt32PtrTy), 1170 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1171 std::make_pair(StringRef(), QualType()) // __context with shared vars 1172 }; 1173 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1174 Params); 1175 break; 1176 } 1177 case OMPD_task: { 1178 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1179 Sema::CapturedParamNameType Params[] = { 1180 std::make_pair(".global_tid.", KmpInt32Ty), 1181 std::make_pair(".part_id.", KmpInt32Ty), 1182 std::make_pair(StringRef(), QualType()) // __context with shared vars 1183 }; 1184 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1185 Params); 1186 // Mark this captured region as inlined, because we don't use outlined 1187 // function directly. 1188 getCurCapturedRegion()->TheCapturedDecl->addAttr( 1189 AlwaysInlineAttr::CreateImplicit( 1190 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 1191 break; 1192 } 1193 case OMPD_ordered: { 1194 Sema::CapturedParamNameType Params[] = { 1195 std::make_pair(StringRef(), QualType()) // __context with shared vars 1196 }; 1197 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1198 Params); 1199 break; 1200 } 1201 case OMPD_atomic: { 1202 Sema::CapturedParamNameType Params[] = { 1203 std::make_pair(StringRef(), QualType()) // __context with shared vars 1204 }; 1205 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1206 Params); 1207 break; 1208 } 1209 case OMPD_target: { 1210 Sema::CapturedParamNameType Params[] = { 1211 std::make_pair(StringRef(), QualType()) // __context with shared vars 1212 }; 1213 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1214 Params); 1215 break; 1216 } 1217 case OMPD_teams: { 1218 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1219 QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); 1220 Sema::CapturedParamNameType Params[] = { 1221 std::make_pair(".global_tid.", KmpInt32PtrTy), 1222 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1223 std::make_pair(StringRef(), QualType()) // __context with shared vars 1224 }; 1225 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1226 Params); 1227 break; 1228 } 1229 case OMPD_threadprivate: 1230 case OMPD_taskyield: 1231 case OMPD_barrier: 1232 case OMPD_taskwait: 1233 case OMPD_flush: 1234 llvm_unreachable("OpenMP Directive is not allowed"); 1235 case OMPD_unknown: 1236 llvm_unreachable("Unknown OpenMP directive"); 1237 } 1238 } 1239 1240 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 1241 ArrayRef<OMPClause *> Clauses) { 1242 if (!S.isUsable()) { 1243 ActOnCapturedRegionError(); 1244 return StmtError(); 1245 } 1246 // Mark all variables in private list clauses as used in inner region. This is 1247 // required for proper codegen. 1248 for (auto *Clause : Clauses) { 1249 if (isOpenMPPrivate(Clause->getClauseKind())) { 1250 for (auto *VarRef : Clause->children()) { 1251 if (auto *E = cast_or_null<Expr>(VarRef)) { 1252 MarkDeclarationsReferencedInExpr(E); 1253 } 1254 } 1255 } 1256 } 1257 return ActOnCapturedRegionEnd(S.get()); 1258 } 1259 1260 static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, 1261 OpenMPDirectiveKind CurrentRegion, 1262 const DeclarationNameInfo &CurrentName, 1263 SourceLocation StartLoc) { 1264 // Allowed nesting of constructs 1265 // +------------------+-----------------+------------------------------------+ 1266 // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)| 1267 // +------------------+-----------------+------------------------------------+ 1268 // | parallel | parallel | * | 1269 // | parallel | for | * | 1270 // | parallel | for simd | * | 1271 // | parallel | master | * | 1272 // | parallel | critical | * | 1273 // | parallel | simd | * | 1274 // | parallel | sections | * | 1275 // | parallel | section | + | 1276 // | parallel | single | * | 1277 // | parallel | parallel for | * | 1278 // | parallel |parallel for simd| * | 1279 // | parallel |parallel sections| * | 1280 // | parallel | task | * | 1281 // | parallel | taskyield | * | 1282 // | parallel | barrier | * | 1283 // | parallel | taskwait | * | 1284 // | parallel | flush | * | 1285 // | parallel | ordered | + | 1286 // | parallel | atomic | * | 1287 // | parallel | target | * | 1288 // | parallel | teams | + | 1289 // +------------------+-----------------+------------------------------------+ 1290 // | for | parallel | * | 1291 // | for | for | + | 1292 // | for | for simd | + | 1293 // | for | master | + | 1294 // | for | critical | * | 1295 // | for | simd | * | 1296 // | for | sections | + | 1297 // | for | section | + | 1298 // | for | single | + | 1299 // | for | parallel for | * | 1300 // | for |parallel for simd| * | 1301 // | for |parallel sections| * | 1302 // | for | task | * | 1303 // | for | taskyield | * | 1304 // | for | barrier | + | 1305 // | for | taskwait | * | 1306 // | for | flush | * | 1307 // | for | ordered | * (if construct is ordered) | 1308 // | for | atomic | * | 1309 // | for | target | * | 1310 // | for | teams | + | 1311 // +------------------+-----------------+------------------------------------+ 1312 // | master | parallel | * | 1313 // | master | for | + | 1314 // | master | for simd | + | 1315 // | master | master | * | 1316 // | master | critical | * | 1317 // | master | simd | * | 1318 // | master | sections | + | 1319 // | master | section | + | 1320 // | master | single | + | 1321 // | master | parallel for | * | 1322 // | master |parallel for simd| * | 1323 // | master |parallel sections| * | 1324 // | master | task | * | 1325 // | master | taskyield | * | 1326 // | master | barrier | + | 1327 // | master | taskwait | * | 1328 // | master | flush | * | 1329 // | master | ordered | + | 1330 // | master | atomic | * | 1331 // | master | target | * | 1332 // | master | teams | + | 1333 // +------------------+-----------------+------------------------------------+ 1334 // | critical | parallel | * | 1335 // | critical | for | + | 1336 // | critical | for simd | + | 1337 // | critical | master | * | 1338 // | critical | critical | * (should have different names) | 1339 // | critical | simd | * | 1340 // | critical | sections | + | 1341 // | critical | section | + | 1342 // | critical | single | + | 1343 // | critical | parallel for | * | 1344 // | critical |parallel for simd| * | 1345 // | critical |parallel sections| * | 1346 // | critical | task | * | 1347 // | critical | taskyield | * | 1348 // | critical | barrier | + | 1349 // | critical | taskwait | * | 1350 // | critical | ordered | + | 1351 // | critical | atomic | * | 1352 // | critical | target | * | 1353 // | critical | teams | + | 1354 // +------------------+-----------------+------------------------------------+ 1355 // | simd | parallel | | 1356 // | simd | for | | 1357 // | simd | for simd | | 1358 // | simd | master | | 1359 // | simd | critical | | 1360 // | simd | simd | | 1361 // | simd | sections | | 1362 // | simd | section | | 1363 // | simd | single | | 1364 // | simd | parallel for | | 1365 // | simd |parallel for simd| | 1366 // | simd |parallel sections| | 1367 // | simd | task | | 1368 // | simd | taskyield | | 1369 // | simd | barrier | | 1370 // | simd | taskwait | | 1371 // | simd | flush | | 1372 // | simd | ordered | | 1373 // | simd | atomic | | 1374 // | simd | target | | 1375 // | simd | teams | | 1376 // +------------------+-----------------+------------------------------------+ 1377 // | for simd | parallel | | 1378 // | for simd | for | | 1379 // | for simd | for simd | | 1380 // | for simd | master | | 1381 // | for simd | critical | | 1382 // | for simd | simd | | 1383 // | for simd | sections | | 1384 // | for simd | section | | 1385 // | for simd | single | | 1386 // | for simd | parallel for | | 1387 // | for simd |parallel for simd| | 1388 // | for simd |parallel sections| | 1389 // | for simd | task | | 1390 // | for simd | taskyield | | 1391 // | for simd | barrier | | 1392 // | for simd | taskwait | | 1393 // | for simd | flush | | 1394 // | for simd | ordered | | 1395 // | for simd | atomic | | 1396 // | for simd | target | | 1397 // | for simd | teams | | 1398 // +------------------+-----------------+------------------------------------+ 1399 // | parallel for simd| parallel | | 1400 // | parallel for simd| for | | 1401 // | parallel for simd| for simd | | 1402 // | parallel for simd| master | | 1403 // | parallel for simd| critical | | 1404 // | parallel for simd| simd | | 1405 // | parallel for simd| sections | | 1406 // | parallel for simd| section | | 1407 // | parallel for simd| single | | 1408 // | parallel for simd| parallel for | | 1409 // | parallel for simd|parallel for simd| | 1410 // | parallel for simd|parallel sections| | 1411 // | parallel for simd| task | | 1412 // | parallel for simd| taskyield | | 1413 // | parallel for simd| barrier | | 1414 // | parallel for simd| taskwait | | 1415 // | parallel for simd| flush | | 1416 // | parallel for simd| ordered | | 1417 // | parallel for simd| atomic | | 1418 // | parallel for simd| target | | 1419 // | parallel for simd| teams | | 1420 // +------------------+-----------------+------------------------------------+ 1421 // | sections | parallel | * | 1422 // | sections | for | + | 1423 // | sections | for simd | + | 1424 // | sections | master | + | 1425 // | sections | critical | * | 1426 // | sections | simd | * | 1427 // | sections | sections | + | 1428 // | sections | section | * | 1429 // | sections | single | + | 1430 // | sections | parallel for | * | 1431 // | sections |parallel for simd| * | 1432 // | sections |parallel sections| * | 1433 // | sections | task | * | 1434 // | sections | taskyield | * | 1435 // | sections | barrier | + | 1436 // | sections | taskwait | * | 1437 // | sections | flush | * | 1438 // | sections | ordered | + | 1439 // | sections | atomic | * | 1440 // | sections | target | * | 1441 // | sections | teams | + | 1442 // +------------------+-----------------+------------------------------------+ 1443 // | section | parallel | * | 1444 // | section | for | + | 1445 // | section | for simd | + | 1446 // | section | master | + | 1447 // | section | critical | * | 1448 // | section | simd | * | 1449 // | section | sections | + | 1450 // | section | section | + | 1451 // | section | single | + | 1452 // | section | parallel for | * | 1453 // | section |parallel for simd| * | 1454 // | section |parallel sections| * | 1455 // | section | task | * | 1456 // | section | taskyield | * | 1457 // | section | barrier | + | 1458 // | section | taskwait | * | 1459 // | section | flush | * | 1460 // | section | ordered | + | 1461 // | section | atomic | * | 1462 // | section | target | * | 1463 // | section | teams | + | 1464 // +------------------+-----------------+------------------------------------+ 1465 // | single | parallel | * | 1466 // | single | for | + | 1467 // | single | for simd | + | 1468 // | single | master | + | 1469 // | single | critical | * | 1470 // | single | simd | * | 1471 // | single | sections | + | 1472 // | single | section | + | 1473 // | single | single | + | 1474 // | single | parallel for | * | 1475 // | single |parallel for simd| * | 1476 // | single |parallel sections| * | 1477 // | single | task | * | 1478 // | single | taskyield | * | 1479 // | single | barrier | + | 1480 // | single | taskwait | * | 1481 // | single | flush | * | 1482 // | single | ordered | + | 1483 // | single | atomic | * | 1484 // | single | target | * | 1485 // | single | teams | + | 1486 // +------------------+-----------------+------------------------------------+ 1487 // | parallel for | parallel | * | 1488 // | parallel for | for | + | 1489 // | parallel for | for simd | + | 1490 // | parallel for | master | + | 1491 // | parallel for | critical | * | 1492 // | parallel for | simd | * | 1493 // | parallel for | sections | + | 1494 // | parallel for | section | + | 1495 // | parallel for | single | + | 1496 // | parallel for | parallel for | * | 1497 // | parallel for |parallel for simd| * | 1498 // | parallel for |parallel sections| * | 1499 // | parallel for | task | * | 1500 // | parallel for | taskyield | * | 1501 // | parallel for | barrier | + | 1502 // | parallel for | taskwait | * | 1503 // | parallel for | flush | * | 1504 // | parallel for | ordered | * (if construct is ordered) | 1505 // | parallel for | atomic | * | 1506 // | parallel for | target | * | 1507 // | parallel for | teams | + | 1508 // +------------------+-----------------+------------------------------------+ 1509 // | parallel sections| parallel | * | 1510 // | parallel sections| for | + | 1511 // | parallel sections| for simd | + | 1512 // | parallel sections| master | + | 1513 // | parallel sections| critical | + | 1514 // | parallel sections| simd | * | 1515 // | parallel sections| sections | + | 1516 // | parallel sections| section | * | 1517 // | parallel sections| single | + | 1518 // | parallel sections| parallel for | * | 1519 // | parallel sections|parallel for simd| * | 1520 // | parallel sections|parallel sections| * | 1521 // | parallel sections| task | * | 1522 // | parallel sections| taskyield | * | 1523 // | parallel sections| barrier | + | 1524 // | parallel sections| taskwait | * | 1525 // | parallel sections| flush | * | 1526 // | parallel sections| ordered | + | 1527 // | parallel sections| atomic | * | 1528 // | parallel sections| target | * | 1529 // | parallel sections| teams | + | 1530 // +------------------+-----------------+------------------------------------+ 1531 // | task | parallel | * | 1532 // | task | for | + | 1533 // | task | for simd | + | 1534 // | task | master | + | 1535 // | task | critical | * | 1536 // | task | simd | * | 1537 // | task | sections | + | 1538 // | task | section | + | 1539 // | task | single | + | 1540 // | task | parallel for | * | 1541 // | task |parallel for simd| * | 1542 // | task |parallel sections| * | 1543 // | task | task | * | 1544 // | task | taskyield | * | 1545 // | task | barrier | + | 1546 // | task | taskwait | * | 1547 // | task | flush | * | 1548 // | task | ordered | + | 1549 // | task | atomic | * | 1550 // | task | target | * | 1551 // | task | teams | + | 1552 // +------------------+-----------------+------------------------------------+ 1553 // | ordered | parallel | * | 1554 // | ordered | for | + | 1555 // | ordered | for simd | + | 1556 // | ordered | master | * | 1557 // | ordered | critical | * | 1558 // | ordered | simd | * | 1559 // | ordered | sections | + | 1560 // | ordered | section | + | 1561 // | ordered | single | + | 1562 // | ordered | parallel for | * | 1563 // | ordered |parallel for simd| * | 1564 // | ordered |parallel sections| * | 1565 // | ordered | task | * | 1566 // | ordered | taskyield | * | 1567 // | ordered | barrier | + | 1568 // | ordered | taskwait | * | 1569 // | ordered | flush | * | 1570 // | ordered | ordered | + | 1571 // | ordered | atomic | * | 1572 // | ordered | target | * | 1573 // | ordered | teams | + | 1574 // +------------------+-----------------+------------------------------------+ 1575 // | atomic | parallel | | 1576 // | atomic | for | | 1577 // | atomic | for simd | | 1578 // | atomic | master | | 1579 // | atomic | critical | | 1580 // | atomic | simd | | 1581 // | atomic | sections | | 1582 // | atomic | section | | 1583 // | atomic | single | | 1584 // | atomic | parallel for | | 1585 // | atomic |parallel for simd| | 1586 // | atomic |parallel sections| | 1587 // | atomic | task | | 1588 // | atomic | taskyield | | 1589 // | atomic | barrier | | 1590 // | atomic | taskwait | | 1591 // | atomic | flush | | 1592 // | atomic | ordered | | 1593 // | atomic | atomic | | 1594 // | atomic | target | | 1595 // | atomic | teams | | 1596 // +------------------+-----------------+------------------------------------+ 1597 // | target | parallel | * | 1598 // | target | for | * | 1599 // | target | for simd | * | 1600 // | target | master | * | 1601 // | target | critical | * | 1602 // | target | simd | * | 1603 // | target | sections | * | 1604 // | target | section | * | 1605 // | target | single | * | 1606 // | target | parallel for | * | 1607 // | target |parallel for simd| * | 1608 // | target |parallel sections| * | 1609 // | target | task | * | 1610 // | target | taskyield | * | 1611 // | target | barrier | * | 1612 // | target | taskwait | * | 1613 // | target | flush | * | 1614 // | target | ordered | * | 1615 // | target | atomic | * | 1616 // | target | target | * | 1617 // | target | teams | * | 1618 // +------------------+-----------------+------------------------------------+ 1619 // | teams | parallel | * | 1620 // | teams | for | + | 1621 // | teams | for simd | + | 1622 // | teams | master | + | 1623 // | teams | critical | + | 1624 // | teams | simd | + | 1625 // | teams | sections | + | 1626 // | teams | section | + | 1627 // | teams | single | + | 1628 // | teams | parallel for | * | 1629 // | teams |parallel for simd| * | 1630 // | teams |parallel sections| * | 1631 // | teams | task | + | 1632 // | teams | taskyield | + | 1633 // | teams | barrier | + | 1634 // | teams | taskwait | + | 1635 // | teams | flush | + | 1636 // | teams | ordered | + | 1637 // | teams | atomic | + | 1638 // | teams | target | + | 1639 // | teams | teams | + | 1640 // +------------------+-----------------+------------------------------------+ 1641 if (Stack->getCurScope()) { 1642 auto ParentRegion = Stack->getParentDirective(); 1643 bool NestingProhibited = false; 1644 bool CloseNesting = true; 1645 enum { 1646 NoRecommend, 1647 ShouldBeInParallelRegion, 1648 ShouldBeInOrderedRegion, 1649 ShouldBeInTargetRegion 1650 } Recommend = NoRecommend; 1651 if (isOpenMPSimdDirective(ParentRegion)) { 1652 // OpenMP [2.16, Nesting of Regions] 1653 // OpenMP constructs may not be nested inside a simd region. 1654 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd); 1655 return true; 1656 } 1657 if (ParentRegion == OMPD_atomic) { 1658 // OpenMP [2.16, Nesting of Regions] 1659 // OpenMP constructs may not be nested inside an atomic region. 1660 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 1661 return true; 1662 } 1663 if (CurrentRegion == OMPD_section) { 1664 // OpenMP [2.7.2, sections Construct, Restrictions] 1665 // Orphaned section directives are prohibited. That is, the section 1666 // directives must appear within the sections construct and must not be 1667 // encountered elsewhere in the sections region. 1668 if (ParentRegion != OMPD_sections && 1669 ParentRegion != OMPD_parallel_sections) { 1670 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 1671 << (ParentRegion != OMPD_unknown) 1672 << getOpenMPDirectiveName(ParentRegion); 1673 return true; 1674 } 1675 return false; 1676 } 1677 // Allow some constructs to be orphaned (they could be used in functions, 1678 // called from OpenMP regions with the required preconditions). 1679 if (ParentRegion == OMPD_unknown) 1680 return false; 1681 if (CurrentRegion == OMPD_master) { 1682 // OpenMP [2.16, Nesting of Regions] 1683 // A master region may not be closely nested inside a worksharing, 1684 // atomic, or explicit task region. 1685 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 1686 ParentRegion == OMPD_task; 1687 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 1688 // OpenMP [2.16, Nesting of Regions] 1689 // A critical region may not be nested (closely or otherwise) inside a 1690 // critical region with the same name. Note that this restriction is not 1691 // sufficient to prevent deadlock. 1692 SourceLocation PreviousCriticalLoc; 1693 bool DeadLock = 1694 Stack->hasDirective([CurrentName, &PreviousCriticalLoc]( 1695 OpenMPDirectiveKind K, 1696 const DeclarationNameInfo &DNI, 1697 SourceLocation Loc) 1698 ->bool { 1699 if (K == OMPD_critical && 1700 DNI.getName() == CurrentName.getName()) { 1701 PreviousCriticalLoc = Loc; 1702 return true; 1703 } else 1704 return false; 1705 }, 1706 false /* skip top directive */); 1707 if (DeadLock) { 1708 SemaRef.Diag(StartLoc, 1709 diag::err_omp_prohibited_region_critical_same_name) 1710 << CurrentName.getName(); 1711 if (PreviousCriticalLoc.isValid()) 1712 SemaRef.Diag(PreviousCriticalLoc, 1713 diag::note_omp_previous_critical_region); 1714 return true; 1715 } 1716 } else if (CurrentRegion == OMPD_barrier) { 1717 // OpenMP [2.16, Nesting of Regions] 1718 // A barrier region may not be closely nested inside a worksharing, 1719 // explicit task, critical, ordered, atomic, or master region. 1720 NestingProhibited = 1721 isOpenMPWorksharingDirective(ParentRegion) || 1722 ParentRegion == OMPD_task || ParentRegion == OMPD_master || 1723 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 1724 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 1725 !isOpenMPParallelDirective(CurrentRegion)) { 1726 // OpenMP [2.16, Nesting of Regions] 1727 // A worksharing region may not be closely nested inside a worksharing, 1728 // explicit task, critical, ordered, atomic, or master region. 1729 NestingProhibited = 1730 isOpenMPWorksharingDirective(ParentRegion) || 1731 ParentRegion == OMPD_task || ParentRegion == OMPD_master || 1732 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 1733 Recommend = ShouldBeInParallelRegion; 1734 } else if (CurrentRegion == OMPD_ordered) { 1735 // OpenMP [2.16, Nesting of Regions] 1736 // An ordered region may not be closely nested inside a critical, 1737 // atomic, or explicit task region. 1738 // An ordered region must be closely nested inside a loop region (or 1739 // parallel loop region) with an ordered clause. 1740 NestingProhibited = ParentRegion == OMPD_critical || 1741 ParentRegion == OMPD_task || 1742 !Stack->isParentOrderedRegion(); 1743 Recommend = ShouldBeInOrderedRegion; 1744 } else if (isOpenMPTeamsDirective(CurrentRegion)) { 1745 // OpenMP [2.16, Nesting of Regions] 1746 // If specified, a teams construct must be contained within a target 1747 // construct. 1748 NestingProhibited = ParentRegion != OMPD_target; 1749 Recommend = ShouldBeInTargetRegion; 1750 Stack->setParentTeamsRegionLoc(Stack->getConstructLoc()); 1751 } 1752 if (!NestingProhibited && isOpenMPTeamsDirective(ParentRegion)) { 1753 // OpenMP [2.16, Nesting of Regions] 1754 // distribute, parallel, parallel sections, parallel workshare, and the 1755 // parallel loop and parallel loop SIMD constructs are the only OpenMP 1756 // constructs that can be closely nested in the teams region. 1757 // TODO: add distribute directive. 1758 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion); 1759 Recommend = ShouldBeInParallelRegion; 1760 } 1761 if (NestingProhibited) { 1762 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 1763 << CloseNesting << getOpenMPDirectiveName(ParentRegion) << Recommend 1764 << getOpenMPDirectiveName(CurrentRegion); 1765 return true; 1766 } 1767 } 1768 return false; 1769 } 1770 1771 StmtResult Sema::ActOnOpenMPExecutableDirective(OpenMPDirectiveKind Kind, 1772 const DeclarationNameInfo &DirName, 1773 ArrayRef<OMPClause *> Clauses, 1774 Stmt *AStmt, 1775 SourceLocation StartLoc, 1776 SourceLocation EndLoc) { 1777 StmtResult Res = StmtError(); 1778 if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, StartLoc)) 1779 return StmtError(); 1780 1781 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 1782 llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA; 1783 bool ErrorFound = false; 1784 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 1785 if (AStmt) { 1786 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 1787 1788 // Check default data sharing attributes for referenced variables. 1789 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 1790 DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt()); 1791 if (DSAChecker.isErrorFound()) 1792 return StmtError(); 1793 // Generate list of implicitly defined firstprivate variables. 1794 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 1795 1796 if (!DSAChecker.getImplicitFirstprivate().empty()) { 1797 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 1798 DSAChecker.getImplicitFirstprivate(), SourceLocation(), 1799 SourceLocation(), SourceLocation())) { 1800 ClausesWithImplicit.push_back(Implicit); 1801 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 1802 DSAChecker.getImplicitFirstprivate().size(); 1803 } else 1804 ErrorFound = true; 1805 } 1806 } 1807 1808 switch (Kind) { 1809 case OMPD_parallel: 1810 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 1811 EndLoc); 1812 break; 1813 case OMPD_simd: 1814 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 1815 VarsWithInheritedDSA); 1816 break; 1817 case OMPD_for: 1818 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 1819 VarsWithInheritedDSA); 1820 break; 1821 case OMPD_for_simd: 1822 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 1823 EndLoc, VarsWithInheritedDSA); 1824 break; 1825 case OMPD_sections: 1826 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 1827 EndLoc); 1828 break; 1829 case OMPD_section: 1830 assert(ClausesWithImplicit.empty() && 1831 "No clauses are allowed for 'omp section' directive"); 1832 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 1833 break; 1834 case OMPD_single: 1835 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 1836 EndLoc); 1837 break; 1838 case OMPD_master: 1839 assert(ClausesWithImplicit.empty() && 1840 "No clauses are allowed for 'omp master' directive"); 1841 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 1842 break; 1843 case OMPD_critical: 1844 assert(ClausesWithImplicit.empty() && 1845 "No clauses are allowed for 'omp critical' directive"); 1846 Res = ActOnOpenMPCriticalDirective(DirName, AStmt, StartLoc, EndLoc); 1847 break; 1848 case OMPD_parallel_for: 1849 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 1850 EndLoc, VarsWithInheritedDSA); 1851 break; 1852 case OMPD_parallel_for_simd: 1853 Res = ActOnOpenMPParallelForSimdDirective( 1854 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 1855 break; 1856 case OMPD_parallel_sections: 1857 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 1858 StartLoc, EndLoc); 1859 break; 1860 case OMPD_task: 1861 Res = 1862 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 1863 break; 1864 case OMPD_taskyield: 1865 assert(ClausesWithImplicit.empty() && 1866 "No clauses are allowed for 'omp taskyield' directive"); 1867 assert(AStmt == nullptr && 1868 "No associated statement allowed for 'omp taskyield' directive"); 1869 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 1870 break; 1871 case OMPD_barrier: 1872 assert(ClausesWithImplicit.empty() && 1873 "No clauses are allowed for 'omp barrier' directive"); 1874 assert(AStmt == nullptr && 1875 "No associated statement allowed for 'omp barrier' directive"); 1876 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 1877 break; 1878 case OMPD_taskwait: 1879 assert(ClausesWithImplicit.empty() && 1880 "No clauses are allowed for 'omp taskwait' directive"); 1881 assert(AStmt == nullptr && 1882 "No associated statement allowed for 'omp taskwait' directive"); 1883 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 1884 break; 1885 case OMPD_flush: 1886 assert(AStmt == nullptr && 1887 "No associated statement allowed for 'omp flush' directive"); 1888 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 1889 break; 1890 case OMPD_ordered: 1891 assert(ClausesWithImplicit.empty() && 1892 "No clauses are allowed for 'omp ordered' directive"); 1893 Res = ActOnOpenMPOrderedDirective(AStmt, StartLoc, EndLoc); 1894 break; 1895 case OMPD_atomic: 1896 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 1897 EndLoc); 1898 break; 1899 case OMPD_teams: 1900 Res = 1901 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 1902 break; 1903 case OMPD_target: 1904 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 1905 EndLoc); 1906 break; 1907 case OMPD_threadprivate: 1908 llvm_unreachable("OpenMP Directive is not allowed"); 1909 case OMPD_unknown: 1910 llvm_unreachable("Unknown OpenMP directive"); 1911 } 1912 1913 for (auto P : VarsWithInheritedDSA) { 1914 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 1915 << P.first << P.second->getSourceRange(); 1916 } 1917 if (!VarsWithInheritedDSA.empty()) 1918 return StmtError(); 1919 1920 if (ErrorFound) 1921 return StmtError(); 1922 return Res; 1923 } 1924 1925 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 1926 Stmt *AStmt, 1927 SourceLocation StartLoc, 1928 SourceLocation EndLoc) { 1929 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 1930 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 1931 // 1.2.2 OpenMP Language Terminology 1932 // Structured block - An executable statement with a single entry at the 1933 // top and a single exit at the bottom. 1934 // The point of exit cannot be a branch out of the structured block. 1935 // longjmp() and throw() must not violate the entry/exit criteria. 1936 CS->getCapturedDecl()->setNothrow(); 1937 1938 getCurFunction()->setHasBranchProtectedScope(); 1939 1940 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 1941 AStmt); 1942 } 1943 1944 namespace { 1945 /// \brief Helper class for checking canonical form of the OpenMP loops and 1946 /// extracting iteration space of each loop in the loop nest, that will be used 1947 /// for IR generation. 1948 class OpenMPIterationSpaceChecker { 1949 /// \brief Reference to Sema. 1950 Sema &SemaRef; 1951 /// \brief A location for diagnostics (when there is no some better location). 1952 SourceLocation DefaultLoc; 1953 /// \brief A location for diagnostics (when increment is not compatible). 1954 SourceLocation ConditionLoc; 1955 /// \brief A source location for referring to loop init later. 1956 SourceRange InitSrcRange; 1957 /// \brief A source location for referring to condition later. 1958 SourceRange ConditionSrcRange; 1959 /// \brief A source location for referring to increment later. 1960 SourceRange IncrementSrcRange; 1961 /// \brief Loop variable. 1962 VarDecl *Var; 1963 /// \brief Reference to loop variable. 1964 DeclRefExpr *VarRef; 1965 /// \brief Lower bound (initializer for the var). 1966 Expr *LB; 1967 /// \brief Upper bound. 1968 Expr *UB; 1969 /// \brief Loop step (increment). 1970 Expr *Step; 1971 /// \brief This flag is true when condition is one of: 1972 /// Var < UB 1973 /// Var <= UB 1974 /// UB > Var 1975 /// UB >= Var 1976 bool TestIsLessOp; 1977 /// \brief This flag is true when condition is strict ( < or > ). 1978 bool TestIsStrictOp; 1979 /// \brief This flag is true when step is subtracted on each iteration. 1980 bool SubtractStep; 1981 1982 public: 1983 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 1984 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc), 1985 InitSrcRange(SourceRange()), ConditionSrcRange(SourceRange()), 1986 IncrementSrcRange(SourceRange()), Var(nullptr), VarRef(nullptr), 1987 LB(nullptr), UB(nullptr), Step(nullptr), TestIsLessOp(false), 1988 TestIsStrictOp(false), SubtractStep(false) {} 1989 /// \brief Check init-expr for canonical loop form and save loop counter 1990 /// variable - #Var and its initialization value - #LB. 1991 bool CheckInit(Stmt *S, bool EmitDiags = true); 1992 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags 1993 /// for less/greater and for strict/non-strict comparison. 1994 bool CheckCond(Expr *S); 1995 /// \brief Check incr-expr for canonical loop form and return true if it 1996 /// does not conform, otherwise save loop step (#Step). 1997 bool CheckInc(Expr *S); 1998 /// \brief Return the loop counter variable. 1999 VarDecl *GetLoopVar() const { return Var; } 2000 /// \brief Return the reference expression to loop counter variable. 2001 DeclRefExpr *GetLoopVarRefExpr() const { return VarRef; } 2002 /// \brief Source range of the loop init. 2003 SourceRange GetInitSrcRange() const { return InitSrcRange; } 2004 /// \brief Source range of the loop condition. 2005 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; } 2006 /// \brief Source range of the loop increment. 2007 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; } 2008 /// \brief True if the step should be subtracted. 2009 bool ShouldSubtractStep() const { return SubtractStep; } 2010 /// \brief Build the expression to calculate the number of iterations. 2011 Expr *BuildNumIterations(Scope *S, const bool LimitedType) const; 2012 /// \brief Build the precondition expression for the loops. 2013 Expr *BuildPreCond(Scope *S, Expr *Cond) const; 2014 /// \brief Build reference expression to the counter be used for codegen. 2015 Expr *BuildCounterVar() const; 2016 /// \brief Build initization of the counter be used for codegen. 2017 Expr *BuildCounterInit() const; 2018 /// \brief Build step of the counter be used for codegen. 2019 Expr *BuildCounterStep() const; 2020 /// \brief Return true if any expression is dependent. 2021 bool Dependent() const; 2022 2023 private: 2024 /// \brief Check the right-hand side of an assignment in the increment 2025 /// expression. 2026 bool CheckIncRHS(Expr *RHS); 2027 /// \brief Helper to set loop counter variable and its initializer. 2028 bool SetVarAndLB(VarDecl *NewVar, DeclRefExpr *NewVarRefExpr, Expr *NewLB); 2029 /// \brief Helper to set upper bound. 2030 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, const SourceRange &SR, 2031 const SourceLocation &SL); 2032 /// \brief Helper to set loop increment. 2033 bool SetStep(Expr *NewStep, bool Subtract); 2034 }; 2035 2036 bool OpenMPIterationSpaceChecker::Dependent() const { 2037 if (!Var) { 2038 assert(!LB && !UB && !Step); 2039 return false; 2040 } 2041 return Var->getType()->isDependentType() || (LB && LB->isValueDependent()) || 2042 (UB && UB->isValueDependent()) || (Step && Step->isValueDependent()); 2043 } 2044 2045 bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar, 2046 DeclRefExpr *NewVarRefExpr, 2047 Expr *NewLB) { 2048 // State consistency checking to ensure correct usage. 2049 assert(Var == nullptr && LB == nullptr && VarRef == nullptr && 2050 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 2051 if (!NewVar || !NewLB) 2052 return true; 2053 Var = NewVar; 2054 VarRef = NewVarRefExpr; 2055 LB = NewLB; 2056 return false; 2057 } 2058 2059 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp, 2060 const SourceRange &SR, 2061 const SourceLocation &SL) { 2062 // State consistency checking to ensure correct usage. 2063 assert(Var != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && 2064 !TestIsLessOp && !TestIsStrictOp); 2065 if (!NewUB) 2066 return true; 2067 UB = NewUB; 2068 TestIsLessOp = LessOp; 2069 TestIsStrictOp = StrictOp; 2070 ConditionSrcRange = SR; 2071 ConditionLoc = SL; 2072 return false; 2073 } 2074 2075 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) { 2076 // State consistency checking to ensure correct usage. 2077 assert(Var != nullptr && LB != nullptr && Step == nullptr); 2078 if (!NewStep) 2079 return true; 2080 if (!NewStep->isValueDependent()) { 2081 // Check that the step is integer expression. 2082 SourceLocation StepLoc = NewStep->getLocStart(); 2083 ExprResult Val = 2084 SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep); 2085 if (Val.isInvalid()) 2086 return true; 2087 NewStep = Val.get(); 2088 2089 // OpenMP [2.6, Canonical Loop Form, Restrictions] 2090 // If test-expr is of form var relational-op b and relational-op is < or 2091 // <= then incr-expr must cause var to increase on each iteration of the 2092 // loop. If test-expr is of form var relational-op b and relational-op is 2093 // > or >= then incr-expr must cause var to decrease on each iteration of 2094 // the loop. 2095 // If test-expr is of form b relational-op var and relational-op is < or 2096 // <= then incr-expr must cause var to decrease on each iteration of the 2097 // loop. If test-expr is of form b relational-op var and relational-op is 2098 // > or >= then incr-expr must cause var to increase on each iteration of 2099 // the loop. 2100 llvm::APSInt Result; 2101 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 2102 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 2103 bool IsConstNeg = 2104 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 2105 bool IsConstPos = 2106 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 2107 bool IsConstZero = IsConstant && !Result.getBoolValue(); 2108 if (UB && (IsConstZero || 2109 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 2110 : (IsConstPos || (IsUnsigned && !Subtract))))) { 2111 SemaRef.Diag(NewStep->getExprLoc(), 2112 diag::err_omp_loop_incr_not_compatible) 2113 << Var << TestIsLessOp << NewStep->getSourceRange(); 2114 SemaRef.Diag(ConditionLoc, 2115 diag::note_omp_loop_cond_requres_compatible_incr) 2116 << TestIsLessOp << ConditionSrcRange; 2117 return true; 2118 } 2119 if (TestIsLessOp == Subtract) { 2120 NewStep = SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, 2121 NewStep).get(); 2122 Subtract = !Subtract; 2123 } 2124 } 2125 2126 Step = NewStep; 2127 SubtractStep = Subtract; 2128 return false; 2129 } 2130 2131 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { 2132 // Check init-expr for canonical loop form and save loop counter 2133 // variable - #Var and its initialization value - #LB. 2134 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 2135 // var = lb 2136 // integer-type var = lb 2137 // random-access-iterator-type var = lb 2138 // pointer-type var = lb 2139 // 2140 if (!S) { 2141 if (EmitDiags) { 2142 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 2143 } 2144 return true; 2145 } 2146 InitSrcRange = S->getSourceRange(); 2147 if (Expr *E = dyn_cast<Expr>(S)) 2148 S = E->IgnoreParens(); 2149 if (auto BO = dyn_cast<BinaryOperator>(S)) { 2150 if (BO->getOpcode() == BO_Assign) 2151 if (auto DRE = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens())) 2152 return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE, 2153 BO->getRHS()); 2154 } else if (auto DS = dyn_cast<DeclStmt>(S)) { 2155 if (DS->isSingleDecl()) { 2156 if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 2157 if (Var->hasInit()) { 2158 // Accept non-canonical init form here but emit ext. warning. 2159 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 2160 SemaRef.Diag(S->getLocStart(), 2161 diag::ext_omp_loop_not_canonical_init) 2162 << S->getSourceRange(); 2163 return SetVarAndLB(Var, nullptr, Var->getInit()); 2164 } 2165 } 2166 } 2167 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) 2168 if (CE->getOperator() == OO_Equal) 2169 if (auto DRE = dyn_cast<DeclRefExpr>(CE->getArg(0))) 2170 return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE, 2171 CE->getArg(1)); 2172 2173 if (EmitDiags) { 2174 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init) 2175 << S->getSourceRange(); 2176 } 2177 return true; 2178 } 2179 2180 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the 2181 /// variable (which may be the loop variable) if possible. 2182 static const VarDecl *GetInitVarDecl(const Expr *E) { 2183 if (!E) 2184 return nullptr; 2185 E = E->IgnoreParenImpCasts(); 2186 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 2187 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 2188 if (Ctor->isCopyConstructor() && CE->getNumArgs() == 1 && 2189 CE->getArg(0) != nullptr) 2190 E = CE->getArg(0)->IgnoreParenImpCasts(); 2191 auto DRE = dyn_cast_or_null<DeclRefExpr>(E); 2192 if (!DRE) 2193 return nullptr; 2194 return dyn_cast<VarDecl>(DRE->getDecl()); 2195 } 2196 2197 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { 2198 // Check test-expr for canonical form, save upper-bound UB, flags for 2199 // less/greater and for strict/non-strict comparison. 2200 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 2201 // var relational-op b 2202 // b relational-op var 2203 // 2204 if (!S) { 2205 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << Var; 2206 return true; 2207 } 2208 S = S->IgnoreParenImpCasts(); 2209 SourceLocation CondLoc = S->getLocStart(); 2210 if (auto BO = dyn_cast<BinaryOperator>(S)) { 2211 if (BO->isRelationalOp()) { 2212 if (GetInitVarDecl(BO->getLHS()) == Var) 2213 return SetUB(BO->getRHS(), 2214 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 2215 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 2216 BO->getSourceRange(), BO->getOperatorLoc()); 2217 if (GetInitVarDecl(BO->getRHS()) == Var) 2218 return SetUB(BO->getLHS(), 2219 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 2220 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 2221 BO->getSourceRange(), BO->getOperatorLoc()); 2222 } 2223 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 2224 if (CE->getNumArgs() == 2) { 2225 auto Op = CE->getOperator(); 2226 switch (Op) { 2227 case OO_Greater: 2228 case OO_GreaterEqual: 2229 case OO_Less: 2230 case OO_LessEqual: 2231 if (GetInitVarDecl(CE->getArg(0)) == Var) 2232 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 2233 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 2234 CE->getOperatorLoc()); 2235 if (GetInitVarDecl(CE->getArg(1)) == Var) 2236 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 2237 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 2238 CE->getOperatorLoc()); 2239 break; 2240 default: 2241 break; 2242 } 2243 } 2244 } 2245 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 2246 << S->getSourceRange() << Var; 2247 return true; 2248 } 2249 2250 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) { 2251 // RHS of canonical loop form increment can be: 2252 // var + incr 2253 // incr + var 2254 // var - incr 2255 // 2256 RHS = RHS->IgnoreParenImpCasts(); 2257 if (auto BO = dyn_cast<BinaryOperator>(RHS)) { 2258 if (BO->isAdditiveOp()) { 2259 bool IsAdd = BO->getOpcode() == BO_Add; 2260 if (GetInitVarDecl(BO->getLHS()) == Var) 2261 return SetStep(BO->getRHS(), !IsAdd); 2262 if (IsAdd && GetInitVarDecl(BO->getRHS()) == Var) 2263 return SetStep(BO->getLHS(), false); 2264 } 2265 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 2266 bool IsAdd = CE->getOperator() == OO_Plus; 2267 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 2268 if (GetInitVarDecl(CE->getArg(0)) == Var) 2269 return SetStep(CE->getArg(1), !IsAdd); 2270 if (IsAdd && GetInitVarDecl(CE->getArg(1)) == Var) 2271 return SetStep(CE->getArg(0), false); 2272 } 2273 } 2274 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr) 2275 << RHS->getSourceRange() << Var; 2276 return true; 2277 } 2278 2279 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { 2280 // Check incr-expr for canonical loop form and return true if it 2281 // does not conform. 2282 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 2283 // ++var 2284 // var++ 2285 // --var 2286 // var-- 2287 // var += incr 2288 // var -= incr 2289 // var = var + incr 2290 // var = incr + var 2291 // var = var - incr 2292 // 2293 if (!S) { 2294 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << Var; 2295 return true; 2296 } 2297 IncrementSrcRange = S->getSourceRange(); 2298 S = S->IgnoreParens(); 2299 if (auto UO = dyn_cast<UnaryOperator>(S)) { 2300 if (UO->isIncrementDecrementOp() && GetInitVarDecl(UO->getSubExpr()) == Var) 2301 return SetStep( 2302 SemaRef.ActOnIntegerConstant(UO->getLocStart(), 2303 (UO->isDecrementOp() ? -1 : 1)).get(), 2304 false); 2305 } else if (auto BO = dyn_cast<BinaryOperator>(S)) { 2306 switch (BO->getOpcode()) { 2307 case BO_AddAssign: 2308 case BO_SubAssign: 2309 if (GetInitVarDecl(BO->getLHS()) == Var) 2310 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 2311 break; 2312 case BO_Assign: 2313 if (GetInitVarDecl(BO->getLHS()) == Var) 2314 return CheckIncRHS(BO->getRHS()); 2315 break; 2316 default: 2317 break; 2318 } 2319 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 2320 switch (CE->getOperator()) { 2321 case OO_PlusPlus: 2322 case OO_MinusMinus: 2323 if (GetInitVarDecl(CE->getArg(0)) == Var) 2324 return SetStep( 2325 SemaRef.ActOnIntegerConstant( 2326 CE->getLocStart(), 2327 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).get(), 2328 false); 2329 break; 2330 case OO_PlusEqual: 2331 case OO_MinusEqual: 2332 if (GetInitVarDecl(CE->getArg(0)) == Var) 2333 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 2334 break; 2335 case OO_Equal: 2336 if (GetInitVarDecl(CE->getArg(0)) == Var) 2337 return CheckIncRHS(CE->getArg(1)); 2338 break; 2339 default: 2340 break; 2341 } 2342 } 2343 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr) 2344 << S->getSourceRange() << Var; 2345 return true; 2346 } 2347 2348 /// \brief Build the expression to calculate the number of iterations. 2349 Expr * 2350 OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, 2351 const bool LimitedType) const { 2352 ExprResult Diff; 2353 if (Var->getType()->isIntegerType() || Var->getType()->isPointerType() || 2354 SemaRef.getLangOpts().CPlusPlus) { 2355 // Upper - Lower 2356 Expr *Upper = TestIsLessOp ? UB : LB; 2357 Expr *Lower = TestIsLessOp ? LB : UB; 2358 2359 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 2360 2361 if (!Diff.isUsable() && Var->getType()->getAsCXXRecordDecl()) { 2362 // BuildBinOp already emitted error, this one is to point user to upper 2363 // and lower bound, and to tell what is passed to 'operator-'. 2364 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) 2365 << Upper->getSourceRange() << Lower->getSourceRange(); 2366 return nullptr; 2367 } 2368 } 2369 2370 if (!Diff.isUsable()) 2371 return nullptr; 2372 2373 // Upper - Lower [- 1] 2374 if (TestIsStrictOp) 2375 Diff = SemaRef.BuildBinOp( 2376 S, DefaultLoc, BO_Sub, Diff.get(), 2377 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 2378 if (!Diff.isUsable()) 2379 return nullptr; 2380 2381 // Upper - Lower [- 1] + Step 2382 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), 2383 Step->IgnoreImplicit()); 2384 if (!Diff.isUsable()) 2385 return nullptr; 2386 2387 // Parentheses (for dumping/debugging purposes only). 2388 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 2389 if (!Diff.isUsable()) 2390 return nullptr; 2391 2392 // (Upper - Lower [- 1] + Step) / Step 2393 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), 2394 Step->IgnoreImplicit()); 2395 if (!Diff.isUsable()) 2396 return nullptr; 2397 2398 // OpenMP runtime requires 32-bit or 64-bit loop variables. 2399 if (LimitedType) { 2400 auto &C = SemaRef.Context; 2401 QualType Type = Diff.get()->getType(); 2402 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 2403 if (NewSize != C.getTypeSize(Type)) { 2404 if (NewSize < C.getTypeSize(Type)) { 2405 assert(NewSize == 64 && "incorrect loop var size"); 2406 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 2407 << InitSrcRange << ConditionSrcRange; 2408 } 2409 QualType NewType = C.getIntTypeForBitwidth( 2410 NewSize, Type->hasSignedIntegerRepresentation()); 2411 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 2412 Sema::AA_Converting, true); 2413 if (!Diff.isUsable()) 2414 return nullptr; 2415 } 2416 } 2417 2418 return Diff.get(); 2419 } 2420 2421 Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const { 2422 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 2423 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 2424 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 2425 auto CondExpr = SemaRef.BuildBinOp( 2426 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) 2427 : (TestIsStrictOp ? BO_GT : BO_GE), 2428 LB, UB); 2429 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 2430 // Otherwise use original loop conditon and evaluate it in runtime. 2431 return CondExpr.isUsable() ? CondExpr.get() : Cond; 2432 } 2433 2434 /// \brief Build reference expression to the counter be used for codegen. 2435 Expr *OpenMPIterationSpaceChecker::BuildCounterVar() const { 2436 return DeclRefExpr::Create(SemaRef.Context, NestedNameSpecifierLoc(), 2437 GetIncrementSrcRange().getBegin(), Var, 2438 /*RefersToEnclosingVariableOrCapture=*/true, 2439 DefaultLoc, Var->getType(), VK_LValue); 2440 } 2441 2442 /// \brief Build initization of the counter be used for codegen. 2443 Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; } 2444 2445 /// \brief Build step of the counter be used for codegen. 2446 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; } 2447 2448 /// \brief Iteration space of a single for loop. 2449 struct LoopIterationSpace { 2450 /// \brief Condition of the loop. 2451 Expr *PreCond; 2452 /// \brief This expression calculates the number of iterations in the loop. 2453 /// It is always possible to calculate it before starting the loop. 2454 Expr *NumIterations; 2455 /// \brief The loop counter variable. 2456 Expr *CounterVar; 2457 /// \brief This is initializer for the initial value of #CounterVar. 2458 Expr *CounterInit; 2459 /// \brief This is step for the #CounterVar used to generate its update: 2460 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 2461 Expr *CounterStep; 2462 /// \brief Should step be subtracted? 2463 bool Subtract; 2464 /// \brief Source range of the loop init. 2465 SourceRange InitSrcRange; 2466 /// \brief Source range of the loop condition. 2467 SourceRange CondSrcRange; 2468 /// \brief Source range of the loop increment. 2469 SourceRange IncSrcRange; 2470 }; 2471 2472 } // namespace 2473 2474 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 2475 assert(getLangOpts().OpenMP && "OpenMP is not active."); 2476 assert(Init && "Expected loop in canonical form."); 2477 unsigned CollapseIteration = DSAStack->getCollapseNumber(); 2478 if (CollapseIteration > 0 && 2479 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2480 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 2481 if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) { 2482 DSAStack->addLoopControlVariable(ISC.GetLoopVar()); 2483 } 2484 DSAStack->setCollapseNumber(CollapseIteration - 1); 2485 } 2486 } 2487 2488 /// \brief Called on a for stmt to check and extract its iteration space 2489 /// for further processing (such as collapsing). 2490 static bool CheckOpenMPIterationSpace( 2491 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 2492 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 2493 Expr *NestedLoopCountExpr, 2494 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA, 2495 LoopIterationSpace &ResultIterSpace) { 2496 // OpenMP [2.6, Canonical Loop Form] 2497 // for (init-expr; test-expr; incr-expr) structured-block 2498 auto For = dyn_cast_or_null<ForStmt>(S); 2499 if (!For) { 2500 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for) 2501 << (NestedLoopCountExpr != nullptr) << getOpenMPDirectiveName(DKind) 2502 << NestedLoopCount << (CurrentNestedLoopCount > 0) 2503 << CurrentNestedLoopCount; 2504 if (NestedLoopCount > 1) 2505 SemaRef.Diag(NestedLoopCountExpr->getExprLoc(), 2506 diag::note_omp_collapse_expr) 2507 << NestedLoopCountExpr->getSourceRange(); 2508 return true; 2509 } 2510 assert(For->getBody()); 2511 2512 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 2513 2514 // Check init. 2515 auto Init = For->getInit(); 2516 if (ISC.CheckInit(Init)) { 2517 return true; 2518 } 2519 2520 bool HasErrors = false; 2521 2522 // Check loop variable's type. 2523 auto Var = ISC.GetLoopVar(); 2524 2525 // OpenMP [2.6, Canonical Loop Form] 2526 // Var is one of the following: 2527 // A variable of signed or unsigned integer type. 2528 // For C++, a variable of a random access iterator type. 2529 // For C, a variable of a pointer type. 2530 auto VarType = Var->getType(); 2531 if (!VarType->isDependentType() && !VarType->isIntegerType() && 2532 !VarType->isPointerType() && 2533 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 2534 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type) 2535 << SemaRef.getLangOpts().CPlusPlus; 2536 HasErrors = true; 2537 } 2538 2539 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in a 2540 // Construct 2541 // The loop iteration variable(s) in the associated for-loop(s) of a for or 2542 // parallel for construct is (are) private. 2543 // The loop iteration variable in the associated for-loop of a simd construct 2544 // with just one associated for-loop is linear with a constant-linear-step 2545 // that is the increment of the associated for-loop. 2546 // Exclude loop var from the list of variables with implicitly defined data 2547 // sharing attributes. 2548 VarsWithImplicitDSA.erase(Var); 2549 2550 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced in 2551 // a Construct, C/C++]. 2552 // The loop iteration variable in the associated for-loop of a simd construct 2553 // with just one associated for-loop may be listed in a linear clause with a 2554 // constant-linear-step that is the increment of the associated for-loop. 2555 // The loop iteration variable(s) in the associated for-loop(s) of a for or 2556 // parallel for construct may be listed in a private or lastprivate clause. 2557 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(Var, false); 2558 auto LoopVarRefExpr = ISC.GetLoopVarRefExpr(); 2559 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 2560 // declared in the loop and it is predetermined as a private. 2561 auto PredeterminedCKind = 2562 isOpenMPSimdDirective(DKind) 2563 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 2564 : OMPC_private; 2565 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 2566 DVar.CKind != PredeterminedCKind) || 2567 (isOpenMPWorksharingDirective(DKind) && !isOpenMPSimdDirective(DKind) && 2568 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private && 2569 DVar.CKind != OMPC_lastprivate)) && 2570 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 2571 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa) 2572 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 2573 << getOpenMPClauseName(PredeterminedCKind); 2574 ReportOriginalDSA(SemaRef, &DSA, Var, DVar, true); 2575 HasErrors = true; 2576 } else if (LoopVarRefExpr != nullptr) { 2577 // Make the loop iteration variable private (for worksharing constructs), 2578 // linear (for simd directives with the only one associated loop) or 2579 // lastprivate (for simd directives with several collapsed loops). 2580 if (DVar.CKind == OMPC_unknown) 2581 DVar = DSA.hasDSA(Var, isOpenMPPrivate, MatchesAlways(), 2582 /*FromParent=*/false); 2583 DSA.addDSA(Var, LoopVarRefExpr, PredeterminedCKind); 2584 } 2585 2586 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 2587 2588 // Check test-expr. 2589 HasErrors |= ISC.CheckCond(For->getCond()); 2590 2591 // Check incr-expr. 2592 HasErrors |= ISC.CheckInc(For->getInc()); 2593 2594 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 2595 return HasErrors; 2596 2597 // Build the loop's iteration space representation. 2598 ResultIterSpace.PreCond = ISC.BuildPreCond(DSA.getCurScope(), For->getCond()); 2599 ResultIterSpace.NumIterations = ISC.BuildNumIterations( 2600 DSA.getCurScope(), /* LimitedType */ isOpenMPWorksharingDirective(DKind)); 2601 ResultIterSpace.CounterVar = ISC.BuildCounterVar(); 2602 ResultIterSpace.CounterInit = ISC.BuildCounterInit(); 2603 ResultIterSpace.CounterStep = ISC.BuildCounterStep(); 2604 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); 2605 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange(); 2606 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange(); 2607 ResultIterSpace.Subtract = ISC.ShouldSubtractStep(); 2608 2609 HasErrors |= (ResultIterSpace.PreCond == nullptr || 2610 ResultIterSpace.NumIterations == nullptr || 2611 ResultIterSpace.CounterVar == nullptr || 2612 ResultIterSpace.CounterInit == nullptr || 2613 ResultIterSpace.CounterStep == nullptr); 2614 2615 return HasErrors; 2616 } 2617 2618 /// \brief Build a variable declaration for OpenMP loop iteration variable. 2619 static VarDecl *BuildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 2620 StringRef Name) { 2621 DeclContext *DC = SemaRef.CurContext; 2622 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 2623 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 2624 VarDecl *Decl = 2625 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 2626 Decl->setImplicit(); 2627 return Decl; 2628 } 2629 2630 /// \brief Build 'VarRef = Start + Iter * Step'. 2631 static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, 2632 SourceLocation Loc, ExprResult VarRef, 2633 ExprResult Start, ExprResult Iter, 2634 ExprResult Step, bool Subtract) { 2635 // Add parentheses (for debugging purposes only). 2636 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 2637 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 2638 !Step.isUsable()) 2639 return ExprError(); 2640 2641 ExprResult Update = SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), 2642 Step.get()->IgnoreImplicit()); 2643 if (!Update.isUsable()) 2644 return ExprError(); 2645 2646 // Build 'VarRef = Start + Iter * Step'. 2647 Update = SemaRef.BuildBinOp(S, Loc, (Subtract ? BO_Sub : BO_Add), 2648 Start.get()->IgnoreImplicit(), Update.get()); 2649 if (!Update.isUsable()) 2650 return ExprError(); 2651 2652 Update = SemaRef.PerformImplicitConversion( 2653 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 2654 if (!Update.isUsable()) 2655 return ExprError(); 2656 2657 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 2658 return Update; 2659 } 2660 2661 /// \brief Convert integer expression \a E to make it have at least \a Bits 2662 /// bits. 2663 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, 2664 Sema &SemaRef) { 2665 if (E == nullptr) 2666 return ExprError(); 2667 auto &C = SemaRef.Context; 2668 QualType OldType = E->getType(); 2669 unsigned HasBits = C.getTypeSize(OldType); 2670 if (HasBits >= Bits) 2671 return ExprResult(E); 2672 // OK to convert to signed, because new type has more bits than old. 2673 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 2674 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 2675 true); 2676 } 2677 2678 /// \brief Check if the given expression \a E is a constant integer that fits 2679 /// into \a Bits bits. 2680 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { 2681 if (E == nullptr) 2682 return false; 2683 llvm::APSInt Result; 2684 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 2685 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 2686 return false; 2687 } 2688 2689 /// \brief Called on a for stmt to check itself and nested loops (if any). 2690 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 2691 /// number of collapsed loops otherwise. 2692 static unsigned 2693 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *NestedLoopCountExpr, 2694 Stmt *AStmt, Sema &SemaRef, DSAStackTy &DSA, 2695 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA, 2696 OMPLoopDirective::HelperExprs &Built) { 2697 unsigned NestedLoopCount = 1; 2698 if (NestedLoopCountExpr) { 2699 // Found 'collapse' clause - calculate collapse number. 2700 llvm::APSInt Result; 2701 if (NestedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 2702 NestedLoopCount = Result.getLimitedValue(); 2703 } 2704 // This is helper routine for loop directives (e.g., 'for', 'simd', 2705 // 'for simd', etc.). 2706 SmallVector<LoopIterationSpace, 4> IterSpaces; 2707 IterSpaces.resize(NestedLoopCount); 2708 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 2709 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 2710 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, 2711 NestedLoopCount, NestedLoopCountExpr, 2712 VarsWithImplicitDSA, IterSpaces[Cnt])) 2713 return 0; 2714 // Move on to the next nested for loop, or to the loop body. 2715 // OpenMP [2.8.1, simd construct, Restrictions] 2716 // All loops associated with the construct must be perfectly nested; that 2717 // is, there must be no intervening code nor any OpenMP directive between 2718 // any two loops. 2719 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 2720 } 2721 2722 Built.clear(/* size */ NestedLoopCount); 2723 2724 if (SemaRef.CurContext->isDependentContext()) 2725 return NestedLoopCount; 2726 2727 // An example of what is generated for the following code: 2728 // 2729 // #pragma omp simd collapse(2) 2730 // for (i = 0; i < NI; ++i) 2731 // for (j = J0; j < NJ; j+=2) { 2732 // <loop body> 2733 // } 2734 // 2735 // We generate the code below. 2736 // Note: the loop body may be outlined in CodeGen. 2737 // Note: some counters may be C++ classes, operator- is used to find number of 2738 // iterations and operator+= to calculate counter value. 2739 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 2740 // or i64 is currently supported). 2741 // 2742 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 2743 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 2744 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 2745 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 2746 // // similar updates for vars in clauses (e.g. 'linear') 2747 // <loop body (using local i and j)> 2748 // } 2749 // i = NI; // assign final values of counters 2750 // j = NJ; 2751 // 2752 2753 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 2754 // the iteration counts of the collapsed for loops. 2755 // Precondition tests if there is at least one iteration (all conditions are 2756 // true). 2757 auto PreCond = ExprResult(IterSpaces[0].PreCond); 2758 auto N0 = IterSpaces[0].NumIterations; 2759 ExprResult LastIteration32 = WidenIterationCount(32 /* Bits */, N0, SemaRef); 2760 ExprResult LastIteration64 = WidenIterationCount(64 /* Bits */, N0, SemaRef); 2761 2762 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 2763 return NestedLoopCount; 2764 2765 auto &C = SemaRef.Context; 2766 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 2767 2768 Scope *CurScope = DSA.getCurScope(); 2769 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 2770 if (PreCond.isUsable()) { 2771 PreCond = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_LAnd, 2772 PreCond.get(), IterSpaces[Cnt].PreCond); 2773 } 2774 auto N = IterSpaces[Cnt].NumIterations; 2775 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 2776 if (LastIteration32.isUsable()) 2777 LastIteration32 = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_Mul, 2778 LastIteration32.get(), N); 2779 if (LastIteration64.isUsable()) 2780 LastIteration64 = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_Mul, 2781 LastIteration64.get(), N); 2782 } 2783 2784 // Choose either the 32-bit or 64-bit version. 2785 ExprResult LastIteration = LastIteration64; 2786 if (LastIteration32.isUsable() && 2787 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 2788 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 2789 FitsInto( 2790 32 /* Bits */, 2791 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 2792 LastIteration64.get(), SemaRef))) 2793 LastIteration = LastIteration32; 2794 2795 if (!LastIteration.isUsable()) 2796 return 0; 2797 2798 // Save the number of iterations. 2799 ExprResult NumIterations = LastIteration; 2800 { 2801 LastIteration = SemaRef.BuildBinOp( 2802 CurScope, SourceLocation(), BO_Sub, LastIteration.get(), 2803 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 2804 if (!LastIteration.isUsable()) 2805 return 0; 2806 } 2807 2808 // Calculate the last iteration number beforehand instead of doing this on 2809 // each iteration. Do not do this if the number of iterations may be kfold-ed. 2810 llvm::APSInt Result; 2811 bool IsConstant = 2812 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 2813 ExprResult CalcLastIteration; 2814 if (!IsConstant) { 2815 SourceLocation SaveLoc; 2816 VarDecl *SaveVar = 2817 BuildVarDecl(SemaRef, SaveLoc, LastIteration.get()->getType(), 2818 ".omp.last.iteration"); 2819 ExprResult SaveRef = SemaRef.BuildDeclRefExpr( 2820 SaveVar, LastIteration.get()->getType(), VK_LValue, SaveLoc); 2821 CalcLastIteration = SemaRef.BuildBinOp(CurScope, SaveLoc, BO_Assign, 2822 SaveRef.get(), LastIteration.get()); 2823 LastIteration = SaveRef; 2824 2825 // Prepare SaveRef + 1. 2826 NumIterations = SemaRef.BuildBinOp( 2827 CurScope, SaveLoc, BO_Add, SaveRef.get(), 2828 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 2829 if (!NumIterations.isUsable()) 2830 return 0; 2831 } 2832 2833 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 2834 2835 QualType VType = LastIteration.get()->getType(); 2836 // Build variables passed into runtime, nesessary for worksharing directives. 2837 ExprResult LB, UB, IL, ST, EUB; 2838 if (isOpenMPWorksharingDirective(DKind)) { 2839 // Lower bound variable, initialized with zero. 2840 VarDecl *LBDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 2841 LB = SemaRef.BuildDeclRefExpr(LBDecl, VType, VK_LValue, InitLoc); 2842 SemaRef.AddInitializerToDecl( 2843 LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 2844 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 2845 2846 // Upper bound variable, initialized with last iteration number. 2847 VarDecl *UBDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 2848 UB = SemaRef.BuildDeclRefExpr(UBDecl, VType, VK_LValue, InitLoc); 2849 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 2850 /*DirectInit*/ false, 2851 /*TypeMayContainAuto*/ false); 2852 2853 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 2854 // This will be used to implement clause 'lastprivate'. 2855 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 2856 VarDecl *ILDecl = BuildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 2857 IL = SemaRef.BuildDeclRefExpr(ILDecl, Int32Ty, VK_LValue, InitLoc); 2858 SemaRef.AddInitializerToDecl( 2859 ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 2860 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 2861 2862 // Stride variable returned by runtime (we initialize it to 1 by default). 2863 VarDecl *STDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.stride"); 2864 ST = SemaRef.BuildDeclRefExpr(STDecl, VType, VK_LValue, InitLoc); 2865 SemaRef.AddInitializerToDecl( 2866 STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 2867 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 2868 2869 // Build expression: UB = min(UB, LastIteration) 2870 // It is nesessary for CodeGen of directives with static scheduling. 2871 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 2872 UB.get(), LastIteration.get()); 2873 ExprResult CondOp = SemaRef.ActOnConditionalOp( 2874 InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get()); 2875 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 2876 CondOp.get()); 2877 EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); 2878 } 2879 2880 // Build the iteration variable and its initialization before loop. 2881 ExprResult IV; 2882 ExprResult Init; 2883 { 2884 VarDecl *IVDecl = BuildVarDecl(SemaRef, InitLoc, VType, ".omp.iv"); 2885 IV = SemaRef.BuildDeclRefExpr(IVDecl, VType, VK_LValue, InitLoc); 2886 Expr *RHS = isOpenMPWorksharingDirective(DKind) 2887 ? LB.get() 2888 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 2889 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 2890 Init = SemaRef.ActOnFinishFullExpr(Init.get()); 2891 } 2892 2893 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. 2894 SourceLocation CondLoc; 2895 ExprResult Cond = 2896 isOpenMPWorksharingDirective(DKind) 2897 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) 2898 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 2899 NumIterations.get()); 2900 // Loop condition with 1 iteration separated (IV < LastIteration) 2901 ExprResult SeparatedCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, 2902 IV.get(), LastIteration.get()); 2903 2904 // Loop increment (IV = IV + 1) 2905 SourceLocation IncLoc; 2906 ExprResult Inc = 2907 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 2908 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 2909 if (!Inc.isUsable()) 2910 return 0; 2911 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 2912 Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); 2913 if (!Inc.isUsable()) 2914 return 0; 2915 2916 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 2917 // Used for directives with static scheduling. 2918 ExprResult NextLB, NextUB; 2919 if (isOpenMPWorksharingDirective(DKind)) { 2920 // LB + ST 2921 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 2922 if (!NextLB.isUsable()) 2923 return 0; 2924 // LB = LB + ST 2925 NextLB = 2926 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 2927 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); 2928 if (!NextLB.isUsable()) 2929 return 0; 2930 // UB + ST 2931 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 2932 if (!NextUB.isUsable()) 2933 return 0; 2934 // UB = UB + ST 2935 NextUB = 2936 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 2937 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); 2938 if (!NextUB.isUsable()) 2939 return 0; 2940 } 2941 2942 // Build updates and final values of the loop counters. 2943 bool HasErrors = false; 2944 Built.Counters.resize(NestedLoopCount); 2945 Built.Updates.resize(NestedLoopCount); 2946 Built.Finals.resize(NestedLoopCount); 2947 { 2948 ExprResult Div; 2949 // Go from inner nested loop to outer. 2950 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 2951 LoopIterationSpace &IS = IterSpaces[Cnt]; 2952 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 2953 // Build: Iter = (IV / Div) % IS.NumIters 2954 // where Div is product of previous iterations' IS.NumIters. 2955 ExprResult Iter; 2956 if (Div.isUsable()) { 2957 Iter = 2958 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); 2959 } else { 2960 Iter = IV; 2961 assert((Cnt == (int)NestedLoopCount - 1) && 2962 "unusable div expected on first iteration only"); 2963 } 2964 2965 if (Cnt != 0 && Iter.isUsable()) 2966 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), 2967 IS.NumIterations); 2968 if (!Iter.isUsable()) { 2969 HasErrors = true; 2970 break; 2971 } 2972 2973 // Build update: IS.CounterVar = IS.Start + Iter * IS.Step 2974 ExprResult Update = 2975 BuildCounterUpdate(SemaRef, CurScope, UpdLoc, IS.CounterVar, 2976 IS.CounterInit, Iter, IS.CounterStep, IS.Subtract); 2977 if (!Update.isUsable()) { 2978 HasErrors = true; 2979 break; 2980 } 2981 2982 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 2983 ExprResult Final = BuildCounterUpdate( 2984 SemaRef, CurScope, UpdLoc, IS.CounterVar, IS.CounterInit, 2985 IS.NumIterations, IS.CounterStep, IS.Subtract); 2986 if (!Final.isUsable()) { 2987 HasErrors = true; 2988 break; 2989 } 2990 2991 // Build Div for the next iteration: Div <- Div * IS.NumIters 2992 if (Cnt != 0) { 2993 if (Div.isUnset()) 2994 Div = IS.NumIterations; 2995 else 2996 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), 2997 IS.NumIterations); 2998 2999 // Add parentheses (for debugging purposes only). 3000 if (Div.isUsable()) 3001 Div = SemaRef.ActOnParenExpr(UpdLoc, UpdLoc, Div.get()); 3002 if (!Div.isUsable()) { 3003 HasErrors = true; 3004 break; 3005 } 3006 } 3007 if (!Update.isUsable() || !Final.isUsable()) { 3008 HasErrors = true; 3009 break; 3010 } 3011 // Save results 3012 Built.Counters[Cnt] = IS.CounterVar; 3013 Built.Updates[Cnt] = Update.get(); 3014 Built.Finals[Cnt] = Final.get(); 3015 } 3016 } 3017 3018 if (HasErrors) 3019 return 0; 3020 3021 // Save results 3022 Built.IterationVarRef = IV.get(); 3023 Built.LastIteration = LastIteration.get(); 3024 Built.NumIterations = NumIterations.get(); 3025 Built.CalcLastIteration = CalcLastIteration.get(); 3026 Built.PreCond = PreCond.get(); 3027 Built.Cond = Cond.get(); 3028 Built.SeparatedCond = SeparatedCond.get(); 3029 Built.Init = Init.get(); 3030 Built.Inc = Inc.get(); 3031 Built.LB = LB.get(); 3032 Built.UB = UB.get(); 3033 Built.IL = IL.get(); 3034 Built.ST = ST.get(); 3035 Built.EUB = EUB.get(); 3036 Built.NLB = NextLB.get(); 3037 Built.NUB = NextUB.get(); 3038 3039 return NestedLoopCount; 3040 } 3041 3042 static Expr *GetCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 3043 auto &&CollapseFilter = [](const OMPClause *C) -> bool { 3044 return C->getClauseKind() == OMPC_collapse; 3045 }; 3046 OMPExecutableDirective::filtered_clause_iterator<decltype(CollapseFilter)> I( 3047 Clauses, std::move(CollapseFilter)); 3048 if (I) 3049 return cast<OMPCollapseClause>(*I)->getNumForLoops(); 3050 return nullptr; 3051 } 3052 3053 StmtResult Sema::ActOnOpenMPSimdDirective( 3054 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 3055 SourceLocation EndLoc, 3056 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { 3057 OMPLoopDirective::HelperExprs B; 3058 // In presence of clause 'collapse', it will define the nested loops number. 3059 unsigned NestedLoopCount = 3060 CheckOpenMPLoop(OMPD_simd, GetCollapseNumberExpr(Clauses), AStmt, *this, 3061 *DSAStack, VarsWithImplicitDSA, B); 3062 if (NestedLoopCount == 0) 3063 return StmtError(); 3064 3065 assert((CurContext->isDependentContext() || B.builtAll()) && 3066 "omp simd loop exprs were not built"); 3067 3068 if (!CurContext->isDependentContext()) { 3069 // Finalize the clauses that need pre-built expressions for CodeGen. 3070 for (auto C : Clauses) { 3071 if (auto LC = dyn_cast<OMPLinearClause>(C)) 3072 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 3073 B.NumIterations, *this, CurScope)) 3074 return StmtError(); 3075 } 3076 } 3077 3078 getCurFunction()->setHasBranchProtectedScope(); 3079 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 3080 Clauses, AStmt, B); 3081 } 3082 3083 StmtResult Sema::ActOnOpenMPForDirective( 3084 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 3085 SourceLocation EndLoc, 3086 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { 3087 OMPLoopDirective::HelperExprs B; 3088 // In presence of clause 'collapse', it will define the nested loops number. 3089 unsigned NestedLoopCount = 3090 CheckOpenMPLoop(OMPD_for, GetCollapseNumberExpr(Clauses), AStmt, *this, 3091 *DSAStack, VarsWithImplicitDSA, B); 3092 if (NestedLoopCount == 0) 3093 return StmtError(); 3094 3095 assert((CurContext->isDependentContext() || B.builtAll()) && 3096 "omp for loop exprs were not built"); 3097 3098 getCurFunction()->setHasBranchProtectedScope(); 3099 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 3100 Clauses, AStmt, B); 3101 } 3102 3103 StmtResult Sema::ActOnOpenMPForSimdDirective( 3104 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 3105 SourceLocation EndLoc, 3106 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { 3107 OMPLoopDirective::HelperExprs B; 3108 // In presence of clause 'collapse', it will define the nested loops number. 3109 unsigned NestedLoopCount = 3110 CheckOpenMPLoop(OMPD_for_simd, GetCollapseNumberExpr(Clauses), AStmt, 3111 *this, *DSAStack, VarsWithImplicitDSA, B); 3112 if (NestedLoopCount == 0) 3113 return StmtError(); 3114 3115 assert((CurContext->isDependentContext() || B.builtAll()) && 3116 "omp for simd loop exprs were not built"); 3117 3118 getCurFunction()->setHasBranchProtectedScope(); 3119 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 3120 Clauses, AStmt, B); 3121 } 3122 3123 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 3124 Stmt *AStmt, 3125 SourceLocation StartLoc, 3126 SourceLocation EndLoc) { 3127 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3128 auto BaseStmt = AStmt; 3129 while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 3130 BaseStmt = CS->getCapturedStmt(); 3131 if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 3132 auto S = C->children(); 3133 if (!S) 3134 return StmtError(); 3135 // All associated statements must be '#pragma omp section' except for 3136 // the first one. 3137 for (++S; S; ++S) { 3138 auto SectionStmt = *S; 3139 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 3140 if (SectionStmt) 3141 Diag(SectionStmt->getLocStart(), 3142 diag::err_omp_sections_substmt_not_section); 3143 return StmtError(); 3144 } 3145 } 3146 } else { 3147 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt); 3148 return StmtError(); 3149 } 3150 3151 getCurFunction()->setHasBranchProtectedScope(); 3152 3153 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, 3154 AStmt); 3155 } 3156 3157 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 3158 SourceLocation StartLoc, 3159 SourceLocation EndLoc) { 3160 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3161 3162 getCurFunction()->setHasBranchProtectedScope(); 3163 3164 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt); 3165 } 3166 3167 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 3168 Stmt *AStmt, 3169 SourceLocation StartLoc, 3170 SourceLocation EndLoc) { 3171 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3172 3173 getCurFunction()->setHasBranchProtectedScope(); 3174 3175 // OpenMP [2.7.3, single Construct, Restrictions] 3176 // The copyprivate clause must not be used with the nowait clause. 3177 OMPClause *Nowait = nullptr; 3178 OMPClause *Copyprivate = nullptr; 3179 for (auto *Clause : Clauses) { 3180 if (Clause->getClauseKind() == OMPC_nowait) 3181 Nowait = Clause; 3182 else if (Clause->getClauseKind() == OMPC_copyprivate) 3183 Copyprivate = Clause; 3184 if (Copyprivate && Nowait) { 3185 Diag(Copyprivate->getLocStart(), 3186 diag::err_omp_single_copyprivate_with_nowait); 3187 Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here); 3188 return StmtError(); 3189 } 3190 } 3191 3192 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 3193 } 3194 3195 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 3196 SourceLocation StartLoc, 3197 SourceLocation EndLoc) { 3198 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3199 3200 getCurFunction()->setHasBranchProtectedScope(); 3201 3202 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 3203 } 3204 3205 StmtResult 3206 Sema::ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, 3207 Stmt *AStmt, SourceLocation StartLoc, 3208 SourceLocation EndLoc) { 3209 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3210 3211 getCurFunction()->setHasBranchProtectedScope(); 3212 3213 return OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 3214 AStmt); 3215 } 3216 3217 StmtResult Sema::ActOnOpenMPParallelForDirective( 3218 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 3219 SourceLocation EndLoc, 3220 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { 3221 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3222 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 3223 // 1.2.2 OpenMP Language Terminology 3224 // Structured block - An executable statement with a single entry at the 3225 // top and a single exit at the bottom. 3226 // The point of exit cannot be a branch out of the structured block. 3227 // longjmp() and throw() must not violate the entry/exit criteria. 3228 CS->getCapturedDecl()->setNothrow(); 3229 3230 OMPLoopDirective::HelperExprs B; 3231 // In presence of clause 'collapse', it will define the nested loops number. 3232 unsigned NestedLoopCount = 3233 CheckOpenMPLoop(OMPD_parallel_for, GetCollapseNumberExpr(Clauses), AStmt, 3234 *this, *DSAStack, VarsWithImplicitDSA, B); 3235 if (NestedLoopCount == 0) 3236 return StmtError(); 3237 3238 assert((CurContext->isDependentContext() || B.builtAll()) && 3239 "omp parallel for loop exprs were not built"); 3240 3241 getCurFunction()->setHasBranchProtectedScope(); 3242 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 3243 NestedLoopCount, Clauses, AStmt, B); 3244 } 3245 3246 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 3247 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 3248 SourceLocation EndLoc, 3249 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { 3250 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3251 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 3252 // 1.2.2 OpenMP Language Terminology 3253 // Structured block - An executable statement with a single entry at the 3254 // top and a single exit at the bottom. 3255 // The point of exit cannot be a branch out of the structured block. 3256 // longjmp() and throw() must not violate the entry/exit criteria. 3257 CS->getCapturedDecl()->setNothrow(); 3258 3259 OMPLoopDirective::HelperExprs B; 3260 // In presence of clause 'collapse', it will define the nested loops number. 3261 unsigned NestedLoopCount = 3262 CheckOpenMPLoop(OMPD_parallel_for_simd, GetCollapseNumberExpr(Clauses), 3263 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 3264 if (NestedLoopCount == 0) 3265 return StmtError(); 3266 3267 getCurFunction()->setHasBranchProtectedScope(); 3268 return OMPParallelForSimdDirective::Create( 3269 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 3270 } 3271 3272 StmtResult 3273 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 3274 Stmt *AStmt, SourceLocation StartLoc, 3275 SourceLocation EndLoc) { 3276 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3277 auto BaseStmt = AStmt; 3278 while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 3279 BaseStmt = CS->getCapturedStmt(); 3280 if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 3281 auto S = C->children(); 3282 if (!S) 3283 return StmtError(); 3284 // All associated statements must be '#pragma omp section' except for 3285 // the first one. 3286 for (++S; S; ++S) { 3287 auto SectionStmt = *S; 3288 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 3289 if (SectionStmt) 3290 Diag(SectionStmt->getLocStart(), 3291 diag::err_omp_parallel_sections_substmt_not_section); 3292 return StmtError(); 3293 } 3294 } 3295 } else { 3296 Diag(AStmt->getLocStart(), 3297 diag::err_omp_parallel_sections_not_compound_stmt); 3298 return StmtError(); 3299 } 3300 3301 getCurFunction()->setHasBranchProtectedScope(); 3302 3303 return OMPParallelSectionsDirective::Create(Context, StartLoc, EndLoc, 3304 Clauses, AStmt); 3305 } 3306 3307 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 3308 Stmt *AStmt, SourceLocation StartLoc, 3309 SourceLocation EndLoc) { 3310 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3311 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 3312 // 1.2.2 OpenMP Language Terminology 3313 // Structured block - An executable statement with a single entry at the 3314 // top and a single exit at the bottom. 3315 // The point of exit cannot be a branch out of the structured block. 3316 // longjmp() and throw() must not violate the entry/exit criteria. 3317 CS->getCapturedDecl()->setNothrow(); 3318 3319 getCurFunction()->setHasBranchProtectedScope(); 3320 3321 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 3322 } 3323 3324 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 3325 SourceLocation EndLoc) { 3326 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 3327 } 3328 3329 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 3330 SourceLocation EndLoc) { 3331 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 3332 } 3333 3334 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 3335 SourceLocation EndLoc) { 3336 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 3337 } 3338 3339 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 3340 SourceLocation StartLoc, 3341 SourceLocation EndLoc) { 3342 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 3343 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 3344 } 3345 3346 StmtResult Sema::ActOnOpenMPOrderedDirective(Stmt *AStmt, 3347 SourceLocation StartLoc, 3348 SourceLocation EndLoc) { 3349 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3350 3351 getCurFunction()->setHasBranchProtectedScope(); 3352 3353 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, AStmt); 3354 } 3355 3356 namespace { 3357 /// \brief Helper class for checking expression in 'omp atomic [update]' 3358 /// construct. 3359 class OpenMPAtomicUpdateChecker { 3360 /// \brief Error results for atomic update expressions. 3361 enum ExprAnalysisErrorCode { 3362 /// \brief A statement is not an expression statement. 3363 NotAnExpression, 3364 /// \brief Expression is not builtin binary or unary operation. 3365 NotABinaryOrUnaryExpression, 3366 /// \brief Unary operation is not post-/pre- increment/decrement operation. 3367 NotAnUnaryIncDecExpression, 3368 /// \brief An expression is not of scalar type. 3369 NotAScalarType, 3370 /// \brief A binary operation is not an assignment operation. 3371 NotAnAssignmentOp, 3372 /// \brief RHS part of the binary operation is not a binary expression. 3373 NotABinaryExpression, 3374 /// \brief RHS part is not additive/multiplicative/shift/biwise binary 3375 /// expression. 3376 NotABinaryOperator, 3377 /// \brief RHS binary operation does not have reference to the updated LHS 3378 /// part. 3379 NotAnUpdateExpression, 3380 /// \brief No errors is found. 3381 NoError 3382 }; 3383 /// \brief Reference to Sema. 3384 Sema &SemaRef; 3385 /// \brief A location for note diagnostics (when error is found). 3386 SourceLocation NoteLoc; 3387 /// \brief 'x' lvalue part of the source atomic expression. 3388 Expr *X; 3389 /// \brief 'expr' rvalue part of the source atomic expression. 3390 Expr *E; 3391 /// \brief Helper expression of the form 3392 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 3393 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 3394 Expr *UpdateExpr; 3395 /// \brief Is 'x' a LHS in a RHS part of full update expression. It is 3396 /// important for non-associative operations. 3397 bool IsXLHSInRHSPart; 3398 BinaryOperatorKind Op; 3399 SourceLocation OpLoc; 3400 /// \brief true if the source expression is a postfix unary operation, false 3401 /// if it is a prefix unary operation. 3402 bool IsPostfixUpdate; 3403 3404 public: 3405 OpenMPAtomicUpdateChecker(Sema &SemaRef) 3406 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 3407 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 3408 /// \brief Check specified statement that it is suitable for 'atomic update' 3409 /// constructs and extract 'x', 'expr' and Operation from the original 3410 /// expression. If DiagId and NoteId == 0, then only check is performed 3411 /// without error notification. 3412 /// \param DiagId Diagnostic which should be emitted if error is found. 3413 /// \param NoteId Diagnostic note for the main error message. 3414 /// \return true if statement is not an update expression, false otherwise. 3415 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 3416 /// \brief Return the 'x' lvalue part of the source atomic expression. 3417 Expr *getX() const { return X; } 3418 /// \brief Return the 'expr' rvalue part of the source atomic expression. 3419 Expr *getExpr() const { return E; } 3420 /// \brief Return the update expression used in calculation of the updated 3421 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 3422 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 3423 Expr *getUpdateExpr() const { return UpdateExpr; } 3424 /// \brief Return true if 'x' is LHS in RHS part of full update expression, 3425 /// false otherwise. 3426 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 3427 3428 /// \brief true if the source expression is a postfix unary operation, false 3429 /// if it is a prefix unary operation. 3430 bool isPostfixUpdate() const { return IsPostfixUpdate; } 3431 3432 private: 3433 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 3434 unsigned NoteId = 0); 3435 }; 3436 } // namespace 3437 3438 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 3439 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 3440 ExprAnalysisErrorCode ErrorFound = NoError; 3441 SourceLocation ErrorLoc, NoteLoc; 3442 SourceRange ErrorRange, NoteRange; 3443 // Allowed constructs are: 3444 // x = x binop expr; 3445 // x = expr binop x; 3446 if (AtomicBinOp->getOpcode() == BO_Assign) { 3447 X = AtomicBinOp->getLHS(); 3448 if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 3449 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 3450 if (AtomicInnerBinOp->isMultiplicativeOp() || 3451 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 3452 AtomicInnerBinOp->isBitwiseOp()) { 3453 Op = AtomicInnerBinOp->getOpcode(); 3454 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 3455 auto *LHS = AtomicInnerBinOp->getLHS(); 3456 auto *RHS = AtomicInnerBinOp->getRHS(); 3457 llvm::FoldingSetNodeID XId, LHSId, RHSId; 3458 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 3459 /*Canonical=*/true); 3460 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 3461 /*Canonical=*/true); 3462 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 3463 /*Canonical=*/true); 3464 if (XId == LHSId) { 3465 E = RHS; 3466 IsXLHSInRHSPart = true; 3467 } else if (XId == RHSId) { 3468 E = LHS; 3469 IsXLHSInRHSPart = false; 3470 } else { 3471 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 3472 ErrorRange = AtomicInnerBinOp->getSourceRange(); 3473 NoteLoc = X->getExprLoc(); 3474 NoteRange = X->getSourceRange(); 3475 ErrorFound = NotAnUpdateExpression; 3476 } 3477 } else { 3478 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 3479 ErrorRange = AtomicInnerBinOp->getSourceRange(); 3480 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 3481 NoteRange = SourceRange(NoteLoc, NoteLoc); 3482 ErrorFound = NotABinaryOperator; 3483 } 3484 } else { 3485 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 3486 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 3487 ErrorFound = NotABinaryExpression; 3488 } 3489 } else { 3490 ErrorLoc = AtomicBinOp->getExprLoc(); 3491 ErrorRange = AtomicBinOp->getSourceRange(); 3492 NoteLoc = AtomicBinOp->getOperatorLoc(); 3493 NoteRange = SourceRange(NoteLoc, NoteLoc); 3494 ErrorFound = NotAnAssignmentOp; 3495 } 3496 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 3497 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 3498 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 3499 return true; 3500 } else if (SemaRef.CurContext->isDependentContext()) 3501 E = X = UpdateExpr = nullptr; 3502 return ErrorFound != NoError; 3503 } 3504 3505 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 3506 unsigned NoteId) { 3507 ExprAnalysisErrorCode ErrorFound = NoError; 3508 SourceLocation ErrorLoc, NoteLoc; 3509 SourceRange ErrorRange, NoteRange; 3510 // Allowed constructs are: 3511 // x++; 3512 // x--; 3513 // ++x; 3514 // --x; 3515 // x binop= expr; 3516 // x = x binop expr; 3517 // x = expr binop x; 3518 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 3519 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 3520 if (AtomicBody->getType()->isScalarType() || 3521 AtomicBody->isInstantiationDependent()) { 3522 if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 3523 AtomicBody->IgnoreParenImpCasts())) { 3524 // Check for Compound Assignment Operation 3525 Op = BinaryOperator::getOpForCompoundAssignment( 3526 AtomicCompAssignOp->getOpcode()); 3527 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 3528 E = AtomicCompAssignOp->getRHS(); 3529 X = AtomicCompAssignOp->getLHS(); 3530 IsXLHSInRHSPart = true; 3531 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 3532 AtomicBody->IgnoreParenImpCasts())) { 3533 // Check for Binary Operation 3534 if(checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 3535 return true; 3536 } else if (auto *AtomicUnaryOp = 3537 dyn_cast<UnaryOperator>(AtomicBody->IgnoreParenImpCasts())) { 3538 // Check for Unary Operation 3539 if (AtomicUnaryOp->isIncrementDecrementOp()) { 3540 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 3541 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 3542 OpLoc = AtomicUnaryOp->getOperatorLoc(); 3543 X = AtomicUnaryOp->getSubExpr(); 3544 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 3545 IsXLHSInRHSPart = true; 3546 } else { 3547 ErrorFound = NotAnUnaryIncDecExpression; 3548 ErrorLoc = AtomicUnaryOp->getExprLoc(); 3549 ErrorRange = AtomicUnaryOp->getSourceRange(); 3550 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 3551 NoteRange = SourceRange(NoteLoc, NoteLoc); 3552 } 3553 } else { 3554 ErrorFound = NotABinaryOrUnaryExpression; 3555 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 3556 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 3557 } 3558 } else { 3559 ErrorFound = NotAScalarType; 3560 NoteLoc = ErrorLoc = AtomicBody->getLocStart(); 3561 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 3562 } 3563 } else { 3564 ErrorFound = NotAnExpression; 3565 NoteLoc = ErrorLoc = S->getLocStart(); 3566 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 3567 } 3568 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 3569 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 3570 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 3571 return true; 3572 } else if (SemaRef.CurContext->isDependentContext()) 3573 E = X = UpdateExpr = nullptr; 3574 if (ErrorFound == NoError && E && X) { 3575 // Build an update expression of form 'OpaqueValueExpr(x) binop 3576 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 3577 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 3578 auto *OVEX = new (SemaRef.getASTContext()) 3579 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 3580 auto *OVEExpr = new (SemaRef.getASTContext()) 3581 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 3582 auto Update = 3583 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 3584 IsXLHSInRHSPart ? OVEExpr : OVEX); 3585 if (Update.isInvalid()) 3586 return true; 3587 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 3588 Sema::AA_Casting); 3589 if (Update.isInvalid()) 3590 return true; 3591 UpdateExpr = Update.get(); 3592 } 3593 return ErrorFound != NoError; 3594 } 3595 3596 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 3597 Stmt *AStmt, 3598 SourceLocation StartLoc, 3599 SourceLocation EndLoc) { 3600 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3601 auto CS = cast<CapturedStmt>(AStmt); 3602 // 1.2.2 OpenMP Language Terminology 3603 // Structured block - An executable statement with a single entry at the 3604 // top and a single exit at the bottom. 3605 // The point of exit cannot be a branch out of the structured block. 3606 // longjmp() and throw() must not violate the entry/exit criteria. 3607 OpenMPClauseKind AtomicKind = OMPC_unknown; 3608 SourceLocation AtomicKindLoc; 3609 for (auto *C : Clauses) { 3610 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 3611 C->getClauseKind() == OMPC_update || 3612 C->getClauseKind() == OMPC_capture) { 3613 if (AtomicKind != OMPC_unknown) { 3614 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) 3615 << SourceRange(C->getLocStart(), C->getLocEnd()); 3616 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 3617 << getOpenMPClauseName(AtomicKind); 3618 } else { 3619 AtomicKind = C->getClauseKind(); 3620 AtomicKindLoc = C->getLocStart(); 3621 } 3622 } 3623 } 3624 3625 auto Body = CS->getCapturedStmt(); 3626 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 3627 Body = EWC->getSubExpr(); 3628 3629 Expr *X = nullptr; 3630 Expr *V = nullptr; 3631 Expr *E = nullptr; 3632 Expr *UE = nullptr; 3633 bool IsXLHSInRHSPart = false; 3634 bool IsPostfixUpdate = false; 3635 // OpenMP [2.12.6, atomic Construct] 3636 // In the next expressions: 3637 // * x and v (as applicable) are both l-value expressions with scalar type. 3638 // * During the execution of an atomic region, multiple syntactic 3639 // occurrences of x must designate the same storage location. 3640 // * Neither of v and expr (as applicable) may access the storage location 3641 // designated by x. 3642 // * Neither of x and expr (as applicable) may access the storage location 3643 // designated by v. 3644 // * expr is an expression with scalar type. 3645 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 3646 // * binop, binop=, ++, and -- are not overloaded operators. 3647 // * The expression x binop expr must be numerically equivalent to x binop 3648 // (expr). This requirement is satisfied if the operators in expr have 3649 // precedence greater than binop, or by using parentheses around expr or 3650 // subexpressions of expr. 3651 // * The expression expr binop x must be numerically equivalent to (expr) 3652 // binop x. This requirement is satisfied if the operators in expr have 3653 // precedence equal to or greater than binop, or by using parentheses around 3654 // expr or subexpressions of expr. 3655 // * For forms that allow multiple occurrences of x, the number of times 3656 // that x is evaluated is unspecified. 3657 if (AtomicKind == OMPC_read) { 3658 enum { 3659 NotAnExpression, 3660 NotAnAssignmentOp, 3661 NotAScalarType, 3662 NotAnLValue, 3663 NoError 3664 } ErrorFound = NoError; 3665 SourceLocation ErrorLoc, NoteLoc; 3666 SourceRange ErrorRange, NoteRange; 3667 // If clause is read: 3668 // v = x; 3669 if (auto AtomicBody = dyn_cast<Expr>(Body)) { 3670 auto AtomicBinOp = 3671 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 3672 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 3673 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 3674 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 3675 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 3676 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 3677 if (!X->isLValue() || !V->isLValue()) { 3678 auto NotLValueExpr = X->isLValue() ? V : X; 3679 ErrorFound = NotAnLValue; 3680 ErrorLoc = AtomicBinOp->getExprLoc(); 3681 ErrorRange = AtomicBinOp->getSourceRange(); 3682 NoteLoc = NotLValueExpr->getExprLoc(); 3683 NoteRange = NotLValueExpr->getSourceRange(); 3684 } 3685 } else if (!X->isInstantiationDependent() || 3686 !V->isInstantiationDependent()) { 3687 auto NotScalarExpr = 3688 (X->isInstantiationDependent() || X->getType()->isScalarType()) 3689 ? V 3690 : X; 3691 ErrorFound = NotAScalarType; 3692 ErrorLoc = AtomicBinOp->getExprLoc(); 3693 ErrorRange = AtomicBinOp->getSourceRange(); 3694 NoteLoc = NotScalarExpr->getExprLoc(); 3695 NoteRange = NotScalarExpr->getSourceRange(); 3696 } 3697 } else { 3698 ErrorFound = NotAnAssignmentOp; 3699 ErrorLoc = AtomicBody->getExprLoc(); 3700 ErrorRange = AtomicBody->getSourceRange(); 3701 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 3702 : AtomicBody->getExprLoc(); 3703 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 3704 : AtomicBody->getSourceRange(); 3705 } 3706 } else { 3707 ErrorFound = NotAnExpression; 3708 NoteLoc = ErrorLoc = Body->getLocStart(); 3709 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 3710 } 3711 if (ErrorFound != NoError) { 3712 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 3713 << ErrorRange; 3714 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 3715 << NoteRange; 3716 return StmtError(); 3717 } else if (CurContext->isDependentContext()) 3718 V = X = nullptr; 3719 } else if (AtomicKind == OMPC_write) { 3720 enum { 3721 NotAnExpression, 3722 NotAnAssignmentOp, 3723 NotAScalarType, 3724 NotAnLValue, 3725 NoError 3726 } ErrorFound = NoError; 3727 SourceLocation ErrorLoc, NoteLoc; 3728 SourceRange ErrorRange, NoteRange; 3729 // If clause is write: 3730 // x = expr; 3731 if (auto AtomicBody = dyn_cast<Expr>(Body)) { 3732 auto AtomicBinOp = 3733 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 3734 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 3735 X = AtomicBinOp->getLHS(); 3736 E = AtomicBinOp->getRHS(); 3737 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 3738 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 3739 if (!X->isLValue()) { 3740 ErrorFound = NotAnLValue; 3741 ErrorLoc = AtomicBinOp->getExprLoc(); 3742 ErrorRange = AtomicBinOp->getSourceRange(); 3743 NoteLoc = X->getExprLoc(); 3744 NoteRange = X->getSourceRange(); 3745 } 3746 } else if (!X->isInstantiationDependent() || 3747 !E->isInstantiationDependent()) { 3748 auto NotScalarExpr = 3749 (X->isInstantiationDependent() || X->getType()->isScalarType()) 3750 ? E 3751 : X; 3752 ErrorFound = NotAScalarType; 3753 ErrorLoc = AtomicBinOp->getExprLoc(); 3754 ErrorRange = AtomicBinOp->getSourceRange(); 3755 NoteLoc = NotScalarExpr->getExprLoc(); 3756 NoteRange = NotScalarExpr->getSourceRange(); 3757 } 3758 } else { 3759 ErrorFound = NotAnAssignmentOp; 3760 ErrorLoc = AtomicBody->getExprLoc(); 3761 ErrorRange = AtomicBody->getSourceRange(); 3762 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 3763 : AtomicBody->getExprLoc(); 3764 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 3765 : AtomicBody->getSourceRange(); 3766 } 3767 } else { 3768 ErrorFound = NotAnExpression; 3769 NoteLoc = ErrorLoc = Body->getLocStart(); 3770 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 3771 } 3772 if (ErrorFound != NoError) { 3773 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 3774 << ErrorRange; 3775 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 3776 << NoteRange; 3777 return StmtError(); 3778 } else if (CurContext->isDependentContext()) 3779 E = X = nullptr; 3780 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 3781 // If clause is update: 3782 // x++; 3783 // x--; 3784 // ++x; 3785 // --x; 3786 // x binop= expr; 3787 // x = x binop expr; 3788 // x = expr binop x; 3789 OpenMPAtomicUpdateChecker Checker(*this); 3790 if (Checker.checkStatement( 3791 Body, (AtomicKind == OMPC_update) 3792 ? diag::err_omp_atomic_update_not_expression_statement 3793 : diag::err_omp_atomic_not_expression_statement, 3794 diag::note_omp_atomic_update)) 3795 return StmtError(); 3796 if (!CurContext->isDependentContext()) { 3797 E = Checker.getExpr(); 3798 X = Checker.getX(); 3799 UE = Checker.getUpdateExpr(); 3800 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 3801 } 3802 } else if (AtomicKind == OMPC_capture) { 3803 enum { 3804 NotAnAssignmentOp, 3805 NotACompoundStatement, 3806 NotTwoSubstatements, 3807 NotASpecificExpression, 3808 NoError 3809 } ErrorFound = NoError; 3810 SourceLocation ErrorLoc, NoteLoc; 3811 SourceRange ErrorRange, NoteRange; 3812 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 3813 // If clause is a capture: 3814 // v = x++; 3815 // v = x--; 3816 // v = ++x; 3817 // v = --x; 3818 // v = x binop= expr; 3819 // v = x = x binop expr; 3820 // v = x = expr binop x; 3821 auto *AtomicBinOp = 3822 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 3823 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 3824 V = AtomicBinOp->getLHS(); 3825 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 3826 OpenMPAtomicUpdateChecker Checker(*this); 3827 if (Checker.checkStatement( 3828 Body, diag::err_omp_atomic_capture_not_expression_statement, 3829 diag::note_omp_atomic_update)) 3830 return StmtError(); 3831 E = Checker.getExpr(); 3832 X = Checker.getX(); 3833 UE = Checker.getUpdateExpr(); 3834 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 3835 IsPostfixUpdate = Checker.isPostfixUpdate(); 3836 } else { 3837 ErrorLoc = AtomicBody->getExprLoc(); 3838 ErrorRange = AtomicBody->getSourceRange(); 3839 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 3840 : AtomicBody->getExprLoc(); 3841 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 3842 : AtomicBody->getSourceRange(); 3843 ErrorFound = NotAnAssignmentOp; 3844 } 3845 if (ErrorFound != NoError) { 3846 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 3847 << ErrorRange; 3848 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 3849 return StmtError(); 3850 } else if (CurContext->isDependentContext()) { 3851 UE = V = E = X = nullptr; 3852 } 3853 } else { 3854 // If clause is a capture: 3855 // { v = x; x = expr; } 3856 // { v = x; x++; } 3857 // { v = x; x--; } 3858 // { v = x; ++x; } 3859 // { v = x; --x; } 3860 // { v = x; x binop= expr; } 3861 // { v = x; x = x binop expr; } 3862 // { v = x; x = expr binop x; } 3863 // { x++; v = x; } 3864 // { x--; v = x; } 3865 // { ++x; v = x; } 3866 // { --x; v = x; } 3867 // { x binop= expr; v = x; } 3868 // { x = x binop expr; v = x; } 3869 // { x = expr binop x; v = x; } 3870 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 3871 // Check that this is { expr1; expr2; } 3872 if (CS->size() == 2) { 3873 auto *First = CS->body_front(); 3874 auto *Second = CS->body_back(); 3875 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 3876 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 3877 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 3878 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 3879 // Need to find what subexpression is 'v' and what is 'x'. 3880 OpenMPAtomicUpdateChecker Checker(*this); 3881 bool IsUpdateExprFound = !Checker.checkStatement(Second); 3882 BinaryOperator *BinOp = nullptr; 3883 if (IsUpdateExprFound) { 3884 BinOp = dyn_cast<BinaryOperator>(First); 3885 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 3886 } 3887 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 3888 // { v = x; x++; } 3889 // { v = x; x--; } 3890 // { v = x; ++x; } 3891 // { v = x; --x; } 3892 // { v = x; x binop= expr; } 3893 // { v = x; x = x binop expr; } 3894 // { v = x; x = expr binop x; } 3895 // Check that the first expression has form v = x. 3896 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 3897 llvm::FoldingSetNodeID XId, PossibleXId; 3898 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 3899 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 3900 IsUpdateExprFound = XId == PossibleXId; 3901 if (IsUpdateExprFound) { 3902 V = BinOp->getLHS(); 3903 X = Checker.getX(); 3904 E = Checker.getExpr(); 3905 UE = Checker.getUpdateExpr(); 3906 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 3907 IsPostfixUpdate = true; 3908 } 3909 } 3910 if (!IsUpdateExprFound) { 3911 IsUpdateExprFound = !Checker.checkStatement(First); 3912 BinOp = nullptr; 3913 if (IsUpdateExprFound) { 3914 BinOp = dyn_cast<BinaryOperator>(Second); 3915 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 3916 } 3917 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 3918 // { x++; v = x; } 3919 // { x--; v = x; } 3920 // { ++x; v = x; } 3921 // { --x; v = x; } 3922 // { x binop= expr; v = x; } 3923 // { x = x binop expr; v = x; } 3924 // { x = expr binop x; v = x; } 3925 // Check that the second expression has form v = x. 3926 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 3927 llvm::FoldingSetNodeID XId, PossibleXId; 3928 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 3929 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 3930 IsUpdateExprFound = XId == PossibleXId; 3931 if (IsUpdateExprFound) { 3932 V = BinOp->getLHS(); 3933 X = Checker.getX(); 3934 E = Checker.getExpr(); 3935 UE = Checker.getUpdateExpr(); 3936 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 3937 IsPostfixUpdate = false; 3938 } 3939 } 3940 } 3941 if (!IsUpdateExprFound) { 3942 // { v = x; x = expr; } 3943 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 3944 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 3945 ErrorFound = NotAnAssignmentOp; 3946 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 3947 : First->getLocStart(); 3948 NoteRange = ErrorRange = FirstBinOp 3949 ? FirstBinOp->getSourceRange() 3950 : SourceRange(ErrorLoc, ErrorLoc); 3951 } else { 3952 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 3953 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 3954 ErrorFound = NotAnAssignmentOp; 3955 NoteLoc = ErrorLoc = SecondBinOp ? SecondBinOp->getOperatorLoc() 3956 : Second->getLocStart(); 3957 NoteRange = ErrorRange = SecondBinOp 3958 ? SecondBinOp->getSourceRange() 3959 : SourceRange(ErrorLoc, ErrorLoc); 3960 } else { 3961 auto *PossibleXRHSInFirst = 3962 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 3963 auto *PossibleXLHSInSecond = 3964 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 3965 llvm::FoldingSetNodeID X1Id, X2Id; 3966 PossibleXRHSInFirst->Profile(X1Id, Context, /*Canonical=*/true); 3967 PossibleXLHSInSecond->Profile(X2Id, Context, 3968 /*Canonical=*/true); 3969 IsUpdateExprFound = X1Id == X2Id; 3970 if (IsUpdateExprFound) { 3971 V = FirstBinOp->getLHS(); 3972 X = SecondBinOp->getLHS(); 3973 E = SecondBinOp->getRHS(); 3974 UE = nullptr; 3975 IsXLHSInRHSPart = false; 3976 IsPostfixUpdate = true; 3977 } else { 3978 ErrorFound = NotASpecificExpression; 3979 ErrorLoc = FirstBinOp->getExprLoc(); 3980 ErrorRange = FirstBinOp->getSourceRange(); 3981 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 3982 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 3983 } 3984 } 3985 } 3986 } 3987 } else { 3988 NoteLoc = ErrorLoc = Body->getLocStart(); 3989 NoteRange = ErrorRange = 3990 SourceRange(Body->getLocStart(), Body->getLocStart()); 3991 ErrorFound = NotTwoSubstatements; 3992 } 3993 } else { 3994 NoteLoc = ErrorLoc = Body->getLocStart(); 3995 NoteRange = ErrorRange = 3996 SourceRange(Body->getLocStart(), Body->getLocStart()); 3997 ErrorFound = NotACompoundStatement; 3998 } 3999 if (ErrorFound != NoError) { 4000 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 4001 << ErrorRange; 4002 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 4003 return StmtError(); 4004 } else if (CurContext->isDependentContext()) { 4005 UE = V = E = X = nullptr; 4006 } 4007 } 4008 } 4009 4010 getCurFunction()->setHasBranchProtectedScope(); 4011 4012 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4013 X, V, E, UE, IsXLHSInRHSPart, 4014 IsPostfixUpdate); 4015 } 4016 4017 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 4018 Stmt *AStmt, 4019 SourceLocation StartLoc, 4020 SourceLocation EndLoc) { 4021 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4022 4023 // OpenMP [2.16, Nesting of Regions] 4024 // If specified, a teams construct must be contained within a target 4025 // construct. That target construct must contain no statements or directives 4026 // outside of the teams construct. 4027 if (DSAStack->hasInnerTeamsRegion()) { 4028 auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true); 4029 bool OMPTeamsFound = true; 4030 if (auto *CS = dyn_cast<CompoundStmt>(S)) { 4031 auto I = CS->body_begin(); 4032 while (I != CS->body_end()) { 4033 auto OED = dyn_cast<OMPExecutableDirective>(*I); 4034 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { 4035 OMPTeamsFound = false; 4036 break; 4037 } 4038 ++I; 4039 } 4040 assert(I != CS->body_end() && "Not found statement"); 4041 S = *I; 4042 } 4043 if (!OMPTeamsFound) { 4044 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 4045 Diag(DSAStack->getInnerTeamsRegionLoc(), 4046 diag::note_omp_nested_teams_construct_here); 4047 Diag(S->getLocStart(), diag::note_omp_nested_statement_here) 4048 << isa<OMPExecutableDirective>(S); 4049 return StmtError(); 4050 } 4051 } 4052 4053 getCurFunction()->setHasBranchProtectedScope(); 4054 4055 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 4056 } 4057 4058 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 4059 Stmt *AStmt, SourceLocation StartLoc, 4060 SourceLocation EndLoc) { 4061 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4062 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 4063 // 1.2.2 OpenMP Language Terminology 4064 // Structured block - An executable statement with a single entry at the 4065 // top and a single exit at the bottom. 4066 // The point of exit cannot be a branch out of the structured block. 4067 // longjmp() and throw() must not violate the entry/exit criteria. 4068 CS->getCapturedDecl()->setNothrow(); 4069 4070 getCurFunction()->setHasBranchProtectedScope(); 4071 4072 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 4073 } 4074 4075 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 4076 SourceLocation StartLoc, 4077 SourceLocation LParenLoc, 4078 SourceLocation EndLoc) { 4079 OMPClause *Res = nullptr; 4080 switch (Kind) { 4081 case OMPC_if: 4082 Res = ActOnOpenMPIfClause(Expr, StartLoc, LParenLoc, EndLoc); 4083 break; 4084 case OMPC_final: 4085 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 4086 break; 4087 case OMPC_num_threads: 4088 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 4089 break; 4090 case OMPC_safelen: 4091 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 4092 break; 4093 case OMPC_collapse: 4094 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 4095 break; 4096 case OMPC_default: 4097 case OMPC_proc_bind: 4098 case OMPC_schedule: 4099 case OMPC_private: 4100 case OMPC_firstprivate: 4101 case OMPC_lastprivate: 4102 case OMPC_shared: 4103 case OMPC_reduction: 4104 case OMPC_linear: 4105 case OMPC_aligned: 4106 case OMPC_copyin: 4107 case OMPC_copyprivate: 4108 case OMPC_ordered: 4109 case OMPC_nowait: 4110 case OMPC_untied: 4111 case OMPC_mergeable: 4112 case OMPC_threadprivate: 4113 case OMPC_flush: 4114 case OMPC_read: 4115 case OMPC_write: 4116 case OMPC_update: 4117 case OMPC_capture: 4118 case OMPC_seq_cst: 4119 case OMPC_unknown: 4120 llvm_unreachable("Clause is not allowed."); 4121 } 4122 return Res; 4123 } 4124 4125 OMPClause *Sema::ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc, 4126 SourceLocation LParenLoc, 4127 SourceLocation EndLoc) { 4128 Expr *ValExpr = Condition; 4129 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 4130 !Condition->isInstantiationDependent() && 4131 !Condition->containsUnexpandedParameterPack()) { 4132 ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(), 4133 Condition->getExprLoc(), Condition); 4134 if (Val.isInvalid()) 4135 return nullptr; 4136 4137 ValExpr = Val.get(); 4138 } 4139 4140 return new (Context) OMPIfClause(ValExpr, StartLoc, LParenLoc, EndLoc); 4141 } 4142 4143 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 4144 SourceLocation StartLoc, 4145 SourceLocation LParenLoc, 4146 SourceLocation EndLoc) { 4147 Expr *ValExpr = Condition; 4148 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 4149 !Condition->isInstantiationDependent() && 4150 !Condition->containsUnexpandedParameterPack()) { 4151 ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(), 4152 Condition->getExprLoc(), Condition); 4153 if (Val.isInvalid()) 4154 return nullptr; 4155 4156 ValExpr = Val.get(); 4157 } 4158 4159 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 4160 } 4161 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 4162 Expr *Op) { 4163 if (!Op) 4164 return ExprError(); 4165 4166 class IntConvertDiagnoser : public ICEConvertDiagnoser { 4167 public: 4168 IntConvertDiagnoser() 4169 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 4170 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 4171 QualType T) override { 4172 return S.Diag(Loc, diag::err_omp_not_integral) << T; 4173 } 4174 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 4175 QualType T) override { 4176 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 4177 } 4178 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 4179 QualType T, 4180 QualType ConvTy) override { 4181 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 4182 } 4183 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 4184 QualType ConvTy) override { 4185 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 4186 << ConvTy->isEnumeralType() << ConvTy; 4187 } 4188 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 4189 QualType T) override { 4190 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 4191 } 4192 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 4193 QualType ConvTy) override { 4194 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 4195 << ConvTy->isEnumeralType() << ConvTy; 4196 } 4197 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 4198 QualType) override { 4199 llvm_unreachable("conversion functions are permitted"); 4200 } 4201 } ConvertDiagnoser; 4202 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 4203 } 4204 4205 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 4206 SourceLocation StartLoc, 4207 SourceLocation LParenLoc, 4208 SourceLocation EndLoc) { 4209 Expr *ValExpr = NumThreads; 4210 if (!NumThreads->isValueDependent() && !NumThreads->isTypeDependent() && 4211 !NumThreads->containsUnexpandedParameterPack()) { 4212 SourceLocation NumThreadsLoc = NumThreads->getLocStart(); 4213 ExprResult Val = 4214 PerformOpenMPImplicitIntegerConversion(NumThreadsLoc, NumThreads); 4215 if (Val.isInvalid()) 4216 return nullptr; 4217 4218 ValExpr = Val.get(); 4219 4220 // OpenMP [2.5, Restrictions] 4221 // The num_threads expression must evaluate to a positive integer value. 4222 llvm::APSInt Result; 4223 if (ValExpr->isIntegerConstantExpr(Result, Context) && Result.isSigned() && 4224 !Result.isStrictlyPositive()) { 4225 Diag(NumThreadsLoc, diag::err_omp_negative_expression_in_clause) 4226 << "num_threads" << NumThreads->getSourceRange(); 4227 return nullptr; 4228 } 4229 } 4230 4231 return new (Context) 4232 OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc); 4233 } 4234 4235 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 4236 OpenMPClauseKind CKind) { 4237 if (!E) 4238 return ExprError(); 4239 if (E->isValueDependent() || E->isTypeDependent() || 4240 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4241 return E; 4242 llvm::APSInt Result; 4243 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 4244 if (ICE.isInvalid()) 4245 return ExprError(); 4246 if (!Result.isStrictlyPositive()) { 4247 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 4248 << getOpenMPClauseName(CKind) << E->getSourceRange(); 4249 return ExprError(); 4250 } 4251 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 4252 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 4253 << E->getSourceRange(); 4254 return ExprError(); 4255 } 4256 if (CKind == OMPC_collapse) { 4257 DSAStack->setCollapseNumber(Result.getExtValue()); 4258 } 4259 return ICE; 4260 } 4261 4262 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 4263 SourceLocation LParenLoc, 4264 SourceLocation EndLoc) { 4265 // OpenMP [2.8.1, simd construct, Description] 4266 // The parameter of the safelen clause must be a constant 4267 // positive integer expression. 4268 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 4269 if (Safelen.isInvalid()) 4270 return nullptr; 4271 return new (Context) 4272 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 4273 } 4274 4275 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 4276 SourceLocation StartLoc, 4277 SourceLocation LParenLoc, 4278 SourceLocation EndLoc) { 4279 // OpenMP [2.7.1, loop construct, Description] 4280 // OpenMP [2.8.1, simd construct, Description] 4281 // OpenMP [2.9.6, distribute construct, Description] 4282 // The parameter of the collapse clause must be a constant 4283 // positive integer expression. 4284 ExprResult NumForLoopsResult = 4285 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 4286 if (NumForLoopsResult.isInvalid()) 4287 return nullptr; 4288 return new (Context) 4289 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 4290 } 4291 4292 OMPClause *Sema::ActOnOpenMPSimpleClause( 4293 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 4294 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 4295 OMPClause *Res = nullptr; 4296 switch (Kind) { 4297 case OMPC_default: 4298 Res = 4299 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 4300 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 4301 break; 4302 case OMPC_proc_bind: 4303 Res = ActOnOpenMPProcBindClause( 4304 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 4305 LParenLoc, EndLoc); 4306 break; 4307 case OMPC_if: 4308 case OMPC_final: 4309 case OMPC_num_threads: 4310 case OMPC_safelen: 4311 case OMPC_collapse: 4312 case OMPC_schedule: 4313 case OMPC_private: 4314 case OMPC_firstprivate: 4315 case OMPC_lastprivate: 4316 case OMPC_shared: 4317 case OMPC_reduction: 4318 case OMPC_linear: 4319 case OMPC_aligned: 4320 case OMPC_copyin: 4321 case OMPC_copyprivate: 4322 case OMPC_ordered: 4323 case OMPC_nowait: 4324 case OMPC_untied: 4325 case OMPC_mergeable: 4326 case OMPC_threadprivate: 4327 case OMPC_flush: 4328 case OMPC_read: 4329 case OMPC_write: 4330 case OMPC_update: 4331 case OMPC_capture: 4332 case OMPC_seq_cst: 4333 case OMPC_unknown: 4334 llvm_unreachable("Clause is not allowed."); 4335 } 4336 return Res; 4337 } 4338 4339 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 4340 SourceLocation KindKwLoc, 4341 SourceLocation StartLoc, 4342 SourceLocation LParenLoc, 4343 SourceLocation EndLoc) { 4344 if (Kind == OMPC_DEFAULT_unknown) { 4345 std::string Values; 4346 static_assert(OMPC_DEFAULT_unknown > 0, 4347 "OMPC_DEFAULT_unknown not greater than 0"); 4348 std::string Sep(", "); 4349 for (unsigned i = 0; i < OMPC_DEFAULT_unknown; ++i) { 4350 Values += "'"; 4351 Values += getOpenMPSimpleClauseTypeName(OMPC_default, i); 4352 Values += "'"; 4353 switch (i) { 4354 case OMPC_DEFAULT_unknown - 2: 4355 Values += " or "; 4356 break; 4357 case OMPC_DEFAULT_unknown - 1: 4358 break; 4359 default: 4360 Values += Sep; 4361 break; 4362 } 4363 } 4364 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 4365 << Values << getOpenMPClauseName(OMPC_default); 4366 return nullptr; 4367 } 4368 switch (Kind) { 4369 case OMPC_DEFAULT_none: 4370 DSAStack->setDefaultDSANone(KindKwLoc); 4371 break; 4372 case OMPC_DEFAULT_shared: 4373 DSAStack->setDefaultDSAShared(KindKwLoc); 4374 break; 4375 case OMPC_DEFAULT_unknown: 4376 llvm_unreachable("Clause kind is not allowed."); 4377 break; 4378 } 4379 return new (Context) 4380 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 4381 } 4382 4383 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 4384 SourceLocation KindKwLoc, 4385 SourceLocation StartLoc, 4386 SourceLocation LParenLoc, 4387 SourceLocation EndLoc) { 4388 if (Kind == OMPC_PROC_BIND_unknown) { 4389 std::string Values; 4390 std::string Sep(", "); 4391 for (unsigned i = 0; i < OMPC_PROC_BIND_unknown; ++i) { 4392 Values += "'"; 4393 Values += getOpenMPSimpleClauseTypeName(OMPC_proc_bind, i); 4394 Values += "'"; 4395 switch (i) { 4396 case OMPC_PROC_BIND_unknown - 2: 4397 Values += " or "; 4398 break; 4399 case OMPC_PROC_BIND_unknown - 1: 4400 break; 4401 default: 4402 Values += Sep; 4403 break; 4404 } 4405 } 4406 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 4407 << Values << getOpenMPClauseName(OMPC_proc_bind); 4408 return nullptr; 4409 } 4410 return new (Context) 4411 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 4412 } 4413 4414 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 4415 OpenMPClauseKind Kind, unsigned Argument, Expr *Expr, 4416 SourceLocation StartLoc, SourceLocation LParenLoc, 4417 SourceLocation ArgumentLoc, SourceLocation CommaLoc, 4418 SourceLocation EndLoc) { 4419 OMPClause *Res = nullptr; 4420 switch (Kind) { 4421 case OMPC_schedule: 4422 Res = ActOnOpenMPScheduleClause( 4423 static_cast<OpenMPScheduleClauseKind>(Argument), Expr, StartLoc, 4424 LParenLoc, ArgumentLoc, CommaLoc, EndLoc); 4425 break; 4426 case OMPC_if: 4427 case OMPC_final: 4428 case OMPC_num_threads: 4429 case OMPC_safelen: 4430 case OMPC_collapse: 4431 case OMPC_default: 4432 case OMPC_proc_bind: 4433 case OMPC_private: 4434 case OMPC_firstprivate: 4435 case OMPC_lastprivate: 4436 case OMPC_shared: 4437 case OMPC_reduction: 4438 case OMPC_linear: 4439 case OMPC_aligned: 4440 case OMPC_copyin: 4441 case OMPC_copyprivate: 4442 case OMPC_ordered: 4443 case OMPC_nowait: 4444 case OMPC_untied: 4445 case OMPC_mergeable: 4446 case OMPC_threadprivate: 4447 case OMPC_flush: 4448 case OMPC_read: 4449 case OMPC_write: 4450 case OMPC_update: 4451 case OMPC_capture: 4452 case OMPC_seq_cst: 4453 case OMPC_unknown: 4454 llvm_unreachable("Clause is not allowed."); 4455 } 4456 return Res; 4457 } 4458 4459 OMPClause *Sema::ActOnOpenMPScheduleClause( 4460 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 4461 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 4462 SourceLocation EndLoc) { 4463 if (Kind == OMPC_SCHEDULE_unknown) { 4464 std::string Values; 4465 std::string Sep(", "); 4466 for (unsigned i = 0; i < OMPC_SCHEDULE_unknown; ++i) { 4467 Values += "'"; 4468 Values += getOpenMPSimpleClauseTypeName(OMPC_schedule, i); 4469 Values += "'"; 4470 switch (i) { 4471 case OMPC_SCHEDULE_unknown - 2: 4472 Values += " or "; 4473 break; 4474 case OMPC_SCHEDULE_unknown - 1: 4475 break; 4476 default: 4477 Values += Sep; 4478 break; 4479 } 4480 } 4481 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 4482 << Values << getOpenMPClauseName(OMPC_schedule); 4483 return nullptr; 4484 } 4485 Expr *ValExpr = ChunkSize; 4486 if (ChunkSize) { 4487 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 4488 !ChunkSize->isInstantiationDependent() && 4489 !ChunkSize->containsUnexpandedParameterPack()) { 4490 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 4491 ExprResult Val = 4492 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 4493 if (Val.isInvalid()) 4494 return nullptr; 4495 4496 ValExpr = Val.get(); 4497 4498 // OpenMP [2.7.1, Restrictions] 4499 // chunk_size must be a loop invariant integer expression with a positive 4500 // value. 4501 llvm::APSInt Result; 4502 if (ValExpr->isIntegerConstantExpr(Result, Context) && 4503 Result.isSigned() && !Result.isStrictlyPositive()) { 4504 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 4505 << "schedule" << ChunkSize->getSourceRange(); 4506 return nullptr; 4507 } 4508 } 4509 } 4510 4511 return new (Context) OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, 4512 EndLoc, Kind, ValExpr); 4513 } 4514 4515 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 4516 SourceLocation StartLoc, 4517 SourceLocation EndLoc) { 4518 OMPClause *Res = nullptr; 4519 switch (Kind) { 4520 case OMPC_ordered: 4521 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 4522 break; 4523 case OMPC_nowait: 4524 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 4525 break; 4526 case OMPC_untied: 4527 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 4528 break; 4529 case OMPC_mergeable: 4530 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 4531 break; 4532 case OMPC_read: 4533 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 4534 break; 4535 case OMPC_write: 4536 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 4537 break; 4538 case OMPC_update: 4539 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 4540 break; 4541 case OMPC_capture: 4542 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 4543 break; 4544 case OMPC_seq_cst: 4545 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 4546 break; 4547 case OMPC_if: 4548 case OMPC_final: 4549 case OMPC_num_threads: 4550 case OMPC_safelen: 4551 case OMPC_collapse: 4552 case OMPC_schedule: 4553 case OMPC_private: 4554 case OMPC_firstprivate: 4555 case OMPC_lastprivate: 4556 case OMPC_shared: 4557 case OMPC_reduction: 4558 case OMPC_linear: 4559 case OMPC_aligned: 4560 case OMPC_copyin: 4561 case OMPC_copyprivate: 4562 case OMPC_default: 4563 case OMPC_proc_bind: 4564 case OMPC_threadprivate: 4565 case OMPC_flush: 4566 case OMPC_unknown: 4567 llvm_unreachable("Clause is not allowed."); 4568 } 4569 return Res; 4570 } 4571 4572 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 4573 SourceLocation EndLoc) { 4574 DSAStack->setOrderedRegion(); 4575 return new (Context) OMPOrderedClause(StartLoc, EndLoc); 4576 } 4577 4578 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 4579 SourceLocation EndLoc) { 4580 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 4581 } 4582 4583 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 4584 SourceLocation EndLoc) { 4585 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 4586 } 4587 4588 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 4589 SourceLocation EndLoc) { 4590 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 4591 } 4592 4593 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 4594 SourceLocation EndLoc) { 4595 return new (Context) OMPReadClause(StartLoc, EndLoc); 4596 } 4597 4598 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 4599 SourceLocation EndLoc) { 4600 return new (Context) OMPWriteClause(StartLoc, EndLoc); 4601 } 4602 4603 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 4604 SourceLocation EndLoc) { 4605 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 4606 } 4607 4608 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 4609 SourceLocation EndLoc) { 4610 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 4611 } 4612 4613 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 4614 SourceLocation EndLoc) { 4615 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 4616 } 4617 4618 OMPClause *Sema::ActOnOpenMPVarListClause( 4619 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 4620 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 4621 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 4622 const DeclarationNameInfo &ReductionId) { 4623 OMPClause *Res = nullptr; 4624 switch (Kind) { 4625 case OMPC_private: 4626 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 4627 break; 4628 case OMPC_firstprivate: 4629 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 4630 break; 4631 case OMPC_lastprivate: 4632 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 4633 break; 4634 case OMPC_shared: 4635 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 4636 break; 4637 case OMPC_reduction: 4638 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 4639 EndLoc, ReductionIdScopeSpec, ReductionId); 4640 break; 4641 case OMPC_linear: 4642 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 4643 ColonLoc, EndLoc); 4644 break; 4645 case OMPC_aligned: 4646 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 4647 ColonLoc, EndLoc); 4648 break; 4649 case OMPC_copyin: 4650 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 4651 break; 4652 case OMPC_copyprivate: 4653 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 4654 break; 4655 case OMPC_flush: 4656 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 4657 break; 4658 case OMPC_if: 4659 case OMPC_final: 4660 case OMPC_num_threads: 4661 case OMPC_safelen: 4662 case OMPC_collapse: 4663 case OMPC_default: 4664 case OMPC_proc_bind: 4665 case OMPC_schedule: 4666 case OMPC_ordered: 4667 case OMPC_nowait: 4668 case OMPC_untied: 4669 case OMPC_mergeable: 4670 case OMPC_threadprivate: 4671 case OMPC_read: 4672 case OMPC_write: 4673 case OMPC_update: 4674 case OMPC_capture: 4675 case OMPC_seq_cst: 4676 case OMPC_unknown: 4677 llvm_unreachable("Clause is not allowed."); 4678 } 4679 return Res; 4680 } 4681 4682 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 4683 SourceLocation StartLoc, 4684 SourceLocation LParenLoc, 4685 SourceLocation EndLoc) { 4686 SmallVector<Expr *, 8> Vars; 4687 SmallVector<Expr *, 8> PrivateCopies; 4688 for (auto &RefExpr : VarList) { 4689 assert(RefExpr && "NULL expr in OpenMP private clause."); 4690 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 4691 // It will be analyzed later. 4692 Vars.push_back(RefExpr); 4693 PrivateCopies.push_back(nullptr); 4694 continue; 4695 } 4696 4697 SourceLocation ELoc = RefExpr->getExprLoc(); 4698 // OpenMP [2.1, C/C++] 4699 // A list item is a variable name. 4700 // OpenMP [2.9.3.3, Restrictions, p.1] 4701 // A variable that is part of another variable (as an array or 4702 // structure element) cannot appear in a private clause. 4703 DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4704 if (!DE || !isa<VarDecl>(DE->getDecl())) { 4705 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 4706 continue; 4707 } 4708 Decl *D = DE->getDecl(); 4709 VarDecl *VD = cast<VarDecl>(D); 4710 4711 QualType Type = VD->getType(); 4712 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 4713 // It will be analyzed later. 4714 Vars.push_back(DE); 4715 PrivateCopies.push_back(nullptr); 4716 continue; 4717 } 4718 4719 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 4720 // A variable that appears in a private clause must not have an incomplete 4721 // type or a reference type. 4722 if (RequireCompleteType(ELoc, Type, 4723 diag::err_omp_private_incomplete_type)) { 4724 continue; 4725 } 4726 if (Type->isReferenceType()) { 4727 Diag(ELoc, diag::err_omp_clause_ref_type_arg) 4728 << getOpenMPClauseName(OMPC_private) << Type; 4729 bool IsDecl = 4730 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 4731 Diag(VD->getLocation(), 4732 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 4733 << VD; 4734 continue; 4735 } 4736 4737 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 4738 // A variable of class type (or array thereof) that appears in a private 4739 // clause requires an accessible, unambiguous default constructor for the 4740 // class type. 4741 while (Type->isArrayType()) { 4742 Type = cast<ArrayType>(Type.getTypePtr())->getElementType(); 4743 } 4744 4745 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 4746 // in a Construct] 4747 // Variables with the predetermined data-sharing attributes may not be 4748 // listed in data-sharing attributes clauses, except for the cases 4749 // listed below. For these exceptions only, listing a predetermined 4750 // variable in a data-sharing attribute clause is allowed and overrides 4751 // the variable's predetermined data-sharing attributes. 4752 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 4753 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 4754 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 4755 << getOpenMPClauseName(OMPC_private); 4756 ReportOriginalDSA(*this, DSAStack, VD, DVar); 4757 continue; 4758 } 4759 4760 // Generate helper private variable and initialize it with the default 4761 // value. The address of the original variable is replaced by the address of 4762 // the new private variable in CodeGen. This new variable is not added to 4763 // IdResolver, so the code in the OpenMP region uses original variable for 4764 // proper diagnostics. 4765 auto VDPrivate = VarDecl::Create(Context, CurContext, DE->getLocStart(), 4766 DE->getExprLoc(), VD->getIdentifier(), 4767 VD->getType().getUnqualifiedType(), 4768 VD->getTypeSourceInfo(), /*S*/ SC_Auto); 4769 ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto*/ false); 4770 if (VDPrivate->isInvalidDecl()) 4771 continue; 4772 CurContext->addDecl(VDPrivate); 4773 auto VDPrivateRefExpr = 4774 DeclRefExpr::Create(Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), 4775 /*TemplateKWLoc*/ SourceLocation(), VDPrivate, 4776 /*RefersToEnclosingVariableOrCapture*/ false, 4777 /*NameLoc*/ SourceLocation(), DE->getType(), 4778 /*VK*/ VK_LValue); 4779 4780 DSAStack->addDSA(VD, DE, OMPC_private); 4781 Vars.push_back(DE); 4782 PrivateCopies.push_back(VDPrivateRefExpr); 4783 } 4784 4785 if (Vars.empty()) 4786 return nullptr; 4787 4788 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 4789 PrivateCopies); 4790 } 4791 4792 namespace { 4793 class DiagsUninitializedSeveretyRAII { 4794 private: 4795 DiagnosticsEngine &Diags; 4796 SourceLocation SavedLoc; 4797 bool IsIgnored; 4798 4799 public: 4800 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 4801 bool IsIgnored) 4802 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 4803 if (!IsIgnored) { 4804 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 4805 /*Map*/ diag::Severity::Ignored, Loc); 4806 } 4807 } 4808 ~DiagsUninitializedSeveretyRAII() { 4809 if (!IsIgnored) 4810 Diags.popMappings(SavedLoc); 4811 } 4812 }; 4813 } 4814 4815 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 4816 SourceLocation StartLoc, 4817 SourceLocation LParenLoc, 4818 SourceLocation EndLoc) { 4819 SmallVector<Expr *, 8> Vars; 4820 SmallVector<Expr *, 8> PrivateCopies; 4821 SmallVector<Expr *, 8> Inits; 4822 bool IsImplicitClause = 4823 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 4824 auto ImplicitClauseLoc = DSAStack->getConstructLoc(); 4825 4826 for (auto &RefExpr : VarList) { 4827 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 4828 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 4829 // It will be analyzed later. 4830 Vars.push_back(RefExpr); 4831 PrivateCopies.push_back(nullptr); 4832 Inits.push_back(nullptr); 4833 continue; 4834 } 4835 4836 SourceLocation ELoc = 4837 IsImplicitClause ? ImplicitClauseLoc : RefExpr->getExprLoc(); 4838 // OpenMP [2.1, C/C++] 4839 // A list item is a variable name. 4840 // OpenMP [2.9.3.3, Restrictions, p.1] 4841 // A variable that is part of another variable (as an array or 4842 // structure element) cannot appear in a private clause. 4843 DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 4844 if (!DE || !isa<VarDecl>(DE->getDecl())) { 4845 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 4846 continue; 4847 } 4848 Decl *D = DE->getDecl(); 4849 VarDecl *VD = cast<VarDecl>(D); 4850 4851 QualType Type = VD->getType(); 4852 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 4853 // It will be analyzed later. 4854 Vars.push_back(DE); 4855 PrivateCopies.push_back(nullptr); 4856 Inits.push_back(nullptr); 4857 continue; 4858 } 4859 4860 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 4861 // A variable that appears in a private clause must not have an incomplete 4862 // type or a reference type. 4863 if (RequireCompleteType(ELoc, Type, 4864 diag::err_omp_firstprivate_incomplete_type)) { 4865 continue; 4866 } 4867 if (Type->isReferenceType()) { 4868 if (IsImplicitClause) { 4869 Diag(ImplicitClauseLoc, 4870 diag::err_omp_task_predetermined_firstprivate_ref_type_arg) 4871 << Type; 4872 Diag(RefExpr->getExprLoc(), diag::note_used_here); 4873 } else { 4874 Diag(ELoc, diag::err_omp_clause_ref_type_arg) 4875 << getOpenMPClauseName(OMPC_firstprivate) << Type; 4876 } 4877 bool IsDecl = 4878 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 4879 Diag(VD->getLocation(), 4880 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 4881 << VD; 4882 continue; 4883 } 4884 4885 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 4886 // A variable of class type (or array thereof) that appears in a private 4887 // clause requires an accessible, unambiguous copy constructor for the 4888 // class type. 4889 Type = Context.getBaseElementType(Type).getNonReferenceType(); 4890 4891 // If an implicit firstprivate variable found it was checked already. 4892 if (!IsImplicitClause) { 4893 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 4894 Type = Type.getNonReferenceType().getCanonicalType(); 4895 bool IsConstant = Type.isConstant(Context); 4896 Type = Context.getBaseElementType(Type); 4897 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 4898 // A list item that specifies a given variable may not appear in more 4899 // than one clause on the same directive, except that a variable may be 4900 // specified in both firstprivate and lastprivate clauses. 4901 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 4902 DVar.CKind != OMPC_lastprivate && DVar.RefExpr) { 4903 Diag(ELoc, diag::err_omp_wrong_dsa) 4904 << getOpenMPClauseName(DVar.CKind) 4905 << getOpenMPClauseName(OMPC_firstprivate); 4906 ReportOriginalDSA(*this, DSAStack, VD, DVar); 4907 continue; 4908 } 4909 4910 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 4911 // in a Construct] 4912 // Variables with the predetermined data-sharing attributes may not be 4913 // listed in data-sharing attributes clauses, except for the cases 4914 // listed below. For these exceptions only, listing a predetermined 4915 // variable in a data-sharing attribute clause is allowed and overrides 4916 // the variable's predetermined data-sharing attributes. 4917 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 4918 // in a Construct, C/C++, p.2] 4919 // Variables with const-qualified type having no mutable member may be 4920 // listed in a firstprivate clause, even if they are static data members. 4921 if (!(IsConstant || VD->isStaticDataMember()) && !DVar.RefExpr && 4922 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 4923 Diag(ELoc, diag::err_omp_wrong_dsa) 4924 << getOpenMPClauseName(DVar.CKind) 4925 << getOpenMPClauseName(OMPC_firstprivate); 4926 ReportOriginalDSA(*this, DSAStack, VD, DVar); 4927 continue; 4928 } 4929 4930 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 4931 // OpenMP [2.9.3.4, Restrictions, p.2] 4932 // A list item that is private within a parallel region must not appear 4933 // in a firstprivate clause on a worksharing construct if any of the 4934 // worksharing regions arising from the worksharing construct ever bind 4935 // to any of the parallel regions arising from the parallel construct. 4936 if (isOpenMPWorksharingDirective(CurrDir) && 4937 !isOpenMPParallelDirective(CurrDir)) { 4938 DVar = DSAStack->getImplicitDSA(VD, true); 4939 if (DVar.CKind != OMPC_shared && 4940 (isOpenMPParallelDirective(DVar.DKind) || 4941 DVar.DKind == OMPD_unknown)) { 4942 Diag(ELoc, diag::err_omp_required_access) 4943 << getOpenMPClauseName(OMPC_firstprivate) 4944 << getOpenMPClauseName(OMPC_shared); 4945 ReportOriginalDSA(*this, DSAStack, VD, DVar); 4946 continue; 4947 } 4948 } 4949 // OpenMP [2.9.3.4, Restrictions, p.3] 4950 // A list item that appears in a reduction clause of a parallel construct 4951 // must not appear in a firstprivate clause on a worksharing or task 4952 // construct if any of the worksharing or task regions arising from the 4953 // worksharing or task construct ever bind to any of the parallel regions 4954 // arising from the parallel construct. 4955 // OpenMP [2.9.3.4, Restrictions, p.4] 4956 // A list item that appears in a reduction clause in worksharing 4957 // construct must not appear in a firstprivate clause in a task construct 4958 // encountered during execution of any of the worksharing regions arising 4959 // from the worksharing construct. 4960 if (CurrDir == OMPD_task) { 4961 DVar = 4962 DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction), 4963 [](OpenMPDirectiveKind K) -> bool { 4964 return isOpenMPParallelDirective(K) || 4965 isOpenMPWorksharingDirective(K); 4966 }, 4967 false); 4968 if (DVar.CKind == OMPC_reduction && 4969 (isOpenMPParallelDirective(DVar.DKind) || 4970 isOpenMPWorksharingDirective(DVar.DKind))) { 4971 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 4972 << getOpenMPDirectiveName(DVar.DKind); 4973 ReportOriginalDSA(*this, DSAStack, VD, DVar); 4974 continue; 4975 } 4976 } 4977 } 4978 4979 auto VDPrivate = 4980 VarDecl::Create(Context, CurContext, DE->getLocStart(), ELoc, 4981 VD->getIdentifier(), VD->getType().getUnqualifiedType(), 4982 VD->getTypeSourceInfo(), /*S*/ SC_Auto); 4983 // Generate helper private variable and initialize it with the value of the 4984 // original variable. The address of the original variable is replaced by 4985 // the address of the new private variable in the CodeGen. This new variable 4986 // is not added to IdResolver, so the code in the OpenMP region uses 4987 // original variable for proper diagnostics and variable capturing. 4988 Expr *VDInitRefExpr = nullptr; 4989 // For arrays generate initializer for single element and replace it by the 4990 // original array element in CodeGen. 4991 if (DE->getType()->isArrayType()) { 4992 auto VDInit = VarDecl::Create(Context, CurContext, DE->getLocStart(), 4993 ELoc, VD->getIdentifier(), Type, 4994 VD->getTypeSourceInfo(), /*S*/ SC_Auto); 4995 CurContext->addHiddenDecl(VDInit); 4996 VDInitRefExpr = DeclRefExpr::Create( 4997 Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), 4998 /*TemplateKWLoc*/ SourceLocation(), VDInit, 4999 /*RefersToEnclosingVariableOrCapture*/ true, ELoc, Type, 5000 /*VK*/ VK_LValue); 5001 auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); 5002 auto *VDInitTemp = 5003 BuildVarDecl(*this, DE->getLocStart(), Type.getUnqualifiedType(), 5004 ".firstprivate.temp"); 5005 InitializedEntity Entity = 5006 InitializedEntity::InitializeVariable(VDInitTemp); 5007 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 5008 5009 InitializationSequence InitSeq(*this, Entity, Kind, Init); 5010 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 5011 if (Result.isInvalid()) 5012 VDPrivate->setInvalidDecl(); 5013 else 5014 VDPrivate->setInit(Result.getAs<Expr>()); 5015 } else { 5016 auto *VDInit = 5017 BuildVarDecl(*this, DE->getLocStart(), Type, ".firstprivate.temp"); 5018 VDInitRefExpr = 5019 BuildDeclRefExpr(VDInit, Type, VK_LValue, DE->getExprLoc()).get(); 5020 AddInitializerToDecl(VDPrivate, 5021 DefaultLvalueConversion(VDInitRefExpr).get(), 5022 /*DirectInit=*/false, /*TypeMayContainAuto=*/false); 5023 } 5024 if (VDPrivate->isInvalidDecl()) { 5025 if (IsImplicitClause) { 5026 Diag(DE->getExprLoc(), 5027 diag::note_omp_task_predetermined_firstprivate_here); 5028 } 5029 continue; 5030 } 5031 CurContext->addDecl(VDPrivate); 5032 auto VDPrivateRefExpr = DeclRefExpr::Create( 5033 Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), 5034 /*TemplateKWLoc*/ SourceLocation(), VDPrivate, 5035 /*RefersToEnclosingVariableOrCapture*/ false, DE->getLocStart(), 5036 DE->getType().getUnqualifiedType(), /*VK*/ VK_LValue); 5037 DSAStack->addDSA(VD, DE, OMPC_firstprivate); 5038 Vars.push_back(DE); 5039 PrivateCopies.push_back(VDPrivateRefExpr); 5040 Inits.push_back(VDInitRefExpr); 5041 } 5042 5043 if (Vars.empty()) 5044 return nullptr; 5045 5046 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 5047 Vars, PrivateCopies, Inits); 5048 } 5049 5050 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 5051 SourceLocation StartLoc, 5052 SourceLocation LParenLoc, 5053 SourceLocation EndLoc) { 5054 SmallVector<Expr *, 8> Vars; 5055 SmallVector<Expr *, 8> SrcExprs; 5056 SmallVector<Expr *, 8> DstExprs; 5057 SmallVector<Expr *, 8> AssignmentOps; 5058 for (auto &RefExpr : VarList) { 5059 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 5060 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 5061 // It will be analyzed later. 5062 Vars.push_back(RefExpr); 5063 SrcExprs.push_back(nullptr); 5064 DstExprs.push_back(nullptr); 5065 AssignmentOps.push_back(nullptr); 5066 continue; 5067 } 5068 5069 SourceLocation ELoc = RefExpr->getExprLoc(); 5070 // OpenMP [2.1, C/C++] 5071 // A list item is a variable name. 5072 // OpenMP [2.14.3.5, Restrictions, p.1] 5073 // A variable that is part of another variable (as an array or structure 5074 // element) cannot appear in a lastprivate clause. 5075 DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 5076 if (!DE || !isa<VarDecl>(DE->getDecl())) { 5077 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 5078 continue; 5079 } 5080 Decl *D = DE->getDecl(); 5081 VarDecl *VD = cast<VarDecl>(D); 5082 5083 QualType Type = VD->getType(); 5084 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 5085 // It will be analyzed later. 5086 Vars.push_back(DE); 5087 SrcExprs.push_back(nullptr); 5088 DstExprs.push_back(nullptr); 5089 AssignmentOps.push_back(nullptr); 5090 continue; 5091 } 5092 5093 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 5094 // A variable that appears in a lastprivate clause must not have an 5095 // incomplete type or a reference type. 5096 if (RequireCompleteType(ELoc, Type, 5097 diag::err_omp_lastprivate_incomplete_type)) { 5098 continue; 5099 } 5100 if (Type->isReferenceType()) { 5101 Diag(ELoc, diag::err_omp_clause_ref_type_arg) 5102 << getOpenMPClauseName(OMPC_lastprivate) << Type; 5103 bool IsDecl = 5104 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5105 Diag(VD->getLocation(), 5106 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5107 << VD; 5108 continue; 5109 } 5110 5111 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 5112 // in a Construct] 5113 // Variables with the predetermined data-sharing attributes may not be 5114 // listed in data-sharing attributes clauses, except for the cases 5115 // listed below. 5116 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 5117 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 5118 DVar.CKind != OMPC_firstprivate && 5119 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 5120 Diag(ELoc, diag::err_omp_wrong_dsa) 5121 << getOpenMPClauseName(DVar.CKind) 5122 << getOpenMPClauseName(OMPC_lastprivate); 5123 ReportOriginalDSA(*this, DSAStack, VD, DVar); 5124 continue; 5125 } 5126 5127 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 5128 // OpenMP [2.14.3.5, Restrictions, p.2] 5129 // A list item that is private within a parallel region, or that appears in 5130 // the reduction clause of a parallel construct, must not appear in a 5131 // lastprivate clause on a worksharing construct if any of the corresponding 5132 // worksharing regions ever binds to any of the corresponding parallel 5133 // regions. 5134 if (isOpenMPWorksharingDirective(CurrDir) && 5135 !isOpenMPParallelDirective(CurrDir)) { 5136 DVar = DSAStack->getImplicitDSA(VD, true); 5137 if (DVar.CKind != OMPC_shared) { 5138 Diag(ELoc, diag::err_omp_required_access) 5139 << getOpenMPClauseName(OMPC_lastprivate) 5140 << getOpenMPClauseName(OMPC_shared); 5141 ReportOriginalDSA(*this, DSAStack, VD, DVar); 5142 continue; 5143 } 5144 } 5145 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 5146 // A variable of class type (or array thereof) that appears in a 5147 // lastprivate clause requires an accessible, unambiguous default 5148 // constructor for the class type, unless the list item is also specified 5149 // in a firstprivate clause. 5150 // A variable of class type (or array thereof) that appears in a 5151 // lastprivate clause requires an accessible, unambiguous copy assignment 5152 // operator for the class type. 5153 Type = Context.getBaseElementType(Type).getNonReferenceType(); 5154 auto *SrcVD = BuildVarDecl(*this, DE->getLocStart(), 5155 Type.getUnqualifiedType(), ".lastprivate.src"); 5156 auto *PseudoSrcExpr = BuildDeclRefExpr(SrcVD, Type.getUnqualifiedType(), 5157 VK_LValue, DE->getExprLoc()).get(); 5158 auto *DstVD = 5159 BuildVarDecl(*this, DE->getLocStart(), Type, ".lastprivate.dst"); 5160 auto *PseudoDstExpr = 5161 BuildDeclRefExpr(DstVD, Type, VK_LValue, DE->getExprLoc()).get(); 5162 // For arrays generate assignment operation for single element and replace 5163 // it by the original array element in CodeGen. 5164 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 5165 PseudoDstExpr, PseudoSrcExpr); 5166 if (AssignmentOp.isInvalid()) 5167 continue; 5168 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 5169 /*DiscardedValue=*/true); 5170 if (AssignmentOp.isInvalid()) 5171 continue; 5172 5173 if (DVar.CKind != OMPC_firstprivate) 5174 DSAStack->addDSA(VD, DE, OMPC_lastprivate); 5175 Vars.push_back(DE); 5176 SrcExprs.push_back(PseudoSrcExpr); 5177 DstExprs.push_back(PseudoDstExpr); 5178 AssignmentOps.push_back(AssignmentOp.get()); 5179 } 5180 5181 if (Vars.empty()) 5182 return nullptr; 5183 5184 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 5185 Vars, SrcExprs, DstExprs, AssignmentOps); 5186 } 5187 5188 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 5189 SourceLocation StartLoc, 5190 SourceLocation LParenLoc, 5191 SourceLocation EndLoc) { 5192 SmallVector<Expr *, 8> Vars; 5193 for (auto &RefExpr : VarList) { 5194 assert(RefExpr && "NULL expr in OpenMP shared clause."); 5195 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 5196 // It will be analyzed later. 5197 Vars.push_back(RefExpr); 5198 continue; 5199 } 5200 5201 SourceLocation ELoc = RefExpr->getExprLoc(); 5202 // OpenMP [2.1, C/C++] 5203 // A list item is a variable name. 5204 // OpenMP [2.14.3.2, Restrictions, p.1] 5205 // A variable that is part of another variable (as an array or structure 5206 // element) cannot appear in a shared unless it is a static data member 5207 // of a C++ class. 5208 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 5209 if (!DE || !isa<VarDecl>(DE->getDecl())) { 5210 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 5211 continue; 5212 } 5213 Decl *D = DE->getDecl(); 5214 VarDecl *VD = cast<VarDecl>(D); 5215 5216 QualType Type = VD->getType(); 5217 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 5218 // It will be analyzed later. 5219 Vars.push_back(DE); 5220 continue; 5221 } 5222 5223 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 5224 // in a Construct] 5225 // Variables with the predetermined data-sharing attributes may not be 5226 // listed in data-sharing attributes clauses, except for the cases 5227 // listed below. For these exceptions only, listing a predetermined 5228 // variable in a data-sharing attribute clause is allowed and overrides 5229 // the variable's predetermined data-sharing attributes. 5230 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 5231 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 5232 DVar.RefExpr) { 5233 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 5234 << getOpenMPClauseName(OMPC_shared); 5235 ReportOriginalDSA(*this, DSAStack, VD, DVar); 5236 continue; 5237 } 5238 5239 DSAStack->addDSA(VD, DE, OMPC_shared); 5240 Vars.push_back(DE); 5241 } 5242 5243 if (Vars.empty()) 5244 return nullptr; 5245 5246 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 5247 } 5248 5249 namespace { 5250 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 5251 DSAStackTy *Stack; 5252 5253 public: 5254 bool VisitDeclRefExpr(DeclRefExpr *E) { 5255 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { 5256 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false); 5257 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 5258 return false; 5259 if (DVar.CKind != OMPC_unknown) 5260 return true; 5261 DSAStackTy::DSAVarData DVarPrivate = 5262 Stack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), false); 5263 if (DVarPrivate.CKind != OMPC_unknown) 5264 return true; 5265 return false; 5266 } 5267 return false; 5268 } 5269 bool VisitStmt(Stmt *S) { 5270 for (auto Child : S->children()) { 5271 if (Child && Visit(Child)) 5272 return true; 5273 } 5274 return false; 5275 } 5276 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 5277 }; 5278 } // namespace 5279 5280 OMPClause *Sema::ActOnOpenMPReductionClause( 5281 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 5282 SourceLocation ColonLoc, SourceLocation EndLoc, 5283 CXXScopeSpec &ReductionIdScopeSpec, 5284 const DeclarationNameInfo &ReductionId) { 5285 // TODO: Allow scope specification search when 'declare reduction' is 5286 // supported. 5287 assert(ReductionIdScopeSpec.isEmpty() && 5288 "No support for scoped reduction identifiers yet."); 5289 5290 auto DN = ReductionId.getName(); 5291 auto OOK = DN.getCXXOverloadedOperator(); 5292 BinaryOperatorKind BOK = BO_Comma; 5293 5294 // OpenMP [2.14.3.6, reduction clause] 5295 // C 5296 // reduction-identifier is either an identifier or one of the following 5297 // operators: +, -, *, &, |, ^, && and || 5298 // C++ 5299 // reduction-identifier is either an id-expression or one of the following 5300 // operators: +, -, *, &, |, ^, && and || 5301 // FIXME: Only 'min' and 'max' identifiers are supported for now. 5302 switch (OOK) { 5303 case OO_Plus: 5304 case OO_Minus: 5305 BOK = BO_Add; 5306 break; 5307 case OO_Star: 5308 BOK = BO_Mul; 5309 break; 5310 case OO_Amp: 5311 BOK = BO_And; 5312 break; 5313 case OO_Pipe: 5314 BOK = BO_Or; 5315 break; 5316 case OO_Caret: 5317 BOK = BO_Xor; 5318 break; 5319 case OO_AmpAmp: 5320 BOK = BO_LAnd; 5321 break; 5322 case OO_PipePipe: 5323 BOK = BO_LOr; 5324 break; 5325 case OO_New: 5326 case OO_Delete: 5327 case OO_Array_New: 5328 case OO_Array_Delete: 5329 case OO_Slash: 5330 case OO_Percent: 5331 case OO_Tilde: 5332 case OO_Exclaim: 5333 case OO_Equal: 5334 case OO_Less: 5335 case OO_Greater: 5336 case OO_LessEqual: 5337 case OO_GreaterEqual: 5338 case OO_PlusEqual: 5339 case OO_MinusEqual: 5340 case OO_StarEqual: 5341 case OO_SlashEqual: 5342 case OO_PercentEqual: 5343 case OO_CaretEqual: 5344 case OO_AmpEqual: 5345 case OO_PipeEqual: 5346 case OO_LessLess: 5347 case OO_GreaterGreater: 5348 case OO_LessLessEqual: 5349 case OO_GreaterGreaterEqual: 5350 case OO_EqualEqual: 5351 case OO_ExclaimEqual: 5352 case OO_PlusPlus: 5353 case OO_MinusMinus: 5354 case OO_Comma: 5355 case OO_ArrowStar: 5356 case OO_Arrow: 5357 case OO_Call: 5358 case OO_Subscript: 5359 case OO_Conditional: 5360 case NUM_OVERLOADED_OPERATORS: 5361 llvm_unreachable("Unexpected reduction identifier"); 5362 case OO_None: 5363 if (auto II = DN.getAsIdentifierInfo()) { 5364 if (II->isStr("max")) 5365 BOK = BO_GT; 5366 else if (II->isStr("min")) 5367 BOK = BO_LT; 5368 } 5369 break; 5370 } 5371 SourceRange ReductionIdRange; 5372 if (ReductionIdScopeSpec.isValid()) { 5373 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 5374 } 5375 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 5376 if (BOK == BO_Comma) { 5377 // Not allowed reduction identifier is found. 5378 Diag(ReductionId.getLocStart(), diag::err_omp_unknown_reduction_identifier) 5379 << ReductionIdRange; 5380 return nullptr; 5381 } 5382 5383 SmallVector<Expr *, 8> Vars; 5384 SmallVector<Expr *, 8> LHSs; 5385 SmallVector<Expr *, 8> RHSs; 5386 SmallVector<Expr *, 8> ReductionOps; 5387 for (auto RefExpr : VarList) { 5388 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 5389 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 5390 // It will be analyzed later. 5391 Vars.push_back(RefExpr); 5392 LHSs.push_back(nullptr); 5393 RHSs.push_back(nullptr); 5394 ReductionOps.push_back(nullptr); 5395 continue; 5396 } 5397 5398 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 5399 RefExpr->isInstantiationDependent() || 5400 RefExpr->containsUnexpandedParameterPack()) { 5401 // It will be analyzed later. 5402 Vars.push_back(RefExpr); 5403 LHSs.push_back(nullptr); 5404 RHSs.push_back(nullptr); 5405 ReductionOps.push_back(nullptr); 5406 continue; 5407 } 5408 5409 auto ELoc = RefExpr->getExprLoc(); 5410 auto ERange = RefExpr->getSourceRange(); 5411 // OpenMP [2.1, C/C++] 5412 // A list item is a variable or array section, subject to the restrictions 5413 // specified in Section 2.4 on page 42 and in each of the sections 5414 // describing clauses and directives for which a list appears. 5415 // OpenMP [2.14.3.3, Restrictions, p.1] 5416 // A variable that is part of another variable (as an array or 5417 // structure element) cannot appear in a private clause. 5418 auto DE = dyn_cast<DeclRefExpr>(RefExpr); 5419 if (!DE || !isa<VarDecl>(DE->getDecl())) { 5420 Diag(ELoc, diag::err_omp_expected_var_name) << ERange; 5421 continue; 5422 } 5423 auto D = DE->getDecl(); 5424 auto VD = cast<VarDecl>(D); 5425 auto Type = VD->getType(); 5426 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 5427 // A variable that appears in a private clause must not have an incomplete 5428 // type or a reference type. 5429 if (RequireCompleteType(ELoc, Type, 5430 diag::err_omp_reduction_incomplete_type)) 5431 continue; 5432 // OpenMP [2.14.3.6, reduction clause, Restrictions] 5433 // Arrays may not appear in a reduction clause. 5434 if (Type.getNonReferenceType()->isArrayType()) { 5435 Diag(ELoc, diag::err_omp_reduction_type_array) << Type << ERange; 5436 bool IsDecl = 5437 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5438 Diag(VD->getLocation(), 5439 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5440 << VD; 5441 continue; 5442 } 5443 // OpenMP [2.14.3.6, reduction clause, Restrictions] 5444 // A list item that appears in a reduction clause must not be 5445 // const-qualified. 5446 if (Type.getNonReferenceType().isConstant(Context)) { 5447 Diag(ELoc, diag::err_omp_const_variable) 5448 << getOpenMPClauseName(OMPC_reduction) << Type << ERange; 5449 bool IsDecl = 5450 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5451 Diag(VD->getLocation(), 5452 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5453 << VD; 5454 continue; 5455 } 5456 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 5457 // If a list-item is a reference type then it must bind to the same object 5458 // for all threads of the team. 5459 VarDecl *VDDef = VD->getDefinition(); 5460 if (Type->isReferenceType() && VDDef) { 5461 DSARefChecker Check(DSAStack); 5462 if (Check.Visit(VDDef->getInit())) { 5463 Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; 5464 Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 5465 continue; 5466 } 5467 } 5468 // OpenMP [2.14.3.6, reduction clause, Restrictions] 5469 // The type of a list item that appears in a reduction clause must be valid 5470 // for the reduction-identifier. For a max or min reduction in C, the type 5471 // of the list item must be an allowed arithmetic data type: char, int, 5472 // float, double, or _Bool, possibly modified with long, short, signed, or 5473 // unsigned. For a max or min reduction in C++, the type of the list item 5474 // must be an allowed arithmetic data type: char, wchar_t, int, float, 5475 // double, or bool, possibly modified with long, short, signed, or unsigned. 5476 if ((BOK == BO_GT || BOK == BO_LT) && 5477 !(Type->isScalarType() || 5478 (getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 5479 Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 5480 << getLangOpts().CPlusPlus; 5481 bool IsDecl = 5482 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5483 Diag(VD->getLocation(), 5484 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5485 << VD; 5486 continue; 5487 } 5488 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 5489 !getLangOpts().CPlusPlus && Type->isFloatingType()) { 5490 Diag(ELoc, diag::err_omp_clause_floating_type_arg); 5491 bool IsDecl = 5492 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5493 Diag(VD->getLocation(), 5494 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5495 << VD; 5496 continue; 5497 } 5498 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 5499 // in a Construct] 5500 // Variables with the predetermined data-sharing attributes may not be 5501 // listed in data-sharing attributes clauses, except for the cases 5502 // listed below. For these exceptions only, listing a predetermined 5503 // variable in a data-sharing attribute clause is allowed and overrides 5504 // the variable's predetermined data-sharing attributes. 5505 // OpenMP [2.14.3.6, Restrictions, p.3] 5506 // Any number of reduction clauses can be specified on the directive, 5507 // but a list item can appear only once in the reduction clauses for that 5508 // directive. 5509 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 5510 if (DVar.CKind == OMPC_reduction) { 5511 Diag(ELoc, diag::err_omp_once_referenced) 5512 << getOpenMPClauseName(OMPC_reduction); 5513 if (DVar.RefExpr) { 5514 Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 5515 } 5516 } else if (DVar.CKind != OMPC_unknown) { 5517 Diag(ELoc, diag::err_omp_wrong_dsa) 5518 << getOpenMPClauseName(DVar.CKind) 5519 << getOpenMPClauseName(OMPC_reduction); 5520 ReportOriginalDSA(*this, DSAStack, VD, DVar); 5521 continue; 5522 } 5523 5524 // OpenMP [2.14.3.6, Restrictions, p.1] 5525 // A list item that appears in a reduction clause of a worksharing 5526 // construct must be shared in the parallel regions to which any of the 5527 // worksharing regions arising from the worksharing construct bind. 5528 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 5529 if (isOpenMPWorksharingDirective(CurrDir) && 5530 !isOpenMPParallelDirective(CurrDir)) { 5531 DVar = DSAStack->getImplicitDSA(VD, true); 5532 if (DVar.CKind != OMPC_shared) { 5533 Diag(ELoc, diag::err_omp_required_access) 5534 << getOpenMPClauseName(OMPC_reduction) 5535 << getOpenMPClauseName(OMPC_shared); 5536 ReportOriginalDSA(*this, DSAStack, VD, DVar); 5537 continue; 5538 } 5539 } 5540 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 5541 auto *LHSVD = BuildVarDecl(*this, ELoc, Type, ".reduction.lhs"); 5542 auto *RHSVD = BuildVarDecl(*this, ELoc, Type, VD->getName()); 5543 // Add initializer for private variable. 5544 Expr *Init = nullptr; 5545 switch (BOK) { 5546 case BO_Add: 5547 case BO_Xor: 5548 case BO_Or: 5549 case BO_LOr: 5550 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 5551 if (Type->isScalarType() || Type->isAnyComplexType()) { 5552 Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 5553 } 5554 break; 5555 case BO_Mul: 5556 case BO_LAnd: 5557 if (Type->isScalarType() || Type->isAnyComplexType()) { 5558 // '*' and '&&' reduction ops - initializer is '1'. 5559 Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 5560 } 5561 break; 5562 case BO_And: { 5563 // '&' reduction op - initializer is '~0'. 5564 QualType OrigType = Type; 5565 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) { 5566 Type = ComplexTy->getElementType(); 5567 } 5568 if (Type->isRealFloatingType()) { 5569 llvm::APFloat InitValue = 5570 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 5571 /*isIEEE=*/true); 5572 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 5573 Type, ELoc); 5574 } else if (Type->isScalarType()) { 5575 auto Size = Context.getTypeSize(Type); 5576 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 5577 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 5578 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 5579 } 5580 if (Init && OrigType->isAnyComplexType()) { 5581 // Init = 0xFFFF + 0xFFFFi; 5582 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 5583 Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 5584 } 5585 Type = OrigType; 5586 break; 5587 } 5588 case BO_LT: 5589 case BO_GT: { 5590 // 'min' reduction op - initializer is 'Largest representable number in 5591 // the reduction list item type'. 5592 // 'max' reduction op - initializer is 'Least representable number in 5593 // the reduction list item type'. 5594 if (Type->isIntegerType() || Type->isPointerType()) { 5595 bool IsSigned = Type->hasSignedIntegerRepresentation(); 5596 auto Size = Context.getTypeSize(Type); 5597 QualType IntTy = 5598 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 5599 llvm::APInt InitValue = 5600 (BOK != BO_LT) 5601 ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 5602 : llvm::APInt::getMinValue(Size) 5603 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 5604 : llvm::APInt::getMaxValue(Size); 5605 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 5606 if (Type->isPointerType()) { 5607 // Cast to pointer type. 5608 auto CastExpr = BuildCStyleCastExpr( 5609 SourceLocation(), Context.getTrivialTypeSourceInfo(Type, ELoc), 5610 SourceLocation(), Init); 5611 if (CastExpr.isInvalid()) 5612 continue; 5613 Init = CastExpr.get(); 5614 } 5615 } else if (Type->isRealFloatingType()) { 5616 llvm::APFloat InitValue = llvm::APFloat::getLargest( 5617 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 5618 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 5619 Type, ELoc); 5620 } 5621 break; 5622 } 5623 case BO_PtrMemD: 5624 case BO_PtrMemI: 5625 case BO_MulAssign: 5626 case BO_Div: 5627 case BO_Rem: 5628 case BO_Sub: 5629 case BO_Shl: 5630 case BO_Shr: 5631 case BO_LE: 5632 case BO_GE: 5633 case BO_EQ: 5634 case BO_NE: 5635 case BO_AndAssign: 5636 case BO_XorAssign: 5637 case BO_OrAssign: 5638 case BO_Assign: 5639 case BO_AddAssign: 5640 case BO_SubAssign: 5641 case BO_DivAssign: 5642 case BO_RemAssign: 5643 case BO_ShlAssign: 5644 case BO_ShrAssign: 5645 case BO_Comma: 5646 llvm_unreachable("Unexpected reduction operation"); 5647 } 5648 if (Init) { 5649 AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false, 5650 /*TypeMayContainAuto=*/false); 5651 } else { 5652 ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false); 5653 } 5654 if (!RHSVD->hasInit()) { 5655 Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type 5656 << ReductionIdRange; 5657 bool IsDecl = 5658 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5659 Diag(VD->getLocation(), 5660 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5661 << VD; 5662 continue; 5663 } 5664 auto *LHSDRE = BuildDeclRefExpr(LHSVD, Type, VK_LValue, ELoc).get(); 5665 auto *RHSDRE = BuildDeclRefExpr(RHSVD, Type, VK_LValue, ELoc).get(); 5666 ExprResult ReductionOp = 5667 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), BOK, 5668 LHSDRE, RHSDRE); 5669 if (ReductionOp.isUsable()) { 5670 if (BOK != BO_LOr && BOK != BO_LAnd) { 5671 ReductionOp = 5672 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 5673 BO_Assign, LHSDRE, ReductionOp.get()); 5674 } else { 5675 auto *ConditionalOp = new (Context) ConditionalOperator( 5676 ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(), 5677 RHSDRE, Type, VK_LValue, OK_Ordinary); 5678 ReductionOp = 5679 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 5680 BO_Assign, LHSDRE, ConditionalOp); 5681 } 5682 if (ReductionOp.isUsable()) { 5683 ReductionOp = ActOnFinishFullExpr(ReductionOp.get()); 5684 } 5685 } 5686 if (ReductionOp.isInvalid()) 5687 continue; 5688 5689 DSAStack->addDSA(VD, DE, OMPC_reduction); 5690 Vars.push_back(DE); 5691 LHSs.push_back(LHSDRE); 5692 RHSs.push_back(RHSDRE); 5693 ReductionOps.push_back(ReductionOp.get()); 5694 } 5695 5696 if (Vars.empty()) 5697 return nullptr; 5698 5699 return OMPReductionClause::Create( 5700 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars, 5701 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, LHSs, 5702 RHSs, ReductionOps); 5703 } 5704 5705 OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, 5706 SourceLocation StartLoc, 5707 SourceLocation LParenLoc, 5708 SourceLocation ColonLoc, 5709 SourceLocation EndLoc) { 5710 SmallVector<Expr *, 8> Vars; 5711 SmallVector<Expr *, 8> Inits; 5712 for (auto &RefExpr : VarList) { 5713 assert(RefExpr && "NULL expr in OpenMP linear clause."); 5714 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 5715 // It will be analyzed later. 5716 Vars.push_back(RefExpr); 5717 Inits.push_back(nullptr); 5718 continue; 5719 } 5720 5721 // OpenMP [2.14.3.7, linear clause] 5722 // A list item that appears in a linear clause is subject to the private 5723 // clause semantics described in Section 2.14.3.3 on page 159 except as 5724 // noted. In addition, the value of the new list item on each iteration 5725 // of the associated loop(s) corresponds to the value of the original 5726 // list item before entering the construct plus the logical number of 5727 // the iteration times linear-step. 5728 5729 SourceLocation ELoc = RefExpr->getExprLoc(); 5730 // OpenMP [2.1, C/C++] 5731 // A list item is a variable name. 5732 // OpenMP [2.14.3.3, Restrictions, p.1] 5733 // A variable that is part of another variable (as an array or 5734 // structure element) cannot appear in a private clause. 5735 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 5736 if (!DE || !isa<VarDecl>(DE->getDecl())) { 5737 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 5738 continue; 5739 } 5740 5741 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 5742 5743 // OpenMP [2.14.3.7, linear clause] 5744 // A list-item cannot appear in more than one linear clause. 5745 // A list-item that appears in a linear clause cannot appear in any 5746 // other data-sharing attribute clause. 5747 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 5748 if (DVar.RefExpr) { 5749 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 5750 << getOpenMPClauseName(OMPC_linear); 5751 ReportOriginalDSA(*this, DSAStack, VD, DVar); 5752 continue; 5753 } 5754 5755 QualType QType = VD->getType(); 5756 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 5757 // It will be analyzed later. 5758 Vars.push_back(DE); 5759 Inits.push_back(nullptr); 5760 continue; 5761 } 5762 5763 // A variable must not have an incomplete type or a reference type. 5764 if (RequireCompleteType(ELoc, QType, 5765 diag::err_omp_linear_incomplete_type)) { 5766 continue; 5767 } 5768 if (QType->isReferenceType()) { 5769 Diag(ELoc, diag::err_omp_clause_ref_type_arg) 5770 << getOpenMPClauseName(OMPC_linear) << QType; 5771 bool IsDecl = 5772 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5773 Diag(VD->getLocation(), 5774 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5775 << VD; 5776 continue; 5777 } 5778 5779 // A list item must not be const-qualified. 5780 if (QType.isConstant(Context)) { 5781 Diag(ELoc, diag::err_omp_const_variable) 5782 << getOpenMPClauseName(OMPC_linear); 5783 bool IsDecl = 5784 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5785 Diag(VD->getLocation(), 5786 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5787 << VD; 5788 continue; 5789 } 5790 5791 // A list item must be of integral or pointer type. 5792 QType = QType.getUnqualifiedType().getCanonicalType(); 5793 const Type *Ty = QType.getTypePtrOrNull(); 5794 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 5795 !Ty->isPointerType())) { 5796 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << QType; 5797 bool IsDecl = 5798 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5799 Diag(VD->getLocation(), 5800 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5801 << VD; 5802 continue; 5803 } 5804 5805 // Build var to save initial value. 5806 VarDecl *Init = BuildVarDecl(*this, ELoc, DE->getType(), ".linear.start"); 5807 AddInitializerToDecl(Init, DefaultLvalueConversion(DE).get(), 5808 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 5809 CurContext->addDecl(Init); 5810 Init->setIsUsed(); 5811 auto InitRef = DeclRefExpr::Create( 5812 Context, /*QualifierLoc*/ NestedNameSpecifierLoc(), 5813 /*TemplateKWLoc*/ SourceLocation(), Init, 5814 /*isEnclosingLocal*/ false, DE->getLocStart(), DE->getType(), 5815 /*VK*/ VK_LValue); 5816 DSAStack->addDSA(VD, DE, OMPC_linear); 5817 Vars.push_back(DE); 5818 Inits.push_back(InitRef); 5819 } 5820 5821 if (Vars.empty()) 5822 return nullptr; 5823 5824 Expr *StepExpr = Step; 5825 Expr *CalcStepExpr = nullptr; 5826 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 5827 !Step->isInstantiationDependent() && 5828 !Step->containsUnexpandedParameterPack()) { 5829 SourceLocation StepLoc = Step->getLocStart(); 5830 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 5831 if (Val.isInvalid()) 5832 return nullptr; 5833 StepExpr = Val.get(); 5834 5835 // Build var to save the step value. 5836 VarDecl *SaveVar = 5837 BuildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 5838 CurContext->addDecl(SaveVar); 5839 SaveVar->setIsUsed(); 5840 ExprResult SaveRef = 5841 BuildDeclRefExpr(SaveVar, StepExpr->getType(), VK_LValue, StepLoc); 5842 ExprResult CalcStep = 5843 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 5844 5845 // Warn about zero linear step (it would be probably better specified as 5846 // making corresponding variables 'const'). 5847 llvm::APSInt Result; 5848 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 5849 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 5850 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 5851 << (Vars.size() > 1); 5852 if (!IsConstant && CalcStep.isUsable()) { 5853 // Calculate the step beforehand instead of doing this on each iteration. 5854 // (This is not used if the number of iterations may be kfold-ed). 5855 CalcStepExpr = CalcStep.get(); 5856 } 5857 } 5858 5859 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, ColonLoc, EndLoc, 5860 Vars, Inits, StepExpr, CalcStepExpr); 5861 } 5862 5863 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 5864 Expr *NumIterations, Sema &SemaRef, 5865 Scope *S) { 5866 // Walk the vars and build update/final expressions for the CodeGen. 5867 SmallVector<Expr *, 8> Updates; 5868 SmallVector<Expr *, 8> Finals; 5869 Expr *Step = Clause.getStep(); 5870 Expr *CalcStep = Clause.getCalcStep(); 5871 // OpenMP [2.14.3.7, linear clause] 5872 // If linear-step is not specified it is assumed to be 1. 5873 if (Step == nullptr) 5874 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 5875 else if (CalcStep) 5876 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 5877 bool HasErrors = false; 5878 auto CurInit = Clause.inits().begin(); 5879 for (auto &RefExpr : Clause.varlists()) { 5880 Expr *InitExpr = *CurInit; 5881 5882 // Build privatized reference to the current linear var. 5883 auto DE = cast<DeclRefExpr>(RefExpr); 5884 auto PrivateRef = DeclRefExpr::Create( 5885 SemaRef.Context, /*QualifierLoc*/ DE->getQualifierLoc(), 5886 /*TemplateKWLoc*/ SourceLocation(), DE->getDecl(), 5887 /* RefersToEnclosingVariableOrCapture */ true, DE->getLocStart(), 5888 DE->getType(), /*VK*/ VK_LValue); 5889 5890 // Build update: Var = InitExpr + IV * Step 5891 ExprResult Update = 5892 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), PrivateRef, 5893 InitExpr, IV, Step, /* Subtract */ false); 5894 Update = SemaRef.ActOnFinishFullExpr(Update.get()); 5895 5896 // Build final: Var = InitExpr + NumIterations * Step 5897 ExprResult Final = 5898 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), RefExpr, InitExpr, 5899 NumIterations, Step, /* Subtract */ false); 5900 Final = SemaRef.ActOnFinishFullExpr(Final.get()); 5901 if (!Update.isUsable() || !Final.isUsable()) { 5902 Updates.push_back(nullptr); 5903 Finals.push_back(nullptr); 5904 HasErrors = true; 5905 } else { 5906 Updates.push_back(Update.get()); 5907 Finals.push_back(Final.get()); 5908 } 5909 ++CurInit; 5910 } 5911 Clause.setUpdates(Updates); 5912 Clause.setFinals(Finals); 5913 return HasErrors; 5914 } 5915 5916 OMPClause *Sema::ActOnOpenMPAlignedClause( 5917 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 5918 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 5919 5920 SmallVector<Expr *, 8> Vars; 5921 for (auto &RefExpr : VarList) { 5922 assert(RefExpr && "NULL expr in OpenMP aligned clause."); 5923 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 5924 // It will be analyzed later. 5925 Vars.push_back(RefExpr); 5926 continue; 5927 } 5928 5929 SourceLocation ELoc = RefExpr->getExprLoc(); 5930 // OpenMP [2.1, C/C++] 5931 // A list item is a variable name. 5932 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 5933 if (!DE || !isa<VarDecl>(DE->getDecl())) { 5934 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 5935 continue; 5936 } 5937 5938 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 5939 5940 // OpenMP [2.8.1, simd construct, Restrictions] 5941 // The type of list items appearing in the aligned clause must be 5942 // array, pointer, reference to array, or reference to pointer. 5943 QualType QType = DE->getType() 5944 .getNonReferenceType() 5945 .getUnqualifiedType() 5946 .getCanonicalType(); 5947 const Type *Ty = QType.getTypePtrOrNull(); 5948 if (!Ty || (!Ty->isDependentType() && !Ty->isArrayType() && 5949 !Ty->isPointerType())) { 5950 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 5951 << QType << getLangOpts().CPlusPlus << RefExpr->getSourceRange(); 5952 bool IsDecl = 5953 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5954 Diag(VD->getLocation(), 5955 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5956 << VD; 5957 continue; 5958 } 5959 5960 // OpenMP [2.8.1, simd construct, Restrictions] 5961 // A list-item cannot appear in more than one aligned clause. 5962 if (DeclRefExpr *PrevRef = DSAStack->addUniqueAligned(VD, DE)) { 5963 Diag(ELoc, diag::err_omp_aligned_twice) << RefExpr->getSourceRange(); 5964 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 5965 << getOpenMPClauseName(OMPC_aligned); 5966 continue; 5967 } 5968 5969 Vars.push_back(DE); 5970 } 5971 5972 // OpenMP [2.8.1, simd construct, Description] 5973 // The parameter of the aligned clause, alignment, must be a constant 5974 // positive integer expression. 5975 // If no optional parameter is specified, implementation-defined default 5976 // alignments for SIMD instructions on the target platforms are assumed. 5977 if (Alignment != nullptr) { 5978 ExprResult AlignResult = 5979 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 5980 if (AlignResult.isInvalid()) 5981 return nullptr; 5982 Alignment = AlignResult.get(); 5983 } 5984 if (Vars.empty()) 5985 return nullptr; 5986 5987 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 5988 EndLoc, Vars, Alignment); 5989 } 5990 5991 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 5992 SourceLocation StartLoc, 5993 SourceLocation LParenLoc, 5994 SourceLocation EndLoc) { 5995 SmallVector<Expr *, 8> Vars; 5996 SmallVector<Expr *, 8> SrcExprs; 5997 SmallVector<Expr *, 8> DstExprs; 5998 SmallVector<Expr *, 8> AssignmentOps; 5999 for (auto &RefExpr : VarList) { 6000 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 6001 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 6002 // It will be analyzed later. 6003 Vars.push_back(RefExpr); 6004 SrcExprs.push_back(nullptr); 6005 DstExprs.push_back(nullptr); 6006 AssignmentOps.push_back(nullptr); 6007 continue; 6008 } 6009 6010 SourceLocation ELoc = RefExpr->getExprLoc(); 6011 // OpenMP [2.1, C/C++] 6012 // A list item is a variable name. 6013 // OpenMP [2.14.4.1, Restrictions, p.1] 6014 // A list item that appears in a copyin clause must be threadprivate. 6015 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 6016 if (!DE || !isa<VarDecl>(DE->getDecl())) { 6017 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 6018 continue; 6019 } 6020 6021 Decl *D = DE->getDecl(); 6022 VarDecl *VD = cast<VarDecl>(D); 6023 6024 QualType Type = VD->getType(); 6025 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 6026 // It will be analyzed later. 6027 Vars.push_back(DE); 6028 SrcExprs.push_back(nullptr); 6029 DstExprs.push_back(nullptr); 6030 AssignmentOps.push_back(nullptr); 6031 continue; 6032 } 6033 6034 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 6035 // A list item that appears in a copyin clause must be threadprivate. 6036 if (!DSAStack->isThreadPrivate(VD)) { 6037 Diag(ELoc, diag::err_omp_required_access) 6038 << getOpenMPClauseName(OMPC_copyin) 6039 << getOpenMPDirectiveName(OMPD_threadprivate); 6040 continue; 6041 } 6042 6043 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 6044 // A variable of class type (or array thereof) that appears in a 6045 // copyin clause requires an accessible, unambiguous copy assignment 6046 // operator for the class type. 6047 Type = Context.getBaseElementType(Type).getNonReferenceType(); 6048 auto *SrcVD = BuildVarDecl(*this, DE->getLocStart(), 6049 Type.getUnqualifiedType(), ".copyin.src"); 6050 auto *PseudoSrcExpr = BuildDeclRefExpr(SrcVD, Type.getUnqualifiedType(), 6051 VK_LValue, DE->getExprLoc()) 6052 .get(); 6053 auto *DstVD = BuildVarDecl(*this, DE->getLocStart(), Type, ".copyin.dst"); 6054 auto *PseudoDstExpr = 6055 BuildDeclRefExpr(DstVD, Type, VK_LValue, DE->getExprLoc()).get(); 6056 // For arrays generate assignment operation for single element and replace 6057 // it by the original array element in CodeGen. 6058 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 6059 PseudoDstExpr, PseudoSrcExpr); 6060 if (AssignmentOp.isInvalid()) 6061 continue; 6062 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 6063 /*DiscardedValue=*/true); 6064 if (AssignmentOp.isInvalid()) 6065 continue; 6066 6067 DSAStack->addDSA(VD, DE, OMPC_copyin); 6068 Vars.push_back(DE); 6069 SrcExprs.push_back(PseudoSrcExpr); 6070 DstExprs.push_back(PseudoDstExpr); 6071 AssignmentOps.push_back(AssignmentOp.get()); 6072 } 6073 6074 if (Vars.empty()) 6075 return nullptr; 6076 6077 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 6078 SrcExprs, DstExprs, AssignmentOps); 6079 } 6080 6081 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 6082 SourceLocation StartLoc, 6083 SourceLocation LParenLoc, 6084 SourceLocation EndLoc) { 6085 SmallVector<Expr *, 8> Vars; 6086 SmallVector<Expr *, 8> SrcExprs; 6087 SmallVector<Expr *, 8> DstExprs; 6088 SmallVector<Expr *, 8> AssignmentOps; 6089 for (auto &RefExpr : VarList) { 6090 assert(RefExpr && "NULL expr in OpenMP copyprivate clause."); 6091 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 6092 // It will be analyzed later. 6093 Vars.push_back(RefExpr); 6094 SrcExprs.push_back(nullptr); 6095 DstExprs.push_back(nullptr); 6096 AssignmentOps.push_back(nullptr); 6097 continue; 6098 } 6099 6100 SourceLocation ELoc = RefExpr->getExprLoc(); 6101 // OpenMP [2.1, C/C++] 6102 // A list item is a variable name. 6103 // OpenMP [2.14.4.1, Restrictions, p.1] 6104 // A list item that appears in a copyin clause must be threadprivate. 6105 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 6106 if (!DE || !isa<VarDecl>(DE->getDecl())) { 6107 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 6108 continue; 6109 } 6110 6111 Decl *D = DE->getDecl(); 6112 VarDecl *VD = cast<VarDecl>(D); 6113 6114 QualType Type = VD->getType(); 6115 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 6116 // It will be analyzed later. 6117 Vars.push_back(DE); 6118 SrcExprs.push_back(nullptr); 6119 DstExprs.push_back(nullptr); 6120 AssignmentOps.push_back(nullptr); 6121 continue; 6122 } 6123 6124 // OpenMP [2.14.4.2, Restrictions, p.2] 6125 // A list item that appears in a copyprivate clause may not appear in a 6126 // private or firstprivate clause on the single construct. 6127 if (!DSAStack->isThreadPrivate(VD)) { 6128 auto DVar = DSAStack->getTopDSA(VD, false); 6129 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 6130 DVar.RefExpr) { 6131 Diag(ELoc, diag::err_omp_wrong_dsa) 6132 << getOpenMPClauseName(DVar.CKind) 6133 << getOpenMPClauseName(OMPC_copyprivate); 6134 ReportOriginalDSA(*this, DSAStack, VD, DVar); 6135 continue; 6136 } 6137 6138 // OpenMP [2.11.4.2, Restrictions, p.1] 6139 // All list items that appear in a copyprivate clause must be either 6140 // threadprivate or private in the enclosing context. 6141 if (DVar.CKind == OMPC_unknown) { 6142 DVar = DSAStack->getImplicitDSA(VD, false); 6143 if (DVar.CKind == OMPC_shared) { 6144 Diag(ELoc, diag::err_omp_required_access) 6145 << getOpenMPClauseName(OMPC_copyprivate) 6146 << "threadprivate or private in the enclosing context"; 6147 ReportOriginalDSA(*this, DSAStack, VD, DVar); 6148 continue; 6149 } 6150 } 6151 } 6152 6153 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 6154 // A variable of class type (or array thereof) that appears in a 6155 // copyin clause requires an accessible, unambiguous copy assignment 6156 // operator for the class type. 6157 Type = Context.getBaseElementType(Type).getUnqualifiedType(); 6158 auto *SrcVD = 6159 BuildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.src"); 6160 auto *PseudoSrcExpr = 6161 BuildDeclRefExpr(SrcVD, Type, VK_LValue, DE->getExprLoc()).get(); 6162 auto *DstVD = 6163 BuildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.dst"); 6164 auto *PseudoDstExpr = 6165 BuildDeclRefExpr(DstVD, Type, VK_LValue, DE->getExprLoc()).get(); 6166 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 6167 PseudoDstExpr, PseudoSrcExpr); 6168 if (AssignmentOp.isInvalid()) 6169 continue; 6170 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 6171 /*DiscardedValue=*/true); 6172 if (AssignmentOp.isInvalid()) 6173 continue; 6174 6175 // No need to mark vars as copyprivate, they are already threadprivate or 6176 // implicitly private. 6177 Vars.push_back(DE); 6178 SrcExprs.push_back(PseudoSrcExpr); 6179 DstExprs.push_back(PseudoDstExpr); 6180 AssignmentOps.push_back(AssignmentOp.get()); 6181 } 6182 6183 if (Vars.empty()) 6184 return nullptr; 6185 6186 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 6187 Vars, SrcExprs, DstExprs, AssignmentOps); 6188 } 6189 6190 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 6191 SourceLocation StartLoc, 6192 SourceLocation LParenLoc, 6193 SourceLocation EndLoc) { 6194 if (VarList.empty()) 6195 return nullptr; 6196 6197 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 6198 } 6199 6200