1 //===--- SemaOpenMP.cpp - Semantic Analysis for OpenMP constructs ---------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// \file 10 /// \brief This file implements semantic analysis for OpenMP directives and 11 /// clauses. 12 /// 13 //===----------------------------------------------------------------------===// 14 15 #include "TreeTransform.h" 16 #include "clang/AST/ASTContext.h" 17 #include "clang/AST/ASTMutationListener.h" 18 #include "clang/AST/CXXInheritance.h" 19 #include "clang/AST/Decl.h" 20 #include "clang/AST/DeclCXX.h" 21 #include "clang/AST/DeclOpenMP.h" 22 #include "clang/AST/StmtCXX.h" 23 #include "clang/AST/StmtOpenMP.h" 24 #include "clang/AST/StmtVisitor.h" 25 #include "clang/AST/TypeOrdering.h" 26 #include "clang/Basic/OpenMPKinds.h" 27 #include "clang/Basic/TargetInfo.h" 28 #include "clang/Lex/Preprocessor.h" 29 #include "clang/Sema/Initialization.h" 30 #include "clang/Sema/Lookup.h" 31 #include "clang/Sema/Scope.h" 32 #include "clang/Sema/ScopeInfo.h" 33 #include "clang/Sema/SemaInternal.h" 34 using namespace clang; 35 36 //===----------------------------------------------------------------------===// 37 // Stack of data-sharing attributes for variables 38 //===----------------------------------------------------------------------===// 39 40 namespace { 41 /// \brief Default data sharing attributes, which can be applied to directive. 42 enum DefaultDataSharingAttributes { 43 DSA_unspecified = 0, /// \brief Data sharing attribute not specified. 44 DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'. 45 DSA_shared = 1 << 1 /// \brief Default data sharing attribute 'shared'. 46 }; 47 48 template <class T> struct MatchesAny { 49 explicit MatchesAny(ArrayRef<T> Arr) : Arr(std::move(Arr)) {} 50 bool operator()(T Kind) { 51 for (auto KindEl : Arr) 52 if (KindEl == Kind) 53 return true; 54 return false; 55 } 56 57 private: 58 ArrayRef<T> Arr; 59 }; 60 struct MatchesAlways { 61 MatchesAlways() {} 62 template <class T> bool operator()(T) { return true; } 63 }; 64 65 typedef MatchesAny<OpenMPClauseKind> MatchesAnyClause; 66 typedef MatchesAny<OpenMPDirectiveKind> MatchesAnyDirective; 67 68 /// \brief Stack for tracking declarations used in OpenMP directives and 69 /// clauses and their data-sharing attributes. 70 class DSAStackTy { 71 public: 72 struct DSAVarData { 73 OpenMPDirectiveKind DKind; 74 OpenMPClauseKind CKind; 75 Expr *RefExpr; 76 DeclRefExpr *PrivateCopy; 77 SourceLocation ImplicitDSALoc; 78 DSAVarData() 79 : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr), 80 PrivateCopy(nullptr), ImplicitDSALoc() {} 81 }; 82 83 private: 84 typedef SmallVector<Expr *, 4> MapInfo; 85 86 struct DSAInfo { 87 OpenMPClauseKind Attributes; 88 Expr *RefExpr; 89 DeclRefExpr *PrivateCopy; 90 }; 91 typedef llvm::DenseMap<ValueDecl *, DSAInfo> DeclSAMapTy; 92 typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy; 93 typedef std::pair<unsigned, VarDecl *> LCDeclInfo; 94 typedef llvm::DenseMap<ValueDecl *, LCDeclInfo> LoopControlVariablesMapTy; 95 typedef llvm::DenseMap<ValueDecl *, MapInfo> MappedDeclsTy; 96 typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>> 97 CriticalsWithHintsTy; 98 99 struct SharingMapTy { 100 DeclSAMapTy SharingMap; 101 AlignedMapTy AlignedMap; 102 MappedDeclsTy MappedDecls; 103 LoopControlVariablesMapTy LCVMap; 104 DefaultDataSharingAttributes DefaultAttr; 105 SourceLocation DefaultAttrLoc; 106 OpenMPDirectiveKind Directive; 107 DeclarationNameInfo DirectiveName; 108 Scope *CurScope; 109 SourceLocation ConstructLoc; 110 /// \brief first argument (Expr *) contains optional argument of the 111 /// 'ordered' clause, the second one is true if the regions has 'ordered' 112 /// clause, false otherwise. 113 llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion; 114 bool NowaitRegion; 115 bool CancelRegion; 116 unsigned AssociatedLoops; 117 SourceLocation InnerTeamsRegionLoc; 118 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 119 Scope *CurScope, SourceLocation Loc) 120 : SharingMap(), AlignedMap(), LCVMap(), DefaultAttr(DSA_unspecified), 121 Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope), 122 ConstructLoc(Loc), OrderedRegion(), NowaitRegion(false), 123 CancelRegion(false), AssociatedLoops(1), InnerTeamsRegionLoc() {} 124 SharingMapTy() 125 : SharingMap(), AlignedMap(), LCVMap(), DefaultAttr(DSA_unspecified), 126 Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr), 127 ConstructLoc(), OrderedRegion(), NowaitRegion(false), 128 CancelRegion(false), AssociatedLoops(1), InnerTeamsRegionLoc() {} 129 }; 130 131 typedef SmallVector<SharingMapTy, 4> StackTy; 132 133 /// \brief Stack of used declaration and their data-sharing attributes. 134 StackTy Stack; 135 /// \brief true, if check for DSA must be from parent directive, false, if 136 /// from current directive. 137 OpenMPClauseKind ClauseKindMode; 138 Sema &SemaRef; 139 bool ForceCapturing; 140 CriticalsWithHintsTy Criticals; 141 142 typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; 143 144 DSAVarData getDSA(StackTy::reverse_iterator& Iter, ValueDecl *D); 145 146 /// \brief Checks if the variable is a local for OpenMP region. 147 bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter); 148 149 public: 150 explicit DSAStackTy(Sema &S) 151 : Stack(1), ClauseKindMode(OMPC_unknown), SemaRef(S), 152 ForceCapturing(false) {} 153 154 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 155 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 156 157 bool isForceVarCapturing() const { return ForceCapturing; } 158 void setForceVarCapturing(bool V) { ForceCapturing = V; } 159 160 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 161 Scope *CurScope, SourceLocation Loc) { 162 Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc)); 163 Stack.back().DefaultAttrLoc = Loc; 164 } 165 166 void pop() { 167 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!"); 168 Stack.pop_back(); 169 } 170 171 void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) { 172 Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint); 173 } 174 const std::pair<OMPCriticalDirective *, llvm::APSInt> 175 getCriticalWithHint(const DeclarationNameInfo &Name) const { 176 auto I = Criticals.find(Name.getAsString()); 177 if (I != Criticals.end()) 178 return I->second; 179 return std::make_pair(nullptr, llvm::APSInt()); 180 } 181 /// \brief If 'aligned' declaration for given variable \a D was not seen yet, 182 /// add it and return NULL; otherwise return previous occurrence's expression 183 /// for diagnostics. 184 Expr *addUniqueAligned(ValueDecl *D, Expr *NewDE); 185 186 /// \brief Register specified variable as loop control variable. 187 void addLoopControlVariable(ValueDecl *D, VarDecl *Capture); 188 /// \brief Check if the specified variable is a loop control variable for 189 /// current region. 190 /// \return The index of the loop control variable in the list of associated 191 /// for-loops (from outer to inner). 192 LCDeclInfo isLoopControlVariable(ValueDecl *D); 193 /// \brief Check if the specified variable is a loop control variable for 194 /// parent region. 195 /// \return The index of the loop control variable in the list of associated 196 /// for-loops (from outer to inner). 197 LCDeclInfo isParentLoopControlVariable(ValueDecl *D); 198 /// \brief Get the loop control variable for the I-th loop (or nullptr) in 199 /// parent directive. 200 ValueDecl *getParentLoopControlVariable(unsigned I); 201 202 /// \brief Adds explicit data sharing attribute to the specified declaration. 203 void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 204 DeclRefExpr *PrivateCopy = nullptr); 205 206 /// \brief Returns data sharing attributes from top of the stack for the 207 /// specified declaration. 208 DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 209 /// \brief Returns data-sharing attributes for the specified declaration. 210 DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent); 211 /// \brief Checks if the specified variables has data-sharing attributes which 212 /// match specified \a CPred predicate in any directive which matches \a DPred 213 /// predicate. 214 template <class ClausesPredicate, class DirectivesPredicate> 215 DSAVarData hasDSA(ValueDecl *D, ClausesPredicate CPred, 216 DirectivesPredicate DPred, bool FromParent); 217 /// \brief Checks if the specified variables has data-sharing attributes which 218 /// match specified \a CPred predicate in any innermost directive which 219 /// matches \a DPred predicate. 220 template <class ClausesPredicate, class DirectivesPredicate> 221 DSAVarData hasInnermostDSA(ValueDecl *D, ClausesPredicate CPred, 222 DirectivesPredicate DPred, bool FromParent); 223 /// \brief Checks if the specified variables has explicit data-sharing 224 /// attributes which match specified \a CPred predicate at the specified 225 /// OpenMP region. 226 bool hasExplicitDSA(ValueDecl *D, 227 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 228 unsigned Level); 229 230 /// \brief Returns true if the directive at level \Level matches in the 231 /// specified \a DPred predicate. 232 bool hasExplicitDirective( 233 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 234 unsigned Level); 235 236 /// \brief Finds a directive which matches specified \a DPred predicate. 237 template <class NamedDirectivesPredicate> 238 bool hasDirective(NamedDirectivesPredicate DPred, bool FromParent); 239 240 /// \brief Returns currently analyzed directive. 241 OpenMPDirectiveKind getCurrentDirective() const { 242 return Stack.back().Directive; 243 } 244 /// \brief Returns parent directive. 245 OpenMPDirectiveKind getParentDirective() const { 246 if (Stack.size() > 2) 247 return Stack[Stack.size() - 2].Directive; 248 return OMPD_unknown; 249 } 250 /// \brief Return the directive associated with the provided scope. 251 OpenMPDirectiveKind getDirectiveForScope(const Scope *S) const; 252 253 /// \brief Set default data sharing attribute to none. 254 void setDefaultDSANone(SourceLocation Loc) { 255 Stack.back().DefaultAttr = DSA_none; 256 Stack.back().DefaultAttrLoc = Loc; 257 } 258 /// \brief Set default data sharing attribute to shared. 259 void setDefaultDSAShared(SourceLocation Loc) { 260 Stack.back().DefaultAttr = DSA_shared; 261 Stack.back().DefaultAttrLoc = Loc; 262 } 263 264 DefaultDataSharingAttributes getDefaultDSA() const { 265 return Stack.back().DefaultAttr; 266 } 267 SourceLocation getDefaultDSALocation() const { 268 return Stack.back().DefaultAttrLoc; 269 } 270 271 /// \brief Checks if the specified variable is a threadprivate. 272 bool isThreadPrivate(VarDecl *D) { 273 DSAVarData DVar = getTopDSA(D, false); 274 return isOpenMPThreadPrivate(DVar.CKind); 275 } 276 277 /// \brief Marks current region as ordered (it has an 'ordered' clause). 278 void setOrderedRegion(bool IsOrdered, Expr *Param) { 279 Stack.back().OrderedRegion.setInt(IsOrdered); 280 Stack.back().OrderedRegion.setPointer(Param); 281 } 282 /// \brief Returns true, if parent region is ordered (has associated 283 /// 'ordered' clause), false - otherwise. 284 bool isParentOrderedRegion() const { 285 if (Stack.size() > 2) 286 return Stack[Stack.size() - 2].OrderedRegion.getInt(); 287 return false; 288 } 289 /// \brief Returns optional parameter for the ordered region. 290 Expr *getParentOrderedRegionParam() const { 291 if (Stack.size() > 2) 292 return Stack[Stack.size() - 2].OrderedRegion.getPointer(); 293 return nullptr; 294 } 295 /// \brief Marks current region as nowait (it has a 'nowait' clause). 296 void setNowaitRegion(bool IsNowait = true) { 297 Stack.back().NowaitRegion = IsNowait; 298 } 299 /// \brief Returns true, if parent region is nowait (has associated 300 /// 'nowait' clause), false - otherwise. 301 bool isParentNowaitRegion() const { 302 if (Stack.size() > 2) 303 return Stack[Stack.size() - 2].NowaitRegion; 304 return false; 305 } 306 /// \brief Marks parent region as cancel region. 307 void setParentCancelRegion(bool Cancel = true) { 308 if (Stack.size() > 2) 309 Stack[Stack.size() - 2].CancelRegion = 310 Stack[Stack.size() - 2].CancelRegion || Cancel; 311 } 312 /// \brief Return true if current region has inner cancel construct. 313 bool isCancelRegion() const { 314 return Stack.back().CancelRegion; 315 } 316 317 /// \brief Set collapse value for the region. 318 void setAssociatedLoops(unsigned Val) { Stack.back().AssociatedLoops = Val; } 319 /// \brief Return collapse value for region. 320 unsigned getAssociatedLoops() const { return Stack.back().AssociatedLoops; } 321 322 /// \brief Marks current target region as one with closely nested teams 323 /// region. 324 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 325 if (Stack.size() > 2) 326 Stack[Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc; 327 } 328 /// \brief Returns true, if current region has closely nested teams region. 329 bool hasInnerTeamsRegion() const { 330 return getInnerTeamsRegionLoc().isValid(); 331 } 332 /// \brief Returns location of the nested teams region (if any). 333 SourceLocation getInnerTeamsRegionLoc() const { 334 if (Stack.size() > 1) 335 return Stack.back().InnerTeamsRegionLoc; 336 return SourceLocation(); 337 } 338 339 Scope *getCurScope() const { return Stack.back().CurScope; } 340 Scope *getCurScope() { return Stack.back().CurScope; } 341 SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; } 342 343 // Do the check specified in MapInfoCheck and return true if any issue is 344 // found. 345 template <class MapInfoCheck> 346 bool checkMapInfoForVar(ValueDecl *VD, bool CurrentRegionOnly, 347 MapInfoCheck Check) { 348 auto SI = Stack.rbegin(); 349 auto SE = Stack.rend(); 350 351 if (SI == SE) 352 return false; 353 354 if (CurrentRegionOnly) { 355 SE = std::next(SI); 356 } else { 357 ++SI; 358 } 359 360 for (; SI != SE; ++SI) { 361 auto MI = SI->MappedDecls.find(VD); 362 if (MI != SI->MappedDecls.end()) { 363 for (Expr *E : MI->second) { 364 if (Check(E)) 365 return true; 366 } 367 } 368 } 369 return false; 370 } 371 372 void addExprToVarMapInfo(ValueDecl *VD, Expr *E) { 373 if (Stack.size() > 1) { 374 Stack.back().MappedDecls[VD].push_back(E); 375 } 376 } 377 }; 378 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { 379 return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) || 380 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; 381 } 382 } // namespace 383 384 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 385 auto *VD = dyn_cast<VarDecl>(D); 386 auto *FD = dyn_cast<FieldDecl>(D); 387 if (VD != nullptr) { 388 VD = VD->getCanonicalDecl(); 389 D = VD; 390 } else { 391 assert(FD); 392 FD = FD->getCanonicalDecl(); 393 D = FD; 394 } 395 return D; 396 } 397 398 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator& Iter, 399 ValueDecl *D) { 400 D = getCanonicalDecl(D); 401 auto *VD = dyn_cast<VarDecl>(D); 402 auto *FD = dyn_cast<FieldDecl>(D); 403 DSAVarData DVar; 404 if (Iter == std::prev(Stack.rend())) { 405 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 406 // in a region but not in construct] 407 // File-scope or namespace-scope variables referenced in called routines 408 // in the region are shared unless they appear in a threadprivate 409 // directive. 410 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D)) 411 DVar.CKind = OMPC_shared; 412 413 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 414 // in a region but not in construct] 415 // Variables with static storage duration that are declared in called 416 // routines in the region are shared. 417 if (VD && VD->hasGlobalStorage()) 418 DVar.CKind = OMPC_shared; 419 420 // Non-static data members are shared by default. 421 if (FD) 422 DVar.CKind = OMPC_shared; 423 424 return DVar; 425 } 426 427 DVar.DKind = Iter->Directive; 428 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 429 // in a Construct, C/C++, predetermined, p.1] 430 // Variables with automatic storage duration that are declared in a scope 431 // inside the construct are private. 432 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 433 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 434 DVar.CKind = OMPC_private; 435 return DVar; 436 } 437 438 // Explicitly specified attributes and local variables with predetermined 439 // attributes. 440 if (Iter->SharingMap.count(D)) { 441 DVar.RefExpr = Iter->SharingMap[D].RefExpr; 442 DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy; 443 DVar.CKind = Iter->SharingMap[D].Attributes; 444 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 445 return DVar; 446 } 447 448 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 449 // in a Construct, C/C++, implicitly determined, p.1] 450 // In a parallel or task construct, the data-sharing attributes of these 451 // variables are determined by the default clause, if present. 452 switch (Iter->DefaultAttr) { 453 case DSA_shared: 454 DVar.CKind = OMPC_shared; 455 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 456 return DVar; 457 case DSA_none: 458 return DVar; 459 case DSA_unspecified: 460 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 461 // in a Construct, implicitly determined, p.2] 462 // In a parallel construct, if no default clause is present, these 463 // variables are shared. 464 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 465 if (isOpenMPParallelDirective(DVar.DKind) || 466 isOpenMPTeamsDirective(DVar.DKind)) { 467 DVar.CKind = OMPC_shared; 468 return DVar; 469 } 470 471 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 472 // in a Construct, implicitly determined, p.4] 473 // In a task construct, if no default clause is present, a variable that in 474 // the enclosing context is determined to be shared by all implicit tasks 475 // bound to the current team is shared. 476 if (isOpenMPTaskingDirective(DVar.DKind)) { 477 DSAVarData DVarTemp; 478 for (StackTy::reverse_iterator I = std::next(Iter), EE = Stack.rend(); 479 I != EE; ++I) { 480 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 481 // Referenced in a Construct, implicitly determined, p.6] 482 // In a task construct, if no default clause is present, a variable 483 // whose data-sharing attribute is not determined by the rules above is 484 // firstprivate. 485 DVarTemp = getDSA(I, D); 486 if (DVarTemp.CKind != OMPC_shared) { 487 DVar.RefExpr = nullptr; 488 DVar.CKind = OMPC_firstprivate; 489 return DVar; 490 } 491 if (isParallelOrTaskRegion(I->Directive)) 492 break; 493 } 494 DVar.CKind = 495 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 496 return DVar; 497 } 498 } 499 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 500 // in a Construct, implicitly determined, p.3] 501 // For constructs other than task, if no default clause is present, these 502 // variables inherit their data-sharing attributes from the enclosing 503 // context. 504 return getDSA(++Iter, D); 505 } 506 507 Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) { 508 assert(Stack.size() > 1 && "Data sharing attributes stack is empty"); 509 D = getCanonicalDecl(D); 510 auto It = Stack.back().AlignedMap.find(D); 511 if (It == Stack.back().AlignedMap.end()) { 512 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 513 Stack.back().AlignedMap[D] = NewDE; 514 return nullptr; 515 } else { 516 assert(It->second && "Unexpected nullptr expr in the aligned map"); 517 return It->second; 518 } 519 return nullptr; 520 } 521 522 void DSAStackTy::addLoopControlVariable(ValueDecl *D, VarDecl *Capture) { 523 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 524 D = getCanonicalDecl(D); 525 Stack.back().LCVMap.insert( 526 std::make_pair(D, LCDeclInfo(Stack.back().LCVMap.size() + 1, Capture))); 527 } 528 529 DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(ValueDecl *D) { 530 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 531 D = getCanonicalDecl(D); 532 return Stack.back().LCVMap.count(D) > 0 ? Stack.back().LCVMap[D] 533 : LCDeclInfo(0, nullptr); 534 } 535 536 DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(ValueDecl *D) { 537 assert(Stack.size() > 2 && "Data-sharing attributes stack is empty"); 538 D = getCanonicalDecl(D); 539 return Stack[Stack.size() - 2].LCVMap.count(D) > 0 540 ? Stack[Stack.size() - 2].LCVMap[D] 541 : LCDeclInfo(0, nullptr); 542 } 543 544 ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) { 545 assert(Stack.size() > 2 && "Data-sharing attributes stack is empty"); 546 if (Stack[Stack.size() - 2].LCVMap.size() < I) 547 return nullptr; 548 for (auto &Pair : Stack[Stack.size() - 2].LCVMap) { 549 if (Pair.second.first == I) 550 return Pair.first; 551 } 552 return nullptr; 553 } 554 555 void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 556 DeclRefExpr *PrivateCopy) { 557 D = getCanonicalDecl(D); 558 if (A == OMPC_threadprivate) { 559 Stack[0].SharingMap[D].Attributes = A; 560 Stack[0].SharingMap[D].RefExpr = E; 561 Stack[0].SharingMap[D].PrivateCopy = nullptr; 562 } else { 563 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 564 Stack.back().SharingMap[D].Attributes = A; 565 Stack.back().SharingMap[D].RefExpr = E; 566 Stack.back().SharingMap[D].PrivateCopy = PrivateCopy; 567 if (PrivateCopy) 568 addDSA(PrivateCopy->getDecl(), PrivateCopy, A); 569 } 570 } 571 572 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) { 573 D = D->getCanonicalDecl(); 574 if (Stack.size() > 2) { 575 reverse_iterator I = Iter, E = std::prev(Stack.rend()); 576 Scope *TopScope = nullptr; 577 while (I != E && !isParallelOrTaskRegion(I->Directive)) { 578 ++I; 579 } 580 if (I == E) 581 return false; 582 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 583 Scope *CurScope = getCurScope(); 584 while (CurScope != TopScope && !CurScope->isDeclScope(D)) { 585 CurScope = CurScope->getParent(); 586 } 587 return CurScope != TopScope; 588 } 589 return false; 590 } 591 592 /// \brief Build a variable declaration for OpenMP loop iteration variable. 593 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 594 StringRef Name, const AttrVec *Attrs = nullptr) { 595 DeclContext *DC = SemaRef.CurContext; 596 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 597 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 598 VarDecl *Decl = 599 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 600 if (Attrs) { 601 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 602 I != E; ++I) 603 Decl->addAttr(*I); 604 } 605 Decl->setImplicit(); 606 return Decl; 607 } 608 609 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 610 SourceLocation Loc, 611 bool RefersToCapture = false) { 612 D->setReferenced(); 613 D->markUsed(S.Context); 614 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 615 SourceLocation(), D, RefersToCapture, Loc, Ty, 616 VK_LValue); 617 } 618 619 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) { 620 D = getCanonicalDecl(D); 621 DSAVarData DVar; 622 623 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 624 // in a Construct, C/C++, predetermined, p.1] 625 // Variables appearing in threadprivate directives are threadprivate. 626 auto *VD = dyn_cast<VarDecl>(D); 627 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 628 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 629 SemaRef.getLangOpts().OpenMPUseTLS && 630 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 631 (VD && VD->getStorageClass() == SC_Register && 632 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 633 addDSA(D, buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 634 D->getLocation()), 635 OMPC_threadprivate); 636 } 637 if (Stack[0].SharingMap.count(D)) { 638 DVar.RefExpr = Stack[0].SharingMap[D].RefExpr; 639 DVar.CKind = OMPC_threadprivate; 640 return DVar; 641 } 642 643 if (Stack.size() == 1) { 644 // Not in OpenMP execution region and top scope was already checked. 645 return DVar; 646 } 647 648 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 649 // in a Construct, C/C++, predetermined, p.4] 650 // Static data members are shared. 651 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 652 // in a Construct, C/C++, predetermined, p.7] 653 // Variables with static storage duration that are declared in a scope 654 // inside the construct are shared. 655 if (VD && VD->isStaticDataMember()) { 656 DSAVarData DVarTemp = 657 hasDSA(D, isOpenMPPrivate, MatchesAlways(), FromParent); 658 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 659 return DVar; 660 661 DVar.CKind = OMPC_shared; 662 return DVar; 663 } 664 665 QualType Type = D->getType().getNonReferenceType().getCanonicalType(); 666 bool IsConstant = Type.isConstant(SemaRef.getASTContext()); 667 Type = SemaRef.getASTContext().getBaseElementType(Type); 668 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 669 // in a Construct, C/C++, predetermined, p.6] 670 // Variables with const qualified type having no mutable member are 671 // shared. 672 CXXRecordDecl *RD = 673 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 674 if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 675 if (auto *CTD = CTSD->getSpecializedTemplate()) 676 RD = CTD->getTemplatedDecl(); 677 if (IsConstant && 678 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() && 679 RD->hasMutableFields())) { 680 // Variables with const-qualified type having no mutable member may be 681 // listed in a firstprivate clause, even if they are static data members. 682 DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate), 683 MatchesAlways(), FromParent); 684 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 685 return DVar; 686 687 DVar.CKind = OMPC_shared; 688 return DVar; 689 } 690 691 // Explicitly specified attributes and local variables with predetermined 692 // attributes. 693 auto StartI = std::next(Stack.rbegin()); 694 auto EndI = std::prev(Stack.rend()); 695 if (FromParent && StartI != EndI) { 696 StartI = std::next(StartI); 697 } 698 auto I = std::prev(StartI); 699 if (I->SharingMap.count(D)) { 700 DVar.RefExpr = I->SharingMap[D].RefExpr; 701 DVar.PrivateCopy = I->SharingMap[D].PrivateCopy; 702 DVar.CKind = I->SharingMap[D].Attributes; 703 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 704 } 705 706 return DVar; 707 } 708 709 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 710 bool FromParent) { 711 D = getCanonicalDecl(D); 712 auto StartI = Stack.rbegin(); 713 auto EndI = std::prev(Stack.rend()); 714 if (FromParent && StartI != EndI) { 715 StartI = std::next(StartI); 716 } 717 return getDSA(StartI, D); 718 } 719 720 template <class ClausesPredicate, class DirectivesPredicate> 721 DSAStackTy::DSAVarData DSAStackTy::hasDSA(ValueDecl *D, ClausesPredicate CPred, 722 DirectivesPredicate DPred, 723 bool FromParent) { 724 D = getCanonicalDecl(D); 725 auto StartI = std::next(Stack.rbegin()); 726 auto EndI = Stack.rend(); 727 if (FromParent && StartI != EndI) { 728 StartI = std::next(StartI); 729 } 730 for (auto I = StartI, EE = EndI; I != EE; ++I) { 731 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) 732 continue; 733 DSAVarData DVar = getDSA(I, D); 734 if (CPred(DVar.CKind)) 735 return DVar; 736 } 737 return DSAVarData(); 738 } 739 740 template <class ClausesPredicate, class DirectivesPredicate> 741 DSAStackTy::DSAVarData 742 DSAStackTy::hasInnermostDSA(ValueDecl *D, ClausesPredicate CPred, 743 DirectivesPredicate DPred, bool FromParent) { 744 D = getCanonicalDecl(D); 745 auto StartI = std::next(Stack.rbegin()); 746 auto EndI = Stack.rend(); 747 if (FromParent && StartI != EndI) { 748 StartI = std::next(StartI); 749 } 750 for (auto I = StartI, EE = EndI; I != EE; ++I) { 751 if (!DPred(I->Directive)) 752 break; 753 DSAVarData DVar = getDSA(I, D); 754 if (CPred(DVar.CKind)) 755 return DVar; 756 return DSAVarData(); 757 } 758 return DSAVarData(); 759 } 760 761 bool DSAStackTy::hasExplicitDSA( 762 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 763 unsigned Level) { 764 if (CPred(ClauseKindMode)) 765 return true; 766 if (isClauseParsingMode()) 767 ++Level; 768 D = getCanonicalDecl(D); 769 auto StartI = Stack.rbegin(); 770 auto EndI = std::prev(Stack.rend()); 771 if (std::distance(StartI, EndI) <= (int)Level) 772 return false; 773 std::advance(StartI, Level); 774 return (StartI->SharingMap.count(D) > 0) && StartI->SharingMap[D].RefExpr && 775 CPred(StartI->SharingMap[D].Attributes); 776 } 777 778 bool DSAStackTy::hasExplicitDirective( 779 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 780 unsigned Level) { 781 if (isClauseParsingMode()) 782 ++Level; 783 auto StartI = Stack.rbegin(); 784 auto EndI = std::prev(Stack.rend()); 785 if (std::distance(StartI, EndI) <= (int)Level) 786 return false; 787 std::advance(StartI, Level); 788 return DPred(StartI->Directive); 789 } 790 791 template <class NamedDirectivesPredicate> 792 bool DSAStackTy::hasDirective(NamedDirectivesPredicate DPred, bool FromParent) { 793 auto StartI = std::next(Stack.rbegin()); 794 auto EndI = std::prev(Stack.rend()); 795 if (FromParent && StartI != EndI) { 796 StartI = std::next(StartI); 797 } 798 for (auto I = StartI, EE = EndI; I != EE; ++I) { 799 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 800 return true; 801 } 802 return false; 803 } 804 805 OpenMPDirectiveKind DSAStackTy::getDirectiveForScope(const Scope *S) const { 806 for (auto I = Stack.rbegin(), EE = Stack.rend(); I != EE; ++I) 807 if (I->CurScope == S) 808 return I->Directive; 809 return OMPD_unknown; 810 } 811 812 void Sema::InitDataSharingAttributesStack() { 813 VarDataSharingAttributesStack = new DSAStackTy(*this); 814 } 815 816 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 817 818 bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, 819 const CapturedRegionScopeInfo *RSI) { 820 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 821 822 auto &Ctx = getASTContext(); 823 bool IsByRef = true; 824 825 // Find the directive that is associated with the provided scope. 826 auto DKind = DSAStack->getDirectiveForScope(RSI->TheScope); 827 auto Ty = D->getType(); 828 829 if (isOpenMPTargetExecutionDirective(DKind)) { 830 // This table summarizes how a given variable should be passed to the device 831 // given its type and the clauses where it appears. This table is based on 832 // the description in OpenMP 4.5 [2.10.4, target Construct] and 833 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 834 // 835 // ========================================================================= 836 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 837 // | |(tofrom:scalar)| | pvt | | | | 838 // ========================================================================= 839 // | scl | | | | - | | bycopy| 840 // | scl | | - | x | - | - | bycopy| 841 // | scl | | x | - | - | - | null | 842 // | scl | x | | | - | | byref | 843 // | scl | x | - | x | - | - | bycopy| 844 // | scl | x | x | - | - | - | null | 845 // | scl | | - | - | - | x | byref | 846 // | scl | x | - | - | - | x | byref | 847 // 848 // | agg | n.a. | | | - | | byref | 849 // | agg | n.a. | - | x | - | - | byref | 850 // | agg | n.a. | x | - | - | - | null | 851 // | agg | n.a. | - | - | - | x | byref | 852 // | agg | n.a. | - | - | - | x[] | byref | 853 // 854 // | ptr | n.a. | | | - | | bycopy| 855 // | ptr | n.a. | - | x | - | - | bycopy| 856 // | ptr | n.a. | x | - | - | - | null | 857 // | ptr | n.a. | - | - | - | x | byref | 858 // | ptr | n.a. | - | - | - | x[] | bycopy| 859 // | ptr | n.a. | - | - | x | | bycopy| 860 // | ptr | n.a. | - | - | x | x | bycopy| 861 // | ptr | n.a. | - | - | x | x[] | bycopy| 862 // ========================================================================= 863 // Legend: 864 // scl - scalar 865 // ptr - pointer 866 // agg - aggregate 867 // x - applies 868 // - - invalid in this combination 869 // [] - mapped with an array section 870 // byref - should be mapped by reference 871 // byval - should be mapped by value 872 // null - initialize a local variable to null on the device 873 // 874 // Observations: 875 // - All scalar declarations that show up in a map clause have to be passed 876 // by reference, because they may have been mapped in the enclosing data 877 // environment. 878 // - If the scalar value does not fit the size of uintptr, it has to be 879 // passed by reference, regardless the result in the table above. 880 // - For pointers mapped by value that have either an implicit map or an 881 // array section, the runtime library may pass the NULL value to the 882 // device instead of the value passed to it by the compiler. 883 884 // FIXME: Right now, only implicit maps are implemented. Properly mapping 885 // values requires having the map, private, and firstprivate clauses SEMA 886 // and parsing in place, which we don't yet. 887 888 if (Ty->isReferenceType()) 889 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 890 IsByRef = !Ty->isScalarType(); 891 } 892 893 // When passing data by value, we need to make sure it fits the uintptr size 894 // and alignment, because the runtime library only deals with uintptr types. 895 // If it does not fit the uintptr size, we need to pass the data by reference 896 // instead. 897 if (!IsByRef && 898 (Ctx.getTypeSizeInChars(Ty) > 899 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 900 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) 901 IsByRef = true; 902 903 return IsByRef; 904 } 905 906 VarDecl *Sema::IsOpenMPCapturedDecl(ValueDecl *D) { 907 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 908 D = getCanonicalDecl(D); 909 910 // If we are attempting to capture a global variable in a directive with 911 // 'target' we return true so that this global is also mapped to the device. 912 // 913 // FIXME: If the declaration is enclosed in a 'declare target' directive, 914 // then it should not be captured. Therefore, an extra check has to be 915 // inserted here once support for 'declare target' is added. 916 // 917 auto *VD = dyn_cast<VarDecl>(D); 918 if (VD && !VD->hasLocalStorage()) { 919 if (DSAStack->getCurrentDirective() == OMPD_target && 920 !DSAStack->isClauseParsingMode()) 921 return VD; 922 if (DSAStack->getCurScope() && 923 DSAStack->hasDirective( 924 [](OpenMPDirectiveKind K, const DeclarationNameInfo &DNI, 925 SourceLocation Loc) -> bool { 926 return isOpenMPTargetExecutionDirective(K); 927 }, 928 false)) 929 return VD; 930 } 931 932 if (DSAStack->getCurrentDirective() != OMPD_unknown && 933 (!DSAStack->isClauseParsingMode() || 934 DSAStack->getParentDirective() != OMPD_unknown)) { 935 auto &&Info = DSAStack->isLoopControlVariable(D); 936 if (Info.first || 937 (VD && VD->hasLocalStorage() && 938 isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || 939 (VD && DSAStack->isForceVarCapturing())) 940 return VD ? VD : Info.second; 941 auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 942 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 943 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 944 DVarPrivate = DSAStack->hasDSA(D, isOpenMPPrivate, MatchesAlways(), 945 DSAStack->isClauseParsingMode()); 946 if (DVarPrivate.CKind != OMPC_unknown) 947 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 948 } 949 return nullptr; 950 } 951 952 bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) { 953 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 954 return DSAStack->hasExplicitDSA( 955 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, Level); 956 } 957 958 bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) { 959 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 960 // Return true if the current level is no longer enclosed in a target region. 961 962 auto *VD = dyn_cast<VarDecl>(D); 963 return VD && !VD->hasLocalStorage() && 964 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 965 Level); 966 } 967 968 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 969 970 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 971 const DeclarationNameInfo &DirName, 972 Scope *CurScope, SourceLocation Loc) { 973 DSAStack->push(DKind, DirName, CurScope, Loc); 974 PushExpressionEvaluationContext(PotentiallyEvaluated); 975 } 976 977 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 978 DSAStack->setClauseParsingMode(K); 979 } 980 981 void Sema::EndOpenMPClause() { 982 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 983 } 984 985 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 986 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 987 // A variable of class type (or array thereof) that appears in a lastprivate 988 // clause requires an accessible, unambiguous default constructor for the 989 // class type, unless the list item is also specified in a firstprivate 990 // clause. 991 if (auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 992 for (auto *C : D->clauses()) { 993 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 994 SmallVector<Expr *, 8> PrivateCopies; 995 for (auto *DE : Clause->varlists()) { 996 if (DE->isValueDependent() || DE->isTypeDependent()) { 997 PrivateCopies.push_back(nullptr); 998 continue; 999 } 1000 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1001 VarDecl *VD = cast<VarDecl>(DRE->getDecl()); 1002 QualType Type = VD->getType().getNonReferenceType(); 1003 auto DVar = DSAStack->getTopDSA(VD, false); 1004 if (DVar.CKind == OMPC_lastprivate) { 1005 // Generate helper private variable and initialize it with the 1006 // default value. The address of the original variable is replaced 1007 // by the address of the new private variable in CodeGen. This new 1008 // variable is not added to IdResolver, so the code in the OpenMP 1009 // region uses original variable for proper diagnostics. 1010 auto *VDPrivate = buildVarDecl( 1011 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1012 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr); 1013 ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); 1014 if (VDPrivate->isInvalidDecl()) 1015 continue; 1016 PrivateCopies.push_back(buildDeclRefExpr( 1017 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1018 } else { 1019 // The variable is also a firstprivate, so initialization sequence 1020 // for private copy is generated already. 1021 PrivateCopies.push_back(nullptr); 1022 } 1023 } 1024 // Set initializers to private copies if no errors were found. 1025 if (PrivateCopies.size() == Clause->varlist_size()) 1026 Clause->setPrivateCopies(PrivateCopies); 1027 } 1028 } 1029 } 1030 1031 DSAStack->pop(); 1032 DiscardCleanupsInEvaluationContext(); 1033 PopExpressionEvaluationContext(); 1034 } 1035 1036 static bool 1037 FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1038 Expr *NumIterations, Sema &SemaRef, Scope *S); 1039 1040 namespace { 1041 1042 class VarDeclFilterCCC : public CorrectionCandidateCallback { 1043 private: 1044 Sema &SemaRef; 1045 1046 public: 1047 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1048 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1049 NamedDecl *ND = Candidate.getCorrectionDecl(); 1050 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) { 1051 return VD->hasGlobalStorage() && 1052 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1053 SemaRef.getCurScope()); 1054 } 1055 return false; 1056 } 1057 }; 1058 } // namespace 1059 1060 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 1061 CXXScopeSpec &ScopeSpec, 1062 const DeclarationNameInfo &Id) { 1063 LookupResult Lookup(*this, Id, LookupOrdinaryName); 1064 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 1065 1066 if (Lookup.isAmbiguous()) 1067 return ExprError(); 1068 1069 VarDecl *VD; 1070 if (!Lookup.isSingleResult()) { 1071 if (TypoCorrection Corrected = CorrectTypo( 1072 Id, LookupOrdinaryName, CurScope, nullptr, 1073 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 1074 diagnoseTypo(Corrected, 1075 PDiag(Lookup.empty() 1076 ? diag::err_undeclared_var_use_suggest 1077 : diag::err_omp_expected_var_arg_suggest) 1078 << Id.getName()); 1079 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 1080 } else { 1081 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 1082 : diag::err_omp_expected_var_arg) 1083 << Id.getName(); 1084 return ExprError(); 1085 } 1086 } else { 1087 if (!(VD = Lookup.getAsSingle<VarDecl>())) { 1088 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 1089 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 1090 return ExprError(); 1091 } 1092 } 1093 Lookup.suppressDiagnostics(); 1094 1095 // OpenMP [2.9.2, Syntax, C/C++] 1096 // Variables must be file-scope, namespace-scope, or static block-scope. 1097 if (!VD->hasGlobalStorage()) { 1098 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 1099 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); 1100 bool IsDecl = 1101 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1102 Diag(VD->getLocation(), 1103 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1104 << VD; 1105 return ExprError(); 1106 } 1107 1108 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 1109 NamedDecl *ND = cast<NamedDecl>(CanonicalVD); 1110 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 1111 // A threadprivate directive for file-scope variables must appear outside 1112 // any definition or declaration. 1113 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 1114 !getCurLexicalContext()->isTranslationUnit()) { 1115 Diag(Id.getLoc(), diag::err_omp_var_scope) 1116 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1117 bool IsDecl = 1118 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1119 Diag(VD->getLocation(), 1120 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1121 << VD; 1122 return ExprError(); 1123 } 1124 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 1125 // A threadprivate directive for static class member variables must appear 1126 // in the class definition, in the same scope in which the member 1127 // variables are declared. 1128 if (CanonicalVD->isStaticDataMember() && 1129 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 1130 Diag(Id.getLoc(), diag::err_omp_var_scope) 1131 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1132 bool IsDecl = 1133 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1134 Diag(VD->getLocation(), 1135 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1136 << VD; 1137 return ExprError(); 1138 } 1139 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 1140 // A threadprivate directive for namespace-scope variables must appear 1141 // outside any definition or declaration other than the namespace 1142 // definition itself. 1143 if (CanonicalVD->getDeclContext()->isNamespace() && 1144 (!getCurLexicalContext()->isFileContext() || 1145 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 1146 Diag(Id.getLoc(), diag::err_omp_var_scope) 1147 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1148 bool IsDecl = 1149 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1150 Diag(VD->getLocation(), 1151 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1152 << VD; 1153 return ExprError(); 1154 } 1155 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 1156 // A threadprivate directive for static block-scope variables must appear 1157 // in the scope of the variable and not in a nested scope. 1158 if (CanonicalVD->isStaticLocal() && CurScope && 1159 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 1160 Diag(Id.getLoc(), diag::err_omp_var_scope) 1161 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1162 bool IsDecl = 1163 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1164 Diag(VD->getLocation(), 1165 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1166 << VD; 1167 return ExprError(); 1168 } 1169 1170 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 1171 // A threadprivate directive must lexically precede all references to any 1172 // of the variables in its list. 1173 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { 1174 Diag(Id.getLoc(), diag::err_omp_var_used) 1175 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1176 return ExprError(); 1177 } 1178 1179 QualType ExprType = VD->getType().getNonReferenceType(); 1180 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 1181 SourceLocation(), VD, 1182 /*RefersToEnclosingVariableOrCapture=*/false, 1183 Id.getLoc(), ExprType, VK_LValue); 1184 } 1185 1186 Sema::DeclGroupPtrTy 1187 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 1188 ArrayRef<Expr *> VarList) { 1189 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 1190 CurContext->addDecl(D); 1191 return DeclGroupPtrTy::make(DeclGroupRef(D)); 1192 } 1193 return nullptr; 1194 } 1195 1196 namespace { 1197 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> { 1198 Sema &SemaRef; 1199 1200 public: 1201 bool VisitDeclRefExpr(const DeclRefExpr *E) { 1202 if (auto VD = dyn_cast<VarDecl>(E->getDecl())) { 1203 if (VD->hasLocalStorage()) { 1204 SemaRef.Diag(E->getLocStart(), 1205 diag::err_omp_local_var_in_threadprivate_init) 1206 << E->getSourceRange(); 1207 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 1208 << VD << VD->getSourceRange(); 1209 return true; 1210 } 1211 } 1212 return false; 1213 } 1214 bool VisitStmt(const Stmt *S) { 1215 for (auto Child : S->children()) { 1216 if (Child && Visit(Child)) 1217 return true; 1218 } 1219 return false; 1220 } 1221 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 1222 }; 1223 } // namespace 1224 1225 OMPThreadPrivateDecl * 1226 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 1227 SmallVector<Expr *, 8> Vars; 1228 for (auto &RefExpr : VarList) { 1229 DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr); 1230 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 1231 SourceLocation ILoc = DE->getExprLoc(); 1232 1233 // Mark variable as used. 1234 VD->setReferenced(); 1235 VD->markUsed(Context); 1236 1237 QualType QType = VD->getType(); 1238 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 1239 // It will be analyzed later. 1240 Vars.push_back(DE); 1241 continue; 1242 } 1243 1244 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1245 // A threadprivate variable must not have an incomplete type. 1246 if (RequireCompleteType(ILoc, VD->getType(), 1247 diag::err_omp_threadprivate_incomplete_type)) { 1248 continue; 1249 } 1250 1251 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1252 // A threadprivate variable must not have a reference type. 1253 if (VD->getType()->isReferenceType()) { 1254 Diag(ILoc, diag::err_omp_ref_type_arg) 1255 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 1256 bool IsDecl = 1257 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1258 Diag(VD->getLocation(), 1259 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1260 << VD; 1261 continue; 1262 } 1263 1264 // Check if this is a TLS variable. If TLS is not being supported, produce 1265 // the corresponding diagnostic. 1266 if ((VD->getTLSKind() != VarDecl::TLS_None && 1267 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1268 getLangOpts().OpenMPUseTLS && 1269 getASTContext().getTargetInfo().isTLSSupported())) || 1270 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 1271 !VD->isLocalVarDecl())) { 1272 Diag(ILoc, diag::err_omp_var_thread_local) 1273 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 1274 bool IsDecl = 1275 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1276 Diag(VD->getLocation(), 1277 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1278 << VD; 1279 continue; 1280 } 1281 1282 // Check if initial value of threadprivate variable reference variable with 1283 // local storage (it is not supported by runtime). 1284 if (auto Init = VD->getAnyInitializer()) { 1285 LocalVarRefChecker Checker(*this); 1286 if (Checker.Visit(Init)) 1287 continue; 1288 } 1289 1290 Vars.push_back(RefExpr); 1291 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 1292 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 1293 Context, SourceRange(Loc, Loc))); 1294 if (auto *ML = Context.getASTMutationListener()) 1295 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 1296 } 1297 OMPThreadPrivateDecl *D = nullptr; 1298 if (!Vars.empty()) { 1299 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 1300 Vars); 1301 D->setAccess(AS_public); 1302 } 1303 return D; 1304 } 1305 1306 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, 1307 const ValueDecl *D, DSAStackTy::DSAVarData DVar, 1308 bool IsLoopIterVar = false) { 1309 if (DVar.RefExpr) { 1310 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 1311 << getOpenMPClauseName(DVar.CKind); 1312 return; 1313 } 1314 enum { 1315 PDSA_StaticMemberShared, 1316 PDSA_StaticLocalVarShared, 1317 PDSA_LoopIterVarPrivate, 1318 PDSA_LoopIterVarLinear, 1319 PDSA_LoopIterVarLastprivate, 1320 PDSA_ConstVarShared, 1321 PDSA_GlobalVarShared, 1322 PDSA_TaskVarFirstprivate, 1323 PDSA_LocalVarPrivate, 1324 PDSA_Implicit 1325 } Reason = PDSA_Implicit; 1326 bool ReportHint = false; 1327 auto ReportLoc = D->getLocation(); 1328 auto *VD = dyn_cast<VarDecl>(D); 1329 if (IsLoopIterVar) { 1330 if (DVar.CKind == OMPC_private) 1331 Reason = PDSA_LoopIterVarPrivate; 1332 else if (DVar.CKind == OMPC_lastprivate) 1333 Reason = PDSA_LoopIterVarLastprivate; 1334 else 1335 Reason = PDSA_LoopIterVarLinear; 1336 } else if (isOpenMPTaskingDirective(DVar.DKind) && 1337 DVar.CKind == OMPC_firstprivate) { 1338 Reason = PDSA_TaskVarFirstprivate; 1339 ReportLoc = DVar.ImplicitDSALoc; 1340 } else if (VD && VD->isStaticLocal()) 1341 Reason = PDSA_StaticLocalVarShared; 1342 else if (VD && VD->isStaticDataMember()) 1343 Reason = PDSA_StaticMemberShared; 1344 else if (VD && VD->isFileVarDecl()) 1345 Reason = PDSA_GlobalVarShared; 1346 else if (D->getType().isConstant(SemaRef.getASTContext())) 1347 Reason = PDSA_ConstVarShared; 1348 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 1349 ReportHint = true; 1350 Reason = PDSA_LocalVarPrivate; 1351 } 1352 if (Reason != PDSA_Implicit) { 1353 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 1354 << Reason << ReportHint 1355 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 1356 } else if (DVar.ImplicitDSALoc.isValid()) { 1357 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 1358 << getOpenMPClauseName(DVar.CKind); 1359 } 1360 } 1361 1362 namespace { 1363 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> { 1364 DSAStackTy *Stack; 1365 Sema &SemaRef; 1366 bool ErrorFound; 1367 CapturedStmt *CS; 1368 llvm::SmallVector<Expr *, 8> ImplicitFirstprivate; 1369 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 1370 1371 public: 1372 void VisitDeclRefExpr(DeclRefExpr *E) { 1373 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1374 // Skip internally declared variables. 1375 if (VD->isLocalVarDecl() && !CS->capturesVariable(VD)) 1376 return; 1377 1378 auto DVar = Stack->getTopDSA(VD, false); 1379 // Check if the variable has explicit DSA set and stop analysis if it so. 1380 if (DVar.RefExpr) return; 1381 1382 auto ELoc = E->getExprLoc(); 1383 auto DKind = Stack->getCurrentDirective(); 1384 // The default(none) clause requires that each variable that is referenced 1385 // in the construct, and does not have a predetermined data-sharing 1386 // attribute, must have its data-sharing attribute explicitly determined 1387 // by being listed in a data-sharing attribute clause. 1388 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 1389 isParallelOrTaskRegion(DKind) && 1390 VarsWithInheritedDSA.count(VD) == 0) { 1391 VarsWithInheritedDSA[VD] = E; 1392 return; 1393 } 1394 1395 // OpenMP [2.9.3.6, Restrictions, p.2] 1396 // A list item that appears in a reduction clause of the innermost 1397 // enclosing worksharing or parallel construct may not be accessed in an 1398 // explicit task. 1399 DVar = Stack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction), 1400 [](OpenMPDirectiveKind K) -> bool { 1401 return isOpenMPParallelDirective(K) || 1402 isOpenMPWorksharingDirective(K) || 1403 isOpenMPTeamsDirective(K); 1404 }, 1405 false); 1406 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 1407 ErrorFound = true; 1408 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1409 ReportOriginalDSA(SemaRef, Stack, VD, DVar); 1410 return; 1411 } 1412 1413 // Define implicit data-sharing attributes for task. 1414 DVar = Stack->getImplicitDSA(VD, false); 1415 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 1416 !Stack->isLoopControlVariable(VD).first) 1417 ImplicitFirstprivate.push_back(E); 1418 } 1419 } 1420 void VisitMemberExpr(MemberExpr *E) { 1421 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 1422 if (auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl())) { 1423 auto DVar = Stack->getTopDSA(FD, false); 1424 // Check if the variable has explicit DSA set and stop analysis if it 1425 // so. 1426 if (DVar.RefExpr) 1427 return; 1428 1429 auto ELoc = E->getExprLoc(); 1430 auto DKind = Stack->getCurrentDirective(); 1431 // OpenMP [2.9.3.6, Restrictions, p.2] 1432 // A list item that appears in a reduction clause of the innermost 1433 // enclosing worksharing or parallel construct may not be accessed in 1434 // an explicit task. 1435 DVar = 1436 Stack->hasInnermostDSA(FD, MatchesAnyClause(OMPC_reduction), 1437 [](OpenMPDirectiveKind K) -> bool { 1438 return isOpenMPParallelDirective(K) || 1439 isOpenMPWorksharingDirective(K) || 1440 isOpenMPTeamsDirective(K); 1441 }, 1442 false); 1443 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 1444 ErrorFound = true; 1445 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1446 ReportOriginalDSA(SemaRef, Stack, FD, DVar); 1447 return; 1448 } 1449 1450 // Define implicit data-sharing attributes for task. 1451 DVar = Stack->getImplicitDSA(FD, false); 1452 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 1453 !Stack->isLoopControlVariable(FD).first) 1454 ImplicitFirstprivate.push_back(E); 1455 } 1456 } 1457 } 1458 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 1459 for (auto *C : S->clauses()) { 1460 // Skip analysis of arguments of implicitly defined firstprivate clause 1461 // for task directives. 1462 if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid())) 1463 for (auto *CC : C->children()) { 1464 if (CC) 1465 Visit(CC); 1466 } 1467 } 1468 } 1469 void VisitStmt(Stmt *S) { 1470 for (auto *C : S->children()) { 1471 if (C && !isa<OMPExecutableDirective>(C)) 1472 Visit(C); 1473 } 1474 } 1475 1476 bool isErrorFound() { return ErrorFound; } 1477 ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; } 1478 llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() { 1479 return VarsWithInheritedDSA; 1480 } 1481 1482 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 1483 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} 1484 }; 1485 } // namespace 1486 1487 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 1488 switch (DKind) { 1489 case OMPD_parallel: { 1490 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1491 QualType KmpInt32PtrTy = 1492 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1493 Sema::CapturedParamNameType Params[] = { 1494 std::make_pair(".global_tid.", KmpInt32PtrTy), 1495 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1496 std::make_pair(StringRef(), QualType()) // __context with shared vars 1497 }; 1498 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1499 Params); 1500 break; 1501 } 1502 case OMPD_simd: { 1503 Sema::CapturedParamNameType Params[] = { 1504 std::make_pair(StringRef(), QualType()) // __context with shared vars 1505 }; 1506 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1507 Params); 1508 break; 1509 } 1510 case OMPD_for: { 1511 Sema::CapturedParamNameType Params[] = { 1512 std::make_pair(StringRef(), QualType()) // __context with shared vars 1513 }; 1514 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1515 Params); 1516 break; 1517 } 1518 case OMPD_for_simd: { 1519 Sema::CapturedParamNameType Params[] = { 1520 std::make_pair(StringRef(), QualType()) // __context with shared vars 1521 }; 1522 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1523 Params); 1524 break; 1525 } 1526 case OMPD_sections: { 1527 Sema::CapturedParamNameType Params[] = { 1528 std::make_pair(StringRef(), QualType()) // __context with shared vars 1529 }; 1530 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1531 Params); 1532 break; 1533 } 1534 case OMPD_section: { 1535 Sema::CapturedParamNameType Params[] = { 1536 std::make_pair(StringRef(), QualType()) // __context with shared vars 1537 }; 1538 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1539 Params); 1540 break; 1541 } 1542 case OMPD_single: { 1543 Sema::CapturedParamNameType Params[] = { 1544 std::make_pair(StringRef(), QualType()) // __context with shared vars 1545 }; 1546 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1547 Params); 1548 break; 1549 } 1550 case OMPD_master: { 1551 Sema::CapturedParamNameType Params[] = { 1552 std::make_pair(StringRef(), QualType()) // __context with shared vars 1553 }; 1554 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1555 Params); 1556 break; 1557 } 1558 case OMPD_critical: { 1559 Sema::CapturedParamNameType Params[] = { 1560 std::make_pair(StringRef(), QualType()) // __context with shared vars 1561 }; 1562 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1563 Params); 1564 break; 1565 } 1566 case OMPD_parallel_for: { 1567 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1568 QualType KmpInt32PtrTy = 1569 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1570 Sema::CapturedParamNameType Params[] = { 1571 std::make_pair(".global_tid.", KmpInt32PtrTy), 1572 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1573 std::make_pair(StringRef(), QualType()) // __context with shared vars 1574 }; 1575 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1576 Params); 1577 break; 1578 } 1579 case OMPD_parallel_for_simd: { 1580 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1581 QualType KmpInt32PtrTy = 1582 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1583 Sema::CapturedParamNameType Params[] = { 1584 std::make_pair(".global_tid.", KmpInt32PtrTy), 1585 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1586 std::make_pair(StringRef(), QualType()) // __context with shared vars 1587 }; 1588 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1589 Params); 1590 break; 1591 } 1592 case OMPD_parallel_sections: { 1593 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1594 QualType KmpInt32PtrTy = 1595 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1596 Sema::CapturedParamNameType Params[] = { 1597 std::make_pair(".global_tid.", KmpInt32PtrTy), 1598 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1599 std::make_pair(StringRef(), QualType()) // __context with shared vars 1600 }; 1601 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1602 Params); 1603 break; 1604 } 1605 case OMPD_task: { 1606 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1607 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 1608 FunctionProtoType::ExtProtoInfo EPI; 1609 EPI.Variadic = true; 1610 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 1611 Sema::CapturedParamNameType Params[] = { 1612 std::make_pair(".global_tid.", KmpInt32Ty), 1613 std::make_pair(".part_id.", KmpInt32Ty), 1614 std::make_pair(".privates.", 1615 Context.VoidPtrTy.withConst().withRestrict()), 1616 std::make_pair( 1617 ".copy_fn.", 1618 Context.getPointerType(CopyFnType).withConst().withRestrict()), 1619 std::make_pair(StringRef(), QualType()) // __context with shared vars 1620 }; 1621 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1622 Params); 1623 // Mark this captured region as inlined, because we don't use outlined 1624 // function directly. 1625 getCurCapturedRegion()->TheCapturedDecl->addAttr( 1626 AlwaysInlineAttr::CreateImplicit( 1627 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 1628 break; 1629 } 1630 case OMPD_ordered: { 1631 Sema::CapturedParamNameType Params[] = { 1632 std::make_pair(StringRef(), QualType()) // __context with shared vars 1633 }; 1634 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1635 Params); 1636 break; 1637 } 1638 case OMPD_atomic: { 1639 Sema::CapturedParamNameType Params[] = { 1640 std::make_pair(StringRef(), QualType()) // __context with shared vars 1641 }; 1642 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1643 Params); 1644 break; 1645 } 1646 case OMPD_target_data: 1647 case OMPD_target: 1648 case OMPD_target_parallel: 1649 case OMPD_target_parallel_for: { 1650 Sema::CapturedParamNameType Params[] = { 1651 std::make_pair(StringRef(), QualType()) // __context with shared vars 1652 }; 1653 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1654 Params); 1655 break; 1656 } 1657 case OMPD_teams: { 1658 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1659 QualType KmpInt32PtrTy = 1660 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1661 Sema::CapturedParamNameType Params[] = { 1662 std::make_pair(".global_tid.", KmpInt32PtrTy), 1663 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1664 std::make_pair(StringRef(), QualType()) // __context with shared vars 1665 }; 1666 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1667 Params); 1668 break; 1669 } 1670 case OMPD_taskgroup: { 1671 Sema::CapturedParamNameType Params[] = { 1672 std::make_pair(StringRef(), QualType()) // __context with shared vars 1673 }; 1674 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1675 Params); 1676 break; 1677 } 1678 case OMPD_taskloop: { 1679 Sema::CapturedParamNameType Params[] = { 1680 std::make_pair(StringRef(), QualType()) // __context with shared vars 1681 }; 1682 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1683 Params); 1684 break; 1685 } 1686 case OMPD_taskloop_simd: { 1687 Sema::CapturedParamNameType Params[] = { 1688 std::make_pair(StringRef(), QualType()) // __context with shared vars 1689 }; 1690 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1691 Params); 1692 break; 1693 } 1694 case OMPD_distribute: { 1695 Sema::CapturedParamNameType Params[] = { 1696 std::make_pair(StringRef(), QualType()) // __context with shared vars 1697 }; 1698 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1699 Params); 1700 break; 1701 } 1702 case OMPD_threadprivate: 1703 case OMPD_taskyield: 1704 case OMPD_barrier: 1705 case OMPD_taskwait: 1706 case OMPD_cancellation_point: 1707 case OMPD_cancel: 1708 case OMPD_flush: 1709 case OMPD_target_enter_data: 1710 case OMPD_target_exit_data: 1711 case OMPD_declare_reduction: 1712 case OMPD_declare_simd: 1713 case OMPD_declare_target: 1714 case OMPD_end_declare_target: 1715 llvm_unreachable("OpenMP Directive is not allowed"); 1716 case OMPD_unknown: 1717 llvm_unreachable("Unknown OpenMP directive"); 1718 } 1719 } 1720 1721 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 1722 Expr *CaptureExpr, bool WithInit, 1723 bool AsExpression) { 1724 assert(CaptureExpr); 1725 ASTContext &C = S.getASTContext(); 1726 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 1727 QualType Ty = Init->getType(); 1728 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 1729 if (S.getLangOpts().CPlusPlus) 1730 Ty = C.getLValueReferenceType(Ty); 1731 else { 1732 Ty = C.getPointerType(Ty); 1733 ExprResult Res = 1734 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 1735 if (!Res.isUsable()) 1736 return nullptr; 1737 Init = Res.get(); 1738 } 1739 WithInit = true; 1740 } 1741 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty); 1742 if (!WithInit) 1743 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange())); 1744 S.CurContext->addHiddenDecl(CED); 1745 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false, 1746 /*TypeMayContainAuto=*/true); 1747 return CED; 1748 } 1749 1750 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 1751 bool WithInit) { 1752 OMPCapturedExprDecl *CD; 1753 if (auto *VD = S.IsOpenMPCapturedDecl(D)) 1754 CD = cast<OMPCapturedExprDecl>(VD); 1755 else 1756 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 1757 /*AsExpression=*/false); 1758 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 1759 CaptureExpr->getExprLoc()); 1760 } 1761 1762 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 1763 if (!Ref) { 1764 auto *CD = 1765 buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."), 1766 CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true); 1767 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 1768 CaptureExpr->getExprLoc()); 1769 } 1770 ExprResult Res = Ref; 1771 if (!S.getLangOpts().CPlusPlus && 1772 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 1773 Ref->getType()->isPointerType()) 1774 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 1775 if (!Res.isUsable()) 1776 return ExprError(); 1777 return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get()); 1778 } 1779 1780 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 1781 ArrayRef<OMPClause *> Clauses) { 1782 if (!S.isUsable()) { 1783 ActOnCapturedRegionError(); 1784 return StmtError(); 1785 } 1786 1787 OMPOrderedClause *OC = nullptr; 1788 OMPScheduleClause *SC = nullptr; 1789 SmallVector<OMPLinearClause *, 4> LCs; 1790 // This is required for proper codegen. 1791 for (auto *Clause : Clauses) { 1792 if (isOpenMPPrivate(Clause->getClauseKind()) || 1793 Clause->getClauseKind() == OMPC_copyprivate || 1794 (getLangOpts().OpenMPUseTLS && 1795 getASTContext().getTargetInfo().isTLSSupported() && 1796 Clause->getClauseKind() == OMPC_copyin)) { 1797 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 1798 // Mark all variables in private list clauses as used in inner region. 1799 for (auto *VarRef : Clause->children()) { 1800 if (auto *E = cast_or_null<Expr>(VarRef)) { 1801 MarkDeclarationsReferencedInExpr(E); 1802 } 1803 } 1804 DSAStack->setForceVarCapturing(/*V=*/false); 1805 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 1806 // Mark all variables in private list clauses as used in inner region. 1807 // Required for proper codegen of combined directives. 1808 // TODO: add processing for other clauses. 1809 if (auto *C = OMPClauseWithPreInit::get(Clause)) { 1810 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 1811 for (auto *D : DS->decls()) 1812 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 1813 } 1814 } 1815 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 1816 if (auto *E = C->getPostUpdateExpr()) 1817 MarkDeclarationsReferencedInExpr(E); 1818 } 1819 } 1820 if (Clause->getClauseKind() == OMPC_schedule) 1821 SC = cast<OMPScheduleClause>(Clause); 1822 else if (Clause->getClauseKind() == OMPC_ordered) 1823 OC = cast<OMPOrderedClause>(Clause); 1824 else if (Clause->getClauseKind() == OMPC_linear) 1825 LCs.push_back(cast<OMPLinearClause>(Clause)); 1826 } 1827 bool ErrorFound = false; 1828 // OpenMP, 2.7.1 Loop Construct, Restrictions 1829 // The nonmonotonic modifier cannot be specified if an ordered clause is 1830 // specified. 1831 if (SC && 1832 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 1833 SC->getSecondScheduleModifier() == 1834 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 1835 OC) { 1836 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 1837 ? SC->getFirstScheduleModifierLoc() 1838 : SC->getSecondScheduleModifierLoc(), 1839 diag::err_omp_schedule_nonmonotonic_ordered) 1840 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 1841 ErrorFound = true; 1842 } 1843 if (!LCs.empty() && OC && OC->getNumForLoops()) { 1844 for (auto *C : LCs) { 1845 Diag(C->getLocStart(), diag::err_omp_linear_ordered) 1846 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 1847 } 1848 ErrorFound = true; 1849 } 1850 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 1851 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 1852 OC->getNumForLoops()) { 1853 Diag(OC->getLocStart(), diag::err_omp_ordered_simd) 1854 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 1855 ErrorFound = true; 1856 } 1857 if (ErrorFound) { 1858 ActOnCapturedRegionError(); 1859 return StmtError(); 1860 } 1861 return ActOnCapturedRegionEnd(S.get()); 1862 } 1863 1864 static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, 1865 OpenMPDirectiveKind CurrentRegion, 1866 const DeclarationNameInfo &CurrentName, 1867 OpenMPDirectiveKind CancelRegion, 1868 SourceLocation StartLoc) { 1869 // Allowed nesting of constructs 1870 // +------------------+-----------------+------------------------------------+ 1871 // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)| 1872 // +------------------+-----------------+------------------------------------+ 1873 // | parallel | parallel | * | 1874 // | parallel | for | * | 1875 // | parallel | for simd | * | 1876 // | parallel | master | * | 1877 // | parallel | critical | * | 1878 // | parallel | simd | * | 1879 // | parallel | sections | * | 1880 // | parallel | section | + | 1881 // | parallel | single | * | 1882 // | parallel | parallel for | * | 1883 // | parallel |parallel for simd| * | 1884 // | parallel |parallel sections| * | 1885 // | parallel | task | * | 1886 // | parallel | taskyield | * | 1887 // | parallel | barrier | * | 1888 // | parallel | taskwait | * | 1889 // | parallel | taskgroup | * | 1890 // | parallel | flush | * | 1891 // | parallel | ordered | + | 1892 // | parallel | atomic | * | 1893 // | parallel | target | * | 1894 // | parallel | target parallel | * | 1895 // | parallel | target parallel | * | 1896 // | | for | | 1897 // | parallel | target enter | * | 1898 // | | data | | 1899 // | parallel | target exit | * | 1900 // | | data | | 1901 // | parallel | teams | + | 1902 // | parallel | cancellation | | 1903 // | | point | ! | 1904 // | parallel | cancel | ! | 1905 // | parallel | taskloop | * | 1906 // | parallel | taskloop simd | * | 1907 // | parallel | distribute | | 1908 // +------------------+-----------------+------------------------------------+ 1909 // | for | parallel | * | 1910 // | for | for | + | 1911 // | for | for simd | + | 1912 // | for | master | + | 1913 // | for | critical | * | 1914 // | for | simd | * | 1915 // | for | sections | + | 1916 // | for | section | + | 1917 // | for | single | + | 1918 // | for | parallel for | * | 1919 // | for |parallel for simd| * | 1920 // | for |parallel sections| * | 1921 // | for | task | * | 1922 // | for | taskyield | * | 1923 // | for | barrier | + | 1924 // | for | taskwait | * | 1925 // | for | taskgroup | * | 1926 // | for | flush | * | 1927 // | for | ordered | * (if construct is ordered) | 1928 // | for | atomic | * | 1929 // | for | target | * | 1930 // | for | target parallel | * | 1931 // | for | target parallel | * | 1932 // | | for | | 1933 // | for | target enter | * | 1934 // | | data | | 1935 // | for | target exit | * | 1936 // | | data | | 1937 // | for | teams | + | 1938 // | for | cancellation | | 1939 // | | point | ! | 1940 // | for | cancel | ! | 1941 // | for | taskloop | * | 1942 // | for | taskloop simd | * | 1943 // | for | distribute | | 1944 // +------------------+-----------------+------------------------------------+ 1945 // | master | parallel | * | 1946 // | master | for | + | 1947 // | master | for simd | + | 1948 // | master | master | * | 1949 // | master | critical | * | 1950 // | master | simd | * | 1951 // | master | sections | + | 1952 // | master | section | + | 1953 // | master | single | + | 1954 // | master | parallel for | * | 1955 // | master |parallel for simd| * | 1956 // | master |parallel sections| * | 1957 // | master | task | * | 1958 // | master | taskyield | * | 1959 // | master | barrier | + | 1960 // | master | taskwait | * | 1961 // | master | taskgroup | * | 1962 // | master | flush | * | 1963 // | master | ordered | + | 1964 // | master | atomic | * | 1965 // | master | target | * | 1966 // | master | target parallel | * | 1967 // | master | target parallel | * | 1968 // | | for | | 1969 // | master | target enter | * | 1970 // | | data | | 1971 // | master | target exit | * | 1972 // | | data | | 1973 // | master | teams | + | 1974 // | master | cancellation | | 1975 // | | point | | 1976 // | master | cancel | | 1977 // | master | taskloop | * | 1978 // | master | taskloop simd | * | 1979 // | master | distribute | | 1980 // +------------------+-----------------+------------------------------------+ 1981 // | critical | parallel | * | 1982 // | critical | for | + | 1983 // | critical | for simd | + | 1984 // | critical | master | * | 1985 // | critical | critical | * (should have different names) | 1986 // | critical | simd | * | 1987 // | critical | sections | + | 1988 // | critical | section | + | 1989 // | critical | single | + | 1990 // | critical | parallel for | * | 1991 // | critical |parallel for simd| * | 1992 // | critical |parallel sections| * | 1993 // | critical | task | * | 1994 // | critical | taskyield | * | 1995 // | critical | barrier | + | 1996 // | critical | taskwait | * | 1997 // | critical | taskgroup | * | 1998 // | critical | ordered | + | 1999 // | critical | atomic | * | 2000 // | critical | target | * | 2001 // | critical | target parallel | * | 2002 // | critical | target parallel | * | 2003 // | | for | | 2004 // | critical | target enter | * | 2005 // | | data | | 2006 // | critical | target exit | * | 2007 // | | data | | 2008 // | critical | teams | + | 2009 // | critical | cancellation | | 2010 // | | point | | 2011 // | critical | cancel | | 2012 // | critical | taskloop | * | 2013 // | critical | taskloop simd | * | 2014 // | critical | distribute | | 2015 // +------------------+-----------------+------------------------------------+ 2016 // | simd | parallel | | 2017 // | simd | for | | 2018 // | simd | for simd | | 2019 // | simd | master | | 2020 // | simd | critical | | 2021 // | simd | simd | * | 2022 // | simd | sections | | 2023 // | simd | section | | 2024 // | simd | single | | 2025 // | simd | parallel for | | 2026 // | simd |parallel for simd| | 2027 // | simd |parallel sections| | 2028 // | simd | task | | 2029 // | simd | taskyield | | 2030 // | simd | barrier | | 2031 // | simd | taskwait | | 2032 // | simd | taskgroup | | 2033 // | simd | flush | | 2034 // | simd | ordered | + (with simd clause) | 2035 // | simd | atomic | | 2036 // | simd | target | | 2037 // | simd | target parallel | | 2038 // | simd | target parallel | | 2039 // | | for | | 2040 // | simd | target enter | | 2041 // | | data | | 2042 // | simd | target exit | | 2043 // | | data | | 2044 // | simd | teams | | 2045 // | simd | cancellation | | 2046 // | | point | | 2047 // | simd | cancel | | 2048 // | simd | taskloop | | 2049 // | simd | taskloop simd | | 2050 // | simd | distribute | | 2051 // +------------------+-----------------+------------------------------------+ 2052 // | for simd | parallel | | 2053 // | for simd | for | | 2054 // | for simd | for simd | | 2055 // | for simd | master | | 2056 // | for simd | critical | | 2057 // | for simd | simd | * | 2058 // | for simd | sections | | 2059 // | for simd | section | | 2060 // | for simd | single | | 2061 // | for simd | parallel for | | 2062 // | for simd |parallel for simd| | 2063 // | for simd |parallel sections| | 2064 // | for simd | task | | 2065 // | for simd | taskyield | | 2066 // | for simd | barrier | | 2067 // | for simd | taskwait | | 2068 // | for simd | taskgroup | | 2069 // | for simd | flush | | 2070 // | for simd | ordered | + (with simd clause) | 2071 // | for simd | atomic | | 2072 // | for simd | target | | 2073 // | for simd | target parallel | | 2074 // | for simd | target parallel | | 2075 // | | for | | 2076 // | for simd | target enter | | 2077 // | | data | | 2078 // | for simd | target exit | | 2079 // | | data | | 2080 // | for simd | teams | | 2081 // | for simd | cancellation | | 2082 // | | point | | 2083 // | for simd | cancel | | 2084 // | for simd | taskloop | | 2085 // | for simd | taskloop simd | | 2086 // | for simd | distribute | | 2087 // +------------------+-----------------+------------------------------------+ 2088 // | parallel for simd| parallel | | 2089 // | parallel for simd| for | | 2090 // | parallel for simd| for simd | | 2091 // | parallel for simd| master | | 2092 // | parallel for simd| critical | | 2093 // | parallel for simd| simd | * | 2094 // | parallel for simd| sections | | 2095 // | parallel for simd| section | | 2096 // | parallel for simd| single | | 2097 // | parallel for simd| parallel for | | 2098 // | parallel for simd|parallel for simd| | 2099 // | parallel for simd|parallel sections| | 2100 // | parallel for simd| task | | 2101 // | parallel for simd| taskyield | | 2102 // | parallel for simd| barrier | | 2103 // | parallel for simd| taskwait | | 2104 // | parallel for simd| taskgroup | | 2105 // | parallel for simd| flush | | 2106 // | parallel for simd| ordered | + (with simd clause) | 2107 // | parallel for simd| atomic | | 2108 // | parallel for simd| target | | 2109 // | parallel for simd| target parallel | | 2110 // | parallel for simd| target parallel | | 2111 // | | for | | 2112 // | parallel for simd| target enter | | 2113 // | | data | | 2114 // | parallel for simd| target exit | | 2115 // | | data | | 2116 // | parallel for simd| teams | | 2117 // | parallel for simd| cancellation | | 2118 // | | point | | 2119 // | parallel for simd| cancel | | 2120 // | parallel for simd| taskloop | | 2121 // | parallel for simd| taskloop simd | | 2122 // | parallel for simd| distribute | | 2123 // +------------------+-----------------+------------------------------------+ 2124 // | sections | parallel | * | 2125 // | sections | for | + | 2126 // | sections | for simd | + | 2127 // | sections | master | + | 2128 // | sections | critical | * | 2129 // | sections | simd | * | 2130 // | sections | sections | + | 2131 // | sections | section | * | 2132 // | sections | single | + | 2133 // | sections | parallel for | * | 2134 // | sections |parallel for simd| * | 2135 // | sections |parallel sections| * | 2136 // | sections | task | * | 2137 // | sections | taskyield | * | 2138 // | sections | barrier | + | 2139 // | sections | taskwait | * | 2140 // | sections | taskgroup | * | 2141 // | sections | flush | * | 2142 // | sections | ordered | + | 2143 // | sections | atomic | * | 2144 // | sections | target | * | 2145 // | sections | target parallel | * | 2146 // | sections | target parallel | * | 2147 // | | for | | 2148 // | sections | target enter | * | 2149 // | | data | | 2150 // | sections | target exit | * | 2151 // | | data | | 2152 // | sections | teams | + | 2153 // | sections | cancellation | | 2154 // | | point | ! | 2155 // | sections | cancel | ! | 2156 // | sections | taskloop | * | 2157 // | sections | taskloop simd | * | 2158 // | sections | distribute | | 2159 // +------------------+-----------------+------------------------------------+ 2160 // | section | parallel | * | 2161 // | section | for | + | 2162 // | section | for simd | + | 2163 // | section | master | + | 2164 // | section | critical | * | 2165 // | section | simd | * | 2166 // | section | sections | + | 2167 // | section | section | + | 2168 // | section | single | + | 2169 // | section | parallel for | * | 2170 // | section |parallel for simd| * | 2171 // | section |parallel sections| * | 2172 // | section | task | * | 2173 // | section | taskyield | * | 2174 // | section | barrier | + | 2175 // | section | taskwait | * | 2176 // | section | taskgroup | * | 2177 // | section | flush | * | 2178 // | section | ordered | + | 2179 // | section | atomic | * | 2180 // | section | target | * | 2181 // | section | target parallel | * | 2182 // | section | target parallel | * | 2183 // | | for | | 2184 // | section | target enter | * | 2185 // | | data | | 2186 // | section | target exit | * | 2187 // | | data | | 2188 // | section | teams | + | 2189 // | section | cancellation | | 2190 // | | point | ! | 2191 // | section | cancel | ! | 2192 // | section | taskloop | * | 2193 // | section | taskloop simd | * | 2194 // | section | distribute | | 2195 // +------------------+-----------------+------------------------------------+ 2196 // | single | parallel | * | 2197 // | single | for | + | 2198 // | single | for simd | + | 2199 // | single | master | + | 2200 // | single | critical | * | 2201 // | single | simd | * | 2202 // | single | sections | + | 2203 // | single | section | + | 2204 // | single | single | + | 2205 // | single | parallel for | * | 2206 // | single |parallel for simd| * | 2207 // | single |parallel sections| * | 2208 // | single | task | * | 2209 // | single | taskyield | * | 2210 // | single | barrier | + | 2211 // | single | taskwait | * | 2212 // | single | taskgroup | * | 2213 // | single | flush | * | 2214 // | single | ordered | + | 2215 // | single | atomic | * | 2216 // | single | target | * | 2217 // | single | target parallel | * | 2218 // | single | target parallel | * | 2219 // | | for | | 2220 // | single | target enter | * | 2221 // | | data | | 2222 // | single | target exit | * | 2223 // | | data | | 2224 // | single | teams | + | 2225 // | single | cancellation | | 2226 // | | point | | 2227 // | single | cancel | | 2228 // | single | taskloop | * | 2229 // | single | taskloop simd | * | 2230 // | single | distribute | | 2231 // +------------------+-----------------+------------------------------------+ 2232 // | parallel for | parallel | * | 2233 // | parallel for | for | + | 2234 // | parallel for | for simd | + | 2235 // | parallel for | master | + | 2236 // | parallel for | critical | * | 2237 // | parallel for | simd | * | 2238 // | parallel for | sections | + | 2239 // | parallel for | section | + | 2240 // | parallel for | single | + | 2241 // | parallel for | parallel for | * | 2242 // | parallel for |parallel for simd| * | 2243 // | parallel for |parallel sections| * | 2244 // | parallel for | task | * | 2245 // | parallel for | taskyield | * | 2246 // | parallel for | barrier | + | 2247 // | parallel for | taskwait | * | 2248 // | parallel for | taskgroup | * | 2249 // | parallel for | flush | * | 2250 // | parallel for | ordered | * (if construct is ordered) | 2251 // | parallel for | atomic | * | 2252 // | parallel for | target | * | 2253 // | parallel for | target parallel | * | 2254 // | parallel for | target parallel | * | 2255 // | | for | | 2256 // | parallel for | target enter | * | 2257 // | | data | | 2258 // | parallel for | target exit | * | 2259 // | | data | | 2260 // | parallel for | teams | + | 2261 // | parallel for | cancellation | | 2262 // | | point | ! | 2263 // | parallel for | cancel | ! | 2264 // | parallel for | taskloop | * | 2265 // | parallel for | taskloop simd | * | 2266 // | parallel for | distribute | | 2267 // +------------------+-----------------+------------------------------------+ 2268 // | parallel sections| parallel | * | 2269 // | parallel sections| for | + | 2270 // | parallel sections| for simd | + | 2271 // | parallel sections| master | + | 2272 // | parallel sections| critical | + | 2273 // | parallel sections| simd | * | 2274 // | parallel sections| sections | + | 2275 // | parallel sections| section | * | 2276 // | parallel sections| single | + | 2277 // | parallel sections| parallel for | * | 2278 // | parallel sections|parallel for simd| * | 2279 // | parallel sections|parallel sections| * | 2280 // | parallel sections| task | * | 2281 // | parallel sections| taskyield | * | 2282 // | parallel sections| barrier | + | 2283 // | parallel sections| taskwait | * | 2284 // | parallel sections| taskgroup | * | 2285 // | parallel sections| flush | * | 2286 // | parallel sections| ordered | + | 2287 // | parallel sections| atomic | * | 2288 // | parallel sections| target | * | 2289 // | parallel sections| target parallel | * | 2290 // | parallel sections| target parallel | * | 2291 // | | for | | 2292 // | parallel sections| target enter | * | 2293 // | | data | | 2294 // | parallel sections| target exit | * | 2295 // | | data | | 2296 // | parallel sections| teams | + | 2297 // | parallel sections| cancellation | | 2298 // | | point | ! | 2299 // | parallel sections| cancel | ! | 2300 // | parallel sections| taskloop | * | 2301 // | parallel sections| taskloop simd | * | 2302 // | parallel sections| distribute | | 2303 // +------------------+-----------------+------------------------------------+ 2304 // | task | parallel | * | 2305 // | task | for | + | 2306 // | task | for simd | + | 2307 // | task | master | + | 2308 // | task | critical | * | 2309 // | task | simd | * | 2310 // | task | sections | + | 2311 // | task | section | + | 2312 // | task | single | + | 2313 // | task | parallel for | * | 2314 // | task |parallel for simd| * | 2315 // | task |parallel sections| * | 2316 // | task | task | * | 2317 // | task | taskyield | * | 2318 // | task | barrier | + | 2319 // | task | taskwait | * | 2320 // | task | taskgroup | * | 2321 // | task | flush | * | 2322 // | task | ordered | + | 2323 // | task | atomic | * | 2324 // | task | target | * | 2325 // | task | target parallel | * | 2326 // | task | target parallel | * | 2327 // | | for | | 2328 // | task | target enter | * | 2329 // | | data | | 2330 // | task | target exit | * | 2331 // | | data | | 2332 // | task | teams | + | 2333 // | task | cancellation | | 2334 // | | point | ! | 2335 // | task | cancel | ! | 2336 // | task | taskloop | * | 2337 // | task | taskloop simd | * | 2338 // | task | distribute | | 2339 // +------------------+-----------------+------------------------------------+ 2340 // | ordered | parallel | * | 2341 // | ordered | for | + | 2342 // | ordered | for simd | + | 2343 // | ordered | master | * | 2344 // | ordered | critical | * | 2345 // | ordered | simd | * | 2346 // | ordered | sections | + | 2347 // | ordered | section | + | 2348 // | ordered | single | + | 2349 // | ordered | parallel for | * | 2350 // | ordered |parallel for simd| * | 2351 // | ordered |parallel sections| * | 2352 // | ordered | task | * | 2353 // | ordered | taskyield | * | 2354 // | ordered | barrier | + | 2355 // | ordered | taskwait | * | 2356 // | ordered | taskgroup | * | 2357 // | ordered | flush | * | 2358 // | ordered | ordered | + | 2359 // | ordered | atomic | * | 2360 // | ordered | target | * | 2361 // | ordered | target parallel | * | 2362 // | ordered | target parallel | * | 2363 // | | for | | 2364 // | ordered | target enter | * | 2365 // | | data | | 2366 // | ordered | target exit | * | 2367 // | | data | | 2368 // | ordered | teams | + | 2369 // | ordered | cancellation | | 2370 // | | point | | 2371 // | ordered | cancel | | 2372 // | ordered | taskloop | * | 2373 // | ordered | taskloop simd | * | 2374 // | ordered | distribute | | 2375 // +------------------+-----------------+------------------------------------+ 2376 // | atomic | parallel | | 2377 // | atomic | for | | 2378 // | atomic | for simd | | 2379 // | atomic | master | | 2380 // | atomic | critical | | 2381 // | atomic | simd | | 2382 // | atomic | sections | | 2383 // | atomic | section | | 2384 // | atomic | single | | 2385 // | atomic | parallel for | | 2386 // | atomic |parallel for simd| | 2387 // | atomic |parallel sections| | 2388 // | atomic | task | | 2389 // | atomic | taskyield | | 2390 // | atomic | barrier | | 2391 // | atomic | taskwait | | 2392 // | atomic | taskgroup | | 2393 // | atomic | flush | | 2394 // | atomic | ordered | | 2395 // | atomic | atomic | | 2396 // | atomic | target | | 2397 // | atomic | target parallel | | 2398 // | atomic | target parallel | | 2399 // | | for | | 2400 // | atomic | target enter | | 2401 // | | data | | 2402 // | atomic | target exit | | 2403 // | | data | | 2404 // | atomic | teams | | 2405 // | atomic | cancellation | | 2406 // | | point | | 2407 // | atomic | cancel | | 2408 // | atomic | taskloop | | 2409 // | atomic | taskloop simd | | 2410 // | atomic | distribute | | 2411 // +------------------+-----------------+------------------------------------+ 2412 // | target | parallel | * | 2413 // | target | for | * | 2414 // | target | for simd | * | 2415 // | target | master | * | 2416 // | target | critical | * | 2417 // | target | simd | * | 2418 // | target | sections | * | 2419 // | target | section | * | 2420 // | target | single | * | 2421 // | target | parallel for | * | 2422 // | target |parallel for simd| * | 2423 // | target |parallel sections| * | 2424 // | target | task | * | 2425 // | target | taskyield | * | 2426 // | target | barrier | * | 2427 // | target | taskwait | * | 2428 // | target | taskgroup | * | 2429 // | target | flush | * | 2430 // | target | ordered | * | 2431 // | target | atomic | * | 2432 // | target | target | | 2433 // | target | target parallel | | 2434 // | target | target parallel | | 2435 // | | for | | 2436 // | target | target enter | | 2437 // | | data | | 2438 // | target | target exit | | 2439 // | | data | | 2440 // | target | teams | * | 2441 // | target | cancellation | | 2442 // | | point | | 2443 // | target | cancel | | 2444 // | target | taskloop | * | 2445 // | target | taskloop simd | * | 2446 // | target | distribute | | 2447 // +------------------+-----------------+------------------------------------+ 2448 // | target parallel | parallel | * | 2449 // | target parallel | for | * | 2450 // | target parallel | for simd | * | 2451 // | target parallel | master | * | 2452 // | target parallel | critical | * | 2453 // | target parallel | simd | * | 2454 // | target parallel | sections | * | 2455 // | target parallel | section | * | 2456 // | target parallel | single | * | 2457 // | target parallel | parallel for | * | 2458 // | target parallel |parallel for simd| * | 2459 // | target parallel |parallel sections| * | 2460 // | target parallel | task | * | 2461 // | target parallel | taskyield | * | 2462 // | target parallel | barrier | * | 2463 // | target parallel | taskwait | * | 2464 // | target parallel | taskgroup | * | 2465 // | target parallel | flush | * | 2466 // | target parallel | ordered | * | 2467 // | target parallel | atomic | * | 2468 // | target parallel | target | | 2469 // | target parallel | target parallel | | 2470 // | target parallel | target parallel | | 2471 // | | for | | 2472 // | target parallel | target enter | | 2473 // | | data | | 2474 // | target parallel | target exit | | 2475 // | | data | | 2476 // | target parallel | teams | | 2477 // | target parallel | cancellation | | 2478 // | | point | ! | 2479 // | target parallel | cancel | ! | 2480 // | target parallel | taskloop | * | 2481 // | target parallel | taskloop simd | * | 2482 // | target parallel | distribute | | 2483 // +------------------+-----------------+------------------------------------+ 2484 // | target parallel | parallel | * | 2485 // | for | | | 2486 // | target parallel | for | * | 2487 // | for | | | 2488 // | target parallel | for simd | * | 2489 // | for | | | 2490 // | target parallel | master | * | 2491 // | for | | | 2492 // | target parallel | critical | * | 2493 // | for | | | 2494 // | target parallel | simd | * | 2495 // | for | | | 2496 // | target parallel | sections | * | 2497 // | for | | | 2498 // | target parallel | section | * | 2499 // | for | | | 2500 // | target parallel | single | * | 2501 // | for | | | 2502 // | target parallel | parallel for | * | 2503 // | for | | | 2504 // | target parallel |parallel for simd| * | 2505 // | for | | | 2506 // | target parallel |parallel sections| * | 2507 // | for | | | 2508 // | target parallel | task | * | 2509 // | for | | | 2510 // | target parallel | taskyield | * | 2511 // | for | | | 2512 // | target parallel | barrier | * | 2513 // | for | | | 2514 // | target parallel | taskwait | * | 2515 // | for | | | 2516 // | target parallel | taskgroup | * | 2517 // | for | | | 2518 // | target parallel | flush | * | 2519 // | for | | | 2520 // | target parallel | ordered | * | 2521 // | for | | | 2522 // | target parallel | atomic | * | 2523 // | for | | | 2524 // | target parallel | target | | 2525 // | for | | | 2526 // | target parallel | target parallel | | 2527 // | for | | | 2528 // | target parallel | target parallel | | 2529 // | for | for | | 2530 // | target parallel | target enter | | 2531 // | for | data | | 2532 // | target parallel | target exit | | 2533 // | for | data | | 2534 // | target parallel | teams | | 2535 // | for | | | 2536 // | target parallel | cancellation | | 2537 // | for | point | ! | 2538 // | target parallel | cancel | ! | 2539 // | for | | | 2540 // | target parallel | taskloop | * | 2541 // | for | | | 2542 // | target parallel | taskloop simd | * | 2543 // | for | | | 2544 // | target parallel | distribute | | 2545 // | for | | | 2546 // +------------------+-----------------+------------------------------------+ 2547 // | teams | parallel | * | 2548 // | teams | for | + | 2549 // | teams | for simd | + | 2550 // | teams | master | + | 2551 // | teams | critical | + | 2552 // | teams | simd | + | 2553 // | teams | sections | + | 2554 // | teams | section | + | 2555 // | teams | single | + | 2556 // | teams | parallel for | * | 2557 // | teams |parallel for simd| * | 2558 // | teams |parallel sections| * | 2559 // | teams | task | + | 2560 // | teams | taskyield | + | 2561 // | teams | barrier | + | 2562 // | teams | taskwait | + | 2563 // | teams | taskgroup | + | 2564 // | teams | flush | + | 2565 // | teams | ordered | + | 2566 // | teams | atomic | + | 2567 // | teams | target | + | 2568 // | teams | target parallel | + | 2569 // | teams | target parallel | + | 2570 // | | for | | 2571 // | teams | target enter | + | 2572 // | | data | | 2573 // | teams | target exit | + | 2574 // | | data | | 2575 // | teams | teams | + | 2576 // | teams | cancellation | | 2577 // | | point | | 2578 // | teams | cancel | | 2579 // | teams | taskloop | + | 2580 // | teams | taskloop simd | + | 2581 // | teams | distribute | ! | 2582 // +------------------+-----------------+------------------------------------+ 2583 // | taskloop | parallel | * | 2584 // | taskloop | for | + | 2585 // | taskloop | for simd | + | 2586 // | taskloop | master | + | 2587 // | taskloop | critical | * | 2588 // | taskloop | simd | * | 2589 // | taskloop | sections | + | 2590 // | taskloop | section | + | 2591 // | taskloop | single | + | 2592 // | taskloop | parallel for | * | 2593 // | taskloop |parallel for simd| * | 2594 // | taskloop |parallel sections| * | 2595 // | taskloop | task | * | 2596 // | taskloop | taskyield | * | 2597 // | taskloop | barrier | + | 2598 // | taskloop | taskwait | * | 2599 // | taskloop | taskgroup | * | 2600 // | taskloop | flush | * | 2601 // | taskloop | ordered | + | 2602 // | taskloop | atomic | * | 2603 // | taskloop | target | * | 2604 // | taskloop | target parallel | * | 2605 // | taskloop | target parallel | * | 2606 // | | for | | 2607 // | taskloop | target enter | * | 2608 // | | data | | 2609 // | taskloop | target exit | * | 2610 // | | data | | 2611 // | taskloop | teams | + | 2612 // | taskloop | cancellation | | 2613 // | | point | | 2614 // | taskloop | cancel | | 2615 // | taskloop | taskloop | * | 2616 // | taskloop | distribute | | 2617 // +------------------+-----------------+------------------------------------+ 2618 // | taskloop simd | parallel | | 2619 // | taskloop simd | for | | 2620 // | taskloop simd | for simd | | 2621 // | taskloop simd | master | | 2622 // | taskloop simd | critical | | 2623 // | taskloop simd | simd | * | 2624 // | taskloop simd | sections | | 2625 // | taskloop simd | section | | 2626 // | taskloop simd | single | | 2627 // | taskloop simd | parallel for | | 2628 // | taskloop simd |parallel for simd| | 2629 // | taskloop simd |parallel sections| | 2630 // | taskloop simd | task | | 2631 // | taskloop simd | taskyield | | 2632 // | taskloop simd | barrier | | 2633 // | taskloop simd | taskwait | | 2634 // | taskloop simd | taskgroup | | 2635 // | taskloop simd | flush | | 2636 // | taskloop simd | ordered | + (with simd clause) | 2637 // | taskloop simd | atomic | | 2638 // | taskloop simd | target | | 2639 // | taskloop simd | target parallel | | 2640 // | taskloop simd | target parallel | | 2641 // | | for | | 2642 // | taskloop simd | target enter | | 2643 // | | data | | 2644 // | taskloop simd | target exit | | 2645 // | | data | | 2646 // | taskloop simd | teams | | 2647 // | taskloop simd | cancellation | | 2648 // | | point | | 2649 // | taskloop simd | cancel | | 2650 // | taskloop simd | taskloop | | 2651 // | taskloop simd | taskloop simd | | 2652 // | taskloop simd | distribute | | 2653 // +------------------+-----------------+------------------------------------+ 2654 // | distribute | parallel | * | 2655 // | distribute | for | * | 2656 // | distribute | for simd | * | 2657 // | distribute | master | * | 2658 // | distribute | critical | * | 2659 // | distribute | simd | * | 2660 // | distribute | sections | * | 2661 // | distribute | section | * | 2662 // | distribute | single | * | 2663 // | distribute | parallel for | * | 2664 // | distribute |parallel for simd| * | 2665 // | distribute |parallel sections| * | 2666 // | distribute | task | * | 2667 // | distribute | taskyield | * | 2668 // | distribute | barrier | * | 2669 // | distribute | taskwait | * | 2670 // | distribute | taskgroup | * | 2671 // | distribute | flush | * | 2672 // | distribute | ordered | + | 2673 // | distribute | atomic | * | 2674 // | distribute | target | | 2675 // | distribute | target parallel | | 2676 // | distribute | target parallel | | 2677 // | | for | | 2678 // | distribute | target enter | | 2679 // | | data | | 2680 // | distribute | target exit | | 2681 // | | data | | 2682 // | distribute | teams | | 2683 // | distribute | cancellation | + | 2684 // | | point | | 2685 // | distribute | cancel | + | 2686 // | distribute | taskloop | * | 2687 // | distribute | taskloop simd | * | 2688 // | distribute | distribute | | 2689 // +------------------+-----------------+------------------------------------+ 2690 if (Stack->getCurScope()) { 2691 auto ParentRegion = Stack->getParentDirective(); 2692 auto OffendingRegion = ParentRegion; 2693 bool NestingProhibited = false; 2694 bool CloseNesting = true; 2695 enum { 2696 NoRecommend, 2697 ShouldBeInParallelRegion, 2698 ShouldBeInOrderedRegion, 2699 ShouldBeInTargetRegion, 2700 ShouldBeInTeamsRegion 2701 } Recommend = NoRecommend; 2702 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered && 2703 CurrentRegion != OMPD_simd) { 2704 // OpenMP [2.16, Nesting of Regions] 2705 // OpenMP constructs may not be nested inside a simd region. 2706 // OpenMP [2.8.1,simd Construct, Restrictions] 2707 // An ordered construct with the simd clause is the only OpenMP construct 2708 // that can appear in the simd region. 2709 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd); 2710 return true; 2711 } 2712 if (ParentRegion == OMPD_atomic) { 2713 // OpenMP [2.16, Nesting of Regions] 2714 // OpenMP constructs may not be nested inside an atomic region. 2715 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 2716 return true; 2717 } 2718 if (CurrentRegion == OMPD_section) { 2719 // OpenMP [2.7.2, sections Construct, Restrictions] 2720 // Orphaned section directives are prohibited. That is, the section 2721 // directives must appear within the sections construct and must not be 2722 // encountered elsewhere in the sections region. 2723 if (ParentRegion != OMPD_sections && 2724 ParentRegion != OMPD_parallel_sections) { 2725 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 2726 << (ParentRegion != OMPD_unknown) 2727 << getOpenMPDirectiveName(ParentRegion); 2728 return true; 2729 } 2730 return false; 2731 } 2732 // Allow some constructs to be orphaned (they could be used in functions, 2733 // called from OpenMP regions with the required preconditions). 2734 if (ParentRegion == OMPD_unknown) 2735 return false; 2736 if (CurrentRegion == OMPD_cancellation_point || 2737 CurrentRegion == OMPD_cancel) { 2738 // OpenMP [2.16, Nesting of Regions] 2739 // A cancellation point construct for which construct-type-clause is 2740 // taskgroup must be nested inside a task construct. A cancellation 2741 // point construct for which construct-type-clause is not taskgroup must 2742 // be closely nested inside an OpenMP construct that matches the type 2743 // specified in construct-type-clause. 2744 // A cancel construct for which construct-type-clause is taskgroup must be 2745 // nested inside a task construct. A cancel construct for which 2746 // construct-type-clause is not taskgroup must be closely nested inside an 2747 // OpenMP construct that matches the type specified in 2748 // construct-type-clause. 2749 NestingProhibited = 2750 !((CancelRegion == OMPD_parallel && 2751 (ParentRegion == OMPD_parallel || 2752 ParentRegion == OMPD_target_parallel)) || 2753 (CancelRegion == OMPD_for && 2754 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 2755 ParentRegion == OMPD_target_parallel_for)) || 2756 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 2757 (CancelRegion == OMPD_sections && 2758 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 2759 ParentRegion == OMPD_parallel_sections))); 2760 } else if (CurrentRegion == OMPD_master) { 2761 // OpenMP [2.16, Nesting of Regions] 2762 // A master region may not be closely nested inside a worksharing, 2763 // atomic, or explicit task region. 2764 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2765 isOpenMPTaskingDirective(ParentRegion); 2766 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 2767 // OpenMP [2.16, Nesting of Regions] 2768 // A critical region may not be nested (closely or otherwise) inside a 2769 // critical region with the same name. Note that this restriction is not 2770 // sufficient to prevent deadlock. 2771 SourceLocation PreviousCriticalLoc; 2772 bool DeadLock = 2773 Stack->hasDirective([CurrentName, &PreviousCriticalLoc]( 2774 OpenMPDirectiveKind K, 2775 const DeclarationNameInfo &DNI, 2776 SourceLocation Loc) 2777 ->bool { 2778 if (K == OMPD_critical && 2779 DNI.getName() == CurrentName.getName()) { 2780 PreviousCriticalLoc = Loc; 2781 return true; 2782 } else 2783 return false; 2784 }, 2785 false /* skip top directive */); 2786 if (DeadLock) { 2787 SemaRef.Diag(StartLoc, 2788 diag::err_omp_prohibited_region_critical_same_name) 2789 << CurrentName.getName(); 2790 if (PreviousCriticalLoc.isValid()) 2791 SemaRef.Diag(PreviousCriticalLoc, 2792 diag::note_omp_previous_critical_region); 2793 return true; 2794 } 2795 } else if (CurrentRegion == OMPD_barrier) { 2796 // OpenMP [2.16, Nesting of Regions] 2797 // A barrier region may not be closely nested inside a worksharing, 2798 // explicit task, critical, ordered, atomic, or master region. 2799 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2800 isOpenMPTaskingDirective(ParentRegion) || 2801 ParentRegion == OMPD_master || 2802 ParentRegion == OMPD_critical || 2803 ParentRegion == OMPD_ordered; 2804 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 2805 !isOpenMPParallelDirective(CurrentRegion)) { 2806 // OpenMP [2.16, Nesting of Regions] 2807 // A worksharing region may not be closely nested inside a worksharing, 2808 // explicit task, critical, ordered, atomic, or master region. 2809 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2810 isOpenMPTaskingDirective(ParentRegion) || 2811 ParentRegion == OMPD_master || 2812 ParentRegion == OMPD_critical || 2813 ParentRegion == OMPD_ordered; 2814 Recommend = ShouldBeInParallelRegion; 2815 } else if (CurrentRegion == OMPD_ordered) { 2816 // OpenMP [2.16, Nesting of Regions] 2817 // An ordered region may not be closely nested inside a critical, 2818 // atomic, or explicit task region. 2819 // An ordered region must be closely nested inside a loop region (or 2820 // parallel loop region) with an ordered clause. 2821 // OpenMP [2.8.1,simd Construct, Restrictions] 2822 // An ordered construct with the simd clause is the only OpenMP construct 2823 // that can appear in the simd region. 2824 NestingProhibited = ParentRegion == OMPD_critical || 2825 isOpenMPTaskingDirective(ParentRegion) || 2826 !(isOpenMPSimdDirective(ParentRegion) || 2827 Stack->isParentOrderedRegion()); 2828 Recommend = ShouldBeInOrderedRegion; 2829 } else if (isOpenMPTeamsDirective(CurrentRegion)) { 2830 // OpenMP [2.16, Nesting of Regions] 2831 // If specified, a teams construct must be contained within a target 2832 // construct. 2833 NestingProhibited = ParentRegion != OMPD_target; 2834 Recommend = ShouldBeInTargetRegion; 2835 Stack->setParentTeamsRegionLoc(Stack->getConstructLoc()); 2836 } 2837 if (!NestingProhibited && isOpenMPTeamsDirective(ParentRegion)) { 2838 // OpenMP [2.16, Nesting of Regions] 2839 // distribute, parallel, parallel sections, parallel workshare, and the 2840 // parallel loop and parallel loop SIMD constructs are the only OpenMP 2841 // constructs that can be closely nested in the teams region. 2842 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 2843 !isOpenMPDistributeDirective(CurrentRegion); 2844 Recommend = ShouldBeInParallelRegion; 2845 } 2846 if (!NestingProhibited && isOpenMPDistributeDirective(CurrentRegion)) { 2847 // OpenMP 4.5 [2.17 Nesting of Regions] 2848 // The region associated with the distribute construct must be strictly 2849 // nested inside a teams region 2850 NestingProhibited = !isOpenMPTeamsDirective(ParentRegion); 2851 Recommend = ShouldBeInTeamsRegion; 2852 } 2853 if (!NestingProhibited && 2854 (isOpenMPTargetExecutionDirective(CurrentRegion) || 2855 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 2856 // OpenMP 4.5 [2.17 Nesting of Regions] 2857 // If a target, target update, target data, target enter data, or 2858 // target exit data construct is encountered during execution of a 2859 // target region, the behavior is unspecified. 2860 NestingProhibited = Stack->hasDirective( 2861 [&OffendingRegion](OpenMPDirectiveKind K, 2862 const DeclarationNameInfo &DNI, 2863 SourceLocation Loc) -> bool { 2864 if (isOpenMPTargetExecutionDirective(K)) { 2865 OffendingRegion = K; 2866 return true; 2867 } else 2868 return false; 2869 }, 2870 false /* don't skip top directive */); 2871 CloseNesting = false; 2872 } 2873 if (NestingProhibited) { 2874 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 2875 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 2876 << Recommend << getOpenMPDirectiveName(CurrentRegion); 2877 return true; 2878 } 2879 } 2880 return false; 2881 } 2882 2883 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 2884 ArrayRef<OMPClause *> Clauses, 2885 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 2886 bool ErrorFound = false; 2887 unsigned NamedModifiersNumber = 0; 2888 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 2889 OMPD_unknown + 1); 2890 SmallVector<SourceLocation, 4> NameModifierLoc; 2891 for (const auto *C : Clauses) { 2892 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 2893 // At most one if clause without a directive-name-modifier can appear on 2894 // the directive. 2895 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 2896 if (FoundNameModifiers[CurNM]) { 2897 S.Diag(C->getLocStart(), diag::err_omp_more_one_clause) 2898 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 2899 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 2900 ErrorFound = true; 2901 } else if (CurNM != OMPD_unknown) { 2902 NameModifierLoc.push_back(IC->getNameModifierLoc()); 2903 ++NamedModifiersNumber; 2904 } 2905 FoundNameModifiers[CurNM] = IC; 2906 if (CurNM == OMPD_unknown) 2907 continue; 2908 // Check if the specified name modifier is allowed for the current 2909 // directive. 2910 // At most one if clause with the particular directive-name-modifier can 2911 // appear on the directive. 2912 bool MatchFound = false; 2913 for (auto NM : AllowedNameModifiers) { 2914 if (CurNM == NM) { 2915 MatchFound = true; 2916 break; 2917 } 2918 } 2919 if (!MatchFound) { 2920 S.Diag(IC->getNameModifierLoc(), 2921 diag::err_omp_wrong_if_directive_name_modifier) 2922 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 2923 ErrorFound = true; 2924 } 2925 } 2926 } 2927 // If any if clause on the directive includes a directive-name-modifier then 2928 // all if clauses on the directive must include a directive-name-modifier. 2929 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 2930 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 2931 S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(), 2932 diag::err_omp_no_more_if_clause); 2933 } else { 2934 std::string Values; 2935 std::string Sep(", "); 2936 unsigned AllowedCnt = 0; 2937 unsigned TotalAllowedNum = 2938 AllowedNameModifiers.size() - NamedModifiersNumber; 2939 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 2940 ++Cnt) { 2941 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 2942 if (!FoundNameModifiers[NM]) { 2943 Values += "'"; 2944 Values += getOpenMPDirectiveName(NM); 2945 Values += "'"; 2946 if (AllowedCnt + 2 == TotalAllowedNum) 2947 Values += " or "; 2948 else if (AllowedCnt + 1 != TotalAllowedNum) 2949 Values += Sep; 2950 ++AllowedCnt; 2951 } 2952 } 2953 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(), 2954 diag::err_omp_unnamed_if_clause) 2955 << (TotalAllowedNum > 1) << Values; 2956 } 2957 for (auto Loc : NameModifierLoc) { 2958 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 2959 } 2960 ErrorFound = true; 2961 } 2962 return ErrorFound; 2963 } 2964 2965 StmtResult Sema::ActOnOpenMPExecutableDirective( 2966 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 2967 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 2968 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 2969 StmtResult Res = StmtError(); 2970 if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 2971 StartLoc)) 2972 return StmtError(); 2973 2974 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 2975 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 2976 bool ErrorFound = false; 2977 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 2978 if (AStmt) { 2979 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 2980 2981 // Check default data sharing attributes for referenced variables. 2982 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 2983 DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt()); 2984 if (DSAChecker.isErrorFound()) 2985 return StmtError(); 2986 // Generate list of implicitly defined firstprivate variables. 2987 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 2988 2989 if (!DSAChecker.getImplicitFirstprivate().empty()) { 2990 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 2991 DSAChecker.getImplicitFirstprivate(), SourceLocation(), 2992 SourceLocation(), SourceLocation())) { 2993 ClausesWithImplicit.push_back(Implicit); 2994 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 2995 DSAChecker.getImplicitFirstprivate().size(); 2996 } else 2997 ErrorFound = true; 2998 } 2999 } 3000 3001 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 3002 switch (Kind) { 3003 case OMPD_parallel: 3004 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 3005 EndLoc); 3006 AllowedNameModifiers.push_back(OMPD_parallel); 3007 break; 3008 case OMPD_simd: 3009 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3010 VarsWithInheritedDSA); 3011 break; 3012 case OMPD_for: 3013 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3014 VarsWithInheritedDSA); 3015 break; 3016 case OMPD_for_simd: 3017 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3018 EndLoc, VarsWithInheritedDSA); 3019 break; 3020 case OMPD_sections: 3021 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 3022 EndLoc); 3023 break; 3024 case OMPD_section: 3025 assert(ClausesWithImplicit.empty() && 3026 "No clauses are allowed for 'omp section' directive"); 3027 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 3028 break; 3029 case OMPD_single: 3030 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 3031 EndLoc); 3032 break; 3033 case OMPD_master: 3034 assert(ClausesWithImplicit.empty() && 3035 "No clauses are allowed for 'omp master' directive"); 3036 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 3037 break; 3038 case OMPD_critical: 3039 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 3040 StartLoc, EndLoc); 3041 break; 3042 case OMPD_parallel_for: 3043 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 3044 EndLoc, VarsWithInheritedDSA); 3045 AllowedNameModifiers.push_back(OMPD_parallel); 3046 break; 3047 case OMPD_parallel_for_simd: 3048 Res = ActOnOpenMPParallelForSimdDirective( 3049 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3050 AllowedNameModifiers.push_back(OMPD_parallel); 3051 break; 3052 case OMPD_parallel_sections: 3053 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 3054 StartLoc, EndLoc); 3055 AllowedNameModifiers.push_back(OMPD_parallel); 3056 break; 3057 case OMPD_task: 3058 Res = 3059 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3060 AllowedNameModifiers.push_back(OMPD_task); 3061 break; 3062 case OMPD_taskyield: 3063 assert(ClausesWithImplicit.empty() && 3064 "No clauses are allowed for 'omp taskyield' directive"); 3065 assert(AStmt == nullptr && 3066 "No associated statement allowed for 'omp taskyield' directive"); 3067 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 3068 break; 3069 case OMPD_barrier: 3070 assert(ClausesWithImplicit.empty() && 3071 "No clauses are allowed for 'omp barrier' directive"); 3072 assert(AStmt == nullptr && 3073 "No associated statement allowed for 'omp barrier' directive"); 3074 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 3075 break; 3076 case OMPD_taskwait: 3077 assert(ClausesWithImplicit.empty() && 3078 "No clauses are allowed for 'omp taskwait' directive"); 3079 assert(AStmt == nullptr && 3080 "No associated statement allowed for 'omp taskwait' directive"); 3081 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 3082 break; 3083 case OMPD_taskgroup: 3084 assert(ClausesWithImplicit.empty() && 3085 "No clauses are allowed for 'omp taskgroup' directive"); 3086 Res = ActOnOpenMPTaskgroupDirective(AStmt, StartLoc, EndLoc); 3087 break; 3088 case OMPD_flush: 3089 assert(AStmt == nullptr && 3090 "No associated statement allowed for 'omp flush' directive"); 3091 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 3092 break; 3093 case OMPD_ordered: 3094 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 3095 EndLoc); 3096 break; 3097 case OMPD_atomic: 3098 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 3099 EndLoc); 3100 break; 3101 case OMPD_teams: 3102 Res = 3103 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3104 break; 3105 case OMPD_target: 3106 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 3107 EndLoc); 3108 AllowedNameModifiers.push_back(OMPD_target); 3109 break; 3110 case OMPD_target_parallel: 3111 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 3112 StartLoc, EndLoc); 3113 AllowedNameModifiers.push_back(OMPD_target); 3114 AllowedNameModifiers.push_back(OMPD_parallel); 3115 break; 3116 case OMPD_target_parallel_for: 3117 Res = ActOnOpenMPTargetParallelForDirective( 3118 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3119 AllowedNameModifiers.push_back(OMPD_target); 3120 AllowedNameModifiers.push_back(OMPD_parallel); 3121 break; 3122 case OMPD_cancellation_point: 3123 assert(ClausesWithImplicit.empty() && 3124 "No clauses are allowed for 'omp cancellation point' directive"); 3125 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 3126 "cancellation point' directive"); 3127 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 3128 break; 3129 case OMPD_cancel: 3130 assert(AStmt == nullptr && 3131 "No associated statement allowed for 'omp cancel' directive"); 3132 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 3133 CancelRegion); 3134 AllowedNameModifiers.push_back(OMPD_cancel); 3135 break; 3136 case OMPD_target_data: 3137 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 3138 EndLoc); 3139 AllowedNameModifiers.push_back(OMPD_target_data); 3140 break; 3141 case OMPD_target_enter_data: 3142 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 3143 EndLoc); 3144 AllowedNameModifiers.push_back(OMPD_target_enter_data); 3145 break; 3146 case OMPD_target_exit_data: 3147 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 3148 EndLoc); 3149 AllowedNameModifiers.push_back(OMPD_target_exit_data); 3150 break; 3151 case OMPD_taskloop: 3152 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 3153 EndLoc, VarsWithInheritedDSA); 3154 AllowedNameModifiers.push_back(OMPD_taskloop); 3155 break; 3156 case OMPD_taskloop_simd: 3157 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3158 EndLoc, VarsWithInheritedDSA); 3159 AllowedNameModifiers.push_back(OMPD_taskloop); 3160 break; 3161 case OMPD_distribute: 3162 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 3163 EndLoc, VarsWithInheritedDSA); 3164 break; 3165 case OMPD_declare_target: 3166 case OMPD_end_declare_target: 3167 case OMPD_threadprivate: 3168 case OMPD_declare_reduction: 3169 case OMPD_declare_simd: 3170 llvm_unreachable("OpenMP Directive is not allowed"); 3171 case OMPD_unknown: 3172 llvm_unreachable("Unknown OpenMP directive"); 3173 } 3174 3175 for (auto P : VarsWithInheritedDSA) { 3176 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 3177 << P.first << P.second->getSourceRange(); 3178 } 3179 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 3180 3181 if (!AllowedNameModifiers.empty()) 3182 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 3183 ErrorFound; 3184 3185 if (ErrorFound) 3186 return StmtError(); 3187 return Res; 3188 } 3189 3190 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 3191 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 3192 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 3193 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 3194 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 3195 assert(Aligneds.size() == Alignments.size()); 3196 assert(Linears.size() == LinModifiers.size()); 3197 assert(Linears.size() == Steps.size()); 3198 if (!DG || DG.get().isNull()) 3199 return DeclGroupPtrTy(); 3200 3201 if (!DG.get().isSingleDecl()) { 3202 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 3203 return DG; 3204 } 3205 auto *ADecl = DG.get().getSingleDecl(); 3206 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 3207 ADecl = FTD->getTemplatedDecl(); 3208 3209 auto *FD = dyn_cast<FunctionDecl>(ADecl); 3210 if (!FD) { 3211 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 3212 return DeclGroupPtrTy(); 3213 } 3214 3215 // OpenMP [2.8.2, declare simd construct, Description] 3216 // The parameter of the simdlen clause must be a constant positive integer 3217 // expression. 3218 ExprResult SL; 3219 if (Simdlen) 3220 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 3221 // OpenMP [2.8.2, declare simd construct, Description] 3222 // The special this pointer can be used as if was one of the arguments to the 3223 // function in any of the linear, aligned, or uniform clauses. 3224 // The uniform clause declares one or more arguments to have an invariant 3225 // value for all concurrent invocations of the function in the execution of a 3226 // single SIMD loop. 3227 llvm::DenseMap<Decl *, Expr *> UniformedArgs; 3228 Expr *UniformedLinearThis = nullptr; 3229 for (auto *E : Uniforms) { 3230 E = E->IgnoreParenImpCasts(); 3231 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3232 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 3233 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3234 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3235 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 3236 UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E)); 3237 continue; 3238 } 3239 if (isa<CXXThisExpr>(E)) { 3240 UniformedLinearThis = E; 3241 continue; 3242 } 3243 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3244 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3245 } 3246 // OpenMP [2.8.2, declare simd construct, Description] 3247 // The aligned clause declares that the object to which each list item points 3248 // is aligned to the number of bytes expressed in the optional parameter of 3249 // the aligned clause. 3250 // The special this pointer can be used as if was one of the arguments to the 3251 // function in any of the linear, aligned, or uniform clauses. 3252 // The type of list items appearing in the aligned clause must be array, 3253 // pointer, reference to array, or reference to pointer. 3254 llvm::DenseMap<Decl *, Expr *> AlignedArgs; 3255 Expr *AlignedThis = nullptr; 3256 for (auto *E : Aligneds) { 3257 E = E->IgnoreParenImpCasts(); 3258 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3259 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3260 auto *CanonPVD = PVD->getCanonicalDecl(); 3261 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3262 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3263 ->getCanonicalDecl() == CanonPVD) { 3264 // OpenMP [2.8.1, simd construct, Restrictions] 3265 // A list-item cannot appear in more than one aligned clause. 3266 if (AlignedArgs.count(CanonPVD) > 0) { 3267 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3268 << 1 << E->getSourceRange(); 3269 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 3270 diag::note_omp_explicit_dsa) 3271 << getOpenMPClauseName(OMPC_aligned); 3272 continue; 3273 } 3274 AlignedArgs[CanonPVD] = E; 3275 QualType QTy = PVD->getType() 3276 .getNonReferenceType() 3277 .getUnqualifiedType() 3278 .getCanonicalType(); 3279 const Type *Ty = QTy.getTypePtrOrNull(); 3280 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 3281 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 3282 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 3283 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 3284 } 3285 continue; 3286 } 3287 } 3288 if (isa<CXXThisExpr>(E)) { 3289 if (AlignedThis) { 3290 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3291 << 2 << E->getSourceRange(); 3292 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 3293 << getOpenMPClauseName(OMPC_aligned); 3294 } 3295 AlignedThis = E; 3296 continue; 3297 } 3298 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3299 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3300 } 3301 // The optional parameter of the aligned clause, alignment, must be a constant 3302 // positive integer expression. If no optional parameter is specified, 3303 // implementation-defined default alignments for SIMD instructions on the 3304 // target platforms are assumed. 3305 SmallVector<Expr *, 4> NewAligns; 3306 for (auto *E : Alignments) { 3307 ExprResult Align; 3308 if (E) 3309 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 3310 NewAligns.push_back(Align.get()); 3311 } 3312 // OpenMP [2.8.2, declare simd construct, Description] 3313 // The linear clause declares one or more list items to be private to a SIMD 3314 // lane and to have a linear relationship with respect to the iteration space 3315 // of a loop. 3316 // The special this pointer can be used as if was one of the arguments to the 3317 // function in any of the linear, aligned, or uniform clauses. 3318 // When a linear-step expression is specified in a linear clause it must be 3319 // either a constant integer expression or an integer-typed parameter that is 3320 // specified in a uniform clause on the directive. 3321 llvm::DenseMap<Decl *, Expr *> LinearArgs; 3322 const bool IsUniformedThis = UniformedLinearThis != nullptr; 3323 auto MI = LinModifiers.begin(); 3324 for (auto *E : Linears) { 3325 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 3326 ++MI; 3327 E = E->IgnoreParenImpCasts(); 3328 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3329 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3330 auto *CanonPVD = PVD->getCanonicalDecl(); 3331 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3332 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3333 ->getCanonicalDecl() == CanonPVD) { 3334 // OpenMP [2.15.3.7, linear Clause, Restrictions] 3335 // A list-item cannot appear in more than one linear clause. 3336 if (LinearArgs.count(CanonPVD) > 0) { 3337 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3338 << getOpenMPClauseName(OMPC_linear) 3339 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 3340 Diag(LinearArgs[CanonPVD]->getExprLoc(), 3341 diag::note_omp_explicit_dsa) 3342 << getOpenMPClauseName(OMPC_linear); 3343 continue; 3344 } 3345 // Each argument can appear in at most one uniform or linear clause. 3346 if (UniformedArgs.count(CanonPVD) > 0) { 3347 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3348 << getOpenMPClauseName(OMPC_linear) 3349 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 3350 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 3351 diag::note_omp_explicit_dsa) 3352 << getOpenMPClauseName(OMPC_uniform); 3353 continue; 3354 } 3355 LinearArgs[CanonPVD] = E; 3356 if (E->isValueDependent() || E->isTypeDependent() || 3357 E->isInstantiationDependent() || 3358 E->containsUnexpandedParameterPack()) 3359 continue; 3360 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 3361 PVD->getOriginalType()); 3362 continue; 3363 } 3364 } 3365 if (isa<CXXThisExpr>(E)) { 3366 if (UniformedLinearThis) { 3367 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3368 << getOpenMPClauseName(OMPC_linear) 3369 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 3370 << E->getSourceRange(); 3371 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 3372 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 3373 : OMPC_linear); 3374 continue; 3375 } 3376 UniformedLinearThis = E; 3377 if (E->isValueDependent() || E->isTypeDependent() || 3378 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 3379 continue; 3380 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 3381 E->getType()); 3382 continue; 3383 } 3384 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3385 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3386 } 3387 Expr *Step = nullptr; 3388 Expr *NewStep = nullptr; 3389 SmallVector<Expr *, 4> NewSteps; 3390 for (auto *E : Steps) { 3391 // Skip the same step expression, it was checked already. 3392 if (Step == E || !E) { 3393 NewSteps.push_back(E ? NewStep : nullptr); 3394 continue; 3395 } 3396 Step = E; 3397 if (auto *DRE = dyn_cast<DeclRefExpr>(Step)) 3398 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3399 auto *CanonPVD = PVD->getCanonicalDecl(); 3400 if (UniformedArgs.count(CanonPVD) == 0) { 3401 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 3402 << Step->getSourceRange(); 3403 } else if (E->isValueDependent() || E->isTypeDependent() || 3404 E->isInstantiationDependent() || 3405 E->containsUnexpandedParameterPack() || 3406 CanonPVD->getType()->hasIntegerRepresentation()) 3407 NewSteps.push_back(Step); 3408 else { 3409 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 3410 << Step->getSourceRange(); 3411 } 3412 continue; 3413 } 3414 NewStep = Step; 3415 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 3416 !Step->isInstantiationDependent() && 3417 !Step->containsUnexpandedParameterPack()) { 3418 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 3419 .get(); 3420 if (NewStep) 3421 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 3422 } 3423 NewSteps.push_back(NewStep); 3424 } 3425 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 3426 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 3427 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 3428 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 3429 const_cast<Expr **>(Linears.data()), Linears.size(), 3430 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 3431 NewSteps.data(), NewSteps.size(), SR); 3432 ADecl->addAttr(NewAttr); 3433 return ConvertDeclToDeclGroup(ADecl); 3434 } 3435 3436 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 3437 Stmt *AStmt, 3438 SourceLocation StartLoc, 3439 SourceLocation EndLoc) { 3440 if (!AStmt) 3441 return StmtError(); 3442 3443 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 3444 // 1.2.2 OpenMP Language Terminology 3445 // Structured block - An executable statement with a single entry at the 3446 // top and a single exit at the bottom. 3447 // The point of exit cannot be a branch out of the structured block. 3448 // longjmp() and throw() must not violate the entry/exit criteria. 3449 CS->getCapturedDecl()->setNothrow(); 3450 3451 getCurFunction()->setHasBranchProtectedScope(); 3452 3453 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 3454 DSAStack->isCancelRegion()); 3455 } 3456 3457 namespace { 3458 /// \brief Helper class for checking canonical form of the OpenMP loops and 3459 /// extracting iteration space of each loop in the loop nest, that will be used 3460 /// for IR generation. 3461 class OpenMPIterationSpaceChecker { 3462 /// \brief Reference to Sema. 3463 Sema &SemaRef; 3464 /// \brief A location for diagnostics (when there is no some better location). 3465 SourceLocation DefaultLoc; 3466 /// \brief A location for diagnostics (when increment is not compatible). 3467 SourceLocation ConditionLoc; 3468 /// \brief A source location for referring to loop init later. 3469 SourceRange InitSrcRange; 3470 /// \brief A source location for referring to condition later. 3471 SourceRange ConditionSrcRange; 3472 /// \brief A source location for referring to increment later. 3473 SourceRange IncrementSrcRange; 3474 /// \brief Loop variable. 3475 ValueDecl *LCDecl = nullptr; 3476 /// \brief Reference to loop variable. 3477 Expr *LCRef = nullptr; 3478 /// \brief Lower bound (initializer for the var). 3479 Expr *LB = nullptr; 3480 /// \brief Upper bound. 3481 Expr *UB = nullptr; 3482 /// \brief Loop step (increment). 3483 Expr *Step = nullptr; 3484 /// \brief This flag is true when condition is one of: 3485 /// Var < UB 3486 /// Var <= UB 3487 /// UB > Var 3488 /// UB >= Var 3489 bool TestIsLessOp = false; 3490 /// \brief This flag is true when condition is strict ( < or > ). 3491 bool TestIsStrictOp = false; 3492 /// \brief This flag is true when step is subtracted on each iteration. 3493 bool SubtractStep = false; 3494 3495 public: 3496 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 3497 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 3498 /// \brief Check init-expr for canonical loop form and save loop counter 3499 /// variable - #Var and its initialization value - #LB. 3500 bool CheckInit(Stmt *S, bool EmitDiags = true); 3501 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags 3502 /// for less/greater and for strict/non-strict comparison. 3503 bool CheckCond(Expr *S); 3504 /// \brief Check incr-expr for canonical loop form and return true if it 3505 /// does not conform, otherwise save loop step (#Step). 3506 bool CheckInc(Expr *S); 3507 /// \brief Return the loop counter variable. 3508 ValueDecl *GetLoopDecl() const { return LCDecl; } 3509 /// \brief Return the reference expression to loop counter variable. 3510 Expr *GetLoopDeclRefExpr() const { return LCRef; } 3511 /// \brief Source range of the loop init. 3512 SourceRange GetInitSrcRange() const { return InitSrcRange; } 3513 /// \brief Source range of the loop condition. 3514 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; } 3515 /// \brief Source range of the loop increment. 3516 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; } 3517 /// \brief True if the step should be subtracted. 3518 bool ShouldSubtractStep() const { return SubtractStep; } 3519 /// \brief Build the expression to calculate the number of iterations. 3520 Expr * 3521 BuildNumIterations(Scope *S, const bool LimitedType, 3522 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3523 /// \brief Build the precondition expression for the loops. 3524 Expr *BuildPreCond(Scope *S, Expr *Cond, 3525 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3526 /// \brief Build reference expression to the counter be used for codegen. 3527 DeclRefExpr * 3528 BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3529 /// \brief Build reference expression to the private counter be used for 3530 /// codegen. 3531 Expr *BuildPrivateCounterVar() const; 3532 /// \brief Build initization of the counter be used for codegen. 3533 Expr *BuildCounterInit() const; 3534 /// \brief Build step of the counter be used for codegen. 3535 Expr *BuildCounterStep() const; 3536 /// \brief Return true if any expression is dependent. 3537 bool Dependent() const; 3538 3539 private: 3540 /// \brief Check the right-hand side of an assignment in the increment 3541 /// expression. 3542 bool CheckIncRHS(Expr *RHS); 3543 /// \brief Helper to set loop counter variable and its initializer. 3544 bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); 3545 /// \brief Helper to set upper bound. 3546 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR, 3547 SourceLocation SL); 3548 /// \brief Helper to set loop increment. 3549 bool SetStep(Expr *NewStep, bool Subtract); 3550 }; 3551 3552 bool OpenMPIterationSpaceChecker::Dependent() const { 3553 if (!LCDecl) { 3554 assert(!LB && !UB && !Step); 3555 return false; 3556 } 3557 return LCDecl->getType()->isDependentType() || 3558 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 3559 (Step && Step->isValueDependent()); 3560 } 3561 3562 static Expr *getExprAsWritten(Expr *E) { 3563 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) 3564 E = ExprTemp->getSubExpr(); 3565 3566 if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 3567 E = MTE->GetTemporaryExpr(); 3568 3569 while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 3570 E = Binder->getSubExpr(); 3571 3572 if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 3573 E = ICE->getSubExprAsWritten(); 3574 return E->IgnoreParens(); 3575 } 3576 3577 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl, 3578 Expr *NewLCRefExpr, 3579 Expr *NewLB) { 3580 // State consistency checking to ensure correct usage. 3581 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 3582 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3583 if (!NewLCDecl || !NewLB) 3584 return true; 3585 LCDecl = getCanonicalDecl(NewLCDecl); 3586 LCRef = NewLCRefExpr; 3587 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 3588 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3589 if ((Ctor->isCopyOrMoveConstructor() || 3590 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3591 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3592 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 3593 LB = NewLB; 3594 return false; 3595 } 3596 3597 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp, 3598 SourceRange SR, SourceLocation SL) { 3599 // State consistency checking to ensure correct usage. 3600 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 3601 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3602 if (!NewUB) 3603 return true; 3604 UB = NewUB; 3605 TestIsLessOp = LessOp; 3606 TestIsStrictOp = StrictOp; 3607 ConditionSrcRange = SR; 3608 ConditionLoc = SL; 3609 return false; 3610 } 3611 3612 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) { 3613 // State consistency checking to ensure correct usage. 3614 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 3615 if (!NewStep) 3616 return true; 3617 if (!NewStep->isValueDependent()) { 3618 // Check that the step is integer expression. 3619 SourceLocation StepLoc = NewStep->getLocStart(); 3620 ExprResult Val = 3621 SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep); 3622 if (Val.isInvalid()) 3623 return true; 3624 NewStep = Val.get(); 3625 3626 // OpenMP [2.6, Canonical Loop Form, Restrictions] 3627 // If test-expr is of form var relational-op b and relational-op is < or 3628 // <= then incr-expr must cause var to increase on each iteration of the 3629 // loop. If test-expr is of form var relational-op b and relational-op is 3630 // > or >= then incr-expr must cause var to decrease on each iteration of 3631 // the loop. 3632 // If test-expr is of form b relational-op var and relational-op is < or 3633 // <= then incr-expr must cause var to decrease on each iteration of the 3634 // loop. If test-expr is of form b relational-op var and relational-op is 3635 // > or >= then incr-expr must cause var to increase on each iteration of 3636 // the loop. 3637 llvm::APSInt Result; 3638 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 3639 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 3640 bool IsConstNeg = 3641 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 3642 bool IsConstPos = 3643 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 3644 bool IsConstZero = IsConstant && !Result.getBoolValue(); 3645 if (UB && (IsConstZero || 3646 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 3647 : (IsConstPos || (IsUnsigned && !Subtract))))) { 3648 SemaRef.Diag(NewStep->getExprLoc(), 3649 diag::err_omp_loop_incr_not_compatible) 3650 << LCDecl << TestIsLessOp << NewStep->getSourceRange(); 3651 SemaRef.Diag(ConditionLoc, 3652 diag::note_omp_loop_cond_requres_compatible_incr) 3653 << TestIsLessOp << ConditionSrcRange; 3654 return true; 3655 } 3656 if (TestIsLessOp == Subtract) { 3657 NewStep = SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, 3658 NewStep).get(); 3659 Subtract = !Subtract; 3660 } 3661 } 3662 3663 Step = NewStep; 3664 SubtractStep = Subtract; 3665 return false; 3666 } 3667 3668 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { 3669 // Check init-expr for canonical loop form and save loop counter 3670 // variable - #Var and its initialization value - #LB. 3671 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 3672 // var = lb 3673 // integer-type var = lb 3674 // random-access-iterator-type var = lb 3675 // pointer-type var = lb 3676 // 3677 if (!S) { 3678 if (EmitDiags) { 3679 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 3680 } 3681 return true; 3682 } 3683 InitSrcRange = S->getSourceRange(); 3684 if (Expr *E = dyn_cast<Expr>(S)) 3685 S = E->IgnoreParens(); 3686 if (auto BO = dyn_cast<BinaryOperator>(S)) { 3687 if (BO->getOpcode() == BO_Assign) { 3688 auto *LHS = BO->getLHS()->IgnoreParens(); 3689 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 3690 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3691 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3692 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3693 return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); 3694 } 3695 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3696 if (ME->isArrow() && 3697 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3698 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3699 } 3700 } 3701 } else if (auto DS = dyn_cast<DeclStmt>(S)) { 3702 if (DS->isSingleDecl()) { 3703 if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 3704 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 3705 // Accept non-canonical init form here but emit ext. warning. 3706 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 3707 SemaRef.Diag(S->getLocStart(), 3708 diag::ext_omp_loop_not_canonical_init) 3709 << S->getSourceRange(); 3710 return SetLCDeclAndLB(Var, nullptr, Var->getInit()); 3711 } 3712 } 3713 } 3714 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3715 if (CE->getOperator() == OO_Equal) { 3716 auto *LHS = CE->getArg(0); 3717 if (auto DRE = dyn_cast<DeclRefExpr>(LHS)) { 3718 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3719 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3720 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3721 return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); 3722 } 3723 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3724 if (ME->isArrow() && 3725 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3726 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3727 } 3728 } 3729 } 3730 3731 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3732 return false; 3733 if (EmitDiags) { 3734 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init) 3735 << S->getSourceRange(); 3736 } 3737 return true; 3738 } 3739 3740 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the 3741 /// variable (which may be the loop variable) if possible. 3742 static const ValueDecl *GetInitLCDecl(Expr *E) { 3743 if (!E) 3744 return nullptr; 3745 E = getExprAsWritten(E); 3746 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 3747 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3748 if ((Ctor->isCopyOrMoveConstructor() || 3749 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3750 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3751 E = CE->getArg(0)->IgnoreParenImpCasts(); 3752 if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 3753 if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 3754 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3755 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3756 return getCanonicalDecl(ME->getMemberDecl()); 3757 return getCanonicalDecl(VD); 3758 } 3759 } 3760 if (auto *ME = dyn_cast_or_null<MemberExpr>(E)) 3761 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3762 return getCanonicalDecl(ME->getMemberDecl()); 3763 return nullptr; 3764 } 3765 3766 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { 3767 // Check test-expr for canonical form, save upper-bound UB, flags for 3768 // less/greater and for strict/non-strict comparison. 3769 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3770 // var relational-op b 3771 // b relational-op var 3772 // 3773 if (!S) { 3774 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 3775 return true; 3776 } 3777 S = getExprAsWritten(S); 3778 SourceLocation CondLoc = S->getLocStart(); 3779 if (auto BO = dyn_cast<BinaryOperator>(S)) { 3780 if (BO->isRelationalOp()) { 3781 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3782 return SetUB(BO->getRHS(), 3783 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 3784 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3785 BO->getSourceRange(), BO->getOperatorLoc()); 3786 if (GetInitLCDecl(BO->getRHS()) == LCDecl) 3787 return SetUB(BO->getLHS(), 3788 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 3789 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3790 BO->getSourceRange(), BO->getOperatorLoc()); 3791 } 3792 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3793 if (CE->getNumArgs() == 2) { 3794 auto Op = CE->getOperator(); 3795 switch (Op) { 3796 case OO_Greater: 3797 case OO_GreaterEqual: 3798 case OO_Less: 3799 case OO_LessEqual: 3800 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3801 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 3802 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3803 CE->getOperatorLoc()); 3804 if (GetInitLCDecl(CE->getArg(1)) == LCDecl) 3805 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 3806 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3807 CE->getOperatorLoc()); 3808 break; 3809 default: 3810 break; 3811 } 3812 } 3813 } 3814 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3815 return false; 3816 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 3817 << S->getSourceRange() << LCDecl; 3818 return true; 3819 } 3820 3821 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) { 3822 // RHS of canonical loop form increment can be: 3823 // var + incr 3824 // incr + var 3825 // var - incr 3826 // 3827 RHS = RHS->IgnoreParenImpCasts(); 3828 if (auto BO = dyn_cast<BinaryOperator>(RHS)) { 3829 if (BO->isAdditiveOp()) { 3830 bool IsAdd = BO->getOpcode() == BO_Add; 3831 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3832 return SetStep(BO->getRHS(), !IsAdd); 3833 if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl) 3834 return SetStep(BO->getLHS(), false); 3835 } 3836 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 3837 bool IsAdd = CE->getOperator() == OO_Plus; 3838 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 3839 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3840 return SetStep(CE->getArg(1), !IsAdd); 3841 if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl) 3842 return SetStep(CE->getArg(0), false); 3843 } 3844 } 3845 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3846 return false; 3847 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr) 3848 << RHS->getSourceRange() << LCDecl; 3849 return true; 3850 } 3851 3852 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { 3853 // Check incr-expr for canonical loop form and return true if it 3854 // does not conform. 3855 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3856 // ++var 3857 // var++ 3858 // --var 3859 // var-- 3860 // var += incr 3861 // var -= incr 3862 // var = var + incr 3863 // var = incr + var 3864 // var = var - incr 3865 // 3866 if (!S) { 3867 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 3868 return true; 3869 } 3870 IncrementSrcRange = S->getSourceRange(); 3871 S = S->IgnoreParens(); 3872 if (auto UO = dyn_cast<UnaryOperator>(S)) { 3873 if (UO->isIncrementDecrementOp() && 3874 GetInitLCDecl(UO->getSubExpr()) == LCDecl) 3875 return SetStep( 3876 SemaRef.ActOnIntegerConstant(UO->getLocStart(), 3877 (UO->isDecrementOp() ? -1 : 1)).get(), 3878 false); 3879 } else if (auto BO = dyn_cast<BinaryOperator>(S)) { 3880 switch (BO->getOpcode()) { 3881 case BO_AddAssign: 3882 case BO_SubAssign: 3883 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3884 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 3885 break; 3886 case BO_Assign: 3887 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3888 return CheckIncRHS(BO->getRHS()); 3889 break; 3890 default: 3891 break; 3892 } 3893 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3894 switch (CE->getOperator()) { 3895 case OO_PlusPlus: 3896 case OO_MinusMinus: 3897 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3898 return SetStep( 3899 SemaRef.ActOnIntegerConstant( 3900 CE->getLocStart(), 3901 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).get(), 3902 false); 3903 break; 3904 case OO_PlusEqual: 3905 case OO_MinusEqual: 3906 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3907 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 3908 break; 3909 case OO_Equal: 3910 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3911 return CheckIncRHS(CE->getArg(1)); 3912 break; 3913 default: 3914 break; 3915 } 3916 } 3917 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3918 return false; 3919 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr) 3920 << S->getSourceRange() << LCDecl; 3921 return true; 3922 } 3923 3924 static ExprResult 3925 tryBuildCapture(Sema &SemaRef, Expr *Capture, 3926 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 3927 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 3928 return SemaRef.PerformImplicitConversion( 3929 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 3930 /*AllowExplicit=*/true); 3931 auto I = Captures.find(Capture); 3932 if (I != Captures.end()) 3933 return buildCapture(SemaRef, Capture, I->second); 3934 DeclRefExpr *Ref = nullptr; 3935 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 3936 Captures[Capture] = Ref; 3937 return Res; 3938 } 3939 3940 /// \brief Build the expression to calculate the number of iterations. 3941 Expr *OpenMPIterationSpaceChecker::BuildNumIterations( 3942 Scope *S, const bool LimitedType, 3943 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 3944 ExprResult Diff; 3945 auto VarType = LCDecl->getType().getNonReferenceType(); 3946 if (VarType->isIntegerType() || VarType->isPointerType() || 3947 SemaRef.getLangOpts().CPlusPlus) { 3948 // Upper - Lower 3949 auto *UBExpr = TestIsLessOp ? UB : LB; 3950 auto *LBExpr = TestIsLessOp ? LB : UB; 3951 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 3952 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 3953 if (!Upper || !Lower) 3954 return nullptr; 3955 3956 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 3957 3958 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 3959 // BuildBinOp already emitted error, this one is to point user to upper 3960 // and lower bound, and to tell what is passed to 'operator-'. 3961 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) 3962 << Upper->getSourceRange() << Lower->getSourceRange(); 3963 return nullptr; 3964 } 3965 } 3966 3967 if (!Diff.isUsable()) 3968 return nullptr; 3969 3970 // Upper - Lower [- 1] 3971 if (TestIsStrictOp) 3972 Diff = SemaRef.BuildBinOp( 3973 S, DefaultLoc, BO_Sub, Diff.get(), 3974 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 3975 if (!Diff.isUsable()) 3976 return nullptr; 3977 3978 // Upper - Lower [- 1] + Step 3979 auto NewStep = tryBuildCapture(SemaRef, Step, Captures); 3980 if (!NewStep.isUsable()) 3981 return nullptr; 3982 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 3983 if (!Diff.isUsable()) 3984 return nullptr; 3985 3986 // Parentheses (for dumping/debugging purposes only). 3987 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 3988 if (!Diff.isUsable()) 3989 return nullptr; 3990 3991 // (Upper - Lower [- 1] + Step) / Step 3992 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 3993 if (!Diff.isUsable()) 3994 return nullptr; 3995 3996 // OpenMP runtime requires 32-bit or 64-bit loop variables. 3997 QualType Type = Diff.get()->getType(); 3998 auto &C = SemaRef.Context; 3999 bool UseVarType = VarType->hasIntegerRepresentation() && 4000 C.getTypeSize(Type) > C.getTypeSize(VarType); 4001 if (!Type->isIntegerType() || UseVarType) { 4002 unsigned NewSize = 4003 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 4004 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 4005 : Type->hasSignedIntegerRepresentation(); 4006 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 4007 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 4008 Diff = SemaRef.PerformImplicitConversion( 4009 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 4010 if (!Diff.isUsable()) 4011 return nullptr; 4012 } 4013 } 4014 if (LimitedType) { 4015 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 4016 if (NewSize != C.getTypeSize(Type)) { 4017 if (NewSize < C.getTypeSize(Type)) { 4018 assert(NewSize == 64 && "incorrect loop var size"); 4019 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 4020 << InitSrcRange << ConditionSrcRange; 4021 } 4022 QualType NewType = C.getIntTypeForBitwidth( 4023 NewSize, Type->hasSignedIntegerRepresentation() || 4024 C.getTypeSize(Type) < NewSize); 4025 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 4026 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 4027 Sema::AA_Converting, true); 4028 if (!Diff.isUsable()) 4029 return nullptr; 4030 } 4031 } 4032 } 4033 4034 return Diff.get(); 4035 } 4036 4037 Expr *OpenMPIterationSpaceChecker::BuildPreCond( 4038 Scope *S, Expr *Cond, 4039 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 4040 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 4041 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4042 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4043 4044 auto NewLB = tryBuildCapture(SemaRef, LB, Captures); 4045 auto NewUB = tryBuildCapture(SemaRef, UB, Captures); 4046 if (!NewLB.isUsable() || !NewUB.isUsable()) 4047 return nullptr; 4048 4049 auto CondExpr = SemaRef.BuildBinOp( 4050 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) 4051 : (TestIsStrictOp ? BO_GT : BO_GE), 4052 NewLB.get(), NewUB.get()); 4053 if (CondExpr.isUsable()) { 4054 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 4055 SemaRef.Context.BoolTy)) 4056 CondExpr = SemaRef.PerformImplicitConversion( 4057 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 4058 /*AllowExplicit=*/true); 4059 } 4060 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4061 // Otherwise use original loop conditon and evaluate it in runtime. 4062 return CondExpr.isUsable() ? CondExpr.get() : Cond; 4063 } 4064 4065 /// \brief Build reference expression to the counter be used for codegen. 4066 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar( 4067 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 4068 auto *VD = dyn_cast<VarDecl>(LCDecl); 4069 if (!VD) { 4070 VD = SemaRef.IsOpenMPCapturedDecl(LCDecl); 4071 auto *Ref = buildDeclRefExpr( 4072 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 4073 Captures.insert(std::make_pair(LCRef, Ref)); 4074 return Ref; 4075 } 4076 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(), 4077 DefaultLoc); 4078 } 4079 4080 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const { 4081 if (LCDecl && !LCDecl->isInvalidDecl()) { 4082 auto Type = LCDecl->getType().getNonReferenceType(); 4083 auto *PrivateVar = 4084 buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(), 4085 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr); 4086 if (PrivateVar->isInvalidDecl()) 4087 return nullptr; 4088 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 4089 } 4090 return nullptr; 4091 } 4092 4093 /// \brief Build initization of the counter be used for codegen. 4094 Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; } 4095 4096 /// \brief Build step of the counter be used for codegen. 4097 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; } 4098 4099 /// \brief Iteration space of a single for loop. 4100 struct LoopIterationSpace { 4101 /// \brief Condition of the loop. 4102 Expr *PreCond; 4103 /// \brief This expression calculates the number of iterations in the loop. 4104 /// It is always possible to calculate it before starting the loop. 4105 Expr *NumIterations; 4106 /// \brief The loop counter variable. 4107 Expr *CounterVar; 4108 /// \brief Private loop counter variable. 4109 Expr *PrivateCounterVar; 4110 /// \brief This is initializer for the initial value of #CounterVar. 4111 Expr *CounterInit; 4112 /// \brief This is step for the #CounterVar used to generate its update: 4113 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4114 Expr *CounterStep; 4115 /// \brief Should step be subtracted? 4116 bool Subtract; 4117 /// \brief Source range of the loop init. 4118 SourceRange InitSrcRange; 4119 /// \brief Source range of the loop condition. 4120 SourceRange CondSrcRange; 4121 /// \brief Source range of the loop increment. 4122 SourceRange IncSrcRange; 4123 }; 4124 4125 } // namespace 4126 4127 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 4128 assert(getLangOpts().OpenMP && "OpenMP is not active."); 4129 assert(Init && "Expected loop in canonical form."); 4130 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 4131 if (AssociatedLoops > 0 && 4132 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 4133 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 4134 if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) { 4135 if (auto *D = ISC.GetLoopDecl()) { 4136 auto *VD = dyn_cast<VarDecl>(D); 4137 if (!VD) { 4138 if (auto *Private = IsOpenMPCapturedDecl(D)) 4139 VD = Private; 4140 else { 4141 auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(), 4142 /*WithInit=*/false); 4143 VD = cast<VarDecl>(Ref->getDecl()); 4144 } 4145 } 4146 DSAStack->addLoopControlVariable(D, VD); 4147 } 4148 } 4149 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 4150 } 4151 } 4152 4153 /// \brief Called on a for stmt to check and extract its iteration space 4154 /// for further processing (such as collapsing). 4155 static bool CheckOpenMPIterationSpace( 4156 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 4157 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 4158 Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, 4159 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 4160 LoopIterationSpace &ResultIterSpace, 4161 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4162 // OpenMP [2.6, Canonical Loop Form] 4163 // for (init-expr; test-expr; incr-expr) structured-block 4164 auto For = dyn_cast_or_null<ForStmt>(S); 4165 if (!For) { 4166 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for) 4167 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 4168 << getOpenMPDirectiveName(DKind) << NestedLoopCount 4169 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 4170 if (NestedLoopCount > 1) { 4171 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 4172 SemaRef.Diag(DSA.getConstructLoc(), 4173 diag::note_omp_collapse_ordered_expr) 4174 << 2 << CollapseLoopCountExpr->getSourceRange() 4175 << OrderedLoopCountExpr->getSourceRange(); 4176 else if (CollapseLoopCountExpr) 4177 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4178 diag::note_omp_collapse_ordered_expr) 4179 << 0 << CollapseLoopCountExpr->getSourceRange(); 4180 else 4181 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4182 diag::note_omp_collapse_ordered_expr) 4183 << 1 << OrderedLoopCountExpr->getSourceRange(); 4184 } 4185 return true; 4186 } 4187 assert(For->getBody()); 4188 4189 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 4190 4191 // Check init. 4192 auto Init = For->getInit(); 4193 if (ISC.CheckInit(Init)) 4194 return true; 4195 4196 bool HasErrors = false; 4197 4198 // Check loop variable's type. 4199 if (auto *LCDecl = ISC.GetLoopDecl()) { 4200 auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr(); 4201 4202 // OpenMP [2.6, Canonical Loop Form] 4203 // Var is one of the following: 4204 // A variable of signed or unsigned integer type. 4205 // For C++, a variable of a random access iterator type. 4206 // For C, a variable of a pointer type. 4207 auto VarType = LCDecl->getType().getNonReferenceType(); 4208 if (!VarType->isDependentType() && !VarType->isIntegerType() && 4209 !VarType->isPointerType() && 4210 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 4211 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type) 4212 << SemaRef.getLangOpts().CPlusPlus; 4213 HasErrors = true; 4214 } 4215 4216 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 4217 // a Construct 4218 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4219 // parallel for construct is (are) private. 4220 // The loop iteration variable in the associated for-loop of a simd 4221 // construct with just one associated for-loop is linear with a 4222 // constant-linear-step that is the increment of the associated for-loop. 4223 // Exclude loop var from the list of variables with implicitly defined data 4224 // sharing attributes. 4225 VarsWithImplicitDSA.erase(LCDecl); 4226 4227 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 4228 // in a Construct, C/C++]. 4229 // The loop iteration variable in the associated for-loop of a simd 4230 // construct with just one associated for-loop may be listed in a linear 4231 // clause with a constant-linear-step that is the increment of the 4232 // associated for-loop. 4233 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4234 // parallel for construct may be listed in a private or lastprivate clause. 4235 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 4236 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 4237 // declared in the loop and it is predetermined as a private. 4238 auto PredeterminedCKind = 4239 isOpenMPSimdDirective(DKind) 4240 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 4241 : OMPC_private; 4242 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4243 DVar.CKind != PredeterminedCKind) || 4244 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 4245 isOpenMPDistributeDirective(DKind)) && 4246 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4247 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 4248 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 4249 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa) 4250 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 4251 << getOpenMPClauseName(PredeterminedCKind); 4252 if (DVar.RefExpr == nullptr) 4253 DVar.CKind = PredeterminedCKind; 4254 ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 4255 HasErrors = true; 4256 } else if (LoopDeclRefExpr != nullptr) { 4257 // Make the loop iteration variable private (for worksharing constructs), 4258 // linear (for simd directives with the only one associated loop) or 4259 // lastprivate (for simd directives with several collapsed or ordered 4260 // loops). 4261 if (DVar.CKind == OMPC_unknown) 4262 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate, MatchesAlways(), 4263 /*FromParent=*/false); 4264 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 4265 } 4266 4267 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 4268 4269 // Check test-expr. 4270 HasErrors |= ISC.CheckCond(For->getCond()); 4271 4272 // Check incr-expr. 4273 HasErrors |= ISC.CheckInc(For->getInc()); 4274 } 4275 4276 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 4277 return HasErrors; 4278 4279 // Build the loop's iteration space representation. 4280 ResultIterSpace.PreCond = 4281 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures); 4282 ResultIterSpace.NumIterations = ISC.BuildNumIterations( 4283 DSA.getCurScope(), 4284 (isOpenMPWorksharingDirective(DKind) || 4285 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 4286 Captures); 4287 ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures); 4288 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); 4289 ResultIterSpace.CounterInit = ISC.BuildCounterInit(); 4290 ResultIterSpace.CounterStep = ISC.BuildCounterStep(); 4291 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); 4292 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange(); 4293 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange(); 4294 ResultIterSpace.Subtract = ISC.ShouldSubtractStep(); 4295 4296 HasErrors |= (ResultIterSpace.PreCond == nullptr || 4297 ResultIterSpace.NumIterations == nullptr || 4298 ResultIterSpace.CounterVar == nullptr || 4299 ResultIterSpace.PrivateCounterVar == nullptr || 4300 ResultIterSpace.CounterInit == nullptr || 4301 ResultIterSpace.CounterStep == nullptr); 4302 4303 return HasErrors; 4304 } 4305 4306 /// \brief Build 'VarRef = Start. 4307 static ExprResult 4308 BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 4309 ExprResult Start, 4310 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4311 // Build 'VarRef = Start. 4312 auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 4313 if (!NewStart.isUsable()) 4314 return ExprError(); 4315 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 4316 VarRef.get()->getType())) { 4317 NewStart = SemaRef.PerformImplicitConversion( 4318 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 4319 /*AllowExplicit=*/true); 4320 if (!NewStart.isUsable()) 4321 return ExprError(); 4322 } 4323 4324 auto Init = 4325 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4326 return Init; 4327 } 4328 4329 /// \brief Build 'VarRef = Start + Iter * Step'. 4330 static ExprResult 4331 BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, 4332 ExprResult VarRef, ExprResult Start, ExprResult Iter, 4333 ExprResult Step, bool Subtract, 4334 llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) { 4335 // Add parentheses (for debugging purposes only). 4336 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 4337 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 4338 !Step.isUsable()) 4339 return ExprError(); 4340 4341 ExprResult NewStep = Step; 4342 if (Captures) 4343 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 4344 if (NewStep.isInvalid()) 4345 return ExprError(); 4346 ExprResult Update = 4347 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 4348 if (!Update.isUsable()) 4349 return ExprError(); 4350 4351 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 4352 // 'VarRef = Start (+|-) Iter * Step'. 4353 ExprResult NewStart = Start; 4354 if (Captures) 4355 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 4356 if (NewStart.isInvalid()) 4357 return ExprError(); 4358 4359 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 4360 ExprResult SavedUpdate = Update; 4361 ExprResult UpdateVal; 4362 if (VarRef.get()->getType()->isOverloadableType() || 4363 NewStart.get()->getType()->isOverloadableType() || 4364 Update.get()->getType()->isOverloadableType()) { 4365 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4366 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4367 Update = 4368 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4369 if (Update.isUsable()) { 4370 UpdateVal = 4371 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 4372 VarRef.get(), SavedUpdate.get()); 4373 if (UpdateVal.isUsable()) { 4374 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 4375 UpdateVal.get()); 4376 } 4377 } 4378 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4379 } 4380 4381 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 4382 if (!Update.isUsable() || !UpdateVal.isUsable()) { 4383 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 4384 NewStart.get(), SavedUpdate.get()); 4385 if (!Update.isUsable()) 4386 return ExprError(); 4387 4388 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 4389 VarRef.get()->getType())) { 4390 Update = SemaRef.PerformImplicitConversion( 4391 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 4392 if (!Update.isUsable()) 4393 return ExprError(); 4394 } 4395 4396 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 4397 } 4398 return Update; 4399 } 4400 4401 /// \brief Convert integer expression \a E to make it have at least \a Bits 4402 /// bits. 4403 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, 4404 Sema &SemaRef) { 4405 if (E == nullptr) 4406 return ExprError(); 4407 auto &C = SemaRef.Context; 4408 QualType OldType = E->getType(); 4409 unsigned HasBits = C.getTypeSize(OldType); 4410 if (HasBits >= Bits) 4411 return ExprResult(E); 4412 // OK to convert to signed, because new type has more bits than old. 4413 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 4414 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 4415 true); 4416 } 4417 4418 /// \brief Check if the given expression \a E is a constant integer that fits 4419 /// into \a Bits bits. 4420 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { 4421 if (E == nullptr) 4422 return false; 4423 llvm::APSInt Result; 4424 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 4425 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 4426 return false; 4427 } 4428 4429 /// Build preinits statement for the given declarations. 4430 static Stmt *buildPreInits(ASTContext &Context, 4431 SmallVectorImpl<Decl *> &PreInits) { 4432 if (!PreInits.empty()) { 4433 return new (Context) DeclStmt( 4434 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 4435 SourceLocation(), SourceLocation()); 4436 } 4437 return nullptr; 4438 } 4439 4440 /// Build preinits statement for the given declarations. 4441 static Stmt *buildPreInits(ASTContext &Context, 4442 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4443 if (!Captures.empty()) { 4444 SmallVector<Decl *, 16> PreInits; 4445 for (auto &Pair : Captures) 4446 PreInits.push_back(Pair.second->getDecl()); 4447 return buildPreInits(Context, PreInits); 4448 } 4449 return nullptr; 4450 } 4451 4452 /// Build postupdate expression for the given list of postupdates expressions. 4453 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 4454 Expr *PostUpdate = nullptr; 4455 if (!PostUpdates.empty()) { 4456 for (auto *E : PostUpdates) { 4457 Expr *ConvE = S.BuildCStyleCastExpr( 4458 E->getExprLoc(), 4459 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 4460 E->getExprLoc(), E) 4461 .get(); 4462 PostUpdate = PostUpdate 4463 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 4464 PostUpdate, ConvE) 4465 .get() 4466 : ConvE; 4467 } 4468 } 4469 return PostUpdate; 4470 } 4471 4472 /// \brief Called on a for stmt to check itself and nested loops (if any). 4473 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 4474 /// number of collapsed loops otherwise. 4475 static unsigned 4476 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 4477 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 4478 DSAStackTy &DSA, 4479 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 4480 OMPLoopDirective::HelperExprs &Built) { 4481 unsigned NestedLoopCount = 1; 4482 if (CollapseLoopCountExpr) { 4483 // Found 'collapse' clause - calculate collapse number. 4484 llvm::APSInt Result; 4485 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 4486 NestedLoopCount = Result.getLimitedValue(); 4487 } 4488 if (OrderedLoopCountExpr) { 4489 // Found 'ordered' clause - calculate collapse number. 4490 llvm::APSInt Result; 4491 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 4492 if (Result.getLimitedValue() < NestedLoopCount) { 4493 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4494 diag::err_omp_wrong_ordered_loop_count) 4495 << OrderedLoopCountExpr->getSourceRange(); 4496 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4497 diag::note_collapse_loop_count) 4498 << CollapseLoopCountExpr->getSourceRange(); 4499 } 4500 NestedLoopCount = Result.getLimitedValue(); 4501 } 4502 } 4503 // This is helper routine for loop directives (e.g., 'for', 'simd', 4504 // 'for simd', etc.). 4505 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 4506 SmallVector<LoopIterationSpace, 4> IterSpaces; 4507 IterSpaces.resize(NestedLoopCount); 4508 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 4509 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 4510 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, 4511 NestedLoopCount, CollapseLoopCountExpr, 4512 OrderedLoopCountExpr, VarsWithImplicitDSA, 4513 IterSpaces[Cnt], Captures)) 4514 return 0; 4515 // Move on to the next nested for loop, or to the loop body. 4516 // OpenMP [2.8.1, simd construct, Restrictions] 4517 // All loops associated with the construct must be perfectly nested; that 4518 // is, there must be no intervening code nor any OpenMP directive between 4519 // any two loops. 4520 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 4521 } 4522 4523 Built.clear(/* size */ NestedLoopCount); 4524 4525 if (SemaRef.CurContext->isDependentContext()) 4526 return NestedLoopCount; 4527 4528 // An example of what is generated for the following code: 4529 // 4530 // #pragma omp simd collapse(2) ordered(2) 4531 // for (i = 0; i < NI; ++i) 4532 // for (k = 0; k < NK; ++k) 4533 // for (j = J0; j < NJ; j+=2) { 4534 // <loop body> 4535 // } 4536 // 4537 // We generate the code below. 4538 // Note: the loop body may be outlined in CodeGen. 4539 // Note: some counters may be C++ classes, operator- is used to find number of 4540 // iterations and operator+= to calculate counter value. 4541 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 4542 // or i64 is currently supported). 4543 // 4544 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 4545 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 4546 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 4547 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 4548 // // similar updates for vars in clauses (e.g. 'linear') 4549 // <loop body (using local i and j)> 4550 // } 4551 // i = NI; // assign final values of counters 4552 // j = NJ; 4553 // 4554 4555 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 4556 // the iteration counts of the collapsed for loops. 4557 // Precondition tests if there is at least one iteration (all conditions are 4558 // true). 4559 auto PreCond = ExprResult(IterSpaces[0].PreCond); 4560 auto N0 = IterSpaces[0].NumIterations; 4561 ExprResult LastIteration32 = WidenIterationCount( 4562 32 /* Bits */, SemaRef.PerformImplicitConversion( 4563 N0->IgnoreImpCasts(), N0->getType(), 4564 Sema::AA_Converting, /*AllowExplicit=*/true) 4565 .get(), 4566 SemaRef); 4567 ExprResult LastIteration64 = WidenIterationCount( 4568 64 /* Bits */, SemaRef.PerformImplicitConversion( 4569 N0->IgnoreImpCasts(), N0->getType(), 4570 Sema::AA_Converting, /*AllowExplicit=*/true) 4571 .get(), 4572 SemaRef); 4573 4574 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 4575 return NestedLoopCount; 4576 4577 auto &C = SemaRef.Context; 4578 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 4579 4580 Scope *CurScope = DSA.getCurScope(); 4581 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 4582 if (PreCond.isUsable()) { 4583 PreCond = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_LAnd, 4584 PreCond.get(), IterSpaces[Cnt].PreCond); 4585 } 4586 auto N = IterSpaces[Cnt].NumIterations; 4587 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 4588 if (LastIteration32.isUsable()) 4589 LastIteration32 = SemaRef.BuildBinOp( 4590 CurScope, SourceLocation(), BO_Mul, LastIteration32.get(), 4591 SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4592 Sema::AA_Converting, 4593 /*AllowExplicit=*/true) 4594 .get()); 4595 if (LastIteration64.isUsable()) 4596 LastIteration64 = SemaRef.BuildBinOp( 4597 CurScope, SourceLocation(), BO_Mul, LastIteration64.get(), 4598 SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4599 Sema::AA_Converting, 4600 /*AllowExplicit=*/true) 4601 .get()); 4602 } 4603 4604 // Choose either the 32-bit or 64-bit version. 4605 ExprResult LastIteration = LastIteration64; 4606 if (LastIteration32.isUsable() && 4607 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 4608 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 4609 FitsInto( 4610 32 /* Bits */, 4611 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 4612 LastIteration64.get(), SemaRef))) 4613 LastIteration = LastIteration32; 4614 4615 if (!LastIteration.isUsable()) 4616 return 0; 4617 4618 // Save the number of iterations. 4619 ExprResult NumIterations = LastIteration; 4620 { 4621 LastIteration = SemaRef.BuildBinOp( 4622 CurScope, SourceLocation(), BO_Sub, LastIteration.get(), 4623 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4624 if (!LastIteration.isUsable()) 4625 return 0; 4626 } 4627 4628 // Calculate the last iteration number beforehand instead of doing this on 4629 // each iteration. Do not do this if the number of iterations may be kfold-ed. 4630 llvm::APSInt Result; 4631 bool IsConstant = 4632 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 4633 ExprResult CalcLastIteration; 4634 if (!IsConstant) { 4635 ExprResult SaveRef = 4636 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 4637 LastIteration = SaveRef; 4638 4639 // Prepare SaveRef + 1. 4640 NumIterations = SemaRef.BuildBinOp( 4641 CurScope, SourceLocation(), BO_Add, SaveRef.get(), 4642 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4643 if (!NumIterations.isUsable()) 4644 return 0; 4645 } 4646 4647 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 4648 4649 QualType VType = LastIteration.get()->getType(); 4650 // Build variables passed into runtime, nesessary for worksharing directives. 4651 ExprResult LB, UB, IL, ST, EUB; 4652 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4653 isOpenMPDistributeDirective(DKind)) { 4654 // Lower bound variable, initialized with zero. 4655 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 4656 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 4657 SemaRef.AddInitializerToDecl( 4658 LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4659 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 4660 4661 // Upper bound variable, initialized with last iteration number. 4662 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 4663 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 4664 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 4665 /*DirectInit*/ false, 4666 /*TypeMayContainAuto*/ false); 4667 4668 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 4669 // This will be used to implement clause 'lastprivate'. 4670 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 4671 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 4672 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 4673 SemaRef.AddInitializerToDecl( 4674 ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4675 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 4676 4677 // Stride variable returned by runtime (we initialize it to 1 by default). 4678 VarDecl *STDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.stride"); 4679 ST = buildDeclRefExpr(SemaRef, STDecl, VType, InitLoc); 4680 SemaRef.AddInitializerToDecl( 4681 STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 4682 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 4683 4684 // Build expression: UB = min(UB, LastIteration) 4685 // It is nesessary for CodeGen of directives with static scheduling. 4686 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 4687 UB.get(), LastIteration.get()); 4688 ExprResult CondOp = SemaRef.ActOnConditionalOp( 4689 InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get()); 4690 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 4691 CondOp.get()); 4692 EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); 4693 } 4694 4695 // Build the iteration variable and its initialization before loop. 4696 ExprResult IV; 4697 ExprResult Init; 4698 { 4699 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.iv"); 4700 IV = buildDeclRefExpr(SemaRef, IVDecl, VType, InitLoc); 4701 Expr *RHS = (isOpenMPWorksharingDirective(DKind) || 4702 isOpenMPTaskLoopDirective(DKind) || 4703 isOpenMPDistributeDirective(DKind)) 4704 ? LB.get() 4705 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 4706 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 4707 Init = SemaRef.ActOnFinishFullExpr(Init.get()); 4708 } 4709 4710 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. 4711 SourceLocation CondLoc; 4712 ExprResult Cond = 4713 (isOpenMPWorksharingDirective(DKind) || 4714 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 4715 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) 4716 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 4717 NumIterations.get()); 4718 4719 // Loop increment (IV = IV + 1) 4720 SourceLocation IncLoc; 4721 ExprResult Inc = 4722 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 4723 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 4724 if (!Inc.isUsable()) 4725 return 0; 4726 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 4727 Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); 4728 if (!Inc.isUsable()) 4729 return 0; 4730 4731 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 4732 // Used for directives with static scheduling. 4733 ExprResult NextLB, NextUB; 4734 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4735 isOpenMPDistributeDirective(DKind)) { 4736 // LB + ST 4737 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 4738 if (!NextLB.isUsable()) 4739 return 0; 4740 // LB = LB + ST 4741 NextLB = 4742 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 4743 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); 4744 if (!NextLB.isUsable()) 4745 return 0; 4746 // UB + ST 4747 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 4748 if (!NextUB.isUsable()) 4749 return 0; 4750 // UB = UB + ST 4751 NextUB = 4752 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 4753 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); 4754 if (!NextUB.isUsable()) 4755 return 0; 4756 } 4757 4758 // Build updates and final values of the loop counters. 4759 bool HasErrors = false; 4760 Built.Counters.resize(NestedLoopCount); 4761 Built.Inits.resize(NestedLoopCount); 4762 Built.Updates.resize(NestedLoopCount); 4763 Built.Finals.resize(NestedLoopCount); 4764 { 4765 ExprResult Div; 4766 // Go from inner nested loop to outer. 4767 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 4768 LoopIterationSpace &IS = IterSpaces[Cnt]; 4769 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 4770 // Build: Iter = (IV / Div) % IS.NumIters 4771 // where Div is product of previous iterations' IS.NumIters. 4772 ExprResult Iter; 4773 if (Div.isUsable()) { 4774 Iter = 4775 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); 4776 } else { 4777 Iter = IV; 4778 assert((Cnt == (int)NestedLoopCount - 1) && 4779 "unusable div expected on first iteration only"); 4780 } 4781 4782 if (Cnt != 0 && Iter.isUsable()) 4783 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), 4784 IS.NumIterations); 4785 if (!Iter.isUsable()) { 4786 HasErrors = true; 4787 break; 4788 } 4789 4790 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 4791 auto *CounterVar = buildDeclRefExpr( 4792 SemaRef, cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()), 4793 IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 4794 /*RefersToCapture=*/true); 4795 ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 4796 IS.CounterInit, Captures); 4797 if (!Init.isUsable()) { 4798 HasErrors = true; 4799 break; 4800 } 4801 ExprResult Update = BuildCounterUpdate( 4802 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 4803 IS.CounterStep, IS.Subtract, &Captures); 4804 if (!Update.isUsable()) { 4805 HasErrors = true; 4806 break; 4807 } 4808 4809 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 4810 ExprResult Final = BuildCounterUpdate( 4811 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 4812 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 4813 if (!Final.isUsable()) { 4814 HasErrors = true; 4815 break; 4816 } 4817 4818 // Build Div for the next iteration: Div <- Div * IS.NumIters 4819 if (Cnt != 0) { 4820 if (Div.isUnset()) 4821 Div = IS.NumIterations; 4822 else 4823 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), 4824 IS.NumIterations); 4825 4826 // Add parentheses (for debugging purposes only). 4827 if (Div.isUsable()) 4828 Div = SemaRef.ActOnParenExpr(UpdLoc, UpdLoc, Div.get()); 4829 if (!Div.isUsable()) { 4830 HasErrors = true; 4831 break; 4832 } 4833 } 4834 if (!Update.isUsable() || !Final.isUsable()) { 4835 HasErrors = true; 4836 break; 4837 } 4838 // Save results 4839 Built.Counters[Cnt] = IS.CounterVar; 4840 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 4841 Built.Inits[Cnt] = Init.get(); 4842 Built.Updates[Cnt] = Update.get(); 4843 Built.Finals[Cnt] = Final.get(); 4844 } 4845 } 4846 4847 if (HasErrors) 4848 return 0; 4849 4850 // Save results 4851 Built.IterationVarRef = IV.get(); 4852 Built.LastIteration = LastIteration.get(); 4853 Built.NumIterations = NumIterations.get(); 4854 Built.CalcLastIteration = 4855 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); 4856 Built.PreCond = PreCond.get(); 4857 Built.PreInits = buildPreInits(C, Captures); 4858 Built.Cond = Cond.get(); 4859 Built.Init = Init.get(); 4860 Built.Inc = Inc.get(); 4861 Built.LB = LB.get(); 4862 Built.UB = UB.get(); 4863 Built.IL = IL.get(); 4864 Built.ST = ST.get(); 4865 Built.EUB = EUB.get(); 4866 Built.NLB = NextLB.get(); 4867 Built.NUB = NextUB.get(); 4868 4869 return NestedLoopCount; 4870 } 4871 4872 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 4873 auto CollapseClauses = 4874 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 4875 if (CollapseClauses.begin() != CollapseClauses.end()) 4876 return (*CollapseClauses.begin())->getNumForLoops(); 4877 return nullptr; 4878 } 4879 4880 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 4881 auto OrderedClauses = 4882 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 4883 if (OrderedClauses.begin() != OrderedClauses.end()) 4884 return (*OrderedClauses.begin())->getNumForLoops(); 4885 return nullptr; 4886 } 4887 4888 static bool checkSimdlenSafelenValues(Sema &S, const Expr *Simdlen, 4889 const Expr *Safelen) { 4890 llvm::APSInt SimdlenRes, SafelenRes; 4891 if (Simdlen->isValueDependent() || Simdlen->isTypeDependent() || 4892 Simdlen->isInstantiationDependent() || 4893 Simdlen->containsUnexpandedParameterPack()) 4894 return false; 4895 if (Safelen->isValueDependent() || Safelen->isTypeDependent() || 4896 Safelen->isInstantiationDependent() || 4897 Safelen->containsUnexpandedParameterPack()) 4898 return false; 4899 Simdlen->EvaluateAsInt(SimdlenRes, S.Context); 4900 Safelen->EvaluateAsInt(SafelenRes, S.Context); 4901 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 4902 // If both simdlen and safelen clauses are specified, the value of the simdlen 4903 // parameter must be less than or equal to the value of the safelen parameter. 4904 if (SimdlenRes > SafelenRes) { 4905 S.Diag(Simdlen->getExprLoc(), diag::err_omp_wrong_simdlen_safelen_values) 4906 << Simdlen->getSourceRange() << Safelen->getSourceRange(); 4907 return true; 4908 } 4909 return false; 4910 } 4911 4912 StmtResult Sema::ActOnOpenMPSimdDirective( 4913 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4914 SourceLocation EndLoc, 4915 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4916 if (!AStmt) 4917 return StmtError(); 4918 4919 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4920 OMPLoopDirective::HelperExprs B; 4921 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 4922 // define the nested loops number. 4923 unsigned NestedLoopCount = CheckOpenMPLoop( 4924 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 4925 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 4926 if (NestedLoopCount == 0) 4927 return StmtError(); 4928 4929 assert((CurContext->isDependentContext() || B.builtAll()) && 4930 "omp simd loop exprs were not built"); 4931 4932 if (!CurContext->isDependentContext()) { 4933 // Finalize the clauses that need pre-built expressions for CodeGen. 4934 for (auto C : Clauses) { 4935 if (auto LC = dyn_cast<OMPLinearClause>(C)) 4936 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 4937 B.NumIterations, *this, CurScope)) 4938 return StmtError(); 4939 } 4940 } 4941 4942 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 4943 // If both simdlen and safelen clauses are specified, the value of the simdlen 4944 // parameter must be less than or equal to the value of the safelen parameter. 4945 OMPSafelenClause *Safelen = nullptr; 4946 OMPSimdlenClause *Simdlen = nullptr; 4947 for (auto *Clause : Clauses) { 4948 if (Clause->getClauseKind() == OMPC_safelen) 4949 Safelen = cast<OMPSafelenClause>(Clause); 4950 else if (Clause->getClauseKind() == OMPC_simdlen) 4951 Simdlen = cast<OMPSimdlenClause>(Clause); 4952 if (Safelen && Simdlen) 4953 break; 4954 } 4955 if (Simdlen && Safelen && 4956 checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), 4957 Safelen->getSafelen())) 4958 return StmtError(); 4959 4960 getCurFunction()->setHasBranchProtectedScope(); 4961 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 4962 Clauses, AStmt, B); 4963 } 4964 4965 StmtResult Sema::ActOnOpenMPForDirective( 4966 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4967 SourceLocation EndLoc, 4968 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4969 if (!AStmt) 4970 return StmtError(); 4971 4972 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4973 OMPLoopDirective::HelperExprs B; 4974 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 4975 // define the nested loops number. 4976 unsigned NestedLoopCount = CheckOpenMPLoop( 4977 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 4978 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 4979 if (NestedLoopCount == 0) 4980 return StmtError(); 4981 4982 assert((CurContext->isDependentContext() || B.builtAll()) && 4983 "omp for loop exprs were not built"); 4984 4985 if (!CurContext->isDependentContext()) { 4986 // Finalize the clauses that need pre-built expressions for CodeGen. 4987 for (auto C : Clauses) { 4988 if (auto LC = dyn_cast<OMPLinearClause>(C)) 4989 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 4990 B.NumIterations, *this, CurScope)) 4991 return StmtError(); 4992 } 4993 } 4994 4995 getCurFunction()->setHasBranchProtectedScope(); 4996 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 4997 Clauses, AStmt, B, DSAStack->isCancelRegion()); 4998 } 4999 5000 StmtResult Sema::ActOnOpenMPForSimdDirective( 5001 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5002 SourceLocation EndLoc, 5003 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5004 if (!AStmt) 5005 return StmtError(); 5006 5007 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5008 OMPLoopDirective::HelperExprs B; 5009 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5010 // define the nested loops number. 5011 unsigned NestedLoopCount = 5012 CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 5013 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5014 VarsWithImplicitDSA, B); 5015 if (NestedLoopCount == 0) 5016 return StmtError(); 5017 5018 assert((CurContext->isDependentContext() || B.builtAll()) && 5019 "omp for simd loop exprs were not built"); 5020 5021 if (!CurContext->isDependentContext()) { 5022 // Finalize the clauses that need pre-built expressions for CodeGen. 5023 for (auto C : Clauses) { 5024 if (auto LC = dyn_cast<OMPLinearClause>(C)) 5025 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5026 B.NumIterations, *this, CurScope)) 5027 return StmtError(); 5028 } 5029 } 5030 5031 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 5032 // If both simdlen and safelen clauses are specified, the value of the simdlen 5033 // parameter must be less than or equal to the value of the safelen parameter. 5034 OMPSafelenClause *Safelen = nullptr; 5035 OMPSimdlenClause *Simdlen = nullptr; 5036 for (auto *Clause : Clauses) { 5037 if (Clause->getClauseKind() == OMPC_safelen) 5038 Safelen = cast<OMPSafelenClause>(Clause); 5039 else if (Clause->getClauseKind() == OMPC_simdlen) 5040 Simdlen = cast<OMPSimdlenClause>(Clause); 5041 if (Safelen && Simdlen) 5042 break; 5043 } 5044 if (Simdlen && Safelen && 5045 checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), 5046 Safelen->getSafelen())) 5047 return StmtError(); 5048 5049 getCurFunction()->setHasBranchProtectedScope(); 5050 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5051 Clauses, AStmt, B); 5052 } 5053 5054 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 5055 Stmt *AStmt, 5056 SourceLocation StartLoc, 5057 SourceLocation EndLoc) { 5058 if (!AStmt) 5059 return StmtError(); 5060 5061 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5062 auto BaseStmt = AStmt; 5063 while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5064 BaseStmt = CS->getCapturedStmt(); 5065 if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5066 auto S = C->children(); 5067 if (S.begin() == S.end()) 5068 return StmtError(); 5069 // All associated statements must be '#pragma omp section' except for 5070 // the first one. 5071 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5072 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5073 if (SectionStmt) 5074 Diag(SectionStmt->getLocStart(), 5075 diag::err_omp_sections_substmt_not_section); 5076 return StmtError(); 5077 } 5078 cast<OMPSectionDirective>(SectionStmt) 5079 ->setHasCancel(DSAStack->isCancelRegion()); 5080 } 5081 } else { 5082 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt); 5083 return StmtError(); 5084 } 5085 5086 getCurFunction()->setHasBranchProtectedScope(); 5087 5088 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5089 DSAStack->isCancelRegion()); 5090 } 5091 5092 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 5093 SourceLocation StartLoc, 5094 SourceLocation EndLoc) { 5095 if (!AStmt) 5096 return StmtError(); 5097 5098 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5099 5100 getCurFunction()->setHasBranchProtectedScope(); 5101 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 5102 5103 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 5104 DSAStack->isCancelRegion()); 5105 } 5106 5107 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 5108 Stmt *AStmt, 5109 SourceLocation StartLoc, 5110 SourceLocation EndLoc) { 5111 if (!AStmt) 5112 return StmtError(); 5113 5114 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5115 5116 getCurFunction()->setHasBranchProtectedScope(); 5117 5118 // OpenMP [2.7.3, single Construct, Restrictions] 5119 // The copyprivate clause must not be used with the nowait clause. 5120 OMPClause *Nowait = nullptr; 5121 OMPClause *Copyprivate = nullptr; 5122 for (auto *Clause : Clauses) { 5123 if (Clause->getClauseKind() == OMPC_nowait) 5124 Nowait = Clause; 5125 else if (Clause->getClauseKind() == OMPC_copyprivate) 5126 Copyprivate = Clause; 5127 if (Copyprivate && Nowait) { 5128 Diag(Copyprivate->getLocStart(), 5129 diag::err_omp_single_copyprivate_with_nowait); 5130 Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here); 5131 return StmtError(); 5132 } 5133 } 5134 5135 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5136 } 5137 5138 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 5139 SourceLocation StartLoc, 5140 SourceLocation EndLoc) { 5141 if (!AStmt) 5142 return StmtError(); 5143 5144 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5145 5146 getCurFunction()->setHasBranchProtectedScope(); 5147 5148 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 5149 } 5150 5151 StmtResult Sema::ActOnOpenMPCriticalDirective( 5152 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 5153 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5154 if (!AStmt) 5155 return StmtError(); 5156 5157 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5158 5159 bool ErrorFound = false; 5160 llvm::APSInt Hint; 5161 SourceLocation HintLoc; 5162 bool DependentHint = false; 5163 for (auto *C : Clauses) { 5164 if (C->getClauseKind() == OMPC_hint) { 5165 if (!DirName.getName()) { 5166 Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name); 5167 ErrorFound = true; 5168 } 5169 Expr *E = cast<OMPHintClause>(C)->getHint(); 5170 if (E->isTypeDependent() || E->isValueDependent() || 5171 E->isInstantiationDependent()) 5172 DependentHint = true; 5173 else { 5174 Hint = E->EvaluateKnownConstInt(Context); 5175 HintLoc = C->getLocStart(); 5176 } 5177 } 5178 } 5179 if (ErrorFound) 5180 return StmtError(); 5181 auto Pair = DSAStack->getCriticalWithHint(DirName); 5182 if (Pair.first && DirName.getName() && !DependentHint) { 5183 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 5184 Diag(StartLoc, diag::err_omp_critical_with_hint); 5185 if (HintLoc.isValid()) { 5186 Diag(HintLoc, diag::note_omp_critical_hint_here) 5187 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 5188 } else 5189 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 5190 if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 5191 Diag(C->getLocStart(), diag::note_omp_critical_hint_here) 5192 << 1 5193 << C->getHint()->EvaluateKnownConstInt(Context).toString( 5194 /*Radix=*/10, /*Signed=*/false); 5195 } else 5196 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1; 5197 } 5198 } 5199 5200 getCurFunction()->setHasBranchProtectedScope(); 5201 5202 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 5203 Clauses, AStmt); 5204 if (!Pair.first && DirName.getName() && !DependentHint) 5205 DSAStack->addCriticalWithHint(Dir, Hint); 5206 return Dir; 5207 } 5208 5209 StmtResult Sema::ActOnOpenMPParallelForDirective( 5210 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5211 SourceLocation EndLoc, 5212 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5213 if (!AStmt) 5214 return StmtError(); 5215 5216 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5217 // 1.2.2 OpenMP Language Terminology 5218 // Structured block - An executable statement with a single entry at the 5219 // top and a single exit at the bottom. 5220 // The point of exit cannot be a branch out of the structured block. 5221 // longjmp() and throw() must not violate the entry/exit criteria. 5222 CS->getCapturedDecl()->setNothrow(); 5223 5224 OMPLoopDirective::HelperExprs B; 5225 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5226 // define the nested loops number. 5227 unsigned NestedLoopCount = 5228 CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 5229 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5230 VarsWithImplicitDSA, B); 5231 if (NestedLoopCount == 0) 5232 return StmtError(); 5233 5234 assert((CurContext->isDependentContext() || B.builtAll()) && 5235 "omp parallel for loop exprs were not built"); 5236 5237 if (!CurContext->isDependentContext()) { 5238 // Finalize the clauses that need pre-built expressions for CodeGen. 5239 for (auto C : Clauses) { 5240 if (auto LC = dyn_cast<OMPLinearClause>(C)) 5241 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5242 B.NumIterations, *this, CurScope)) 5243 return StmtError(); 5244 } 5245 } 5246 5247 getCurFunction()->setHasBranchProtectedScope(); 5248 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 5249 NestedLoopCount, Clauses, AStmt, B, 5250 DSAStack->isCancelRegion()); 5251 } 5252 5253 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 5254 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5255 SourceLocation EndLoc, 5256 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5257 if (!AStmt) 5258 return StmtError(); 5259 5260 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5261 // 1.2.2 OpenMP Language Terminology 5262 // Structured block - An executable statement with a single entry at the 5263 // top and a single exit at the bottom. 5264 // The point of exit cannot be a branch out of the structured block. 5265 // longjmp() and throw() must not violate the entry/exit criteria. 5266 CS->getCapturedDecl()->setNothrow(); 5267 5268 OMPLoopDirective::HelperExprs B; 5269 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5270 // define the nested loops number. 5271 unsigned NestedLoopCount = 5272 CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 5273 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5274 VarsWithImplicitDSA, B); 5275 if (NestedLoopCount == 0) 5276 return StmtError(); 5277 5278 if (!CurContext->isDependentContext()) { 5279 // Finalize the clauses that need pre-built expressions for CodeGen. 5280 for (auto C : Clauses) { 5281 if (auto LC = dyn_cast<OMPLinearClause>(C)) 5282 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5283 B.NumIterations, *this, CurScope)) 5284 return StmtError(); 5285 } 5286 } 5287 5288 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 5289 // If both simdlen and safelen clauses are specified, the value of the simdlen 5290 // parameter must be less than or equal to the value of the safelen parameter. 5291 OMPSafelenClause *Safelen = nullptr; 5292 OMPSimdlenClause *Simdlen = nullptr; 5293 for (auto *Clause : Clauses) { 5294 if (Clause->getClauseKind() == OMPC_safelen) 5295 Safelen = cast<OMPSafelenClause>(Clause); 5296 else if (Clause->getClauseKind() == OMPC_simdlen) 5297 Simdlen = cast<OMPSimdlenClause>(Clause); 5298 if (Safelen && Simdlen) 5299 break; 5300 } 5301 if (Simdlen && Safelen && 5302 checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), 5303 Safelen->getSafelen())) 5304 return StmtError(); 5305 5306 getCurFunction()->setHasBranchProtectedScope(); 5307 return OMPParallelForSimdDirective::Create( 5308 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 5309 } 5310 5311 StmtResult 5312 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 5313 Stmt *AStmt, SourceLocation StartLoc, 5314 SourceLocation EndLoc) { 5315 if (!AStmt) 5316 return StmtError(); 5317 5318 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5319 auto BaseStmt = AStmt; 5320 while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5321 BaseStmt = CS->getCapturedStmt(); 5322 if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5323 auto S = C->children(); 5324 if (S.begin() == S.end()) 5325 return StmtError(); 5326 // All associated statements must be '#pragma omp section' except for 5327 // the first one. 5328 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5329 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5330 if (SectionStmt) 5331 Diag(SectionStmt->getLocStart(), 5332 diag::err_omp_parallel_sections_substmt_not_section); 5333 return StmtError(); 5334 } 5335 cast<OMPSectionDirective>(SectionStmt) 5336 ->setHasCancel(DSAStack->isCancelRegion()); 5337 } 5338 } else { 5339 Diag(AStmt->getLocStart(), 5340 diag::err_omp_parallel_sections_not_compound_stmt); 5341 return StmtError(); 5342 } 5343 5344 getCurFunction()->setHasBranchProtectedScope(); 5345 5346 return OMPParallelSectionsDirective::Create( 5347 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 5348 } 5349 5350 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 5351 Stmt *AStmt, SourceLocation StartLoc, 5352 SourceLocation EndLoc) { 5353 if (!AStmt) 5354 return StmtError(); 5355 5356 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5357 // 1.2.2 OpenMP Language Terminology 5358 // Structured block - An executable statement with a single entry at the 5359 // top and a single exit at the bottom. 5360 // The point of exit cannot be a branch out of the structured block. 5361 // longjmp() and throw() must not violate the entry/exit criteria. 5362 CS->getCapturedDecl()->setNothrow(); 5363 5364 getCurFunction()->setHasBranchProtectedScope(); 5365 5366 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5367 DSAStack->isCancelRegion()); 5368 } 5369 5370 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 5371 SourceLocation EndLoc) { 5372 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 5373 } 5374 5375 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 5376 SourceLocation EndLoc) { 5377 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 5378 } 5379 5380 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 5381 SourceLocation EndLoc) { 5382 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 5383 } 5384 5385 StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt, 5386 SourceLocation StartLoc, 5387 SourceLocation EndLoc) { 5388 if (!AStmt) 5389 return StmtError(); 5390 5391 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5392 5393 getCurFunction()->setHasBranchProtectedScope(); 5394 5395 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, AStmt); 5396 } 5397 5398 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 5399 SourceLocation StartLoc, 5400 SourceLocation EndLoc) { 5401 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 5402 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 5403 } 5404 5405 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 5406 Stmt *AStmt, 5407 SourceLocation StartLoc, 5408 SourceLocation EndLoc) { 5409 OMPClause *DependFound = nullptr; 5410 OMPClause *DependSourceClause = nullptr; 5411 OMPClause *DependSinkClause = nullptr; 5412 bool ErrorFound = false; 5413 OMPThreadsClause *TC = nullptr; 5414 OMPSIMDClause *SC = nullptr; 5415 for (auto *C : Clauses) { 5416 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 5417 DependFound = C; 5418 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 5419 if (DependSourceClause) { 5420 Diag(C->getLocStart(), diag::err_omp_more_one_clause) 5421 << getOpenMPDirectiveName(OMPD_ordered) 5422 << getOpenMPClauseName(OMPC_depend) << 2; 5423 ErrorFound = true; 5424 } else 5425 DependSourceClause = C; 5426 if (DependSinkClause) { 5427 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5428 << 0; 5429 ErrorFound = true; 5430 } 5431 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 5432 if (DependSourceClause) { 5433 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5434 << 1; 5435 ErrorFound = true; 5436 } 5437 DependSinkClause = C; 5438 } 5439 } else if (C->getClauseKind() == OMPC_threads) 5440 TC = cast<OMPThreadsClause>(C); 5441 else if (C->getClauseKind() == OMPC_simd) 5442 SC = cast<OMPSIMDClause>(C); 5443 } 5444 if (!ErrorFound && !SC && 5445 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 5446 // OpenMP [2.8.1,simd Construct, Restrictions] 5447 // An ordered construct with the simd clause is the only OpenMP construct 5448 // that can appear in the simd region. 5449 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 5450 ErrorFound = true; 5451 } else if (DependFound && (TC || SC)) { 5452 Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd) 5453 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 5454 ErrorFound = true; 5455 } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) { 5456 Diag(DependFound->getLocStart(), 5457 diag::err_omp_ordered_directive_without_param); 5458 ErrorFound = true; 5459 } else if (TC || Clauses.empty()) { 5460 if (auto *Param = DSAStack->getParentOrderedRegionParam()) { 5461 SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc; 5462 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 5463 << (TC != nullptr); 5464 Diag(Param->getLocStart(), diag::note_omp_ordered_param); 5465 ErrorFound = true; 5466 } 5467 } 5468 if ((!AStmt && !DependFound) || ErrorFound) 5469 return StmtError(); 5470 5471 if (AStmt) { 5472 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5473 5474 getCurFunction()->setHasBranchProtectedScope(); 5475 } 5476 5477 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5478 } 5479 5480 namespace { 5481 /// \brief Helper class for checking expression in 'omp atomic [update]' 5482 /// construct. 5483 class OpenMPAtomicUpdateChecker { 5484 /// \brief Error results for atomic update expressions. 5485 enum ExprAnalysisErrorCode { 5486 /// \brief A statement is not an expression statement. 5487 NotAnExpression, 5488 /// \brief Expression is not builtin binary or unary operation. 5489 NotABinaryOrUnaryExpression, 5490 /// \brief Unary operation is not post-/pre- increment/decrement operation. 5491 NotAnUnaryIncDecExpression, 5492 /// \brief An expression is not of scalar type. 5493 NotAScalarType, 5494 /// \brief A binary operation is not an assignment operation. 5495 NotAnAssignmentOp, 5496 /// \brief RHS part of the binary operation is not a binary expression. 5497 NotABinaryExpression, 5498 /// \brief RHS part is not additive/multiplicative/shift/biwise binary 5499 /// expression. 5500 NotABinaryOperator, 5501 /// \brief RHS binary operation does not have reference to the updated LHS 5502 /// part. 5503 NotAnUpdateExpression, 5504 /// \brief No errors is found. 5505 NoError 5506 }; 5507 /// \brief Reference to Sema. 5508 Sema &SemaRef; 5509 /// \brief A location for note diagnostics (when error is found). 5510 SourceLocation NoteLoc; 5511 /// \brief 'x' lvalue part of the source atomic expression. 5512 Expr *X; 5513 /// \brief 'expr' rvalue part of the source atomic expression. 5514 Expr *E; 5515 /// \brief Helper expression of the form 5516 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5517 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5518 Expr *UpdateExpr; 5519 /// \brief Is 'x' a LHS in a RHS part of full update expression. It is 5520 /// important for non-associative operations. 5521 bool IsXLHSInRHSPart; 5522 BinaryOperatorKind Op; 5523 SourceLocation OpLoc; 5524 /// \brief true if the source expression is a postfix unary operation, false 5525 /// if it is a prefix unary operation. 5526 bool IsPostfixUpdate; 5527 5528 public: 5529 OpenMPAtomicUpdateChecker(Sema &SemaRef) 5530 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 5531 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 5532 /// \brief Check specified statement that it is suitable for 'atomic update' 5533 /// constructs and extract 'x', 'expr' and Operation from the original 5534 /// expression. If DiagId and NoteId == 0, then only check is performed 5535 /// without error notification. 5536 /// \param DiagId Diagnostic which should be emitted if error is found. 5537 /// \param NoteId Diagnostic note for the main error message. 5538 /// \return true if statement is not an update expression, false otherwise. 5539 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 5540 /// \brief Return the 'x' lvalue part of the source atomic expression. 5541 Expr *getX() const { return X; } 5542 /// \brief Return the 'expr' rvalue part of the source atomic expression. 5543 Expr *getExpr() const { return E; } 5544 /// \brief Return the update expression used in calculation of the updated 5545 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5546 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5547 Expr *getUpdateExpr() const { return UpdateExpr; } 5548 /// \brief Return true if 'x' is LHS in RHS part of full update expression, 5549 /// false otherwise. 5550 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 5551 5552 /// \brief true if the source expression is a postfix unary operation, false 5553 /// if it is a prefix unary operation. 5554 bool isPostfixUpdate() const { return IsPostfixUpdate; } 5555 5556 private: 5557 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 5558 unsigned NoteId = 0); 5559 }; 5560 } // namespace 5561 5562 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 5563 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 5564 ExprAnalysisErrorCode ErrorFound = NoError; 5565 SourceLocation ErrorLoc, NoteLoc; 5566 SourceRange ErrorRange, NoteRange; 5567 // Allowed constructs are: 5568 // x = x binop expr; 5569 // x = expr binop x; 5570 if (AtomicBinOp->getOpcode() == BO_Assign) { 5571 X = AtomicBinOp->getLHS(); 5572 if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 5573 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 5574 if (AtomicInnerBinOp->isMultiplicativeOp() || 5575 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 5576 AtomicInnerBinOp->isBitwiseOp()) { 5577 Op = AtomicInnerBinOp->getOpcode(); 5578 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 5579 auto *LHS = AtomicInnerBinOp->getLHS(); 5580 auto *RHS = AtomicInnerBinOp->getRHS(); 5581 llvm::FoldingSetNodeID XId, LHSId, RHSId; 5582 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 5583 /*Canonical=*/true); 5584 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 5585 /*Canonical=*/true); 5586 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 5587 /*Canonical=*/true); 5588 if (XId == LHSId) { 5589 E = RHS; 5590 IsXLHSInRHSPart = true; 5591 } else if (XId == RHSId) { 5592 E = LHS; 5593 IsXLHSInRHSPart = false; 5594 } else { 5595 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5596 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5597 NoteLoc = X->getExprLoc(); 5598 NoteRange = X->getSourceRange(); 5599 ErrorFound = NotAnUpdateExpression; 5600 } 5601 } else { 5602 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5603 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5604 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 5605 NoteRange = SourceRange(NoteLoc, NoteLoc); 5606 ErrorFound = NotABinaryOperator; 5607 } 5608 } else { 5609 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 5610 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 5611 ErrorFound = NotABinaryExpression; 5612 } 5613 } else { 5614 ErrorLoc = AtomicBinOp->getExprLoc(); 5615 ErrorRange = AtomicBinOp->getSourceRange(); 5616 NoteLoc = AtomicBinOp->getOperatorLoc(); 5617 NoteRange = SourceRange(NoteLoc, NoteLoc); 5618 ErrorFound = NotAnAssignmentOp; 5619 } 5620 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5621 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5622 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5623 return true; 5624 } else if (SemaRef.CurContext->isDependentContext()) 5625 E = X = UpdateExpr = nullptr; 5626 return ErrorFound != NoError; 5627 } 5628 5629 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 5630 unsigned NoteId) { 5631 ExprAnalysisErrorCode ErrorFound = NoError; 5632 SourceLocation ErrorLoc, NoteLoc; 5633 SourceRange ErrorRange, NoteRange; 5634 // Allowed constructs are: 5635 // x++; 5636 // x--; 5637 // ++x; 5638 // --x; 5639 // x binop= expr; 5640 // x = x binop expr; 5641 // x = expr binop x; 5642 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 5643 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 5644 if (AtomicBody->getType()->isScalarType() || 5645 AtomicBody->isInstantiationDependent()) { 5646 if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 5647 AtomicBody->IgnoreParenImpCasts())) { 5648 // Check for Compound Assignment Operation 5649 Op = BinaryOperator::getOpForCompoundAssignment( 5650 AtomicCompAssignOp->getOpcode()); 5651 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 5652 E = AtomicCompAssignOp->getRHS(); 5653 X = AtomicCompAssignOp->getLHS(); 5654 IsXLHSInRHSPart = true; 5655 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 5656 AtomicBody->IgnoreParenImpCasts())) { 5657 // Check for Binary Operation 5658 if(checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 5659 return true; 5660 } else if (auto *AtomicUnaryOp = 5661 dyn_cast<UnaryOperator>(AtomicBody->IgnoreParenImpCasts())) { 5662 // Check for Unary Operation 5663 if (AtomicUnaryOp->isIncrementDecrementOp()) { 5664 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 5665 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 5666 OpLoc = AtomicUnaryOp->getOperatorLoc(); 5667 X = AtomicUnaryOp->getSubExpr(); 5668 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 5669 IsXLHSInRHSPart = true; 5670 } else { 5671 ErrorFound = NotAnUnaryIncDecExpression; 5672 ErrorLoc = AtomicUnaryOp->getExprLoc(); 5673 ErrorRange = AtomicUnaryOp->getSourceRange(); 5674 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 5675 NoteRange = SourceRange(NoteLoc, NoteLoc); 5676 } 5677 } else if (!AtomicBody->isInstantiationDependent()) { 5678 ErrorFound = NotABinaryOrUnaryExpression; 5679 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 5680 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 5681 } 5682 } else { 5683 ErrorFound = NotAScalarType; 5684 NoteLoc = ErrorLoc = AtomicBody->getLocStart(); 5685 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5686 } 5687 } else { 5688 ErrorFound = NotAnExpression; 5689 NoteLoc = ErrorLoc = S->getLocStart(); 5690 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5691 } 5692 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5693 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5694 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5695 return true; 5696 } else if (SemaRef.CurContext->isDependentContext()) 5697 E = X = UpdateExpr = nullptr; 5698 if (ErrorFound == NoError && E && X) { 5699 // Build an update expression of form 'OpaqueValueExpr(x) binop 5700 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 5701 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 5702 auto *OVEX = new (SemaRef.getASTContext()) 5703 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 5704 auto *OVEExpr = new (SemaRef.getASTContext()) 5705 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 5706 auto Update = 5707 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 5708 IsXLHSInRHSPart ? OVEExpr : OVEX); 5709 if (Update.isInvalid()) 5710 return true; 5711 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 5712 Sema::AA_Casting); 5713 if (Update.isInvalid()) 5714 return true; 5715 UpdateExpr = Update.get(); 5716 } 5717 return ErrorFound != NoError; 5718 } 5719 5720 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 5721 Stmt *AStmt, 5722 SourceLocation StartLoc, 5723 SourceLocation EndLoc) { 5724 if (!AStmt) 5725 return StmtError(); 5726 5727 auto CS = cast<CapturedStmt>(AStmt); 5728 // 1.2.2 OpenMP Language Terminology 5729 // Structured block - An executable statement with a single entry at the 5730 // top and a single exit at the bottom. 5731 // The point of exit cannot be a branch out of the structured block. 5732 // longjmp() and throw() must not violate the entry/exit criteria. 5733 OpenMPClauseKind AtomicKind = OMPC_unknown; 5734 SourceLocation AtomicKindLoc; 5735 for (auto *C : Clauses) { 5736 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 5737 C->getClauseKind() == OMPC_update || 5738 C->getClauseKind() == OMPC_capture) { 5739 if (AtomicKind != OMPC_unknown) { 5740 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) 5741 << SourceRange(C->getLocStart(), C->getLocEnd()); 5742 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 5743 << getOpenMPClauseName(AtomicKind); 5744 } else { 5745 AtomicKind = C->getClauseKind(); 5746 AtomicKindLoc = C->getLocStart(); 5747 } 5748 } 5749 } 5750 5751 auto Body = CS->getCapturedStmt(); 5752 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 5753 Body = EWC->getSubExpr(); 5754 5755 Expr *X = nullptr; 5756 Expr *V = nullptr; 5757 Expr *E = nullptr; 5758 Expr *UE = nullptr; 5759 bool IsXLHSInRHSPart = false; 5760 bool IsPostfixUpdate = false; 5761 // OpenMP [2.12.6, atomic Construct] 5762 // In the next expressions: 5763 // * x and v (as applicable) are both l-value expressions with scalar type. 5764 // * During the execution of an atomic region, multiple syntactic 5765 // occurrences of x must designate the same storage location. 5766 // * Neither of v and expr (as applicable) may access the storage location 5767 // designated by x. 5768 // * Neither of x and expr (as applicable) may access the storage location 5769 // designated by v. 5770 // * expr is an expression with scalar type. 5771 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 5772 // * binop, binop=, ++, and -- are not overloaded operators. 5773 // * The expression x binop expr must be numerically equivalent to x binop 5774 // (expr). This requirement is satisfied if the operators in expr have 5775 // precedence greater than binop, or by using parentheses around expr or 5776 // subexpressions of expr. 5777 // * The expression expr binop x must be numerically equivalent to (expr) 5778 // binop x. This requirement is satisfied if the operators in expr have 5779 // precedence equal to or greater than binop, or by using parentheses around 5780 // expr or subexpressions of expr. 5781 // * For forms that allow multiple occurrences of x, the number of times 5782 // that x is evaluated is unspecified. 5783 if (AtomicKind == OMPC_read) { 5784 enum { 5785 NotAnExpression, 5786 NotAnAssignmentOp, 5787 NotAScalarType, 5788 NotAnLValue, 5789 NoError 5790 } ErrorFound = NoError; 5791 SourceLocation ErrorLoc, NoteLoc; 5792 SourceRange ErrorRange, NoteRange; 5793 // If clause is read: 5794 // v = x; 5795 if (auto AtomicBody = dyn_cast<Expr>(Body)) { 5796 auto AtomicBinOp = 5797 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5798 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5799 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 5800 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 5801 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 5802 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 5803 if (!X->isLValue() || !V->isLValue()) { 5804 auto NotLValueExpr = X->isLValue() ? V : X; 5805 ErrorFound = NotAnLValue; 5806 ErrorLoc = AtomicBinOp->getExprLoc(); 5807 ErrorRange = AtomicBinOp->getSourceRange(); 5808 NoteLoc = NotLValueExpr->getExprLoc(); 5809 NoteRange = NotLValueExpr->getSourceRange(); 5810 } 5811 } else if (!X->isInstantiationDependent() || 5812 !V->isInstantiationDependent()) { 5813 auto NotScalarExpr = 5814 (X->isInstantiationDependent() || X->getType()->isScalarType()) 5815 ? V 5816 : X; 5817 ErrorFound = NotAScalarType; 5818 ErrorLoc = AtomicBinOp->getExprLoc(); 5819 ErrorRange = AtomicBinOp->getSourceRange(); 5820 NoteLoc = NotScalarExpr->getExprLoc(); 5821 NoteRange = NotScalarExpr->getSourceRange(); 5822 } 5823 } else if (!AtomicBody->isInstantiationDependent()) { 5824 ErrorFound = NotAnAssignmentOp; 5825 ErrorLoc = AtomicBody->getExprLoc(); 5826 ErrorRange = AtomicBody->getSourceRange(); 5827 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5828 : AtomicBody->getExprLoc(); 5829 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5830 : AtomicBody->getSourceRange(); 5831 } 5832 } else { 5833 ErrorFound = NotAnExpression; 5834 NoteLoc = ErrorLoc = Body->getLocStart(); 5835 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5836 } 5837 if (ErrorFound != NoError) { 5838 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 5839 << ErrorRange; 5840 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 5841 << NoteRange; 5842 return StmtError(); 5843 } else if (CurContext->isDependentContext()) 5844 V = X = nullptr; 5845 } else if (AtomicKind == OMPC_write) { 5846 enum { 5847 NotAnExpression, 5848 NotAnAssignmentOp, 5849 NotAScalarType, 5850 NotAnLValue, 5851 NoError 5852 } ErrorFound = NoError; 5853 SourceLocation ErrorLoc, NoteLoc; 5854 SourceRange ErrorRange, NoteRange; 5855 // If clause is write: 5856 // x = expr; 5857 if (auto AtomicBody = dyn_cast<Expr>(Body)) { 5858 auto AtomicBinOp = 5859 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5860 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5861 X = AtomicBinOp->getLHS(); 5862 E = AtomicBinOp->getRHS(); 5863 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 5864 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 5865 if (!X->isLValue()) { 5866 ErrorFound = NotAnLValue; 5867 ErrorLoc = AtomicBinOp->getExprLoc(); 5868 ErrorRange = AtomicBinOp->getSourceRange(); 5869 NoteLoc = X->getExprLoc(); 5870 NoteRange = X->getSourceRange(); 5871 } 5872 } else if (!X->isInstantiationDependent() || 5873 !E->isInstantiationDependent()) { 5874 auto NotScalarExpr = 5875 (X->isInstantiationDependent() || X->getType()->isScalarType()) 5876 ? E 5877 : X; 5878 ErrorFound = NotAScalarType; 5879 ErrorLoc = AtomicBinOp->getExprLoc(); 5880 ErrorRange = AtomicBinOp->getSourceRange(); 5881 NoteLoc = NotScalarExpr->getExprLoc(); 5882 NoteRange = NotScalarExpr->getSourceRange(); 5883 } 5884 } else if (!AtomicBody->isInstantiationDependent()) { 5885 ErrorFound = NotAnAssignmentOp; 5886 ErrorLoc = AtomicBody->getExprLoc(); 5887 ErrorRange = AtomicBody->getSourceRange(); 5888 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5889 : AtomicBody->getExprLoc(); 5890 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5891 : AtomicBody->getSourceRange(); 5892 } 5893 } else { 5894 ErrorFound = NotAnExpression; 5895 NoteLoc = ErrorLoc = Body->getLocStart(); 5896 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5897 } 5898 if (ErrorFound != NoError) { 5899 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 5900 << ErrorRange; 5901 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 5902 << NoteRange; 5903 return StmtError(); 5904 } else if (CurContext->isDependentContext()) 5905 E = X = nullptr; 5906 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 5907 // If clause is update: 5908 // x++; 5909 // x--; 5910 // ++x; 5911 // --x; 5912 // x binop= expr; 5913 // x = x binop expr; 5914 // x = expr binop x; 5915 OpenMPAtomicUpdateChecker Checker(*this); 5916 if (Checker.checkStatement( 5917 Body, (AtomicKind == OMPC_update) 5918 ? diag::err_omp_atomic_update_not_expression_statement 5919 : diag::err_omp_atomic_not_expression_statement, 5920 diag::note_omp_atomic_update)) 5921 return StmtError(); 5922 if (!CurContext->isDependentContext()) { 5923 E = Checker.getExpr(); 5924 X = Checker.getX(); 5925 UE = Checker.getUpdateExpr(); 5926 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5927 } 5928 } else if (AtomicKind == OMPC_capture) { 5929 enum { 5930 NotAnAssignmentOp, 5931 NotACompoundStatement, 5932 NotTwoSubstatements, 5933 NotASpecificExpression, 5934 NoError 5935 } ErrorFound = NoError; 5936 SourceLocation ErrorLoc, NoteLoc; 5937 SourceRange ErrorRange, NoteRange; 5938 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 5939 // If clause is a capture: 5940 // v = x++; 5941 // v = x--; 5942 // v = ++x; 5943 // v = --x; 5944 // v = x binop= expr; 5945 // v = x = x binop expr; 5946 // v = x = expr binop x; 5947 auto *AtomicBinOp = 5948 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5949 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5950 V = AtomicBinOp->getLHS(); 5951 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 5952 OpenMPAtomicUpdateChecker Checker(*this); 5953 if (Checker.checkStatement( 5954 Body, diag::err_omp_atomic_capture_not_expression_statement, 5955 diag::note_omp_atomic_update)) 5956 return StmtError(); 5957 E = Checker.getExpr(); 5958 X = Checker.getX(); 5959 UE = Checker.getUpdateExpr(); 5960 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5961 IsPostfixUpdate = Checker.isPostfixUpdate(); 5962 } else if (!AtomicBody->isInstantiationDependent()) { 5963 ErrorLoc = AtomicBody->getExprLoc(); 5964 ErrorRange = AtomicBody->getSourceRange(); 5965 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5966 : AtomicBody->getExprLoc(); 5967 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5968 : AtomicBody->getSourceRange(); 5969 ErrorFound = NotAnAssignmentOp; 5970 } 5971 if (ErrorFound != NoError) { 5972 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 5973 << ErrorRange; 5974 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 5975 return StmtError(); 5976 } else if (CurContext->isDependentContext()) { 5977 UE = V = E = X = nullptr; 5978 } 5979 } else { 5980 // If clause is a capture: 5981 // { v = x; x = expr; } 5982 // { v = x; x++; } 5983 // { v = x; x--; } 5984 // { v = x; ++x; } 5985 // { v = x; --x; } 5986 // { v = x; x binop= expr; } 5987 // { v = x; x = x binop expr; } 5988 // { v = x; x = expr binop x; } 5989 // { x++; v = x; } 5990 // { x--; v = x; } 5991 // { ++x; v = x; } 5992 // { --x; v = x; } 5993 // { x binop= expr; v = x; } 5994 // { x = x binop expr; v = x; } 5995 // { x = expr binop x; v = x; } 5996 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 5997 // Check that this is { expr1; expr2; } 5998 if (CS->size() == 2) { 5999 auto *First = CS->body_front(); 6000 auto *Second = CS->body_back(); 6001 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 6002 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 6003 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 6004 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 6005 // Need to find what subexpression is 'v' and what is 'x'. 6006 OpenMPAtomicUpdateChecker Checker(*this); 6007 bool IsUpdateExprFound = !Checker.checkStatement(Second); 6008 BinaryOperator *BinOp = nullptr; 6009 if (IsUpdateExprFound) { 6010 BinOp = dyn_cast<BinaryOperator>(First); 6011 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6012 } 6013 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6014 // { v = x; x++; } 6015 // { v = x; x--; } 6016 // { v = x; ++x; } 6017 // { v = x; --x; } 6018 // { v = x; x binop= expr; } 6019 // { v = x; x = x binop expr; } 6020 // { v = x; x = expr binop x; } 6021 // Check that the first expression has form v = x. 6022 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6023 llvm::FoldingSetNodeID XId, PossibleXId; 6024 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6025 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6026 IsUpdateExprFound = XId == PossibleXId; 6027 if (IsUpdateExprFound) { 6028 V = BinOp->getLHS(); 6029 X = Checker.getX(); 6030 E = Checker.getExpr(); 6031 UE = Checker.getUpdateExpr(); 6032 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6033 IsPostfixUpdate = true; 6034 } 6035 } 6036 if (!IsUpdateExprFound) { 6037 IsUpdateExprFound = !Checker.checkStatement(First); 6038 BinOp = nullptr; 6039 if (IsUpdateExprFound) { 6040 BinOp = dyn_cast<BinaryOperator>(Second); 6041 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6042 } 6043 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6044 // { x++; v = x; } 6045 // { x--; v = x; } 6046 // { ++x; v = x; } 6047 // { --x; v = x; } 6048 // { x binop= expr; v = x; } 6049 // { x = x binop expr; v = x; } 6050 // { x = expr binop x; v = x; } 6051 // Check that the second expression has form v = x. 6052 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6053 llvm::FoldingSetNodeID XId, PossibleXId; 6054 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6055 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6056 IsUpdateExprFound = XId == PossibleXId; 6057 if (IsUpdateExprFound) { 6058 V = BinOp->getLHS(); 6059 X = Checker.getX(); 6060 E = Checker.getExpr(); 6061 UE = Checker.getUpdateExpr(); 6062 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6063 IsPostfixUpdate = false; 6064 } 6065 } 6066 } 6067 if (!IsUpdateExprFound) { 6068 // { v = x; x = expr; } 6069 auto *FirstExpr = dyn_cast<Expr>(First); 6070 auto *SecondExpr = dyn_cast<Expr>(Second); 6071 if (!FirstExpr || !SecondExpr || 6072 !(FirstExpr->isInstantiationDependent() || 6073 SecondExpr->isInstantiationDependent())) { 6074 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 6075 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 6076 ErrorFound = NotAnAssignmentOp; 6077 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 6078 : First->getLocStart(); 6079 NoteRange = ErrorRange = FirstBinOp 6080 ? FirstBinOp->getSourceRange() 6081 : SourceRange(ErrorLoc, ErrorLoc); 6082 } else { 6083 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 6084 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 6085 ErrorFound = NotAnAssignmentOp; 6086 NoteLoc = ErrorLoc = SecondBinOp 6087 ? SecondBinOp->getOperatorLoc() 6088 : Second->getLocStart(); 6089 NoteRange = ErrorRange = 6090 SecondBinOp ? SecondBinOp->getSourceRange() 6091 : SourceRange(ErrorLoc, ErrorLoc); 6092 } else { 6093 auto *PossibleXRHSInFirst = 6094 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 6095 auto *PossibleXLHSInSecond = 6096 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 6097 llvm::FoldingSetNodeID X1Id, X2Id; 6098 PossibleXRHSInFirst->Profile(X1Id, Context, 6099 /*Canonical=*/true); 6100 PossibleXLHSInSecond->Profile(X2Id, Context, 6101 /*Canonical=*/true); 6102 IsUpdateExprFound = X1Id == X2Id; 6103 if (IsUpdateExprFound) { 6104 V = FirstBinOp->getLHS(); 6105 X = SecondBinOp->getLHS(); 6106 E = SecondBinOp->getRHS(); 6107 UE = nullptr; 6108 IsXLHSInRHSPart = false; 6109 IsPostfixUpdate = true; 6110 } else { 6111 ErrorFound = NotASpecificExpression; 6112 ErrorLoc = FirstBinOp->getExprLoc(); 6113 ErrorRange = FirstBinOp->getSourceRange(); 6114 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 6115 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 6116 } 6117 } 6118 } 6119 } 6120 } 6121 } else { 6122 NoteLoc = ErrorLoc = Body->getLocStart(); 6123 NoteRange = ErrorRange = 6124 SourceRange(Body->getLocStart(), Body->getLocStart()); 6125 ErrorFound = NotTwoSubstatements; 6126 } 6127 } else { 6128 NoteLoc = ErrorLoc = Body->getLocStart(); 6129 NoteRange = ErrorRange = 6130 SourceRange(Body->getLocStart(), Body->getLocStart()); 6131 ErrorFound = NotACompoundStatement; 6132 } 6133 if (ErrorFound != NoError) { 6134 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 6135 << ErrorRange; 6136 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6137 return StmtError(); 6138 } else if (CurContext->isDependentContext()) { 6139 UE = V = E = X = nullptr; 6140 } 6141 } 6142 } 6143 6144 getCurFunction()->setHasBranchProtectedScope(); 6145 6146 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6147 X, V, E, UE, IsXLHSInRHSPart, 6148 IsPostfixUpdate); 6149 } 6150 6151 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 6152 Stmt *AStmt, 6153 SourceLocation StartLoc, 6154 SourceLocation EndLoc) { 6155 if (!AStmt) 6156 return StmtError(); 6157 6158 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6159 // 1.2.2 OpenMP Language Terminology 6160 // Structured block - An executable statement with a single entry at the 6161 // top and a single exit at the bottom. 6162 // The point of exit cannot be a branch out of the structured block. 6163 // longjmp() and throw() must not violate the entry/exit criteria. 6164 CS->getCapturedDecl()->setNothrow(); 6165 6166 // OpenMP [2.16, Nesting of Regions] 6167 // If specified, a teams construct must be contained within a target 6168 // construct. That target construct must contain no statements or directives 6169 // outside of the teams construct. 6170 if (DSAStack->hasInnerTeamsRegion()) { 6171 auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true); 6172 bool OMPTeamsFound = true; 6173 if (auto *CS = dyn_cast<CompoundStmt>(S)) { 6174 auto I = CS->body_begin(); 6175 while (I != CS->body_end()) { 6176 auto OED = dyn_cast<OMPExecutableDirective>(*I); 6177 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { 6178 OMPTeamsFound = false; 6179 break; 6180 } 6181 ++I; 6182 } 6183 assert(I != CS->body_end() && "Not found statement"); 6184 S = *I; 6185 } 6186 if (!OMPTeamsFound) { 6187 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 6188 Diag(DSAStack->getInnerTeamsRegionLoc(), 6189 diag::note_omp_nested_teams_construct_here); 6190 Diag(S->getLocStart(), diag::note_omp_nested_statement_here) 6191 << isa<OMPExecutableDirective>(S); 6192 return StmtError(); 6193 } 6194 } 6195 6196 getCurFunction()->setHasBranchProtectedScope(); 6197 6198 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6199 } 6200 6201 StmtResult 6202 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 6203 Stmt *AStmt, SourceLocation StartLoc, 6204 SourceLocation EndLoc) { 6205 if (!AStmt) 6206 return StmtError(); 6207 6208 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6209 // 1.2.2 OpenMP Language Terminology 6210 // Structured block - An executable statement with a single entry at the 6211 // top and a single exit at the bottom. 6212 // The point of exit cannot be a branch out of the structured block. 6213 // longjmp() and throw() must not violate the entry/exit criteria. 6214 CS->getCapturedDecl()->setNothrow(); 6215 6216 getCurFunction()->setHasBranchProtectedScope(); 6217 6218 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6219 AStmt); 6220 } 6221 6222 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 6223 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6224 SourceLocation EndLoc, 6225 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6226 if (!AStmt) 6227 return StmtError(); 6228 6229 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6230 // 1.2.2 OpenMP Language Terminology 6231 // Structured block - An executable statement with a single entry at the 6232 // top and a single exit at the bottom. 6233 // The point of exit cannot be a branch out of the structured block. 6234 // longjmp() and throw() must not violate the entry/exit criteria. 6235 CS->getCapturedDecl()->setNothrow(); 6236 6237 OMPLoopDirective::HelperExprs B; 6238 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6239 // define the nested loops number. 6240 unsigned NestedLoopCount = 6241 CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 6242 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6243 VarsWithImplicitDSA, B); 6244 if (NestedLoopCount == 0) 6245 return StmtError(); 6246 6247 assert((CurContext->isDependentContext() || B.builtAll()) && 6248 "omp target parallel for loop exprs were not built"); 6249 6250 if (!CurContext->isDependentContext()) { 6251 // Finalize the clauses that need pre-built expressions for CodeGen. 6252 for (auto C : Clauses) { 6253 if (auto LC = dyn_cast<OMPLinearClause>(C)) 6254 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6255 B.NumIterations, *this, CurScope)) 6256 return StmtError(); 6257 } 6258 } 6259 6260 getCurFunction()->setHasBranchProtectedScope(); 6261 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 6262 NestedLoopCount, Clauses, AStmt, 6263 B, DSAStack->isCancelRegion()); 6264 } 6265 6266 /// \brief Check for existence of a map clause in the list of clauses. 6267 static bool HasMapClause(ArrayRef<OMPClause *> Clauses) { 6268 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end(); 6269 I != E; ++I) { 6270 if (*I != nullptr && (*I)->getClauseKind() == OMPC_map) { 6271 return true; 6272 } 6273 } 6274 6275 return false; 6276 } 6277 6278 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 6279 Stmt *AStmt, 6280 SourceLocation StartLoc, 6281 SourceLocation EndLoc) { 6282 if (!AStmt) 6283 return StmtError(); 6284 6285 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6286 6287 // OpenMP [2.10.1, Restrictions, p. 97] 6288 // At least one map clause must appear on the directive. 6289 if (!HasMapClause(Clauses)) { 6290 Diag(StartLoc, diag::err_omp_no_map_for_directive) << 6291 getOpenMPDirectiveName(OMPD_target_data); 6292 return StmtError(); 6293 } 6294 6295 getCurFunction()->setHasBranchProtectedScope(); 6296 6297 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 6298 AStmt); 6299 } 6300 6301 StmtResult 6302 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 6303 SourceLocation StartLoc, 6304 SourceLocation EndLoc) { 6305 // OpenMP [2.10.2, Restrictions, p. 99] 6306 // At least one map clause must appear on the directive. 6307 if (!HasMapClause(Clauses)) { 6308 Diag(StartLoc, diag::err_omp_no_map_for_directive) 6309 << getOpenMPDirectiveName(OMPD_target_enter_data); 6310 return StmtError(); 6311 } 6312 6313 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, 6314 Clauses); 6315 } 6316 6317 StmtResult 6318 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 6319 SourceLocation StartLoc, 6320 SourceLocation EndLoc) { 6321 // OpenMP [2.10.3, Restrictions, p. 102] 6322 // At least one map clause must appear on the directive. 6323 if (!HasMapClause(Clauses)) { 6324 Diag(StartLoc, diag::err_omp_no_map_for_directive) 6325 << getOpenMPDirectiveName(OMPD_target_exit_data); 6326 return StmtError(); 6327 } 6328 6329 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses); 6330 } 6331 6332 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 6333 Stmt *AStmt, SourceLocation StartLoc, 6334 SourceLocation EndLoc) { 6335 if (!AStmt) 6336 return StmtError(); 6337 6338 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6339 // 1.2.2 OpenMP Language Terminology 6340 // Structured block - An executable statement with a single entry at the 6341 // top and a single exit at the bottom. 6342 // The point of exit cannot be a branch out of the structured block. 6343 // longjmp() and throw() must not violate the entry/exit criteria. 6344 CS->getCapturedDecl()->setNothrow(); 6345 6346 getCurFunction()->setHasBranchProtectedScope(); 6347 6348 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6349 } 6350 6351 StmtResult 6352 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 6353 SourceLocation EndLoc, 6354 OpenMPDirectiveKind CancelRegion) { 6355 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for && 6356 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) { 6357 Diag(StartLoc, diag::err_omp_wrong_cancel_region) 6358 << getOpenMPDirectiveName(CancelRegion); 6359 return StmtError(); 6360 } 6361 if (DSAStack->isParentNowaitRegion()) { 6362 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 6363 return StmtError(); 6364 } 6365 if (DSAStack->isParentOrderedRegion()) { 6366 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 6367 return StmtError(); 6368 } 6369 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 6370 CancelRegion); 6371 } 6372 6373 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 6374 SourceLocation StartLoc, 6375 SourceLocation EndLoc, 6376 OpenMPDirectiveKind CancelRegion) { 6377 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for && 6378 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) { 6379 Diag(StartLoc, diag::err_omp_wrong_cancel_region) 6380 << getOpenMPDirectiveName(CancelRegion); 6381 return StmtError(); 6382 } 6383 if (DSAStack->isParentNowaitRegion()) { 6384 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 6385 return StmtError(); 6386 } 6387 if (DSAStack->isParentOrderedRegion()) { 6388 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 6389 return StmtError(); 6390 } 6391 DSAStack->setParentCancelRegion(/*Cancel=*/true); 6392 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6393 CancelRegion); 6394 } 6395 6396 static bool checkGrainsizeNumTasksClauses(Sema &S, 6397 ArrayRef<OMPClause *> Clauses) { 6398 OMPClause *PrevClause = nullptr; 6399 bool ErrorFound = false; 6400 for (auto *C : Clauses) { 6401 if (C->getClauseKind() == OMPC_grainsize || 6402 C->getClauseKind() == OMPC_num_tasks) { 6403 if (!PrevClause) 6404 PrevClause = C; 6405 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 6406 S.Diag(C->getLocStart(), 6407 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 6408 << getOpenMPClauseName(C->getClauseKind()) 6409 << getOpenMPClauseName(PrevClause->getClauseKind()); 6410 S.Diag(PrevClause->getLocStart(), 6411 diag::note_omp_previous_grainsize_num_tasks) 6412 << getOpenMPClauseName(PrevClause->getClauseKind()); 6413 ErrorFound = true; 6414 } 6415 } 6416 } 6417 return ErrorFound; 6418 } 6419 6420 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 6421 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6422 SourceLocation EndLoc, 6423 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6424 if (!AStmt) 6425 return StmtError(); 6426 6427 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6428 OMPLoopDirective::HelperExprs B; 6429 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6430 // define the nested loops number. 6431 unsigned NestedLoopCount = 6432 CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 6433 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6434 VarsWithImplicitDSA, B); 6435 if (NestedLoopCount == 0) 6436 return StmtError(); 6437 6438 assert((CurContext->isDependentContext() || B.builtAll()) && 6439 "omp for loop exprs were not built"); 6440 6441 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6442 // The grainsize clause and num_tasks clause are mutually exclusive and may 6443 // not appear on the same taskloop directive. 6444 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6445 return StmtError(); 6446 6447 getCurFunction()->setHasBranchProtectedScope(); 6448 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 6449 NestedLoopCount, Clauses, AStmt, B); 6450 } 6451 6452 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 6453 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6454 SourceLocation EndLoc, 6455 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6456 if (!AStmt) 6457 return StmtError(); 6458 6459 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6460 OMPLoopDirective::HelperExprs B; 6461 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6462 // define the nested loops number. 6463 unsigned NestedLoopCount = 6464 CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 6465 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6466 VarsWithImplicitDSA, B); 6467 if (NestedLoopCount == 0) 6468 return StmtError(); 6469 6470 assert((CurContext->isDependentContext() || B.builtAll()) && 6471 "omp for loop exprs were not built"); 6472 6473 if (!CurContext->isDependentContext()) { 6474 // Finalize the clauses that need pre-built expressions for CodeGen. 6475 for (auto C : Clauses) { 6476 if (auto LC = dyn_cast<OMPLinearClause>(C)) 6477 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6478 B.NumIterations, *this, CurScope)) 6479 return StmtError(); 6480 } 6481 } 6482 6483 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6484 // The grainsize clause and num_tasks clause are mutually exclusive and may 6485 // not appear on the same taskloop directive. 6486 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6487 return StmtError(); 6488 6489 getCurFunction()->setHasBranchProtectedScope(); 6490 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 6491 NestedLoopCount, Clauses, AStmt, B); 6492 } 6493 6494 StmtResult Sema::ActOnOpenMPDistributeDirective( 6495 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6496 SourceLocation EndLoc, 6497 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6498 if (!AStmt) 6499 return StmtError(); 6500 6501 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6502 OMPLoopDirective::HelperExprs B; 6503 // In presence of clause 'collapse' with number of loops, it will 6504 // define the nested loops number. 6505 unsigned NestedLoopCount = 6506 CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 6507 nullptr /*ordered not a clause on distribute*/, AStmt, 6508 *this, *DSAStack, VarsWithImplicitDSA, B); 6509 if (NestedLoopCount == 0) 6510 return StmtError(); 6511 6512 assert((CurContext->isDependentContext() || B.builtAll()) && 6513 "omp for loop exprs were not built"); 6514 6515 getCurFunction()->setHasBranchProtectedScope(); 6516 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 6517 NestedLoopCount, Clauses, AStmt, B); 6518 } 6519 6520 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 6521 SourceLocation StartLoc, 6522 SourceLocation LParenLoc, 6523 SourceLocation EndLoc) { 6524 OMPClause *Res = nullptr; 6525 switch (Kind) { 6526 case OMPC_final: 6527 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 6528 break; 6529 case OMPC_num_threads: 6530 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 6531 break; 6532 case OMPC_safelen: 6533 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 6534 break; 6535 case OMPC_simdlen: 6536 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 6537 break; 6538 case OMPC_collapse: 6539 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 6540 break; 6541 case OMPC_ordered: 6542 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 6543 break; 6544 case OMPC_device: 6545 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 6546 break; 6547 case OMPC_num_teams: 6548 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 6549 break; 6550 case OMPC_thread_limit: 6551 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 6552 break; 6553 case OMPC_priority: 6554 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 6555 break; 6556 case OMPC_grainsize: 6557 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 6558 break; 6559 case OMPC_num_tasks: 6560 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 6561 break; 6562 case OMPC_hint: 6563 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 6564 break; 6565 case OMPC_if: 6566 case OMPC_default: 6567 case OMPC_proc_bind: 6568 case OMPC_schedule: 6569 case OMPC_private: 6570 case OMPC_firstprivate: 6571 case OMPC_lastprivate: 6572 case OMPC_shared: 6573 case OMPC_reduction: 6574 case OMPC_linear: 6575 case OMPC_aligned: 6576 case OMPC_copyin: 6577 case OMPC_copyprivate: 6578 case OMPC_nowait: 6579 case OMPC_untied: 6580 case OMPC_mergeable: 6581 case OMPC_threadprivate: 6582 case OMPC_flush: 6583 case OMPC_read: 6584 case OMPC_write: 6585 case OMPC_update: 6586 case OMPC_capture: 6587 case OMPC_seq_cst: 6588 case OMPC_depend: 6589 case OMPC_threads: 6590 case OMPC_simd: 6591 case OMPC_map: 6592 case OMPC_nogroup: 6593 case OMPC_dist_schedule: 6594 case OMPC_defaultmap: 6595 case OMPC_unknown: 6596 case OMPC_uniform: 6597 llvm_unreachable("Clause is not allowed."); 6598 } 6599 return Res; 6600 } 6601 6602 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 6603 Expr *Condition, SourceLocation StartLoc, 6604 SourceLocation LParenLoc, 6605 SourceLocation NameModifierLoc, 6606 SourceLocation ColonLoc, 6607 SourceLocation EndLoc) { 6608 Expr *ValExpr = Condition; 6609 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 6610 !Condition->isInstantiationDependent() && 6611 !Condition->containsUnexpandedParameterPack()) { 6612 ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(), 6613 Condition->getExprLoc(), Condition); 6614 if (Val.isInvalid()) 6615 return nullptr; 6616 6617 ValExpr = Val.get(); 6618 } 6619 6620 return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc, 6621 NameModifierLoc, ColonLoc, EndLoc); 6622 } 6623 6624 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 6625 SourceLocation StartLoc, 6626 SourceLocation LParenLoc, 6627 SourceLocation EndLoc) { 6628 Expr *ValExpr = Condition; 6629 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 6630 !Condition->isInstantiationDependent() && 6631 !Condition->containsUnexpandedParameterPack()) { 6632 ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(), 6633 Condition->getExprLoc(), Condition); 6634 if (Val.isInvalid()) 6635 return nullptr; 6636 6637 ValExpr = Val.get(); 6638 } 6639 6640 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 6641 } 6642 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 6643 Expr *Op) { 6644 if (!Op) 6645 return ExprError(); 6646 6647 class IntConvertDiagnoser : public ICEConvertDiagnoser { 6648 public: 6649 IntConvertDiagnoser() 6650 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 6651 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 6652 QualType T) override { 6653 return S.Diag(Loc, diag::err_omp_not_integral) << T; 6654 } 6655 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 6656 QualType T) override { 6657 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 6658 } 6659 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 6660 QualType T, 6661 QualType ConvTy) override { 6662 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 6663 } 6664 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 6665 QualType ConvTy) override { 6666 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 6667 << ConvTy->isEnumeralType() << ConvTy; 6668 } 6669 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 6670 QualType T) override { 6671 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 6672 } 6673 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 6674 QualType ConvTy) override { 6675 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 6676 << ConvTy->isEnumeralType() << ConvTy; 6677 } 6678 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 6679 QualType) override { 6680 llvm_unreachable("conversion functions are permitted"); 6681 } 6682 } ConvertDiagnoser; 6683 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 6684 } 6685 6686 static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 6687 OpenMPClauseKind CKind, 6688 bool StrictlyPositive) { 6689 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 6690 !ValExpr->isInstantiationDependent()) { 6691 SourceLocation Loc = ValExpr->getExprLoc(); 6692 ExprResult Value = 6693 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 6694 if (Value.isInvalid()) 6695 return false; 6696 6697 ValExpr = Value.get(); 6698 // The expression must evaluate to a non-negative integer value. 6699 llvm::APSInt Result; 6700 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 6701 Result.isSigned() && 6702 !((!StrictlyPositive && Result.isNonNegative()) || 6703 (StrictlyPositive && Result.isStrictlyPositive()))) { 6704 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 6705 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 6706 << ValExpr->getSourceRange(); 6707 return false; 6708 } 6709 } 6710 return true; 6711 } 6712 6713 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 6714 SourceLocation StartLoc, 6715 SourceLocation LParenLoc, 6716 SourceLocation EndLoc) { 6717 Expr *ValExpr = NumThreads; 6718 6719 // OpenMP [2.5, Restrictions] 6720 // The num_threads expression must evaluate to a positive integer value. 6721 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 6722 /*StrictlyPositive=*/true)) 6723 return nullptr; 6724 6725 return new (Context) 6726 OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc); 6727 } 6728 6729 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 6730 OpenMPClauseKind CKind, 6731 bool StrictlyPositive) { 6732 if (!E) 6733 return ExprError(); 6734 if (E->isValueDependent() || E->isTypeDependent() || 6735 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 6736 return E; 6737 llvm::APSInt Result; 6738 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 6739 if (ICE.isInvalid()) 6740 return ExprError(); 6741 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 6742 (!StrictlyPositive && !Result.isNonNegative())) { 6743 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 6744 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 6745 << E->getSourceRange(); 6746 return ExprError(); 6747 } 6748 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 6749 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 6750 << E->getSourceRange(); 6751 return ExprError(); 6752 } 6753 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 6754 DSAStack->setAssociatedLoops(Result.getExtValue()); 6755 else if (CKind == OMPC_ordered) 6756 DSAStack->setAssociatedLoops(Result.getExtValue()); 6757 return ICE; 6758 } 6759 6760 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 6761 SourceLocation LParenLoc, 6762 SourceLocation EndLoc) { 6763 // OpenMP [2.8.1, simd construct, Description] 6764 // The parameter of the safelen clause must be a constant 6765 // positive integer expression. 6766 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 6767 if (Safelen.isInvalid()) 6768 return nullptr; 6769 return new (Context) 6770 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 6771 } 6772 6773 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 6774 SourceLocation LParenLoc, 6775 SourceLocation EndLoc) { 6776 // OpenMP [2.8.1, simd construct, Description] 6777 // The parameter of the simdlen clause must be a constant 6778 // positive integer expression. 6779 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 6780 if (Simdlen.isInvalid()) 6781 return nullptr; 6782 return new (Context) 6783 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 6784 } 6785 6786 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 6787 SourceLocation StartLoc, 6788 SourceLocation LParenLoc, 6789 SourceLocation EndLoc) { 6790 // OpenMP [2.7.1, loop construct, Description] 6791 // OpenMP [2.8.1, simd construct, Description] 6792 // OpenMP [2.9.6, distribute construct, Description] 6793 // The parameter of the collapse clause must be a constant 6794 // positive integer expression. 6795 ExprResult NumForLoopsResult = 6796 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 6797 if (NumForLoopsResult.isInvalid()) 6798 return nullptr; 6799 return new (Context) 6800 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 6801 } 6802 6803 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 6804 SourceLocation EndLoc, 6805 SourceLocation LParenLoc, 6806 Expr *NumForLoops) { 6807 // OpenMP [2.7.1, loop construct, Description] 6808 // OpenMP [2.8.1, simd construct, Description] 6809 // OpenMP [2.9.6, distribute construct, Description] 6810 // The parameter of the ordered clause must be a constant 6811 // positive integer expression if any. 6812 if (NumForLoops && LParenLoc.isValid()) { 6813 ExprResult NumForLoopsResult = 6814 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 6815 if (NumForLoopsResult.isInvalid()) 6816 return nullptr; 6817 NumForLoops = NumForLoopsResult.get(); 6818 } else 6819 NumForLoops = nullptr; 6820 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops); 6821 return new (Context) 6822 OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc); 6823 } 6824 6825 OMPClause *Sema::ActOnOpenMPSimpleClause( 6826 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 6827 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 6828 OMPClause *Res = nullptr; 6829 switch (Kind) { 6830 case OMPC_default: 6831 Res = 6832 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 6833 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 6834 break; 6835 case OMPC_proc_bind: 6836 Res = ActOnOpenMPProcBindClause( 6837 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 6838 LParenLoc, EndLoc); 6839 break; 6840 case OMPC_if: 6841 case OMPC_final: 6842 case OMPC_num_threads: 6843 case OMPC_safelen: 6844 case OMPC_simdlen: 6845 case OMPC_collapse: 6846 case OMPC_schedule: 6847 case OMPC_private: 6848 case OMPC_firstprivate: 6849 case OMPC_lastprivate: 6850 case OMPC_shared: 6851 case OMPC_reduction: 6852 case OMPC_linear: 6853 case OMPC_aligned: 6854 case OMPC_copyin: 6855 case OMPC_copyprivate: 6856 case OMPC_ordered: 6857 case OMPC_nowait: 6858 case OMPC_untied: 6859 case OMPC_mergeable: 6860 case OMPC_threadprivate: 6861 case OMPC_flush: 6862 case OMPC_read: 6863 case OMPC_write: 6864 case OMPC_update: 6865 case OMPC_capture: 6866 case OMPC_seq_cst: 6867 case OMPC_depend: 6868 case OMPC_device: 6869 case OMPC_threads: 6870 case OMPC_simd: 6871 case OMPC_map: 6872 case OMPC_num_teams: 6873 case OMPC_thread_limit: 6874 case OMPC_priority: 6875 case OMPC_grainsize: 6876 case OMPC_nogroup: 6877 case OMPC_num_tasks: 6878 case OMPC_hint: 6879 case OMPC_dist_schedule: 6880 case OMPC_defaultmap: 6881 case OMPC_unknown: 6882 case OMPC_uniform: 6883 llvm_unreachable("Clause is not allowed."); 6884 } 6885 return Res; 6886 } 6887 6888 static std::string 6889 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 6890 ArrayRef<unsigned> Exclude = llvm::None) { 6891 std::string Values; 6892 unsigned Bound = Last >= 2 ? Last - 2 : 0; 6893 unsigned Skipped = Exclude.size(); 6894 auto S = Exclude.begin(), E = Exclude.end(); 6895 for (unsigned i = First; i < Last; ++i) { 6896 if (std::find(S, E, i) != E) { 6897 --Skipped; 6898 continue; 6899 } 6900 Values += "'"; 6901 Values += getOpenMPSimpleClauseTypeName(K, i); 6902 Values += "'"; 6903 if (i == Bound - Skipped) 6904 Values += " or "; 6905 else if (i != Bound + 1 - Skipped) 6906 Values += ", "; 6907 } 6908 return Values; 6909 } 6910 6911 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 6912 SourceLocation KindKwLoc, 6913 SourceLocation StartLoc, 6914 SourceLocation LParenLoc, 6915 SourceLocation EndLoc) { 6916 if (Kind == OMPC_DEFAULT_unknown) { 6917 static_assert(OMPC_DEFAULT_unknown > 0, 6918 "OMPC_DEFAULT_unknown not greater than 0"); 6919 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 6920 << getListOfPossibleValues(OMPC_default, /*First=*/0, 6921 /*Last=*/OMPC_DEFAULT_unknown) 6922 << getOpenMPClauseName(OMPC_default); 6923 return nullptr; 6924 } 6925 switch (Kind) { 6926 case OMPC_DEFAULT_none: 6927 DSAStack->setDefaultDSANone(KindKwLoc); 6928 break; 6929 case OMPC_DEFAULT_shared: 6930 DSAStack->setDefaultDSAShared(KindKwLoc); 6931 break; 6932 case OMPC_DEFAULT_unknown: 6933 llvm_unreachable("Clause kind is not allowed."); 6934 break; 6935 } 6936 return new (Context) 6937 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 6938 } 6939 6940 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 6941 SourceLocation KindKwLoc, 6942 SourceLocation StartLoc, 6943 SourceLocation LParenLoc, 6944 SourceLocation EndLoc) { 6945 if (Kind == OMPC_PROC_BIND_unknown) { 6946 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 6947 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 6948 /*Last=*/OMPC_PROC_BIND_unknown) 6949 << getOpenMPClauseName(OMPC_proc_bind); 6950 return nullptr; 6951 } 6952 return new (Context) 6953 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 6954 } 6955 6956 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 6957 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 6958 SourceLocation StartLoc, SourceLocation LParenLoc, 6959 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 6960 SourceLocation EndLoc) { 6961 OMPClause *Res = nullptr; 6962 switch (Kind) { 6963 case OMPC_schedule: 6964 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 6965 assert(Argument.size() == NumberOfElements && 6966 ArgumentLoc.size() == NumberOfElements); 6967 Res = ActOnOpenMPScheduleClause( 6968 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 6969 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 6970 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 6971 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 6972 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 6973 break; 6974 case OMPC_if: 6975 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 6976 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 6977 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 6978 DelimLoc, EndLoc); 6979 break; 6980 case OMPC_dist_schedule: 6981 Res = ActOnOpenMPDistScheduleClause( 6982 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 6983 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 6984 break; 6985 case OMPC_defaultmap: 6986 enum { Modifier, DefaultmapKind }; 6987 Res = ActOnOpenMPDefaultmapClause( 6988 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 6989 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 6990 StartLoc, LParenLoc, ArgumentLoc[Modifier], 6991 ArgumentLoc[DefaultmapKind], EndLoc); 6992 break; 6993 case OMPC_final: 6994 case OMPC_num_threads: 6995 case OMPC_safelen: 6996 case OMPC_simdlen: 6997 case OMPC_collapse: 6998 case OMPC_default: 6999 case OMPC_proc_bind: 7000 case OMPC_private: 7001 case OMPC_firstprivate: 7002 case OMPC_lastprivate: 7003 case OMPC_shared: 7004 case OMPC_reduction: 7005 case OMPC_linear: 7006 case OMPC_aligned: 7007 case OMPC_copyin: 7008 case OMPC_copyprivate: 7009 case OMPC_ordered: 7010 case OMPC_nowait: 7011 case OMPC_untied: 7012 case OMPC_mergeable: 7013 case OMPC_threadprivate: 7014 case OMPC_flush: 7015 case OMPC_read: 7016 case OMPC_write: 7017 case OMPC_update: 7018 case OMPC_capture: 7019 case OMPC_seq_cst: 7020 case OMPC_depend: 7021 case OMPC_device: 7022 case OMPC_threads: 7023 case OMPC_simd: 7024 case OMPC_map: 7025 case OMPC_num_teams: 7026 case OMPC_thread_limit: 7027 case OMPC_priority: 7028 case OMPC_grainsize: 7029 case OMPC_nogroup: 7030 case OMPC_num_tasks: 7031 case OMPC_hint: 7032 case OMPC_unknown: 7033 case OMPC_uniform: 7034 llvm_unreachable("Clause is not allowed."); 7035 } 7036 return Res; 7037 } 7038 7039 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 7040 OpenMPScheduleClauseModifier M2, 7041 SourceLocation M1Loc, SourceLocation M2Loc) { 7042 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 7043 SmallVector<unsigned, 2> Excluded; 7044 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 7045 Excluded.push_back(M2); 7046 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 7047 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 7048 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 7049 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 7050 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 7051 << getListOfPossibleValues(OMPC_schedule, 7052 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 7053 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 7054 Excluded) 7055 << getOpenMPClauseName(OMPC_schedule); 7056 return true; 7057 } 7058 return false; 7059 } 7060 7061 OMPClause *Sema::ActOnOpenMPScheduleClause( 7062 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 7063 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 7064 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 7065 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 7066 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 7067 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 7068 return nullptr; 7069 // OpenMP, 2.7.1, Loop Construct, Restrictions 7070 // Either the monotonic modifier or the nonmonotonic modifier can be specified 7071 // but not both. 7072 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 7073 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 7074 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 7075 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 7076 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 7077 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 7078 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 7079 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 7080 return nullptr; 7081 } 7082 if (Kind == OMPC_SCHEDULE_unknown) { 7083 std::string Values; 7084 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 7085 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 7086 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 7087 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 7088 Exclude); 7089 } else { 7090 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 7091 /*Last=*/OMPC_SCHEDULE_unknown); 7092 } 7093 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 7094 << Values << getOpenMPClauseName(OMPC_schedule); 7095 return nullptr; 7096 } 7097 // OpenMP, 2.7.1, Loop Construct, Restrictions 7098 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 7099 // schedule(guided). 7100 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 7101 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 7102 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 7103 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 7104 diag::err_omp_schedule_nonmonotonic_static); 7105 return nullptr; 7106 } 7107 Expr *ValExpr = ChunkSize; 7108 Stmt *HelperValStmt = nullptr; 7109 if (ChunkSize) { 7110 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 7111 !ChunkSize->isInstantiationDependent() && 7112 !ChunkSize->containsUnexpandedParameterPack()) { 7113 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 7114 ExprResult Val = 7115 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 7116 if (Val.isInvalid()) 7117 return nullptr; 7118 7119 ValExpr = Val.get(); 7120 7121 // OpenMP [2.7.1, Restrictions] 7122 // chunk_size must be a loop invariant integer expression with a positive 7123 // value. 7124 llvm::APSInt Result; 7125 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 7126 if (Result.isSigned() && !Result.isStrictlyPositive()) { 7127 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 7128 << "schedule" << 1 << ChunkSize->getSourceRange(); 7129 return nullptr; 7130 } 7131 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 7132 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 7133 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 7134 HelperValStmt = buildPreInits(Context, Captures); 7135 } 7136 } 7137 } 7138 7139 return new (Context) 7140 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 7141 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 7142 } 7143 7144 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 7145 SourceLocation StartLoc, 7146 SourceLocation EndLoc) { 7147 OMPClause *Res = nullptr; 7148 switch (Kind) { 7149 case OMPC_ordered: 7150 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 7151 break; 7152 case OMPC_nowait: 7153 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 7154 break; 7155 case OMPC_untied: 7156 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 7157 break; 7158 case OMPC_mergeable: 7159 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 7160 break; 7161 case OMPC_read: 7162 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 7163 break; 7164 case OMPC_write: 7165 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 7166 break; 7167 case OMPC_update: 7168 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 7169 break; 7170 case OMPC_capture: 7171 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 7172 break; 7173 case OMPC_seq_cst: 7174 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 7175 break; 7176 case OMPC_threads: 7177 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 7178 break; 7179 case OMPC_simd: 7180 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 7181 break; 7182 case OMPC_nogroup: 7183 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 7184 break; 7185 case OMPC_if: 7186 case OMPC_final: 7187 case OMPC_num_threads: 7188 case OMPC_safelen: 7189 case OMPC_simdlen: 7190 case OMPC_collapse: 7191 case OMPC_schedule: 7192 case OMPC_private: 7193 case OMPC_firstprivate: 7194 case OMPC_lastprivate: 7195 case OMPC_shared: 7196 case OMPC_reduction: 7197 case OMPC_linear: 7198 case OMPC_aligned: 7199 case OMPC_copyin: 7200 case OMPC_copyprivate: 7201 case OMPC_default: 7202 case OMPC_proc_bind: 7203 case OMPC_threadprivate: 7204 case OMPC_flush: 7205 case OMPC_depend: 7206 case OMPC_device: 7207 case OMPC_map: 7208 case OMPC_num_teams: 7209 case OMPC_thread_limit: 7210 case OMPC_priority: 7211 case OMPC_grainsize: 7212 case OMPC_num_tasks: 7213 case OMPC_hint: 7214 case OMPC_dist_schedule: 7215 case OMPC_defaultmap: 7216 case OMPC_unknown: 7217 case OMPC_uniform: 7218 llvm_unreachable("Clause is not allowed."); 7219 } 7220 return Res; 7221 } 7222 7223 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 7224 SourceLocation EndLoc) { 7225 DSAStack->setNowaitRegion(); 7226 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 7227 } 7228 7229 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 7230 SourceLocation EndLoc) { 7231 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 7232 } 7233 7234 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 7235 SourceLocation EndLoc) { 7236 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 7237 } 7238 7239 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 7240 SourceLocation EndLoc) { 7241 return new (Context) OMPReadClause(StartLoc, EndLoc); 7242 } 7243 7244 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 7245 SourceLocation EndLoc) { 7246 return new (Context) OMPWriteClause(StartLoc, EndLoc); 7247 } 7248 7249 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 7250 SourceLocation EndLoc) { 7251 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 7252 } 7253 7254 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 7255 SourceLocation EndLoc) { 7256 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 7257 } 7258 7259 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 7260 SourceLocation EndLoc) { 7261 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 7262 } 7263 7264 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 7265 SourceLocation EndLoc) { 7266 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 7267 } 7268 7269 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 7270 SourceLocation EndLoc) { 7271 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 7272 } 7273 7274 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 7275 SourceLocation EndLoc) { 7276 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 7277 } 7278 7279 OMPClause *Sema::ActOnOpenMPVarListClause( 7280 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 7281 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 7282 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 7283 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, 7284 OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, 7285 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 7286 SourceLocation DepLinMapLoc) { 7287 OMPClause *Res = nullptr; 7288 switch (Kind) { 7289 case OMPC_private: 7290 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7291 break; 7292 case OMPC_firstprivate: 7293 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7294 break; 7295 case OMPC_lastprivate: 7296 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7297 break; 7298 case OMPC_shared: 7299 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 7300 break; 7301 case OMPC_reduction: 7302 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 7303 EndLoc, ReductionIdScopeSpec, ReductionId); 7304 break; 7305 case OMPC_linear: 7306 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 7307 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 7308 break; 7309 case OMPC_aligned: 7310 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 7311 ColonLoc, EndLoc); 7312 break; 7313 case OMPC_copyin: 7314 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 7315 break; 7316 case OMPC_copyprivate: 7317 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7318 break; 7319 case OMPC_flush: 7320 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 7321 break; 7322 case OMPC_depend: 7323 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 7324 StartLoc, LParenLoc, EndLoc); 7325 break; 7326 case OMPC_map: 7327 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, 7328 DepLinMapLoc, ColonLoc, VarList, StartLoc, 7329 LParenLoc, EndLoc); 7330 break; 7331 case OMPC_if: 7332 case OMPC_final: 7333 case OMPC_num_threads: 7334 case OMPC_safelen: 7335 case OMPC_simdlen: 7336 case OMPC_collapse: 7337 case OMPC_default: 7338 case OMPC_proc_bind: 7339 case OMPC_schedule: 7340 case OMPC_ordered: 7341 case OMPC_nowait: 7342 case OMPC_untied: 7343 case OMPC_mergeable: 7344 case OMPC_threadprivate: 7345 case OMPC_read: 7346 case OMPC_write: 7347 case OMPC_update: 7348 case OMPC_capture: 7349 case OMPC_seq_cst: 7350 case OMPC_device: 7351 case OMPC_threads: 7352 case OMPC_simd: 7353 case OMPC_num_teams: 7354 case OMPC_thread_limit: 7355 case OMPC_priority: 7356 case OMPC_grainsize: 7357 case OMPC_nogroup: 7358 case OMPC_num_tasks: 7359 case OMPC_hint: 7360 case OMPC_dist_schedule: 7361 case OMPC_defaultmap: 7362 case OMPC_unknown: 7363 case OMPC_uniform: 7364 llvm_unreachable("Clause is not allowed."); 7365 } 7366 return Res; 7367 } 7368 7369 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 7370 ExprObjectKind OK, SourceLocation Loc) { 7371 ExprResult Res = BuildDeclRefExpr( 7372 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 7373 if (!Res.isUsable()) 7374 return ExprError(); 7375 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 7376 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 7377 if (!Res.isUsable()) 7378 return ExprError(); 7379 } 7380 if (VK != VK_LValue && Res.get()->isGLValue()) { 7381 Res = DefaultLvalueConversion(Res.get()); 7382 if (!Res.isUsable()) 7383 return ExprError(); 7384 } 7385 return Res; 7386 } 7387 7388 static std::pair<ValueDecl *, bool> 7389 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 7390 SourceRange &ERange, bool AllowArraySection = false) { 7391 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 7392 RefExpr->containsUnexpandedParameterPack()) 7393 return std::make_pair(nullptr, true); 7394 7395 // OpenMP [3.1, C/C++] 7396 // A list item is a variable name. 7397 // OpenMP [2.9.3.3, Restrictions, p.1] 7398 // A variable that is part of another variable (as an array or 7399 // structure element) cannot appear in a private clause. 7400 RefExpr = RefExpr->IgnoreParens(); 7401 enum { 7402 NoArrayExpr = -1, 7403 ArraySubscript = 0, 7404 OMPArraySection = 1 7405 } IsArrayExpr = NoArrayExpr; 7406 if (AllowArraySection) { 7407 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 7408 auto *Base = ASE->getBase()->IgnoreParenImpCasts(); 7409 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 7410 Base = TempASE->getBase()->IgnoreParenImpCasts(); 7411 RefExpr = Base; 7412 IsArrayExpr = ArraySubscript; 7413 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 7414 auto *Base = OASE->getBase()->IgnoreParenImpCasts(); 7415 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 7416 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 7417 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 7418 Base = TempASE->getBase()->IgnoreParenImpCasts(); 7419 RefExpr = Base; 7420 IsArrayExpr = OMPArraySection; 7421 } 7422 } 7423 ELoc = RefExpr->getExprLoc(); 7424 ERange = RefExpr->getSourceRange(); 7425 RefExpr = RefExpr->IgnoreParenImpCasts(); 7426 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 7427 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 7428 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 7429 (S.getCurrentThisType().isNull() || !ME || 7430 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 7431 !isa<FieldDecl>(ME->getMemberDecl()))) { 7432 if (IsArrayExpr != NoArrayExpr) 7433 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 7434 << ERange; 7435 else { 7436 S.Diag(ELoc, 7437 AllowArraySection 7438 ? diag::err_omp_expected_var_name_member_expr_or_array_item 7439 : diag::err_omp_expected_var_name_member_expr) 7440 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 7441 } 7442 return std::make_pair(nullptr, false); 7443 } 7444 return std::make_pair(DE ? DE->getDecl() : ME->getMemberDecl(), false); 7445 } 7446 7447 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 7448 SourceLocation StartLoc, 7449 SourceLocation LParenLoc, 7450 SourceLocation EndLoc) { 7451 SmallVector<Expr *, 8> Vars; 7452 SmallVector<Expr *, 8> PrivateCopies; 7453 for (auto &RefExpr : VarList) { 7454 assert(RefExpr && "NULL expr in OpenMP private clause."); 7455 SourceLocation ELoc; 7456 SourceRange ERange; 7457 Expr *SimpleRefExpr = RefExpr; 7458 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 7459 if (Res.second) { 7460 // It will be analyzed later. 7461 Vars.push_back(RefExpr); 7462 PrivateCopies.push_back(nullptr); 7463 } 7464 ValueDecl *D = Res.first; 7465 if (!D) 7466 continue; 7467 7468 QualType Type = D->getType(); 7469 auto *VD = dyn_cast<VarDecl>(D); 7470 7471 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 7472 // A variable that appears in a private clause must not have an incomplete 7473 // type or a reference type. 7474 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 7475 continue; 7476 Type = Type.getNonReferenceType(); 7477 7478 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7479 // in a Construct] 7480 // Variables with the predetermined data-sharing attributes may not be 7481 // listed in data-sharing attributes clauses, except for the cases 7482 // listed below. For these exceptions only, listing a predetermined 7483 // variable in a data-sharing attribute clause is allowed and overrides 7484 // the variable's predetermined data-sharing attributes. 7485 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7486 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 7487 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 7488 << getOpenMPClauseName(OMPC_private); 7489 ReportOriginalDSA(*this, DSAStack, D, DVar); 7490 continue; 7491 } 7492 7493 // Variably modified types are not supported for tasks. 7494 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 7495 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 7496 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 7497 << getOpenMPClauseName(OMPC_private) << Type 7498 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7499 bool IsDecl = 7500 !VD || 7501 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 7502 Diag(D->getLocation(), 7503 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 7504 << D; 7505 continue; 7506 } 7507 7508 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 7509 // A list item cannot appear in both a map clause and a data-sharing 7510 // attribute clause on the same construct 7511 if (DSAStack->getCurrentDirective() == OMPD_target) { 7512 if(DSAStack->checkMapInfoForVar(VD, /* CurrentRegionOnly = */ true, 7513 [&](Expr *RE) -> bool {return true;})) { 7514 Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) 7515 << getOpenMPClauseName(OMPC_private) 7516 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7517 ReportOriginalDSA(*this, DSAStack, D, DVar); 7518 continue; 7519 } 7520 } 7521 7522 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 7523 // A variable of class type (or array thereof) that appears in a private 7524 // clause requires an accessible, unambiguous default constructor for the 7525 // class type. 7526 // Generate helper private variable and initialize it with the default 7527 // value. The address of the original variable is replaced by the address of 7528 // the new private variable in CodeGen. This new variable is not added to 7529 // IdResolver, so the code in the OpenMP region uses original variable for 7530 // proper diagnostics. 7531 Type = Type.getUnqualifiedType(); 7532 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 7533 D->hasAttrs() ? &D->getAttrs() : nullptr); 7534 ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); 7535 if (VDPrivate->isInvalidDecl()) 7536 continue; 7537 auto VDPrivateRefExpr = buildDeclRefExpr( 7538 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 7539 7540 DeclRefExpr *Ref = nullptr; 7541 if (!VD) 7542 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 7543 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 7544 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 7545 PrivateCopies.push_back(VDPrivateRefExpr); 7546 } 7547 7548 if (Vars.empty()) 7549 return nullptr; 7550 7551 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 7552 PrivateCopies); 7553 } 7554 7555 namespace { 7556 class DiagsUninitializedSeveretyRAII { 7557 private: 7558 DiagnosticsEngine &Diags; 7559 SourceLocation SavedLoc; 7560 bool IsIgnored; 7561 7562 public: 7563 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 7564 bool IsIgnored) 7565 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 7566 if (!IsIgnored) { 7567 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 7568 /*Map*/ diag::Severity::Ignored, Loc); 7569 } 7570 } 7571 ~DiagsUninitializedSeveretyRAII() { 7572 if (!IsIgnored) 7573 Diags.popMappings(SavedLoc); 7574 } 7575 }; 7576 } 7577 7578 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 7579 SourceLocation StartLoc, 7580 SourceLocation LParenLoc, 7581 SourceLocation EndLoc) { 7582 SmallVector<Expr *, 8> Vars; 7583 SmallVector<Expr *, 8> PrivateCopies; 7584 SmallVector<Expr *, 8> Inits; 7585 SmallVector<Decl *, 4> ExprCaptures; 7586 bool IsImplicitClause = 7587 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 7588 auto ImplicitClauseLoc = DSAStack->getConstructLoc(); 7589 7590 for (auto &RefExpr : VarList) { 7591 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 7592 SourceLocation ELoc; 7593 SourceRange ERange; 7594 Expr *SimpleRefExpr = RefExpr; 7595 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 7596 if (Res.second) { 7597 // It will be analyzed later. 7598 Vars.push_back(RefExpr); 7599 PrivateCopies.push_back(nullptr); 7600 Inits.push_back(nullptr); 7601 } 7602 ValueDecl *D = Res.first; 7603 if (!D) 7604 continue; 7605 7606 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 7607 QualType Type = D->getType(); 7608 auto *VD = dyn_cast<VarDecl>(D); 7609 7610 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 7611 // A variable that appears in a private clause must not have an incomplete 7612 // type or a reference type. 7613 if (RequireCompleteType(ELoc, Type, 7614 diag::err_omp_firstprivate_incomplete_type)) 7615 continue; 7616 Type = Type.getNonReferenceType(); 7617 7618 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 7619 // A variable of class type (or array thereof) that appears in a private 7620 // clause requires an accessible, unambiguous copy constructor for the 7621 // class type. 7622 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 7623 7624 // If an implicit firstprivate variable found it was checked already. 7625 DSAStackTy::DSAVarData TopDVar; 7626 if (!IsImplicitClause) { 7627 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7628 TopDVar = DVar; 7629 bool IsConstant = ElemType.isConstant(Context); 7630 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 7631 // A list item that specifies a given variable may not appear in more 7632 // than one clause on the same directive, except that a variable may be 7633 // specified in both firstprivate and lastprivate clauses. 7634 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 7635 DVar.CKind != OMPC_lastprivate && DVar.RefExpr) { 7636 Diag(ELoc, diag::err_omp_wrong_dsa) 7637 << getOpenMPClauseName(DVar.CKind) 7638 << getOpenMPClauseName(OMPC_firstprivate); 7639 ReportOriginalDSA(*this, DSAStack, D, DVar); 7640 continue; 7641 } 7642 7643 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7644 // in a Construct] 7645 // Variables with the predetermined data-sharing attributes may not be 7646 // listed in data-sharing attributes clauses, except for the cases 7647 // listed below. For these exceptions only, listing a predetermined 7648 // variable in a data-sharing attribute clause is allowed and overrides 7649 // the variable's predetermined data-sharing attributes. 7650 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7651 // in a Construct, C/C++, p.2] 7652 // Variables with const-qualified type having no mutable member may be 7653 // listed in a firstprivate clause, even if they are static data members. 7654 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 7655 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 7656 Diag(ELoc, diag::err_omp_wrong_dsa) 7657 << getOpenMPClauseName(DVar.CKind) 7658 << getOpenMPClauseName(OMPC_firstprivate); 7659 ReportOriginalDSA(*this, DSAStack, D, DVar); 7660 continue; 7661 } 7662 7663 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 7664 // OpenMP [2.9.3.4, Restrictions, p.2] 7665 // A list item that is private within a parallel region must not appear 7666 // in a firstprivate clause on a worksharing construct if any of the 7667 // worksharing regions arising from the worksharing construct ever bind 7668 // to any of the parallel regions arising from the parallel construct. 7669 if (isOpenMPWorksharingDirective(CurrDir) && 7670 !isOpenMPParallelDirective(CurrDir)) { 7671 DVar = DSAStack->getImplicitDSA(D, true); 7672 if (DVar.CKind != OMPC_shared && 7673 (isOpenMPParallelDirective(DVar.DKind) || 7674 DVar.DKind == OMPD_unknown)) { 7675 Diag(ELoc, diag::err_omp_required_access) 7676 << getOpenMPClauseName(OMPC_firstprivate) 7677 << getOpenMPClauseName(OMPC_shared); 7678 ReportOriginalDSA(*this, DSAStack, D, DVar); 7679 continue; 7680 } 7681 } 7682 // OpenMP [2.9.3.4, Restrictions, p.3] 7683 // A list item that appears in a reduction clause of a parallel construct 7684 // must not appear in a firstprivate clause on a worksharing or task 7685 // construct if any of the worksharing or task regions arising from the 7686 // worksharing or task construct ever bind to any of the parallel regions 7687 // arising from the parallel construct. 7688 // OpenMP [2.9.3.4, Restrictions, p.4] 7689 // A list item that appears in a reduction clause in worksharing 7690 // construct must not appear in a firstprivate clause in a task construct 7691 // encountered during execution of any of the worksharing regions arising 7692 // from the worksharing construct. 7693 if (isOpenMPTaskingDirective(CurrDir)) { 7694 DVar = 7695 DSAStack->hasInnermostDSA(D, MatchesAnyClause(OMPC_reduction), 7696 [](OpenMPDirectiveKind K) -> bool { 7697 return isOpenMPParallelDirective(K) || 7698 isOpenMPWorksharingDirective(K); 7699 }, 7700 false); 7701 if (DVar.CKind == OMPC_reduction && 7702 (isOpenMPParallelDirective(DVar.DKind) || 7703 isOpenMPWorksharingDirective(DVar.DKind))) { 7704 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 7705 << getOpenMPDirectiveName(DVar.DKind); 7706 ReportOriginalDSA(*this, DSAStack, D, DVar); 7707 continue; 7708 } 7709 } 7710 7711 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 7712 // A list item that is private within a teams region must not appear in a 7713 // firstprivate clause on a distribute construct if any of the distribute 7714 // regions arising from the distribute construct ever bind to any of the 7715 // teams regions arising from the teams construct. 7716 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 7717 // A list item that appears in a reduction clause of a teams construct 7718 // must not appear in a firstprivate clause on a distribute construct if 7719 // any of the distribute regions arising from the distribute construct 7720 // ever bind to any of the teams regions arising from the teams construct. 7721 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 7722 // A list item may appear in a firstprivate or lastprivate clause but not 7723 // both. 7724 if (CurrDir == OMPD_distribute) { 7725 DVar = DSAStack->hasInnermostDSA(D, MatchesAnyClause(OMPC_private), 7726 [](OpenMPDirectiveKind K) -> bool { 7727 return isOpenMPTeamsDirective(K); 7728 }, 7729 false); 7730 if (DVar.CKind == OMPC_private && isOpenMPTeamsDirective(DVar.DKind)) { 7731 Diag(ELoc, diag::err_omp_firstprivate_distribute_private_teams); 7732 ReportOriginalDSA(*this, DSAStack, D, DVar); 7733 continue; 7734 } 7735 DVar = DSAStack->hasInnermostDSA(D, MatchesAnyClause(OMPC_reduction), 7736 [](OpenMPDirectiveKind K) -> bool { 7737 return isOpenMPTeamsDirective(K); 7738 }, 7739 false); 7740 if (DVar.CKind == OMPC_reduction && 7741 isOpenMPTeamsDirective(DVar.DKind)) { 7742 Diag(ELoc, diag::err_omp_firstprivate_distribute_in_teams_reduction); 7743 ReportOriginalDSA(*this, DSAStack, D, DVar); 7744 continue; 7745 } 7746 DVar = DSAStack->getTopDSA(D, false); 7747 if (DVar.CKind == OMPC_lastprivate) { 7748 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); 7749 ReportOriginalDSA(*this, DSAStack, D, DVar); 7750 continue; 7751 } 7752 } 7753 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 7754 // A list item cannot appear in both a map clause and a data-sharing 7755 // attribute clause on the same construct 7756 if (CurrDir == OMPD_target) { 7757 if(DSAStack->checkMapInfoForVar(VD, /* CurrentRegionOnly = */ true, 7758 [&](Expr *RE) -> bool {return true;})) { 7759 Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) 7760 << getOpenMPClauseName(OMPC_firstprivate) 7761 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7762 ReportOriginalDSA(*this, DSAStack, D, DVar); 7763 continue; 7764 } 7765 } 7766 } 7767 7768 // Variably modified types are not supported for tasks. 7769 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 7770 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 7771 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 7772 << getOpenMPClauseName(OMPC_firstprivate) << Type 7773 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7774 bool IsDecl = 7775 !VD || 7776 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 7777 Diag(D->getLocation(), 7778 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 7779 << D; 7780 continue; 7781 } 7782 7783 Type = Type.getUnqualifiedType(); 7784 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 7785 D->hasAttrs() ? &D->getAttrs() : nullptr); 7786 // Generate helper private variable and initialize it with the value of the 7787 // original variable. The address of the original variable is replaced by 7788 // the address of the new private variable in the CodeGen. This new variable 7789 // is not added to IdResolver, so the code in the OpenMP region uses 7790 // original variable for proper diagnostics and variable capturing. 7791 Expr *VDInitRefExpr = nullptr; 7792 // For arrays generate initializer for single element and replace it by the 7793 // original array element in CodeGen. 7794 if (Type->isArrayType()) { 7795 auto VDInit = 7796 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 7797 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 7798 auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); 7799 ElemType = ElemType.getUnqualifiedType(); 7800 auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 7801 ".firstprivate.temp"); 7802 InitializedEntity Entity = 7803 InitializedEntity::InitializeVariable(VDInitTemp); 7804 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 7805 7806 InitializationSequence InitSeq(*this, Entity, Kind, Init); 7807 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 7808 if (Result.isInvalid()) 7809 VDPrivate->setInvalidDecl(); 7810 else 7811 VDPrivate->setInit(Result.getAs<Expr>()); 7812 // Remove temp variable declaration. 7813 Context.Deallocate(VDInitTemp); 7814 } else { 7815 auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 7816 ".firstprivate.temp"); 7817 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 7818 RefExpr->getExprLoc()); 7819 AddInitializerToDecl(VDPrivate, 7820 DefaultLvalueConversion(VDInitRefExpr).get(), 7821 /*DirectInit=*/false, /*TypeMayContainAuto=*/false); 7822 } 7823 if (VDPrivate->isInvalidDecl()) { 7824 if (IsImplicitClause) { 7825 Diag(RefExpr->getExprLoc(), 7826 diag::note_omp_task_predetermined_firstprivate_here); 7827 } 7828 continue; 7829 } 7830 CurContext->addDecl(VDPrivate); 7831 auto VDPrivateRefExpr = buildDeclRefExpr( 7832 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 7833 RefExpr->getExprLoc()); 7834 DeclRefExpr *Ref = nullptr; 7835 if (!VD) { 7836 if (TopDVar.CKind == OMPC_lastprivate) 7837 Ref = TopDVar.PrivateCopy; 7838 else { 7839 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 7840 if (!IsOpenMPCapturedDecl(D)) 7841 ExprCaptures.push_back(Ref->getDecl()); 7842 } 7843 } 7844 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 7845 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 7846 PrivateCopies.push_back(VDPrivateRefExpr); 7847 Inits.push_back(VDInitRefExpr); 7848 } 7849 7850 if (Vars.empty()) 7851 return nullptr; 7852 7853 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 7854 Vars, PrivateCopies, Inits, 7855 buildPreInits(Context, ExprCaptures)); 7856 } 7857 7858 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 7859 SourceLocation StartLoc, 7860 SourceLocation LParenLoc, 7861 SourceLocation EndLoc) { 7862 SmallVector<Expr *, 8> Vars; 7863 SmallVector<Expr *, 8> SrcExprs; 7864 SmallVector<Expr *, 8> DstExprs; 7865 SmallVector<Expr *, 8> AssignmentOps; 7866 SmallVector<Decl *, 4> ExprCaptures; 7867 SmallVector<Expr *, 4> ExprPostUpdates; 7868 for (auto &RefExpr : VarList) { 7869 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 7870 SourceLocation ELoc; 7871 SourceRange ERange; 7872 Expr *SimpleRefExpr = RefExpr; 7873 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 7874 if (Res.second) { 7875 // It will be analyzed later. 7876 Vars.push_back(RefExpr); 7877 SrcExprs.push_back(nullptr); 7878 DstExprs.push_back(nullptr); 7879 AssignmentOps.push_back(nullptr); 7880 } 7881 ValueDecl *D = Res.first; 7882 if (!D) 7883 continue; 7884 7885 QualType Type = D->getType(); 7886 auto *VD = dyn_cast<VarDecl>(D); 7887 7888 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 7889 // A variable that appears in a lastprivate clause must not have an 7890 // incomplete type or a reference type. 7891 if (RequireCompleteType(ELoc, Type, 7892 diag::err_omp_lastprivate_incomplete_type)) 7893 continue; 7894 Type = Type.getNonReferenceType(); 7895 7896 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 7897 // in a Construct] 7898 // Variables with the predetermined data-sharing attributes may not be 7899 // listed in data-sharing attributes clauses, except for the cases 7900 // listed below. 7901 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7902 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 7903 DVar.CKind != OMPC_firstprivate && 7904 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 7905 Diag(ELoc, diag::err_omp_wrong_dsa) 7906 << getOpenMPClauseName(DVar.CKind) 7907 << getOpenMPClauseName(OMPC_lastprivate); 7908 ReportOriginalDSA(*this, DSAStack, D, DVar); 7909 continue; 7910 } 7911 7912 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 7913 // OpenMP [2.14.3.5, Restrictions, p.2] 7914 // A list item that is private within a parallel region, or that appears in 7915 // the reduction clause of a parallel construct, must not appear in a 7916 // lastprivate clause on a worksharing construct if any of the corresponding 7917 // worksharing regions ever binds to any of the corresponding parallel 7918 // regions. 7919 DSAStackTy::DSAVarData TopDVar = DVar; 7920 if (isOpenMPWorksharingDirective(CurrDir) && 7921 !isOpenMPParallelDirective(CurrDir)) { 7922 DVar = DSAStack->getImplicitDSA(D, true); 7923 if (DVar.CKind != OMPC_shared) { 7924 Diag(ELoc, diag::err_omp_required_access) 7925 << getOpenMPClauseName(OMPC_lastprivate) 7926 << getOpenMPClauseName(OMPC_shared); 7927 ReportOriginalDSA(*this, DSAStack, D, DVar); 7928 continue; 7929 } 7930 } 7931 7932 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 7933 // A list item may appear in a firstprivate or lastprivate clause but not 7934 // both. 7935 if (CurrDir == OMPD_distribute) { 7936 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7937 if (DVar.CKind == OMPC_firstprivate) { 7938 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); 7939 ReportOriginalDSA(*this, DSAStack, D, DVar); 7940 continue; 7941 } 7942 } 7943 7944 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 7945 // A variable of class type (or array thereof) that appears in a 7946 // lastprivate clause requires an accessible, unambiguous default 7947 // constructor for the class type, unless the list item is also specified 7948 // in a firstprivate clause. 7949 // A variable of class type (or array thereof) that appears in a 7950 // lastprivate clause requires an accessible, unambiguous copy assignment 7951 // operator for the class type. 7952 Type = Context.getBaseElementType(Type).getNonReferenceType(); 7953 auto *SrcVD = buildVarDecl(*this, ERange.getBegin(), 7954 Type.getUnqualifiedType(), ".lastprivate.src", 7955 D->hasAttrs() ? &D->getAttrs() : nullptr); 7956 auto *PseudoSrcExpr = 7957 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 7958 auto *DstVD = 7959 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 7960 D->hasAttrs() ? &D->getAttrs() : nullptr); 7961 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 7962 // For arrays generate assignment operation for single element and replace 7963 // it by the original array element in CodeGen. 7964 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 7965 PseudoDstExpr, PseudoSrcExpr); 7966 if (AssignmentOp.isInvalid()) 7967 continue; 7968 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 7969 /*DiscardedValue=*/true); 7970 if (AssignmentOp.isInvalid()) 7971 continue; 7972 7973 DeclRefExpr *Ref = nullptr; 7974 if (!VD) { 7975 if (TopDVar.CKind == OMPC_firstprivate) 7976 Ref = TopDVar.PrivateCopy; 7977 else { 7978 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 7979 if (!IsOpenMPCapturedDecl(D)) 7980 ExprCaptures.push_back(Ref->getDecl()); 7981 } 7982 if (TopDVar.CKind == OMPC_firstprivate || 7983 (!IsOpenMPCapturedDecl(D) && 7984 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 7985 ExprResult RefRes = DefaultLvalueConversion(Ref); 7986 if (!RefRes.isUsable()) 7987 continue; 7988 ExprResult PostUpdateRes = 7989 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 7990 RefRes.get()); 7991 if (!PostUpdateRes.isUsable()) 7992 continue; 7993 ExprPostUpdates.push_back( 7994 IgnoredValueConversions(PostUpdateRes.get()).get()); 7995 } 7996 } 7997 if (TopDVar.CKind != OMPC_firstprivate) 7998 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 7999 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 8000 SrcExprs.push_back(PseudoSrcExpr); 8001 DstExprs.push_back(PseudoDstExpr); 8002 AssignmentOps.push_back(AssignmentOp.get()); 8003 } 8004 8005 if (Vars.empty()) 8006 return nullptr; 8007 8008 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 8009 Vars, SrcExprs, DstExprs, AssignmentOps, 8010 buildPreInits(Context, ExprCaptures), 8011 buildPostUpdate(*this, ExprPostUpdates)); 8012 } 8013 8014 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 8015 SourceLocation StartLoc, 8016 SourceLocation LParenLoc, 8017 SourceLocation EndLoc) { 8018 SmallVector<Expr *, 8> Vars; 8019 for (auto &RefExpr : VarList) { 8020 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 8021 SourceLocation ELoc; 8022 SourceRange ERange; 8023 Expr *SimpleRefExpr = RefExpr; 8024 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8025 if (Res.second) { 8026 // It will be analyzed later. 8027 Vars.push_back(RefExpr); 8028 } 8029 ValueDecl *D = Res.first; 8030 if (!D) 8031 continue; 8032 8033 auto *VD = dyn_cast<VarDecl>(D); 8034 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8035 // in a Construct] 8036 // Variables with the predetermined data-sharing attributes may not be 8037 // listed in data-sharing attributes clauses, except for the cases 8038 // listed below. For these exceptions only, listing a predetermined 8039 // variable in a data-sharing attribute clause is allowed and overrides 8040 // the variable's predetermined data-sharing attributes. 8041 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8042 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 8043 DVar.RefExpr) { 8044 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 8045 << getOpenMPClauseName(OMPC_shared); 8046 ReportOriginalDSA(*this, DSAStack, D, DVar); 8047 continue; 8048 } 8049 8050 DeclRefExpr *Ref = nullptr; 8051 if (!VD && IsOpenMPCapturedDecl(D)) 8052 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 8053 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 8054 Vars.push_back((VD || !Ref) ? RefExpr->IgnoreParens() : Ref); 8055 } 8056 8057 if (Vars.empty()) 8058 return nullptr; 8059 8060 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 8061 } 8062 8063 namespace { 8064 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 8065 DSAStackTy *Stack; 8066 8067 public: 8068 bool VisitDeclRefExpr(DeclRefExpr *E) { 8069 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { 8070 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false); 8071 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 8072 return false; 8073 if (DVar.CKind != OMPC_unknown) 8074 return true; 8075 DSAStackTy::DSAVarData DVarPrivate = 8076 Stack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), false); 8077 if (DVarPrivate.CKind != OMPC_unknown) 8078 return true; 8079 return false; 8080 } 8081 return false; 8082 } 8083 bool VisitStmt(Stmt *S) { 8084 for (auto Child : S->children()) { 8085 if (Child && Visit(Child)) 8086 return true; 8087 } 8088 return false; 8089 } 8090 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 8091 }; 8092 } // namespace 8093 8094 namespace { 8095 // Transform MemberExpression for specified FieldDecl of current class to 8096 // DeclRefExpr to specified OMPCapturedExprDecl. 8097 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 8098 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 8099 ValueDecl *Field; 8100 DeclRefExpr *CapturedExpr; 8101 8102 public: 8103 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 8104 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 8105 8106 ExprResult TransformMemberExpr(MemberExpr *E) { 8107 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 8108 E->getMemberDecl() == Field) { 8109 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 8110 return CapturedExpr; 8111 } 8112 return BaseTransform::TransformMemberExpr(E); 8113 } 8114 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 8115 }; 8116 } // namespace 8117 8118 template <typename T> 8119 static T filterLookupForUDR(SmallVectorImpl<UnresolvedSet<8>> &Lookups, 8120 const llvm::function_ref<T(ValueDecl *)> &Gen) { 8121 for (auto &Set : Lookups) { 8122 for (auto *D : Set) { 8123 if (auto Res = Gen(cast<ValueDecl>(D))) 8124 return Res; 8125 } 8126 } 8127 return T(); 8128 } 8129 8130 static ExprResult 8131 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 8132 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 8133 const DeclarationNameInfo &ReductionId, QualType Ty, 8134 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 8135 if (ReductionIdScopeSpec.isInvalid()) 8136 return ExprError(); 8137 SmallVector<UnresolvedSet<8>, 4> Lookups; 8138 if (S) { 8139 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 8140 Lookup.suppressDiagnostics(); 8141 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 8142 auto *D = Lookup.getRepresentativeDecl(); 8143 do { 8144 S = S->getParent(); 8145 } while (S && !S->isDeclScope(D)); 8146 if (S) 8147 S = S->getParent(); 8148 Lookups.push_back(UnresolvedSet<8>()); 8149 Lookups.back().append(Lookup.begin(), Lookup.end()); 8150 Lookup.clear(); 8151 } 8152 } else if (auto *ULE = 8153 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 8154 Lookups.push_back(UnresolvedSet<8>()); 8155 Decl *PrevD = nullptr; 8156 for(auto *D : ULE->decls()) { 8157 if (D == PrevD) 8158 Lookups.push_back(UnresolvedSet<8>()); 8159 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) 8160 Lookups.back().addDecl(DRD); 8161 PrevD = D; 8162 } 8163 } 8164 if (Ty->isDependentType() || Ty->isInstantiationDependentType() || 8165 Ty->containsUnexpandedParameterPack() || 8166 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool { 8167 return !D->isInvalidDecl() && 8168 (D->getType()->isDependentType() || 8169 D->getType()->isInstantiationDependentType() || 8170 D->getType()->containsUnexpandedParameterPack()); 8171 })) { 8172 UnresolvedSet<8> ResSet; 8173 for (auto &Set : Lookups) { 8174 ResSet.append(Set.begin(), Set.end()); 8175 // The last item marks the end of all declarations at the specified scope. 8176 ResSet.addDecl(Set[Set.size() - 1]); 8177 } 8178 return UnresolvedLookupExpr::Create( 8179 SemaRef.Context, /*NamingClass=*/nullptr, 8180 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 8181 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 8182 } 8183 if (auto *VD = filterLookupForUDR<ValueDecl *>( 8184 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 8185 if (!D->isInvalidDecl() && 8186 SemaRef.Context.hasSameType(D->getType(), Ty)) 8187 return D; 8188 return nullptr; 8189 })) 8190 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 8191 if (auto *VD = filterLookupForUDR<ValueDecl *>( 8192 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 8193 if (!D->isInvalidDecl() && 8194 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 8195 !Ty.isMoreQualifiedThan(D->getType())) 8196 return D; 8197 return nullptr; 8198 })) { 8199 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 8200 /*DetectVirtual=*/false); 8201 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 8202 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 8203 VD->getType().getUnqualifiedType()))) { 8204 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), 8205 /*DiagID=*/0) != 8206 Sema::AR_inaccessible) { 8207 SemaRef.BuildBasePathArray(Paths, BasePath); 8208 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 8209 } 8210 } 8211 } 8212 } 8213 if (ReductionIdScopeSpec.isSet()) { 8214 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 8215 return ExprError(); 8216 } 8217 return ExprEmpty(); 8218 } 8219 8220 OMPClause *Sema::ActOnOpenMPReductionClause( 8221 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 8222 SourceLocation ColonLoc, SourceLocation EndLoc, 8223 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 8224 ArrayRef<Expr *> UnresolvedReductions) { 8225 auto DN = ReductionId.getName(); 8226 auto OOK = DN.getCXXOverloadedOperator(); 8227 BinaryOperatorKind BOK = BO_Comma; 8228 8229 // OpenMP [2.14.3.6, reduction clause] 8230 // C 8231 // reduction-identifier is either an identifier or one of the following 8232 // operators: +, -, *, &, |, ^, && and || 8233 // C++ 8234 // reduction-identifier is either an id-expression or one of the following 8235 // operators: +, -, *, &, |, ^, && and || 8236 // FIXME: Only 'min' and 'max' identifiers are supported for now. 8237 switch (OOK) { 8238 case OO_Plus: 8239 case OO_Minus: 8240 BOK = BO_Add; 8241 break; 8242 case OO_Star: 8243 BOK = BO_Mul; 8244 break; 8245 case OO_Amp: 8246 BOK = BO_And; 8247 break; 8248 case OO_Pipe: 8249 BOK = BO_Or; 8250 break; 8251 case OO_Caret: 8252 BOK = BO_Xor; 8253 break; 8254 case OO_AmpAmp: 8255 BOK = BO_LAnd; 8256 break; 8257 case OO_PipePipe: 8258 BOK = BO_LOr; 8259 break; 8260 case OO_New: 8261 case OO_Delete: 8262 case OO_Array_New: 8263 case OO_Array_Delete: 8264 case OO_Slash: 8265 case OO_Percent: 8266 case OO_Tilde: 8267 case OO_Exclaim: 8268 case OO_Equal: 8269 case OO_Less: 8270 case OO_Greater: 8271 case OO_LessEqual: 8272 case OO_GreaterEqual: 8273 case OO_PlusEqual: 8274 case OO_MinusEqual: 8275 case OO_StarEqual: 8276 case OO_SlashEqual: 8277 case OO_PercentEqual: 8278 case OO_CaretEqual: 8279 case OO_AmpEqual: 8280 case OO_PipeEqual: 8281 case OO_LessLess: 8282 case OO_GreaterGreater: 8283 case OO_LessLessEqual: 8284 case OO_GreaterGreaterEqual: 8285 case OO_EqualEqual: 8286 case OO_ExclaimEqual: 8287 case OO_PlusPlus: 8288 case OO_MinusMinus: 8289 case OO_Comma: 8290 case OO_ArrowStar: 8291 case OO_Arrow: 8292 case OO_Call: 8293 case OO_Subscript: 8294 case OO_Conditional: 8295 case OO_Coawait: 8296 case NUM_OVERLOADED_OPERATORS: 8297 llvm_unreachable("Unexpected reduction identifier"); 8298 case OO_None: 8299 if (auto II = DN.getAsIdentifierInfo()) { 8300 if (II->isStr("max")) 8301 BOK = BO_GT; 8302 else if (II->isStr("min")) 8303 BOK = BO_LT; 8304 } 8305 break; 8306 } 8307 SourceRange ReductionIdRange; 8308 if (ReductionIdScopeSpec.isValid()) 8309 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 8310 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 8311 8312 SmallVector<Expr *, 8> Vars; 8313 SmallVector<Expr *, 8> Privates; 8314 SmallVector<Expr *, 8> LHSs; 8315 SmallVector<Expr *, 8> RHSs; 8316 SmallVector<Expr *, 8> ReductionOps; 8317 SmallVector<Decl *, 4> ExprCaptures; 8318 SmallVector<Expr *, 4> ExprPostUpdates; 8319 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 8320 bool FirstIter = true; 8321 for (auto RefExpr : VarList) { 8322 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 8323 // OpenMP [2.1, C/C++] 8324 // A list item is a variable or array section, subject to the restrictions 8325 // specified in Section 2.4 on page 42 and in each of the sections 8326 // describing clauses and directives for which a list appears. 8327 // OpenMP [2.14.3.3, Restrictions, p.1] 8328 // A variable that is part of another variable (as an array or 8329 // structure element) cannot appear in a private clause. 8330 if (!FirstIter && IR != ER) 8331 ++IR; 8332 FirstIter = false; 8333 SourceLocation ELoc; 8334 SourceRange ERange; 8335 Expr *SimpleRefExpr = RefExpr; 8336 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 8337 /*AllowArraySection=*/true); 8338 if (Res.second) { 8339 // It will be analyzed later. 8340 Vars.push_back(RefExpr); 8341 Privates.push_back(nullptr); 8342 LHSs.push_back(nullptr); 8343 RHSs.push_back(nullptr); 8344 // Try to find 'declare reduction' corresponding construct before using 8345 // builtin/overloaded operators. 8346 QualType Type = Context.DependentTy; 8347 CXXCastPath BasePath; 8348 ExprResult DeclareReductionRef = buildDeclareReductionRef( 8349 *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, 8350 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 8351 if (CurContext->isDependentContext() && 8352 (DeclareReductionRef.isUnset() || 8353 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 8354 ReductionOps.push_back(DeclareReductionRef.get()); 8355 else 8356 ReductionOps.push_back(nullptr); 8357 } 8358 ValueDecl *D = Res.first; 8359 if (!D) 8360 continue; 8361 8362 QualType Type; 8363 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 8364 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 8365 if (ASE) 8366 Type = ASE->getType().getNonReferenceType(); 8367 else if (OASE) { 8368 auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 8369 if (auto *ATy = BaseType->getAsArrayTypeUnsafe()) 8370 Type = ATy->getElementType(); 8371 else 8372 Type = BaseType->getPointeeType(); 8373 Type = Type.getNonReferenceType(); 8374 } else 8375 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 8376 auto *VD = dyn_cast<VarDecl>(D); 8377 8378 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 8379 // A variable that appears in a private clause must not have an incomplete 8380 // type or a reference type. 8381 if (RequireCompleteType(ELoc, Type, 8382 diag::err_omp_reduction_incomplete_type)) 8383 continue; 8384 // OpenMP [2.14.3.6, reduction clause, Restrictions] 8385 // A list item that appears in a reduction clause must not be 8386 // const-qualified. 8387 if (Type.getNonReferenceType().isConstant(Context)) { 8388 Diag(ELoc, diag::err_omp_const_reduction_list_item) 8389 << getOpenMPClauseName(OMPC_reduction) << Type << ERange; 8390 if (!ASE && !OASE) { 8391 bool IsDecl = !VD || 8392 VD->isThisDeclarationADefinition(Context) == 8393 VarDecl::DeclarationOnly; 8394 Diag(D->getLocation(), 8395 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8396 << D; 8397 } 8398 continue; 8399 } 8400 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 8401 // If a list-item is a reference type then it must bind to the same object 8402 // for all threads of the team. 8403 if (!ASE && !OASE && VD) { 8404 VarDecl *VDDef = VD->getDefinition(); 8405 if (VD->getType()->isReferenceType() && VDDef) { 8406 DSARefChecker Check(DSAStack); 8407 if (Check.Visit(VDDef->getInit())) { 8408 Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; 8409 Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 8410 continue; 8411 } 8412 } 8413 } 8414 8415 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 8416 // in a Construct] 8417 // Variables with the predetermined data-sharing attributes may not be 8418 // listed in data-sharing attributes clauses, except for the cases 8419 // listed below. For these exceptions only, listing a predetermined 8420 // variable in a data-sharing attribute clause is allowed and overrides 8421 // the variable's predetermined data-sharing attributes. 8422 // OpenMP [2.14.3.6, Restrictions, p.3] 8423 // Any number of reduction clauses can be specified on the directive, 8424 // but a list item can appear only once in the reduction clauses for that 8425 // directive. 8426 DSAStackTy::DSAVarData DVar; 8427 DVar = DSAStack->getTopDSA(D, false); 8428 if (DVar.CKind == OMPC_reduction) { 8429 Diag(ELoc, diag::err_omp_once_referenced) 8430 << getOpenMPClauseName(OMPC_reduction); 8431 if (DVar.RefExpr) 8432 Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 8433 } else if (DVar.CKind != OMPC_unknown) { 8434 Diag(ELoc, diag::err_omp_wrong_dsa) 8435 << getOpenMPClauseName(DVar.CKind) 8436 << getOpenMPClauseName(OMPC_reduction); 8437 ReportOriginalDSA(*this, DSAStack, D, DVar); 8438 continue; 8439 } 8440 8441 // OpenMP [2.14.3.6, Restrictions, p.1] 8442 // A list item that appears in a reduction clause of a worksharing 8443 // construct must be shared in the parallel regions to which any of the 8444 // worksharing regions arising from the worksharing construct bind. 8445 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 8446 if (isOpenMPWorksharingDirective(CurrDir) && 8447 !isOpenMPParallelDirective(CurrDir)) { 8448 DVar = DSAStack->getImplicitDSA(D, true); 8449 if (DVar.CKind != OMPC_shared) { 8450 Diag(ELoc, diag::err_omp_required_access) 8451 << getOpenMPClauseName(OMPC_reduction) 8452 << getOpenMPClauseName(OMPC_shared); 8453 ReportOriginalDSA(*this, DSAStack, D, DVar); 8454 continue; 8455 } 8456 } 8457 8458 // Try to find 'declare reduction' corresponding construct before using 8459 // builtin/overloaded operators. 8460 CXXCastPath BasePath; 8461 ExprResult DeclareReductionRef = buildDeclareReductionRef( 8462 *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, 8463 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 8464 if (DeclareReductionRef.isInvalid()) 8465 continue; 8466 if (CurContext->isDependentContext() && 8467 (DeclareReductionRef.isUnset() || 8468 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 8469 Vars.push_back(RefExpr); 8470 Privates.push_back(nullptr); 8471 LHSs.push_back(nullptr); 8472 RHSs.push_back(nullptr); 8473 ReductionOps.push_back(DeclareReductionRef.get()); 8474 continue; 8475 } 8476 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 8477 // Not allowed reduction identifier is found. 8478 Diag(ReductionId.getLocStart(), 8479 diag::err_omp_unknown_reduction_identifier) 8480 << Type << ReductionIdRange; 8481 continue; 8482 } 8483 8484 // OpenMP [2.14.3.6, reduction clause, Restrictions] 8485 // The type of a list item that appears in a reduction clause must be valid 8486 // for the reduction-identifier. For a max or min reduction in C, the type 8487 // of the list item must be an allowed arithmetic data type: char, int, 8488 // float, double, or _Bool, possibly modified with long, short, signed, or 8489 // unsigned. For a max or min reduction in C++, the type of the list item 8490 // must be an allowed arithmetic data type: char, wchar_t, int, float, 8491 // double, or bool, possibly modified with long, short, signed, or unsigned. 8492 if (DeclareReductionRef.isUnset()) { 8493 if ((BOK == BO_GT || BOK == BO_LT) && 8494 !(Type->isScalarType() || 8495 (getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 8496 Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 8497 << getLangOpts().CPlusPlus; 8498 if (!ASE && !OASE) { 8499 bool IsDecl = !VD || 8500 VD->isThisDeclarationADefinition(Context) == 8501 VarDecl::DeclarationOnly; 8502 Diag(D->getLocation(), 8503 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8504 << D; 8505 } 8506 continue; 8507 } 8508 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 8509 !getLangOpts().CPlusPlus && Type->isFloatingType()) { 8510 Diag(ELoc, diag::err_omp_clause_floating_type_arg); 8511 if (!ASE && !OASE) { 8512 bool IsDecl = !VD || 8513 VD->isThisDeclarationADefinition(Context) == 8514 VarDecl::DeclarationOnly; 8515 Diag(D->getLocation(), 8516 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8517 << D; 8518 } 8519 continue; 8520 } 8521 } 8522 8523 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 8524 auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs", 8525 D->hasAttrs() ? &D->getAttrs() : nullptr); 8526 auto *RHSVD = buildVarDecl(*this, ELoc, Type, D->getName(), 8527 D->hasAttrs() ? &D->getAttrs() : nullptr); 8528 auto PrivateTy = Type; 8529 if (OASE || 8530 (!ASE && 8531 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 8532 // For arays/array sections only: 8533 // Create pseudo array type for private copy. The size for this array will 8534 // be generated during codegen. 8535 // For array subscripts or single variables Private Ty is the same as Type 8536 // (type of the variable or single array element). 8537 PrivateTy = Context.getVariableArrayType( 8538 Type, new (Context) OpaqueValueExpr(SourceLocation(), 8539 Context.getSizeType(), VK_RValue), 8540 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 8541 } else if (!ASE && !OASE && 8542 Context.getAsArrayType(D->getType().getNonReferenceType())) 8543 PrivateTy = D->getType().getNonReferenceType(); 8544 // Private copy. 8545 auto *PrivateVD = buildVarDecl(*this, ELoc, PrivateTy, D->getName(), 8546 D->hasAttrs() ? &D->getAttrs() : nullptr); 8547 // Add initializer for private variable. 8548 Expr *Init = nullptr; 8549 auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc); 8550 auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc); 8551 if (DeclareReductionRef.isUsable()) { 8552 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 8553 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 8554 if (DRD->getInitializer()) { 8555 Init = DRDRef; 8556 RHSVD->setInit(DRDRef); 8557 RHSVD->setInitStyle(VarDecl::CallInit); 8558 } 8559 } else { 8560 switch (BOK) { 8561 case BO_Add: 8562 case BO_Xor: 8563 case BO_Or: 8564 case BO_LOr: 8565 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 8566 if (Type->isScalarType() || Type->isAnyComplexType()) 8567 Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 8568 break; 8569 case BO_Mul: 8570 case BO_LAnd: 8571 if (Type->isScalarType() || Type->isAnyComplexType()) { 8572 // '*' and '&&' reduction ops - initializer is '1'. 8573 Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 8574 } 8575 break; 8576 case BO_And: { 8577 // '&' reduction op - initializer is '~0'. 8578 QualType OrigType = Type; 8579 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 8580 Type = ComplexTy->getElementType(); 8581 if (Type->isRealFloatingType()) { 8582 llvm::APFloat InitValue = 8583 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 8584 /*isIEEE=*/true); 8585 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 8586 Type, ELoc); 8587 } else if (Type->isScalarType()) { 8588 auto Size = Context.getTypeSize(Type); 8589 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 8590 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 8591 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 8592 } 8593 if (Init && OrigType->isAnyComplexType()) { 8594 // Init = 0xFFFF + 0xFFFFi; 8595 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 8596 Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 8597 } 8598 Type = OrigType; 8599 break; 8600 } 8601 case BO_LT: 8602 case BO_GT: { 8603 // 'min' reduction op - initializer is 'Largest representable number in 8604 // the reduction list item type'. 8605 // 'max' reduction op - initializer is 'Least representable number in 8606 // the reduction list item type'. 8607 if (Type->isIntegerType() || Type->isPointerType()) { 8608 bool IsSigned = Type->hasSignedIntegerRepresentation(); 8609 auto Size = Context.getTypeSize(Type); 8610 QualType IntTy = 8611 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 8612 llvm::APInt InitValue = 8613 (BOK != BO_LT) 8614 ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 8615 : llvm::APInt::getMinValue(Size) 8616 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 8617 : llvm::APInt::getMaxValue(Size); 8618 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 8619 if (Type->isPointerType()) { 8620 // Cast to pointer type. 8621 auto CastExpr = BuildCStyleCastExpr( 8622 SourceLocation(), Context.getTrivialTypeSourceInfo(Type, ELoc), 8623 SourceLocation(), Init); 8624 if (CastExpr.isInvalid()) 8625 continue; 8626 Init = CastExpr.get(); 8627 } 8628 } else if (Type->isRealFloatingType()) { 8629 llvm::APFloat InitValue = llvm::APFloat::getLargest( 8630 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 8631 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 8632 Type, ELoc); 8633 } 8634 break; 8635 } 8636 case BO_PtrMemD: 8637 case BO_PtrMemI: 8638 case BO_MulAssign: 8639 case BO_Div: 8640 case BO_Rem: 8641 case BO_Sub: 8642 case BO_Shl: 8643 case BO_Shr: 8644 case BO_LE: 8645 case BO_GE: 8646 case BO_EQ: 8647 case BO_NE: 8648 case BO_AndAssign: 8649 case BO_XorAssign: 8650 case BO_OrAssign: 8651 case BO_Assign: 8652 case BO_AddAssign: 8653 case BO_SubAssign: 8654 case BO_DivAssign: 8655 case BO_RemAssign: 8656 case BO_ShlAssign: 8657 case BO_ShrAssign: 8658 case BO_Comma: 8659 llvm_unreachable("Unexpected reduction operation"); 8660 } 8661 } 8662 if (Init && DeclareReductionRef.isUnset()) { 8663 AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false, 8664 /*TypeMayContainAuto=*/false); 8665 } else if (!Init) 8666 ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false); 8667 if (RHSVD->isInvalidDecl()) 8668 continue; 8669 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 8670 Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type 8671 << ReductionIdRange; 8672 bool IsDecl = 8673 !VD || 8674 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8675 Diag(D->getLocation(), 8676 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8677 << D; 8678 continue; 8679 } 8680 // Store initializer for single element in private copy. Will be used during 8681 // codegen. 8682 PrivateVD->setInit(RHSVD->getInit()); 8683 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 8684 auto *PrivateDRE = buildDeclRefExpr(*this, PrivateVD, PrivateTy, ELoc); 8685 ExprResult ReductionOp; 8686 if (DeclareReductionRef.isUsable()) { 8687 QualType RedTy = DeclareReductionRef.get()->getType(); 8688 QualType PtrRedTy = Context.getPointerType(RedTy); 8689 ExprResult LHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 8690 ExprResult RHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 8691 if (!BasePath.empty()) { 8692 LHS = DefaultLvalueConversion(LHS.get()); 8693 RHS = DefaultLvalueConversion(RHS.get()); 8694 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 8695 CK_UncheckedDerivedToBase, LHS.get(), 8696 &BasePath, LHS.get()->getValueKind()); 8697 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 8698 CK_UncheckedDerivedToBase, RHS.get(), 8699 &BasePath, RHS.get()->getValueKind()); 8700 } 8701 FunctionProtoType::ExtProtoInfo EPI; 8702 QualType Params[] = {PtrRedTy, PtrRedTy}; 8703 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 8704 auto *OVE = new (Context) OpaqueValueExpr( 8705 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 8706 DefaultLvalueConversion(DeclareReductionRef.get()).get()); 8707 Expr *Args[] = {LHS.get(), RHS.get()}; 8708 ReductionOp = new (Context) 8709 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 8710 } else { 8711 ReductionOp = BuildBinOp(DSAStack->getCurScope(), 8712 ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE); 8713 if (ReductionOp.isUsable()) { 8714 if (BOK != BO_LT && BOK != BO_GT) { 8715 ReductionOp = 8716 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 8717 BO_Assign, LHSDRE, ReductionOp.get()); 8718 } else { 8719 auto *ConditionalOp = new (Context) ConditionalOperator( 8720 ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(), 8721 RHSDRE, Type, VK_LValue, OK_Ordinary); 8722 ReductionOp = 8723 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 8724 BO_Assign, LHSDRE, ConditionalOp); 8725 } 8726 ReductionOp = ActOnFinishFullExpr(ReductionOp.get()); 8727 } 8728 if (ReductionOp.isInvalid()) 8729 continue; 8730 } 8731 8732 DeclRefExpr *Ref = nullptr; 8733 Expr *VarsExpr = RefExpr->IgnoreParens(); 8734 if (!VD) { 8735 if (ASE || OASE) { 8736 TransformExprToCaptures RebuildToCapture(*this, D); 8737 VarsExpr = 8738 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 8739 Ref = RebuildToCapture.getCapturedExpr(); 8740 } else { 8741 VarsExpr = Ref = 8742 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 8743 } 8744 if (!IsOpenMPCapturedDecl(D)) { 8745 ExprCaptures.push_back(Ref->getDecl()); 8746 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 8747 ExprResult RefRes = DefaultLvalueConversion(Ref); 8748 if (!RefRes.isUsable()) 8749 continue; 8750 ExprResult PostUpdateRes = 8751 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 8752 SimpleRefExpr, RefRes.get()); 8753 if (!PostUpdateRes.isUsable()) 8754 continue; 8755 ExprPostUpdates.push_back( 8756 IgnoredValueConversions(PostUpdateRes.get()).get()); 8757 } 8758 } 8759 } 8760 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 8761 Vars.push_back(VarsExpr); 8762 Privates.push_back(PrivateDRE); 8763 LHSs.push_back(LHSDRE); 8764 RHSs.push_back(RHSDRE); 8765 ReductionOps.push_back(ReductionOp.get()); 8766 } 8767 8768 if (Vars.empty()) 8769 return nullptr; 8770 8771 return OMPReductionClause::Create( 8772 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars, 8773 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates, 8774 LHSs, RHSs, ReductionOps, buildPreInits(Context, ExprCaptures), 8775 buildPostUpdate(*this, ExprPostUpdates)); 8776 } 8777 8778 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 8779 SourceLocation LinLoc) { 8780 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 8781 LinKind == OMPC_LINEAR_unknown) { 8782 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 8783 return true; 8784 } 8785 return false; 8786 } 8787 8788 bool Sema::CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, 8789 OpenMPLinearClauseKind LinKind, 8790 QualType Type) { 8791 auto *VD = dyn_cast_or_null<VarDecl>(D); 8792 // A variable must not have an incomplete type or a reference type. 8793 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 8794 return true; 8795 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 8796 !Type->isReferenceType()) { 8797 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 8798 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 8799 return true; 8800 } 8801 Type = Type.getNonReferenceType(); 8802 8803 // A list item must not be const-qualified. 8804 if (Type.isConstant(Context)) { 8805 Diag(ELoc, diag::err_omp_const_variable) 8806 << getOpenMPClauseName(OMPC_linear); 8807 if (D) { 8808 bool IsDecl = 8809 !VD || 8810 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8811 Diag(D->getLocation(), 8812 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8813 << D; 8814 } 8815 return true; 8816 } 8817 8818 // A list item must be of integral or pointer type. 8819 Type = Type.getUnqualifiedType().getCanonicalType(); 8820 const auto *Ty = Type.getTypePtrOrNull(); 8821 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 8822 !Ty->isPointerType())) { 8823 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 8824 if (D) { 8825 bool IsDecl = 8826 !VD || 8827 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8828 Diag(D->getLocation(), 8829 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8830 << D; 8831 } 8832 return true; 8833 } 8834 return false; 8835 } 8836 8837 OMPClause *Sema::ActOnOpenMPLinearClause( 8838 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 8839 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 8840 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 8841 SmallVector<Expr *, 8> Vars; 8842 SmallVector<Expr *, 8> Privates; 8843 SmallVector<Expr *, 8> Inits; 8844 SmallVector<Decl *, 4> ExprCaptures; 8845 SmallVector<Expr *, 4> ExprPostUpdates; 8846 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 8847 LinKind = OMPC_LINEAR_val; 8848 for (auto &RefExpr : VarList) { 8849 assert(RefExpr && "NULL expr in OpenMP linear clause."); 8850 SourceLocation ELoc; 8851 SourceRange ERange; 8852 Expr *SimpleRefExpr = RefExpr; 8853 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 8854 /*AllowArraySection=*/false); 8855 if (Res.second) { 8856 // It will be analyzed later. 8857 Vars.push_back(RefExpr); 8858 Privates.push_back(nullptr); 8859 Inits.push_back(nullptr); 8860 } 8861 ValueDecl *D = Res.first; 8862 if (!D) 8863 continue; 8864 8865 QualType Type = D->getType(); 8866 auto *VD = dyn_cast<VarDecl>(D); 8867 8868 // OpenMP [2.14.3.7, linear clause] 8869 // A list-item cannot appear in more than one linear clause. 8870 // A list-item that appears in a linear clause cannot appear in any 8871 // other data-sharing attribute clause. 8872 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8873 if (DVar.RefExpr) { 8874 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 8875 << getOpenMPClauseName(OMPC_linear); 8876 ReportOriginalDSA(*this, DSAStack, D, DVar); 8877 continue; 8878 } 8879 8880 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 8881 continue; 8882 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 8883 8884 // Build private copy of original var. 8885 auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(), 8886 D->hasAttrs() ? &D->getAttrs() : nullptr); 8887 auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 8888 // Build var to save initial value. 8889 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 8890 Expr *InitExpr; 8891 DeclRefExpr *Ref = nullptr; 8892 if (!VD) { 8893 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 8894 if (!IsOpenMPCapturedDecl(D)) { 8895 ExprCaptures.push_back(Ref->getDecl()); 8896 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 8897 ExprResult RefRes = DefaultLvalueConversion(Ref); 8898 if (!RefRes.isUsable()) 8899 continue; 8900 ExprResult PostUpdateRes = 8901 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 8902 SimpleRefExpr, RefRes.get()); 8903 if (!PostUpdateRes.isUsable()) 8904 continue; 8905 ExprPostUpdates.push_back( 8906 IgnoredValueConversions(PostUpdateRes.get()).get()); 8907 } 8908 } 8909 } 8910 if (LinKind == OMPC_LINEAR_uval) 8911 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 8912 else 8913 InitExpr = VD ? SimpleRefExpr : Ref; 8914 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 8915 /*DirectInit=*/false, /*TypeMayContainAuto=*/false); 8916 auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 8917 8918 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 8919 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 8920 Privates.push_back(PrivateRef); 8921 Inits.push_back(InitRef); 8922 } 8923 8924 if (Vars.empty()) 8925 return nullptr; 8926 8927 Expr *StepExpr = Step; 8928 Expr *CalcStepExpr = nullptr; 8929 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 8930 !Step->isInstantiationDependent() && 8931 !Step->containsUnexpandedParameterPack()) { 8932 SourceLocation StepLoc = Step->getLocStart(); 8933 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 8934 if (Val.isInvalid()) 8935 return nullptr; 8936 StepExpr = Val.get(); 8937 8938 // Build var to save the step value. 8939 VarDecl *SaveVar = 8940 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 8941 ExprResult SaveRef = 8942 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 8943 ExprResult CalcStep = 8944 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 8945 CalcStep = ActOnFinishFullExpr(CalcStep.get()); 8946 8947 // Warn about zero linear step (it would be probably better specified as 8948 // making corresponding variables 'const'). 8949 llvm::APSInt Result; 8950 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 8951 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 8952 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 8953 << (Vars.size() > 1); 8954 if (!IsConstant && CalcStep.isUsable()) { 8955 // Calculate the step beforehand instead of doing this on each iteration. 8956 // (This is not used if the number of iterations may be kfold-ed). 8957 CalcStepExpr = CalcStep.get(); 8958 } 8959 } 8960 8961 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 8962 ColonLoc, EndLoc, Vars, Privates, Inits, 8963 StepExpr, CalcStepExpr, 8964 buildPreInits(Context, ExprCaptures), 8965 buildPostUpdate(*this, ExprPostUpdates)); 8966 } 8967 8968 static bool 8969 FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 8970 Expr *NumIterations, Sema &SemaRef, Scope *S) { 8971 // Walk the vars and build update/final expressions for the CodeGen. 8972 SmallVector<Expr *, 8> Updates; 8973 SmallVector<Expr *, 8> Finals; 8974 Expr *Step = Clause.getStep(); 8975 Expr *CalcStep = Clause.getCalcStep(); 8976 // OpenMP [2.14.3.7, linear clause] 8977 // If linear-step is not specified it is assumed to be 1. 8978 if (Step == nullptr) 8979 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 8980 else if (CalcStep) { 8981 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 8982 } 8983 bool HasErrors = false; 8984 auto CurInit = Clause.inits().begin(); 8985 auto CurPrivate = Clause.privates().begin(); 8986 auto LinKind = Clause.getModifier(); 8987 for (auto &RefExpr : Clause.varlists()) { 8988 Expr *InitExpr = *CurInit; 8989 8990 // Build privatized reference to the current linear var. 8991 auto DE = cast<DeclRefExpr>(RefExpr); 8992 Expr *CapturedRef; 8993 if (LinKind == OMPC_LINEAR_uval) 8994 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 8995 else 8996 CapturedRef = 8997 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 8998 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 8999 /*RefersToCapture=*/true); 9000 9001 // Build update: Var = InitExpr + IV * Step 9002 ExprResult Update = 9003 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 9004 InitExpr, IV, Step, /* Subtract */ false); 9005 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(), 9006 /*DiscardedValue=*/true); 9007 9008 // Build final: Var = InitExpr + NumIterations * Step 9009 ExprResult Final = 9010 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 9011 InitExpr, NumIterations, Step, /* Subtract */ false); 9012 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(), 9013 /*DiscardedValue=*/true); 9014 if (!Update.isUsable() || !Final.isUsable()) { 9015 Updates.push_back(nullptr); 9016 Finals.push_back(nullptr); 9017 HasErrors = true; 9018 } else { 9019 Updates.push_back(Update.get()); 9020 Finals.push_back(Final.get()); 9021 } 9022 ++CurInit; 9023 ++CurPrivate; 9024 } 9025 Clause.setUpdates(Updates); 9026 Clause.setFinals(Finals); 9027 return HasErrors; 9028 } 9029 9030 OMPClause *Sema::ActOnOpenMPAlignedClause( 9031 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 9032 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 9033 9034 SmallVector<Expr *, 8> Vars; 9035 for (auto &RefExpr : VarList) { 9036 assert(RefExpr && "NULL expr in OpenMP linear clause."); 9037 SourceLocation ELoc; 9038 SourceRange ERange; 9039 Expr *SimpleRefExpr = RefExpr; 9040 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 9041 /*AllowArraySection=*/false); 9042 if (Res.second) { 9043 // It will be analyzed later. 9044 Vars.push_back(RefExpr); 9045 } 9046 ValueDecl *D = Res.first; 9047 if (!D) 9048 continue; 9049 9050 QualType QType = D->getType(); 9051 auto *VD = dyn_cast<VarDecl>(D); 9052 9053 // OpenMP [2.8.1, simd construct, Restrictions] 9054 // The type of list items appearing in the aligned clause must be 9055 // array, pointer, reference to array, or reference to pointer. 9056 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 9057 const Type *Ty = QType.getTypePtrOrNull(); 9058 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 9059 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 9060 << QType << getLangOpts().CPlusPlus << ERange; 9061 bool IsDecl = 9062 !VD || 9063 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9064 Diag(D->getLocation(), 9065 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9066 << D; 9067 continue; 9068 } 9069 9070 // OpenMP [2.8.1, simd construct, Restrictions] 9071 // A list-item cannot appear in more than one aligned clause. 9072 if (Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 9073 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 9074 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 9075 << getOpenMPClauseName(OMPC_aligned); 9076 continue; 9077 } 9078 9079 DeclRefExpr *Ref = nullptr; 9080 if (!VD && IsOpenMPCapturedDecl(D)) 9081 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 9082 Vars.push_back(DefaultFunctionArrayConversion( 9083 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 9084 .get()); 9085 } 9086 9087 // OpenMP [2.8.1, simd construct, Description] 9088 // The parameter of the aligned clause, alignment, must be a constant 9089 // positive integer expression. 9090 // If no optional parameter is specified, implementation-defined default 9091 // alignments for SIMD instructions on the target platforms are assumed. 9092 if (Alignment != nullptr) { 9093 ExprResult AlignResult = 9094 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 9095 if (AlignResult.isInvalid()) 9096 return nullptr; 9097 Alignment = AlignResult.get(); 9098 } 9099 if (Vars.empty()) 9100 return nullptr; 9101 9102 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 9103 EndLoc, Vars, Alignment); 9104 } 9105 9106 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 9107 SourceLocation StartLoc, 9108 SourceLocation LParenLoc, 9109 SourceLocation EndLoc) { 9110 SmallVector<Expr *, 8> Vars; 9111 SmallVector<Expr *, 8> SrcExprs; 9112 SmallVector<Expr *, 8> DstExprs; 9113 SmallVector<Expr *, 8> AssignmentOps; 9114 for (auto &RefExpr : VarList) { 9115 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 9116 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 9117 // It will be analyzed later. 9118 Vars.push_back(RefExpr); 9119 SrcExprs.push_back(nullptr); 9120 DstExprs.push_back(nullptr); 9121 AssignmentOps.push_back(nullptr); 9122 continue; 9123 } 9124 9125 SourceLocation ELoc = RefExpr->getExprLoc(); 9126 // OpenMP [2.1, C/C++] 9127 // A list item is a variable name. 9128 // OpenMP [2.14.4.1, Restrictions, p.1] 9129 // A list item that appears in a copyin clause must be threadprivate. 9130 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 9131 if (!DE || !isa<VarDecl>(DE->getDecl())) { 9132 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 9133 << 0 << RefExpr->getSourceRange(); 9134 continue; 9135 } 9136 9137 Decl *D = DE->getDecl(); 9138 VarDecl *VD = cast<VarDecl>(D); 9139 9140 QualType Type = VD->getType(); 9141 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 9142 // It will be analyzed later. 9143 Vars.push_back(DE); 9144 SrcExprs.push_back(nullptr); 9145 DstExprs.push_back(nullptr); 9146 AssignmentOps.push_back(nullptr); 9147 continue; 9148 } 9149 9150 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 9151 // A list item that appears in a copyin clause must be threadprivate. 9152 if (!DSAStack->isThreadPrivate(VD)) { 9153 Diag(ELoc, diag::err_omp_required_access) 9154 << getOpenMPClauseName(OMPC_copyin) 9155 << getOpenMPDirectiveName(OMPD_threadprivate); 9156 continue; 9157 } 9158 9159 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 9160 // A variable of class type (or array thereof) that appears in a 9161 // copyin clause requires an accessible, unambiguous copy assignment 9162 // operator for the class type. 9163 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 9164 auto *SrcVD = 9165 buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(), 9166 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 9167 auto *PseudoSrcExpr = buildDeclRefExpr( 9168 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 9169 auto *DstVD = 9170 buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst", 9171 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 9172 auto *PseudoDstExpr = 9173 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 9174 // For arrays generate assignment operation for single element and replace 9175 // it by the original array element in CodeGen. 9176 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 9177 PseudoDstExpr, PseudoSrcExpr); 9178 if (AssignmentOp.isInvalid()) 9179 continue; 9180 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 9181 /*DiscardedValue=*/true); 9182 if (AssignmentOp.isInvalid()) 9183 continue; 9184 9185 DSAStack->addDSA(VD, DE, OMPC_copyin); 9186 Vars.push_back(DE); 9187 SrcExprs.push_back(PseudoSrcExpr); 9188 DstExprs.push_back(PseudoDstExpr); 9189 AssignmentOps.push_back(AssignmentOp.get()); 9190 } 9191 9192 if (Vars.empty()) 9193 return nullptr; 9194 9195 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 9196 SrcExprs, DstExprs, AssignmentOps); 9197 } 9198 9199 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 9200 SourceLocation StartLoc, 9201 SourceLocation LParenLoc, 9202 SourceLocation EndLoc) { 9203 SmallVector<Expr *, 8> Vars; 9204 SmallVector<Expr *, 8> SrcExprs; 9205 SmallVector<Expr *, 8> DstExprs; 9206 SmallVector<Expr *, 8> AssignmentOps; 9207 for (auto &RefExpr : VarList) { 9208 assert(RefExpr && "NULL expr in OpenMP linear clause."); 9209 SourceLocation ELoc; 9210 SourceRange ERange; 9211 Expr *SimpleRefExpr = RefExpr; 9212 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 9213 /*AllowArraySection=*/false); 9214 if (Res.second) { 9215 // It will be analyzed later. 9216 Vars.push_back(RefExpr); 9217 SrcExprs.push_back(nullptr); 9218 DstExprs.push_back(nullptr); 9219 AssignmentOps.push_back(nullptr); 9220 } 9221 ValueDecl *D = Res.first; 9222 if (!D) 9223 continue; 9224 9225 QualType Type = D->getType(); 9226 auto *VD = dyn_cast<VarDecl>(D); 9227 9228 // OpenMP [2.14.4.2, Restrictions, p.2] 9229 // A list item that appears in a copyprivate clause may not appear in a 9230 // private or firstprivate clause on the single construct. 9231 if (!VD || !DSAStack->isThreadPrivate(VD)) { 9232 auto DVar = DSAStack->getTopDSA(D, false); 9233 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 9234 DVar.RefExpr) { 9235 Diag(ELoc, diag::err_omp_wrong_dsa) 9236 << getOpenMPClauseName(DVar.CKind) 9237 << getOpenMPClauseName(OMPC_copyprivate); 9238 ReportOriginalDSA(*this, DSAStack, D, DVar); 9239 continue; 9240 } 9241 9242 // OpenMP [2.11.4.2, Restrictions, p.1] 9243 // All list items that appear in a copyprivate clause must be either 9244 // threadprivate or private in the enclosing context. 9245 if (DVar.CKind == OMPC_unknown) { 9246 DVar = DSAStack->getImplicitDSA(D, false); 9247 if (DVar.CKind == OMPC_shared) { 9248 Diag(ELoc, diag::err_omp_required_access) 9249 << getOpenMPClauseName(OMPC_copyprivate) 9250 << "threadprivate or private in the enclosing context"; 9251 ReportOriginalDSA(*this, DSAStack, D, DVar); 9252 continue; 9253 } 9254 } 9255 } 9256 9257 // Variably modified types are not supported. 9258 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 9259 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 9260 << getOpenMPClauseName(OMPC_copyprivate) << Type 9261 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 9262 bool IsDecl = 9263 !VD || 9264 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9265 Diag(D->getLocation(), 9266 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9267 << D; 9268 continue; 9269 } 9270 9271 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 9272 // A variable of class type (or array thereof) that appears in a 9273 // copyin clause requires an accessible, unambiguous copy assignment 9274 // operator for the class type. 9275 Type = Context.getBaseElementType(Type.getNonReferenceType()) 9276 .getUnqualifiedType(); 9277 auto *SrcVD = 9278 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src", 9279 D->hasAttrs() ? &D->getAttrs() : nullptr); 9280 auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 9281 auto *DstVD = 9282 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst", 9283 D->hasAttrs() ? &D->getAttrs() : nullptr); 9284 auto *PseudoDstExpr = 9285 buildDeclRefExpr(*this, DstVD, Type, ELoc); 9286 auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 9287 PseudoDstExpr, PseudoSrcExpr); 9288 if (AssignmentOp.isInvalid()) 9289 continue; 9290 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 9291 /*DiscardedValue=*/true); 9292 if (AssignmentOp.isInvalid()) 9293 continue; 9294 9295 // No need to mark vars as copyprivate, they are already threadprivate or 9296 // implicitly private. 9297 assert(VD || IsOpenMPCapturedDecl(D)); 9298 Vars.push_back( 9299 VD ? RefExpr->IgnoreParens() 9300 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 9301 SrcExprs.push_back(PseudoSrcExpr); 9302 DstExprs.push_back(PseudoDstExpr); 9303 AssignmentOps.push_back(AssignmentOp.get()); 9304 } 9305 9306 if (Vars.empty()) 9307 return nullptr; 9308 9309 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9310 Vars, SrcExprs, DstExprs, AssignmentOps); 9311 } 9312 9313 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 9314 SourceLocation StartLoc, 9315 SourceLocation LParenLoc, 9316 SourceLocation EndLoc) { 9317 if (VarList.empty()) 9318 return nullptr; 9319 9320 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 9321 } 9322 9323 OMPClause * 9324 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 9325 SourceLocation DepLoc, SourceLocation ColonLoc, 9326 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 9327 SourceLocation LParenLoc, SourceLocation EndLoc) { 9328 if (DSAStack->getCurrentDirective() == OMPD_ordered && 9329 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 9330 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 9331 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 9332 return nullptr; 9333 } 9334 if (DSAStack->getCurrentDirective() != OMPD_ordered && 9335 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 9336 DepKind == OMPC_DEPEND_sink)) { 9337 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 9338 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 9339 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 9340 /*Last=*/OMPC_DEPEND_unknown, Except) 9341 << getOpenMPClauseName(OMPC_depend); 9342 return nullptr; 9343 } 9344 SmallVector<Expr *, 8> Vars; 9345 llvm::APSInt DepCounter(/*BitWidth=*/32); 9346 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 9347 if (DepKind == OMPC_DEPEND_sink) { 9348 if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) { 9349 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 9350 TotalDepCount.setIsUnsigned(/*Val=*/true); 9351 } 9352 } 9353 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) || 9354 DSAStack->getParentOrderedRegionParam()) { 9355 for (auto &RefExpr : VarList) { 9356 assert(RefExpr && "NULL expr in OpenMP shared clause."); 9357 if (isa<DependentScopeDeclRefExpr>(RefExpr) || 9358 (DepKind == OMPC_DEPEND_sink && CurContext->isDependentContext())) { 9359 // It will be analyzed later. 9360 Vars.push_back(RefExpr); 9361 continue; 9362 } 9363 9364 SourceLocation ELoc = RefExpr->getExprLoc(); 9365 auto *SimpleExpr = RefExpr->IgnoreParenCasts(); 9366 if (DepKind == OMPC_DEPEND_sink) { 9367 if (DepCounter >= TotalDepCount) { 9368 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 9369 continue; 9370 } 9371 ++DepCounter; 9372 // OpenMP [2.13.9, Summary] 9373 // depend(dependence-type : vec), where dependence-type is: 9374 // 'sink' and where vec is the iteration vector, which has the form: 9375 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 9376 // where n is the value specified by the ordered clause in the loop 9377 // directive, xi denotes the loop iteration variable of the i-th nested 9378 // loop associated with the loop directive, and di is a constant 9379 // non-negative integer. 9380 SimpleExpr = SimpleExpr->IgnoreImplicit(); 9381 auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr); 9382 if (!DE) { 9383 OverloadedOperatorKind OOK = OO_None; 9384 SourceLocation OOLoc; 9385 Expr *LHS, *RHS; 9386 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 9387 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 9388 OOLoc = BO->getOperatorLoc(); 9389 LHS = BO->getLHS()->IgnoreParenImpCasts(); 9390 RHS = BO->getRHS()->IgnoreParenImpCasts(); 9391 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 9392 OOK = OCE->getOperator(); 9393 OOLoc = OCE->getOperatorLoc(); 9394 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 9395 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 9396 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 9397 OOK = MCE->getMethodDecl() 9398 ->getNameInfo() 9399 .getName() 9400 .getCXXOverloadedOperator(); 9401 OOLoc = MCE->getCallee()->getExprLoc(); 9402 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 9403 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 9404 } else { 9405 Diag(ELoc, diag::err_omp_depend_sink_wrong_expr); 9406 continue; 9407 } 9408 DE = dyn_cast<DeclRefExpr>(LHS); 9409 if (!DE) { 9410 Diag(LHS->getExprLoc(), 9411 diag::err_omp_depend_sink_expected_loop_iteration) 9412 << DSAStack->getParentLoopControlVariable( 9413 DepCounter.getZExtValue()); 9414 continue; 9415 } 9416 if (OOK != OO_Plus && OOK != OO_Minus) { 9417 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 9418 continue; 9419 } 9420 ExprResult Res = VerifyPositiveIntegerConstantInClause( 9421 RHS, OMPC_depend, /*StrictlyPositive=*/false); 9422 if (Res.isInvalid()) 9423 continue; 9424 } 9425 auto *VD = dyn_cast<VarDecl>(DE->getDecl()); 9426 if (!CurContext->isDependentContext() && 9427 DSAStack->getParentOrderedRegionParam() && 9428 (!VD || 9429 DepCounter != DSAStack->isParentLoopControlVariable(VD).first)) { 9430 Diag(DE->getExprLoc(), 9431 diag::err_omp_depend_sink_expected_loop_iteration) 9432 << DSAStack->getParentLoopControlVariable( 9433 DepCounter.getZExtValue()); 9434 continue; 9435 } 9436 } else { 9437 // OpenMP [2.11.1.1, Restrictions, p.3] 9438 // A variable that is part of another variable (such as a field of a 9439 // structure) but is not an array element or an array section cannot 9440 // appear in a depend clause. 9441 auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr); 9442 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 9443 auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 9444 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 9445 (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) || 9446 (ASE && 9447 !ASE->getBase() 9448 ->getType() 9449 .getNonReferenceType() 9450 ->isPointerType() && 9451 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 9452 Diag(ELoc, diag::err_omp_expected_var_name_member_expr_or_array_item) 9453 << 0 << RefExpr->getSourceRange(); 9454 continue; 9455 } 9456 } 9457 9458 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 9459 } 9460 9461 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 9462 TotalDepCount > VarList.size() && 9463 DSAStack->getParentOrderedRegionParam()) { 9464 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 9465 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 9466 } 9467 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 9468 Vars.empty()) 9469 return nullptr; 9470 } 9471 9472 return OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, DepKind, 9473 DepLoc, ColonLoc, Vars); 9474 } 9475 9476 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 9477 SourceLocation LParenLoc, 9478 SourceLocation EndLoc) { 9479 Expr *ValExpr = Device; 9480 9481 // OpenMP [2.9.1, Restrictions] 9482 // The device expression must evaluate to a non-negative integer value. 9483 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 9484 /*StrictlyPositive=*/false)) 9485 return nullptr; 9486 9487 return new (Context) OMPDeviceClause(ValExpr, StartLoc, LParenLoc, EndLoc); 9488 } 9489 9490 static bool IsCXXRecordForMappable(Sema &SemaRef, SourceLocation Loc, 9491 DSAStackTy *Stack, CXXRecordDecl *RD) { 9492 if (!RD || RD->isInvalidDecl()) 9493 return true; 9494 9495 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) 9496 if (auto *CTD = CTSD->getSpecializedTemplate()) 9497 RD = CTD->getTemplatedDecl(); 9498 auto QTy = SemaRef.Context.getRecordType(RD); 9499 if (RD->isDynamicClass()) { 9500 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 9501 SemaRef.Diag(RD->getLocation(), diag::note_omp_polymorphic_in_target); 9502 return false; 9503 } 9504 auto *DC = RD; 9505 bool IsCorrect = true; 9506 for (auto *I : DC->decls()) { 9507 if (I) { 9508 if (auto *MD = dyn_cast<CXXMethodDecl>(I)) { 9509 if (MD->isStatic()) { 9510 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 9511 SemaRef.Diag(MD->getLocation(), 9512 diag::note_omp_static_member_in_target); 9513 IsCorrect = false; 9514 } 9515 } else if (auto *VD = dyn_cast<VarDecl>(I)) { 9516 if (VD->isStaticDataMember()) { 9517 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 9518 SemaRef.Diag(VD->getLocation(), 9519 diag::note_omp_static_member_in_target); 9520 IsCorrect = false; 9521 } 9522 } 9523 } 9524 } 9525 9526 for (auto &I : RD->bases()) { 9527 if (!IsCXXRecordForMappable(SemaRef, I.getLocStart(), Stack, 9528 I.getType()->getAsCXXRecordDecl())) 9529 IsCorrect = false; 9530 } 9531 return IsCorrect; 9532 } 9533 9534 static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 9535 DSAStackTy *Stack, QualType QTy) { 9536 NamedDecl *ND; 9537 if (QTy->isIncompleteType(&ND)) { 9538 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 9539 return false; 9540 } else if (CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(ND)) { 9541 if (!RD->isInvalidDecl() && 9542 !IsCXXRecordForMappable(SemaRef, SL, Stack, RD)) 9543 return false; 9544 } 9545 return true; 9546 } 9547 9548 /// \brief Return true if it can be proven that the provided array expression 9549 /// (array section or array subscript) does NOT specify the whole size of the 9550 /// array whose base type is \a BaseQTy. 9551 static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 9552 const Expr *E, 9553 QualType BaseQTy) { 9554 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 9555 9556 // If this is an array subscript, it refers to the whole size if the size of 9557 // the dimension is constant and equals 1. Also, an array section assumes the 9558 // format of an array subscript if no colon is used. 9559 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 9560 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 9561 return ATy->getSize().getSExtValue() != 1; 9562 // Size can't be evaluated statically. 9563 return false; 9564 } 9565 9566 assert(OASE && "Expecting array section if not an array subscript."); 9567 auto *LowerBound = OASE->getLowerBound(); 9568 auto *Length = OASE->getLength(); 9569 9570 // If there is a lower bound that does not evaluates to zero, we are not 9571 // convering the whole dimension. 9572 if (LowerBound) { 9573 llvm::APSInt ConstLowerBound; 9574 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) 9575 return false; // Can't get the integer value as a constant. 9576 if (ConstLowerBound.getSExtValue()) 9577 return true; 9578 } 9579 9580 // If we don't have a length we covering the whole dimension. 9581 if (!Length) 9582 return false; 9583 9584 // If the base is a pointer, we don't have a way to get the size of the 9585 // pointee. 9586 if (BaseQTy->isPointerType()) 9587 return false; 9588 9589 // We can only check if the length is the same as the size of the dimension 9590 // if we have a constant array. 9591 auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 9592 if (!CATy) 9593 return false; 9594 9595 llvm::APSInt ConstLength; 9596 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 9597 return false; // Can't get the integer value as a constant. 9598 9599 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 9600 } 9601 9602 // Return true if it can be proven that the provided array expression (array 9603 // section or array subscript) does NOT specify a single element of the array 9604 // whose base type is \a BaseQTy. 9605 static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 9606 const Expr *E, 9607 QualType BaseQTy) { 9608 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 9609 9610 // An array subscript always refer to a single element. Also, an array section 9611 // assumes the format of an array subscript if no colon is used. 9612 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 9613 return false; 9614 9615 assert(OASE && "Expecting array section if not an array subscript."); 9616 auto *Length = OASE->getLength(); 9617 9618 // If we don't have a length we have to check if the array has unitary size 9619 // for this dimension. Also, we should always expect a length if the base type 9620 // is pointer. 9621 if (!Length) { 9622 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 9623 return ATy->getSize().getSExtValue() != 1; 9624 // We cannot assume anything. 9625 return false; 9626 } 9627 9628 // Check if the length evaluates to 1. 9629 llvm::APSInt ConstLength; 9630 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 9631 return false; // Can't get the integer value as a constant. 9632 9633 return ConstLength.getSExtValue() != 1; 9634 } 9635 9636 // Return the expression of the base of the map clause or null if it cannot 9637 // be determined and do all the necessary checks to see if the expression is 9638 // valid as a standalone map clause expression. 9639 static Expr *CheckMapClauseExpressionBase(Sema &SemaRef, Expr *E) { 9640 SourceLocation ELoc = E->getExprLoc(); 9641 SourceRange ERange = E->getSourceRange(); 9642 9643 // The base of elements of list in a map clause have to be either: 9644 // - a reference to variable or field. 9645 // - a member expression. 9646 // - an array expression. 9647 // 9648 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 9649 // reference to 'r'. 9650 // 9651 // If we have: 9652 // 9653 // struct SS { 9654 // Bla S; 9655 // foo() { 9656 // #pragma omp target map (S.Arr[:12]); 9657 // } 9658 // } 9659 // 9660 // We want to retrieve the member expression 'this->S'; 9661 9662 Expr *RelevantExpr = nullptr; 9663 9664 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 9665 // If a list item is an array section, it must specify contiguous storage. 9666 // 9667 // For this restriction it is sufficient that we make sure only references 9668 // to variables or fields and array expressions, and that no array sections 9669 // exist except in the rightmost expression (unless they cover the whole 9670 // dimension of the array). E.g. these would be invalid: 9671 // 9672 // r.ArrS[3:5].Arr[6:7] 9673 // 9674 // r.ArrS[3:5].x 9675 // 9676 // but these would be valid: 9677 // r.ArrS[3].Arr[6:7] 9678 // 9679 // r.ArrS[3].x 9680 9681 bool AllowUnitySizeArraySection = true; 9682 bool AllowWholeSizeArraySection = true; 9683 9684 while (!RelevantExpr) { 9685 E = E->IgnoreParenImpCasts(); 9686 9687 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 9688 if (!isa<VarDecl>(CurE->getDecl())) 9689 break; 9690 9691 RelevantExpr = CurE; 9692 9693 // If we got a reference to a declaration, we should not expect any array 9694 // section before that. 9695 AllowUnitySizeArraySection = false; 9696 AllowWholeSizeArraySection = false; 9697 continue; 9698 } 9699 9700 if (auto *CurE = dyn_cast<MemberExpr>(E)) { 9701 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 9702 9703 if (isa<CXXThisExpr>(BaseE)) 9704 // We found a base expression: this->Val. 9705 RelevantExpr = CurE; 9706 else 9707 E = BaseE; 9708 9709 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 9710 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 9711 << CurE->getSourceRange(); 9712 break; 9713 } 9714 9715 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 9716 9717 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 9718 // A bit-field cannot appear in a map clause. 9719 // 9720 if (FD->isBitField()) { 9721 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_map_clause) 9722 << CurE->getSourceRange(); 9723 break; 9724 } 9725 9726 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 9727 // If the type of a list item is a reference to a type T then the type 9728 // will be considered to be T for all purposes of this clause. 9729 QualType CurType = BaseE->getType().getNonReferenceType(); 9730 9731 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 9732 // A list item cannot be a variable that is a member of a structure with 9733 // a union type. 9734 // 9735 if (auto *RT = CurType->getAs<RecordType>()) 9736 if (RT->isUnionType()) { 9737 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 9738 << CurE->getSourceRange(); 9739 break; 9740 } 9741 9742 // If we got a member expression, we should not expect any array section 9743 // before that: 9744 // 9745 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 9746 // If a list item is an element of a structure, only the rightmost symbol 9747 // of the variable reference can be an array section. 9748 // 9749 AllowUnitySizeArraySection = false; 9750 AllowWholeSizeArraySection = false; 9751 continue; 9752 } 9753 9754 if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 9755 E = CurE->getBase()->IgnoreParenImpCasts(); 9756 9757 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 9758 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 9759 << 0 << CurE->getSourceRange(); 9760 break; 9761 } 9762 9763 // If we got an array subscript that express the whole dimension we 9764 // can have any array expressions before. If it only expressing part of 9765 // the dimension, we can only have unitary-size array expressions. 9766 if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 9767 E->getType())) 9768 AllowWholeSizeArraySection = false; 9769 continue; 9770 } 9771 9772 if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 9773 E = CurE->getBase()->IgnoreParenImpCasts(); 9774 9775 auto CurType = 9776 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 9777 9778 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 9779 // If the type of a list item is a reference to a type T then the type 9780 // will be considered to be T for all purposes of this clause. 9781 if (CurType->isReferenceType()) 9782 CurType = CurType->getPointeeType(); 9783 9784 bool IsPointer = CurType->isAnyPointerType(); 9785 9786 if (!IsPointer && !CurType->isArrayType()) { 9787 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 9788 << 0 << CurE->getSourceRange(); 9789 break; 9790 } 9791 9792 bool NotWhole = 9793 CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 9794 bool NotUnity = 9795 CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 9796 9797 if (AllowWholeSizeArraySection && AllowUnitySizeArraySection) { 9798 // Any array section is currently allowed. 9799 // 9800 // If this array section refers to the whole dimension we can still 9801 // accept other array sections before this one, except if the base is a 9802 // pointer. Otherwise, only unitary sections are accepted. 9803 if (NotWhole || IsPointer) 9804 AllowWholeSizeArraySection = false; 9805 } else if ((AllowUnitySizeArraySection && NotUnity) || 9806 (AllowWholeSizeArraySection && NotWhole)) { 9807 // A unity or whole array section is not allowed and that is not 9808 // compatible with the properties of the current array section. 9809 SemaRef.Diag( 9810 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 9811 << CurE->getSourceRange(); 9812 break; 9813 } 9814 continue; 9815 } 9816 9817 // If nothing else worked, this is not a valid map clause expression. 9818 SemaRef.Diag(ELoc, 9819 diag::err_omp_expected_named_var_member_or_array_expression) 9820 << ERange; 9821 break; 9822 } 9823 9824 return RelevantExpr; 9825 } 9826 9827 // Return true if expression E associated with value VD has conflicts with other 9828 // map information. 9829 static bool CheckMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, 9830 Expr *E, bool CurrentRegionOnly) { 9831 assert(VD && E); 9832 9833 // Types used to organize the components of a valid map clause. 9834 typedef std::pair<Expr *, ValueDecl *> MapExpressionComponent; 9835 typedef SmallVector<MapExpressionComponent, 4> MapExpressionComponents; 9836 9837 // Helper to extract the components in the map clause expression E and store 9838 // them into MEC. This assumes that E is a valid map clause expression, i.e. 9839 // it has already passed the single clause checks. 9840 auto ExtractMapExpressionComponents = [](Expr *TE, 9841 MapExpressionComponents &MEC) { 9842 while (true) { 9843 TE = TE->IgnoreParenImpCasts(); 9844 9845 if (auto *CurE = dyn_cast<DeclRefExpr>(TE)) { 9846 MEC.push_back( 9847 MapExpressionComponent(CurE, cast<VarDecl>(CurE->getDecl()))); 9848 break; 9849 } 9850 9851 if (auto *CurE = dyn_cast<MemberExpr>(TE)) { 9852 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 9853 9854 MEC.push_back(MapExpressionComponent( 9855 CurE, cast<FieldDecl>(CurE->getMemberDecl()))); 9856 if (isa<CXXThisExpr>(BaseE)) 9857 break; 9858 9859 TE = BaseE; 9860 continue; 9861 } 9862 9863 if (auto *CurE = dyn_cast<ArraySubscriptExpr>(TE)) { 9864 MEC.push_back(MapExpressionComponent(CurE, nullptr)); 9865 TE = CurE->getBase()->IgnoreParenImpCasts(); 9866 continue; 9867 } 9868 9869 if (auto *CurE = dyn_cast<OMPArraySectionExpr>(TE)) { 9870 MEC.push_back(MapExpressionComponent(CurE, nullptr)); 9871 TE = CurE->getBase()->IgnoreParenImpCasts(); 9872 continue; 9873 } 9874 9875 llvm_unreachable( 9876 "Expecting only valid map clause expressions at this point!"); 9877 } 9878 }; 9879 9880 SourceLocation ELoc = E->getExprLoc(); 9881 SourceRange ERange = E->getSourceRange(); 9882 9883 // In order to easily check the conflicts we need to match each component of 9884 // the expression under test with the components of the expressions that are 9885 // already in the stack. 9886 9887 MapExpressionComponents CurComponents; 9888 ExtractMapExpressionComponents(E, CurComponents); 9889 9890 assert(!CurComponents.empty() && "Map clause expression with no components!"); 9891 assert(CurComponents.back().second == VD && 9892 "Map clause expression with unexpected base!"); 9893 9894 // Variables to help detecting enclosing problems in data environment nests. 9895 bool IsEnclosedByDataEnvironmentExpr = false; 9896 Expr *EnclosingExpr = nullptr; 9897 9898 bool FoundError = 9899 DSAS->checkMapInfoForVar(VD, CurrentRegionOnly, [&](Expr *RE) -> bool { 9900 MapExpressionComponents StackComponents; 9901 ExtractMapExpressionComponents(RE, StackComponents); 9902 assert(!StackComponents.empty() && 9903 "Map clause expression with no components!"); 9904 assert(StackComponents.back().second == VD && 9905 "Map clause expression with unexpected base!"); 9906 9907 // Expressions must start from the same base. Here we detect at which 9908 // point both expressions diverge from each other and see if we can 9909 // detect if the memory referred to both expressions is contiguous and 9910 // do not overlap. 9911 auto CI = CurComponents.rbegin(); 9912 auto CE = CurComponents.rend(); 9913 auto SI = StackComponents.rbegin(); 9914 auto SE = StackComponents.rend(); 9915 for (; CI != CE && SI != SE; ++CI, ++SI) { 9916 9917 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 9918 // At most one list item can be an array item derived from a given 9919 // variable in map clauses of the same construct. 9920 if (CurrentRegionOnly && (isa<ArraySubscriptExpr>(CI->first) || 9921 isa<OMPArraySectionExpr>(CI->first)) && 9922 (isa<ArraySubscriptExpr>(SI->first) || 9923 isa<OMPArraySectionExpr>(SI->first))) { 9924 SemaRef.Diag(CI->first->getExprLoc(), 9925 diag::err_omp_multiple_array_items_in_map_clause) 9926 << CI->first->getSourceRange(); 9927 ; 9928 SemaRef.Diag(SI->first->getExprLoc(), diag::note_used_here) 9929 << SI->first->getSourceRange(); 9930 return true; 9931 } 9932 9933 // Do both expressions have the same kind? 9934 if (CI->first->getStmtClass() != SI->first->getStmtClass()) 9935 break; 9936 9937 // Are we dealing with different variables/fields? 9938 if (CI->second != SI->second) 9939 break; 9940 } 9941 9942 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 9943 // List items of map clauses in the same construct must not share 9944 // original storage. 9945 // 9946 // If the expressions are exactly the same or one is a subset of the 9947 // other, it means they are sharing storage. 9948 if (CI == CE && SI == SE) { 9949 if (CurrentRegionOnly) { 9950 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 9951 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 9952 << RE->getSourceRange(); 9953 return true; 9954 } else { 9955 // If we find the same expression in the enclosing data environment, 9956 // that is legal. 9957 IsEnclosedByDataEnvironmentExpr = true; 9958 return false; 9959 } 9960 } 9961 9962 QualType DerivedType = std::prev(CI)->first->getType(); 9963 SourceLocation DerivedLoc = std::prev(CI)->first->getExprLoc(); 9964 9965 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 9966 // If the type of a list item is a reference to a type T then the type 9967 // will be considered to be T for all purposes of this clause. 9968 if (DerivedType->isReferenceType()) 9969 DerivedType = DerivedType->getPointeeType(); 9970 9971 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 9972 // A variable for which the type is pointer and an array section 9973 // derived from that variable must not appear as list items of map 9974 // clauses of the same construct. 9975 // 9976 // Also, cover one of the cases in: 9977 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 9978 // If any part of the original storage of a list item has corresponding 9979 // storage in the device data environment, all of the original storage 9980 // must have corresponding storage in the device data environment. 9981 // 9982 if (DerivedType->isAnyPointerType()) { 9983 if (CI == CE || SI == SE) { 9984 SemaRef.Diag( 9985 DerivedLoc, 9986 diag::err_omp_pointer_mapped_along_with_derived_section) 9987 << DerivedLoc; 9988 } else { 9989 assert(CI != CE && SI != SE); 9990 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced) 9991 << DerivedLoc; 9992 } 9993 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 9994 << RE->getSourceRange(); 9995 return true; 9996 } 9997 9998 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 9999 // List items of map clauses in the same construct must not share 10000 // original storage. 10001 // 10002 // An expression is a subset of the other. 10003 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 10004 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 10005 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 10006 << RE->getSourceRange(); 10007 return true; 10008 } 10009 10010 // The current expression uses the same base as other expression in the 10011 // data environment but does not contain it completelly. 10012 if (!CurrentRegionOnly && SI != SE) 10013 EnclosingExpr = RE; 10014 10015 // The current expression is a subset of the expression in the data 10016 // environment. 10017 IsEnclosedByDataEnvironmentExpr |= 10018 (!CurrentRegionOnly && CI != CE && SI == SE); 10019 10020 return false; 10021 }); 10022 10023 if (CurrentRegionOnly) 10024 return FoundError; 10025 10026 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 10027 // If any part of the original storage of a list item has corresponding 10028 // storage in the device data environment, all of the original storage must 10029 // have corresponding storage in the device data environment. 10030 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 10031 // If a list item is an element of a structure, and a different element of 10032 // the structure has a corresponding list item in the device data environment 10033 // prior to a task encountering the construct associated with the map clause, 10034 // then the list item must also have a correspnding list item in the device 10035 // data environment prior to the task encountering the construct. 10036 // 10037 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 10038 SemaRef.Diag(ELoc, 10039 diag::err_omp_original_storage_is_shared_and_does_not_contain) 10040 << ERange; 10041 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 10042 << EnclosingExpr->getSourceRange(); 10043 return true; 10044 } 10045 10046 return FoundError; 10047 } 10048 10049 OMPClause * 10050 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, 10051 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 10052 SourceLocation MapLoc, SourceLocation ColonLoc, 10053 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 10054 SourceLocation LParenLoc, SourceLocation EndLoc) { 10055 SmallVector<Expr *, 4> Vars; 10056 10057 for (auto &RE : VarList) { 10058 assert(RE && "Null expr in omp map"); 10059 if (isa<DependentScopeDeclRefExpr>(RE)) { 10060 // It will be analyzed later. 10061 Vars.push_back(RE); 10062 continue; 10063 } 10064 SourceLocation ELoc = RE->getExprLoc(); 10065 10066 auto *VE = RE->IgnoreParenLValueCasts(); 10067 10068 if (VE->isValueDependent() || VE->isTypeDependent() || 10069 VE->isInstantiationDependent() || 10070 VE->containsUnexpandedParameterPack()) { 10071 // We can only analyze this information once the missing information is 10072 // resolved. 10073 Vars.push_back(RE); 10074 continue; 10075 } 10076 10077 auto *SimpleExpr = RE->IgnoreParenCasts(); 10078 10079 if (!RE->IgnoreParenImpCasts()->isLValue()) { 10080 Diag(ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 10081 << RE->getSourceRange(); 10082 continue; 10083 } 10084 10085 // Obtain the array or member expression bases if required. 10086 auto *BE = CheckMapClauseExpressionBase(*this, SimpleExpr); 10087 if (!BE) 10088 continue; 10089 10090 // If the base is a reference to a variable, we rely on that variable for 10091 // the following checks. If it is a 'this' expression we rely on the field. 10092 ValueDecl *D = nullptr; 10093 if (auto *DRE = dyn_cast<DeclRefExpr>(BE)) { 10094 D = DRE->getDecl(); 10095 } else { 10096 auto *ME = cast<MemberExpr>(BE); 10097 assert(isa<CXXThisExpr>(ME->getBase()) && "Unexpected expression!"); 10098 D = ME->getMemberDecl(); 10099 } 10100 assert(D && "Null decl on map clause."); 10101 10102 auto *VD = dyn_cast<VarDecl>(D); 10103 auto *FD = dyn_cast<FieldDecl>(D); 10104 10105 assert((VD || FD) && "Only variables or fields are expected here!"); 10106 (void)FD; 10107 10108 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 10109 // threadprivate variables cannot appear in a map clause. 10110 if (VD && DSAStack->isThreadPrivate(VD)) { 10111 auto DVar = DSAStack->getTopDSA(VD, false); 10112 Diag(ELoc, diag::err_omp_threadprivate_in_map); 10113 ReportOriginalDSA(*this, DSAStack, VD, DVar); 10114 continue; 10115 } 10116 10117 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 10118 // A list item cannot appear in both a map clause and a data-sharing 10119 // attribute clause on the same construct. 10120 // 10121 // TODO: Implement this check - it cannot currently be tested because of 10122 // missing implementation of the other data sharing clauses in target 10123 // directives. 10124 10125 // Check conflicts with other map clause expressions. We check the conflicts 10126 // with the current construct separately from the enclosing data 10127 // environment, because the restrictions are different. 10128 if (CheckMapConflicts(*this, DSAStack, D, SimpleExpr, 10129 /*CurrentRegionOnly=*/true)) 10130 break; 10131 if (CheckMapConflicts(*this, DSAStack, D, SimpleExpr, 10132 /*CurrentRegionOnly=*/false)) 10133 break; 10134 10135 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 10136 // If the type of a list item is a reference to a type T then the type will 10137 // be considered to be T for all purposes of this clause. 10138 QualType Type = D->getType(); 10139 if (Type->isReferenceType()) 10140 Type = Type->getPointeeType(); 10141 10142 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 10143 // A list item must have a mappable type. 10144 if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), *this, 10145 DSAStack, Type)) 10146 continue; 10147 10148 // target enter data 10149 // OpenMP [2.10.2, Restrictions, p. 99] 10150 // A map-type must be specified in all map clauses and must be either 10151 // to or alloc. 10152 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 10153 if (DKind == OMPD_target_enter_data && 10154 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 10155 Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 10156 << (IsMapTypeImplicit ? 1 : 0) 10157 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 10158 << getOpenMPDirectiveName(DKind); 10159 continue; 10160 } 10161 10162 // target exit_data 10163 // OpenMP [2.10.3, Restrictions, p. 102] 10164 // A map-type must be specified in all map clauses and must be either 10165 // from, release, or delete. 10166 DKind = DSAStack->getCurrentDirective(); 10167 if (DKind == OMPD_target_exit_data && 10168 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 10169 MapType == OMPC_MAP_delete)) { 10170 Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 10171 << (IsMapTypeImplicit ? 1 : 0) 10172 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 10173 << getOpenMPDirectiveName(DKind); 10174 continue; 10175 } 10176 10177 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10178 // A list item cannot appear in both a map clause and a data-sharing 10179 // attribute clause on the same construct 10180 if (DKind == OMPD_target && VD) { 10181 auto DVar = DSAStack->getTopDSA(VD, false); 10182 if (isOpenMPPrivate(DVar.CKind)) { 10183 Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) 10184 << getOpenMPClauseName(DVar.CKind) 10185 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10186 ReportOriginalDSA(*this, DSAStack, D, DVar); 10187 continue; 10188 } 10189 } 10190 10191 Vars.push_back(RE); 10192 DSAStack->addExprToVarMapInfo(D, RE); 10193 } 10194 10195 // We need to produce a map clause even if we don't have variables so that 10196 // other diagnostics related with non-existing map clauses are accurate. 10197 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 10198 MapTypeModifier, MapType, IsMapTypeImplicit, 10199 MapLoc); 10200 } 10201 10202 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 10203 TypeResult ParsedType) { 10204 assert(ParsedType.isUsable()); 10205 10206 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 10207 if (ReductionType.isNull()) 10208 return QualType(); 10209 10210 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 10211 // A type name in a declare reduction directive cannot be a function type, an 10212 // array type, a reference type, or a type qualified with const, volatile or 10213 // restrict. 10214 if (ReductionType.hasQualifiers()) { 10215 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 10216 return QualType(); 10217 } 10218 10219 if (ReductionType->isFunctionType()) { 10220 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 10221 return QualType(); 10222 } 10223 if (ReductionType->isReferenceType()) { 10224 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 10225 return QualType(); 10226 } 10227 if (ReductionType->isArrayType()) { 10228 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 10229 return QualType(); 10230 } 10231 return ReductionType; 10232 } 10233 10234 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 10235 Scope *S, DeclContext *DC, DeclarationName Name, 10236 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 10237 AccessSpecifier AS, Decl *PrevDeclInScope) { 10238 SmallVector<Decl *, 8> Decls; 10239 Decls.reserve(ReductionTypes.size()); 10240 10241 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 10242 ForRedeclaration); 10243 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 10244 // A reduction-identifier may not be re-declared in the current scope for the 10245 // same type or for a type that is compatible according to the base language 10246 // rules. 10247 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 10248 OMPDeclareReductionDecl *PrevDRD = nullptr; 10249 bool InCompoundScope = true; 10250 if (S != nullptr) { 10251 // Find previous declaration with the same name not referenced in other 10252 // declarations. 10253 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 10254 InCompoundScope = 10255 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 10256 LookupName(Lookup, S); 10257 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 10258 /*AllowInlineNamespace=*/false); 10259 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 10260 auto Filter = Lookup.makeFilter(); 10261 while (Filter.hasNext()) { 10262 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 10263 if (InCompoundScope) { 10264 auto I = UsedAsPrevious.find(PrevDecl); 10265 if (I == UsedAsPrevious.end()) 10266 UsedAsPrevious[PrevDecl] = false; 10267 if (auto *D = PrevDecl->getPrevDeclInScope()) 10268 UsedAsPrevious[D] = true; 10269 } 10270 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 10271 PrevDecl->getLocation(); 10272 } 10273 Filter.done(); 10274 if (InCompoundScope) { 10275 for (auto &PrevData : UsedAsPrevious) { 10276 if (!PrevData.second) { 10277 PrevDRD = PrevData.first; 10278 break; 10279 } 10280 } 10281 } 10282 } else if (PrevDeclInScope != nullptr) { 10283 auto *PrevDRDInScope = PrevDRD = 10284 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 10285 do { 10286 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 10287 PrevDRDInScope->getLocation(); 10288 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 10289 } while (PrevDRDInScope != nullptr); 10290 } 10291 for (auto &TyData : ReductionTypes) { 10292 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 10293 bool Invalid = false; 10294 if (I != PreviousRedeclTypes.end()) { 10295 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 10296 << TyData.first; 10297 Diag(I->second, diag::note_previous_definition); 10298 Invalid = true; 10299 } 10300 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 10301 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 10302 Name, TyData.first, PrevDRD); 10303 DC->addDecl(DRD); 10304 DRD->setAccess(AS); 10305 Decls.push_back(DRD); 10306 if (Invalid) 10307 DRD->setInvalidDecl(); 10308 else 10309 PrevDRD = DRD; 10310 } 10311 10312 return DeclGroupPtrTy::make( 10313 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 10314 } 10315 10316 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 10317 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10318 10319 // Enter new function scope. 10320 PushFunctionScope(); 10321 getCurFunction()->setHasBranchProtectedScope(); 10322 getCurFunction()->setHasOMPDeclareReductionCombiner(); 10323 10324 if (S != nullptr) 10325 PushDeclContext(S, DRD); 10326 else 10327 CurContext = DRD; 10328 10329 PushExpressionEvaluationContext(PotentiallyEvaluated); 10330 10331 QualType ReductionType = DRD->getType(); 10332 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 10333 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 10334 // uses semantics of argument handles by value, but it should be passed by 10335 // reference. C lang does not support references, so pass all parameters as 10336 // pointers. 10337 // Create 'T omp_in;' variable. 10338 auto *OmpInParm = 10339 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 10340 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 10341 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 10342 // uses semantics of argument handles by value, but it should be passed by 10343 // reference. C lang does not support references, so pass all parameters as 10344 // pointers. 10345 // Create 'T omp_out;' variable. 10346 auto *OmpOutParm = 10347 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 10348 if (S != nullptr) { 10349 PushOnScopeChains(OmpInParm, S); 10350 PushOnScopeChains(OmpOutParm, S); 10351 } else { 10352 DRD->addDecl(OmpInParm); 10353 DRD->addDecl(OmpOutParm); 10354 } 10355 } 10356 10357 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 10358 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10359 DiscardCleanupsInEvaluationContext(); 10360 PopExpressionEvaluationContext(); 10361 10362 PopDeclContext(); 10363 PopFunctionScopeInfo(); 10364 10365 if (Combiner != nullptr) 10366 DRD->setCombiner(Combiner); 10367 else 10368 DRD->setInvalidDecl(); 10369 } 10370 10371 void Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 10372 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10373 10374 // Enter new function scope. 10375 PushFunctionScope(); 10376 getCurFunction()->setHasBranchProtectedScope(); 10377 10378 if (S != nullptr) 10379 PushDeclContext(S, DRD); 10380 else 10381 CurContext = DRD; 10382 10383 PushExpressionEvaluationContext(PotentiallyEvaluated); 10384 10385 QualType ReductionType = DRD->getType(); 10386 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 10387 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 10388 // uses semantics of argument handles by value, but it should be passed by 10389 // reference. C lang does not support references, so pass all parameters as 10390 // pointers. 10391 // Create 'T omp_priv;' variable. 10392 auto *OmpPrivParm = 10393 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 10394 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 10395 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 10396 // uses semantics of argument handles by value, but it should be passed by 10397 // reference. C lang does not support references, so pass all parameters as 10398 // pointers. 10399 // Create 'T omp_orig;' variable. 10400 auto *OmpOrigParm = 10401 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 10402 if (S != nullptr) { 10403 PushOnScopeChains(OmpPrivParm, S); 10404 PushOnScopeChains(OmpOrigParm, S); 10405 } else { 10406 DRD->addDecl(OmpPrivParm); 10407 DRD->addDecl(OmpOrigParm); 10408 } 10409 } 10410 10411 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, 10412 Expr *Initializer) { 10413 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10414 DiscardCleanupsInEvaluationContext(); 10415 PopExpressionEvaluationContext(); 10416 10417 PopDeclContext(); 10418 PopFunctionScopeInfo(); 10419 10420 if (Initializer != nullptr) 10421 DRD->setInitializer(Initializer); 10422 else 10423 DRD->setInvalidDecl(); 10424 } 10425 10426 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 10427 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 10428 for (auto *D : DeclReductions.get()) { 10429 if (IsValid) { 10430 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10431 if (S != nullptr) 10432 PushOnScopeChains(DRD, S, /*AddToContext=*/false); 10433 } else 10434 D->setInvalidDecl(); 10435 } 10436 return DeclReductions; 10437 } 10438 10439 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 10440 SourceLocation StartLoc, 10441 SourceLocation LParenLoc, 10442 SourceLocation EndLoc) { 10443 Expr *ValExpr = NumTeams; 10444 10445 // OpenMP [teams Constrcut, Restrictions] 10446 // The num_teams expression must evaluate to a positive integer value. 10447 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 10448 /*StrictlyPositive=*/true)) 10449 return nullptr; 10450 10451 return new (Context) OMPNumTeamsClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10452 } 10453 10454 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 10455 SourceLocation StartLoc, 10456 SourceLocation LParenLoc, 10457 SourceLocation EndLoc) { 10458 Expr *ValExpr = ThreadLimit; 10459 10460 // OpenMP [teams Constrcut, Restrictions] 10461 // The thread_limit expression must evaluate to a positive integer value. 10462 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 10463 /*StrictlyPositive=*/true)) 10464 return nullptr; 10465 10466 return new (Context) OMPThreadLimitClause(ValExpr, StartLoc, LParenLoc, 10467 EndLoc); 10468 } 10469 10470 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 10471 SourceLocation StartLoc, 10472 SourceLocation LParenLoc, 10473 SourceLocation EndLoc) { 10474 Expr *ValExpr = Priority; 10475 10476 // OpenMP [2.9.1, task Constrcut] 10477 // The priority-value is a non-negative numerical scalar expression. 10478 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 10479 /*StrictlyPositive=*/false)) 10480 return nullptr; 10481 10482 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10483 } 10484 10485 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 10486 SourceLocation StartLoc, 10487 SourceLocation LParenLoc, 10488 SourceLocation EndLoc) { 10489 Expr *ValExpr = Grainsize; 10490 10491 // OpenMP [2.9.2, taskloop Constrcut] 10492 // The parameter of the grainsize clause must be a positive integer 10493 // expression. 10494 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 10495 /*StrictlyPositive=*/true)) 10496 return nullptr; 10497 10498 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10499 } 10500 10501 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 10502 SourceLocation StartLoc, 10503 SourceLocation LParenLoc, 10504 SourceLocation EndLoc) { 10505 Expr *ValExpr = NumTasks; 10506 10507 // OpenMP [2.9.2, taskloop Constrcut] 10508 // The parameter of the num_tasks clause must be a positive integer 10509 // expression. 10510 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 10511 /*StrictlyPositive=*/true)) 10512 return nullptr; 10513 10514 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10515 } 10516 10517 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 10518 SourceLocation LParenLoc, 10519 SourceLocation EndLoc) { 10520 // OpenMP [2.13.2, critical construct, Description] 10521 // ... where hint-expression is an integer constant expression that evaluates 10522 // to a valid lock hint. 10523 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 10524 if (HintExpr.isInvalid()) 10525 return nullptr; 10526 return new (Context) 10527 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 10528 } 10529 10530 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 10531 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10532 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 10533 SourceLocation EndLoc) { 10534 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 10535 std::string Values; 10536 Values += "'"; 10537 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 10538 Values += "'"; 10539 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 10540 << Values << getOpenMPClauseName(OMPC_dist_schedule); 10541 return nullptr; 10542 } 10543 Expr *ValExpr = ChunkSize; 10544 Stmt *HelperValStmt = nullptr; 10545 if (ChunkSize) { 10546 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 10547 !ChunkSize->isInstantiationDependent() && 10548 !ChunkSize->containsUnexpandedParameterPack()) { 10549 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 10550 ExprResult Val = 10551 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 10552 if (Val.isInvalid()) 10553 return nullptr; 10554 10555 ValExpr = Val.get(); 10556 10557 // OpenMP [2.7.1, Restrictions] 10558 // chunk_size must be a loop invariant integer expression with a positive 10559 // value. 10560 llvm::APSInt Result; 10561 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 10562 if (Result.isSigned() && !Result.isStrictlyPositive()) { 10563 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 10564 << "dist_schedule" << ChunkSize->getSourceRange(); 10565 return nullptr; 10566 } 10567 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 10568 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 10569 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10570 HelperValStmt = buildPreInits(Context, Captures); 10571 } 10572 } 10573 } 10574 10575 return new (Context) 10576 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 10577 Kind, ValExpr, HelperValStmt); 10578 } 10579 10580 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 10581 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 10582 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 10583 SourceLocation KindLoc, SourceLocation EndLoc) { 10584 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 10585 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 10586 Kind != OMPC_DEFAULTMAP_scalar) { 10587 std::string Value; 10588 SourceLocation Loc; 10589 Value += "'"; 10590 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 10591 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 10592 OMPC_DEFAULTMAP_MODIFIER_tofrom); 10593 Loc = MLoc; 10594 } else { 10595 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 10596 OMPC_DEFAULTMAP_scalar); 10597 Loc = KindLoc; 10598 } 10599 Value += "'"; 10600 Diag(Loc, diag::err_omp_unexpected_clause_value) 10601 << Value << getOpenMPClauseName(OMPC_defaultmap); 10602 return nullptr; 10603 } 10604 10605 return new (Context) 10606 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 10607 } 10608 10609 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 10610 DeclContext *CurLexicalContext = getCurLexicalContext(); 10611 if (!CurLexicalContext->isFileContext() && 10612 !CurLexicalContext->isExternCContext() && 10613 !CurLexicalContext->isExternCXXContext()) { 10614 Diag(Loc, diag::err_omp_region_not_file_context); 10615 return false; 10616 } 10617 if (IsInOpenMPDeclareTargetContext) { 10618 Diag(Loc, diag::err_omp_enclosed_declare_target); 10619 return false; 10620 } 10621 10622 IsInOpenMPDeclareTargetContext = true; 10623 return true; 10624 } 10625 10626 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 10627 assert(IsInOpenMPDeclareTargetContext && 10628 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 10629 10630 IsInOpenMPDeclareTargetContext = false; 10631 } 10632 10633 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 10634 Sema &SemaRef, Decl *D) { 10635 if (!D) 10636 return; 10637 Decl *LD = nullptr; 10638 if (isa<TagDecl>(D)) { 10639 LD = cast<TagDecl>(D)->getDefinition(); 10640 } else if (isa<VarDecl>(D)) { 10641 LD = cast<VarDecl>(D)->getDefinition(); 10642 10643 // If this is an implicit variable that is legal and we do not need to do 10644 // anything. 10645 if (cast<VarDecl>(D)->isImplicit()) { 10646 D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(SemaRef.Context)); 10647 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 10648 ML->DeclarationMarkedOpenMPDeclareTarget(D); 10649 return; 10650 } 10651 10652 } else if (isa<FunctionDecl>(D)) { 10653 const FunctionDecl *FD = nullptr; 10654 if (cast<FunctionDecl>(D)->hasBody(FD)) 10655 LD = const_cast<FunctionDecl *>(FD); 10656 10657 // If the definition is associated with the current declaration in the 10658 // target region (it can be e.g. a lambda) that is legal and we do not need 10659 // to do anything else. 10660 if (LD == D) { 10661 D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(SemaRef.Context)); 10662 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 10663 ML->DeclarationMarkedOpenMPDeclareTarget(D); 10664 return; 10665 } 10666 } 10667 if (!LD) 10668 LD = D; 10669 if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() && 10670 (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) { 10671 // Outlined declaration is not declared target. 10672 if (LD->isOutOfLine()) { 10673 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 10674 SemaRef.Diag(SL, diag::note_used_here) << SR; 10675 } else { 10676 DeclContext *DC = LD->getDeclContext(); 10677 while (DC) { 10678 if (isa<FunctionDecl>(DC) && 10679 cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>()) 10680 break; 10681 DC = DC->getParent(); 10682 } 10683 if (DC) 10684 return; 10685 10686 // Is not declared in target context. 10687 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 10688 SemaRef.Diag(SL, diag::note_used_here) << SR; 10689 } 10690 // Mark decl as declared target to prevent further diagnostic. 10691 D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(SemaRef.Context)); 10692 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 10693 ML->DeclarationMarkedOpenMPDeclareTarget(D); 10694 } 10695 } 10696 10697 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 10698 Sema &SemaRef, DSAStackTy *Stack, 10699 ValueDecl *VD) { 10700 if (VD->hasAttr<OMPDeclareTargetDeclAttr>()) 10701 return true; 10702 if (!CheckTypeMappable(SL, SR, SemaRef, Stack, VD->getType())) 10703 return false; 10704 return true; 10705 } 10706 10707 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D) { 10708 if (!D || D->isInvalidDecl()) 10709 return; 10710 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 10711 SourceLocation SL = E ? E->getLocStart() : D->getLocation(); 10712 // 2.10.6: threadprivate variable cannot appear in a declare target directive. 10713 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 10714 if (DSAStack->isThreadPrivate(VD)) { 10715 Diag(SL, diag::err_omp_threadprivate_in_target); 10716 ReportOriginalDSA(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 10717 return; 10718 } 10719 } 10720 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 10721 // Problem if any with var declared with incomplete type will be reported 10722 // as normal, so no need to check it here. 10723 if ((E || !VD->getType()->isIncompleteType()) && 10724 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) { 10725 // Mark decl as declared target to prevent further diagnostic. 10726 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) { 10727 VD->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(Context)); 10728 if (ASTMutationListener *ML = Context.getASTMutationListener()) 10729 ML->DeclarationMarkedOpenMPDeclareTarget(VD); 10730 } 10731 return; 10732 } 10733 } 10734 if (!E) { 10735 // Checking declaration inside declare target region. 10736 if (!D->hasAttr<OMPDeclareTargetDeclAttr>() && 10737 (isa<VarDecl>(D) || isa<FunctionDecl>(D))) { 10738 D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(Context)); 10739 if (ASTMutationListener *ML = Context.getASTMutationListener()) 10740 ML->DeclarationMarkedOpenMPDeclareTarget(D); 10741 } 10742 return; 10743 } 10744 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 10745 } 10746