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