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