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 3194 Sema::ActOnOpenMPDeclareSimdDirective(DeclGroupPtrTy DG, 3195 OMPDeclareSimdDeclAttr::BranchStateTy BS, 3196 SourceRange SR) { 3197 if (!DG || DG.get().isNull()) 3198 return DeclGroupPtrTy(); 3199 3200 if (!DG.get().isSingleDecl()) { 3201 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 3202 return DG; 3203 } 3204 auto *ADecl = DG.get().getSingleDecl(); 3205 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 3206 ADecl = FTD->getTemplatedDecl(); 3207 3208 if (!isa<FunctionDecl>(ADecl)) { 3209 Diag(ADecl->getLocation(), diag::err_omp_function_expected) 3210 << ADecl->getDeclContext()->isFileContext(); 3211 return DeclGroupPtrTy(); 3212 } 3213 3214 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit(Context, BS, SR); 3215 ADecl->addAttr(NewAttr); 3216 return ConvertDeclToDeclGroup(ADecl); 3217 } 3218 3219 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 3220 Stmt *AStmt, 3221 SourceLocation StartLoc, 3222 SourceLocation EndLoc) { 3223 if (!AStmt) 3224 return StmtError(); 3225 3226 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 3227 // 1.2.2 OpenMP Language Terminology 3228 // Structured block - An executable statement with a single entry at the 3229 // top and a single exit at the bottom. 3230 // The point of exit cannot be a branch out of the structured block. 3231 // longjmp() and throw() must not violate the entry/exit criteria. 3232 CS->getCapturedDecl()->setNothrow(); 3233 3234 getCurFunction()->setHasBranchProtectedScope(); 3235 3236 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 3237 DSAStack->isCancelRegion()); 3238 } 3239 3240 namespace { 3241 /// \brief Helper class for checking canonical form of the OpenMP loops and 3242 /// extracting iteration space of each loop in the loop nest, that will be used 3243 /// for IR generation. 3244 class OpenMPIterationSpaceChecker { 3245 /// \brief Reference to Sema. 3246 Sema &SemaRef; 3247 /// \brief A location for diagnostics (when there is no some better location). 3248 SourceLocation DefaultLoc; 3249 /// \brief A location for diagnostics (when increment is not compatible). 3250 SourceLocation ConditionLoc; 3251 /// \brief A source location for referring to loop init later. 3252 SourceRange InitSrcRange; 3253 /// \brief A source location for referring to condition later. 3254 SourceRange ConditionSrcRange; 3255 /// \brief A source location for referring to increment later. 3256 SourceRange IncrementSrcRange; 3257 /// \brief Loop variable. 3258 ValueDecl *LCDecl = nullptr; 3259 /// \brief Reference to loop variable. 3260 Expr *LCRef = nullptr; 3261 /// \brief Lower bound (initializer for the var). 3262 Expr *LB = nullptr; 3263 /// \brief Upper bound. 3264 Expr *UB = nullptr; 3265 /// \brief Loop step (increment). 3266 Expr *Step = nullptr; 3267 /// \brief This flag is true when condition is one of: 3268 /// Var < UB 3269 /// Var <= UB 3270 /// UB > Var 3271 /// UB >= Var 3272 bool TestIsLessOp = false; 3273 /// \brief This flag is true when condition is strict ( < or > ). 3274 bool TestIsStrictOp = false; 3275 /// \brief This flag is true when step is subtracted on each iteration. 3276 bool SubtractStep = false; 3277 3278 public: 3279 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 3280 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 3281 /// \brief Check init-expr for canonical loop form and save loop counter 3282 /// variable - #Var and its initialization value - #LB. 3283 bool CheckInit(Stmt *S, bool EmitDiags = true); 3284 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags 3285 /// for less/greater and for strict/non-strict comparison. 3286 bool CheckCond(Expr *S); 3287 /// \brief Check incr-expr for canonical loop form and return true if it 3288 /// does not conform, otherwise save loop step (#Step). 3289 bool CheckInc(Expr *S); 3290 /// \brief Return the loop counter variable. 3291 ValueDecl *GetLoopDecl() const { return LCDecl; } 3292 /// \brief Return the reference expression to loop counter variable. 3293 Expr *GetLoopDeclRefExpr() const { return LCRef; } 3294 /// \brief Source range of the loop init. 3295 SourceRange GetInitSrcRange() const { return InitSrcRange; } 3296 /// \brief Source range of the loop condition. 3297 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; } 3298 /// \brief Source range of the loop increment. 3299 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; } 3300 /// \brief True if the step should be subtracted. 3301 bool ShouldSubtractStep() const { return SubtractStep; } 3302 /// \brief Build the expression to calculate the number of iterations. 3303 Expr * 3304 BuildNumIterations(Scope *S, const bool LimitedType, 3305 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3306 /// \brief Build the precondition expression for the loops. 3307 Expr *BuildPreCond(Scope *S, Expr *Cond, 3308 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3309 /// \brief Build reference expression to the counter be used for codegen. 3310 DeclRefExpr * 3311 BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3312 /// \brief Build reference expression to the private counter be used for 3313 /// codegen. 3314 Expr *BuildPrivateCounterVar() const; 3315 /// \brief Build initization of the counter be used for codegen. 3316 Expr *BuildCounterInit() const; 3317 /// \brief Build step of the counter be used for codegen. 3318 Expr *BuildCounterStep() const; 3319 /// \brief Return true if any expression is dependent. 3320 bool Dependent() const; 3321 3322 private: 3323 /// \brief Check the right-hand side of an assignment in the increment 3324 /// expression. 3325 bool CheckIncRHS(Expr *RHS); 3326 /// \brief Helper to set loop counter variable and its initializer. 3327 bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); 3328 /// \brief Helper to set upper bound. 3329 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR, 3330 SourceLocation SL); 3331 /// \brief Helper to set loop increment. 3332 bool SetStep(Expr *NewStep, bool Subtract); 3333 }; 3334 3335 bool OpenMPIterationSpaceChecker::Dependent() const { 3336 if (!LCDecl) { 3337 assert(!LB && !UB && !Step); 3338 return false; 3339 } 3340 return LCDecl->getType()->isDependentType() || 3341 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 3342 (Step && Step->isValueDependent()); 3343 } 3344 3345 static Expr *getExprAsWritten(Expr *E) { 3346 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) 3347 E = ExprTemp->getSubExpr(); 3348 3349 if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 3350 E = MTE->GetTemporaryExpr(); 3351 3352 while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 3353 E = Binder->getSubExpr(); 3354 3355 if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 3356 E = ICE->getSubExprAsWritten(); 3357 return E->IgnoreParens(); 3358 } 3359 3360 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl, 3361 Expr *NewLCRefExpr, 3362 Expr *NewLB) { 3363 // State consistency checking to ensure correct usage. 3364 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 3365 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3366 if (!NewLCDecl || !NewLB) 3367 return true; 3368 LCDecl = getCanonicalDecl(NewLCDecl); 3369 LCRef = NewLCRefExpr; 3370 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 3371 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3372 if ((Ctor->isCopyOrMoveConstructor() || 3373 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3374 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3375 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 3376 LB = NewLB; 3377 return false; 3378 } 3379 3380 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp, 3381 SourceRange SR, SourceLocation SL) { 3382 // State consistency checking to ensure correct usage. 3383 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 3384 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3385 if (!NewUB) 3386 return true; 3387 UB = NewUB; 3388 TestIsLessOp = LessOp; 3389 TestIsStrictOp = StrictOp; 3390 ConditionSrcRange = SR; 3391 ConditionLoc = SL; 3392 return false; 3393 } 3394 3395 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) { 3396 // State consistency checking to ensure correct usage. 3397 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 3398 if (!NewStep) 3399 return true; 3400 if (!NewStep->isValueDependent()) { 3401 // Check that the step is integer expression. 3402 SourceLocation StepLoc = NewStep->getLocStart(); 3403 ExprResult Val = 3404 SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep); 3405 if (Val.isInvalid()) 3406 return true; 3407 NewStep = Val.get(); 3408 3409 // OpenMP [2.6, Canonical Loop Form, Restrictions] 3410 // If test-expr is of form var relational-op b and relational-op is < or 3411 // <= then incr-expr must cause var to increase on each iteration of the 3412 // loop. If test-expr is of form var relational-op b and relational-op is 3413 // > or >= then incr-expr must cause var to decrease on each iteration of 3414 // the loop. 3415 // If test-expr is of form b relational-op var and relational-op is < or 3416 // <= then incr-expr must cause var to decrease on each iteration of the 3417 // loop. If test-expr is of form b relational-op var and relational-op is 3418 // > or >= then incr-expr must cause var to increase on each iteration of 3419 // the loop. 3420 llvm::APSInt Result; 3421 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 3422 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 3423 bool IsConstNeg = 3424 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 3425 bool IsConstPos = 3426 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 3427 bool IsConstZero = IsConstant && !Result.getBoolValue(); 3428 if (UB && (IsConstZero || 3429 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 3430 : (IsConstPos || (IsUnsigned && !Subtract))))) { 3431 SemaRef.Diag(NewStep->getExprLoc(), 3432 diag::err_omp_loop_incr_not_compatible) 3433 << LCDecl << TestIsLessOp << NewStep->getSourceRange(); 3434 SemaRef.Diag(ConditionLoc, 3435 diag::note_omp_loop_cond_requres_compatible_incr) 3436 << TestIsLessOp << ConditionSrcRange; 3437 return true; 3438 } 3439 if (TestIsLessOp == Subtract) { 3440 NewStep = SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, 3441 NewStep).get(); 3442 Subtract = !Subtract; 3443 } 3444 } 3445 3446 Step = NewStep; 3447 SubtractStep = Subtract; 3448 return false; 3449 } 3450 3451 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { 3452 // Check init-expr for canonical loop form and save loop counter 3453 // variable - #Var and its initialization value - #LB. 3454 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 3455 // var = lb 3456 // integer-type var = lb 3457 // random-access-iterator-type var = lb 3458 // pointer-type var = lb 3459 // 3460 if (!S) { 3461 if (EmitDiags) { 3462 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 3463 } 3464 return true; 3465 } 3466 InitSrcRange = S->getSourceRange(); 3467 if (Expr *E = dyn_cast<Expr>(S)) 3468 S = E->IgnoreParens(); 3469 if (auto BO = dyn_cast<BinaryOperator>(S)) { 3470 if (BO->getOpcode() == BO_Assign) { 3471 auto *LHS = BO->getLHS()->IgnoreParens(); 3472 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 3473 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3474 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3475 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3476 return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); 3477 } 3478 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3479 if (ME->isArrow() && 3480 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3481 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3482 } 3483 } 3484 } else if (auto DS = dyn_cast<DeclStmt>(S)) { 3485 if (DS->isSingleDecl()) { 3486 if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 3487 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 3488 // Accept non-canonical init form here but emit ext. warning. 3489 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 3490 SemaRef.Diag(S->getLocStart(), 3491 diag::ext_omp_loop_not_canonical_init) 3492 << S->getSourceRange(); 3493 return SetLCDeclAndLB(Var, nullptr, Var->getInit()); 3494 } 3495 } 3496 } 3497 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3498 if (CE->getOperator() == OO_Equal) { 3499 auto *LHS = CE->getArg(0); 3500 if (auto DRE = dyn_cast<DeclRefExpr>(LHS)) { 3501 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3502 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3503 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3504 return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); 3505 } 3506 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3507 if (ME->isArrow() && 3508 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3509 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3510 } 3511 } 3512 } 3513 3514 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3515 return false; 3516 if (EmitDiags) { 3517 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init) 3518 << S->getSourceRange(); 3519 } 3520 return true; 3521 } 3522 3523 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the 3524 /// variable (which may be the loop variable) if possible. 3525 static const ValueDecl *GetInitLCDecl(Expr *E) { 3526 if (!E) 3527 return nullptr; 3528 E = getExprAsWritten(E); 3529 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 3530 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3531 if ((Ctor->isCopyOrMoveConstructor() || 3532 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3533 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3534 E = CE->getArg(0)->IgnoreParenImpCasts(); 3535 if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 3536 if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 3537 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3538 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3539 return getCanonicalDecl(ME->getMemberDecl()); 3540 return getCanonicalDecl(VD); 3541 } 3542 } 3543 if (auto *ME = dyn_cast_or_null<MemberExpr>(E)) 3544 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3545 return getCanonicalDecl(ME->getMemberDecl()); 3546 return nullptr; 3547 } 3548 3549 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { 3550 // Check test-expr for canonical form, save upper-bound UB, flags for 3551 // less/greater and for strict/non-strict comparison. 3552 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3553 // var relational-op b 3554 // b relational-op var 3555 // 3556 if (!S) { 3557 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 3558 return true; 3559 } 3560 S = getExprAsWritten(S); 3561 SourceLocation CondLoc = S->getLocStart(); 3562 if (auto BO = dyn_cast<BinaryOperator>(S)) { 3563 if (BO->isRelationalOp()) { 3564 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3565 return SetUB(BO->getRHS(), 3566 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 3567 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3568 BO->getSourceRange(), BO->getOperatorLoc()); 3569 if (GetInitLCDecl(BO->getRHS()) == LCDecl) 3570 return SetUB(BO->getLHS(), 3571 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 3572 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3573 BO->getSourceRange(), BO->getOperatorLoc()); 3574 } 3575 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3576 if (CE->getNumArgs() == 2) { 3577 auto Op = CE->getOperator(); 3578 switch (Op) { 3579 case OO_Greater: 3580 case OO_GreaterEqual: 3581 case OO_Less: 3582 case OO_LessEqual: 3583 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3584 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 3585 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3586 CE->getOperatorLoc()); 3587 if (GetInitLCDecl(CE->getArg(1)) == LCDecl) 3588 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 3589 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3590 CE->getOperatorLoc()); 3591 break; 3592 default: 3593 break; 3594 } 3595 } 3596 } 3597 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3598 return false; 3599 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 3600 << S->getSourceRange() << LCDecl; 3601 return true; 3602 } 3603 3604 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) { 3605 // RHS of canonical loop form increment can be: 3606 // var + incr 3607 // incr + var 3608 // var - incr 3609 // 3610 RHS = RHS->IgnoreParenImpCasts(); 3611 if (auto BO = dyn_cast<BinaryOperator>(RHS)) { 3612 if (BO->isAdditiveOp()) { 3613 bool IsAdd = BO->getOpcode() == BO_Add; 3614 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3615 return SetStep(BO->getRHS(), !IsAdd); 3616 if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl) 3617 return SetStep(BO->getLHS(), false); 3618 } 3619 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 3620 bool IsAdd = CE->getOperator() == OO_Plus; 3621 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 3622 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3623 return SetStep(CE->getArg(1), !IsAdd); 3624 if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl) 3625 return SetStep(CE->getArg(0), false); 3626 } 3627 } 3628 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3629 return false; 3630 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr) 3631 << RHS->getSourceRange() << LCDecl; 3632 return true; 3633 } 3634 3635 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { 3636 // Check incr-expr for canonical loop form and return true if it 3637 // does not conform. 3638 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3639 // ++var 3640 // var++ 3641 // --var 3642 // var-- 3643 // var += incr 3644 // var -= incr 3645 // var = var + incr 3646 // var = incr + var 3647 // var = var - incr 3648 // 3649 if (!S) { 3650 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 3651 return true; 3652 } 3653 IncrementSrcRange = S->getSourceRange(); 3654 S = S->IgnoreParens(); 3655 if (auto UO = dyn_cast<UnaryOperator>(S)) { 3656 if (UO->isIncrementDecrementOp() && 3657 GetInitLCDecl(UO->getSubExpr()) == LCDecl) 3658 return SetStep( 3659 SemaRef.ActOnIntegerConstant(UO->getLocStart(), 3660 (UO->isDecrementOp() ? -1 : 1)).get(), 3661 false); 3662 } else if (auto BO = dyn_cast<BinaryOperator>(S)) { 3663 switch (BO->getOpcode()) { 3664 case BO_AddAssign: 3665 case BO_SubAssign: 3666 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3667 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 3668 break; 3669 case BO_Assign: 3670 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3671 return CheckIncRHS(BO->getRHS()); 3672 break; 3673 default: 3674 break; 3675 } 3676 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3677 switch (CE->getOperator()) { 3678 case OO_PlusPlus: 3679 case OO_MinusMinus: 3680 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3681 return SetStep( 3682 SemaRef.ActOnIntegerConstant( 3683 CE->getLocStart(), 3684 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).get(), 3685 false); 3686 break; 3687 case OO_PlusEqual: 3688 case OO_MinusEqual: 3689 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3690 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 3691 break; 3692 case OO_Equal: 3693 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3694 return CheckIncRHS(CE->getArg(1)); 3695 break; 3696 default: 3697 break; 3698 } 3699 } 3700 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3701 return false; 3702 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr) 3703 << S->getSourceRange() << LCDecl; 3704 return true; 3705 } 3706 3707 static ExprResult 3708 tryBuildCapture(Sema &SemaRef, Expr *Capture, 3709 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 3710 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 3711 return SemaRef.PerformImplicitConversion( 3712 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 3713 /*AllowExplicit=*/true); 3714 auto I = Captures.find(Capture); 3715 if (I != Captures.end()) 3716 return buildCapture(SemaRef, Capture, I->second); 3717 DeclRefExpr *Ref = nullptr; 3718 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 3719 Captures[Capture] = Ref; 3720 return Res; 3721 } 3722 3723 /// \brief Build the expression to calculate the number of iterations. 3724 Expr *OpenMPIterationSpaceChecker::BuildNumIterations( 3725 Scope *S, const bool LimitedType, 3726 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 3727 ExprResult Diff; 3728 auto VarType = LCDecl->getType().getNonReferenceType(); 3729 if (VarType->isIntegerType() || VarType->isPointerType() || 3730 SemaRef.getLangOpts().CPlusPlus) { 3731 // Upper - Lower 3732 auto *UBExpr = TestIsLessOp ? UB : LB; 3733 auto *LBExpr = TestIsLessOp ? LB : UB; 3734 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 3735 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 3736 if (!Upper || !Lower) 3737 return nullptr; 3738 3739 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 3740 3741 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 3742 // BuildBinOp already emitted error, this one is to point user to upper 3743 // and lower bound, and to tell what is passed to 'operator-'. 3744 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) 3745 << Upper->getSourceRange() << Lower->getSourceRange(); 3746 return nullptr; 3747 } 3748 } 3749 3750 if (!Diff.isUsable()) 3751 return nullptr; 3752 3753 // Upper - Lower [- 1] 3754 if (TestIsStrictOp) 3755 Diff = SemaRef.BuildBinOp( 3756 S, DefaultLoc, BO_Sub, Diff.get(), 3757 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 3758 if (!Diff.isUsable()) 3759 return nullptr; 3760 3761 // Upper - Lower [- 1] + Step 3762 auto NewStep = tryBuildCapture(SemaRef, Step, Captures); 3763 if (!NewStep.isUsable()) 3764 return nullptr; 3765 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 3766 if (!Diff.isUsable()) 3767 return nullptr; 3768 3769 // Parentheses (for dumping/debugging purposes only). 3770 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 3771 if (!Diff.isUsable()) 3772 return nullptr; 3773 3774 // (Upper - Lower [- 1] + Step) / Step 3775 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 3776 if (!Diff.isUsable()) 3777 return nullptr; 3778 3779 // OpenMP runtime requires 32-bit or 64-bit loop variables. 3780 QualType Type = Diff.get()->getType(); 3781 auto &C = SemaRef.Context; 3782 bool UseVarType = VarType->hasIntegerRepresentation() && 3783 C.getTypeSize(Type) > C.getTypeSize(VarType); 3784 if (!Type->isIntegerType() || UseVarType) { 3785 unsigned NewSize = 3786 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 3787 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 3788 : Type->hasSignedIntegerRepresentation(); 3789 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 3790 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 3791 Diff = SemaRef.PerformImplicitConversion( 3792 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 3793 if (!Diff.isUsable()) 3794 return nullptr; 3795 } 3796 } 3797 if (LimitedType) { 3798 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 3799 if (NewSize != C.getTypeSize(Type)) { 3800 if (NewSize < C.getTypeSize(Type)) { 3801 assert(NewSize == 64 && "incorrect loop var size"); 3802 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 3803 << InitSrcRange << ConditionSrcRange; 3804 } 3805 QualType NewType = C.getIntTypeForBitwidth( 3806 NewSize, Type->hasSignedIntegerRepresentation() || 3807 C.getTypeSize(Type) < NewSize); 3808 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 3809 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 3810 Sema::AA_Converting, true); 3811 if (!Diff.isUsable()) 3812 return nullptr; 3813 } 3814 } 3815 } 3816 3817 return Diff.get(); 3818 } 3819 3820 Expr *OpenMPIterationSpaceChecker::BuildPreCond( 3821 Scope *S, Expr *Cond, 3822 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 3823 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 3824 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 3825 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 3826 3827 auto NewLB = tryBuildCapture(SemaRef, LB, Captures); 3828 auto NewUB = tryBuildCapture(SemaRef, UB, Captures); 3829 if (!NewLB.isUsable() || !NewUB.isUsable()) 3830 return nullptr; 3831 3832 auto CondExpr = SemaRef.BuildBinOp( 3833 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) 3834 : (TestIsStrictOp ? BO_GT : BO_GE), 3835 NewLB.get(), NewUB.get()); 3836 if (CondExpr.isUsable()) { 3837 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 3838 SemaRef.Context.BoolTy)) 3839 CondExpr = SemaRef.PerformImplicitConversion( 3840 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 3841 /*AllowExplicit=*/true); 3842 } 3843 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 3844 // Otherwise use original loop conditon and evaluate it in runtime. 3845 return CondExpr.isUsable() ? CondExpr.get() : Cond; 3846 } 3847 3848 /// \brief Build reference expression to the counter be used for codegen. 3849 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar( 3850 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 3851 auto *VD = dyn_cast<VarDecl>(LCDecl); 3852 if (!VD) { 3853 VD = SemaRef.IsOpenMPCapturedDecl(LCDecl); 3854 auto *Ref = buildDeclRefExpr( 3855 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 3856 Captures.insert(std::make_pair(LCRef, Ref)); 3857 return Ref; 3858 } 3859 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(), 3860 DefaultLoc); 3861 } 3862 3863 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const { 3864 if (LCDecl && !LCDecl->isInvalidDecl()) { 3865 auto Type = LCDecl->getType().getNonReferenceType(); 3866 auto *PrivateVar = 3867 buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(), 3868 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr); 3869 if (PrivateVar->isInvalidDecl()) 3870 return nullptr; 3871 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 3872 } 3873 return nullptr; 3874 } 3875 3876 /// \brief Build initization of the counter be used for codegen. 3877 Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; } 3878 3879 /// \brief Build step of the counter be used for codegen. 3880 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; } 3881 3882 /// \brief Iteration space of a single for loop. 3883 struct LoopIterationSpace { 3884 /// \brief Condition of the loop. 3885 Expr *PreCond; 3886 /// \brief This expression calculates the number of iterations in the loop. 3887 /// It is always possible to calculate it before starting the loop. 3888 Expr *NumIterations; 3889 /// \brief The loop counter variable. 3890 Expr *CounterVar; 3891 /// \brief Private loop counter variable. 3892 Expr *PrivateCounterVar; 3893 /// \brief This is initializer for the initial value of #CounterVar. 3894 Expr *CounterInit; 3895 /// \brief This is step for the #CounterVar used to generate its update: 3896 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 3897 Expr *CounterStep; 3898 /// \brief Should step be subtracted? 3899 bool Subtract; 3900 /// \brief Source range of the loop init. 3901 SourceRange InitSrcRange; 3902 /// \brief Source range of the loop condition. 3903 SourceRange CondSrcRange; 3904 /// \brief Source range of the loop increment. 3905 SourceRange IncSrcRange; 3906 }; 3907 3908 } // namespace 3909 3910 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 3911 assert(getLangOpts().OpenMP && "OpenMP is not active."); 3912 assert(Init && "Expected loop in canonical form."); 3913 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 3914 if (AssociatedLoops > 0 && 3915 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 3916 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 3917 if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) { 3918 if (auto *D = ISC.GetLoopDecl()) { 3919 auto *VD = dyn_cast<VarDecl>(D); 3920 if (!VD) { 3921 if (auto *Private = IsOpenMPCapturedDecl(D)) 3922 VD = Private; 3923 else { 3924 auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(), 3925 /*WithInit=*/false); 3926 VD = cast<VarDecl>(Ref->getDecl()); 3927 } 3928 } 3929 DSAStack->addLoopControlVariable(D, VD); 3930 } 3931 } 3932 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 3933 } 3934 } 3935 3936 /// \brief Called on a for stmt to check and extract its iteration space 3937 /// for further processing (such as collapsing). 3938 static bool CheckOpenMPIterationSpace( 3939 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 3940 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 3941 Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, 3942 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 3943 LoopIterationSpace &ResultIterSpace, 3944 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 3945 // OpenMP [2.6, Canonical Loop Form] 3946 // for (init-expr; test-expr; incr-expr) structured-block 3947 auto For = dyn_cast_or_null<ForStmt>(S); 3948 if (!For) { 3949 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for) 3950 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 3951 << getOpenMPDirectiveName(DKind) << NestedLoopCount 3952 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 3953 if (NestedLoopCount > 1) { 3954 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 3955 SemaRef.Diag(DSA.getConstructLoc(), 3956 diag::note_omp_collapse_ordered_expr) 3957 << 2 << CollapseLoopCountExpr->getSourceRange() 3958 << OrderedLoopCountExpr->getSourceRange(); 3959 else if (CollapseLoopCountExpr) 3960 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 3961 diag::note_omp_collapse_ordered_expr) 3962 << 0 << CollapseLoopCountExpr->getSourceRange(); 3963 else 3964 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 3965 diag::note_omp_collapse_ordered_expr) 3966 << 1 << OrderedLoopCountExpr->getSourceRange(); 3967 } 3968 return true; 3969 } 3970 assert(For->getBody()); 3971 3972 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 3973 3974 // Check init. 3975 auto Init = For->getInit(); 3976 if (ISC.CheckInit(Init)) 3977 return true; 3978 3979 bool HasErrors = false; 3980 3981 // Check loop variable's type. 3982 if (auto *LCDecl = ISC.GetLoopDecl()) { 3983 auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr(); 3984 3985 // OpenMP [2.6, Canonical Loop Form] 3986 // Var is one of the following: 3987 // A variable of signed or unsigned integer type. 3988 // For C++, a variable of a random access iterator type. 3989 // For C, a variable of a pointer type. 3990 auto VarType = LCDecl->getType().getNonReferenceType(); 3991 if (!VarType->isDependentType() && !VarType->isIntegerType() && 3992 !VarType->isPointerType() && 3993 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 3994 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type) 3995 << SemaRef.getLangOpts().CPlusPlus; 3996 HasErrors = true; 3997 } 3998 3999 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 4000 // a Construct 4001 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4002 // parallel for construct is (are) private. 4003 // The loop iteration variable in the associated for-loop of a simd 4004 // construct with just one associated for-loop is linear with a 4005 // constant-linear-step that is the increment of the associated for-loop. 4006 // Exclude loop var from the list of variables with implicitly defined data 4007 // sharing attributes. 4008 VarsWithImplicitDSA.erase(LCDecl); 4009 4010 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 4011 // in a Construct, C/C++]. 4012 // The loop iteration variable in the associated for-loop of a simd 4013 // construct with just one associated for-loop may be listed in a linear 4014 // clause with a constant-linear-step that is the increment of the 4015 // associated for-loop. 4016 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4017 // parallel for construct may be listed in a private or lastprivate clause. 4018 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 4019 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 4020 // declared in the loop and it is predetermined as a private. 4021 auto PredeterminedCKind = 4022 isOpenMPSimdDirective(DKind) 4023 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 4024 : OMPC_private; 4025 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4026 DVar.CKind != PredeterminedCKind) || 4027 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 4028 isOpenMPDistributeDirective(DKind)) && 4029 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4030 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 4031 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 4032 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa) 4033 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 4034 << getOpenMPClauseName(PredeterminedCKind); 4035 if (DVar.RefExpr == nullptr) 4036 DVar.CKind = PredeterminedCKind; 4037 ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 4038 HasErrors = true; 4039 } else if (LoopDeclRefExpr != nullptr) { 4040 // Make the loop iteration variable private (for worksharing constructs), 4041 // linear (for simd directives with the only one associated loop) or 4042 // lastprivate (for simd directives with several collapsed or ordered 4043 // loops). 4044 if (DVar.CKind == OMPC_unknown) 4045 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate, MatchesAlways(), 4046 /*FromParent=*/false); 4047 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 4048 } 4049 4050 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 4051 4052 // Check test-expr. 4053 HasErrors |= ISC.CheckCond(For->getCond()); 4054 4055 // Check incr-expr. 4056 HasErrors |= ISC.CheckInc(For->getInc()); 4057 } 4058 4059 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 4060 return HasErrors; 4061 4062 // Build the loop's iteration space representation. 4063 ResultIterSpace.PreCond = 4064 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures); 4065 ResultIterSpace.NumIterations = ISC.BuildNumIterations( 4066 DSA.getCurScope(), 4067 (isOpenMPWorksharingDirective(DKind) || 4068 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 4069 Captures); 4070 ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures); 4071 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); 4072 ResultIterSpace.CounterInit = ISC.BuildCounterInit(); 4073 ResultIterSpace.CounterStep = ISC.BuildCounterStep(); 4074 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); 4075 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange(); 4076 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange(); 4077 ResultIterSpace.Subtract = ISC.ShouldSubtractStep(); 4078 4079 HasErrors |= (ResultIterSpace.PreCond == nullptr || 4080 ResultIterSpace.NumIterations == nullptr || 4081 ResultIterSpace.CounterVar == nullptr || 4082 ResultIterSpace.PrivateCounterVar == nullptr || 4083 ResultIterSpace.CounterInit == nullptr || 4084 ResultIterSpace.CounterStep == nullptr); 4085 4086 return HasErrors; 4087 } 4088 4089 /// \brief Build 'VarRef = Start. 4090 static ExprResult 4091 BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 4092 ExprResult Start, 4093 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4094 // Build 'VarRef = Start. 4095 auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 4096 if (!NewStart.isUsable()) 4097 return ExprError(); 4098 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 4099 VarRef.get()->getType())) { 4100 NewStart = SemaRef.PerformImplicitConversion( 4101 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 4102 /*AllowExplicit=*/true); 4103 if (!NewStart.isUsable()) 4104 return ExprError(); 4105 } 4106 4107 auto Init = 4108 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4109 return Init; 4110 } 4111 4112 /// \brief Build 'VarRef = Start + Iter * Step'. 4113 static ExprResult 4114 BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, 4115 ExprResult VarRef, ExprResult Start, ExprResult Iter, 4116 ExprResult Step, bool Subtract, 4117 llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) { 4118 // Add parentheses (for debugging purposes only). 4119 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 4120 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 4121 !Step.isUsable()) 4122 return ExprError(); 4123 4124 ExprResult NewStep = Step; 4125 if (Captures) 4126 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 4127 if (NewStep.isInvalid()) 4128 return ExprError(); 4129 ExprResult Update = 4130 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 4131 if (!Update.isUsable()) 4132 return ExprError(); 4133 4134 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 4135 // 'VarRef = Start (+|-) Iter * Step'. 4136 ExprResult NewStart = Start; 4137 if (Captures) 4138 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 4139 if (NewStart.isInvalid()) 4140 return ExprError(); 4141 4142 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 4143 ExprResult SavedUpdate = Update; 4144 ExprResult UpdateVal; 4145 if (VarRef.get()->getType()->isOverloadableType() || 4146 NewStart.get()->getType()->isOverloadableType() || 4147 Update.get()->getType()->isOverloadableType()) { 4148 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4149 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4150 Update = 4151 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4152 if (Update.isUsable()) { 4153 UpdateVal = 4154 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 4155 VarRef.get(), SavedUpdate.get()); 4156 if (UpdateVal.isUsable()) { 4157 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 4158 UpdateVal.get()); 4159 } 4160 } 4161 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4162 } 4163 4164 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 4165 if (!Update.isUsable() || !UpdateVal.isUsable()) { 4166 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 4167 NewStart.get(), SavedUpdate.get()); 4168 if (!Update.isUsable()) 4169 return ExprError(); 4170 4171 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 4172 VarRef.get()->getType())) { 4173 Update = SemaRef.PerformImplicitConversion( 4174 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 4175 if (!Update.isUsable()) 4176 return ExprError(); 4177 } 4178 4179 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 4180 } 4181 return Update; 4182 } 4183 4184 /// \brief Convert integer expression \a E to make it have at least \a Bits 4185 /// bits. 4186 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, 4187 Sema &SemaRef) { 4188 if (E == nullptr) 4189 return ExprError(); 4190 auto &C = SemaRef.Context; 4191 QualType OldType = E->getType(); 4192 unsigned HasBits = C.getTypeSize(OldType); 4193 if (HasBits >= Bits) 4194 return ExprResult(E); 4195 // OK to convert to signed, because new type has more bits than old. 4196 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 4197 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 4198 true); 4199 } 4200 4201 /// \brief Check if the given expression \a E is a constant integer that fits 4202 /// into \a Bits bits. 4203 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { 4204 if (E == nullptr) 4205 return false; 4206 llvm::APSInt Result; 4207 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 4208 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 4209 return false; 4210 } 4211 4212 /// Build preinits statement for the given declarations. 4213 static Stmt *buildPreInits(ASTContext &Context, 4214 SmallVectorImpl<Decl *> &PreInits) { 4215 if (!PreInits.empty()) { 4216 return new (Context) DeclStmt( 4217 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 4218 SourceLocation(), SourceLocation()); 4219 } 4220 return nullptr; 4221 } 4222 4223 /// Build preinits statement for the given declarations. 4224 static Stmt *buildPreInits(ASTContext &Context, 4225 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4226 if (!Captures.empty()) { 4227 SmallVector<Decl *, 16> PreInits; 4228 for (auto &Pair : Captures) 4229 PreInits.push_back(Pair.second->getDecl()); 4230 return buildPreInits(Context, PreInits); 4231 } 4232 return nullptr; 4233 } 4234 4235 /// Build postupdate expression for the given list of postupdates expressions. 4236 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 4237 Expr *PostUpdate = nullptr; 4238 if (!PostUpdates.empty()) { 4239 for (auto *E : PostUpdates) { 4240 Expr *ConvE = S.BuildCStyleCastExpr( 4241 E->getExprLoc(), 4242 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 4243 E->getExprLoc(), E) 4244 .get(); 4245 PostUpdate = PostUpdate 4246 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 4247 PostUpdate, ConvE) 4248 .get() 4249 : ConvE; 4250 } 4251 } 4252 return PostUpdate; 4253 } 4254 4255 /// \brief Called on a for stmt to check itself and nested loops (if any). 4256 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 4257 /// number of collapsed loops otherwise. 4258 static unsigned 4259 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 4260 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 4261 DSAStackTy &DSA, 4262 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 4263 OMPLoopDirective::HelperExprs &Built) { 4264 unsigned NestedLoopCount = 1; 4265 if (CollapseLoopCountExpr) { 4266 // Found 'collapse' clause - calculate collapse number. 4267 llvm::APSInt Result; 4268 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 4269 NestedLoopCount = Result.getLimitedValue(); 4270 } 4271 if (OrderedLoopCountExpr) { 4272 // Found 'ordered' clause - calculate collapse number. 4273 llvm::APSInt Result; 4274 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 4275 if (Result.getLimitedValue() < NestedLoopCount) { 4276 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4277 diag::err_omp_wrong_ordered_loop_count) 4278 << OrderedLoopCountExpr->getSourceRange(); 4279 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4280 diag::note_collapse_loop_count) 4281 << CollapseLoopCountExpr->getSourceRange(); 4282 } 4283 NestedLoopCount = Result.getLimitedValue(); 4284 } 4285 } 4286 // This is helper routine for loop directives (e.g., 'for', 'simd', 4287 // 'for simd', etc.). 4288 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 4289 SmallVector<LoopIterationSpace, 4> IterSpaces; 4290 IterSpaces.resize(NestedLoopCount); 4291 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 4292 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 4293 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, 4294 NestedLoopCount, CollapseLoopCountExpr, 4295 OrderedLoopCountExpr, VarsWithImplicitDSA, 4296 IterSpaces[Cnt], Captures)) 4297 return 0; 4298 // Move on to the next nested for loop, or to the loop body. 4299 // OpenMP [2.8.1, simd construct, Restrictions] 4300 // All loops associated with the construct must be perfectly nested; that 4301 // is, there must be no intervening code nor any OpenMP directive between 4302 // any two loops. 4303 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 4304 } 4305 4306 Built.clear(/* size */ NestedLoopCount); 4307 4308 if (SemaRef.CurContext->isDependentContext()) 4309 return NestedLoopCount; 4310 4311 // An example of what is generated for the following code: 4312 // 4313 // #pragma omp simd collapse(2) ordered(2) 4314 // for (i = 0; i < NI; ++i) 4315 // for (k = 0; k < NK; ++k) 4316 // for (j = J0; j < NJ; j+=2) { 4317 // <loop body> 4318 // } 4319 // 4320 // We generate the code below. 4321 // Note: the loop body may be outlined in CodeGen. 4322 // Note: some counters may be C++ classes, operator- is used to find number of 4323 // iterations and operator+= to calculate counter value. 4324 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 4325 // or i64 is currently supported). 4326 // 4327 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 4328 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 4329 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 4330 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 4331 // // similar updates for vars in clauses (e.g. 'linear') 4332 // <loop body (using local i and j)> 4333 // } 4334 // i = NI; // assign final values of counters 4335 // j = NJ; 4336 // 4337 4338 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 4339 // the iteration counts of the collapsed for loops. 4340 // Precondition tests if there is at least one iteration (all conditions are 4341 // true). 4342 auto PreCond = ExprResult(IterSpaces[0].PreCond); 4343 auto N0 = IterSpaces[0].NumIterations; 4344 ExprResult LastIteration32 = WidenIterationCount( 4345 32 /* Bits */, SemaRef.PerformImplicitConversion( 4346 N0->IgnoreImpCasts(), N0->getType(), 4347 Sema::AA_Converting, /*AllowExplicit=*/true) 4348 .get(), 4349 SemaRef); 4350 ExprResult LastIteration64 = WidenIterationCount( 4351 64 /* Bits */, SemaRef.PerformImplicitConversion( 4352 N0->IgnoreImpCasts(), N0->getType(), 4353 Sema::AA_Converting, /*AllowExplicit=*/true) 4354 .get(), 4355 SemaRef); 4356 4357 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 4358 return NestedLoopCount; 4359 4360 auto &C = SemaRef.Context; 4361 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 4362 4363 Scope *CurScope = DSA.getCurScope(); 4364 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 4365 if (PreCond.isUsable()) { 4366 PreCond = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_LAnd, 4367 PreCond.get(), IterSpaces[Cnt].PreCond); 4368 } 4369 auto N = IterSpaces[Cnt].NumIterations; 4370 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 4371 if (LastIteration32.isUsable()) 4372 LastIteration32 = SemaRef.BuildBinOp( 4373 CurScope, SourceLocation(), BO_Mul, LastIteration32.get(), 4374 SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4375 Sema::AA_Converting, 4376 /*AllowExplicit=*/true) 4377 .get()); 4378 if (LastIteration64.isUsable()) 4379 LastIteration64 = SemaRef.BuildBinOp( 4380 CurScope, SourceLocation(), BO_Mul, LastIteration64.get(), 4381 SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4382 Sema::AA_Converting, 4383 /*AllowExplicit=*/true) 4384 .get()); 4385 } 4386 4387 // Choose either the 32-bit or 64-bit version. 4388 ExprResult LastIteration = LastIteration64; 4389 if (LastIteration32.isUsable() && 4390 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 4391 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 4392 FitsInto( 4393 32 /* Bits */, 4394 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 4395 LastIteration64.get(), SemaRef))) 4396 LastIteration = LastIteration32; 4397 4398 if (!LastIteration.isUsable()) 4399 return 0; 4400 4401 // Save the number of iterations. 4402 ExprResult NumIterations = LastIteration; 4403 { 4404 LastIteration = SemaRef.BuildBinOp( 4405 CurScope, SourceLocation(), BO_Sub, LastIteration.get(), 4406 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4407 if (!LastIteration.isUsable()) 4408 return 0; 4409 } 4410 4411 // Calculate the last iteration number beforehand instead of doing this on 4412 // each iteration. Do not do this if the number of iterations may be kfold-ed. 4413 llvm::APSInt Result; 4414 bool IsConstant = 4415 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 4416 ExprResult CalcLastIteration; 4417 if (!IsConstant) { 4418 ExprResult SaveRef = 4419 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 4420 LastIteration = SaveRef; 4421 4422 // Prepare SaveRef + 1. 4423 NumIterations = SemaRef.BuildBinOp( 4424 CurScope, SourceLocation(), BO_Add, SaveRef.get(), 4425 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4426 if (!NumIterations.isUsable()) 4427 return 0; 4428 } 4429 4430 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 4431 4432 QualType VType = LastIteration.get()->getType(); 4433 // Build variables passed into runtime, nesessary for worksharing directives. 4434 ExprResult LB, UB, IL, ST, EUB; 4435 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4436 isOpenMPDistributeDirective(DKind)) { 4437 // Lower bound variable, initialized with zero. 4438 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 4439 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 4440 SemaRef.AddInitializerToDecl( 4441 LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4442 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 4443 4444 // Upper bound variable, initialized with last iteration number. 4445 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 4446 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 4447 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 4448 /*DirectInit*/ false, 4449 /*TypeMayContainAuto*/ false); 4450 4451 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 4452 // This will be used to implement clause 'lastprivate'. 4453 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 4454 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 4455 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 4456 SemaRef.AddInitializerToDecl( 4457 ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4458 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 4459 4460 // Stride variable returned by runtime (we initialize it to 1 by default). 4461 VarDecl *STDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.stride"); 4462 ST = buildDeclRefExpr(SemaRef, STDecl, VType, InitLoc); 4463 SemaRef.AddInitializerToDecl( 4464 STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 4465 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 4466 4467 // Build expression: UB = min(UB, LastIteration) 4468 // It is nesessary for CodeGen of directives with static scheduling. 4469 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 4470 UB.get(), LastIteration.get()); 4471 ExprResult CondOp = SemaRef.ActOnConditionalOp( 4472 InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get()); 4473 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 4474 CondOp.get()); 4475 EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); 4476 } 4477 4478 // Build the iteration variable and its initialization before loop. 4479 ExprResult IV; 4480 ExprResult Init; 4481 { 4482 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.iv"); 4483 IV = buildDeclRefExpr(SemaRef, IVDecl, VType, InitLoc); 4484 Expr *RHS = (isOpenMPWorksharingDirective(DKind) || 4485 isOpenMPTaskLoopDirective(DKind) || 4486 isOpenMPDistributeDirective(DKind)) 4487 ? LB.get() 4488 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 4489 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 4490 Init = SemaRef.ActOnFinishFullExpr(Init.get()); 4491 } 4492 4493 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. 4494 SourceLocation CondLoc; 4495 ExprResult Cond = 4496 (isOpenMPWorksharingDirective(DKind) || 4497 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 4498 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) 4499 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 4500 NumIterations.get()); 4501 4502 // Loop increment (IV = IV + 1) 4503 SourceLocation IncLoc; 4504 ExprResult Inc = 4505 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 4506 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 4507 if (!Inc.isUsable()) 4508 return 0; 4509 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 4510 Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); 4511 if (!Inc.isUsable()) 4512 return 0; 4513 4514 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 4515 // Used for directives with static scheduling. 4516 ExprResult NextLB, NextUB; 4517 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4518 isOpenMPDistributeDirective(DKind)) { 4519 // LB + ST 4520 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 4521 if (!NextLB.isUsable()) 4522 return 0; 4523 // LB = LB + ST 4524 NextLB = 4525 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 4526 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); 4527 if (!NextLB.isUsable()) 4528 return 0; 4529 // UB + ST 4530 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 4531 if (!NextUB.isUsable()) 4532 return 0; 4533 // UB = UB + ST 4534 NextUB = 4535 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 4536 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); 4537 if (!NextUB.isUsable()) 4538 return 0; 4539 } 4540 4541 // Build updates and final values of the loop counters. 4542 bool HasErrors = false; 4543 Built.Counters.resize(NestedLoopCount); 4544 Built.Inits.resize(NestedLoopCount); 4545 Built.Updates.resize(NestedLoopCount); 4546 Built.Finals.resize(NestedLoopCount); 4547 { 4548 ExprResult Div; 4549 // Go from inner nested loop to outer. 4550 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 4551 LoopIterationSpace &IS = IterSpaces[Cnt]; 4552 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 4553 // Build: Iter = (IV / Div) % IS.NumIters 4554 // where Div is product of previous iterations' IS.NumIters. 4555 ExprResult Iter; 4556 if (Div.isUsable()) { 4557 Iter = 4558 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); 4559 } else { 4560 Iter = IV; 4561 assert((Cnt == (int)NestedLoopCount - 1) && 4562 "unusable div expected on first iteration only"); 4563 } 4564 4565 if (Cnt != 0 && Iter.isUsable()) 4566 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), 4567 IS.NumIterations); 4568 if (!Iter.isUsable()) { 4569 HasErrors = true; 4570 break; 4571 } 4572 4573 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 4574 auto *CounterVar = buildDeclRefExpr( 4575 SemaRef, cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()), 4576 IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 4577 /*RefersToCapture=*/true); 4578 ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 4579 IS.CounterInit, Captures); 4580 if (!Init.isUsable()) { 4581 HasErrors = true; 4582 break; 4583 } 4584 ExprResult Update = BuildCounterUpdate( 4585 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 4586 IS.CounterStep, IS.Subtract, &Captures); 4587 if (!Update.isUsable()) { 4588 HasErrors = true; 4589 break; 4590 } 4591 4592 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 4593 ExprResult Final = BuildCounterUpdate( 4594 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 4595 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 4596 if (!Final.isUsable()) { 4597 HasErrors = true; 4598 break; 4599 } 4600 4601 // Build Div for the next iteration: Div <- Div * IS.NumIters 4602 if (Cnt != 0) { 4603 if (Div.isUnset()) 4604 Div = IS.NumIterations; 4605 else 4606 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), 4607 IS.NumIterations); 4608 4609 // Add parentheses (for debugging purposes only). 4610 if (Div.isUsable()) 4611 Div = SemaRef.ActOnParenExpr(UpdLoc, UpdLoc, Div.get()); 4612 if (!Div.isUsable()) { 4613 HasErrors = true; 4614 break; 4615 } 4616 } 4617 if (!Update.isUsable() || !Final.isUsable()) { 4618 HasErrors = true; 4619 break; 4620 } 4621 // Save results 4622 Built.Counters[Cnt] = IS.CounterVar; 4623 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 4624 Built.Inits[Cnt] = Init.get(); 4625 Built.Updates[Cnt] = Update.get(); 4626 Built.Finals[Cnt] = Final.get(); 4627 } 4628 } 4629 4630 if (HasErrors) 4631 return 0; 4632 4633 // Save results 4634 Built.IterationVarRef = IV.get(); 4635 Built.LastIteration = LastIteration.get(); 4636 Built.NumIterations = NumIterations.get(); 4637 Built.CalcLastIteration = 4638 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); 4639 Built.PreCond = PreCond.get(); 4640 Built.PreInits = buildPreInits(C, Captures); 4641 Built.Cond = Cond.get(); 4642 Built.Init = Init.get(); 4643 Built.Inc = Inc.get(); 4644 Built.LB = LB.get(); 4645 Built.UB = UB.get(); 4646 Built.IL = IL.get(); 4647 Built.ST = ST.get(); 4648 Built.EUB = EUB.get(); 4649 Built.NLB = NextLB.get(); 4650 Built.NUB = NextUB.get(); 4651 4652 return NestedLoopCount; 4653 } 4654 4655 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 4656 auto CollapseClauses = 4657 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 4658 if (CollapseClauses.begin() != CollapseClauses.end()) 4659 return (*CollapseClauses.begin())->getNumForLoops(); 4660 return nullptr; 4661 } 4662 4663 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 4664 auto OrderedClauses = 4665 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 4666 if (OrderedClauses.begin() != OrderedClauses.end()) 4667 return (*OrderedClauses.begin())->getNumForLoops(); 4668 return nullptr; 4669 } 4670 4671 static bool checkSimdlenSafelenValues(Sema &S, const Expr *Simdlen, 4672 const Expr *Safelen) { 4673 llvm::APSInt SimdlenRes, SafelenRes; 4674 if (Simdlen->isValueDependent() || Simdlen->isTypeDependent() || 4675 Simdlen->isInstantiationDependent() || 4676 Simdlen->containsUnexpandedParameterPack()) 4677 return false; 4678 if (Safelen->isValueDependent() || Safelen->isTypeDependent() || 4679 Safelen->isInstantiationDependent() || 4680 Safelen->containsUnexpandedParameterPack()) 4681 return false; 4682 Simdlen->EvaluateAsInt(SimdlenRes, S.Context); 4683 Safelen->EvaluateAsInt(SafelenRes, S.Context); 4684 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 4685 // If both simdlen and safelen clauses are specified, the value of the simdlen 4686 // parameter must be less than or equal to the value of the safelen parameter. 4687 if (SimdlenRes > SafelenRes) { 4688 S.Diag(Simdlen->getExprLoc(), diag::err_omp_wrong_simdlen_safelen_values) 4689 << Simdlen->getSourceRange() << Safelen->getSourceRange(); 4690 return true; 4691 } 4692 return false; 4693 } 4694 4695 StmtResult Sema::ActOnOpenMPSimdDirective( 4696 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4697 SourceLocation EndLoc, 4698 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4699 if (!AStmt) 4700 return StmtError(); 4701 4702 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4703 OMPLoopDirective::HelperExprs B; 4704 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 4705 // define the nested loops number. 4706 unsigned NestedLoopCount = CheckOpenMPLoop( 4707 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 4708 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 4709 if (NestedLoopCount == 0) 4710 return StmtError(); 4711 4712 assert((CurContext->isDependentContext() || B.builtAll()) && 4713 "omp simd loop exprs were not built"); 4714 4715 if (!CurContext->isDependentContext()) { 4716 // Finalize the clauses that need pre-built expressions for CodeGen. 4717 for (auto C : Clauses) { 4718 if (auto LC = dyn_cast<OMPLinearClause>(C)) 4719 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 4720 B.NumIterations, *this, CurScope)) 4721 return StmtError(); 4722 } 4723 } 4724 4725 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 4726 // If both simdlen and safelen clauses are specified, the value of the simdlen 4727 // parameter must be less than or equal to the value of the safelen parameter. 4728 OMPSafelenClause *Safelen = nullptr; 4729 OMPSimdlenClause *Simdlen = nullptr; 4730 for (auto *Clause : Clauses) { 4731 if (Clause->getClauseKind() == OMPC_safelen) 4732 Safelen = cast<OMPSafelenClause>(Clause); 4733 else if (Clause->getClauseKind() == OMPC_simdlen) 4734 Simdlen = cast<OMPSimdlenClause>(Clause); 4735 if (Safelen && Simdlen) 4736 break; 4737 } 4738 if (Simdlen && Safelen && 4739 checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), 4740 Safelen->getSafelen())) 4741 return StmtError(); 4742 4743 getCurFunction()->setHasBranchProtectedScope(); 4744 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 4745 Clauses, AStmt, B); 4746 } 4747 4748 StmtResult Sema::ActOnOpenMPForDirective( 4749 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4750 SourceLocation EndLoc, 4751 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4752 if (!AStmt) 4753 return StmtError(); 4754 4755 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4756 OMPLoopDirective::HelperExprs B; 4757 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 4758 // define the nested loops number. 4759 unsigned NestedLoopCount = CheckOpenMPLoop( 4760 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 4761 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 4762 if (NestedLoopCount == 0) 4763 return StmtError(); 4764 4765 assert((CurContext->isDependentContext() || B.builtAll()) && 4766 "omp for loop exprs were not built"); 4767 4768 if (!CurContext->isDependentContext()) { 4769 // Finalize the clauses that need pre-built expressions for CodeGen. 4770 for (auto C : Clauses) { 4771 if (auto LC = dyn_cast<OMPLinearClause>(C)) 4772 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 4773 B.NumIterations, *this, CurScope)) 4774 return StmtError(); 4775 } 4776 } 4777 4778 getCurFunction()->setHasBranchProtectedScope(); 4779 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 4780 Clauses, AStmt, B, DSAStack->isCancelRegion()); 4781 } 4782 4783 StmtResult Sema::ActOnOpenMPForSimdDirective( 4784 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4785 SourceLocation EndLoc, 4786 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4787 if (!AStmt) 4788 return StmtError(); 4789 4790 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4791 OMPLoopDirective::HelperExprs B; 4792 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 4793 // define the nested loops number. 4794 unsigned NestedLoopCount = 4795 CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 4796 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 4797 VarsWithImplicitDSA, B); 4798 if (NestedLoopCount == 0) 4799 return StmtError(); 4800 4801 assert((CurContext->isDependentContext() || B.builtAll()) && 4802 "omp for simd loop exprs were not built"); 4803 4804 if (!CurContext->isDependentContext()) { 4805 // Finalize the clauses that need pre-built expressions for CodeGen. 4806 for (auto C : Clauses) { 4807 if (auto LC = dyn_cast<OMPLinearClause>(C)) 4808 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 4809 B.NumIterations, *this, CurScope)) 4810 return StmtError(); 4811 } 4812 } 4813 4814 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 4815 // If both simdlen and safelen clauses are specified, the value of the simdlen 4816 // parameter must be less than or equal to the value of the safelen parameter. 4817 OMPSafelenClause *Safelen = nullptr; 4818 OMPSimdlenClause *Simdlen = nullptr; 4819 for (auto *Clause : Clauses) { 4820 if (Clause->getClauseKind() == OMPC_safelen) 4821 Safelen = cast<OMPSafelenClause>(Clause); 4822 else if (Clause->getClauseKind() == OMPC_simdlen) 4823 Simdlen = cast<OMPSimdlenClause>(Clause); 4824 if (Safelen && Simdlen) 4825 break; 4826 } 4827 if (Simdlen && Safelen && 4828 checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), 4829 Safelen->getSafelen())) 4830 return StmtError(); 4831 4832 getCurFunction()->setHasBranchProtectedScope(); 4833 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 4834 Clauses, AStmt, B); 4835 } 4836 4837 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 4838 Stmt *AStmt, 4839 SourceLocation StartLoc, 4840 SourceLocation EndLoc) { 4841 if (!AStmt) 4842 return StmtError(); 4843 4844 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4845 auto BaseStmt = AStmt; 4846 while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 4847 BaseStmt = CS->getCapturedStmt(); 4848 if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 4849 auto S = C->children(); 4850 if (S.begin() == S.end()) 4851 return StmtError(); 4852 // All associated statements must be '#pragma omp section' except for 4853 // the first one. 4854 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 4855 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 4856 if (SectionStmt) 4857 Diag(SectionStmt->getLocStart(), 4858 diag::err_omp_sections_substmt_not_section); 4859 return StmtError(); 4860 } 4861 cast<OMPSectionDirective>(SectionStmt) 4862 ->setHasCancel(DSAStack->isCancelRegion()); 4863 } 4864 } else { 4865 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt); 4866 return StmtError(); 4867 } 4868 4869 getCurFunction()->setHasBranchProtectedScope(); 4870 4871 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4872 DSAStack->isCancelRegion()); 4873 } 4874 4875 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 4876 SourceLocation StartLoc, 4877 SourceLocation EndLoc) { 4878 if (!AStmt) 4879 return StmtError(); 4880 4881 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4882 4883 getCurFunction()->setHasBranchProtectedScope(); 4884 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 4885 4886 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 4887 DSAStack->isCancelRegion()); 4888 } 4889 4890 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 4891 Stmt *AStmt, 4892 SourceLocation StartLoc, 4893 SourceLocation EndLoc) { 4894 if (!AStmt) 4895 return StmtError(); 4896 4897 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4898 4899 getCurFunction()->setHasBranchProtectedScope(); 4900 4901 // OpenMP [2.7.3, single Construct, Restrictions] 4902 // The copyprivate clause must not be used with the nowait clause. 4903 OMPClause *Nowait = nullptr; 4904 OMPClause *Copyprivate = nullptr; 4905 for (auto *Clause : Clauses) { 4906 if (Clause->getClauseKind() == OMPC_nowait) 4907 Nowait = Clause; 4908 else if (Clause->getClauseKind() == OMPC_copyprivate) 4909 Copyprivate = Clause; 4910 if (Copyprivate && Nowait) { 4911 Diag(Copyprivate->getLocStart(), 4912 diag::err_omp_single_copyprivate_with_nowait); 4913 Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here); 4914 return StmtError(); 4915 } 4916 } 4917 4918 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 4919 } 4920 4921 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 4922 SourceLocation StartLoc, 4923 SourceLocation EndLoc) { 4924 if (!AStmt) 4925 return StmtError(); 4926 4927 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4928 4929 getCurFunction()->setHasBranchProtectedScope(); 4930 4931 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 4932 } 4933 4934 StmtResult Sema::ActOnOpenMPCriticalDirective( 4935 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 4936 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4937 if (!AStmt) 4938 return StmtError(); 4939 4940 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4941 4942 bool ErrorFound = false; 4943 llvm::APSInt Hint; 4944 SourceLocation HintLoc; 4945 bool DependentHint = false; 4946 for (auto *C : Clauses) { 4947 if (C->getClauseKind() == OMPC_hint) { 4948 if (!DirName.getName()) { 4949 Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name); 4950 ErrorFound = true; 4951 } 4952 Expr *E = cast<OMPHintClause>(C)->getHint(); 4953 if (E->isTypeDependent() || E->isValueDependent() || 4954 E->isInstantiationDependent()) 4955 DependentHint = true; 4956 else { 4957 Hint = E->EvaluateKnownConstInt(Context); 4958 HintLoc = C->getLocStart(); 4959 } 4960 } 4961 } 4962 if (ErrorFound) 4963 return StmtError(); 4964 auto Pair = DSAStack->getCriticalWithHint(DirName); 4965 if (Pair.first && DirName.getName() && !DependentHint) { 4966 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 4967 Diag(StartLoc, diag::err_omp_critical_with_hint); 4968 if (HintLoc.isValid()) { 4969 Diag(HintLoc, diag::note_omp_critical_hint_here) 4970 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 4971 } else 4972 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 4973 if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 4974 Diag(C->getLocStart(), diag::note_omp_critical_hint_here) 4975 << 1 4976 << C->getHint()->EvaluateKnownConstInt(Context).toString( 4977 /*Radix=*/10, /*Signed=*/false); 4978 } else 4979 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1; 4980 } 4981 } 4982 4983 getCurFunction()->setHasBranchProtectedScope(); 4984 4985 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 4986 Clauses, AStmt); 4987 if (!Pair.first && DirName.getName() && !DependentHint) 4988 DSAStack->addCriticalWithHint(Dir, Hint); 4989 return Dir; 4990 } 4991 4992 StmtResult Sema::ActOnOpenMPParallelForDirective( 4993 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4994 SourceLocation EndLoc, 4995 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4996 if (!AStmt) 4997 return StmtError(); 4998 4999 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5000 // 1.2.2 OpenMP Language Terminology 5001 // Structured block - An executable statement with a single entry at the 5002 // top and a single exit at the bottom. 5003 // The point of exit cannot be a branch out of the structured block. 5004 // longjmp() and throw() must not violate the entry/exit criteria. 5005 CS->getCapturedDecl()->setNothrow(); 5006 5007 OMPLoopDirective::HelperExprs B; 5008 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5009 // define the nested loops number. 5010 unsigned NestedLoopCount = 5011 CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 5012 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5013 VarsWithImplicitDSA, B); 5014 if (NestedLoopCount == 0) 5015 return StmtError(); 5016 5017 assert((CurContext->isDependentContext() || B.builtAll()) && 5018 "omp parallel for loop exprs were not built"); 5019 5020 if (!CurContext->isDependentContext()) { 5021 // Finalize the clauses that need pre-built expressions for CodeGen. 5022 for (auto C : Clauses) { 5023 if (auto LC = dyn_cast<OMPLinearClause>(C)) 5024 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5025 B.NumIterations, *this, CurScope)) 5026 return StmtError(); 5027 } 5028 } 5029 5030 getCurFunction()->setHasBranchProtectedScope(); 5031 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 5032 NestedLoopCount, Clauses, AStmt, B, 5033 DSAStack->isCancelRegion()); 5034 } 5035 5036 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 5037 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5038 SourceLocation EndLoc, 5039 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5040 if (!AStmt) 5041 return StmtError(); 5042 5043 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5044 // 1.2.2 OpenMP Language Terminology 5045 // Structured block - An executable statement with a single entry at the 5046 // top and a single exit at the bottom. 5047 // The point of exit cannot be a branch out of the structured block. 5048 // longjmp() and throw() must not violate the entry/exit criteria. 5049 CS->getCapturedDecl()->setNothrow(); 5050 5051 OMPLoopDirective::HelperExprs B; 5052 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5053 // define the nested loops number. 5054 unsigned NestedLoopCount = 5055 CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 5056 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5057 VarsWithImplicitDSA, B); 5058 if (NestedLoopCount == 0) 5059 return StmtError(); 5060 5061 if (!CurContext->isDependentContext()) { 5062 // Finalize the clauses that need pre-built expressions for CodeGen. 5063 for (auto C : Clauses) { 5064 if (auto LC = dyn_cast<OMPLinearClause>(C)) 5065 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5066 B.NumIterations, *this, CurScope)) 5067 return StmtError(); 5068 } 5069 } 5070 5071 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 5072 // If both simdlen and safelen clauses are specified, the value of the simdlen 5073 // parameter must be less than or equal to the value of the safelen parameter. 5074 OMPSafelenClause *Safelen = nullptr; 5075 OMPSimdlenClause *Simdlen = nullptr; 5076 for (auto *Clause : Clauses) { 5077 if (Clause->getClauseKind() == OMPC_safelen) 5078 Safelen = cast<OMPSafelenClause>(Clause); 5079 else if (Clause->getClauseKind() == OMPC_simdlen) 5080 Simdlen = cast<OMPSimdlenClause>(Clause); 5081 if (Safelen && Simdlen) 5082 break; 5083 } 5084 if (Simdlen && Safelen && 5085 checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), 5086 Safelen->getSafelen())) 5087 return StmtError(); 5088 5089 getCurFunction()->setHasBranchProtectedScope(); 5090 return OMPParallelForSimdDirective::Create( 5091 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 5092 } 5093 5094 StmtResult 5095 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 5096 Stmt *AStmt, SourceLocation StartLoc, 5097 SourceLocation EndLoc) { 5098 if (!AStmt) 5099 return StmtError(); 5100 5101 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5102 auto BaseStmt = AStmt; 5103 while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5104 BaseStmt = CS->getCapturedStmt(); 5105 if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5106 auto S = C->children(); 5107 if (S.begin() == S.end()) 5108 return StmtError(); 5109 // All associated statements must be '#pragma omp section' except for 5110 // the first one. 5111 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5112 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5113 if (SectionStmt) 5114 Diag(SectionStmt->getLocStart(), 5115 diag::err_omp_parallel_sections_substmt_not_section); 5116 return StmtError(); 5117 } 5118 cast<OMPSectionDirective>(SectionStmt) 5119 ->setHasCancel(DSAStack->isCancelRegion()); 5120 } 5121 } else { 5122 Diag(AStmt->getLocStart(), 5123 diag::err_omp_parallel_sections_not_compound_stmt); 5124 return StmtError(); 5125 } 5126 5127 getCurFunction()->setHasBranchProtectedScope(); 5128 5129 return OMPParallelSectionsDirective::Create( 5130 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 5131 } 5132 5133 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 5134 Stmt *AStmt, SourceLocation StartLoc, 5135 SourceLocation EndLoc) { 5136 if (!AStmt) 5137 return StmtError(); 5138 5139 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5140 // 1.2.2 OpenMP Language Terminology 5141 // Structured block - An executable statement with a single entry at the 5142 // top and a single exit at the bottom. 5143 // The point of exit cannot be a branch out of the structured block. 5144 // longjmp() and throw() must not violate the entry/exit criteria. 5145 CS->getCapturedDecl()->setNothrow(); 5146 5147 getCurFunction()->setHasBranchProtectedScope(); 5148 5149 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5150 DSAStack->isCancelRegion()); 5151 } 5152 5153 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 5154 SourceLocation EndLoc) { 5155 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 5156 } 5157 5158 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 5159 SourceLocation EndLoc) { 5160 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 5161 } 5162 5163 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 5164 SourceLocation EndLoc) { 5165 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 5166 } 5167 5168 StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt, 5169 SourceLocation StartLoc, 5170 SourceLocation EndLoc) { 5171 if (!AStmt) 5172 return StmtError(); 5173 5174 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5175 5176 getCurFunction()->setHasBranchProtectedScope(); 5177 5178 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, AStmt); 5179 } 5180 5181 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 5182 SourceLocation StartLoc, 5183 SourceLocation EndLoc) { 5184 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 5185 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 5186 } 5187 5188 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 5189 Stmt *AStmt, 5190 SourceLocation StartLoc, 5191 SourceLocation EndLoc) { 5192 OMPClause *DependFound = nullptr; 5193 OMPClause *DependSourceClause = nullptr; 5194 OMPClause *DependSinkClause = nullptr; 5195 bool ErrorFound = false; 5196 OMPThreadsClause *TC = nullptr; 5197 OMPSIMDClause *SC = nullptr; 5198 for (auto *C : Clauses) { 5199 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 5200 DependFound = C; 5201 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 5202 if (DependSourceClause) { 5203 Diag(C->getLocStart(), diag::err_omp_more_one_clause) 5204 << getOpenMPDirectiveName(OMPD_ordered) 5205 << getOpenMPClauseName(OMPC_depend) << 2; 5206 ErrorFound = true; 5207 } else 5208 DependSourceClause = C; 5209 if (DependSinkClause) { 5210 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5211 << 0; 5212 ErrorFound = true; 5213 } 5214 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 5215 if (DependSourceClause) { 5216 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5217 << 1; 5218 ErrorFound = true; 5219 } 5220 DependSinkClause = C; 5221 } 5222 } else if (C->getClauseKind() == OMPC_threads) 5223 TC = cast<OMPThreadsClause>(C); 5224 else if (C->getClauseKind() == OMPC_simd) 5225 SC = cast<OMPSIMDClause>(C); 5226 } 5227 if (!ErrorFound && !SC && 5228 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 5229 // OpenMP [2.8.1,simd Construct, Restrictions] 5230 // An ordered construct with the simd clause is the only OpenMP construct 5231 // that can appear in the simd region. 5232 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 5233 ErrorFound = true; 5234 } else if (DependFound && (TC || SC)) { 5235 Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd) 5236 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 5237 ErrorFound = true; 5238 } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) { 5239 Diag(DependFound->getLocStart(), 5240 diag::err_omp_ordered_directive_without_param); 5241 ErrorFound = true; 5242 } else if (TC || Clauses.empty()) { 5243 if (auto *Param = DSAStack->getParentOrderedRegionParam()) { 5244 SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc; 5245 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 5246 << (TC != nullptr); 5247 Diag(Param->getLocStart(), diag::note_omp_ordered_param); 5248 ErrorFound = true; 5249 } 5250 } 5251 if ((!AStmt && !DependFound) || ErrorFound) 5252 return StmtError(); 5253 5254 if (AStmt) { 5255 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5256 5257 getCurFunction()->setHasBranchProtectedScope(); 5258 } 5259 5260 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5261 } 5262 5263 namespace { 5264 /// \brief Helper class for checking expression in 'omp atomic [update]' 5265 /// construct. 5266 class OpenMPAtomicUpdateChecker { 5267 /// \brief Error results for atomic update expressions. 5268 enum ExprAnalysisErrorCode { 5269 /// \brief A statement is not an expression statement. 5270 NotAnExpression, 5271 /// \brief Expression is not builtin binary or unary operation. 5272 NotABinaryOrUnaryExpression, 5273 /// \brief Unary operation is not post-/pre- increment/decrement operation. 5274 NotAnUnaryIncDecExpression, 5275 /// \brief An expression is not of scalar type. 5276 NotAScalarType, 5277 /// \brief A binary operation is not an assignment operation. 5278 NotAnAssignmentOp, 5279 /// \brief RHS part of the binary operation is not a binary expression. 5280 NotABinaryExpression, 5281 /// \brief RHS part is not additive/multiplicative/shift/biwise binary 5282 /// expression. 5283 NotABinaryOperator, 5284 /// \brief RHS binary operation does not have reference to the updated LHS 5285 /// part. 5286 NotAnUpdateExpression, 5287 /// \brief No errors is found. 5288 NoError 5289 }; 5290 /// \brief Reference to Sema. 5291 Sema &SemaRef; 5292 /// \brief A location for note diagnostics (when error is found). 5293 SourceLocation NoteLoc; 5294 /// \brief 'x' lvalue part of the source atomic expression. 5295 Expr *X; 5296 /// \brief 'expr' rvalue part of the source atomic expression. 5297 Expr *E; 5298 /// \brief Helper expression of the form 5299 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5300 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5301 Expr *UpdateExpr; 5302 /// \brief Is 'x' a LHS in a RHS part of full update expression. It is 5303 /// important for non-associative operations. 5304 bool IsXLHSInRHSPart; 5305 BinaryOperatorKind Op; 5306 SourceLocation OpLoc; 5307 /// \brief true if the source expression is a postfix unary operation, false 5308 /// if it is a prefix unary operation. 5309 bool IsPostfixUpdate; 5310 5311 public: 5312 OpenMPAtomicUpdateChecker(Sema &SemaRef) 5313 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 5314 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 5315 /// \brief Check specified statement that it is suitable for 'atomic update' 5316 /// constructs and extract 'x', 'expr' and Operation from the original 5317 /// expression. If DiagId and NoteId == 0, then only check is performed 5318 /// without error notification. 5319 /// \param DiagId Diagnostic which should be emitted if error is found. 5320 /// \param NoteId Diagnostic note for the main error message. 5321 /// \return true if statement is not an update expression, false otherwise. 5322 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 5323 /// \brief Return the 'x' lvalue part of the source atomic expression. 5324 Expr *getX() const { return X; } 5325 /// \brief Return the 'expr' rvalue part of the source atomic expression. 5326 Expr *getExpr() const { return E; } 5327 /// \brief Return the update expression used in calculation of the updated 5328 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5329 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5330 Expr *getUpdateExpr() const { return UpdateExpr; } 5331 /// \brief Return true if 'x' is LHS in RHS part of full update expression, 5332 /// false otherwise. 5333 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 5334 5335 /// \brief true if the source expression is a postfix unary operation, false 5336 /// if it is a prefix unary operation. 5337 bool isPostfixUpdate() const { return IsPostfixUpdate; } 5338 5339 private: 5340 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 5341 unsigned NoteId = 0); 5342 }; 5343 } // namespace 5344 5345 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 5346 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 5347 ExprAnalysisErrorCode ErrorFound = NoError; 5348 SourceLocation ErrorLoc, NoteLoc; 5349 SourceRange ErrorRange, NoteRange; 5350 // Allowed constructs are: 5351 // x = x binop expr; 5352 // x = expr binop x; 5353 if (AtomicBinOp->getOpcode() == BO_Assign) { 5354 X = AtomicBinOp->getLHS(); 5355 if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 5356 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 5357 if (AtomicInnerBinOp->isMultiplicativeOp() || 5358 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 5359 AtomicInnerBinOp->isBitwiseOp()) { 5360 Op = AtomicInnerBinOp->getOpcode(); 5361 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 5362 auto *LHS = AtomicInnerBinOp->getLHS(); 5363 auto *RHS = AtomicInnerBinOp->getRHS(); 5364 llvm::FoldingSetNodeID XId, LHSId, RHSId; 5365 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 5366 /*Canonical=*/true); 5367 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 5368 /*Canonical=*/true); 5369 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 5370 /*Canonical=*/true); 5371 if (XId == LHSId) { 5372 E = RHS; 5373 IsXLHSInRHSPart = true; 5374 } else if (XId == RHSId) { 5375 E = LHS; 5376 IsXLHSInRHSPart = false; 5377 } else { 5378 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5379 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5380 NoteLoc = X->getExprLoc(); 5381 NoteRange = X->getSourceRange(); 5382 ErrorFound = NotAnUpdateExpression; 5383 } 5384 } else { 5385 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5386 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5387 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 5388 NoteRange = SourceRange(NoteLoc, NoteLoc); 5389 ErrorFound = NotABinaryOperator; 5390 } 5391 } else { 5392 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 5393 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 5394 ErrorFound = NotABinaryExpression; 5395 } 5396 } else { 5397 ErrorLoc = AtomicBinOp->getExprLoc(); 5398 ErrorRange = AtomicBinOp->getSourceRange(); 5399 NoteLoc = AtomicBinOp->getOperatorLoc(); 5400 NoteRange = SourceRange(NoteLoc, NoteLoc); 5401 ErrorFound = NotAnAssignmentOp; 5402 } 5403 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5404 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5405 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5406 return true; 5407 } else if (SemaRef.CurContext->isDependentContext()) 5408 E = X = UpdateExpr = nullptr; 5409 return ErrorFound != NoError; 5410 } 5411 5412 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 5413 unsigned NoteId) { 5414 ExprAnalysisErrorCode ErrorFound = NoError; 5415 SourceLocation ErrorLoc, NoteLoc; 5416 SourceRange ErrorRange, NoteRange; 5417 // Allowed constructs are: 5418 // x++; 5419 // x--; 5420 // ++x; 5421 // --x; 5422 // x binop= expr; 5423 // x = x binop expr; 5424 // x = expr binop x; 5425 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 5426 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 5427 if (AtomicBody->getType()->isScalarType() || 5428 AtomicBody->isInstantiationDependent()) { 5429 if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 5430 AtomicBody->IgnoreParenImpCasts())) { 5431 // Check for Compound Assignment Operation 5432 Op = BinaryOperator::getOpForCompoundAssignment( 5433 AtomicCompAssignOp->getOpcode()); 5434 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 5435 E = AtomicCompAssignOp->getRHS(); 5436 X = AtomicCompAssignOp->getLHS(); 5437 IsXLHSInRHSPart = true; 5438 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 5439 AtomicBody->IgnoreParenImpCasts())) { 5440 // Check for Binary Operation 5441 if(checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 5442 return true; 5443 } else if (auto *AtomicUnaryOp = 5444 dyn_cast<UnaryOperator>(AtomicBody->IgnoreParenImpCasts())) { 5445 // Check for Unary Operation 5446 if (AtomicUnaryOp->isIncrementDecrementOp()) { 5447 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 5448 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 5449 OpLoc = AtomicUnaryOp->getOperatorLoc(); 5450 X = AtomicUnaryOp->getSubExpr(); 5451 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 5452 IsXLHSInRHSPart = true; 5453 } else { 5454 ErrorFound = NotAnUnaryIncDecExpression; 5455 ErrorLoc = AtomicUnaryOp->getExprLoc(); 5456 ErrorRange = AtomicUnaryOp->getSourceRange(); 5457 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 5458 NoteRange = SourceRange(NoteLoc, NoteLoc); 5459 } 5460 } else if (!AtomicBody->isInstantiationDependent()) { 5461 ErrorFound = NotABinaryOrUnaryExpression; 5462 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 5463 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 5464 } 5465 } else { 5466 ErrorFound = NotAScalarType; 5467 NoteLoc = ErrorLoc = AtomicBody->getLocStart(); 5468 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5469 } 5470 } else { 5471 ErrorFound = NotAnExpression; 5472 NoteLoc = ErrorLoc = S->getLocStart(); 5473 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5474 } 5475 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5476 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5477 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5478 return true; 5479 } else if (SemaRef.CurContext->isDependentContext()) 5480 E = X = UpdateExpr = nullptr; 5481 if (ErrorFound == NoError && E && X) { 5482 // Build an update expression of form 'OpaqueValueExpr(x) binop 5483 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 5484 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 5485 auto *OVEX = new (SemaRef.getASTContext()) 5486 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 5487 auto *OVEExpr = new (SemaRef.getASTContext()) 5488 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 5489 auto Update = 5490 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 5491 IsXLHSInRHSPart ? OVEExpr : OVEX); 5492 if (Update.isInvalid()) 5493 return true; 5494 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 5495 Sema::AA_Casting); 5496 if (Update.isInvalid()) 5497 return true; 5498 UpdateExpr = Update.get(); 5499 } 5500 return ErrorFound != NoError; 5501 } 5502 5503 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 5504 Stmt *AStmt, 5505 SourceLocation StartLoc, 5506 SourceLocation EndLoc) { 5507 if (!AStmt) 5508 return StmtError(); 5509 5510 auto CS = cast<CapturedStmt>(AStmt); 5511 // 1.2.2 OpenMP Language Terminology 5512 // Structured block - An executable statement with a single entry at the 5513 // top and a single exit at the bottom. 5514 // The point of exit cannot be a branch out of the structured block. 5515 // longjmp() and throw() must not violate the entry/exit criteria. 5516 OpenMPClauseKind AtomicKind = OMPC_unknown; 5517 SourceLocation AtomicKindLoc; 5518 for (auto *C : Clauses) { 5519 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 5520 C->getClauseKind() == OMPC_update || 5521 C->getClauseKind() == OMPC_capture) { 5522 if (AtomicKind != OMPC_unknown) { 5523 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) 5524 << SourceRange(C->getLocStart(), C->getLocEnd()); 5525 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 5526 << getOpenMPClauseName(AtomicKind); 5527 } else { 5528 AtomicKind = C->getClauseKind(); 5529 AtomicKindLoc = C->getLocStart(); 5530 } 5531 } 5532 } 5533 5534 auto Body = CS->getCapturedStmt(); 5535 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 5536 Body = EWC->getSubExpr(); 5537 5538 Expr *X = nullptr; 5539 Expr *V = nullptr; 5540 Expr *E = nullptr; 5541 Expr *UE = nullptr; 5542 bool IsXLHSInRHSPart = false; 5543 bool IsPostfixUpdate = false; 5544 // OpenMP [2.12.6, atomic Construct] 5545 // In the next expressions: 5546 // * x and v (as applicable) are both l-value expressions with scalar type. 5547 // * During the execution of an atomic region, multiple syntactic 5548 // occurrences of x must designate the same storage location. 5549 // * Neither of v and expr (as applicable) may access the storage location 5550 // designated by x. 5551 // * Neither of x and expr (as applicable) may access the storage location 5552 // designated by v. 5553 // * expr is an expression with scalar type. 5554 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 5555 // * binop, binop=, ++, and -- are not overloaded operators. 5556 // * The expression x binop expr must be numerically equivalent to x binop 5557 // (expr). This requirement is satisfied if the operators in expr have 5558 // precedence greater than binop, or by using parentheses around expr or 5559 // subexpressions of expr. 5560 // * The expression expr binop x must be numerically equivalent to (expr) 5561 // binop x. This requirement is satisfied if the operators in expr have 5562 // precedence equal to or greater than binop, or by using parentheses around 5563 // expr or subexpressions of expr. 5564 // * For forms that allow multiple occurrences of x, the number of times 5565 // that x is evaluated is unspecified. 5566 if (AtomicKind == OMPC_read) { 5567 enum { 5568 NotAnExpression, 5569 NotAnAssignmentOp, 5570 NotAScalarType, 5571 NotAnLValue, 5572 NoError 5573 } ErrorFound = NoError; 5574 SourceLocation ErrorLoc, NoteLoc; 5575 SourceRange ErrorRange, NoteRange; 5576 // If clause is read: 5577 // v = x; 5578 if (auto AtomicBody = dyn_cast<Expr>(Body)) { 5579 auto AtomicBinOp = 5580 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5581 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5582 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 5583 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 5584 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 5585 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 5586 if (!X->isLValue() || !V->isLValue()) { 5587 auto NotLValueExpr = X->isLValue() ? V : X; 5588 ErrorFound = NotAnLValue; 5589 ErrorLoc = AtomicBinOp->getExprLoc(); 5590 ErrorRange = AtomicBinOp->getSourceRange(); 5591 NoteLoc = NotLValueExpr->getExprLoc(); 5592 NoteRange = NotLValueExpr->getSourceRange(); 5593 } 5594 } else if (!X->isInstantiationDependent() || 5595 !V->isInstantiationDependent()) { 5596 auto NotScalarExpr = 5597 (X->isInstantiationDependent() || X->getType()->isScalarType()) 5598 ? V 5599 : X; 5600 ErrorFound = NotAScalarType; 5601 ErrorLoc = AtomicBinOp->getExprLoc(); 5602 ErrorRange = AtomicBinOp->getSourceRange(); 5603 NoteLoc = NotScalarExpr->getExprLoc(); 5604 NoteRange = NotScalarExpr->getSourceRange(); 5605 } 5606 } else if (!AtomicBody->isInstantiationDependent()) { 5607 ErrorFound = NotAnAssignmentOp; 5608 ErrorLoc = AtomicBody->getExprLoc(); 5609 ErrorRange = AtomicBody->getSourceRange(); 5610 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5611 : AtomicBody->getExprLoc(); 5612 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5613 : AtomicBody->getSourceRange(); 5614 } 5615 } else { 5616 ErrorFound = NotAnExpression; 5617 NoteLoc = ErrorLoc = Body->getLocStart(); 5618 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5619 } 5620 if (ErrorFound != NoError) { 5621 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 5622 << ErrorRange; 5623 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 5624 << NoteRange; 5625 return StmtError(); 5626 } else if (CurContext->isDependentContext()) 5627 V = X = nullptr; 5628 } else if (AtomicKind == OMPC_write) { 5629 enum { 5630 NotAnExpression, 5631 NotAnAssignmentOp, 5632 NotAScalarType, 5633 NotAnLValue, 5634 NoError 5635 } ErrorFound = NoError; 5636 SourceLocation ErrorLoc, NoteLoc; 5637 SourceRange ErrorRange, NoteRange; 5638 // If clause is write: 5639 // x = expr; 5640 if (auto AtomicBody = dyn_cast<Expr>(Body)) { 5641 auto AtomicBinOp = 5642 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5643 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5644 X = AtomicBinOp->getLHS(); 5645 E = AtomicBinOp->getRHS(); 5646 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 5647 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 5648 if (!X->isLValue()) { 5649 ErrorFound = NotAnLValue; 5650 ErrorLoc = AtomicBinOp->getExprLoc(); 5651 ErrorRange = AtomicBinOp->getSourceRange(); 5652 NoteLoc = X->getExprLoc(); 5653 NoteRange = X->getSourceRange(); 5654 } 5655 } else if (!X->isInstantiationDependent() || 5656 !E->isInstantiationDependent()) { 5657 auto NotScalarExpr = 5658 (X->isInstantiationDependent() || X->getType()->isScalarType()) 5659 ? E 5660 : X; 5661 ErrorFound = NotAScalarType; 5662 ErrorLoc = AtomicBinOp->getExprLoc(); 5663 ErrorRange = AtomicBinOp->getSourceRange(); 5664 NoteLoc = NotScalarExpr->getExprLoc(); 5665 NoteRange = NotScalarExpr->getSourceRange(); 5666 } 5667 } else if (!AtomicBody->isInstantiationDependent()) { 5668 ErrorFound = NotAnAssignmentOp; 5669 ErrorLoc = AtomicBody->getExprLoc(); 5670 ErrorRange = AtomicBody->getSourceRange(); 5671 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5672 : AtomicBody->getExprLoc(); 5673 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5674 : AtomicBody->getSourceRange(); 5675 } 5676 } else { 5677 ErrorFound = NotAnExpression; 5678 NoteLoc = ErrorLoc = Body->getLocStart(); 5679 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5680 } 5681 if (ErrorFound != NoError) { 5682 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 5683 << ErrorRange; 5684 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 5685 << NoteRange; 5686 return StmtError(); 5687 } else if (CurContext->isDependentContext()) 5688 E = X = nullptr; 5689 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 5690 // If clause is update: 5691 // x++; 5692 // x--; 5693 // ++x; 5694 // --x; 5695 // x binop= expr; 5696 // x = x binop expr; 5697 // x = expr binop x; 5698 OpenMPAtomicUpdateChecker Checker(*this); 5699 if (Checker.checkStatement( 5700 Body, (AtomicKind == OMPC_update) 5701 ? diag::err_omp_atomic_update_not_expression_statement 5702 : diag::err_omp_atomic_not_expression_statement, 5703 diag::note_omp_atomic_update)) 5704 return StmtError(); 5705 if (!CurContext->isDependentContext()) { 5706 E = Checker.getExpr(); 5707 X = Checker.getX(); 5708 UE = Checker.getUpdateExpr(); 5709 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5710 } 5711 } else if (AtomicKind == OMPC_capture) { 5712 enum { 5713 NotAnAssignmentOp, 5714 NotACompoundStatement, 5715 NotTwoSubstatements, 5716 NotASpecificExpression, 5717 NoError 5718 } ErrorFound = NoError; 5719 SourceLocation ErrorLoc, NoteLoc; 5720 SourceRange ErrorRange, NoteRange; 5721 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 5722 // If clause is a capture: 5723 // v = x++; 5724 // v = x--; 5725 // v = ++x; 5726 // v = --x; 5727 // v = x binop= expr; 5728 // v = x = x binop expr; 5729 // v = x = expr binop x; 5730 auto *AtomicBinOp = 5731 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5732 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5733 V = AtomicBinOp->getLHS(); 5734 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 5735 OpenMPAtomicUpdateChecker Checker(*this); 5736 if (Checker.checkStatement( 5737 Body, diag::err_omp_atomic_capture_not_expression_statement, 5738 diag::note_omp_atomic_update)) 5739 return StmtError(); 5740 E = Checker.getExpr(); 5741 X = Checker.getX(); 5742 UE = Checker.getUpdateExpr(); 5743 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5744 IsPostfixUpdate = Checker.isPostfixUpdate(); 5745 } else if (!AtomicBody->isInstantiationDependent()) { 5746 ErrorLoc = AtomicBody->getExprLoc(); 5747 ErrorRange = AtomicBody->getSourceRange(); 5748 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5749 : AtomicBody->getExprLoc(); 5750 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5751 : AtomicBody->getSourceRange(); 5752 ErrorFound = NotAnAssignmentOp; 5753 } 5754 if (ErrorFound != NoError) { 5755 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 5756 << ErrorRange; 5757 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 5758 return StmtError(); 5759 } else if (CurContext->isDependentContext()) { 5760 UE = V = E = X = nullptr; 5761 } 5762 } else { 5763 // If clause is a capture: 5764 // { v = x; x = expr; } 5765 // { v = x; x++; } 5766 // { v = x; x--; } 5767 // { v = x; ++x; } 5768 // { v = x; --x; } 5769 // { v = x; x binop= expr; } 5770 // { v = x; x = x binop expr; } 5771 // { v = x; x = expr binop x; } 5772 // { x++; v = x; } 5773 // { x--; v = x; } 5774 // { ++x; v = x; } 5775 // { --x; v = x; } 5776 // { x binop= expr; v = x; } 5777 // { x = x binop expr; v = x; } 5778 // { x = expr binop x; v = x; } 5779 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 5780 // Check that this is { expr1; expr2; } 5781 if (CS->size() == 2) { 5782 auto *First = CS->body_front(); 5783 auto *Second = CS->body_back(); 5784 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 5785 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 5786 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 5787 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 5788 // Need to find what subexpression is 'v' and what is 'x'. 5789 OpenMPAtomicUpdateChecker Checker(*this); 5790 bool IsUpdateExprFound = !Checker.checkStatement(Second); 5791 BinaryOperator *BinOp = nullptr; 5792 if (IsUpdateExprFound) { 5793 BinOp = dyn_cast<BinaryOperator>(First); 5794 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 5795 } 5796 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 5797 // { v = x; x++; } 5798 // { v = x; x--; } 5799 // { v = x; ++x; } 5800 // { v = x; --x; } 5801 // { v = x; x binop= expr; } 5802 // { v = x; x = x binop expr; } 5803 // { v = x; x = expr binop x; } 5804 // Check that the first expression has form v = x. 5805 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 5806 llvm::FoldingSetNodeID XId, PossibleXId; 5807 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 5808 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 5809 IsUpdateExprFound = XId == PossibleXId; 5810 if (IsUpdateExprFound) { 5811 V = BinOp->getLHS(); 5812 X = Checker.getX(); 5813 E = Checker.getExpr(); 5814 UE = Checker.getUpdateExpr(); 5815 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5816 IsPostfixUpdate = true; 5817 } 5818 } 5819 if (!IsUpdateExprFound) { 5820 IsUpdateExprFound = !Checker.checkStatement(First); 5821 BinOp = nullptr; 5822 if (IsUpdateExprFound) { 5823 BinOp = dyn_cast<BinaryOperator>(Second); 5824 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 5825 } 5826 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 5827 // { x++; v = x; } 5828 // { x--; v = x; } 5829 // { ++x; v = x; } 5830 // { --x; v = x; } 5831 // { x binop= expr; v = x; } 5832 // { x = x binop expr; v = x; } 5833 // { x = expr binop x; v = x; } 5834 // Check that the second expression has form v = x. 5835 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 5836 llvm::FoldingSetNodeID XId, PossibleXId; 5837 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 5838 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 5839 IsUpdateExprFound = XId == PossibleXId; 5840 if (IsUpdateExprFound) { 5841 V = BinOp->getLHS(); 5842 X = Checker.getX(); 5843 E = Checker.getExpr(); 5844 UE = Checker.getUpdateExpr(); 5845 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5846 IsPostfixUpdate = false; 5847 } 5848 } 5849 } 5850 if (!IsUpdateExprFound) { 5851 // { v = x; x = expr; } 5852 auto *FirstExpr = dyn_cast<Expr>(First); 5853 auto *SecondExpr = dyn_cast<Expr>(Second); 5854 if (!FirstExpr || !SecondExpr || 5855 !(FirstExpr->isInstantiationDependent() || 5856 SecondExpr->isInstantiationDependent())) { 5857 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 5858 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 5859 ErrorFound = NotAnAssignmentOp; 5860 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 5861 : First->getLocStart(); 5862 NoteRange = ErrorRange = FirstBinOp 5863 ? FirstBinOp->getSourceRange() 5864 : SourceRange(ErrorLoc, ErrorLoc); 5865 } else { 5866 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 5867 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 5868 ErrorFound = NotAnAssignmentOp; 5869 NoteLoc = ErrorLoc = SecondBinOp 5870 ? SecondBinOp->getOperatorLoc() 5871 : Second->getLocStart(); 5872 NoteRange = ErrorRange = 5873 SecondBinOp ? SecondBinOp->getSourceRange() 5874 : SourceRange(ErrorLoc, ErrorLoc); 5875 } else { 5876 auto *PossibleXRHSInFirst = 5877 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 5878 auto *PossibleXLHSInSecond = 5879 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 5880 llvm::FoldingSetNodeID X1Id, X2Id; 5881 PossibleXRHSInFirst->Profile(X1Id, Context, 5882 /*Canonical=*/true); 5883 PossibleXLHSInSecond->Profile(X2Id, Context, 5884 /*Canonical=*/true); 5885 IsUpdateExprFound = X1Id == X2Id; 5886 if (IsUpdateExprFound) { 5887 V = FirstBinOp->getLHS(); 5888 X = SecondBinOp->getLHS(); 5889 E = SecondBinOp->getRHS(); 5890 UE = nullptr; 5891 IsXLHSInRHSPart = false; 5892 IsPostfixUpdate = true; 5893 } else { 5894 ErrorFound = NotASpecificExpression; 5895 ErrorLoc = FirstBinOp->getExprLoc(); 5896 ErrorRange = FirstBinOp->getSourceRange(); 5897 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 5898 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 5899 } 5900 } 5901 } 5902 } 5903 } 5904 } else { 5905 NoteLoc = ErrorLoc = Body->getLocStart(); 5906 NoteRange = ErrorRange = 5907 SourceRange(Body->getLocStart(), Body->getLocStart()); 5908 ErrorFound = NotTwoSubstatements; 5909 } 5910 } else { 5911 NoteLoc = ErrorLoc = Body->getLocStart(); 5912 NoteRange = ErrorRange = 5913 SourceRange(Body->getLocStart(), Body->getLocStart()); 5914 ErrorFound = NotACompoundStatement; 5915 } 5916 if (ErrorFound != NoError) { 5917 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 5918 << ErrorRange; 5919 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 5920 return StmtError(); 5921 } else if (CurContext->isDependentContext()) { 5922 UE = V = E = X = nullptr; 5923 } 5924 } 5925 } 5926 5927 getCurFunction()->setHasBranchProtectedScope(); 5928 5929 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5930 X, V, E, UE, IsXLHSInRHSPart, 5931 IsPostfixUpdate); 5932 } 5933 5934 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 5935 Stmt *AStmt, 5936 SourceLocation StartLoc, 5937 SourceLocation EndLoc) { 5938 if (!AStmt) 5939 return StmtError(); 5940 5941 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5942 // 1.2.2 OpenMP Language Terminology 5943 // Structured block - An executable statement with a single entry at the 5944 // top and a single exit at the bottom. 5945 // The point of exit cannot be a branch out of the structured block. 5946 // longjmp() and throw() must not violate the entry/exit criteria. 5947 CS->getCapturedDecl()->setNothrow(); 5948 5949 // OpenMP [2.16, Nesting of Regions] 5950 // If specified, a teams construct must be contained within a target 5951 // construct. That target construct must contain no statements or directives 5952 // outside of the teams construct. 5953 if (DSAStack->hasInnerTeamsRegion()) { 5954 auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true); 5955 bool OMPTeamsFound = true; 5956 if (auto *CS = dyn_cast<CompoundStmt>(S)) { 5957 auto I = CS->body_begin(); 5958 while (I != CS->body_end()) { 5959 auto OED = dyn_cast<OMPExecutableDirective>(*I); 5960 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { 5961 OMPTeamsFound = false; 5962 break; 5963 } 5964 ++I; 5965 } 5966 assert(I != CS->body_end() && "Not found statement"); 5967 S = *I; 5968 } 5969 if (!OMPTeamsFound) { 5970 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 5971 Diag(DSAStack->getInnerTeamsRegionLoc(), 5972 diag::note_omp_nested_teams_construct_here); 5973 Diag(S->getLocStart(), diag::note_omp_nested_statement_here) 5974 << isa<OMPExecutableDirective>(S); 5975 return StmtError(); 5976 } 5977 } 5978 5979 getCurFunction()->setHasBranchProtectedScope(); 5980 5981 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5982 } 5983 5984 StmtResult 5985 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 5986 Stmt *AStmt, SourceLocation StartLoc, 5987 SourceLocation EndLoc) { 5988 if (!AStmt) 5989 return StmtError(); 5990 5991 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5992 // 1.2.2 OpenMP Language Terminology 5993 // Structured block - An executable statement with a single entry at the 5994 // top and a single exit at the bottom. 5995 // The point of exit cannot be a branch out of the structured block. 5996 // longjmp() and throw() must not violate the entry/exit criteria. 5997 CS->getCapturedDecl()->setNothrow(); 5998 5999 getCurFunction()->setHasBranchProtectedScope(); 6000 6001 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6002 AStmt); 6003 } 6004 6005 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 6006 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6007 SourceLocation EndLoc, 6008 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6009 if (!AStmt) 6010 return StmtError(); 6011 6012 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6013 // 1.2.2 OpenMP Language Terminology 6014 // Structured block - An executable statement with a single entry at the 6015 // top and a single exit at the bottom. 6016 // The point of exit cannot be a branch out of the structured block. 6017 // longjmp() and throw() must not violate the entry/exit criteria. 6018 CS->getCapturedDecl()->setNothrow(); 6019 6020 OMPLoopDirective::HelperExprs B; 6021 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6022 // define the nested loops number. 6023 unsigned NestedLoopCount = 6024 CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 6025 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6026 VarsWithImplicitDSA, B); 6027 if (NestedLoopCount == 0) 6028 return StmtError(); 6029 6030 assert((CurContext->isDependentContext() || B.builtAll()) && 6031 "omp target parallel for loop exprs were not built"); 6032 6033 if (!CurContext->isDependentContext()) { 6034 // Finalize the clauses that need pre-built expressions for CodeGen. 6035 for (auto C : Clauses) { 6036 if (auto LC = dyn_cast<OMPLinearClause>(C)) 6037 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6038 B.NumIterations, *this, CurScope)) 6039 return StmtError(); 6040 } 6041 } 6042 6043 getCurFunction()->setHasBranchProtectedScope(); 6044 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 6045 NestedLoopCount, Clauses, AStmt, 6046 B, DSAStack->isCancelRegion()); 6047 } 6048 6049 /// \brief Check for existence of a map clause in the list of clauses. 6050 static bool HasMapClause(ArrayRef<OMPClause *> Clauses) { 6051 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end(); 6052 I != E; ++I) { 6053 if (*I != nullptr && (*I)->getClauseKind() == OMPC_map) { 6054 return true; 6055 } 6056 } 6057 6058 return false; 6059 } 6060 6061 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 6062 Stmt *AStmt, 6063 SourceLocation StartLoc, 6064 SourceLocation EndLoc) { 6065 if (!AStmt) 6066 return StmtError(); 6067 6068 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6069 6070 // OpenMP [2.10.1, Restrictions, p. 97] 6071 // At least one map clause must appear on the directive. 6072 if (!HasMapClause(Clauses)) { 6073 Diag(StartLoc, diag::err_omp_no_map_for_directive) << 6074 getOpenMPDirectiveName(OMPD_target_data); 6075 return StmtError(); 6076 } 6077 6078 getCurFunction()->setHasBranchProtectedScope(); 6079 6080 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 6081 AStmt); 6082 } 6083 6084 StmtResult 6085 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 6086 SourceLocation StartLoc, 6087 SourceLocation EndLoc) { 6088 // OpenMP [2.10.2, Restrictions, p. 99] 6089 // At least one map clause must appear on the directive. 6090 if (!HasMapClause(Clauses)) { 6091 Diag(StartLoc, diag::err_omp_no_map_for_directive) 6092 << getOpenMPDirectiveName(OMPD_target_enter_data); 6093 return StmtError(); 6094 } 6095 6096 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, 6097 Clauses); 6098 } 6099 6100 StmtResult 6101 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 6102 SourceLocation StartLoc, 6103 SourceLocation EndLoc) { 6104 // OpenMP [2.10.3, Restrictions, p. 102] 6105 // At least one map clause must appear on the directive. 6106 if (!HasMapClause(Clauses)) { 6107 Diag(StartLoc, diag::err_omp_no_map_for_directive) 6108 << getOpenMPDirectiveName(OMPD_target_exit_data); 6109 return StmtError(); 6110 } 6111 6112 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses); 6113 } 6114 6115 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 6116 Stmt *AStmt, SourceLocation StartLoc, 6117 SourceLocation EndLoc) { 6118 if (!AStmt) 6119 return StmtError(); 6120 6121 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6122 // 1.2.2 OpenMP Language Terminology 6123 // Structured block - An executable statement with a single entry at the 6124 // top and a single exit at the bottom. 6125 // The point of exit cannot be a branch out of the structured block. 6126 // longjmp() and throw() must not violate the entry/exit criteria. 6127 CS->getCapturedDecl()->setNothrow(); 6128 6129 getCurFunction()->setHasBranchProtectedScope(); 6130 6131 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6132 } 6133 6134 StmtResult 6135 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 6136 SourceLocation EndLoc, 6137 OpenMPDirectiveKind CancelRegion) { 6138 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for && 6139 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) { 6140 Diag(StartLoc, diag::err_omp_wrong_cancel_region) 6141 << getOpenMPDirectiveName(CancelRegion); 6142 return StmtError(); 6143 } 6144 if (DSAStack->isParentNowaitRegion()) { 6145 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 6146 return StmtError(); 6147 } 6148 if (DSAStack->isParentOrderedRegion()) { 6149 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 6150 return StmtError(); 6151 } 6152 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 6153 CancelRegion); 6154 } 6155 6156 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 6157 SourceLocation StartLoc, 6158 SourceLocation EndLoc, 6159 OpenMPDirectiveKind CancelRegion) { 6160 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for && 6161 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) { 6162 Diag(StartLoc, diag::err_omp_wrong_cancel_region) 6163 << getOpenMPDirectiveName(CancelRegion); 6164 return StmtError(); 6165 } 6166 if (DSAStack->isParentNowaitRegion()) { 6167 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 6168 return StmtError(); 6169 } 6170 if (DSAStack->isParentOrderedRegion()) { 6171 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 6172 return StmtError(); 6173 } 6174 DSAStack->setParentCancelRegion(/*Cancel=*/true); 6175 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6176 CancelRegion); 6177 } 6178 6179 static bool checkGrainsizeNumTasksClauses(Sema &S, 6180 ArrayRef<OMPClause *> Clauses) { 6181 OMPClause *PrevClause = nullptr; 6182 bool ErrorFound = false; 6183 for (auto *C : Clauses) { 6184 if (C->getClauseKind() == OMPC_grainsize || 6185 C->getClauseKind() == OMPC_num_tasks) { 6186 if (!PrevClause) 6187 PrevClause = C; 6188 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 6189 S.Diag(C->getLocStart(), 6190 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 6191 << getOpenMPClauseName(C->getClauseKind()) 6192 << getOpenMPClauseName(PrevClause->getClauseKind()); 6193 S.Diag(PrevClause->getLocStart(), 6194 diag::note_omp_previous_grainsize_num_tasks) 6195 << getOpenMPClauseName(PrevClause->getClauseKind()); 6196 ErrorFound = true; 6197 } 6198 } 6199 } 6200 return ErrorFound; 6201 } 6202 6203 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 6204 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6205 SourceLocation EndLoc, 6206 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6207 if (!AStmt) 6208 return StmtError(); 6209 6210 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6211 OMPLoopDirective::HelperExprs B; 6212 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6213 // define the nested loops number. 6214 unsigned NestedLoopCount = 6215 CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 6216 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6217 VarsWithImplicitDSA, B); 6218 if (NestedLoopCount == 0) 6219 return StmtError(); 6220 6221 assert((CurContext->isDependentContext() || B.builtAll()) && 6222 "omp for loop exprs were not built"); 6223 6224 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6225 // The grainsize clause and num_tasks clause are mutually exclusive and may 6226 // not appear on the same taskloop directive. 6227 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6228 return StmtError(); 6229 6230 getCurFunction()->setHasBranchProtectedScope(); 6231 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 6232 NestedLoopCount, Clauses, AStmt, B); 6233 } 6234 6235 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 6236 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6237 SourceLocation EndLoc, 6238 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6239 if (!AStmt) 6240 return StmtError(); 6241 6242 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6243 OMPLoopDirective::HelperExprs B; 6244 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6245 // define the nested loops number. 6246 unsigned NestedLoopCount = 6247 CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 6248 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6249 VarsWithImplicitDSA, B); 6250 if (NestedLoopCount == 0) 6251 return StmtError(); 6252 6253 assert((CurContext->isDependentContext() || B.builtAll()) && 6254 "omp for loop exprs were not built"); 6255 6256 if (!CurContext->isDependentContext()) { 6257 // Finalize the clauses that need pre-built expressions for CodeGen. 6258 for (auto C : Clauses) { 6259 if (auto LC = dyn_cast<OMPLinearClause>(C)) 6260 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6261 B.NumIterations, *this, CurScope)) 6262 return StmtError(); 6263 } 6264 } 6265 6266 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6267 // The grainsize clause and num_tasks clause are mutually exclusive and may 6268 // not appear on the same taskloop directive. 6269 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6270 return StmtError(); 6271 6272 getCurFunction()->setHasBranchProtectedScope(); 6273 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 6274 NestedLoopCount, Clauses, AStmt, B); 6275 } 6276 6277 StmtResult Sema::ActOnOpenMPDistributeDirective( 6278 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6279 SourceLocation EndLoc, 6280 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6281 if (!AStmt) 6282 return StmtError(); 6283 6284 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6285 OMPLoopDirective::HelperExprs B; 6286 // In presence of clause 'collapse' with number of loops, it will 6287 // define the nested loops number. 6288 unsigned NestedLoopCount = 6289 CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 6290 nullptr /*ordered not a clause on distribute*/, AStmt, 6291 *this, *DSAStack, VarsWithImplicitDSA, B); 6292 if (NestedLoopCount == 0) 6293 return StmtError(); 6294 6295 assert((CurContext->isDependentContext() || B.builtAll()) && 6296 "omp for loop exprs were not built"); 6297 6298 getCurFunction()->setHasBranchProtectedScope(); 6299 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 6300 NestedLoopCount, Clauses, AStmt, B); 6301 } 6302 6303 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 6304 SourceLocation StartLoc, 6305 SourceLocation LParenLoc, 6306 SourceLocation EndLoc) { 6307 OMPClause *Res = nullptr; 6308 switch (Kind) { 6309 case OMPC_final: 6310 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 6311 break; 6312 case OMPC_num_threads: 6313 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 6314 break; 6315 case OMPC_safelen: 6316 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 6317 break; 6318 case OMPC_simdlen: 6319 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 6320 break; 6321 case OMPC_collapse: 6322 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 6323 break; 6324 case OMPC_ordered: 6325 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 6326 break; 6327 case OMPC_device: 6328 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 6329 break; 6330 case OMPC_num_teams: 6331 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 6332 break; 6333 case OMPC_thread_limit: 6334 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 6335 break; 6336 case OMPC_priority: 6337 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 6338 break; 6339 case OMPC_grainsize: 6340 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 6341 break; 6342 case OMPC_num_tasks: 6343 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 6344 break; 6345 case OMPC_hint: 6346 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 6347 break; 6348 case OMPC_if: 6349 case OMPC_default: 6350 case OMPC_proc_bind: 6351 case OMPC_schedule: 6352 case OMPC_private: 6353 case OMPC_firstprivate: 6354 case OMPC_lastprivate: 6355 case OMPC_shared: 6356 case OMPC_reduction: 6357 case OMPC_linear: 6358 case OMPC_aligned: 6359 case OMPC_copyin: 6360 case OMPC_copyprivate: 6361 case OMPC_nowait: 6362 case OMPC_untied: 6363 case OMPC_mergeable: 6364 case OMPC_threadprivate: 6365 case OMPC_flush: 6366 case OMPC_read: 6367 case OMPC_write: 6368 case OMPC_update: 6369 case OMPC_capture: 6370 case OMPC_seq_cst: 6371 case OMPC_depend: 6372 case OMPC_threads: 6373 case OMPC_simd: 6374 case OMPC_map: 6375 case OMPC_nogroup: 6376 case OMPC_dist_schedule: 6377 case OMPC_defaultmap: 6378 case OMPC_unknown: 6379 llvm_unreachable("Clause is not allowed."); 6380 } 6381 return Res; 6382 } 6383 6384 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 6385 Expr *Condition, SourceLocation StartLoc, 6386 SourceLocation LParenLoc, 6387 SourceLocation NameModifierLoc, 6388 SourceLocation ColonLoc, 6389 SourceLocation EndLoc) { 6390 Expr *ValExpr = Condition; 6391 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 6392 !Condition->isInstantiationDependent() && 6393 !Condition->containsUnexpandedParameterPack()) { 6394 ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(), 6395 Condition->getExprLoc(), Condition); 6396 if (Val.isInvalid()) 6397 return nullptr; 6398 6399 ValExpr = Val.get(); 6400 } 6401 6402 return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc, 6403 NameModifierLoc, ColonLoc, EndLoc); 6404 } 6405 6406 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 6407 SourceLocation StartLoc, 6408 SourceLocation LParenLoc, 6409 SourceLocation EndLoc) { 6410 Expr *ValExpr = Condition; 6411 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 6412 !Condition->isInstantiationDependent() && 6413 !Condition->containsUnexpandedParameterPack()) { 6414 ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(), 6415 Condition->getExprLoc(), Condition); 6416 if (Val.isInvalid()) 6417 return nullptr; 6418 6419 ValExpr = Val.get(); 6420 } 6421 6422 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 6423 } 6424 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 6425 Expr *Op) { 6426 if (!Op) 6427 return ExprError(); 6428 6429 class IntConvertDiagnoser : public ICEConvertDiagnoser { 6430 public: 6431 IntConvertDiagnoser() 6432 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 6433 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 6434 QualType T) override { 6435 return S.Diag(Loc, diag::err_omp_not_integral) << T; 6436 } 6437 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 6438 QualType T) override { 6439 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 6440 } 6441 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 6442 QualType T, 6443 QualType ConvTy) override { 6444 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 6445 } 6446 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 6447 QualType ConvTy) override { 6448 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 6449 << ConvTy->isEnumeralType() << ConvTy; 6450 } 6451 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 6452 QualType T) override { 6453 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 6454 } 6455 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 6456 QualType ConvTy) override { 6457 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 6458 << ConvTy->isEnumeralType() << ConvTy; 6459 } 6460 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 6461 QualType) override { 6462 llvm_unreachable("conversion functions are permitted"); 6463 } 6464 } ConvertDiagnoser; 6465 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 6466 } 6467 6468 static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 6469 OpenMPClauseKind CKind, 6470 bool StrictlyPositive) { 6471 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 6472 !ValExpr->isInstantiationDependent()) { 6473 SourceLocation Loc = ValExpr->getExprLoc(); 6474 ExprResult Value = 6475 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 6476 if (Value.isInvalid()) 6477 return false; 6478 6479 ValExpr = Value.get(); 6480 // The expression must evaluate to a non-negative integer value. 6481 llvm::APSInt Result; 6482 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 6483 Result.isSigned() && 6484 !((!StrictlyPositive && Result.isNonNegative()) || 6485 (StrictlyPositive && Result.isStrictlyPositive()))) { 6486 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 6487 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 6488 << ValExpr->getSourceRange(); 6489 return false; 6490 } 6491 } 6492 return true; 6493 } 6494 6495 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 6496 SourceLocation StartLoc, 6497 SourceLocation LParenLoc, 6498 SourceLocation EndLoc) { 6499 Expr *ValExpr = NumThreads; 6500 6501 // OpenMP [2.5, Restrictions] 6502 // The num_threads expression must evaluate to a positive integer value. 6503 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 6504 /*StrictlyPositive=*/true)) 6505 return nullptr; 6506 6507 return new (Context) 6508 OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc); 6509 } 6510 6511 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 6512 OpenMPClauseKind CKind, 6513 bool StrictlyPositive) { 6514 if (!E) 6515 return ExprError(); 6516 if (E->isValueDependent() || E->isTypeDependent() || 6517 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 6518 return E; 6519 llvm::APSInt Result; 6520 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 6521 if (ICE.isInvalid()) 6522 return ExprError(); 6523 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 6524 (!StrictlyPositive && !Result.isNonNegative())) { 6525 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 6526 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 6527 << E->getSourceRange(); 6528 return ExprError(); 6529 } 6530 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 6531 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 6532 << E->getSourceRange(); 6533 return ExprError(); 6534 } 6535 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 6536 DSAStack->setAssociatedLoops(Result.getExtValue()); 6537 else if (CKind == OMPC_ordered) 6538 DSAStack->setAssociatedLoops(Result.getExtValue()); 6539 return ICE; 6540 } 6541 6542 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 6543 SourceLocation LParenLoc, 6544 SourceLocation EndLoc) { 6545 // OpenMP [2.8.1, simd construct, Description] 6546 // The parameter of the safelen clause must be a constant 6547 // positive integer expression. 6548 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 6549 if (Safelen.isInvalid()) 6550 return nullptr; 6551 return new (Context) 6552 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 6553 } 6554 6555 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 6556 SourceLocation LParenLoc, 6557 SourceLocation EndLoc) { 6558 // OpenMP [2.8.1, simd construct, Description] 6559 // The parameter of the simdlen clause must be a constant 6560 // positive integer expression. 6561 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 6562 if (Simdlen.isInvalid()) 6563 return nullptr; 6564 return new (Context) 6565 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 6566 } 6567 6568 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 6569 SourceLocation StartLoc, 6570 SourceLocation LParenLoc, 6571 SourceLocation EndLoc) { 6572 // OpenMP [2.7.1, loop construct, Description] 6573 // OpenMP [2.8.1, simd construct, Description] 6574 // OpenMP [2.9.6, distribute construct, Description] 6575 // The parameter of the collapse clause must be a constant 6576 // positive integer expression. 6577 ExprResult NumForLoopsResult = 6578 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 6579 if (NumForLoopsResult.isInvalid()) 6580 return nullptr; 6581 return new (Context) 6582 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 6583 } 6584 6585 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 6586 SourceLocation EndLoc, 6587 SourceLocation LParenLoc, 6588 Expr *NumForLoops) { 6589 // OpenMP [2.7.1, loop construct, Description] 6590 // OpenMP [2.8.1, simd construct, Description] 6591 // OpenMP [2.9.6, distribute construct, Description] 6592 // The parameter of the ordered clause must be a constant 6593 // positive integer expression if any. 6594 if (NumForLoops && LParenLoc.isValid()) { 6595 ExprResult NumForLoopsResult = 6596 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 6597 if (NumForLoopsResult.isInvalid()) 6598 return nullptr; 6599 NumForLoops = NumForLoopsResult.get(); 6600 } else 6601 NumForLoops = nullptr; 6602 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops); 6603 return new (Context) 6604 OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc); 6605 } 6606 6607 OMPClause *Sema::ActOnOpenMPSimpleClause( 6608 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 6609 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 6610 OMPClause *Res = nullptr; 6611 switch (Kind) { 6612 case OMPC_default: 6613 Res = 6614 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 6615 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 6616 break; 6617 case OMPC_proc_bind: 6618 Res = ActOnOpenMPProcBindClause( 6619 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 6620 LParenLoc, EndLoc); 6621 break; 6622 case OMPC_if: 6623 case OMPC_final: 6624 case OMPC_num_threads: 6625 case OMPC_safelen: 6626 case OMPC_simdlen: 6627 case OMPC_collapse: 6628 case OMPC_schedule: 6629 case OMPC_private: 6630 case OMPC_firstprivate: 6631 case OMPC_lastprivate: 6632 case OMPC_shared: 6633 case OMPC_reduction: 6634 case OMPC_linear: 6635 case OMPC_aligned: 6636 case OMPC_copyin: 6637 case OMPC_copyprivate: 6638 case OMPC_ordered: 6639 case OMPC_nowait: 6640 case OMPC_untied: 6641 case OMPC_mergeable: 6642 case OMPC_threadprivate: 6643 case OMPC_flush: 6644 case OMPC_read: 6645 case OMPC_write: 6646 case OMPC_update: 6647 case OMPC_capture: 6648 case OMPC_seq_cst: 6649 case OMPC_depend: 6650 case OMPC_device: 6651 case OMPC_threads: 6652 case OMPC_simd: 6653 case OMPC_map: 6654 case OMPC_num_teams: 6655 case OMPC_thread_limit: 6656 case OMPC_priority: 6657 case OMPC_grainsize: 6658 case OMPC_nogroup: 6659 case OMPC_num_tasks: 6660 case OMPC_hint: 6661 case OMPC_dist_schedule: 6662 case OMPC_defaultmap: 6663 case OMPC_unknown: 6664 llvm_unreachable("Clause is not allowed."); 6665 } 6666 return Res; 6667 } 6668 6669 static std::string 6670 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 6671 ArrayRef<unsigned> Exclude = llvm::None) { 6672 std::string Values; 6673 unsigned Bound = Last >= 2 ? Last - 2 : 0; 6674 unsigned Skipped = Exclude.size(); 6675 auto S = Exclude.begin(), E = Exclude.end(); 6676 for (unsigned i = First; i < Last; ++i) { 6677 if (std::find(S, E, i) != E) { 6678 --Skipped; 6679 continue; 6680 } 6681 Values += "'"; 6682 Values += getOpenMPSimpleClauseTypeName(K, i); 6683 Values += "'"; 6684 if (i == Bound - Skipped) 6685 Values += " or "; 6686 else if (i != Bound + 1 - Skipped) 6687 Values += ", "; 6688 } 6689 return Values; 6690 } 6691 6692 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 6693 SourceLocation KindKwLoc, 6694 SourceLocation StartLoc, 6695 SourceLocation LParenLoc, 6696 SourceLocation EndLoc) { 6697 if (Kind == OMPC_DEFAULT_unknown) { 6698 static_assert(OMPC_DEFAULT_unknown > 0, 6699 "OMPC_DEFAULT_unknown not greater than 0"); 6700 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 6701 << getListOfPossibleValues(OMPC_default, /*First=*/0, 6702 /*Last=*/OMPC_DEFAULT_unknown) 6703 << getOpenMPClauseName(OMPC_default); 6704 return nullptr; 6705 } 6706 switch (Kind) { 6707 case OMPC_DEFAULT_none: 6708 DSAStack->setDefaultDSANone(KindKwLoc); 6709 break; 6710 case OMPC_DEFAULT_shared: 6711 DSAStack->setDefaultDSAShared(KindKwLoc); 6712 break; 6713 case OMPC_DEFAULT_unknown: 6714 llvm_unreachable("Clause kind is not allowed."); 6715 break; 6716 } 6717 return new (Context) 6718 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 6719 } 6720 6721 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 6722 SourceLocation KindKwLoc, 6723 SourceLocation StartLoc, 6724 SourceLocation LParenLoc, 6725 SourceLocation EndLoc) { 6726 if (Kind == OMPC_PROC_BIND_unknown) { 6727 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 6728 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 6729 /*Last=*/OMPC_PROC_BIND_unknown) 6730 << getOpenMPClauseName(OMPC_proc_bind); 6731 return nullptr; 6732 } 6733 return new (Context) 6734 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 6735 } 6736 6737 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 6738 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 6739 SourceLocation StartLoc, SourceLocation LParenLoc, 6740 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 6741 SourceLocation EndLoc) { 6742 OMPClause *Res = nullptr; 6743 switch (Kind) { 6744 case OMPC_schedule: 6745 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 6746 assert(Argument.size() == NumberOfElements && 6747 ArgumentLoc.size() == NumberOfElements); 6748 Res = ActOnOpenMPScheduleClause( 6749 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 6750 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 6751 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 6752 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 6753 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 6754 break; 6755 case OMPC_if: 6756 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 6757 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 6758 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 6759 DelimLoc, EndLoc); 6760 break; 6761 case OMPC_dist_schedule: 6762 Res = ActOnOpenMPDistScheduleClause( 6763 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 6764 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 6765 break; 6766 case OMPC_defaultmap: 6767 enum { Modifier, DefaultmapKind }; 6768 Res = ActOnOpenMPDefaultmapClause( 6769 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 6770 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 6771 StartLoc, LParenLoc, ArgumentLoc[Modifier], 6772 ArgumentLoc[DefaultmapKind], EndLoc); 6773 break; 6774 case OMPC_final: 6775 case OMPC_num_threads: 6776 case OMPC_safelen: 6777 case OMPC_simdlen: 6778 case OMPC_collapse: 6779 case OMPC_default: 6780 case OMPC_proc_bind: 6781 case OMPC_private: 6782 case OMPC_firstprivate: 6783 case OMPC_lastprivate: 6784 case OMPC_shared: 6785 case OMPC_reduction: 6786 case OMPC_linear: 6787 case OMPC_aligned: 6788 case OMPC_copyin: 6789 case OMPC_copyprivate: 6790 case OMPC_ordered: 6791 case OMPC_nowait: 6792 case OMPC_untied: 6793 case OMPC_mergeable: 6794 case OMPC_threadprivate: 6795 case OMPC_flush: 6796 case OMPC_read: 6797 case OMPC_write: 6798 case OMPC_update: 6799 case OMPC_capture: 6800 case OMPC_seq_cst: 6801 case OMPC_depend: 6802 case OMPC_device: 6803 case OMPC_threads: 6804 case OMPC_simd: 6805 case OMPC_map: 6806 case OMPC_num_teams: 6807 case OMPC_thread_limit: 6808 case OMPC_priority: 6809 case OMPC_grainsize: 6810 case OMPC_nogroup: 6811 case OMPC_num_tasks: 6812 case OMPC_hint: 6813 case OMPC_unknown: 6814 llvm_unreachable("Clause is not allowed."); 6815 } 6816 return Res; 6817 } 6818 6819 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 6820 OpenMPScheduleClauseModifier M2, 6821 SourceLocation M1Loc, SourceLocation M2Loc) { 6822 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 6823 SmallVector<unsigned, 2> Excluded; 6824 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 6825 Excluded.push_back(M2); 6826 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 6827 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 6828 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 6829 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 6830 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 6831 << getListOfPossibleValues(OMPC_schedule, 6832 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 6833 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 6834 Excluded) 6835 << getOpenMPClauseName(OMPC_schedule); 6836 return true; 6837 } 6838 return false; 6839 } 6840 6841 OMPClause *Sema::ActOnOpenMPScheduleClause( 6842 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 6843 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 6844 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 6845 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 6846 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 6847 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 6848 return nullptr; 6849 // OpenMP, 2.7.1, Loop Construct, Restrictions 6850 // Either the monotonic modifier or the nonmonotonic modifier can be specified 6851 // but not both. 6852 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 6853 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 6854 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 6855 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 6856 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 6857 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 6858 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 6859 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 6860 return nullptr; 6861 } 6862 if (Kind == OMPC_SCHEDULE_unknown) { 6863 std::string Values; 6864 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 6865 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 6866 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 6867 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 6868 Exclude); 6869 } else { 6870 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 6871 /*Last=*/OMPC_SCHEDULE_unknown); 6872 } 6873 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 6874 << Values << getOpenMPClauseName(OMPC_schedule); 6875 return nullptr; 6876 } 6877 // OpenMP, 2.7.1, Loop Construct, Restrictions 6878 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 6879 // schedule(guided). 6880 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 6881 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 6882 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 6883 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 6884 diag::err_omp_schedule_nonmonotonic_static); 6885 return nullptr; 6886 } 6887 Expr *ValExpr = ChunkSize; 6888 Stmt *HelperValStmt = nullptr; 6889 if (ChunkSize) { 6890 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 6891 !ChunkSize->isInstantiationDependent() && 6892 !ChunkSize->containsUnexpandedParameterPack()) { 6893 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 6894 ExprResult Val = 6895 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 6896 if (Val.isInvalid()) 6897 return nullptr; 6898 6899 ValExpr = Val.get(); 6900 6901 // OpenMP [2.7.1, Restrictions] 6902 // chunk_size must be a loop invariant integer expression with a positive 6903 // value. 6904 llvm::APSInt Result; 6905 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 6906 if (Result.isSigned() && !Result.isStrictlyPositive()) { 6907 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 6908 << "schedule" << 1 << ChunkSize->getSourceRange(); 6909 return nullptr; 6910 } 6911 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 6912 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 6913 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 6914 HelperValStmt = buildPreInits(Context, Captures); 6915 } 6916 } 6917 } 6918 6919 return new (Context) 6920 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 6921 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 6922 } 6923 6924 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 6925 SourceLocation StartLoc, 6926 SourceLocation EndLoc) { 6927 OMPClause *Res = nullptr; 6928 switch (Kind) { 6929 case OMPC_ordered: 6930 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 6931 break; 6932 case OMPC_nowait: 6933 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 6934 break; 6935 case OMPC_untied: 6936 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 6937 break; 6938 case OMPC_mergeable: 6939 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 6940 break; 6941 case OMPC_read: 6942 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 6943 break; 6944 case OMPC_write: 6945 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 6946 break; 6947 case OMPC_update: 6948 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 6949 break; 6950 case OMPC_capture: 6951 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 6952 break; 6953 case OMPC_seq_cst: 6954 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 6955 break; 6956 case OMPC_threads: 6957 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 6958 break; 6959 case OMPC_simd: 6960 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 6961 break; 6962 case OMPC_nogroup: 6963 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 6964 break; 6965 case OMPC_if: 6966 case OMPC_final: 6967 case OMPC_num_threads: 6968 case OMPC_safelen: 6969 case OMPC_simdlen: 6970 case OMPC_collapse: 6971 case OMPC_schedule: 6972 case OMPC_private: 6973 case OMPC_firstprivate: 6974 case OMPC_lastprivate: 6975 case OMPC_shared: 6976 case OMPC_reduction: 6977 case OMPC_linear: 6978 case OMPC_aligned: 6979 case OMPC_copyin: 6980 case OMPC_copyprivate: 6981 case OMPC_default: 6982 case OMPC_proc_bind: 6983 case OMPC_threadprivate: 6984 case OMPC_flush: 6985 case OMPC_depend: 6986 case OMPC_device: 6987 case OMPC_map: 6988 case OMPC_num_teams: 6989 case OMPC_thread_limit: 6990 case OMPC_priority: 6991 case OMPC_grainsize: 6992 case OMPC_num_tasks: 6993 case OMPC_hint: 6994 case OMPC_dist_schedule: 6995 case OMPC_defaultmap: 6996 case OMPC_unknown: 6997 llvm_unreachable("Clause is not allowed."); 6998 } 6999 return Res; 7000 } 7001 7002 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 7003 SourceLocation EndLoc) { 7004 DSAStack->setNowaitRegion(); 7005 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 7006 } 7007 7008 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 7009 SourceLocation EndLoc) { 7010 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 7011 } 7012 7013 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 7014 SourceLocation EndLoc) { 7015 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 7016 } 7017 7018 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 7019 SourceLocation EndLoc) { 7020 return new (Context) OMPReadClause(StartLoc, EndLoc); 7021 } 7022 7023 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 7024 SourceLocation EndLoc) { 7025 return new (Context) OMPWriteClause(StartLoc, EndLoc); 7026 } 7027 7028 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 7029 SourceLocation EndLoc) { 7030 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 7031 } 7032 7033 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 7034 SourceLocation EndLoc) { 7035 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 7036 } 7037 7038 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 7039 SourceLocation EndLoc) { 7040 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 7041 } 7042 7043 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 7044 SourceLocation EndLoc) { 7045 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 7046 } 7047 7048 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 7049 SourceLocation EndLoc) { 7050 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 7051 } 7052 7053 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 7054 SourceLocation EndLoc) { 7055 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 7056 } 7057 7058 OMPClause *Sema::ActOnOpenMPVarListClause( 7059 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 7060 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 7061 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 7062 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, 7063 OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, 7064 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 7065 SourceLocation DepLinMapLoc) { 7066 OMPClause *Res = nullptr; 7067 switch (Kind) { 7068 case OMPC_private: 7069 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7070 break; 7071 case OMPC_firstprivate: 7072 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7073 break; 7074 case OMPC_lastprivate: 7075 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7076 break; 7077 case OMPC_shared: 7078 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 7079 break; 7080 case OMPC_reduction: 7081 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 7082 EndLoc, ReductionIdScopeSpec, ReductionId); 7083 break; 7084 case OMPC_linear: 7085 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 7086 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 7087 break; 7088 case OMPC_aligned: 7089 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 7090 ColonLoc, EndLoc); 7091 break; 7092 case OMPC_copyin: 7093 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 7094 break; 7095 case OMPC_copyprivate: 7096 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7097 break; 7098 case OMPC_flush: 7099 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 7100 break; 7101 case OMPC_depend: 7102 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 7103 StartLoc, LParenLoc, EndLoc); 7104 break; 7105 case OMPC_map: 7106 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, 7107 DepLinMapLoc, ColonLoc, VarList, StartLoc, 7108 LParenLoc, EndLoc); 7109 break; 7110 case OMPC_if: 7111 case OMPC_final: 7112 case OMPC_num_threads: 7113 case OMPC_safelen: 7114 case OMPC_simdlen: 7115 case OMPC_collapse: 7116 case OMPC_default: 7117 case OMPC_proc_bind: 7118 case OMPC_schedule: 7119 case OMPC_ordered: 7120 case OMPC_nowait: 7121 case OMPC_untied: 7122 case OMPC_mergeable: 7123 case OMPC_threadprivate: 7124 case OMPC_read: 7125 case OMPC_write: 7126 case OMPC_update: 7127 case OMPC_capture: 7128 case OMPC_seq_cst: 7129 case OMPC_device: 7130 case OMPC_threads: 7131 case OMPC_simd: 7132 case OMPC_num_teams: 7133 case OMPC_thread_limit: 7134 case OMPC_priority: 7135 case OMPC_grainsize: 7136 case OMPC_nogroup: 7137 case OMPC_num_tasks: 7138 case OMPC_hint: 7139 case OMPC_dist_schedule: 7140 case OMPC_defaultmap: 7141 case OMPC_unknown: 7142 llvm_unreachable("Clause is not allowed."); 7143 } 7144 return Res; 7145 } 7146 7147 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 7148 ExprObjectKind OK, SourceLocation Loc) { 7149 ExprResult Res = BuildDeclRefExpr( 7150 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 7151 if (!Res.isUsable()) 7152 return ExprError(); 7153 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 7154 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 7155 if (!Res.isUsable()) 7156 return ExprError(); 7157 } 7158 if (VK != VK_LValue && Res.get()->isGLValue()) { 7159 Res = DefaultLvalueConversion(Res.get()); 7160 if (!Res.isUsable()) 7161 return ExprError(); 7162 } 7163 return Res; 7164 } 7165 7166 static std::pair<ValueDecl *, bool> 7167 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 7168 SourceRange &ERange, bool AllowArraySection = false) { 7169 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 7170 RefExpr->containsUnexpandedParameterPack()) 7171 return std::make_pair(nullptr, true); 7172 7173 // OpenMP [3.1, C/C++] 7174 // A list item is a variable name. 7175 // OpenMP [2.9.3.3, Restrictions, p.1] 7176 // A variable that is part of another variable (as an array or 7177 // structure element) cannot appear in a private clause. 7178 RefExpr = RefExpr->IgnoreParens(); 7179 enum { 7180 NoArrayExpr = -1, 7181 ArraySubscript = 0, 7182 OMPArraySection = 1 7183 } IsArrayExpr = NoArrayExpr; 7184 if (AllowArraySection) { 7185 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 7186 auto *Base = ASE->getBase()->IgnoreParenImpCasts(); 7187 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 7188 Base = TempASE->getBase()->IgnoreParenImpCasts(); 7189 RefExpr = Base; 7190 IsArrayExpr = ArraySubscript; 7191 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 7192 auto *Base = OASE->getBase()->IgnoreParenImpCasts(); 7193 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 7194 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 7195 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 7196 Base = TempASE->getBase()->IgnoreParenImpCasts(); 7197 RefExpr = Base; 7198 IsArrayExpr = OMPArraySection; 7199 } 7200 } 7201 ELoc = RefExpr->getExprLoc(); 7202 ERange = RefExpr->getSourceRange(); 7203 RefExpr = RefExpr->IgnoreParenImpCasts(); 7204 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 7205 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 7206 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 7207 (S.getCurrentThisType().isNull() || !ME || 7208 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 7209 !isa<FieldDecl>(ME->getMemberDecl()))) { 7210 if (IsArrayExpr != NoArrayExpr) 7211 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 7212 << ERange; 7213 else { 7214 S.Diag(ELoc, 7215 AllowArraySection 7216 ? diag::err_omp_expected_var_name_member_expr_or_array_item 7217 : diag::err_omp_expected_var_name_member_expr) 7218 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 7219 } 7220 return std::make_pair(nullptr, false); 7221 } 7222 return std::make_pair(DE ? DE->getDecl() : ME->getMemberDecl(), false); 7223 } 7224 7225 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 7226 SourceLocation StartLoc, 7227 SourceLocation LParenLoc, 7228 SourceLocation EndLoc) { 7229 SmallVector<Expr *, 8> Vars; 7230 SmallVector<Expr *, 8> PrivateCopies; 7231 for (auto &RefExpr : VarList) { 7232 assert(RefExpr && "NULL expr in OpenMP private clause."); 7233 SourceLocation ELoc; 7234 SourceRange ERange; 7235 Expr *SimpleRefExpr = RefExpr; 7236 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 7237 if (Res.second) { 7238 // It will be analyzed later. 7239 Vars.push_back(RefExpr); 7240 PrivateCopies.push_back(nullptr); 7241 } 7242 ValueDecl *D = Res.first; 7243 if (!D) 7244 continue; 7245 7246 QualType Type = D->getType(); 7247 auto *VD = dyn_cast<VarDecl>(D); 7248 7249 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 7250 // A variable that appears in a private clause must not have an incomplete 7251 // type or a reference type. 7252 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 7253 continue; 7254 Type = Type.getNonReferenceType(); 7255 7256 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7257 // in a Construct] 7258 // Variables with the predetermined data-sharing attributes may not be 7259 // listed in data-sharing attributes clauses, except for the cases 7260 // listed below. For these exceptions only, listing a predetermined 7261 // variable in a data-sharing attribute clause is allowed and overrides 7262 // the variable's predetermined data-sharing attributes. 7263 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7264 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 7265 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 7266 << getOpenMPClauseName(OMPC_private); 7267 ReportOriginalDSA(*this, DSAStack, D, DVar); 7268 continue; 7269 } 7270 7271 // Variably modified types are not supported for tasks. 7272 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 7273 DSAStack->getCurrentDirective() == OMPD_task) { 7274 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 7275 << getOpenMPClauseName(OMPC_private) << Type 7276 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7277 bool IsDecl = 7278 !VD || 7279 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 7280 Diag(D->getLocation(), 7281 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 7282 << D; 7283 continue; 7284 } 7285 7286 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 7287 // A list item cannot appear in both a map clause and a data-sharing 7288 // attribute clause on the same construct 7289 if (DSAStack->getCurrentDirective() == OMPD_target) { 7290 if(DSAStack->checkMapInfoForVar(VD, /* CurrentRegionOnly = */ true, 7291 [&](Expr *RE) -> bool {return true;})) { 7292 Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) 7293 << getOpenMPClauseName(OMPC_private) 7294 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7295 ReportOriginalDSA(*this, DSAStack, D, DVar); 7296 continue; 7297 } 7298 } 7299 7300 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 7301 // A variable of class type (or array thereof) that appears in a private 7302 // clause requires an accessible, unambiguous default constructor for the 7303 // class type. 7304 // Generate helper private variable and initialize it with the default 7305 // value. The address of the original variable is replaced by the address of 7306 // the new private variable in CodeGen. This new variable is not added to 7307 // IdResolver, so the code in the OpenMP region uses original variable for 7308 // proper diagnostics. 7309 Type = Type.getUnqualifiedType(); 7310 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 7311 D->hasAttrs() ? &D->getAttrs() : nullptr); 7312 ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); 7313 if (VDPrivate->isInvalidDecl()) 7314 continue; 7315 auto VDPrivateRefExpr = buildDeclRefExpr( 7316 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 7317 7318 DeclRefExpr *Ref = nullptr; 7319 if (!VD) 7320 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 7321 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 7322 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 7323 PrivateCopies.push_back(VDPrivateRefExpr); 7324 } 7325 7326 if (Vars.empty()) 7327 return nullptr; 7328 7329 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 7330 PrivateCopies); 7331 } 7332 7333 namespace { 7334 class DiagsUninitializedSeveretyRAII { 7335 private: 7336 DiagnosticsEngine &Diags; 7337 SourceLocation SavedLoc; 7338 bool IsIgnored; 7339 7340 public: 7341 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 7342 bool IsIgnored) 7343 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 7344 if (!IsIgnored) { 7345 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 7346 /*Map*/ diag::Severity::Ignored, Loc); 7347 } 7348 } 7349 ~DiagsUninitializedSeveretyRAII() { 7350 if (!IsIgnored) 7351 Diags.popMappings(SavedLoc); 7352 } 7353 }; 7354 } 7355 7356 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 7357 SourceLocation StartLoc, 7358 SourceLocation LParenLoc, 7359 SourceLocation EndLoc) { 7360 SmallVector<Expr *, 8> Vars; 7361 SmallVector<Expr *, 8> PrivateCopies; 7362 SmallVector<Expr *, 8> Inits; 7363 SmallVector<Decl *, 4> ExprCaptures; 7364 bool IsImplicitClause = 7365 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 7366 auto ImplicitClauseLoc = DSAStack->getConstructLoc(); 7367 7368 for (auto &RefExpr : VarList) { 7369 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 7370 SourceLocation ELoc; 7371 SourceRange ERange; 7372 Expr *SimpleRefExpr = RefExpr; 7373 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 7374 if (Res.second) { 7375 // It will be analyzed later. 7376 Vars.push_back(RefExpr); 7377 PrivateCopies.push_back(nullptr); 7378 Inits.push_back(nullptr); 7379 } 7380 ValueDecl *D = Res.first; 7381 if (!D) 7382 continue; 7383 7384 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 7385 QualType Type = D->getType(); 7386 auto *VD = dyn_cast<VarDecl>(D); 7387 7388 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 7389 // A variable that appears in a private clause must not have an incomplete 7390 // type or a reference type. 7391 if (RequireCompleteType(ELoc, Type, 7392 diag::err_omp_firstprivate_incomplete_type)) 7393 continue; 7394 Type = Type.getNonReferenceType(); 7395 7396 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 7397 // A variable of class type (or array thereof) that appears in a private 7398 // clause requires an accessible, unambiguous copy constructor for the 7399 // class type. 7400 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 7401 7402 // If an implicit firstprivate variable found it was checked already. 7403 DSAStackTy::DSAVarData TopDVar; 7404 if (!IsImplicitClause) { 7405 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7406 TopDVar = DVar; 7407 bool IsConstant = ElemType.isConstant(Context); 7408 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 7409 // A list item that specifies a given variable may not appear in more 7410 // than one clause on the same directive, except that a variable may be 7411 // specified in both firstprivate and lastprivate clauses. 7412 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 7413 DVar.CKind != OMPC_lastprivate && DVar.RefExpr) { 7414 Diag(ELoc, diag::err_omp_wrong_dsa) 7415 << getOpenMPClauseName(DVar.CKind) 7416 << getOpenMPClauseName(OMPC_firstprivate); 7417 ReportOriginalDSA(*this, DSAStack, D, DVar); 7418 continue; 7419 } 7420 7421 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7422 // in a Construct] 7423 // Variables with the predetermined data-sharing attributes may not be 7424 // listed in data-sharing attributes clauses, except for the cases 7425 // listed below. For these exceptions only, listing a predetermined 7426 // variable in a data-sharing attribute clause is allowed and overrides 7427 // the variable's predetermined data-sharing attributes. 7428 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7429 // in a Construct, C/C++, p.2] 7430 // Variables with const-qualified type having no mutable member may be 7431 // listed in a firstprivate clause, even if they are static data members. 7432 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 7433 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 7434 Diag(ELoc, diag::err_omp_wrong_dsa) 7435 << getOpenMPClauseName(DVar.CKind) 7436 << getOpenMPClauseName(OMPC_firstprivate); 7437 ReportOriginalDSA(*this, DSAStack, D, DVar); 7438 continue; 7439 } 7440 7441 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 7442 // OpenMP [2.9.3.4, Restrictions, p.2] 7443 // A list item that is private within a parallel region must not appear 7444 // in a firstprivate clause on a worksharing construct if any of the 7445 // worksharing regions arising from the worksharing construct ever bind 7446 // to any of the parallel regions arising from the parallel construct. 7447 if (isOpenMPWorksharingDirective(CurrDir) && 7448 !isOpenMPParallelDirective(CurrDir)) { 7449 DVar = DSAStack->getImplicitDSA(D, true); 7450 if (DVar.CKind != OMPC_shared && 7451 (isOpenMPParallelDirective(DVar.DKind) || 7452 DVar.DKind == OMPD_unknown)) { 7453 Diag(ELoc, diag::err_omp_required_access) 7454 << getOpenMPClauseName(OMPC_firstprivate) 7455 << getOpenMPClauseName(OMPC_shared); 7456 ReportOriginalDSA(*this, DSAStack, D, DVar); 7457 continue; 7458 } 7459 } 7460 // OpenMP [2.9.3.4, Restrictions, p.3] 7461 // A list item that appears in a reduction clause of a parallel construct 7462 // must not appear in a firstprivate clause on a worksharing or task 7463 // construct if any of the worksharing or task regions arising from the 7464 // worksharing or task construct ever bind to any of the parallel regions 7465 // arising from the parallel construct. 7466 // OpenMP [2.9.3.4, Restrictions, p.4] 7467 // A list item that appears in a reduction clause in worksharing 7468 // construct must not appear in a firstprivate clause in a task construct 7469 // encountered during execution of any of the worksharing regions arising 7470 // from the worksharing construct. 7471 if (CurrDir == OMPD_task) { 7472 DVar = 7473 DSAStack->hasInnermostDSA(D, MatchesAnyClause(OMPC_reduction), 7474 [](OpenMPDirectiveKind K) -> bool { 7475 return isOpenMPParallelDirective(K) || 7476 isOpenMPWorksharingDirective(K); 7477 }, 7478 false); 7479 if (DVar.CKind == OMPC_reduction && 7480 (isOpenMPParallelDirective(DVar.DKind) || 7481 isOpenMPWorksharingDirective(DVar.DKind))) { 7482 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 7483 << getOpenMPDirectiveName(DVar.DKind); 7484 ReportOriginalDSA(*this, DSAStack, D, DVar); 7485 continue; 7486 } 7487 } 7488 7489 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 7490 // A list item that is private within a teams region must not appear in a 7491 // firstprivate clause on a distribute construct if any of the distribute 7492 // regions arising from the distribute construct ever bind to any of the 7493 // teams regions arising from the teams construct. 7494 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 7495 // A list item that appears in a reduction clause of a teams construct 7496 // must not appear in a firstprivate clause on a distribute construct if 7497 // any of the distribute regions arising from the distribute construct 7498 // ever bind to any of the teams regions arising from the teams construct. 7499 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 7500 // A list item may appear in a firstprivate or lastprivate clause but not 7501 // both. 7502 if (CurrDir == OMPD_distribute) { 7503 DVar = DSAStack->hasInnermostDSA(D, MatchesAnyClause(OMPC_private), 7504 [](OpenMPDirectiveKind K) -> bool { 7505 return isOpenMPTeamsDirective(K); 7506 }, 7507 false); 7508 if (DVar.CKind == OMPC_private && isOpenMPTeamsDirective(DVar.DKind)) { 7509 Diag(ELoc, diag::err_omp_firstprivate_distribute_private_teams); 7510 ReportOriginalDSA(*this, DSAStack, D, DVar); 7511 continue; 7512 } 7513 DVar = DSAStack->hasInnermostDSA(D, MatchesAnyClause(OMPC_reduction), 7514 [](OpenMPDirectiveKind K) -> bool { 7515 return isOpenMPTeamsDirective(K); 7516 }, 7517 false); 7518 if (DVar.CKind == OMPC_reduction && 7519 isOpenMPTeamsDirective(DVar.DKind)) { 7520 Diag(ELoc, diag::err_omp_firstprivate_distribute_in_teams_reduction); 7521 ReportOriginalDSA(*this, DSAStack, D, DVar); 7522 continue; 7523 } 7524 DVar = DSAStack->getTopDSA(D, false); 7525 if (DVar.CKind == OMPC_lastprivate) { 7526 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); 7527 ReportOriginalDSA(*this, DSAStack, D, DVar); 7528 continue; 7529 } 7530 } 7531 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 7532 // A list item cannot appear in both a map clause and a data-sharing 7533 // attribute clause on the same construct 7534 if (CurrDir == OMPD_target) { 7535 if(DSAStack->checkMapInfoForVar(VD, /* CurrentRegionOnly = */ true, 7536 [&](Expr *RE) -> bool {return true;})) { 7537 Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) 7538 << getOpenMPClauseName(OMPC_firstprivate) 7539 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7540 ReportOriginalDSA(*this, DSAStack, D, DVar); 7541 continue; 7542 } 7543 } 7544 } 7545 7546 // Variably modified types are not supported for tasks. 7547 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 7548 DSAStack->getCurrentDirective() == OMPD_task) { 7549 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 7550 << getOpenMPClauseName(OMPC_firstprivate) << Type 7551 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7552 bool IsDecl = 7553 !VD || 7554 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 7555 Diag(D->getLocation(), 7556 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 7557 << D; 7558 continue; 7559 } 7560 7561 Type = Type.getUnqualifiedType(); 7562 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 7563 D->hasAttrs() ? &D->getAttrs() : nullptr); 7564 // Generate helper private variable and initialize it with the value of the 7565 // original variable. The address of the original variable is replaced by 7566 // the address of the new private variable in the CodeGen. This new variable 7567 // is not added to IdResolver, so the code in the OpenMP region uses 7568 // original variable for proper diagnostics and variable capturing. 7569 Expr *VDInitRefExpr = nullptr; 7570 // For arrays generate initializer for single element and replace it by the 7571 // original array element in CodeGen. 7572 if (Type->isArrayType()) { 7573 auto VDInit = 7574 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 7575 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 7576 auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); 7577 ElemType = ElemType.getUnqualifiedType(); 7578 auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 7579 ".firstprivate.temp"); 7580 InitializedEntity Entity = 7581 InitializedEntity::InitializeVariable(VDInitTemp); 7582 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 7583 7584 InitializationSequence InitSeq(*this, Entity, Kind, Init); 7585 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 7586 if (Result.isInvalid()) 7587 VDPrivate->setInvalidDecl(); 7588 else 7589 VDPrivate->setInit(Result.getAs<Expr>()); 7590 // Remove temp variable declaration. 7591 Context.Deallocate(VDInitTemp); 7592 } else { 7593 auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 7594 ".firstprivate.temp"); 7595 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 7596 RefExpr->getExprLoc()); 7597 AddInitializerToDecl(VDPrivate, 7598 DefaultLvalueConversion(VDInitRefExpr).get(), 7599 /*DirectInit=*/false, /*TypeMayContainAuto=*/false); 7600 } 7601 if (VDPrivate->isInvalidDecl()) { 7602 if (IsImplicitClause) { 7603 Diag(RefExpr->getExprLoc(), 7604 diag::note_omp_task_predetermined_firstprivate_here); 7605 } 7606 continue; 7607 } 7608 CurContext->addDecl(VDPrivate); 7609 auto VDPrivateRefExpr = buildDeclRefExpr( 7610 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 7611 RefExpr->getExprLoc()); 7612 DeclRefExpr *Ref = nullptr; 7613 if (!VD) { 7614 if (TopDVar.CKind == OMPC_lastprivate) 7615 Ref = TopDVar.PrivateCopy; 7616 else { 7617 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 7618 if (!IsOpenMPCapturedDecl(D)) 7619 ExprCaptures.push_back(Ref->getDecl()); 7620 } 7621 } 7622 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 7623 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 7624 PrivateCopies.push_back(VDPrivateRefExpr); 7625 Inits.push_back(VDInitRefExpr); 7626 } 7627 7628 if (Vars.empty()) 7629 return nullptr; 7630 7631 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 7632 Vars, PrivateCopies, Inits, 7633 buildPreInits(Context, ExprCaptures)); 7634 } 7635 7636 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 7637 SourceLocation StartLoc, 7638 SourceLocation LParenLoc, 7639 SourceLocation EndLoc) { 7640 SmallVector<Expr *, 8> Vars; 7641 SmallVector<Expr *, 8> SrcExprs; 7642 SmallVector<Expr *, 8> DstExprs; 7643 SmallVector<Expr *, 8> AssignmentOps; 7644 SmallVector<Decl *, 4> ExprCaptures; 7645 SmallVector<Expr *, 4> ExprPostUpdates; 7646 for (auto &RefExpr : VarList) { 7647 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 7648 SourceLocation ELoc; 7649 SourceRange ERange; 7650 Expr *SimpleRefExpr = RefExpr; 7651 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 7652 if (Res.second) { 7653 // It will be analyzed later. 7654 Vars.push_back(RefExpr); 7655 SrcExprs.push_back(nullptr); 7656 DstExprs.push_back(nullptr); 7657 AssignmentOps.push_back(nullptr); 7658 } 7659 ValueDecl *D = Res.first; 7660 if (!D) 7661 continue; 7662 7663 QualType Type = D->getType(); 7664 auto *VD = dyn_cast<VarDecl>(D); 7665 7666 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 7667 // A variable that appears in a lastprivate clause must not have an 7668 // incomplete type or a reference type. 7669 if (RequireCompleteType(ELoc, Type, 7670 diag::err_omp_lastprivate_incomplete_type)) 7671 continue; 7672 Type = Type.getNonReferenceType(); 7673 7674 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 7675 // in a Construct] 7676 // Variables with the predetermined data-sharing attributes may not be 7677 // listed in data-sharing attributes clauses, except for the cases 7678 // listed below. 7679 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7680 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 7681 DVar.CKind != OMPC_firstprivate && 7682 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 7683 Diag(ELoc, diag::err_omp_wrong_dsa) 7684 << getOpenMPClauseName(DVar.CKind) 7685 << getOpenMPClauseName(OMPC_lastprivate); 7686 ReportOriginalDSA(*this, DSAStack, D, DVar); 7687 continue; 7688 } 7689 7690 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 7691 // OpenMP [2.14.3.5, Restrictions, p.2] 7692 // A list item that is private within a parallel region, or that appears in 7693 // the reduction clause of a parallel construct, must not appear in a 7694 // lastprivate clause on a worksharing construct if any of the corresponding 7695 // worksharing regions ever binds to any of the corresponding parallel 7696 // regions. 7697 DSAStackTy::DSAVarData TopDVar = DVar; 7698 if (isOpenMPWorksharingDirective(CurrDir) && 7699 !isOpenMPParallelDirective(CurrDir)) { 7700 DVar = DSAStack->getImplicitDSA(D, true); 7701 if (DVar.CKind != OMPC_shared) { 7702 Diag(ELoc, diag::err_omp_required_access) 7703 << getOpenMPClauseName(OMPC_lastprivate) 7704 << getOpenMPClauseName(OMPC_shared); 7705 ReportOriginalDSA(*this, DSAStack, D, DVar); 7706 continue; 7707 } 7708 } 7709 7710 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 7711 // A list item may appear in a firstprivate or lastprivate clause but not 7712 // both. 7713 if (CurrDir == OMPD_distribute) { 7714 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7715 if (DVar.CKind == OMPC_firstprivate) { 7716 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); 7717 ReportOriginalDSA(*this, DSAStack, D, DVar); 7718 continue; 7719 } 7720 } 7721 7722 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 7723 // A variable of class type (or array thereof) that appears in a 7724 // lastprivate clause requires an accessible, unambiguous default 7725 // constructor for the class type, unless the list item is also specified 7726 // in a firstprivate clause. 7727 // A variable of class type (or array thereof) that appears in a 7728 // lastprivate clause requires an accessible, unambiguous copy assignment 7729 // operator for the class type. 7730 Type = Context.getBaseElementType(Type).getNonReferenceType(); 7731 auto *SrcVD = buildVarDecl(*this, ERange.getBegin(), 7732 Type.getUnqualifiedType(), ".lastprivate.src", 7733 D->hasAttrs() ? &D->getAttrs() : nullptr); 7734 auto *PseudoSrcExpr = 7735 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 7736 auto *DstVD = 7737 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 7738 D->hasAttrs() ? &D->getAttrs() : nullptr); 7739 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 7740 // For arrays generate assignment operation for single element and replace 7741 // it by the original array element in CodeGen. 7742 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 7743 PseudoDstExpr, PseudoSrcExpr); 7744 if (AssignmentOp.isInvalid()) 7745 continue; 7746 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 7747 /*DiscardedValue=*/true); 7748 if (AssignmentOp.isInvalid()) 7749 continue; 7750 7751 DeclRefExpr *Ref = nullptr; 7752 if (!VD) { 7753 if (TopDVar.CKind == OMPC_firstprivate) 7754 Ref = TopDVar.PrivateCopy; 7755 else { 7756 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 7757 if (!IsOpenMPCapturedDecl(D)) 7758 ExprCaptures.push_back(Ref->getDecl()); 7759 } 7760 if (TopDVar.CKind == OMPC_firstprivate || 7761 (!IsOpenMPCapturedDecl(D) && 7762 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 7763 ExprResult RefRes = DefaultLvalueConversion(Ref); 7764 if (!RefRes.isUsable()) 7765 continue; 7766 ExprResult PostUpdateRes = 7767 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 7768 RefRes.get()); 7769 if (!PostUpdateRes.isUsable()) 7770 continue; 7771 ExprPostUpdates.push_back( 7772 IgnoredValueConversions(PostUpdateRes.get()).get()); 7773 } 7774 } 7775 if (TopDVar.CKind != OMPC_firstprivate) 7776 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 7777 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 7778 SrcExprs.push_back(PseudoSrcExpr); 7779 DstExprs.push_back(PseudoDstExpr); 7780 AssignmentOps.push_back(AssignmentOp.get()); 7781 } 7782 7783 if (Vars.empty()) 7784 return nullptr; 7785 7786 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 7787 Vars, SrcExprs, DstExprs, AssignmentOps, 7788 buildPreInits(Context, ExprCaptures), 7789 buildPostUpdate(*this, ExprPostUpdates)); 7790 } 7791 7792 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 7793 SourceLocation StartLoc, 7794 SourceLocation LParenLoc, 7795 SourceLocation EndLoc) { 7796 SmallVector<Expr *, 8> Vars; 7797 for (auto &RefExpr : VarList) { 7798 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 7799 SourceLocation ELoc; 7800 SourceRange ERange; 7801 Expr *SimpleRefExpr = RefExpr; 7802 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 7803 if (Res.second) { 7804 // It will be analyzed later. 7805 Vars.push_back(RefExpr); 7806 } 7807 ValueDecl *D = Res.first; 7808 if (!D) 7809 continue; 7810 7811 auto *VD = dyn_cast<VarDecl>(D); 7812 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7813 // in a Construct] 7814 // Variables with the predetermined data-sharing attributes may not be 7815 // listed in data-sharing attributes clauses, except for the cases 7816 // listed below. For these exceptions only, listing a predetermined 7817 // variable in a data-sharing attribute clause is allowed and overrides 7818 // the variable's predetermined data-sharing attributes. 7819 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7820 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 7821 DVar.RefExpr) { 7822 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 7823 << getOpenMPClauseName(OMPC_shared); 7824 ReportOriginalDSA(*this, DSAStack, D, DVar); 7825 continue; 7826 } 7827 7828 DeclRefExpr *Ref = nullptr; 7829 if (!VD && IsOpenMPCapturedDecl(D)) 7830 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 7831 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 7832 Vars.push_back((VD || !Ref) ? RefExpr->IgnoreParens() : Ref); 7833 } 7834 7835 if (Vars.empty()) 7836 return nullptr; 7837 7838 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 7839 } 7840 7841 namespace { 7842 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 7843 DSAStackTy *Stack; 7844 7845 public: 7846 bool VisitDeclRefExpr(DeclRefExpr *E) { 7847 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { 7848 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false); 7849 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 7850 return false; 7851 if (DVar.CKind != OMPC_unknown) 7852 return true; 7853 DSAStackTy::DSAVarData DVarPrivate = 7854 Stack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), false); 7855 if (DVarPrivate.CKind != OMPC_unknown) 7856 return true; 7857 return false; 7858 } 7859 return false; 7860 } 7861 bool VisitStmt(Stmt *S) { 7862 for (auto Child : S->children()) { 7863 if (Child && Visit(Child)) 7864 return true; 7865 } 7866 return false; 7867 } 7868 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 7869 }; 7870 } // namespace 7871 7872 namespace { 7873 // Transform MemberExpression for specified FieldDecl of current class to 7874 // DeclRefExpr to specified OMPCapturedExprDecl. 7875 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 7876 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 7877 ValueDecl *Field; 7878 DeclRefExpr *CapturedExpr; 7879 7880 public: 7881 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 7882 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 7883 7884 ExprResult TransformMemberExpr(MemberExpr *E) { 7885 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 7886 E->getMemberDecl() == Field) { 7887 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 7888 return CapturedExpr; 7889 } 7890 return BaseTransform::TransformMemberExpr(E); 7891 } 7892 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 7893 }; 7894 } // namespace 7895 7896 template <typename T> 7897 static T filterLookupForUDR(SmallVectorImpl<UnresolvedSet<8>> &Lookups, 7898 const llvm::function_ref<T(ValueDecl *)> &Gen) { 7899 for (auto &Set : Lookups) { 7900 for (auto *D : Set) { 7901 if (auto Res = Gen(cast<ValueDecl>(D))) 7902 return Res; 7903 } 7904 } 7905 return T(); 7906 } 7907 7908 static ExprResult 7909 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 7910 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 7911 const DeclarationNameInfo &ReductionId, QualType Ty, 7912 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 7913 if (ReductionIdScopeSpec.isInvalid()) 7914 return ExprError(); 7915 SmallVector<UnresolvedSet<8>, 4> Lookups; 7916 if (S) { 7917 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 7918 Lookup.suppressDiagnostics(); 7919 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 7920 auto *D = Lookup.getRepresentativeDecl(); 7921 do { 7922 S = S->getParent(); 7923 } while (S && !S->isDeclScope(D)); 7924 if (S) 7925 S = S->getParent(); 7926 Lookups.push_back(UnresolvedSet<8>()); 7927 Lookups.back().append(Lookup.begin(), Lookup.end()); 7928 Lookup.clear(); 7929 } 7930 } else if (auto *ULE = 7931 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 7932 Lookups.push_back(UnresolvedSet<8>()); 7933 Decl *PrevD = nullptr; 7934 for(auto *D : ULE->decls()) { 7935 if (D == PrevD) 7936 Lookups.push_back(UnresolvedSet<8>()); 7937 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) 7938 Lookups.back().addDecl(DRD); 7939 PrevD = D; 7940 } 7941 } 7942 if (Ty->isDependentType() || Ty->isInstantiationDependentType() || 7943 Ty->containsUnexpandedParameterPack() || 7944 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool { 7945 return !D->isInvalidDecl() && 7946 (D->getType()->isDependentType() || 7947 D->getType()->isInstantiationDependentType() || 7948 D->getType()->containsUnexpandedParameterPack()); 7949 })) { 7950 UnresolvedSet<8> ResSet; 7951 for (auto &Set : Lookups) { 7952 ResSet.append(Set.begin(), Set.end()); 7953 // The last item marks the end of all declarations at the specified scope. 7954 ResSet.addDecl(Set[Set.size() - 1]); 7955 } 7956 return UnresolvedLookupExpr::Create( 7957 SemaRef.Context, /*NamingClass=*/nullptr, 7958 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 7959 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 7960 } 7961 if (auto *VD = filterLookupForUDR<ValueDecl *>( 7962 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 7963 if (!D->isInvalidDecl() && 7964 SemaRef.Context.hasSameType(D->getType(), Ty)) 7965 return D; 7966 return nullptr; 7967 })) 7968 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 7969 if (auto *VD = filterLookupForUDR<ValueDecl *>( 7970 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 7971 if (!D->isInvalidDecl() && 7972 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 7973 !Ty.isMoreQualifiedThan(D->getType())) 7974 return D; 7975 return nullptr; 7976 })) { 7977 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 7978 /*DetectVirtual=*/false); 7979 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 7980 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 7981 VD->getType().getUnqualifiedType()))) { 7982 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), 7983 /*DiagID=*/0) != 7984 Sema::AR_inaccessible) { 7985 SemaRef.BuildBasePathArray(Paths, BasePath); 7986 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 7987 } 7988 } 7989 } 7990 } 7991 if (ReductionIdScopeSpec.isSet()) { 7992 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 7993 return ExprError(); 7994 } 7995 return ExprEmpty(); 7996 } 7997 7998 OMPClause *Sema::ActOnOpenMPReductionClause( 7999 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 8000 SourceLocation ColonLoc, SourceLocation EndLoc, 8001 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 8002 ArrayRef<Expr *> UnresolvedReductions) { 8003 auto DN = ReductionId.getName(); 8004 auto OOK = DN.getCXXOverloadedOperator(); 8005 BinaryOperatorKind BOK = BO_Comma; 8006 8007 // OpenMP [2.14.3.6, reduction clause] 8008 // C 8009 // reduction-identifier is either an identifier or one of the following 8010 // operators: +, -, *, &, |, ^, && and || 8011 // C++ 8012 // reduction-identifier is either an id-expression or one of the following 8013 // operators: +, -, *, &, |, ^, && and || 8014 // FIXME: Only 'min' and 'max' identifiers are supported for now. 8015 switch (OOK) { 8016 case OO_Plus: 8017 case OO_Minus: 8018 BOK = BO_Add; 8019 break; 8020 case OO_Star: 8021 BOK = BO_Mul; 8022 break; 8023 case OO_Amp: 8024 BOK = BO_And; 8025 break; 8026 case OO_Pipe: 8027 BOK = BO_Or; 8028 break; 8029 case OO_Caret: 8030 BOK = BO_Xor; 8031 break; 8032 case OO_AmpAmp: 8033 BOK = BO_LAnd; 8034 break; 8035 case OO_PipePipe: 8036 BOK = BO_LOr; 8037 break; 8038 case OO_New: 8039 case OO_Delete: 8040 case OO_Array_New: 8041 case OO_Array_Delete: 8042 case OO_Slash: 8043 case OO_Percent: 8044 case OO_Tilde: 8045 case OO_Exclaim: 8046 case OO_Equal: 8047 case OO_Less: 8048 case OO_Greater: 8049 case OO_LessEqual: 8050 case OO_GreaterEqual: 8051 case OO_PlusEqual: 8052 case OO_MinusEqual: 8053 case OO_StarEqual: 8054 case OO_SlashEqual: 8055 case OO_PercentEqual: 8056 case OO_CaretEqual: 8057 case OO_AmpEqual: 8058 case OO_PipeEqual: 8059 case OO_LessLess: 8060 case OO_GreaterGreater: 8061 case OO_LessLessEqual: 8062 case OO_GreaterGreaterEqual: 8063 case OO_EqualEqual: 8064 case OO_ExclaimEqual: 8065 case OO_PlusPlus: 8066 case OO_MinusMinus: 8067 case OO_Comma: 8068 case OO_ArrowStar: 8069 case OO_Arrow: 8070 case OO_Call: 8071 case OO_Subscript: 8072 case OO_Conditional: 8073 case OO_Coawait: 8074 case NUM_OVERLOADED_OPERATORS: 8075 llvm_unreachable("Unexpected reduction identifier"); 8076 case OO_None: 8077 if (auto II = DN.getAsIdentifierInfo()) { 8078 if (II->isStr("max")) 8079 BOK = BO_GT; 8080 else if (II->isStr("min")) 8081 BOK = BO_LT; 8082 } 8083 break; 8084 } 8085 SourceRange ReductionIdRange; 8086 if (ReductionIdScopeSpec.isValid()) 8087 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 8088 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 8089 8090 SmallVector<Expr *, 8> Vars; 8091 SmallVector<Expr *, 8> Privates; 8092 SmallVector<Expr *, 8> LHSs; 8093 SmallVector<Expr *, 8> RHSs; 8094 SmallVector<Expr *, 8> ReductionOps; 8095 SmallVector<Decl *, 4> ExprCaptures; 8096 SmallVector<Expr *, 4> ExprPostUpdates; 8097 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 8098 bool FirstIter = true; 8099 for (auto RefExpr : VarList) { 8100 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 8101 // OpenMP [2.1, C/C++] 8102 // A list item is a variable or array section, subject to the restrictions 8103 // specified in Section 2.4 on page 42 and in each of the sections 8104 // describing clauses and directives for which a list appears. 8105 // OpenMP [2.14.3.3, Restrictions, p.1] 8106 // A variable that is part of another variable (as an array or 8107 // structure element) cannot appear in a private clause. 8108 if (!FirstIter && IR != ER) 8109 ++IR; 8110 FirstIter = false; 8111 SourceLocation ELoc; 8112 SourceRange ERange; 8113 Expr *SimpleRefExpr = RefExpr; 8114 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 8115 /*AllowArraySection=*/true); 8116 if (Res.second) { 8117 // It will be analyzed later. 8118 Vars.push_back(RefExpr); 8119 Privates.push_back(nullptr); 8120 LHSs.push_back(nullptr); 8121 RHSs.push_back(nullptr); 8122 // Try to find 'declare reduction' corresponding construct before using 8123 // builtin/overloaded operators. 8124 QualType Type = Context.DependentTy; 8125 CXXCastPath BasePath; 8126 ExprResult DeclareReductionRef = buildDeclareReductionRef( 8127 *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, 8128 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 8129 if (CurContext->isDependentContext() && 8130 (DeclareReductionRef.isUnset() || 8131 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 8132 ReductionOps.push_back(DeclareReductionRef.get()); 8133 else 8134 ReductionOps.push_back(nullptr); 8135 } 8136 ValueDecl *D = Res.first; 8137 if (!D) 8138 continue; 8139 8140 QualType Type; 8141 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 8142 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 8143 if (ASE) 8144 Type = ASE->getType().getNonReferenceType(); 8145 else if (OASE) { 8146 auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 8147 if (auto *ATy = BaseType->getAsArrayTypeUnsafe()) 8148 Type = ATy->getElementType(); 8149 else 8150 Type = BaseType->getPointeeType(); 8151 Type = Type.getNonReferenceType(); 8152 } else 8153 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 8154 auto *VD = dyn_cast<VarDecl>(D); 8155 8156 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 8157 // A variable that appears in a private clause must not have an incomplete 8158 // type or a reference type. 8159 if (RequireCompleteType(ELoc, Type, 8160 diag::err_omp_reduction_incomplete_type)) 8161 continue; 8162 // OpenMP [2.14.3.6, reduction clause, Restrictions] 8163 // A list item that appears in a reduction clause must not be 8164 // const-qualified. 8165 if (Type.getNonReferenceType().isConstant(Context)) { 8166 Diag(ELoc, diag::err_omp_const_reduction_list_item) 8167 << getOpenMPClauseName(OMPC_reduction) << Type << ERange; 8168 if (!ASE && !OASE) { 8169 bool IsDecl = !VD || 8170 VD->isThisDeclarationADefinition(Context) == 8171 VarDecl::DeclarationOnly; 8172 Diag(D->getLocation(), 8173 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8174 << D; 8175 } 8176 continue; 8177 } 8178 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 8179 // If a list-item is a reference type then it must bind to the same object 8180 // for all threads of the team. 8181 if (!ASE && !OASE && VD) { 8182 VarDecl *VDDef = VD->getDefinition(); 8183 if (VD->getType()->isReferenceType() && VDDef) { 8184 DSARefChecker Check(DSAStack); 8185 if (Check.Visit(VDDef->getInit())) { 8186 Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; 8187 Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 8188 continue; 8189 } 8190 } 8191 } 8192 8193 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 8194 // in a Construct] 8195 // Variables with the predetermined data-sharing attributes may not be 8196 // listed in data-sharing attributes clauses, except for the cases 8197 // listed below. For these exceptions only, listing a predetermined 8198 // variable in a data-sharing attribute clause is allowed and overrides 8199 // the variable's predetermined data-sharing attributes. 8200 // OpenMP [2.14.3.6, Restrictions, p.3] 8201 // Any number of reduction clauses can be specified on the directive, 8202 // but a list item can appear only once in the reduction clauses for that 8203 // directive. 8204 DSAStackTy::DSAVarData DVar; 8205 DVar = DSAStack->getTopDSA(D, false); 8206 if (DVar.CKind == OMPC_reduction) { 8207 Diag(ELoc, diag::err_omp_once_referenced) 8208 << getOpenMPClauseName(OMPC_reduction); 8209 if (DVar.RefExpr) 8210 Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 8211 } else if (DVar.CKind != OMPC_unknown) { 8212 Diag(ELoc, diag::err_omp_wrong_dsa) 8213 << getOpenMPClauseName(DVar.CKind) 8214 << getOpenMPClauseName(OMPC_reduction); 8215 ReportOriginalDSA(*this, DSAStack, D, DVar); 8216 continue; 8217 } 8218 8219 // OpenMP [2.14.3.6, Restrictions, p.1] 8220 // A list item that appears in a reduction clause of a worksharing 8221 // construct must be shared in the parallel regions to which any of the 8222 // worksharing regions arising from the worksharing construct bind. 8223 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 8224 if (isOpenMPWorksharingDirective(CurrDir) && 8225 !isOpenMPParallelDirective(CurrDir)) { 8226 DVar = DSAStack->getImplicitDSA(D, true); 8227 if (DVar.CKind != OMPC_shared) { 8228 Diag(ELoc, diag::err_omp_required_access) 8229 << getOpenMPClauseName(OMPC_reduction) 8230 << getOpenMPClauseName(OMPC_shared); 8231 ReportOriginalDSA(*this, DSAStack, D, DVar); 8232 continue; 8233 } 8234 } 8235 8236 // Try to find 'declare reduction' corresponding construct before using 8237 // builtin/overloaded operators. 8238 CXXCastPath BasePath; 8239 ExprResult DeclareReductionRef = buildDeclareReductionRef( 8240 *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, 8241 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 8242 if (DeclareReductionRef.isInvalid()) 8243 continue; 8244 if (CurContext->isDependentContext() && 8245 (DeclareReductionRef.isUnset() || 8246 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 8247 Vars.push_back(RefExpr); 8248 Privates.push_back(nullptr); 8249 LHSs.push_back(nullptr); 8250 RHSs.push_back(nullptr); 8251 ReductionOps.push_back(DeclareReductionRef.get()); 8252 continue; 8253 } 8254 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 8255 // Not allowed reduction identifier is found. 8256 Diag(ReductionId.getLocStart(), 8257 diag::err_omp_unknown_reduction_identifier) 8258 << Type << ReductionIdRange; 8259 continue; 8260 } 8261 8262 // OpenMP [2.14.3.6, reduction clause, Restrictions] 8263 // The type of a list item that appears in a reduction clause must be valid 8264 // for the reduction-identifier. For a max or min reduction in C, the type 8265 // of the list item must be an allowed arithmetic data type: char, int, 8266 // float, double, or _Bool, possibly modified with long, short, signed, or 8267 // unsigned. For a max or min reduction in C++, the type of the list item 8268 // must be an allowed arithmetic data type: char, wchar_t, int, float, 8269 // double, or bool, possibly modified with long, short, signed, or unsigned. 8270 if (DeclareReductionRef.isUnset()) { 8271 if ((BOK == BO_GT || BOK == BO_LT) && 8272 !(Type->isScalarType() || 8273 (getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 8274 Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 8275 << getLangOpts().CPlusPlus; 8276 if (!ASE && !OASE) { 8277 bool IsDecl = !VD || 8278 VD->isThisDeclarationADefinition(Context) == 8279 VarDecl::DeclarationOnly; 8280 Diag(D->getLocation(), 8281 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8282 << D; 8283 } 8284 continue; 8285 } 8286 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 8287 !getLangOpts().CPlusPlus && Type->isFloatingType()) { 8288 Diag(ELoc, diag::err_omp_clause_floating_type_arg); 8289 if (!ASE && !OASE) { 8290 bool IsDecl = !VD || 8291 VD->isThisDeclarationADefinition(Context) == 8292 VarDecl::DeclarationOnly; 8293 Diag(D->getLocation(), 8294 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8295 << D; 8296 } 8297 continue; 8298 } 8299 } 8300 8301 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 8302 auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs", 8303 D->hasAttrs() ? &D->getAttrs() : nullptr); 8304 auto *RHSVD = buildVarDecl(*this, ELoc, Type, D->getName(), 8305 D->hasAttrs() ? &D->getAttrs() : nullptr); 8306 auto PrivateTy = Type; 8307 if (OASE || 8308 (!ASE && 8309 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 8310 // For arays/array sections only: 8311 // Create pseudo array type for private copy. The size for this array will 8312 // be generated during codegen. 8313 // For array subscripts or single variables Private Ty is the same as Type 8314 // (type of the variable or single array element). 8315 PrivateTy = Context.getVariableArrayType( 8316 Type, new (Context) OpaqueValueExpr(SourceLocation(), 8317 Context.getSizeType(), VK_RValue), 8318 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 8319 } else if (!ASE && !OASE && 8320 Context.getAsArrayType(D->getType().getNonReferenceType())) 8321 PrivateTy = D->getType().getNonReferenceType(); 8322 // Private copy. 8323 auto *PrivateVD = buildVarDecl(*this, ELoc, PrivateTy, D->getName(), 8324 D->hasAttrs() ? &D->getAttrs() : nullptr); 8325 // Add initializer for private variable. 8326 Expr *Init = nullptr; 8327 auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc); 8328 auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc); 8329 if (DeclareReductionRef.isUsable()) { 8330 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 8331 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 8332 if (DRD->getInitializer()) { 8333 Init = DRDRef; 8334 RHSVD->setInit(DRDRef); 8335 RHSVD->setInitStyle(VarDecl::CallInit); 8336 } 8337 } else { 8338 switch (BOK) { 8339 case BO_Add: 8340 case BO_Xor: 8341 case BO_Or: 8342 case BO_LOr: 8343 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 8344 if (Type->isScalarType() || Type->isAnyComplexType()) 8345 Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 8346 break; 8347 case BO_Mul: 8348 case BO_LAnd: 8349 if (Type->isScalarType() || Type->isAnyComplexType()) { 8350 // '*' and '&&' reduction ops - initializer is '1'. 8351 Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 8352 } 8353 break; 8354 case BO_And: { 8355 // '&' reduction op - initializer is '~0'. 8356 QualType OrigType = Type; 8357 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 8358 Type = ComplexTy->getElementType(); 8359 if (Type->isRealFloatingType()) { 8360 llvm::APFloat InitValue = 8361 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 8362 /*isIEEE=*/true); 8363 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 8364 Type, ELoc); 8365 } else if (Type->isScalarType()) { 8366 auto Size = Context.getTypeSize(Type); 8367 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 8368 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 8369 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 8370 } 8371 if (Init && OrigType->isAnyComplexType()) { 8372 // Init = 0xFFFF + 0xFFFFi; 8373 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 8374 Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 8375 } 8376 Type = OrigType; 8377 break; 8378 } 8379 case BO_LT: 8380 case BO_GT: { 8381 // 'min' reduction op - initializer is 'Largest representable number in 8382 // the reduction list item type'. 8383 // 'max' reduction op - initializer is 'Least representable number in 8384 // the reduction list item type'. 8385 if (Type->isIntegerType() || Type->isPointerType()) { 8386 bool IsSigned = Type->hasSignedIntegerRepresentation(); 8387 auto Size = Context.getTypeSize(Type); 8388 QualType IntTy = 8389 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 8390 llvm::APInt InitValue = 8391 (BOK != BO_LT) 8392 ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 8393 : llvm::APInt::getMinValue(Size) 8394 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 8395 : llvm::APInt::getMaxValue(Size); 8396 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 8397 if (Type->isPointerType()) { 8398 // Cast to pointer type. 8399 auto CastExpr = BuildCStyleCastExpr( 8400 SourceLocation(), Context.getTrivialTypeSourceInfo(Type, ELoc), 8401 SourceLocation(), Init); 8402 if (CastExpr.isInvalid()) 8403 continue; 8404 Init = CastExpr.get(); 8405 } 8406 } else if (Type->isRealFloatingType()) { 8407 llvm::APFloat InitValue = llvm::APFloat::getLargest( 8408 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 8409 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 8410 Type, ELoc); 8411 } 8412 break; 8413 } 8414 case BO_PtrMemD: 8415 case BO_PtrMemI: 8416 case BO_MulAssign: 8417 case BO_Div: 8418 case BO_Rem: 8419 case BO_Sub: 8420 case BO_Shl: 8421 case BO_Shr: 8422 case BO_LE: 8423 case BO_GE: 8424 case BO_EQ: 8425 case BO_NE: 8426 case BO_AndAssign: 8427 case BO_XorAssign: 8428 case BO_OrAssign: 8429 case BO_Assign: 8430 case BO_AddAssign: 8431 case BO_SubAssign: 8432 case BO_DivAssign: 8433 case BO_RemAssign: 8434 case BO_ShlAssign: 8435 case BO_ShrAssign: 8436 case BO_Comma: 8437 llvm_unreachable("Unexpected reduction operation"); 8438 } 8439 } 8440 if (Init && DeclareReductionRef.isUnset()) { 8441 AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false, 8442 /*TypeMayContainAuto=*/false); 8443 } else if (!Init) 8444 ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false); 8445 if (RHSVD->isInvalidDecl()) 8446 continue; 8447 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 8448 Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type 8449 << ReductionIdRange; 8450 bool IsDecl = 8451 !VD || 8452 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8453 Diag(D->getLocation(), 8454 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8455 << D; 8456 continue; 8457 } 8458 // Store initializer for single element in private copy. Will be used during 8459 // codegen. 8460 PrivateVD->setInit(RHSVD->getInit()); 8461 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 8462 auto *PrivateDRE = buildDeclRefExpr(*this, PrivateVD, PrivateTy, ELoc); 8463 ExprResult ReductionOp; 8464 if (DeclareReductionRef.isUsable()) { 8465 QualType RedTy = DeclareReductionRef.get()->getType(); 8466 QualType PtrRedTy = Context.getPointerType(RedTy); 8467 ExprResult LHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 8468 ExprResult RHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 8469 if (!BasePath.empty()) { 8470 LHS = DefaultLvalueConversion(LHS.get()); 8471 RHS = DefaultLvalueConversion(RHS.get()); 8472 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 8473 CK_UncheckedDerivedToBase, LHS.get(), 8474 &BasePath, LHS.get()->getValueKind()); 8475 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 8476 CK_UncheckedDerivedToBase, RHS.get(), 8477 &BasePath, RHS.get()->getValueKind()); 8478 } 8479 FunctionProtoType::ExtProtoInfo EPI; 8480 QualType Params[] = {PtrRedTy, PtrRedTy}; 8481 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 8482 auto *OVE = new (Context) OpaqueValueExpr( 8483 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 8484 DefaultLvalueConversion(DeclareReductionRef.get()).get()); 8485 Expr *Args[] = {LHS.get(), RHS.get()}; 8486 ReductionOp = new (Context) 8487 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 8488 } else { 8489 ReductionOp = BuildBinOp(DSAStack->getCurScope(), 8490 ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE); 8491 if (ReductionOp.isUsable()) { 8492 if (BOK != BO_LT && BOK != BO_GT) { 8493 ReductionOp = 8494 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 8495 BO_Assign, LHSDRE, ReductionOp.get()); 8496 } else { 8497 auto *ConditionalOp = new (Context) ConditionalOperator( 8498 ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(), 8499 RHSDRE, Type, VK_LValue, OK_Ordinary); 8500 ReductionOp = 8501 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 8502 BO_Assign, LHSDRE, ConditionalOp); 8503 } 8504 ReductionOp = ActOnFinishFullExpr(ReductionOp.get()); 8505 } 8506 if (ReductionOp.isInvalid()) 8507 continue; 8508 } 8509 8510 DeclRefExpr *Ref = nullptr; 8511 Expr *VarsExpr = RefExpr->IgnoreParens(); 8512 if (!VD) { 8513 if (ASE || OASE) { 8514 TransformExprToCaptures RebuildToCapture(*this, D); 8515 VarsExpr = 8516 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 8517 Ref = RebuildToCapture.getCapturedExpr(); 8518 } else { 8519 VarsExpr = Ref = 8520 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 8521 } 8522 if (!IsOpenMPCapturedDecl(D)) { 8523 ExprCaptures.push_back(Ref->getDecl()); 8524 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 8525 ExprResult RefRes = DefaultLvalueConversion(Ref); 8526 if (!RefRes.isUsable()) 8527 continue; 8528 ExprResult PostUpdateRes = 8529 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 8530 SimpleRefExpr, RefRes.get()); 8531 if (!PostUpdateRes.isUsable()) 8532 continue; 8533 ExprPostUpdates.push_back( 8534 IgnoredValueConversions(PostUpdateRes.get()).get()); 8535 } 8536 } 8537 } 8538 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 8539 Vars.push_back(VarsExpr); 8540 Privates.push_back(PrivateDRE); 8541 LHSs.push_back(LHSDRE); 8542 RHSs.push_back(RHSDRE); 8543 ReductionOps.push_back(ReductionOp.get()); 8544 } 8545 8546 if (Vars.empty()) 8547 return nullptr; 8548 8549 return OMPReductionClause::Create( 8550 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars, 8551 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates, 8552 LHSs, RHSs, ReductionOps, buildPreInits(Context, ExprCaptures), 8553 buildPostUpdate(*this, ExprPostUpdates)); 8554 } 8555 8556 OMPClause *Sema::ActOnOpenMPLinearClause( 8557 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 8558 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 8559 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 8560 SmallVector<Expr *, 8> Vars; 8561 SmallVector<Expr *, 8> Privates; 8562 SmallVector<Expr *, 8> Inits; 8563 SmallVector<Decl *, 4> ExprCaptures; 8564 SmallVector<Expr *, 4> ExprPostUpdates; 8565 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 8566 LinKind == OMPC_LINEAR_unknown) { 8567 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 8568 LinKind = OMPC_LINEAR_val; 8569 } 8570 for (auto &RefExpr : VarList) { 8571 assert(RefExpr && "NULL expr in OpenMP linear clause."); 8572 SourceLocation ELoc; 8573 SourceRange ERange; 8574 Expr *SimpleRefExpr = RefExpr; 8575 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 8576 /*AllowArraySection=*/false); 8577 if (Res.second) { 8578 // It will be analyzed later. 8579 Vars.push_back(RefExpr); 8580 Privates.push_back(nullptr); 8581 Inits.push_back(nullptr); 8582 } 8583 ValueDecl *D = Res.first; 8584 if (!D) 8585 continue; 8586 8587 QualType Type = D->getType(); 8588 auto *VD = dyn_cast<VarDecl>(D); 8589 8590 // OpenMP [2.14.3.7, linear clause] 8591 // A list-item cannot appear in more than one linear clause. 8592 // A list-item that appears in a linear clause cannot appear in any 8593 // other data-sharing attribute clause. 8594 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8595 if (DVar.RefExpr) { 8596 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 8597 << getOpenMPClauseName(OMPC_linear); 8598 ReportOriginalDSA(*this, DSAStack, D, DVar); 8599 continue; 8600 } 8601 8602 // A variable must not have an incomplete type or a reference type. 8603 if (RequireCompleteType(ELoc, Type, 8604 diag::err_omp_linear_incomplete_type)) 8605 continue; 8606 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 8607 !Type->isReferenceType()) { 8608 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 8609 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 8610 continue; 8611 } 8612 Type = Type.getNonReferenceType(); 8613 8614 // A list item must not be const-qualified. 8615 if (Type.isConstant(Context)) { 8616 Diag(ELoc, diag::err_omp_const_variable) 8617 << getOpenMPClauseName(OMPC_linear); 8618 bool IsDecl = 8619 !VD || 8620 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8621 Diag(D->getLocation(), 8622 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8623 << D; 8624 continue; 8625 } 8626 8627 // A list item must be of integral or pointer type. 8628 Type = Type.getUnqualifiedType().getCanonicalType(); 8629 const auto *Ty = Type.getTypePtrOrNull(); 8630 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 8631 !Ty->isPointerType())) { 8632 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 8633 bool IsDecl = 8634 !VD || 8635 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8636 Diag(D->getLocation(), 8637 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8638 << D; 8639 continue; 8640 } 8641 8642 // Build private copy of original var. 8643 auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(), 8644 D->hasAttrs() ? &D->getAttrs() : nullptr); 8645 auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 8646 // Build var to save initial value. 8647 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 8648 Expr *InitExpr; 8649 DeclRefExpr *Ref = nullptr; 8650 if (!VD) { 8651 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 8652 if (!IsOpenMPCapturedDecl(D)) { 8653 ExprCaptures.push_back(Ref->getDecl()); 8654 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 8655 ExprResult RefRes = DefaultLvalueConversion(Ref); 8656 if (!RefRes.isUsable()) 8657 continue; 8658 ExprResult PostUpdateRes = 8659 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 8660 SimpleRefExpr, RefRes.get()); 8661 if (!PostUpdateRes.isUsable()) 8662 continue; 8663 ExprPostUpdates.push_back( 8664 IgnoredValueConversions(PostUpdateRes.get()).get()); 8665 } 8666 } 8667 } 8668 if (LinKind == OMPC_LINEAR_uval) 8669 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 8670 else 8671 InitExpr = VD ? SimpleRefExpr : Ref; 8672 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 8673 /*DirectInit=*/false, /*TypeMayContainAuto=*/false); 8674 auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 8675 8676 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 8677 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 8678 Privates.push_back(PrivateRef); 8679 Inits.push_back(InitRef); 8680 } 8681 8682 if (Vars.empty()) 8683 return nullptr; 8684 8685 Expr *StepExpr = Step; 8686 Expr *CalcStepExpr = nullptr; 8687 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 8688 !Step->isInstantiationDependent() && 8689 !Step->containsUnexpandedParameterPack()) { 8690 SourceLocation StepLoc = Step->getLocStart(); 8691 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 8692 if (Val.isInvalid()) 8693 return nullptr; 8694 StepExpr = Val.get(); 8695 8696 // Build var to save the step value. 8697 VarDecl *SaveVar = 8698 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 8699 ExprResult SaveRef = 8700 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 8701 ExprResult CalcStep = 8702 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 8703 CalcStep = ActOnFinishFullExpr(CalcStep.get()); 8704 8705 // Warn about zero linear step (it would be probably better specified as 8706 // making corresponding variables 'const'). 8707 llvm::APSInt Result; 8708 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 8709 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 8710 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 8711 << (Vars.size() > 1); 8712 if (!IsConstant && CalcStep.isUsable()) { 8713 // Calculate the step beforehand instead of doing this on each iteration. 8714 // (This is not used if the number of iterations may be kfold-ed). 8715 CalcStepExpr = CalcStep.get(); 8716 } 8717 } 8718 8719 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 8720 ColonLoc, EndLoc, Vars, Privates, Inits, 8721 StepExpr, CalcStepExpr, 8722 buildPreInits(Context, ExprCaptures), 8723 buildPostUpdate(*this, ExprPostUpdates)); 8724 } 8725 8726 static bool 8727 FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 8728 Expr *NumIterations, Sema &SemaRef, Scope *S) { 8729 // Walk the vars and build update/final expressions for the CodeGen. 8730 SmallVector<Expr *, 8> Updates; 8731 SmallVector<Expr *, 8> Finals; 8732 Expr *Step = Clause.getStep(); 8733 Expr *CalcStep = Clause.getCalcStep(); 8734 // OpenMP [2.14.3.7, linear clause] 8735 // If linear-step is not specified it is assumed to be 1. 8736 if (Step == nullptr) 8737 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 8738 else if (CalcStep) { 8739 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 8740 } 8741 bool HasErrors = false; 8742 auto CurInit = Clause.inits().begin(); 8743 auto CurPrivate = Clause.privates().begin(); 8744 auto LinKind = Clause.getModifier(); 8745 for (auto &RefExpr : Clause.varlists()) { 8746 Expr *InitExpr = *CurInit; 8747 8748 // Build privatized reference to the current linear var. 8749 auto DE = cast<DeclRefExpr>(RefExpr); 8750 Expr *CapturedRef; 8751 if (LinKind == OMPC_LINEAR_uval) 8752 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 8753 else 8754 CapturedRef = 8755 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 8756 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 8757 /*RefersToCapture=*/true); 8758 8759 // Build update: Var = InitExpr + IV * Step 8760 ExprResult Update = 8761 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 8762 InitExpr, IV, Step, /* Subtract */ false); 8763 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(), 8764 /*DiscardedValue=*/true); 8765 8766 // Build final: Var = InitExpr + NumIterations * Step 8767 ExprResult Final = 8768 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 8769 InitExpr, NumIterations, Step, /* Subtract */ false); 8770 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(), 8771 /*DiscardedValue=*/true); 8772 if (!Update.isUsable() || !Final.isUsable()) { 8773 Updates.push_back(nullptr); 8774 Finals.push_back(nullptr); 8775 HasErrors = true; 8776 } else { 8777 Updates.push_back(Update.get()); 8778 Finals.push_back(Final.get()); 8779 } 8780 ++CurInit; 8781 ++CurPrivate; 8782 } 8783 Clause.setUpdates(Updates); 8784 Clause.setFinals(Finals); 8785 return HasErrors; 8786 } 8787 8788 OMPClause *Sema::ActOnOpenMPAlignedClause( 8789 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 8790 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 8791 8792 SmallVector<Expr *, 8> Vars; 8793 for (auto &RefExpr : VarList) { 8794 assert(RefExpr && "NULL expr in OpenMP linear clause."); 8795 SourceLocation ELoc; 8796 SourceRange ERange; 8797 Expr *SimpleRefExpr = RefExpr; 8798 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 8799 /*AllowArraySection=*/false); 8800 if (Res.second) { 8801 // It will be analyzed later. 8802 Vars.push_back(RefExpr); 8803 } 8804 ValueDecl *D = Res.first; 8805 if (!D) 8806 continue; 8807 8808 QualType QType = D->getType(); 8809 auto *VD = dyn_cast<VarDecl>(D); 8810 8811 // OpenMP [2.8.1, simd construct, Restrictions] 8812 // The type of list items appearing in the aligned clause must be 8813 // array, pointer, reference to array, or reference to pointer. 8814 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 8815 const Type *Ty = QType.getTypePtrOrNull(); 8816 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 8817 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 8818 << QType << getLangOpts().CPlusPlus << ERange; 8819 bool IsDecl = 8820 !VD || 8821 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8822 Diag(D->getLocation(), 8823 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8824 << D; 8825 continue; 8826 } 8827 8828 // OpenMP [2.8.1, simd construct, Restrictions] 8829 // A list-item cannot appear in more than one aligned clause. 8830 if (Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 8831 Diag(ELoc, diag::err_omp_aligned_twice) << ERange; 8832 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 8833 << getOpenMPClauseName(OMPC_aligned); 8834 continue; 8835 } 8836 8837 DeclRefExpr *Ref = nullptr; 8838 if (!VD && IsOpenMPCapturedDecl(D)) 8839 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 8840 Vars.push_back(DefaultFunctionArrayConversion( 8841 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 8842 .get()); 8843 } 8844 8845 // OpenMP [2.8.1, simd construct, Description] 8846 // The parameter of the aligned clause, alignment, must be a constant 8847 // positive integer expression. 8848 // If no optional parameter is specified, implementation-defined default 8849 // alignments for SIMD instructions on the target platforms are assumed. 8850 if (Alignment != nullptr) { 8851 ExprResult AlignResult = 8852 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 8853 if (AlignResult.isInvalid()) 8854 return nullptr; 8855 Alignment = AlignResult.get(); 8856 } 8857 if (Vars.empty()) 8858 return nullptr; 8859 8860 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 8861 EndLoc, Vars, Alignment); 8862 } 8863 8864 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 8865 SourceLocation StartLoc, 8866 SourceLocation LParenLoc, 8867 SourceLocation EndLoc) { 8868 SmallVector<Expr *, 8> Vars; 8869 SmallVector<Expr *, 8> SrcExprs; 8870 SmallVector<Expr *, 8> DstExprs; 8871 SmallVector<Expr *, 8> AssignmentOps; 8872 for (auto &RefExpr : VarList) { 8873 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 8874 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 8875 // It will be analyzed later. 8876 Vars.push_back(RefExpr); 8877 SrcExprs.push_back(nullptr); 8878 DstExprs.push_back(nullptr); 8879 AssignmentOps.push_back(nullptr); 8880 continue; 8881 } 8882 8883 SourceLocation ELoc = RefExpr->getExprLoc(); 8884 // OpenMP [2.1, C/C++] 8885 // A list item is a variable name. 8886 // OpenMP [2.14.4.1, Restrictions, p.1] 8887 // A list item that appears in a copyin clause must be threadprivate. 8888 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 8889 if (!DE || !isa<VarDecl>(DE->getDecl())) { 8890 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 8891 << 0 << RefExpr->getSourceRange(); 8892 continue; 8893 } 8894 8895 Decl *D = DE->getDecl(); 8896 VarDecl *VD = cast<VarDecl>(D); 8897 8898 QualType Type = VD->getType(); 8899 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 8900 // It will be analyzed later. 8901 Vars.push_back(DE); 8902 SrcExprs.push_back(nullptr); 8903 DstExprs.push_back(nullptr); 8904 AssignmentOps.push_back(nullptr); 8905 continue; 8906 } 8907 8908 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 8909 // A list item that appears in a copyin clause must be threadprivate. 8910 if (!DSAStack->isThreadPrivate(VD)) { 8911 Diag(ELoc, diag::err_omp_required_access) 8912 << getOpenMPClauseName(OMPC_copyin) 8913 << getOpenMPDirectiveName(OMPD_threadprivate); 8914 continue; 8915 } 8916 8917 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 8918 // A variable of class type (or array thereof) that appears in a 8919 // copyin clause requires an accessible, unambiguous copy assignment 8920 // operator for the class type. 8921 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 8922 auto *SrcVD = 8923 buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(), 8924 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 8925 auto *PseudoSrcExpr = buildDeclRefExpr( 8926 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 8927 auto *DstVD = 8928 buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst", 8929 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 8930 auto *PseudoDstExpr = 8931 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 8932 // For arrays generate assignment operation for single element and replace 8933 // it by the original array element in CodeGen. 8934 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 8935 PseudoDstExpr, PseudoSrcExpr); 8936 if (AssignmentOp.isInvalid()) 8937 continue; 8938 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 8939 /*DiscardedValue=*/true); 8940 if (AssignmentOp.isInvalid()) 8941 continue; 8942 8943 DSAStack->addDSA(VD, DE, OMPC_copyin); 8944 Vars.push_back(DE); 8945 SrcExprs.push_back(PseudoSrcExpr); 8946 DstExprs.push_back(PseudoDstExpr); 8947 AssignmentOps.push_back(AssignmentOp.get()); 8948 } 8949 8950 if (Vars.empty()) 8951 return nullptr; 8952 8953 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 8954 SrcExprs, DstExprs, AssignmentOps); 8955 } 8956 8957 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 8958 SourceLocation StartLoc, 8959 SourceLocation LParenLoc, 8960 SourceLocation EndLoc) { 8961 SmallVector<Expr *, 8> Vars; 8962 SmallVector<Expr *, 8> SrcExprs; 8963 SmallVector<Expr *, 8> DstExprs; 8964 SmallVector<Expr *, 8> AssignmentOps; 8965 for (auto &RefExpr : VarList) { 8966 assert(RefExpr && "NULL expr in OpenMP linear clause."); 8967 SourceLocation ELoc; 8968 SourceRange ERange; 8969 Expr *SimpleRefExpr = RefExpr; 8970 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 8971 /*AllowArraySection=*/false); 8972 if (Res.second) { 8973 // It will be analyzed later. 8974 Vars.push_back(RefExpr); 8975 SrcExprs.push_back(nullptr); 8976 DstExprs.push_back(nullptr); 8977 AssignmentOps.push_back(nullptr); 8978 } 8979 ValueDecl *D = Res.first; 8980 if (!D) 8981 continue; 8982 8983 QualType Type = D->getType(); 8984 auto *VD = dyn_cast<VarDecl>(D); 8985 8986 // OpenMP [2.14.4.2, Restrictions, p.2] 8987 // A list item that appears in a copyprivate clause may not appear in a 8988 // private or firstprivate clause on the single construct. 8989 if (!VD || !DSAStack->isThreadPrivate(VD)) { 8990 auto DVar = DSAStack->getTopDSA(D, false); 8991 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 8992 DVar.RefExpr) { 8993 Diag(ELoc, diag::err_omp_wrong_dsa) 8994 << getOpenMPClauseName(DVar.CKind) 8995 << getOpenMPClauseName(OMPC_copyprivate); 8996 ReportOriginalDSA(*this, DSAStack, D, DVar); 8997 continue; 8998 } 8999 9000 // OpenMP [2.11.4.2, Restrictions, p.1] 9001 // All list items that appear in a copyprivate clause must be either 9002 // threadprivate or private in the enclosing context. 9003 if (DVar.CKind == OMPC_unknown) { 9004 DVar = DSAStack->getImplicitDSA(D, false); 9005 if (DVar.CKind == OMPC_shared) { 9006 Diag(ELoc, diag::err_omp_required_access) 9007 << getOpenMPClauseName(OMPC_copyprivate) 9008 << "threadprivate or private in the enclosing context"; 9009 ReportOriginalDSA(*this, DSAStack, D, DVar); 9010 continue; 9011 } 9012 } 9013 } 9014 9015 // Variably modified types are not supported. 9016 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 9017 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 9018 << getOpenMPClauseName(OMPC_copyprivate) << Type 9019 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 9020 bool IsDecl = 9021 !VD || 9022 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9023 Diag(D->getLocation(), 9024 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9025 << D; 9026 continue; 9027 } 9028 9029 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 9030 // A variable of class type (or array thereof) that appears in a 9031 // copyin clause requires an accessible, unambiguous copy assignment 9032 // operator for the class type. 9033 Type = Context.getBaseElementType(Type.getNonReferenceType()) 9034 .getUnqualifiedType(); 9035 auto *SrcVD = 9036 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src", 9037 D->hasAttrs() ? &D->getAttrs() : nullptr); 9038 auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 9039 auto *DstVD = 9040 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst", 9041 D->hasAttrs() ? &D->getAttrs() : nullptr); 9042 auto *PseudoDstExpr = 9043 buildDeclRefExpr(*this, DstVD, Type, ELoc); 9044 auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 9045 PseudoDstExpr, PseudoSrcExpr); 9046 if (AssignmentOp.isInvalid()) 9047 continue; 9048 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 9049 /*DiscardedValue=*/true); 9050 if (AssignmentOp.isInvalid()) 9051 continue; 9052 9053 // No need to mark vars as copyprivate, they are already threadprivate or 9054 // implicitly private. 9055 assert(VD || IsOpenMPCapturedDecl(D)); 9056 Vars.push_back( 9057 VD ? RefExpr->IgnoreParens() 9058 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 9059 SrcExprs.push_back(PseudoSrcExpr); 9060 DstExprs.push_back(PseudoDstExpr); 9061 AssignmentOps.push_back(AssignmentOp.get()); 9062 } 9063 9064 if (Vars.empty()) 9065 return nullptr; 9066 9067 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9068 Vars, SrcExprs, DstExprs, AssignmentOps); 9069 } 9070 9071 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 9072 SourceLocation StartLoc, 9073 SourceLocation LParenLoc, 9074 SourceLocation EndLoc) { 9075 if (VarList.empty()) 9076 return nullptr; 9077 9078 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 9079 } 9080 9081 OMPClause * 9082 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 9083 SourceLocation DepLoc, SourceLocation ColonLoc, 9084 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 9085 SourceLocation LParenLoc, SourceLocation EndLoc) { 9086 if (DSAStack->getCurrentDirective() == OMPD_ordered && 9087 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 9088 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 9089 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 9090 return nullptr; 9091 } 9092 if (DSAStack->getCurrentDirective() != OMPD_ordered && 9093 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 9094 DepKind == OMPC_DEPEND_sink)) { 9095 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 9096 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 9097 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 9098 /*Last=*/OMPC_DEPEND_unknown, Except) 9099 << getOpenMPClauseName(OMPC_depend); 9100 return nullptr; 9101 } 9102 SmallVector<Expr *, 8> Vars; 9103 llvm::APSInt DepCounter(/*BitWidth=*/32); 9104 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 9105 if (DepKind == OMPC_DEPEND_sink) { 9106 if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) { 9107 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 9108 TotalDepCount.setIsUnsigned(/*Val=*/true); 9109 } 9110 } 9111 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) || 9112 DSAStack->getParentOrderedRegionParam()) { 9113 for (auto &RefExpr : VarList) { 9114 assert(RefExpr && "NULL expr in OpenMP shared clause."); 9115 if (isa<DependentScopeDeclRefExpr>(RefExpr) || 9116 (DepKind == OMPC_DEPEND_sink && CurContext->isDependentContext())) { 9117 // It will be analyzed later. 9118 Vars.push_back(RefExpr); 9119 continue; 9120 } 9121 9122 SourceLocation ELoc = RefExpr->getExprLoc(); 9123 auto *SimpleExpr = RefExpr->IgnoreParenCasts(); 9124 if (DepKind == OMPC_DEPEND_sink) { 9125 if (DepCounter >= TotalDepCount) { 9126 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 9127 continue; 9128 } 9129 ++DepCounter; 9130 // OpenMP [2.13.9, Summary] 9131 // depend(dependence-type : vec), where dependence-type is: 9132 // 'sink' and where vec is the iteration vector, which has the form: 9133 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 9134 // where n is the value specified by the ordered clause in the loop 9135 // directive, xi denotes the loop iteration variable of the i-th nested 9136 // loop associated with the loop directive, and di is a constant 9137 // non-negative integer. 9138 SimpleExpr = SimpleExpr->IgnoreImplicit(); 9139 auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr); 9140 if (!DE) { 9141 OverloadedOperatorKind OOK = OO_None; 9142 SourceLocation OOLoc; 9143 Expr *LHS, *RHS; 9144 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 9145 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 9146 OOLoc = BO->getOperatorLoc(); 9147 LHS = BO->getLHS()->IgnoreParenImpCasts(); 9148 RHS = BO->getRHS()->IgnoreParenImpCasts(); 9149 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 9150 OOK = OCE->getOperator(); 9151 OOLoc = OCE->getOperatorLoc(); 9152 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 9153 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 9154 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 9155 OOK = MCE->getMethodDecl() 9156 ->getNameInfo() 9157 .getName() 9158 .getCXXOverloadedOperator(); 9159 OOLoc = MCE->getCallee()->getExprLoc(); 9160 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 9161 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 9162 } else { 9163 Diag(ELoc, diag::err_omp_depend_sink_wrong_expr); 9164 continue; 9165 } 9166 DE = dyn_cast<DeclRefExpr>(LHS); 9167 if (!DE) { 9168 Diag(LHS->getExprLoc(), 9169 diag::err_omp_depend_sink_expected_loop_iteration) 9170 << DSAStack->getParentLoopControlVariable( 9171 DepCounter.getZExtValue()); 9172 continue; 9173 } 9174 if (OOK != OO_Plus && OOK != OO_Minus) { 9175 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 9176 continue; 9177 } 9178 ExprResult Res = VerifyPositiveIntegerConstantInClause( 9179 RHS, OMPC_depend, /*StrictlyPositive=*/false); 9180 if (Res.isInvalid()) 9181 continue; 9182 } 9183 auto *VD = dyn_cast<VarDecl>(DE->getDecl()); 9184 if (!CurContext->isDependentContext() && 9185 DSAStack->getParentOrderedRegionParam() && 9186 (!VD || 9187 DepCounter != DSAStack->isParentLoopControlVariable(VD).first)) { 9188 Diag(DE->getExprLoc(), 9189 diag::err_omp_depend_sink_expected_loop_iteration) 9190 << DSAStack->getParentLoopControlVariable( 9191 DepCounter.getZExtValue()); 9192 continue; 9193 } 9194 } else { 9195 // OpenMP [2.11.1.1, Restrictions, p.3] 9196 // A variable that is part of another variable (such as a field of a 9197 // structure) but is not an array element or an array section cannot 9198 // appear in a depend clause. 9199 auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr); 9200 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 9201 auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 9202 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 9203 (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) || 9204 (ASE && 9205 !ASE->getBase() 9206 ->getType() 9207 .getNonReferenceType() 9208 ->isPointerType() && 9209 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 9210 Diag(ELoc, diag::err_omp_expected_var_name_member_expr_or_array_item) 9211 << 0 << RefExpr->getSourceRange(); 9212 continue; 9213 } 9214 } 9215 9216 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 9217 } 9218 9219 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 9220 TotalDepCount > VarList.size() && 9221 DSAStack->getParentOrderedRegionParam()) { 9222 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 9223 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 9224 } 9225 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 9226 Vars.empty()) 9227 return nullptr; 9228 } 9229 9230 return OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, DepKind, 9231 DepLoc, ColonLoc, Vars); 9232 } 9233 9234 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 9235 SourceLocation LParenLoc, 9236 SourceLocation EndLoc) { 9237 Expr *ValExpr = Device; 9238 9239 // OpenMP [2.9.1, Restrictions] 9240 // The device expression must evaluate to a non-negative integer value. 9241 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 9242 /*StrictlyPositive=*/false)) 9243 return nullptr; 9244 9245 return new (Context) OMPDeviceClause(ValExpr, StartLoc, LParenLoc, EndLoc); 9246 } 9247 9248 static bool IsCXXRecordForMappable(Sema &SemaRef, SourceLocation Loc, 9249 DSAStackTy *Stack, CXXRecordDecl *RD) { 9250 if (!RD || RD->isInvalidDecl()) 9251 return true; 9252 9253 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) 9254 if (auto *CTD = CTSD->getSpecializedTemplate()) 9255 RD = CTD->getTemplatedDecl(); 9256 auto QTy = SemaRef.Context.getRecordType(RD); 9257 if (RD->isDynamicClass()) { 9258 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 9259 SemaRef.Diag(RD->getLocation(), diag::note_omp_polymorphic_in_target); 9260 return false; 9261 } 9262 auto *DC = RD; 9263 bool IsCorrect = true; 9264 for (auto *I : DC->decls()) { 9265 if (I) { 9266 if (auto *MD = dyn_cast<CXXMethodDecl>(I)) { 9267 if (MD->isStatic()) { 9268 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 9269 SemaRef.Diag(MD->getLocation(), 9270 diag::note_omp_static_member_in_target); 9271 IsCorrect = false; 9272 } 9273 } else if (auto *VD = dyn_cast<VarDecl>(I)) { 9274 if (VD->isStaticDataMember()) { 9275 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 9276 SemaRef.Diag(VD->getLocation(), 9277 diag::note_omp_static_member_in_target); 9278 IsCorrect = false; 9279 } 9280 } 9281 } 9282 } 9283 9284 for (auto &I : RD->bases()) { 9285 if (!IsCXXRecordForMappable(SemaRef, I.getLocStart(), Stack, 9286 I.getType()->getAsCXXRecordDecl())) 9287 IsCorrect = false; 9288 } 9289 return IsCorrect; 9290 } 9291 9292 static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 9293 DSAStackTy *Stack, QualType QTy) { 9294 NamedDecl *ND; 9295 if (QTy->isIncompleteType(&ND)) { 9296 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 9297 return false; 9298 } else if (CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(ND)) { 9299 if (!RD->isInvalidDecl() && 9300 !IsCXXRecordForMappable(SemaRef, SL, Stack, RD)) 9301 return false; 9302 } 9303 return true; 9304 } 9305 9306 /// \brief Return true if it can be proven that the provided array expression 9307 /// (array section or array subscript) does NOT specify the whole size of the 9308 /// array whose base type is \a BaseQTy. 9309 static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 9310 const Expr *E, 9311 QualType BaseQTy) { 9312 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 9313 9314 // If this is an array subscript, it refers to the whole size if the size of 9315 // the dimension is constant and equals 1. Also, an array section assumes the 9316 // format of an array subscript if no colon is used. 9317 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 9318 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 9319 return ATy->getSize().getSExtValue() != 1; 9320 // Size can't be evaluated statically. 9321 return false; 9322 } 9323 9324 assert(OASE && "Expecting array section if not an array subscript."); 9325 auto *LowerBound = OASE->getLowerBound(); 9326 auto *Length = OASE->getLength(); 9327 9328 // If there is a lower bound that does not evaluates to zero, we are not 9329 // convering the whole dimension. 9330 if (LowerBound) { 9331 llvm::APSInt ConstLowerBound; 9332 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) 9333 return false; // Can't get the integer value as a constant. 9334 if (ConstLowerBound.getSExtValue()) 9335 return true; 9336 } 9337 9338 // If we don't have a length we covering the whole dimension. 9339 if (!Length) 9340 return false; 9341 9342 // If the base is a pointer, we don't have a way to get the size of the 9343 // pointee. 9344 if (BaseQTy->isPointerType()) 9345 return false; 9346 9347 // We can only check if the length is the same as the size of the dimension 9348 // if we have a constant array. 9349 auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 9350 if (!CATy) 9351 return false; 9352 9353 llvm::APSInt ConstLength; 9354 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 9355 return false; // Can't get the integer value as a constant. 9356 9357 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 9358 } 9359 9360 // Return true if it can be proven that the provided array expression (array 9361 // section or array subscript) does NOT specify a single element of the array 9362 // whose base type is \a BaseQTy. 9363 static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 9364 const Expr *E, 9365 QualType BaseQTy) { 9366 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 9367 9368 // An array subscript always refer to a single element. Also, an array section 9369 // assumes the format of an array subscript if no colon is used. 9370 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 9371 return false; 9372 9373 assert(OASE && "Expecting array section if not an array subscript."); 9374 auto *Length = OASE->getLength(); 9375 9376 // If we don't have a length we have to check if the array has unitary size 9377 // for this dimension. Also, we should always expect a length if the base type 9378 // is pointer. 9379 if (!Length) { 9380 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 9381 return ATy->getSize().getSExtValue() != 1; 9382 // We cannot assume anything. 9383 return false; 9384 } 9385 9386 // Check if the length evaluates to 1. 9387 llvm::APSInt ConstLength; 9388 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 9389 return false; // Can't get the integer value as a constant. 9390 9391 return ConstLength.getSExtValue() != 1; 9392 } 9393 9394 // Return the expression of the base of the map clause or null if it cannot 9395 // be determined and do all the necessary checks to see if the expression is 9396 // valid as a standalone map clause expression. 9397 static Expr *CheckMapClauseExpressionBase(Sema &SemaRef, Expr *E) { 9398 SourceLocation ELoc = E->getExprLoc(); 9399 SourceRange ERange = E->getSourceRange(); 9400 9401 // The base of elements of list in a map clause have to be either: 9402 // - a reference to variable or field. 9403 // - a member expression. 9404 // - an array expression. 9405 // 9406 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 9407 // reference to 'r'. 9408 // 9409 // If we have: 9410 // 9411 // struct SS { 9412 // Bla S; 9413 // foo() { 9414 // #pragma omp target map (S.Arr[:12]); 9415 // } 9416 // } 9417 // 9418 // We want to retrieve the member expression 'this->S'; 9419 9420 Expr *RelevantExpr = nullptr; 9421 9422 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 9423 // If a list item is an array section, it must specify contiguous storage. 9424 // 9425 // For this restriction it is sufficient that we make sure only references 9426 // to variables or fields and array expressions, and that no array sections 9427 // exist except in the rightmost expression (unless they cover the whole 9428 // dimension of the array). E.g. these would be invalid: 9429 // 9430 // r.ArrS[3:5].Arr[6:7] 9431 // 9432 // r.ArrS[3:5].x 9433 // 9434 // but these would be valid: 9435 // r.ArrS[3].Arr[6:7] 9436 // 9437 // r.ArrS[3].x 9438 9439 bool AllowUnitySizeArraySection = true; 9440 bool AllowWholeSizeArraySection = true; 9441 9442 while (!RelevantExpr) { 9443 E = E->IgnoreParenImpCasts(); 9444 9445 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 9446 if (!isa<VarDecl>(CurE->getDecl())) 9447 break; 9448 9449 RelevantExpr = CurE; 9450 9451 // If we got a reference to a declaration, we should not expect any array 9452 // section before that. 9453 AllowUnitySizeArraySection = false; 9454 AllowWholeSizeArraySection = false; 9455 continue; 9456 } 9457 9458 if (auto *CurE = dyn_cast<MemberExpr>(E)) { 9459 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 9460 9461 if (isa<CXXThisExpr>(BaseE)) 9462 // We found a base expression: this->Val. 9463 RelevantExpr = CurE; 9464 else 9465 E = BaseE; 9466 9467 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 9468 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 9469 << CurE->getSourceRange(); 9470 break; 9471 } 9472 9473 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 9474 9475 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 9476 // A bit-field cannot appear in a map clause. 9477 // 9478 if (FD->isBitField()) { 9479 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_map_clause) 9480 << CurE->getSourceRange(); 9481 break; 9482 } 9483 9484 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 9485 // If the type of a list item is a reference to a type T then the type 9486 // will be considered to be T for all purposes of this clause. 9487 QualType CurType = BaseE->getType().getNonReferenceType(); 9488 9489 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 9490 // A list item cannot be a variable that is a member of a structure with 9491 // a union type. 9492 // 9493 if (auto *RT = CurType->getAs<RecordType>()) 9494 if (RT->isUnionType()) { 9495 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 9496 << CurE->getSourceRange(); 9497 break; 9498 } 9499 9500 // If we got a member expression, we should not expect any array section 9501 // before that: 9502 // 9503 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 9504 // If a list item is an element of a structure, only the rightmost symbol 9505 // of the variable reference can be an array section. 9506 // 9507 AllowUnitySizeArraySection = false; 9508 AllowWholeSizeArraySection = false; 9509 continue; 9510 } 9511 9512 if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 9513 E = CurE->getBase()->IgnoreParenImpCasts(); 9514 9515 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 9516 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 9517 << 0 << CurE->getSourceRange(); 9518 break; 9519 } 9520 9521 // If we got an array subscript that express the whole dimension we 9522 // can have any array expressions before. If it only expressing part of 9523 // the dimension, we can only have unitary-size array expressions. 9524 if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 9525 E->getType())) 9526 AllowWholeSizeArraySection = false; 9527 continue; 9528 } 9529 9530 if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 9531 E = CurE->getBase()->IgnoreParenImpCasts(); 9532 9533 auto CurType = 9534 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 9535 9536 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 9537 // If the type of a list item is a reference to a type T then the type 9538 // will be considered to be T for all purposes of this clause. 9539 if (CurType->isReferenceType()) 9540 CurType = CurType->getPointeeType(); 9541 9542 bool IsPointer = CurType->isAnyPointerType(); 9543 9544 if (!IsPointer && !CurType->isArrayType()) { 9545 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 9546 << 0 << CurE->getSourceRange(); 9547 break; 9548 } 9549 9550 bool NotWhole = 9551 CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 9552 bool NotUnity = 9553 CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 9554 9555 if (AllowWholeSizeArraySection && AllowUnitySizeArraySection) { 9556 // Any array section is currently allowed. 9557 // 9558 // If this array section refers to the whole dimension we can still 9559 // accept other array sections before this one, except if the base is a 9560 // pointer. Otherwise, only unitary sections are accepted. 9561 if (NotWhole || IsPointer) 9562 AllowWholeSizeArraySection = false; 9563 } else if ((AllowUnitySizeArraySection && NotUnity) || 9564 (AllowWholeSizeArraySection && NotWhole)) { 9565 // A unity or whole array section is not allowed and that is not 9566 // compatible with the properties of the current array section. 9567 SemaRef.Diag( 9568 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 9569 << CurE->getSourceRange(); 9570 break; 9571 } 9572 continue; 9573 } 9574 9575 // If nothing else worked, this is not a valid map clause expression. 9576 SemaRef.Diag(ELoc, 9577 diag::err_omp_expected_named_var_member_or_array_expression) 9578 << ERange; 9579 break; 9580 } 9581 9582 return RelevantExpr; 9583 } 9584 9585 // Return true if expression E associated with value VD has conflicts with other 9586 // map information. 9587 static bool CheckMapConflicts(Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, 9588 Expr *E, bool CurrentRegionOnly) { 9589 assert(VD && E); 9590 9591 // Types used to organize the components of a valid map clause. 9592 typedef std::pair<Expr *, ValueDecl *> MapExpressionComponent; 9593 typedef SmallVector<MapExpressionComponent, 4> MapExpressionComponents; 9594 9595 // Helper to extract the components in the map clause expression E and store 9596 // them into MEC. This assumes that E is a valid map clause expression, i.e. 9597 // it has already passed the single clause checks. 9598 auto ExtractMapExpressionComponents = [](Expr *TE, 9599 MapExpressionComponents &MEC) { 9600 while (true) { 9601 TE = TE->IgnoreParenImpCasts(); 9602 9603 if (auto *CurE = dyn_cast<DeclRefExpr>(TE)) { 9604 MEC.push_back( 9605 MapExpressionComponent(CurE, cast<VarDecl>(CurE->getDecl()))); 9606 break; 9607 } 9608 9609 if (auto *CurE = dyn_cast<MemberExpr>(TE)) { 9610 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 9611 9612 MEC.push_back(MapExpressionComponent( 9613 CurE, cast<FieldDecl>(CurE->getMemberDecl()))); 9614 if (isa<CXXThisExpr>(BaseE)) 9615 break; 9616 9617 TE = BaseE; 9618 continue; 9619 } 9620 9621 if (auto *CurE = dyn_cast<ArraySubscriptExpr>(TE)) { 9622 MEC.push_back(MapExpressionComponent(CurE, nullptr)); 9623 TE = CurE->getBase()->IgnoreParenImpCasts(); 9624 continue; 9625 } 9626 9627 if (auto *CurE = dyn_cast<OMPArraySectionExpr>(TE)) { 9628 MEC.push_back(MapExpressionComponent(CurE, nullptr)); 9629 TE = CurE->getBase()->IgnoreParenImpCasts(); 9630 continue; 9631 } 9632 9633 llvm_unreachable( 9634 "Expecting only valid map clause expressions at this point!"); 9635 } 9636 }; 9637 9638 SourceLocation ELoc = E->getExprLoc(); 9639 SourceRange ERange = E->getSourceRange(); 9640 9641 // In order to easily check the conflicts we need to match each component of 9642 // the expression under test with the components of the expressions that are 9643 // already in the stack. 9644 9645 MapExpressionComponents CurComponents; 9646 ExtractMapExpressionComponents(E, CurComponents); 9647 9648 assert(!CurComponents.empty() && "Map clause expression with no components!"); 9649 assert(CurComponents.back().second == VD && 9650 "Map clause expression with unexpected base!"); 9651 9652 // Variables to help detecting enclosing problems in data environment nests. 9653 bool IsEnclosedByDataEnvironmentExpr = false; 9654 Expr *EnclosingExpr = nullptr; 9655 9656 bool FoundError = 9657 DSAS->checkMapInfoForVar(VD, CurrentRegionOnly, [&](Expr *RE) -> bool { 9658 MapExpressionComponents StackComponents; 9659 ExtractMapExpressionComponents(RE, StackComponents); 9660 assert(!StackComponents.empty() && 9661 "Map clause expression with no components!"); 9662 assert(StackComponents.back().second == VD && 9663 "Map clause expression with unexpected base!"); 9664 9665 // Expressions must start from the same base. Here we detect at which 9666 // point both expressions diverge from each other and see if we can 9667 // detect if the memory referred to both expressions is contiguous and 9668 // do not overlap. 9669 auto CI = CurComponents.rbegin(); 9670 auto CE = CurComponents.rend(); 9671 auto SI = StackComponents.rbegin(); 9672 auto SE = StackComponents.rend(); 9673 for (; CI != CE && SI != SE; ++CI, ++SI) { 9674 9675 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 9676 // At most one list item can be an array item derived from a given 9677 // variable in map clauses of the same construct. 9678 if (CurrentRegionOnly && (isa<ArraySubscriptExpr>(CI->first) || 9679 isa<OMPArraySectionExpr>(CI->first)) && 9680 (isa<ArraySubscriptExpr>(SI->first) || 9681 isa<OMPArraySectionExpr>(SI->first))) { 9682 SemaRef.Diag(CI->first->getExprLoc(), 9683 diag::err_omp_multiple_array_items_in_map_clause) 9684 << CI->first->getSourceRange(); 9685 ; 9686 SemaRef.Diag(SI->first->getExprLoc(), diag::note_used_here) 9687 << SI->first->getSourceRange(); 9688 return true; 9689 } 9690 9691 // Do both expressions have the same kind? 9692 if (CI->first->getStmtClass() != SI->first->getStmtClass()) 9693 break; 9694 9695 // Are we dealing with different variables/fields? 9696 if (CI->second != SI->second) 9697 break; 9698 } 9699 9700 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 9701 // List items of map clauses in the same construct must not share 9702 // original storage. 9703 // 9704 // If the expressions are exactly the same or one is a subset of the 9705 // other, it means they are sharing storage. 9706 if (CI == CE && SI == SE) { 9707 if (CurrentRegionOnly) { 9708 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 9709 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 9710 << RE->getSourceRange(); 9711 return true; 9712 } else { 9713 // If we find the same expression in the enclosing data environment, 9714 // that is legal. 9715 IsEnclosedByDataEnvironmentExpr = true; 9716 return false; 9717 } 9718 } 9719 9720 QualType DerivedType = std::prev(CI)->first->getType(); 9721 SourceLocation DerivedLoc = std::prev(CI)->first->getExprLoc(); 9722 9723 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 9724 // If the type of a list item is a reference to a type T then the type 9725 // will be considered to be T for all purposes of this clause. 9726 if (DerivedType->isReferenceType()) 9727 DerivedType = DerivedType->getPointeeType(); 9728 9729 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 9730 // A variable for which the type is pointer and an array section 9731 // derived from that variable must not appear as list items of map 9732 // clauses of the same construct. 9733 // 9734 // Also, cover one of the cases in: 9735 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 9736 // If any part of the original storage of a list item has corresponding 9737 // storage in the device data environment, all of the original storage 9738 // must have corresponding storage in the device data environment. 9739 // 9740 if (DerivedType->isAnyPointerType()) { 9741 if (CI == CE || SI == SE) { 9742 SemaRef.Diag( 9743 DerivedLoc, 9744 diag::err_omp_pointer_mapped_along_with_derived_section) 9745 << DerivedLoc; 9746 } else { 9747 assert(CI != CE && SI != SE); 9748 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced) 9749 << DerivedLoc; 9750 } 9751 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 9752 << RE->getSourceRange(); 9753 return true; 9754 } 9755 9756 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 9757 // List items of map clauses in the same construct must not share 9758 // original storage. 9759 // 9760 // An expression is a subset of the other. 9761 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 9762 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 9763 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 9764 << RE->getSourceRange(); 9765 return true; 9766 } 9767 9768 // The current expression uses the same base as other expression in the 9769 // data environment but does not contain it completelly. 9770 if (!CurrentRegionOnly && SI != SE) 9771 EnclosingExpr = RE; 9772 9773 // The current expression is a subset of the expression in the data 9774 // environment. 9775 IsEnclosedByDataEnvironmentExpr |= 9776 (!CurrentRegionOnly && CI != CE && SI == SE); 9777 9778 return false; 9779 }); 9780 9781 if (CurrentRegionOnly) 9782 return FoundError; 9783 9784 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 9785 // If any part of the original storage of a list item has corresponding 9786 // storage in the device data environment, all of the original storage must 9787 // have corresponding storage in the device data environment. 9788 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 9789 // If a list item is an element of a structure, and a different element of 9790 // the structure has a corresponding list item in the device data environment 9791 // prior to a task encountering the construct associated with the map clause, 9792 // then the list item must also have a correspnding list item in the device 9793 // data environment prior to the task encountering the construct. 9794 // 9795 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 9796 SemaRef.Diag(ELoc, 9797 diag::err_omp_original_storage_is_shared_and_does_not_contain) 9798 << ERange; 9799 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 9800 << EnclosingExpr->getSourceRange(); 9801 return true; 9802 } 9803 9804 return FoundError; 9805 } 9806 9807 OMPClause * 9808 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, 9809 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 9810 SourceLocation MapLoc, SourceLocation ColonLoc, 9811 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 9812 SourceLocation LParenLoc, SourceLocation EndLoc) { 9813 SmallVector<Expr *, 4> Vars; 9814 9815 for (auto &RE : VarList) { 9816 assert(RE && "Null expr in omp map"); 9817 if (isa<DependentScopeDeclRefExpr>(RE)) { 9818 // It will be analyzed later. 9819 Vars.push_back(RE); 9820 continue; 9821 } 9822 SourceLocation ELoc = RE->getExprLoc(); 9823 9824 auto *VE = RE->IgnoreParenLValueCasts(); 9825 9826 if (VE->isValueDependent() || VE->isTypeDependent() || 9827 VE->isInstantiationDependent() || 9828 VE->containsUnexpandedParameterPack()) { 9829 // We can only analyze this information once the missing information is 9830 // resolved. 9831 Vars.push_back(RE); 9832 continue; 9833 } 9834 9835 auto *SimpleExpr = RE->IgnoreParenCasts(); 9836 9837 if (!RE->IgnoreParenImpCasts()->isLValue()) { 9838 Diag(ELoc, diag::err_omp_expected_named_var_member_or_array_expression) 9839 << RE->getSourceRange(); 9840 continue; 9841 } 9842 9843 // Obtain the array or member expression bases if required. 9844 auto *BE = CheckMapClauseExpressionBase(*this, SimpleExpr); 9845 if (!BE) 9846 continue; 9847 9848 // If the base is a reference to a variable, we rely on that variable for 9849 // the following checks. If it is a 'this' expression we rely on the field. 9850 ValueDecl *D = nullptr; 9851 if (auto *DRE = dyn_cast<DeclRefExpr>(BE)) { 9852 D = DRE->getDecl(); 9853 } else { 9854 auto *ME = cast<MemberExpr>(BE); 9855 assert(isa<CXXThisExpr>(ME->getBase()) && "Unexpected expression!"); 9856 D = ME->getMemberDecl(); 9857 } 9858 assert(D && "Null decl on map clause."); 9859 9860 auto *VD = dyn_cast<VarDecl>(D); 9861 auto *FD = dyn_cast<FieldDecl>(D); 9862 9863 assert((VD || FD) && "Only variables or fields are expected here!"); 9864 (void)FD; 9865 9866 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 9867 // threadprivate variables cannot appear in a map clause. 9868 if (VD && DSAStack->isThreadPrivate(VD)) { 9869 auto DVar = DSAStack->getTopDSA(VD, false); 9870 Diag(ELoc, diag::err_omp_threadprivate_in_map); 9871 ReportOriginalDSA(*this, DSAStack, VD, DVar); 9872 continue; 9873 } 9874 9875 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 9876 // A list item cannot appear in both a map clause and a data-sharing 9877 // attribute clause on the same construct. 9878 // 9879 // TODO: Implement this check - it cannot currently be tested because of 9880 // missing implementation of the other data sharing clauses in target 9881 // directives. 9882 9883 // Check conflicts with other map clause expressions. We check the conflicts 9884 // with the current construct separately from the enclosing data 9885 // environment, because the restrictions are different. 9886 if (CheckMapConflicts(*this, DSAStack, D, SimpleExpr, 9887 /*CurrentRegionOnly=*/true)) 9888 break; 9889 if (CheckMapConflicts(*this, DSAStack, D, SimpleExpr, 9890 /*CurrentRegionOnly=*/false)) 9891 break; 9892 9893 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 9894 // If the type of a list item is a reference to a type T then the type will 9895 // be considered to be T for all purposes of this clause. 9896 QualType Type = D->getType(); 9897 if (Type->isReferenceType()) 9898 Type = Type->getPointeeType(); 9899 9900 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 9901 // A list item must have a mappable type. 9902 if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), *this, 9903 DSAStack, Type)) 9904 continue; 9905 9906 // target enter data 9907 // OpenMP [2.10.2, Restrictions, p. 99] 9908 // A map-type must be specified in all map clauses and must be either 9909 // to or alloc. 9910 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 9911 if (DKind == OMPD_target_enter_data && 9912 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 9913 Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 9914 << (IsMapTypeImplicit ? 1 : 0) 9915 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 9916 << getOpenMPDirectiveName(DKind); 9917 continue; 9918 } 9919 9920 // target exit_data 9921 // OpenMP [2.10.3, Restrictions, p. 102] 9922 // A map-type must be specified in all map clauses and must be either 9923 // from, release, or delete. 9924 DKind = DSAStack->getCurrentDirective(); 9925 if (DKind == OMPD_target_exit_data && 9926 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 9927 MapType == OMPC_MAP_delete)) { 9928 Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 9929 << (IsMapTypeImplicit ? 1 : 0) 9930 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 9931 << getOpenMPDirectiveName(DKind); 9932 continue; 9933 } 9934 9935 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 9936 // A list item cannot appear in both a map clause and a data-sharing 9937 // attribute clause on the same construct 9938 if (DKind == OMPD_target && VD) { 9939 auto DVar = DSAStack->getTopDSA(VD, false); 9940 if (isOpenMPPrivate(DVar.CKind)) { 9941 Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) 9942 << getOpenMPClauseName(DVar.CKind) 9943 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 9944 ReportOriginalDSA(*this, DSAStack, D, DVar); 9945 continue; 9946 } 9947 } 9948 9949 Vars.push_back(RE); 9950 DSAStack->addExprToVarMapInfo(D, RE); 9951 } 9952 9953 // We need to produce a map clause even if we don't have variables so that 9954 // other diagnostics related with non-existing map clauses are accurate. 9955 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 9956 MapTypeModifier, MapType, IsMapTypeImplicit, 9957 MapLoc); 9958 } 9959 9960 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 9961 TypeResult ParsedType) { 9962 assert(ParsedType.isUsable()); 9963 9964 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 9965 if (ReductionType.isNull()) 9966 return QualType(); 9967 9968 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 9969 // A type name in a declare reduction directive cannot be a function type, an 9970 // array type, a reference type, or a type qualified with const, volatile or 9971 // restrict. 9972 if (ReductionType.hasQualifiers()) { 9973 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 9974 return QualType(); 9975 } 9976 9977 if (ReductionType->isFunctionType()) { 9978 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 9979 return QualType(); 9980 } 9981 if (ReductionType->isReferenceType()) { 9982 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 9983 return QualType(); 9984 } 9985 if (ReductionType->isArrayType()) { 9986 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 9987 return QualType(); 9988 } 9989 return ReductionType; 9990 } 9991 9992 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 9993 Scope *S, DeclContext *DC, DeclarationName Name, 9994 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 9995 AccessSpecifier AS, Decl *PrevDeclInScope) { 9996 SmallVector<Decl *, 8> Decls; 9997 Decls.reserve(ReductionTypes.size()); 9998 9999 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 10000 ForRedeclaration); 10001 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 10002 // A reduction-identifier may not be re-declared in the current scope for the 10003 // same type or for a type that is compatible according to the base language 10004 // rules. 10005 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 10006 OMPDeclareReductionDecl *PrevDRD = nullptr; 10007 bool InCompoundScope = true; 10008 if (S != nullptr) { 10009 // Find previous declaration with the same name not referenced in other 10010 // declarations. 10011 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 10012 InCompoundScope = 10013 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 10014 LookupName(Lookup, S); 10015 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 10016 /*AllowInlineNamespace=*/false); 10017 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 10018 auto Filter = Lookup.makeFilter(); 10019 while (Filter.hasNext()) { 10020 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 10021 if (InCompoundScope) { 10022 auto I = UsedAsPrevious.find(PrevDecl); 10023 if (I == UsedAsPrevious.end()) 10024 UsedAsPrevious[PrevDecl] = false; 10025 if (auto *D = PrevDecl->getPrevDeclInScope()) 10026 UsedAsPrevious[D] = true; 10027 } 10028 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 10029 PrevDecl->getLocation(); 10030 } 10031 Filter.done(); 10032 if (InCompoundScope) { 10033 for (auto &PrevData : UsedAsPrevious) { 10034 if (!PrevData.second) { 10035 PrevDRD = PrevData.first; 10036 break; 10037 } 10038 } 10039 } 10040 } else if (PrevDeclInScope != nullptr) { 10041 auto *PrevDRDInScope = PrevDRD = 10042 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 10043 do { 10044 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 10045 PrevDRDInScope->getLocation(); 10046 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 10047 } while (PrevDRDInScope != nullptr); 10048 } 10049 for (auto &TyData : ReductionTypes) { 10050 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 10051 bool Invalid = false; 10052 if (I != PreviousRedeclTypes.end()) { 10053 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 10054 << TyData.first; 10055 Diag(I->second, diag::note_previous_definition); 10056 Invalid = true; 10057 } 10058 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 10059 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 10060 Name, TyData.first, PrevDRD); 10061 DC->addDecl(DRD); 10062 DRD->setAccess(AS); 10063 Decls.push_back(DRD); 10064 if (Invalid) 10065 DRD->setInvalidDecl(); 10066 else 10067 PrevDRD = DRD; 10068 } 10069 10070 return DeclGroupPtrTy::make( 10071 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 10072 } 10073 10074 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 10075 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10076 10077 // Enter new function scope. 10078 PushFunctionScope(); 10079 getCurFunction()->setHasBranchProtectedScope(); 10080 getCurFunction()->setHasOMPDeclareReductionCombiner(); 10081 10082 if (S != nullptr) 10083 PushDeclContext(S, DRD); 10084 else 10085 CurContext = DRD; 10086 10087 PushExpressionEvaluationContext(PotentiallyEvaluated); 10088 10089 QualType ReductionType = DRD->getType(); 10090 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 10091 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 10092 // uses semantics of argument handles by value, but it should be passed by 10093 // reference. C lang does not support references, so pass all parameters as 10094 // pointers. 10095 // Create 'T omp_in;' variable. 10096 auto *OmpInParm = 10097 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 10098 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 10099 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 10100 // uses semantics of argument handles by value, but it should be passed by 10101 // reference. C lang does not support references, so pass all parameters as 10102 // pointers. 10103 // Create 'T omp_out;' variable. 10104 auto *OmpOutParm = 10105 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 10106 if (S != nullptr) { 10107 PushOnScopeChains(OmpInParm, S); 10108 PushOnScopeChains(OmpOutParm, S); 10109 } else { 10110 DRD->addDecl(OmpInParm); 10111 DRD->addDecl(OmpOutParm); 10112 } 10113 } 10114 10115 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 10116 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10117 DiscardCleanupsInEvaluationContext(); 10118 PopExpressionEvaluationContext(); 10119 10120 PopDeclContext(); 10121 PopFunctionScopeInfo(); 10122 10123 if (Combiner != nullptr) 10124 DRD->setCombiner(Combiner); 10125 else 10126 DRD->setInvalidDecl(); 10127 } 10128 10129 void Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 10130 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10131 10132 // Enter new function scope. 10133 PushFunctionScope(); 10134 getCurFunction()->setHasBranchProtectedScope(); 10135 10136 if (S != nullptr) 10137 PushDeclContext(S, DRD); 10138 else 10139 CurContext = DRD; 10140 10141 PushExpressionEvaluationContext(PotentiallyEvaluated); 10142 10143 QualType ReductionType = DRD->getType(); 10144 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 10145 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 10146 // uses semantics of argument handles by value, but it should be passed by 10147 // reference. C lang does not support references, so pass all parameters as 10148 // pointers. 10149 // Create 'T omp_priv;' variable. 10150 auto *OmpPrivParm = 10151 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 10152 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 10153 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 10154 // uses semantics of argument handles by value, but it should be passed by 10155 // reference. C lang does not support references, so pass all parameters as 10156 // pointers. 10157 // Create 'T omp_orig;' variable. 10158 auto *OmpOrigParm = 10159 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 10160 if (S != nullptr) { 10161 PushOnScopeChains(OmpPrivParm, S); 10162 PushOnScopeChains(OmpOrigParm, S); 10163 } else { 10164 DRD->addDecl(OmpPrivParm); 10165 DRD->addDecl(OmpOrigParm); 10166 } 10167 } 10168 10169 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, 10170 Expr *Initializer) { 10171 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10172 DiscardCleanupsInEvaluationContext(); 10173 PopExpressionEvaluationContext(); 10174 10175 PopDeclContext(); 10176 PopFunctionScopeInfo(); 10177 10178 if (Initializer != nullptr) 10179 DRD->setInitializer(Initializer); 10180 else 10181 DRD->setInvalidDecl(); 10182 } 10183 10184 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 10185 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 10186 for (auto *D : DeclReductions.get()) { 10187 if (IsValid) { 10188 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10189 if (S != nullptr) 10190 PushOnScopeChains(DRD, S, /*AddToContext=*/false); 10191 } else 10192 D->setInvalidDecl(); 10193 } 10194 return DeclReductions; 10195 } 10196 10197 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 10198 SourceLocation StartLoc, 10199 SourceLocation LParenLoc, 10200 SourceLocation EndLoc) { 10201 Expr *ValExpr = NumTeams; 10202 10203 // OpenMP [teams Constrcut, Restrictions] 10204 // The num_teams expression must evaluate to a positive integer value. 10205 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 10206 /*StrictlyPositive=*/true)) 10207 return nullptr; 10208 10209 return new (Context) OMPNumTeamsClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10210 } 10211 10212 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 10213 SourceLocation StartLoc, 10214 SourceLocation LParenLoc, 10215 SourceLocation EndLoc) { 10216 Expr *ValExpr = ThreadLimit; 10217 10218 // OpenMP [teams Constrcut, Restrictions] 10219 // The thread_limit expression must evaluate to a positive integer value. 10220 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 10221 /*StrictlyPositive=*/true)) 10222 return nullptr; 10223 10224 return new (Context) OMPThreadLimitClause(ValExpr, StartLoc, LParenLoc, 10225 EndLoc); 10226 } 10227 10228 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 10229 SourceLocation StartLoc, 10230 SourceLocation LParenLoc, 10231 SourceLocation EndLoc) { 10232 Expr *ValExpr = Priority; 10233 10234 // OpenMP [2.9.1, task Constrcut] 10235 // The priority-value is a non-negative numerical scalar expression. 10236 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 10237 /*StrictlyPositive=*/false)) 10238 return nullptr; 10239 10240 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10241 } 10242 10243 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 10244 SourceLocation StartLoc, 10245 SourceLocation LParenLoc, 10246 SourceLocation EndLoc) { 10247 Expr *ValExpr = Grainsize; 10248 10249 // OpenMP [2.9.2, taskloop Constrcut] 10250 // The parameter of the grainsize clause must be a positive integer 10251 // expression. 10252 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 10253 /*StrictlyPositive=*/true)) 10254 return nullptr; 10255 10256 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10257 } 10258 10259 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 10260 SourceLocation StartLoc, 10261 SourceLocation LParenLoc, 10262 SourceLocation EndLoc) { 10263 Expr *ValExpr = NumTasks; 10264 10265 // OpenMP [2.9.2, taskloop Constrcut] 10266 // The parameter of the num_tasks clause must be a positive integer 10267 // expression. 10268 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 10269 /*StrictlyPositive=*/true)) 10270 return nullptr; 10271 10272 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10273 } 10274 10275 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 10276 SourceLocation LParenLoc, 10277 SourceLocation EndLoc) { 10278 // OpenMP [2.13.2, critical construct, Description] 10279 // ... where hint-expression is an integer constant expression that evaluates 10280 // to a valid lock hint. 10281 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 10282 if (HintExpr.isInvalid()) 10283 return nullptr; 10284 return new (Context) 10285 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 10286 } 10287 10288 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 10289 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10290 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 10291 SourceLocation EndLoc) { 10292 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 10293 std::string Values; 10294 Values += "'"; 10295 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 10296 Values += "'"; 10297 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 10298 << Values << getOpenMPClauseName(OMPC_dist_schedule); 10299 return nullptr; 10300 } 10301 Expr *ValExpr = ChunkSize; 10302 Stmt *HelperValStmt = nullptr; 10303 if (ChunkSize) { 10304 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 10305 !ChunkSize->isInstantiationDependent() && 10306 !ChunkSize->containsUnexpandedParameterPack()) { 10307 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 10308 ExprResult Val = 10309 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 10310 if (Val.isInvalid()) 10311 return nullptr; 10312 10313 ValExpr = Val.get(); 10314 10315 // OpenMP [2.7.1, Restrictions] 10316 // chunk_size must be a loop invariant integer expression with a positive 10317 // value. 10318 llvm::APSInt Result; 10319 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 10320 if (Result.isSigned() && !Result.isStrictlyPositive()) { 10321 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 10322 << "dist_schedule" << ChunkSize->getSourceRange(); 10323 return nullptr; 10324 } 10325 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 10326 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 10327 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10328 HelperValStmt = buildPreInits(Context, Captures); 10329 } 10330 } 10331 } 10332 10333 return new (Context) 10334 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 10335 Kind, ValExpr, HelperValStmt); 10336 } 10337 10338 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 10339 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 10340 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 10341 SourceLocation KindLoc, SourceLocation EndLoc) { 10342 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 10343 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 10344 Kind != OMPC_DEFAULTMAP_scalar) { 10345 std::string Value; 10346 SourceLocation Loc; 10347 Value += "'"; 10348 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 10349 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 10350 OMPC_DEFAULTMAP_MODIFIER_tofrom); 10351 Loc = MLoc; 10352 } else { 10353 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 10354 OMPC_DEFAULTMAP_scalar); 10355 Loc = KindLoc; 10356 } 10357 Value += "'"; 10358 Diag(Loc, diag::err_omp_unexpected_clause_value) 10359 << Value << getOpenMPClauseName(OMPC_defaultmap); 10360 return nullptr; 10361 } 10362 10363 return new (Context) 10364 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 10365 } 10366 10367 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 10368 DeclContext *CurLexicalContext = getCurLexicalContext(); 10369 if (!CurLexicalContext->isFileContext() && 10370 !CurLexicalContext->isExternCContext() && 10371 !CurLexicalContext->isExternCXXContext()) { 10372 Diag(Loc, diag::err_omp_region_not_file_context); 10373 return false; 10374 } 10375 if (IsInOpenMPDeclareTargetContext) { 10376 Diag(Loc, diag::err_omp_enclosed_declare_target); 10377 return false; 10378 } 10379 10380 IsInOpenMPDeclareTargetContext = true; 10381 return true; 10382 } 10383 10384 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 10385 assert(IsInOpenMPDeclareTargetContext && 10386 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 10387 10388 IsInOpenMPDeclareTargetContext = false; 10389 } 10390 10391 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 10392 Sema &SemaRef, Decl *D) { 10393 if (!D) 10394 return; 10395 Decl *LD = nullptr; 10396 if (isa<TagDecl>(D)) { 10397 LD = cast<TagDecl>(D)->getDefinition(); 10398 } else if (isa<VarDecl>(D)) { 10399 LD = cast<VarDecl>(D)->getDefinition(); 10400 10401 // If this is an implicit variable that is legal and we do not need to do 10402 // anything. 10403 if (cast<VarDecl>(D)->isImplicit()) { 10404 D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(SemaRef.Context)); 10405 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 10406 ML->DeclarationMarkedOpenMPDeclareTarget(D); 10407 return; 10408 } 10409 10410 } else if (isa<FunctionDecl>(D)) { 10411 const FunctionDecl *FD = nullptr; 10412 if (cast<FunctionDecl>(D)->hasBody(FD)) 10413 LD = const_cast<FunctionDecl *>(FD); 10414 10415 // If the definition is associated with the current declaration in the 10416 // target region (it can be e.g. a lambda) that is legal and we do not need 10417 // to do anything else. 10418 if (LD == D) { 10419 D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(SemaRef.Context)); 10420 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 10421 ML->DeclarationMarkedOpenMPDeclareTarget(D); 10422 return; 10423 } 10424 } 10425 if (!LD) 10426 LD = D; 10427 if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() && 10428 (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) { 10429 // Outlined declaration is not declared target. 10430 if (LD->isOutOfLine()) { 10431 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 10432 SemaRef.Diag(SL, diag::note_used_here) << SR; 10433 } else { 10434 DeclContext *DC = LD->getDeclContext(); 10435 while (DC) { 10436 if (isa<FunctionDecl>(DC) && 10437 cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>()) 10438 break; 10439 DC = DC->getParent(); 10440 } 10441 if (DC) 10442 return; 10443 10444 // Is not declared in target context. 10445 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 10446 SemaRef.Diag(SL, diag::note_used_here) << SR; 10447 } 10448 // Mark decl as declared target to prevent further diagnostic. 10449 D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(SemaRef.Context)); 10450 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 10451 ML->DeclarationMarkedOpenMPDeclareTarget(D); 10452 } 10453 } 10454 10455 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 10456 Sema &SemaRef, DSAStackTy *Stack, 10457 ValueDecl *VD) { 10458 if (VD->hasAttr<OMPDeclareTargetDeclAttr>()) 10459 return true; 10460 if (!CheckTypeMappable(SL, SR, SemaRef, Stack, VD->getType())) 10461 return false; 10462 return true; 10463 } 10464 10465 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D) { 10466 if (!D || D->isInvalidDecl()) 10467 return; 10468 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 10469 SourceLocation SL = E ? E->getLocStart() : D->getLocation(); 10470 // 2.10.6: threadprivate variable cannot appear in a declare target directive. 10471 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 10472 if (DSAStack->isThreadPrivate(VD)) { 10473 Diag(SL, diag::err_omp_threadprivate_in_target); 10474 ReportOriginalDSA(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 10475 return; 10476 } 10477 } 10478 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 10479 // Problem if any with var declared with incomplete type will be reported 10480 // as normal, so no need to check it here. 10481 if ((E || !VD->getType()->isIncompleteType()) && 10482 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) { 10483 // Mark decl as declared target to prevent further diagnostic. 10484 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) { 10485 VD->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(Context)); 10486 if (ASTMutationListener *ML = Context.getASTMutationListener()) 10487 ML->DeclarationMarkedOpenMPDeclareTarget(VD); 10488 } 10489 return; 10490 } 10491 } 10492 if (!E) { 10493 // Checking declaration inside declare target region. 10494 if (!D->hasAttr<OMPDeclareTargetDeclAttr>() && 10495 (isa<VarDecl>(D) || isa<FunctionDecl>(D))) { 10496 D->addAttr(OMPDeclareTargetDeclAttr::CreateImplicit(Context)); 10497 if (ASTMutationListener *ML = Context.getASTMutationListener()) 10498 ML->DeclarationMarkedOpenMPDeclareTarget(D); 10499 } 10500 return; 10501 } 10502 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 10503 } 10504