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