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