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 /// \brief Stack for tracking declarations used in OpenMP directives and 49 /// clauses and their data-sharing attributes. 50 class DSAStackTy final { 51 public: 52 struct DSAVarData final { 53 OpenMPDirectiveKind DKind = OMPD_unknown; 54 OpenMPClauseKind CKind = OMPC_unknown; 55 Expr *RefExpr = nullptr; 56 DeclRefExpr *PrivateCopy = nullptr; 57 SourceLocation ImplicitDSALoc; 58 DSAVarData() {} 59 }; 60 typedef llvm::SmallVector<std::pair<Expr *, OverloadedOperatorKind>, 4> 61 OperatorOffsetTy; 62 63 private: 64 struct DSAInfo final { 65 OpenMPClauseKind Attributes = OMPC_unknown; 66 /// Pointer to a reference expression and a flag which shows that the 67 /// variable is marked as lastprivate(true) or not (false). 68 llvm::PointerIntPair<Expr *, 1, bool> RefExpr; 69 DeclRefExpr *PrivateCopy = nullptr; 70 }; 71 typedef llvm::DenseMap<ValueDecl *, DSAInfo> DeclSAMapTy; 72 typedef llvm::DenseMap<ValueDecl *, Expr *> AlignedMapTy; 73 typedef std::pair<unsigned, VarDecl *> LCDeclInfo; 74 typedef llvm::DenseMap<ValueDecl *, LCDeclInfo> LoopControlVariablesMapTy; 75 typedef llvm::DenseMap< 76 ValueDecl *, OMPClauseMappableExprCommon::MappableExprComponentLists> 77 MappedExprComponentsTy; 78 typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>> 79 CriticalsWithHintsTy; 80 typedef llvm::DenseMap<OMPDependClause *, OperatorOffsetTy> 81 DoacrossDependMapTy; 82 83 struct SharingMapTy final { 84 DeclSAMapTy SharingMap; 85 AlignedMapTy AlignedMap; 86 MappedExprComponentsTy MappedExprComponents; 87 LoopControlVariablesMapTy LCVMap; 88 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 89 SourceLocation DefaultAttrLoc; 90 OpenMPDirectiveKind Directive = OMPD_unknown; 91 DeclarationNameInfo DirectiveName; 92 Scope *CurScope = nullptr; 93 SourceLocation ConstructLoc; 94 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 95 /// get the data (loop counters etc.) about enclosing loop-based construct. 96 /// This data is required during codegen. 97 DoacrossDependMapTy DoacrossDepends; 98 /// \brief first argument (Expr *) contains optional argument of the 99 /// 'ordered' clause, the second one is true if the regions has 'ordered' 100 /// clause, false otherwise. 101 llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion; 102 bool NowaitRegion = false; 103 bool CancelRegion = false; 104 unsigned AssociatedLoops = 1; 105 SourceLocation InnerTeamsRegionLoc; 106 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 107 Scope *CurScope, SourceLocation Loc) 108 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 109 ConstructLoc(Loc) {} 110 SharingMapTy() {} 111 }; 112 113 typedef SmallVector<SharingMapTy, 4> StackTy; 114 115 /// \brief Stack of used declaration and their data-sharing attributes. 116 StackTy Stack; 117 /// \brief true, if check for DSA must be from parent directive, false, if 118 /// from current directive. 119 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 120 Sema &SemaRef; 121 bool ForceCapturing = false; 122 CriticalsWithHintsTy Criticals; 123 124 typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; 125 126 DSAVarData getDSA(StackTy::reverse_iterator& Iter, ValueDecl *D); 127 128 /// \brief Checks if the variable is a local for OpenMP region. 129 bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter); 130 131 public: 132 explicit DSAStackTy(Sema &S) : Stack(1), SemaRef(S) {} 133 134 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 135 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 136 137 bool isForceVarCapturing() const { return ForceCapturing; } 138 void setForceVarCapturing(bool V) { ForceCapturing = V; } 139 140 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 141 Scope *CurScope, SourceLocation Loc) { 142 Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc)); 143 Stack.back().DefaultAttrLoc = Loc; 144 } 145 146 void pop() { 147 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!"); 148 Stack.pop_back(); 149 } 150 151 void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) { 152 Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint); 153 } 154 const std::pair<OMPCriticalDirective *, llvm::APSInt> 155 getCriticalWithHint(const DeclarationNameInfo &Name) const { 156 auto I = Criticals.find(Name.getAsString()); 157 if (I != Criticals.end()) 158 return I->second; 159 return std::make_pair(nullptr, llvm::APSInt()); 160 } 161 /// \brief If 'aligned' declaration for given variable \a D was not seen yet, 162 /// add it and return NULL; otherwise return previous occurrence's expression 163 /// for diagnostics. 164 Expr *addUniqueAligned(ValueDecl *D, Expr *NewDE); 165 166 /// \brief Register specified variable as loop control variable. 167 void addLoopControlVariable(ValueDecl *D, VarDecl *Capture); 168 /// \brief Check if the specified variable is a loop control variable for 169 /// current region. 170 /// \return The index of the loop control variable in the list of associated 171 /// for-loops (from outer to inner). 172 LCDeclInfo isLoopControlVariable(ValueDecl *D); 173 /// \brief Check if the specified variable is a loop control variable for 174 /// parent region. 175 /// \return The index of the loop control variable in the list of associated 176 /// for-loops (from outer to inner). 177 LCDeclInfo isParentLoopControlVariable(ValueDecl *D); 178 /// \brief Get the loop control variable for the I-th loop (or nullptr) in 179 /// parent directive. 180 ValueDecl *getParentLoopControlVariable(unsigned I); 181 182 /// \brief Adds explicit data sharing attribute to the specified declaration. 183 void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 184 DeclRefExpr *PrivateCopy = nullptr); 185 186 /// \brief Returns data sharing attributes from top of the stack for the 187 /// specified declaration. 188 DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 189 /// \brief Returns data-sharing attributes for the specified declaration. 190 DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent); 191 /// \brief Checks if the specified variables has data-sharing attributes which 192 /// match specified \a CPred predicate in any directive which matches \a DPred 193 /// predicate. 194 DSAVarData hasDSA(ValueDecl *D, 195 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 196 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 197 bool FromParent); 198 /// \brief Checks if the specified variables has data-sharing attributes which 199 /// match specified \a CPred predicate in any innermost directive which 200 /// matches \a DPred predicate. 201 DSAVarData 202 hasInnermostDSA(ValueDecl *D, 203 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 204 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 205 bool FromParent); 206 /// \brief Checks if the specified variables has explicit data-sharing 207 /// attributes which match specified \a CPred predicate at the specified 208 /// OpenMP region. 209 bool hasExplicitDSA(ValueDecl *D, 210 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 211 unsigned Level, bool NotLastprivate = false); 212 213 /// \brief Returns true if the directive at level \Level matches in the 214 /// specified \a DPred predicate. 215 bool hasExplicitDirective( 216 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 217 unsigned Level); 218 219 /// \brief Finds a directive which matches specified \a DPred predicate. 220 bool hasDirective(const llvm::function_ref<bool(OpenMPDirectiveKind, 221 const DeclarationNameInfo &, 222 SourceLocation)> &DPred, 223 bool FromParent); 224 225 /// \brief Returns currently analyzed directive. 226 OpenMPDirectiveKind getCurrentDirective() const { 227 return Stack.back().Directive; 228 } 229 /// \brief Returns parent directive. 230 OpenMPDirectiveKind getParentDirective() const { 231 if (Stack.size() > 2) 232 return Stack[Stack.size() - 2].Directive; 233 return OMPD_unknown; 234 } 235 236 /// \brief Set default data sharing attribute to none. 237 void setDefaultDSANone(SourceLocation Loc) { 238 Stack.back().DefaultAttr = DSA_none; 239 Stack.back().DefaultAttrLoc = Loc; 240 } 241 /// \brief Set default data sharing attribute to shared. 242 void setDefaultDSAShared(SourceLocation Loc) { 243 Stack.back().DefaultAttr = DSA_shared; 244 Stack.back().DefaultAttrLoc = Loc; 245 } 246 247 DefaultDataSharingAttributes getDefaultDSA() const { 248 return Stack.back().DefaultAttr; 249 } 250 SourceLocation getDefaultDSALocation() const { 251 return Stack.back().DefaultAttrLoc; 252 } 253 254 /// \brief Checks if the specified variable is a threadprivate. 255 bool isThreadPrivate(VarDecl *D) { 256 DSAVarData DVar = getTopDSA(D, false); 257 return isOpenMPThreadPrivate(DVar.CKind); 258 } 259 260 /// \brief Marks current region as ordered (it has an 'ordered' clause). 261 void setOrderedRegion(bool IsOrdered, Expr *Param) { 262 Stack.back().OrderedRegion.setInt(IsOrdered); 263 Stack.back().OrderedRegion.setPointer(Param); 264 } 265 /// \brief Returns true, if parent region is ordered (has associated 266 /// 'ordered' clause), false - otherwise. 267 bool isParentOrderedRegion() const { 268 if (Stack.size() > 2) 269 return Stack[Stack.size() - 2].OrderedRegion.getInt(); 270 return false; 271 } 272 /// \brief Returns optional parameter for the ordered region. 273 Expr *getParentOrderedRegionParam() const { 274 if (Stack.size() > 2) 275 return Stack[Stack.size() - 2].OrderedRegion.getPointer(); 276 return nullptr; 277 } 278 /// \brief Marks current region as nowait (it has a 'nowait' clause). 279 void setNowaitRegion(bool IsNowait = true) { 280 Stack.back().NowaitRegion = IsNowait; 281 } 282 /// \brief Returns true, if parent region is nowait (has associated 283 /// 'nowait' clause), false - otherwise. 284 bool isParentNowaitRegion() const { 285 if (Stack.size() > 2) 286 return Stack[Stack.size() - 2].NowaitRegion; 287 return false; 288 } 289 /// \brief Marks parent region as cancel region. 290 void setParentCancelRegion(bool Cancel = true) { 291 if (Stack.size() > 2) 292 Stack[Stack.size() - 2].CancelRegion = 293 Stack[Stack.size() - 2].CancelRegion || Cancel; 294 } 295 /// \brief Return true if current region has inner cancel construct. 296 bool isCancelRegion() const { 297 return Stack.back().CancelRegion; 298 } 299 300 /// \brief Set collapse value for the region. 301 void setAssociatedLoops(unsigned Val) { Stack.back().AssociatedLoops = Val; } 302 /// \brief Return collapse value for region. 303 unsigned getAssociatedLoops() const { return Stack.back().AssociatedLoops; } 304 305 /// \brief Marks current target region as one with closely nested teams 306 /// region. 307 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 308 if (Stack.size() > 2) 309 Stack[Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc; 310 } 311 /// \brief Returns true, if current region has closely nested teams region. 312 bool hasInnerTeamsRegion() const { 313 return getInnerTeamsRegionLoc().isValid(); 314 } 315 /// \brief Returns location of the nested teams region (if any). 316 SourceLocation getInnerTeamsRegionLoc() const { 317 if (Stack.size() > 1) 318 return Stack.back().InnerTeamsRegionLoc; 319 return SourceLocation(); 320 } 321 322 Scope *getCurScope() const { return Stack.back().CurScope; } 323 Scope *getCurScope() { return Stack.back().CurScope; } 324 SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; } 325 326 // Do the check specified in \a Check to all component lists and return true 327 // if any issue is found. 328 bool checkMappableExprComponentListsForDecl( 329 ValueDecl *VD, bool CurrentRegionOnly, 330 const llvm::function_ref<bool( 331 OMPClauseMappableExprCommon::MappableExprComponentListRef)> &Check) { 332 auto SI = Stack.rbegin(); 333 auto SE = Stack.rend(); 334 335 if (SI == SE) 336 return false; 337 338 if (CurrentRegionOnly) { 339 SE = std::next(SI); 340 } else { 341 ++SI; 342 } 343 344 for (; SI != SE; ++SI) { 345 auto MI = SI->MappedExprComponents.find(VD); 346 if (MI != SI->MappedExprComponents.end()) 347 for (auto &L : MI->second) 348 if (Check(L)) 349 return true; 350 } 351 return false; 352 } 353 354 // Create a new mappable expression component list associated with a given 355 // declaration and initialize it with the provided list of components. 356 void addMappableExpressionComponents( 357 ValueDecl *VD, 358 OMPClauseMappableExprCommon::MappableExprComponentListRef Components) { 359 assert(Stack.size() > 1 && 360 "Not expecting to retrieve components from a empty stack!"); 361 auto &MEC = Stack.back().MappedExprComponents[VD]; 362 // Create new entry and append the new components there. 363 MEC.resize(MEC.size() + 1); 364 MEC.back().append(Components.begin(), Components.end()); 365 } 366 367 unsigned getNestingLevel() const { 368 assert(Stack.size() > 1); 369 return Stack.size() - 2; 370 } 371 void addDoacrossDependClause(OMPDependClause *C, OperatorOffsetTy &OpsOffs) { 372 assert(Stack.size() > 2); 373 assert(isOpenMPWorksharingDirective(Stack[Stack.size() - 2].Directive)); 374 Stack[Stack.size() - 2].DoacrossDepends.insert({C, OpsOffs}); 375 } 376 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 377 getDoacrossDependClauses() const { 378 assert(Stack.size() > 1); 379 if (isOpenMPWorksharingDirective(Stack[Stack.size() - 1].Directive)) { 380 auto &Ref = Stack[Stack.size() - 1].DoacrossDepends; 381 return llvm::make_range(Ref.begin(), Ref.end()); 382 } 383 return llvm::make_range(Stack[0].DoacrossDepends.end(), 384 Stack[0].DoacrossDepends.end()); 385 } 386 }; 387 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { 388 return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) || 389 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; 390 } 391 } // namespace 392 393 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 394 auto *VD = dyn_cast<VarDecl>(D); 395 auto *FD = dyn_cast<FieldDecl>(D); 396 if (VD != nullptr) { 397 VD = VD->getCanonicalDecl(); 398 D = VD; 399 } else { 400 assert(FD); 401 FD = FD->getCanonicalDecl(); 402 D = FD; 403 } 404 return D; 405 } 406 407 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator& Iter, 408 ValueDecl *D) { 409 D = getCanonicalDecl(D); 410 auto *VD = dyn_cast<VarDecl>(D); 411 auto *FD = dyn_cast<FieldDecl>(D); 412 DSAVarData DVar; 413 if (Iter == std::prev(Stack.rend())) { 414 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 415 // in a region but not in construct] 416 // File-scope or namespace-scope variables referenced in called routines 417 // in the region are shared unless they appear in a threadprivate 418 // directive. 419 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D)) 420 DVar.CKind = OMPC_shared; 421 422 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 423 // in a region but not in construct] 424 // Variables with static storage duration that are declared in called 425 // routines in the region are shared. 426 if (VD && VD->hasGlobalStorage()) 427 DVar.CKind = OMPC_shared; 428 429 // Non-static data members are shared by default. 430 if (FD) 431 DVar.CKind = OMPC_shared; 432 433 return DVar; 434 } 435 436 DVar.DKind = Iter->Directive; 437 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 438 // in a Construct, C/C++, predetermined, p.1] 439 // Variables with automatic storage duration that are declared in a scope 440 // inside the construct are private. 441 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 442 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 443 DVar.CKind = OMPC_private; 444 return DVar; 445 } 446 447 // Explicitly specified attributes and local variables with predetermined 448 // attributes. 449 if (Iter->SharingMap.count(D)) { 450 DVar.RefExpr = Iter->SharingMap[D].RefExpr.getPointer(); 451 DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy; 452 DVar.CKind = Iter->SharingMap[D].Attributes; 453 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 454 return DVar; 455 } 456 457 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 458 // in a Construct, C/C++, implicitly determined, p.1] 459 // In a parallel or task construct, the data-sharing attributes of these 460 // variables are determined by the default clause, if present. 461 switch (Iter->DefaultAttr) { 462 case DSA_shared: 463 DVar.CKind = OMPC_shared; 464 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 465 return DVar; 466 case DSA_none: 467 return DVar; 468 case DSA_unspecified: 469 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 470 // in a Construct, implicitly determined, p.2] 471 // In a parallel construct, if no default clause is present, these 472 // variables are shared. 473 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 474 if (isOpenMPParallelDirective(DVar.DKind) || 475 isOpenMPTeamsDirective(DVar.DKind)) { 476 DVar.CKind = OMPC_shared; 477 return DVar; 478 } 479 480 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 481 // in a Construct, implicitly determined, p.4] 482 // In a task construct, if no default clause is present, a variable that in 483 // the enclosing context is determined to be shared by all implicit tasks 484 // bound to the current team is shared. 485 if (isOpenMPTaskingDirective(DVar.DKind)) { 486 DSAVarData DVarTemp; 487 for (StackTy::reverse_iterator I = std::next(Iter), EE = Stack.rend(); 488 I != EE; ++I) { 489 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 490 // Referenced in a Construct, implicitly determined, p.6] 491 // In a task construct, if no default clause is present, a variable 492 // whose data-sharing attribute is not determined by the rules above is 493 // firstprivate. 494 DVarTemp = getDSA(I, D); 495 if (DVarTemp.CKind != OMPC_shared) { 496 DVar.RefExpr = nullptr; 497 DVar.CKind = OMPC_firstprivate; 498 return DVar; 499 } 500 if (isParallelOrTaskRegion(I->Directive)) 501 break; 502 } 503 DVar.CKind = 504 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 505 return DVar; 506 } 507 } 508 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 509 // in a Construct, implicitly determined, p.3] 510 // For constructs other than task, if no default clause is present, these 511 // variables inherit their data-sharing attributes from the enclosing 512 // context. 513 return getDSA(++Iter, D); 514 } 515 516 Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) { 517 assert(Stack.size() > 1 && "Data sharing attributes stack is empty"); 518 D = getCanonicalDecl(D); 519 auto It = Stack.back().AlignedMap.find(D); 520 if (It == Stack.back().AlignedMap.end()) { 521 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 522 Stack.back().AlignedMap[D] = NewDE; 523 return nullptr; 524 } else { 525 assert(It->second && "Unexpected nullptr expr in the aligned map"); 526 return It->second; 527 } 528 return nullptr; 529 } 530 531 void DSAStackTy::addLoopControlVariable(ValueDecl *D, VarDecl *Capture) { 532 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 533 D = getCanonicalDecl(D); 534 Stack.back().LCVMap.insert( 535 std::make_pair(D, LCDeclInfo(Stack.back().LCVMap.size() + 1, Capture))); 536 } 537 538 DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(ValueDecl *D) { 539 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 540 D = getCanonicalDecl(D); 541 return Stack.back().LCVMap.count(D) > 0 ? Stack.back().LCVMap[D] 542 : LCDeclInfo(0, nullptr); 543 } 544 545 DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(ValueDecl *D) { 546 assert(Stack.size() > 2 && "Data-sharing attributes stack is empty"); 547 D = getCanonicalDecl(D); 548 return Stack[Stack.size() - 2].LCVMap.count(D) > 0 549 ? Stack[Stack.size() - 2].LCVMap[D] 550 : LCDeclInfo(0, nullptr); 551 } 552 553 ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) { 554 assert(Stack.size() > 2 && "Data-sharing attributes stack is empty"); 555 if (Stack[Stack.size() - 2].LCVMap.size() < I) 556 return nullptr; 557 for (auto &Pair : Stack[Stack.size() - 2].LCVMap) { 558 if (Pair.second.first == I) 559 return Pair.first; 560 } 561 return nullptr; 562 } 563 564 void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 565 DeclRefExpr *PrivateCopy) { 566 D = getCanonicalDecl(D); 567 if (A == OMPC_threadprivate) { 568 auto &Data = Stack[0].SharingMap[D]; 569 Data.Attributes = A; 570 Data.RefExpr.setPointer(E); 571 Data.PrivateCopy = nullptr; 572 } else { 573 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 574 auto &Data = Stack.back().SharingMap[D]; 575 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 576 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 577 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 578 (isLoopControlVariable(D).first && A == OMPC_private)); 579 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 580 Data.RefExpr.setInt(/*IntVal=*/true); 581 return; 582 } 583 const bool IsLastprivate = 584 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 585 Data.Attributes = A; 586 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 587 Data.PrivateCopy = PrivateCopy; 588 if (PrivateCopy) { 589 auto &Data = Stack.back().SharingMap[PrivateCopy->getDecl()]; 590 Data.Attributes = A; 591 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 592 Data.PrivateCopy = nullptr; 593 } 594 } 595 } 596 597 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) { 598 D = D->getCanonicalDecl(); 599 if (Stack.size() > 2) { 600 reverse_iterator I = Iter, E = std::prev(Stack.rend()); 601 Scope *TopScope = nullptr; 602 while (I != E && !isParallelOrTaskRegion(I->Directive)) { 603 ++I; 604 } 605 if (I == E) 606 return false; 607 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 608 Scope *CurScope = getCurScope(); 609 while (CurScope != TopScope && !CurScope->isDeclScope(D)) { 610 CurScope = CurScope->getParent(); 611 } 612 return CurScope != TopScope; 613 } 614 return false; 615 } 616 617 /// \brief Build a variable declaration for OpenMP loop iteration variable. 618 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 619 StringRef Name, const AttrVec *Attrs = nullptr) { 620 DeclContext *DC = SemaRef.CurContext; 621 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 622 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 623 VarDecl *Decl = 624 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 625 if (Attrs) { 626 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 627 I != E; ++I) 628 Decl->addAttr(*I); 629 } 630 Decl->setImplicit(); 631 return Decl; 632 } 633 634 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 635 SourceLocation Loc, 636 bool RefersToCapture = false) { 637 D->setReferenced(); 638 D->markUsed(S.Context); 639 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 640 SourceLocation(), D, RefersToCapture, Loc, Ty, 641 VK_LValue); 642 } 643 644 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) { 645 D = getCanonicalDecl(D); 646 DSAVarData DVar; 647 648 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 649 // in a Construct, C/C++, predetermined, p.1] 650 // Variables appearing in threadprivate directives are threadprivate. 651 auto *VD = dyn_cast<VarDecl>(D); 652 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 653 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 654 SemaRef.getLangOpts().OpenMPUseTLS && 655 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 656 (VD && VD->getStorageClass() == SC_Register && 657 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 658 addDSA(D, buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 659 D->getLocation()), 660 OMPC_threadprivate); 661 } 662 if (Stack[0].SharingMap.count(D)) { 663 DVar.RefExpr = Stack[0].SharingMap[D].RefExpr.getPointer(); 664 DVar.CKind = OMPC_threadprivate; 665 return DVar; 666 } 667 668 if (Stack.size() == 1) { 669 // Not in OpenMP execution region and top scope was already checked. 670 return DVar; 671 } 672 673 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 674 // in a Construct, C/C++, predetermined, p.4] 675 // Static data members are shared. 676 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 677 // in a Construct, C/C++, predetermined, p.7] 678 // Variables with static storage duration that are declared in a scope 679 // inside the construct are shared. 680 auto &&MatchesAlways = [](OpenMPDirectiveKind) -> bool { return true; }; 681 if (VD && VD->isStaticDataMember()) { 682 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 683 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 684 return DVar; 685 686 DVar.CKind = OMPC_shared; 687 return DVar; 688 } 689 690 QualType Type = D->getType().getNonReferenceType().getCanonicalType(); 691 bool IsConstant = Type.isConstant(SemaRef.getASTContext()); 692 Type = SemaRef.getASTContext().getBaseElementType(Type); 693 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 694 // in a Construct, C/C++, predetermined, p.6] 695 // Variables with const qualified type having no mutable member are 696 // shared. 697 CXXRecordDecl *RD = 698 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 699 if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 700 if (auto *CTD = CTSD->getSpecializedTemplate()) 701 RD = CTD->getTemplatedDecl(); 702 if (IsConstant && 703 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() && 704 RD->hasMutableFields())) { 705 // Variables with const-qualified type having no mutable member may be 706 // listed in a firstprivate clause, even if they are static data members. 707 DSAVarData DVarTemp = hasDSA( 708 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_firstprivate; }, 709 MatchesAlways, FromParent); 710 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 711 return DVar; 712 713 DVar.CKind = OMPC_shared; 714 return DVar; 715 } 716 717 // Explicitly specified attributes and local variables with predetermined 718 // attributes. 719 auto StartI = std::next(Stack.rbegin()); 720 auto EndI = std::prev(Stack.rend()); 721 if (FromParent && StartI != EndI) { 722 StartI = std::next(StartI); 723 } 724 auto I = std::prev(StartI); 725 if (I->SharingMap.count(D)) { 726 DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer(); 727 DVar.PrivateCopy = I->SharingMap[D].PrivateCopy; 728 DVar.CKind = I->SharingMap[D].Attributes; 729 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 730 } 731 732 return DVar; 733 } 734 735 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 736 bool FromParent) { 737 D = getCanonicalDecl(D); 738 auto StartI = Stack.rbegin(); 739 auto EndI = std::prev(Stack.rend()); 740 if (FromParent && StartI != EndI) { 741 StartI = std::next(StartI); 742 } 743 return getDSA(StartI, D); 744 } 745 746 DSAStackTy::DSAVarData 747 DSAStackTy::hasDSA(ValueDecl *D, 748 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 749 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 750 bool FromParent) { 751 D = getCanonicalDecl(D); 752 auto StartI = std::next(Stack.rbegin()); 753 auto EndI = Stack.rend(); 754 if (FromParent && StartI != EndI) { 755 StartI = std::next(StartI); 756 } 757 for (auto I = StartI, EE = EndI; I != EE; ++I) { 758 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) 759 continue; 760 DSAVarData DVar = getDSA(I, D); 761 if (CPred(DVar.CKind)) 762 return DVar; 763 } 764 return DSAVarData(); 765 } 766 767 DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 768 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 769 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 770 bool FromParent) { 771 D = getCanonicalDecl(D); 772 auto StartI = std::next(Stack.rbegin()); 773 auto EndI = Stack.rend(); 774 if (FromParent && StartI != EndI) { 775 StartI = std::next(StartI); 776 } 777 for (auto I = StartI, EE = EndI; I != EE; ++I) { 778 if (!DPred(I->Directive)) 779 break; 780 DSAVarData DVar = getDSA(I, D); 781 if (CPred(DVar.CKind)) 782 return DVar; 783 return DSAVarData(); 784 } 785 return DSAVarData(); 786 } 787 788 bool DSAStackTy::hasExplicitDSA( 789 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 790 unsigned Level, bool NotLastprivate) { 791 if (CPred(ClauseKindMode)) 792 return true; 793 D = getCanonicalDecl(D); 794 auto StartI = std::next(Stack.begin()); 795 auto EndI = Stack.end(); 796 if (std::distance(StartI, EndI) <= (int)Level) 797 return false; 798 std::advance(StartI, Level); 799 return (StartI->SharingMap.count(D) > 0) && 800 StartI->SharingMap[D].RefExpr.getPointer() && 801 CPred(StartI->SharingMap[D].Attributes) && 802 (!NotLastprivate || !StartI->SharingMap[D].RefExpr.getInt()); 803 } 804 805 bool DSAStackTy::hasExplicitDirective( 806 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 807 unsigned Level) { 808 auto StartI = std::next(Stack.begin()); 809 auto EndI = Stack.end(); 810 if (std::distance(StartI, EndI) <= (int)Level) 811 return false; 812 std::advance(StartI, Level); 813 return DPred(StartI->Directive); 814 } 815 816 bool DSAStackTy::hasDirective( 817 const llvm::function_ref<bool(OpenMPDirectiveKind, 818 const DeclarationNameInfo &, SourceLocation)> 819 &DPred, 820 bool FromParent) { 821 // We look only in the enclosing region. 822 if (Stack.size() < 2) 823 return false; 824 auto StartI = std::next(Stack.rbegin()); 825 auto EndI = std::prev(Stack.rend()); 826 if (FromParent && StartI != EndI) { 827 StartI = std::next(StartI); 828 } 829 for (auto I = StartI, EE = EndI; I != EE; ++I) { 830 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 831 return true; 832 } 833 return false; 834 } 835 836 void Sema::InitDataSharingAttributesStack() { 837 VarDataSharingAttributesStack = new DSAStackTy(*this); 838 } 839 840 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 841 842 bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level) { 843 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 844 845 auto &Ctx = getASTContext(); 846 bool IsByRef = true; 847 848 // Find the directive that is associated with the provided scope. 849 auto Ty = D->getType(); 850 851 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 852 // This table summarizes how a given variable should be passed to the device 853 // given its type and the clauses where it appears. This table is based on 854 // the description in OpenMP 4.5 [2.10.4, target Construct] and 855 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 856 // 857 // ========================================================================= 858 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 859 // | |(tofrom:scalar)| | pvt | | | | 860 // ========================================================================= 861 // | scl | | | | - | | bycopy| 862 // | scl | | - | x | - | - | bycopy| 863 // | scl | | x | - | - | - | null | 864 // | scl | x | | | - | | byref | 865 // | scl | x | - | x | - | - | bycopy| 866 // | scl | x | x | - | - | - | null | 867 // | scl | | - | - | - | x | byref | 868 // | scl | x | - | - | - | x | byref | 869 // 870 // | agg | n.a. | | | - | | byref | 871 // | agg | n.a. | - | x | - | - | byref | 872 // | agg | n.a. | x | - | - | - | null | 873 // | agg | n.a. | - | - | - | x | byref | 874 // | agg | n.a. | - | - | - | x[] | byref | 875 // 876 // | ptr | n.a. | | | - | | bycopy| 877 // | ptr | n.a. | - | x | - | - | bycopy| 878 // | ptr | n.a. | x | - | - | - | null | 879 // | ptr | n.a. | - | - | - | x | byref | 880 // | ptr | n.a. | - | - | - | x[] | bycopy| 881 // | ptr | n.a. | - | - | x | | bycopy| 882 // | ptr | n.a. | - | - | x | x | bycopy| 883 // | ptr | n.a. | - | - | x | x[] | bycopy| 884 // ========================================================================= 885 // Legend: 886 // scl - scalar 887 // ptr - pointer 888 // agg - aggregate 889 // x - applies 890 // - - invalid in this combination 891 // [] - mapped with an array section 892 // byref - should be mapped by reference 893 // byval - should be mapped by value 894 // null - initialize a local variable to null on the device 895 // 896 // Observations: 897 // - All scalar declarations that show up in a map clause have to be passed 898 // by reference, because they may have been mapped in the enclosing data 899 // environment. 900 // - If the scalar value does not fit the size of uintptr, it has to be 901 // passed by reference, regardless the result in the table above. 902 // - For pointers mapped by value that have either an implicit map or an 903 // array section, the runtime library may pass the NULL value to the 904 // device instead of the value passed to it by the compiler. 905 906 907 if (Ty->isReferenceType()) 908 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 909 910 // Locate map clauses and see if the variable being captured is referred to 911 // in any of those clauses. Here we only care about variables, not fields, 912 // because fields are part of aggregates. 913 bool IsVariableUsedInMapClause = false; 914 bool IsVariableAssociatedWithSection = false; 915 916 DSAStack->checkMappableExprComponentListsForDecl( 917 D, /*CurrentRegionOnly=*/true, 918 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef 919 MapExprComponents) { 920 921 auto EI = MapExprComponents.rbegin(); 922 auto EE = MapExprComponents.rend(); 923 924 assert(EI != EE && "Invalid map expression!"); 925 926 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 927 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 928 929 ++EI; 930 if (EI == EE) 931 return false; 932 933 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 934 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 935 isa<MemberExpr>(EI->getAssociatedExpression())) { 936 IsVariableAssociatedWithSection = true; 937 // There is nothing more we need to know about this variable. 938 return true; 939 } 940 941 // Keep looking for more map info. 942 return false; 943 }); 944 945 if (IsVariableUsedInMapClause) { 946 // If variable is identified in a map clause it is always captured by 947 // reference except if it is a pointer that is dereferenced somehow. 948 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 949 } else { 950 // By default, all the data that has a scalar type is mapped by copy. 951 IsByRef = !Ty->isScalarType(); 952 } 953 } 954 955 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 956 IsByRef = !DSAStack->hasExplicitDSA( 957 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 958 Level, /*NotLastprivate=*/true); 959 } 960 961 // When passing data by copy, we need to make sure it fits the uintptr size 962 // and alignment, because the runtime library only deals with uintptr types. 963 // If it does not fit the uintptr size, we need to pass the data by reference 964 // instead. 965 if (!IsByRef && 966 (Ctx.getTypeSizeInChars(Ty) > 967 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 968 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 969 IsByRef = true; 970 } 971 972 return IsByRef; 973 } 974 975 unsigned Sema::getOpenMPNestingLevel() const { 976 assert(getLangOpts().OpenMP); 977 return DSAStack->getNestingLevel(); 978 } 979 980 VarDecl *Sema::IsOpenMPCapturedDecl(ValueDecl *D) { 981 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 982 D = getCanonicalDecl(D); 983 984 // If we are attempting to capture a global variable in a directive with 985 // 'target' we return true so that this global is also mapped to the device. 986 // 987 // FIXME: If the declaration is enclosed in a 'declare target' directive, 988 // then it should not be captured. Therefore, an extra check has to be 989 // inserted here once support for 'declare target' is added. 990 // 991 auto *VD = dyn_cast<VarDecl>(D); 992 if (VD && !VD->hasLocalStorage()) { 993 if (DSAStack->getCurrentDirective() == OMPD_target && 994 !DSAStack->isClauseParsingMode()) 995 return VD; 996 if (DSAStack->hasDirective( 997 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 998 SourceLocation) -> bool { 999 return isOpenMPTargetExecutionDirective(K); 1000 }, 1001 false)) 1002 return VD; 1003 } 1004 1005 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1006 (!DSAStack->isClauseParsingMode() || 1007 DSAStack->getParentDirective() != OMPD_unknown)) { 1008 auto &&Info = DSAStack->isLoopControlVariable(D); 1009 if (Info.first || 1010 (VD && VD->hasLocalStorage() && 1011 isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || 1012 (VD && DSAStack->isForceVarCapturing())) 1013 return VD ? VD : Info.second; 1014 auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1015 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1016 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1017 DVarPrivate = DSAStack->hasDSA( 1018 D, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, 1019 DSAStack->isClauseParsingMode()); 1020 if (DVarPrivate.CKind != OMPC_unknown) 1021 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1022 } 1023 return nullptr; 1024 } 1025 1026 bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) { 1027 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1028 return DSAStack->hasExplicitDSA( 1029 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, Level); 1030 } 1031 1032 bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) { 1033 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1034 // Return true if the current level is no longer enclosed in a target region. 1035 1036 auto *VD = dyn_cast<VarDecl>(D); 1037 return VD && !VD->hasLocalStorage() && 1038 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1039 Level); 1040 } 1041 1042 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1043 1044 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1045 const DeclarationNameInfo &DirName, 1046 Scope *CurScope, SourceLocation Loc) { 1047 DSAStack->push(DKind, DirName, CurScope, Loc); 1048 PushExpressionEvaluationContext(PotentiallyEvaluated); 1049 } 1050 1051 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1052 DSAStack->setClauseParsingMode(K); 1053 } 1054 1055 void Sema::EndOpenMPClause() { 1056 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1057 } 1058 1059 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1060 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1061 // A variable of class type (or array thereof) that appears in a lastprivate 1062 // clause requires an accessible, unambiguous default constructor for the 1063 // class type, unless the list item is also specified in a firstprivate 1064 // clause. 1065 if (auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1066 for (auto *C : D->clauses()) { 1067 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1068 SmallVector<Expr *, 8> PrivateCopies; 1069 for (auto *DE : Clause->varlists()) { 1070 if (DE->isValueDependent() || DE->isTypeDependent()) { 1071 PrivateCopies.push_back(nullptr); 1072 continue; 1073 } 1074 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1075 VarDecl *VD = cast<VarDecl>(DRE->getDecl()); 1076 QualType Type = VD->getType().getNonReferenceType(); 1077 auto DVar = DSAStack->getTopDSA(VD, false); 1078 if (DVar.CKind == OMPC_lastprivate) { 1079 // Generate helper private variable and initialize it with the 1080 // default value. The address of the original variable is replaced 1081 // by the address of the new private variable in CodeGen. This new 1082 // variable is not added to IdResolver, so the code in the OpenMP 1083 // region uses original variable for proper diagnostics. 1084 auto *VDPrivate = buildVarDecl( 1085 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1086 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr); 1087 ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); 1088 if (VDPrivate->isInvalidDecl()) 1089 continue; 1090 PrivateCopies.push_back(buildDeclRefExpr( 1091 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1092 } else { 1093 // The variable is also a firstprivate, so initialization sequence 1094 // for private copy is generated already. 1095 PrivateCopies.push_back(nullptr); 1096 } 1097 } 1098 // Set initializers to private copies if no errors were found. 1099 if (PrivateCopies.size() == Clause->varlist_size()) 1100 Clause->setPrivateCopies(PrivateCopies); 1101 } 1102 } 1103 } 1104 1105 DSAStack->pop(); 1106 DiscardCleanupsInEvaluationContext(); 1107 PopExpressionEvaluationContext(); 1108 } 1109 1110 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1111 Expr *NumIterations, Sema &SemaRef, 1112 Scope *S, DSAStackTy *Stack); 1113 1114 namespace { 1115 1116 class VarDeclFilterCCC : public CorrectionCandidateCallback { 1117 private: 1118 Sema &SemaRef; 1119 1120 public: 1121 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1122 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1123 NamedDecl *ND = Candidate.getCorrectionDecl(); 1124 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) { 1125 return VD->hasGlobalStorage() && 1126 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1127 SemaRef.getCurScope()); 1128 } 1129 return false; 1130 } 1131 }; 1132 1133 class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback { 1134 private: 1135 Sema &SemaRef; 1136 1137 public: 1138 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 1139 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1140 NamedDecl *ND = Candidate.getCorrectionDecl(); 1141 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { 1142 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1143 SemaRef.getCurScope()); 1144 } 1145 return false; 1146 } 1147 }; 1148 1149 } // namespace 1150 1151 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 1152 CXXScopeSpec &ScopeSpec, 1153 const DeclarationNameInfo &Id) { 1154 LookupResult Lookup(*this, Id, LookupOrdinaryName); 1155 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 1156 1157 if (Lookup.isAmbiguous()) 1158 return ExprError(); 1159 1160 VarDecl *VD; 1161 if (!Lookup.isSingleResult()) { 1162 if (TypoCorrection Corrected = CorrectTypo( 1163 Id, LookupOrdinaryName, CurScope, nullptr, 1164 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 1165 diagnoseTypo(Corrected, 1166 PDiag(Lookup.empty() 1167 ? diag::err_undeclared_var_use_suggest 1168 : diag::err_omp_expected_var_arg_suggest) 1169 << Id.getName()); 1170 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 1171 } else { 1172 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 1173 : diag::err_omp_expected_var_arg) 1174 << Id.getName(); 1175 return ExprError(); 1176 } 1177 } else { 1178 if (!(VD = Lookup.getAsSingle<VarDecl>())) { 1179 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 1180 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 1181 return ExprError(); 1182 } 1183 } 1184 Lookup.suppressDiagnostics(); 1185 1186 // OpenMP [2.9.2, Syntax, C/C++] 1187 // Variables must be file-scope, namespace-scope, or static block-scope. 1188 if (!VD->hasGlobalStorage()) { 1189 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 1190 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); 1191 bool IsDecl = 1192 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1193 Diag(VD->getLocation(), 1194 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1195 << VD; 1196 return ExprError(); 1197 } 1198 1199 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 1200 NamedDecl *ND = cast<NamedDecl>(CanonicalVD); 1201 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 1202 // A threadprivate directive for file-scope variables must appear outside 1203 // any definition or declaration. 1204 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 1205 !getCurLexicalContext()->isTranslationUnit()) { 1206 Diag(Id.getLoc(), diag::err_omp_var_scope) 1207 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1208 bool IsDecl = 1209 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1210 Diag(VD->getLocation(), 1211 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1212 << VD; 1213 return ExprError(); 1214 } 1215 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 1216 // A threadprivate directive for static class member variables must appear 1217 // in the class definition, in the same scope in which the member 1218 // variables are declared. 1219 if (CanonicalVD->isStaticDataMember() && 1220 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 1221 Diag(Id.getLoc(), diag::err_omp_var_scope) 1222 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1223 bool IsDecl = 1224 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1225 Diag(VD->getLocation(), 1226 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1227 << VD; 1228 return ExprError(); 1229 } 1230 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 1231 // A threadprivate directive for namespace-scope variables must appear 1232 // outside any definition or declaration other than the namespace 1233 // definition itself. 1234 if (CanonicalVD->getDeclContext()->isNamespace() && 1235 (!getCurLexicalContext()->isFileContext() || 1236 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 1237 Diag(Id.getLoc(), diag::err_omp_var_scope) 1238 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1239 bool IsDecl = 1240 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1241 Diag(VD->getLocation(), 1242 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1243 << VD; 1244 return ExprError(); 1245 } 1246 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 1247 // A threadprivate directive for static block-scope variables must appear 1248 // in the scope of the variable and not in a nested scope. 1249 if (CanonicalVD->isStaticLocal() && CurScope && 1250 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 1251 Diag(Id.getLoc(), diag::err_omp_var_scope) 1252 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1253 bool IsDecl = 1254 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1255 Diag(VD->getLocation(), 1256 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1257 << VD; 1258 return ExprError(); 1259 } 1260 1261 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 1262 // A threadprivate directive must lexically precede all references to any 1263 // of the variables in its list. 1264 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { 1265 Diag(Id.getLoc(), diag::err_omp_var_used) 1266 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1267 return ExprError(); 1268 } 1269 1270 QualType ExprType = VD->getType().getNonReferenceType(); 1271 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 1272 SourceLocation(), VD, 1273 /*RefersToEnclosingVariableOrCapture=*/false, 1274 Id.getLoc(), ExprType, VK_LValue); 1275 } 1276 1277 Sema::DeclGroupPtrTy 1278 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 1279 ArrayRef<Expr *> VarList) { 1280 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 1281 CurContext->addDecl(D); 1282 return DeclGroupPtrTy::make(DeclGroupRef(D)); 1283 } 1284 return nullptr; 1285 } 1286 1287 namespace { 1288 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> { 1289 Sema &SemaRef; 1290 1291 public: 1292 bool VisitDeclRefExpr(const DeclRefExpr *E) { 1293 if (auto VD = dyn_cast<VarDecl>(E->getDecl())) { 1294 if (VD->hasLocalStorage()) { 1295 SemaRef.Diag(E->getLocStart(), 1296 diag::err_omp_local_var_in_threadprivate_init) 1297 << E->getSourceRange(); 1298 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 1299 << VD << VD->getSourceRange(); 1300 return true; 1301 } 1302 } 1303 return false; 1304 } 1305 bool VisitStmt(const Stmt *S) { 1306 for (auto Child : S->children()) { 1307 if (Child && Visit(Child)) 1308 return true; 1309 } 1310 return false; 1311 } 1312 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 1313 }; 1314 } // namespace 1315 1316 OMPThreadPrivateDecl * 1317 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 1318 SmallVector<Expr *, 8> Vars; 1319 for (auto &RefExpr : VarList) { 1320 DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr); 1321 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 1322 SourceLocation ILoc = DE->getExprLoc(); 1323 1324 // Mark variable as used. 1325 VD->setReferenced(); 1326 VD->markUsed(Context); 1327 1328 QualType QType = VD->getType(); 1329 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 1330 // It will be analyzed later. 1331 Vars.push_back(DE); 1332 continue; 1333 } 1334 1335 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1336 // A threadprivate variable must not have an incomplete type. 1337 if (RequireCompleteType(ILoc, VD->getType(), 1338 diag::err_omp_threadprivate_incomplete_type)) { 1339 continue; 1340 } 1341 1342 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1343 // A threadprivate variable must not have a reference type. 1344 if (VD->getType()->isReferenceType()) { 1345 Diag(ILoc, diag::err_omp_ref_type_arg) 1346 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 1347 bool IsDecl = 1348 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1349 Diag(VD->getLocation(), 1350 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1351 << VD; 1352 continue; 1353 } 1354 1355 // Check if this is a TLS variable. If TLS is not being supported, produce 1356 // the corresponding diagnostic. 1357 if ((VD->getTLSKind() != VarDecl::TLS_None && 1358 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1359 getLangOpts().OpenMPUseTLS && 1360 getASTContext().getTargetInfo().isTLSSupported())) || 1361 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 1362 !VD->isLocalVarDecl())) { 1363 Diag(ILoc, diag::err_omp_var_thread_local) 1364 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 1365 bool IsDecl = 1366 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1367 Diag(VD->getLocation(), 1368 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1369 << VD; 1370 continue; 1371 } 1372 1373 // Check if initial value of threadprivate variable reference variable with 1374 // local storage (it is not supported by runtime). 1375 if (auto Init = VD->getAnyInitializer()) { 1376 LocalVarRefChecker Checker(*this); 1377 if (Checker.Visit(Init)) 1378 continue; 1379 } 1380 1381 Vars.push_back(RefExpr); 1382 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 1383 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 1384 Context, SourceRange(Loc, Loc))); 1385 if (auto *ML = Context.getASTMutationListener()) 1386 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 1387 } 1388 OMPThreadPrivateDecl *D = nullptr; 1389 if (!Vars.empty()) { 1390 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 1391 Vars); 1392 D->setAccess(AS_public); 1393 } 1394 return D; 1395 } 1396 1397 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, 1398 const ValueDecl *D, DSAStackTy::DSAVarData DVar, 1399 bool IsLoopIterVar = false) { 1400 if (DVar.RefExpr) { 1401 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 1402 << getOpenMPClauseName(DVar.CKind); 1403 return; 1404 } 1405 enum { 1406 PDSA_StaticMemberShared, 1407 PDSA_StaticLocalVarShared, 1408 PDSA_LoopIterVarPrivate, 1409 PDSA_LoopIterVarLinear, 1410 PDSA_LoopIterVarLastprivate, 1411 PDSA_ConstVarShared, 1412 PDSA_GlobalVarShared, 1413 PDSA_TaskVarFirstprivate, 1414 PDSA_LocalVarPrivate, 1415 PDSA_Implicit 1416 } Reason = PDSA_Implicit; 1417 bool ReportHint = false; 1418 auto ReportLoc = D->getLocation(); 1419 auto *VD = dyn_cast<VarDecl>(D); 1420 if (IsLoopIterVar) { 1421 if (DVar.CKind == OMPC_private) 1422 Reason = PDSA_LoopIterVarPrivate; 1423 else if (DVar.CKind == OMPC_lastprivate) 1424 Reason = PDSA_LoopIterVarLastprivate; 1425 else 1426 Reason = PDSA_LoopIterVarLinear; 1427 } else if (isOpenMPTaskingDirective(DVar.DKind) && 1428 DVar.CKind == OMPC_firstprivate) { 1429 Reason = PDSA_TaskVarFirstprivate; 1430 ReportLoc = DVar.ImplicitDSALoc; 1431 } else if (VD && VD->isStaticLocal()) 1432 Reason = PDSA_StaticLocalVarShared; 1433 else if (VD && VD->isStaticDataMember()) 1434 Reason = PDSA_StaticMemberShared; 1435 else if (VD && VD->isFileVarDecl()) 1436 Reason = PDSA_GlobalVarShared; 1437 else if (D->getType().isConstant(SemaRef.getASTContext())) 1438 Reason = PDSA_ConstVarShared; 1439 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 1440 ReportHint = true; 1441 Reason = PDSA_LocalVarPrivate; 1442 } 1443 if (Reason != PDSA_Implicit) { 1444 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 1445 << Reason << ReportHint 1446 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 1447 } else if (DVar.ImplicitDSALoc.isValid()) { 1448 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 1449 << getOpenMPClauseName(DVar.CKind); 1450 } 1451 } 1452 1453 namespace { 1454 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> { 1455 DSAStackTy *Stack; 1456 Sema &SemaRef; 1457 bool ErrorFound; 1458 CapturedStmt *CS; 1459 llvm::SmallVector<Expr *, 8> ImplicitFirstprivate; 1460 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 1461 1462 public: 1463 void VisitDeclRefExpr(DeclRefExpr *E) { 1464 if (E->isTypeDependent() || E->isValueDependent() || 1465 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 1466 return; 1467 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1468 // Skip internally declared variables. 1469 if (VD->isLocalVarDecl() && !CS->capturesVariable(VD)) 1470 return; 1471 1472 auto DVar = Stack->getTopDSA(VD, false); 1473 // Check if the variable has explicit DSA set and stop analysis if it so. 1474 if (DVar.RefExpr) return; 1475 1476 auto ELoc = E->getExprLoc(); 1477 auto DKind = Stack->getCurrentDirective(); 1478 // The default(none) clause requires that each variable that is referenced 1479 // in the construct, and does not have a predetermined data-sharing 1480 // attribute, must have its data-sharing attribute explicitly determined 1481 // by being listed in a data-sharing attribute clause. 1482 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 1483 isParallelOrTaskRegion(DKind) && 1484 VarsWithInheritedDSA.count(VD) == 0) { 1485 VarsWithInheritedDSA[VD] = E; 1486 return; 1487 } 1488 1489 // OpenMP [2.9.3.6, Restrictions, p.2] 1490 // A list item that appears in a reduction clause of the innermost 1491 // enclosing worksharing or parallel construct may not be accessed in an 1492 // explicit task. 1493 DVar = Stack->hasInnermostDSA( 1494 VD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 1495 [](OpenMPDirectiveKind K) -> bool { 1496 return isOpenMPParallelDirective(K) || 1497 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 1498 }, 1499 false); 1500 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 1501 ErrorFound = true; 1502 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1503 ReportOriginalDSA(SemaRef, Stack, VD, DVar); 1504 return; 1505 } 1506 1507 // Define implicit data-sharing attributes for task. 1508 DVar = Stack->getImplicitDSA(VD, false); 1509 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 1510 !Stack->isLoopControlVariable(VD).first) 1511 ImplicitFirstprivate.push_back(E); 1512 } 1513 } 1514 void VisitMemberExpr(MemberExpr *E) { 1515 if (E->isTypeDependent() || E->isValueDependent() || 1516 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 1517 return; 1518 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 1519 if (auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl())) { 1520 auto DVar = Stack->getTopDSA(FD, false); 1521 // Check if the variable has explicit DSA set and stop analysis if it 1522 // so. 1523 if (DVar.RefExpr) 1524 return; 1525 1526 auto ELoc = E->getExprLoc(); 1527 auto DKind = Stack->getCurrentDirective(); 1528 // OpenMP [2.9.3.6, Restrictions, p.2] 1529 // A list item that appears in a reduction clause of the innermost 1530 // enclosing worksharing or parallel construct may not be accessed in 1531 // an explicit task. 1532 DVar = Stack->hasInnermostDSA( 1533 FD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 1534 [](OpenMPDirectiveKind K) -> bool { 1535 return isOpenMPParallelDirective(K) || 1536 isOpenMPWorksharingDirective(K) || 1537 isOpenMPTeamsDirective(K); 1538 }, 1539 false); 1540 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 1541 ErrorFound = true; 1542 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1543 ReportOriginalDSA(SemaRef, Stack, FD, DVar); 1544 return; 1545 } 1546 1547 // Define implicit data-sharing attributes for task. 1548 DVar = Stack->getImplicitDSA(FD, false); 1549 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 1550 !Stack->isLoopControlVariable(FD).first) 1551 ImplicitFirstprivate.push_back(E); 1552 } 1553 } 1554 } 1555 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 1556 for (auto *C : S->clauses()) { 1557 // Skip analysis of arguments of implicitly defined firstprivate clause 1558 // for task directives. 1559 if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid())) 1560 for (auto *CC : C->children()) { 1561 if (CC) 1562 Visit(CC); 1563 } 1564 } 1565 } 1566 void VisitStmt(Stmt *S) { 1567 for (auto *C : S->children()) { 1568 if (C && !isa<OMPExecutableDirective>(C)) 1569 Visit(C); 1570 } 1571 } 1572 1573 bool isErrorFound() { return ErrorFound; } 1574 ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; } 1575 llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() { 1576 return VarsWithInheritedDSA; 1577 } 1578 1579 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 1580 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} 1581 }; 1582 } // namespace 1583 1584 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 1585 switch (DKind) { 1586 case OMPD_parallel: { 1587 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1588 QualType KmpInt32PtrTy = 1589 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1590 Sema::CapturedParamNameType Params[] = { 1591 std::make_pair(".global_tid.", KmpInt32PtrTy), 1592 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1593 std::make_pair(StringRef(), QualType()) // __context with shared vars 1594 }; 1595 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1596 Params); 1597 break; 1598 } 1599 case OMPD_simd: { 1600 Sema::CapturedParamNameType Params[] = { 1601 std::make_pair(StringRef(), QualType()) // __context with shared vars 1602 }; 1603 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1604 Params); 1605 break; 1606 } 1607 case OMPD_for: { 1608 Sema::CapturedParamNameType Params[] = { 1609 std::make_pair(StringRef(), QualType()) // __context with shared vars 1610 }; 1611 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1612 Params); 1613 break; 1614 } 1615 case OMPD_for_simd: { 1616 Sema::CapturedParamNameType Params[] = { 1617 std::make_pair(StringRef(), QualType()) // __context with shared vars 1618 }; 1619 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1620 Params); 1621 break; 1622 } 1623 case OMPD_sections: { 1624 Sema::CapturedParamNameType Params[] = { 1625 std::make_pair(StringRef(), QualType()) // __context with shared vars 1626 }; 1627 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1628 Params); 1629 break; 1630 } 1631 case OMPD_section: { 1632 Sema::CapturedParamNameType Params[] = { 1633 std::make_pair(StringRef(), QualType()) // __context with shared vars 1634 }; 1635 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1636 Params); 1637 break; 1638 } 1639 case OMPD_single: { 1640 Sema::CapturedParamNameType Params[] = { 1641 std::make_pair(StringRef(), QualType()) // __context with shared vars 1642 }; 1643 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1644 Params); 1645 break; 1646 } 1647 case OMPD_master: { 1648 Sema::CapturedParamNameType Params[] = { 1649 std::make_pair(StringRef(), QualType()) // __context with shared vars 1650 }; 1651 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1652 Params); 1653 break; 1654 } 1655 case OMPD_critical: { 1656 Sema::CapturedParamNameType Params[] = { 1657 std::make_pair(StringRef(), QualType()) // __context with shared vars 1658 }; 1659 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1660 Params); 1661 break; 1662 } 1663 case OMPD_parallel_for: { 1664 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1665 QualType KmpInt32PtrTy = 1666 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1667 Sema::CapturedParamNameType Params[] = { 1668 std::make_pair(".global_tid.", KmpInt32PtrTy), 1669 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1670 std::make_pair(StringRef(), QualType()) // __context with shared vars 1671 }; 1672 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1673 Params); 1674 break; 1675 } 1676 case OMPD_parallel_for_simd: { 1677 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1678 QualType KmpInt32PtrTy = 1679 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1680 Sema::CapturedParamNameType Params[] = { 1681 std::make_pair(".global_tid.", KmpInt32PtrTy), 1682 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1683 std::make_pair(StringRef(), QualType()) // __context with shared vars 1684 }; 1685 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1686 Params); 1687 break; 1688 } 1689 case OMPD_parallel_sections: { 1690 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1691 QualType KmpInt32PtrTy = 1692 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1693 Sema::CapturedParamNameType Params[] = { 1694 std::make_pair(".global_tid.", KmpInt32PtrTy), 1695 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1696 std::make_pair(StringRef(), QualType()) // __context with shared vars 1697 }; 1698 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1699 Params); 1700 break; 1701 } 1702 case OMPD_task: { 1703 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1704 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 1705 FunctionProtoType::ExtProtoInfo EPI; 1706 EPI.Variadic = true; 1707 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 1708 Sema::CapturedParamNameType Params[] = { 1709 std::make_pair(".global_tid.", KmpInt32Ty), 1710 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), 1711 std::make_pair(".privates.", Context.VoidPtrTy.withConst()), 1712 std::make_pair(".copy_fn.", 1713 Context.getPointerType(CopyFnType).withConst()), 1714 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 1715 std::make_pair(StringRef(), QualType()) // __context with shared vars 1716 }; 1717 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1718 Params); 1719 // Mark this captured region as inlined, because we don't use outlined 1720 // function directly. 1721 getCurCapturedRegion()->TheCapturedDecl->addAttr( 1722 AlwaysInlineAttr::CreateImplicit( 1723 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 1724 break; 1725 } 1726 case OMPD_ordered: { 1727 Sema::CapturedParamNameType Params[] = { 1728 std::make_pair(StringRef(), QualType()) // __context with shared vars 1729 }; 1730 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1731 Params); 1732 break; 1733 } 1734 case OMPD_atomic: { 1735 Sema::CapturedParamNameType Params[] = { 1736 std::make_pair(StringRef(), QualType()) // __context with shared vars 1737 }; 1738 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1739 Params); 1740 break; 1741 } 1742 case OMPD_target_data: 1743 case OMPD_target: 1744 case OMPD_target_parallel: 1745 case OMPD_target_parallel_for: { 1746 Sema::CapturedParamNameType Params[] = { 1747 std::make_pair(StringRef(), QualType()) // __context with shared vars 1748 }; 1749 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1750 Params); 1751 break; 1752 } 1753 case OMPD_teams: { 1754 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1755 QualType KmpInt32PtrTy = 1756 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1757 Sema::CapturedParamNameType Params[] = { 1758 std::make_pair(".global_tid.", KmpInt32PtrTy), 1759 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1760 std::make_pair(StringRef(), QualType()) // __context with shared vars 1761 }; 1762 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1763 Params); 1764 break; 1765 } 1766 case OMPD_taskgroup: { 1767 Sema::CapturedParamNameType Params[] = { 1768 std::make_pair(StringRef(), QualType()) // __context with shared vars 1769 }; 1770 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1771 Params); 1772 break; 1773 } 1774 case OMPD_taskloop: 1775 case OMPD_taskloop_simd: { 1776 QualType KmpInt32Ty = 1777 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1); 1778 QualType KmpUInt64Ty = 1779 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 1780 QualType KmpInt64Ty = 1781 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 1782 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 1783 FunctionProtoType::ExtProtoInfo EPI; 1784 EPI.Variadic = true; 1785 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 1786 Sema::CapturedParamNameType Params[] = { 1787 std::make_pair(".global_tid.", KmpInt32Ty), 1788 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), 1789 std::make_pair(".privates.", 1790 Context.VoidPtrTy.withConst().withRestrict()), 1791 std::make_pair( 1792 ".copy_fn.", 1793 Context.getPointerType(CopyFnType).withConst().withRestrict()), 1794 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 1795 std::make_pair(".lb.", KmpUInt64Ty), 1796 std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty), 1797 std::make_pair(".liter.", KmpInt32Ty), 1798 std::make_pair(StringRef(), QualType()) // __context with shared vars 1799 }; 1800 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1801 Params); 1802 // Mark this captured region as inlined, because we don't use outlined 1803 // function directly. 1804 getCurCapturedRegion()->TheCapturedDecl->addAttr( 1805 AlwaysInlineAttr::CreateImplicit( 1806 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 1807 break; 1808 } 1809 case OMPD_distribute: { 1810 Sema::CapturedParamNameType Params[] = { 1811 std::make_pair(StringRef(), QualType()) // __context with shared vars 1812 }; 1813 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1814 Params); 1815 break; 1816 } 1817 case OMPD_threadprivate: 1818 case OMPD_taskyield: 1819 case OMPD_barrier: 1820 case OMPD_taskwait: 1821 case OMPD_cancellation_point: 1822 case OMPD_cancel: 1823 case OMPD_flush: 1824 case OMPD_target_enter_data: 1825 case OMPD_target_exit_data: 1826 case OMPD_declare_reduction: 1827 case OMPD_declare_simd: 1828 case OMPD_declare_target: 1829 case OMPD_end_declare_target: 1830 case OMPD_target_update: 1831 llvm_unreachable("OpenMP Directive is not allowed"); 1832 case OMPD_unknown: 1833 llvm_unreachable("Unknown OpenMP directive"); 1834 } 1835 } 1836 1837 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 1838 Expr *CaptureExpr, bool WithInit, 1839 bool AsExpression) { 1840 assert(CaptureExpr); 1841 ASTContext &C = S.getASTContext(); 1842 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 1843 QualType Ty = Init->getType(); 1844 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 1845 if (S.getLangOpts().CPlusPlus) 1846 Ty = C.getLValueReferenceType(Ty); 1847 else { 1848 Ty = C.getPointerType(Ty); 1849 ExprResult Res = 1850 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 1851 if (!Res.isUsable()) 1852 return nullptr; 1853 Init = Res.get(); 1854 } 1855 WithInit = true; 1856 } 1857 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty); 1858 if (!WithInit) 1859 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange())); 1860 S.CurContext->addHiddenDecl(CED); 1861 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false, 1862 /*TypeMayContainAuto=*/true); 1863 return CED; 1864 } 1865 1866 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 1867 bool WithInit) { 1868 OMPCapturedExprDecl *CD; 1869 if (auto *VD = S.IsOpenMPCapturedDecl(D)) 1870 CD = cast<OMPCapturedExprDecl>(VD); 1871 else 1872 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 1873 /*AsExpression=*/false); 1874 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 1875 CaptureExpr->getExprLoc()); 1876 } 1877 1878 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 1879 if (!Ref) { 1880 auto *CD = 1881 buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."), 1882 CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true); 1883 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 1884 CaptureExpr->getExprLoc()); 1885 } 1886 ExprResult Res = Ref; 1887 if (!S.getLangOpts().CPlusPlus && 1888 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 1889 Ref->getType()->isPointerType()) 1890 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 1891 if (!Res.isUsable()) 1892 return ExprError(); 1893 return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get()); 1894 } 1895 1896 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 1897 ArrayRef<OMPClause *> Clauses) { 1898 if (!S.isUsable()) { 1899 ActOnCapturedRegionError(); 1900 return StmtError(); 1901 } 1902 1903 OMPOrderedClause *OC = nullptr; 1904 OMPScheduleClause *SC = nullptr; 1905 SmallVector<OMPLinearClause *, 4> LCs; 1906 // This is required for proper codegen. 1907 for (auto *Clause : Clauses) { 1908 if (isOpenMPPrivate(Clause->getClauseKind()) || 1909 Clause->getClauseKind() == OMPC_copyprivate || 1910 (getLangOpts().OpenMPUseTLS && 1911 getASTContext().getTargetInfo().isTLSSupported() && 1912 Clause->getClauseKind() == OMPC_copyin)) { 1913 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 1914 // Mark all variables in private list clauses as used in inner region. 1915 for (auto *VarRef : Clause->children()) { 1916 if (auto *E = cast_or_null<Expr>(VarRef)) { 1917 MarkDeclarationsReferencedInExpr(E); 1918 } 1919 } 1920 DSAStack->setForceVarCapturing(/*V=*/false); 1921 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 1922 // Mark all variables in private list clauses as used in inner region. 1923 // Required for proper codegen of combined directives. 1924 // TODO: add processing for other clauses. 1925 if (auto *C = OMPClauseWithPreInit::get(Clause)) { 1926 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 1927 for (auto *D : DS->decls()) 1928 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 1929 } 1930 } 1931 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 1932 if (auto *E = C->getPostUpdateExpr()) 1933 MarkDeclarationsReferencedInExpr(E); 1934 } 1935 } 1936 if (Clause->getClauseKind() == OMPC_schedule) 1937 SC = cast<OMPScheduleClause>(Clause); 1938 else if (Clause->getClauseKind() == OMPC_ordered) 1939 OC = cast<OMPOrderedClause>(Clause); 1940 else if (Clause->getClauseKind() == OMPC_linear) 1941 LCs.push_back(cast<OMPLinearClause>(Clause)); 1942 } 1943 bool ErrorFound = false; 1944 // OpenMP, 2.7.1 Loop Construct, Restrictions 1945 // The nonmonotonic modifier cannot be specified if an ordered clause is 1946 // specified. 1947 if (SC && 1948 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 1949 SC->getSecondScheduleModifier() == 1950 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 1951 OC) { 1952 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 1953 ? SC->getFirstScheduleModifierLoc() 1954 : SC->getSecondScheduleModifierLoc(), 1955 diag::err_omp_schedule_nonmonotonic_ordered) 1956 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 1957 ErrorFound = true; 1958 } 1959 if (!LCs.empty() && OC && OC->getNumForLoops()) { 1960 for (auto *C : LCs) { 1961 Diag(C->getLocStart(), diag::err_omp_linear_ordered) 1962 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 1963 } 1964 ErrorFound = true; 1965 } 1966 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 1967 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 1968 OC->getNumForLoops()) { 1969 Diag(OC->getLocStart(), diag::err_omp_ordered_simd) 1970 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 1971 ErrorFound = true; 1972 } 1973 if (ErrorFound) { 1974 ActOnCapturedRegionError(); 1975 return StmtError(); 1976 } 1977 return ActOnCapturedRegionEnd(S.get()); 1978 } 1979 1980 static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, 1981 OpenMPDirectiveKind CurrentRegion, 1982 const DeclarationNameInfo &CurrentName, 1983 OpenMPDirectiveKind CancelRegion, 1984 SourceLocation StartLoc) { 1985 // Allowed nesting of constructs 1986 // +------------------+-----------------+------------------------------------+ 1987 // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)| 1988 // +------------------+-----------------+------------------------------------+ 1989 // | parallel | parallel | * | 1990 // | parallel | for | * | 1991 // | parallel | for simd | * | 1992 // | parallel | master | * | 1993 // | parallel | critical | * | 1994 // | parallel | simd | * | 1995 // | parallel | sections | * | 1996 // | parallel | section | + | 1997 // | parallel | single | * | 1998 // | parallel | parallel for | * | 1999 // | parallel |parallel for simd| * | 2000 // | parallel |parallel sections| * | 2001 // | parallel | task | * | 2002 // | parallel | taskyield | * | 2003 // | parallel | barrier | * | 2004 // | parallel | taskwait | * | 2005 // | parallel | taskgroup | * | 2006 // | parallel | flush | * | 2007 // | parallel | ordered | + | 2008 // | parallel | atomic | * | 2009 // | parallel | target | * | 2010 // | parallel | target parallel | * | 2011 // | parallel | target parallel | * | 2012 // | | for | | 2013 // | parallel | target enter | * | 2014 // | | data | | 2015 // | parallel | target exit | * | 2016 // | | data | | 2017 // | parallel | teams | + | 2018 // | parallel | cancellation | | 2019 // | | point | ! | 2020 // | parallel | cancel | ! | 2021 // | parallel | taskloop | * | 2022 // | parallel | taskloop simd | * | 2023 // | parallel | distribute | | 2024 // +------------------+-----------------+------------------------------------+ 2025 // | for | parallel | * | 2026 // | for | for | + | 2027 // | for | for simd | + | 2028 // | for | master | + | 2029 // | for | critical | * | 2030 // | for | simd | * | 2031 // | for | sections | + | 2032 // | for | section | + | 2033 // | for | single | + | 2034 // | for | parallel for | * | 2035 // | for |parallel for simd| * | 2036 // | for |parallel sections| * | 2037 // | for | task | * | 2038 // | for | taskyield | * | 2039 // | for | barrier | + | 2040 // | for | taskwait | * | 2041 // | for | taskgroup | * | 2042 // | for | flush | * | 2043 // | for | ordered | * (if construct is ordered) | 2044 // | for | atomic | * | 2045 // | for | target | * | 2046 // | for | target parallel | * | 2047 // | for | target parallel | * | 2048 // | | for | | 2049 // | for | target enter | * | 2050 // | | data | | 2051 // | for | target exit | * | 2052 // | | data | | 2053 // | for | teams | + | 2054 // | for | cancellation | | 2055 // | | point | ! | 2056 // | for | cancel | ! | 2057 // | for | taskloop | * | 2058 // | for | taskloop simd | * | 2059 // | for | distribute | | 2060 // +------------------+-----------------+------------------------------------+ 2061 // | master | parallel | * | 2062 // | master | for | + | 2063 // | master | for simd | + | 2064 // | master | master | * | 2065 // | master | critical | * | 2066 // | master | simd | * | 2067 // | master | sections | + | 2068 // | master | section | + | 2069 // | master | single | + | 2070 // | master | parallel for | * | 2071 // | master |parallel for simd| * | 2072 // | master |parallel sections| * | 2073 // | master | task | * | 2074 // | master | taskyield | * | 2075 // | master | barrier | + | 2076 // | master | taskwait | * | 2077 // | master | taskgroup | * | 2078 // | master | flush | * | 2079 // | master | ordered | + | 2080 // | master | atomic | * | 2081 // | master | target | * | 2082 // | master | target parallel | * | 2083 // | master | target parallel | * | 2084 // | | for | | 2085 // | master | target enter | * | 2086 // | | data | | 2087 // | master | target exit | * | 2088 // | | data | | 2089 // | master | teams | + | 2090 // | master | cancellation | | 2091 // | | point | | 2092 // | master | cancel | | 2093 // | master | taskloop | * | 2094 // | master | taskloop simd | * | 2095 // | master | distribute | | 2096 // +------------------+-----------------+------------------------------------+ 2097 // | critical | parallel | * | 2098 // | critical | for | + | 2099 // | critical | for simd | + | 2100 // | critical | master | * | 2101 // | critical | critical | * (should have different names) | 2102 // | critical | simd | * | 2103 // | critical | sections | + | 2104 // | critical | section | + | 2105 // | critical | single | + | 2106 // | critical | parallel for | * | 2107 // | critical |parallel for simd| * | 2108 // | critical |parallel sections| * | 2109 // | critical | task | * | 2110 // | critical | taskyield | * | 2111 // | critical | barrier | + | 2112 // | critical | taskwait | * | 2113 // | critical | taskgroup | * | 2114 // | critical | ordered | + | 2115 // | critical | atomic | * | 2116 // | critical | target | * | 2117 // | critical | target parallel | * | 2118 // | critical | target parallel | * | 2119 // | | for | | 2120 // | critical | target enter | * | 2121 // | | data | | 2122 // | critical | target exit | * | 2123 // | | data | | 2124 // | critical | teams | + | 2125 // | critical | cancellation | | 2126 // | | point | | 2127 // | critical | cancel | | 2128 // | critical | taskloop | * | 2129 // | critical | taskloop simd | * | 2130 // | critical | distribute | | 2131 // +------------------+-----------------+------------------------------------+ 2132 // | simd | parallel | | 2133 // | simd | for | | 2134 // | simd | for simd | | 2135 // | simd | master | | 2136 // | simd | critical | | 2137 // | simd | simd | * | 2138 // | simd | sections | | 2139 // | simd | section | | 2140 // | simd | single | | 2141 // | simd | parallel for | | 2142 // | simd |parallel for simd| | 2143 // | simd |parallel sections| | 2144 // | simd | task | | 2145 // | simd | taskyield | | 2146 // | simd | barrier | | 2147 // | simd | taskwait | | 2148 // | simd | taskgroup | | 2149 // | simd | flush | | 2150 // | simd | ordered | + (with simd clause) | 2151 // | simd | atomic | | 2152 // | simd | target | | 2153 // | simd | target parallel | | 2154 // | simd | target parallel | | 2155 // | | for | | 2156 // | simd | target enter | | 2157 // | | data | | 2158 // | simd | target exit | | 2159 // | | data | | 2160 // | simd | teams | | 2161 // | simd | cancellation | | 2162 // | | point | | 2163 // | simd | cancel | | 2164 // | simd | taskloop | | 2165 // | simd | taskloop simd | | 2166 // | simd | distribute | | 2167 // +------------------+-----------------+------------------------------------+ 2168 // | for simd | parallel | | 2169 // | for simd | for | | 2170 // | for simd | for simd | | 2171 // | for simd | master | | 2172 // | for simd | critical | | 2173 // | for simd | simd | * | 2174 // | for simd | sections | | 2175 // | for simd | section | | 2176 // | for simd | single | | 2177 // | for simd | parallel for | | 2178 // | for simd |parallel for simd| | 2179 // | for simd |parallel sections| | 2180 // | for simd | task | | 2181 // | for simd | taskyield | | 2182 // | for simd | barrier | | 2183 // | for simd | taskwait | | 2184 // | for simd | taskgroup | | 2185 // | for simd | flush | | 2186 // | for simd | ordered | + (with simd clause) | 2187 // | for simd | atomic | | 2188 // | for simd | target | | 2189 // | for simd | target parallel | | 2190 // | for simd | target parallel | | 2191 // | | for | | 2192 // | for simd | target enter | | 2193 // | | data | | 2194 // | for simd | target exit | | 2195 // | | data | | 2196 // | for simd | teams | | 2197 // | for simd | cancellation | | 2198 // | | point | | 2199 // | for simd | cancel | | 2200 // | for simd | taskloop | | 2201 // | for simd | taskloop simd | | 2202 // | for simd | distribute | | 2203 // +------------------+-----------------+------------------------------------+ 2204 // | parallel for simd| parallel | | 2205 // | parallel for simd| for | | 2206 // | parallel for simd| for simd | | 2207 // | parallel for simd| master | | 2208 // | parallel for simd| critical | | 2209 // | parallel for simd| simd | * | 2210 // | parallel for simd| sections | | 2211 // | parallel for simd| section | | 2212 // | parallel for simd| single | | 2213 // | parallel for simd| parallel for | | 2214 // | parallel for simd|parallel for simd| | 2215 // | parallel for simd|parallel sections| | 2216 // | parallel for simd| task | | 2217 // | parallel for simd| taskyield | | 2218 // | parallel for simd| barrier | | 2219 // | parallel for simd| taskwait | | 2220 // | parallel for simd| taskgroup | | 2221 // | parallel for simd| flush | | 2222 // | parallel for simd| ordered | + (with simd clause) | 2223 // | parallel for simd| atomic | | 2224 // | parallel for simd| target | | 2225 // | parallel for simd| target parallel | | 2226 // | parallel for simd| target parallel | | 2227 // | | for | | 2228 // | parallel for simd| target enter | | 2229 // | | data | | 2230 // | parallel for simd| target exit | | 2231 // | | data | | 2232 // | parallel for simd| teams | | 2233 // | parallel for simd| cancellation | | 2234 // | | point | | 2235 // | parallel for simd| cancel | | 2236 // | parallel for simd| taskloop | | 2237 // | parallel for simd| taskloop simd | | 2238 // | parallel for simd| distribute | | 2239 // +------------------+-----------------+------------------------------------+ 2240 // | sections | parallel | * | 2241 // | sections | for | + | 2242 // | sections | for simd | + | 2243 // | sections | master | + | 2244 // | sections | critical | * | 2245 // | sections | simd | * | 2246 // | sections | sections | + | 2247 // | sections | section | * | 2248 // | sections | single | + | 2249 // | sections | parallel for | * | 2250 // | sections |parallel for simd| * | 2251 // | sections |parallel sections| * | 2252 // | sections | task | * | 2253 // | sections | taskyield | * | 2254 // | sections | barrier | + | 2255 // | sections | taskwait | * | 2256 // | sections | taskgroup | * | 2257 // | sections | flush | * | 2258 // | sections | ordered | + | 2259 // | sections | atomic | * | 2260 // | sections | target | * | 2261 // | sections | target parallel | * | 2262 // | sections | target parallel | * | 2263 // | | for | | 2264 // | sections | target enter | * | 2265 // | | data | | 2266 // | sections | target exit | * | 2267 // | | data | | 2268 // | sections | teams | + | 2269 // | sections | cancellation | | 2270 // | | point | ! | 2271 // | sections | cancel | ! | 2272 // | sections | taskloop | * | 2273 // | sections | taskloop simd | * | 2274 // | sections | distribute | | 2275 // +------------------+-----------------+------------------------------------+ 2276 // | section | parallel | * | 2277 // | section | for | + | 2278 // | section | for simd | + | 2279 // | section | master | + | 2280 // | section | critical | * | 2281 // | section | simd | * | 2282 // | section | sections | + | 2283 // | section | section | + | 2284 // | section | single | + | 2285 // | section | parallel for | * | 2286 // | section |parallel for simd| * | 2287 // | section |parallel sections| * | 2288 // | section | task | * | 2289 // | section | taskyield | * | 2290 // | section | barrier | + | 2291 // | section | taskwait | * | 2292 // | section | taskgroup | * | 2293 // | section | flush | * | 2294 // | section | ordered | + | 2295 // | section | atomic | * | 2296 // | section | target | * | 2297 // | section | target parallel | * | 2298 // | section | target parallel | * | 2299 // | | for | | 2300 // | section | target enter | * | 2301 // | | data | | 2302 // | section | target exit | * | 2303 // | | data | | 2304 // | section | teams | + | 2305 // | section | cancellation | | 2306 // | | point | ! | 2307 // | section | cancel | ! | 2308 // | section | taskloop | * | 2309 // | section | taskloop simd | * | 2310 // | section | distribute | | 2311 // +------------------+-----------------+------------------------------------+ 2312 // | single | parallel | * | 2313 // | single | for | + | 2314 // | single | for simd | + | 2315 // | single | master | + | 2316 // | single | critical | * | 2317 // | single | simd | * | 2318 // | single | sections | + | 2319 // | single | section | + | 2320 // | single | single | + | 2321 // | single | parallel for | * | 2322 // | single |parallel for simd| * | 2323 // | single |parallel sections| * | 2324 // | single | task | * | 2325 // | single | taskyield | * | 2326 // | single | barrier | + | 2327 // | single | taskwait | * | 2328 // | single | taskgroup | * | 2329 // | single | flush | * | 2330 // | single | ordered | + | 2331 // | single | atomic | * | 2332 // | single | target | * | 2333 // | single | target parallel | * | 2334 // | single | target parallel | * | 2335 // | | for | | 2336 // | single | target enter | * | 2337 // | | data | | 2338 // | single | target exit | * | 2339 // | | data | | 2340 // | single | teams | + | 2341 // | single | cancellation | | 2342 // | | point | | 2343 // | single | cancel | | 2344 // | single | taskloop | * | 2345 // | single | taskloop simd | * | 2346 // | single | distribute | | 2347 // +------------------+-----------------+------------------------------------+ 2348 // | parallel for | parallel | * | 2349 // | parallel for | for | + | 2350 // | parallel for | for simd | + | 2351 // | parallel for | master | + | 2352 // | parallel for | critical | * | 2353 // | parallel for | simd | * | 2354 // | parallel for | sections | + | 2355 // | parallel for | section | + | 2356 // | parallel for | single | + | 2357 // | parallel for | parallel for | * | 2358 // | parallel for |parallel for simd| * | 2359 // | parallel for |parallel sections| * | 2360 // | parallel for | task | * | 2361 // | parallel for | taskyield | * | 2362 // | parallel for | barrier | + | 2363 // | parallel for | taskwait | * | 2364 // | parallel for | taskgroup | * | 2365 // | parallel for | flush | * | 2366 // | parallel for | ordered | * (if construct is ordered) | 2367 // | parallel for | atomic | * | 2368 // | parallel for | target | * | 2369 // | parallel for | target parallel | * | 2370 // | parallel for | target parallel | * | 2371 // | | for | | 2372 // | parallel for | target enter | * | 2373 // | | data | | 2374 // | parallel for | target exit | * | 2375 // | | data | | 2376 // | parallel for | teams | + | 2377 // | parallel for | cancellation | | 2378 // | | point | ! | 2379 // | parallel for | cancel | ! | 2380 // | parallel for | taskloop | * | 2381 // | parallel for | taskloop simd | * | 2382 // | parallel for | distribute | | 2383 // +------------------+-----------------+------------------------------------+ 2384 // | parallel sections| parallel | * | 2385 // | parallel sections| for | + | 2386 // | parallel sections| for simd | + | 2387 // | parallel sections| master | + | 2388 // | parallel sections| critical | + | 2389 // | parallel sections| simd | * | 2390 // | parallel sections| sections | + | 2391 // | parallel sections| section | * | 2392 // | parallel sections| single | + | 2393 // | parallel sections| parallel for | * | 2394 // | parallel sections|parallel for simd| * | 2395 // | parallel sections|parallel sections| * | 2396 // | parallel sections| task | * | 2397 // | parallel sections| taskyield | * | 2398 // | parallel sections| barrier | + | 2399 // | parallel sections| taskwait | * | 2400 // | parallel sections| taskgroup | * | 2401 // | parallel sections| flush | * | 2402 // | parallel sections| ordered | + | 2403 // | parallel sections| atomic | * | 2404 // | parallel sections| target | * | 2405 // | parallel sections| target parallel | * | 2406 // | parallel sections| target parallel | * | 2407 // | | for | | 2408 // | parallel sections| target enter | * | 2409 // | | data | | 2410 // | parallel sections| target exit | * | 2411 // | | data | | 2412 // | parallel sections| teams | + | 2413 // | parallel sections| cancellation | | 2414 // | | point | ! | 2415 // | parallel sections| cancel | ! | 2416 // | parallel sections| taskloop | * | 2417 // | parallel sections| taskloop simd | * | 2418 // | parallel sections| distribute | | 2419 // +------------------+-----------------+------------------------------------+ 2420 // | task | parallel | * | 2421 // | task | for | + | 2422 // | task | for simd | + | 2423 // | task | master | + | 2424 // | task | critical | * | 2425 // | task | simd | * | 2426 // | task | sections | + | 2427 // | task | section | + | 2428 // | task | single | + | 2429 // | task | parallel for | * | 2430 // | task |parallel for simd| * | 2431 // | task |parallel sections| * | 2432 // | task | task | * | 2433 // | task | taskyield | * | 2434 // | task | barrier | + | 2435 // | task | taskwait | * | 2436 // | task | taskgroup | * | 2437 // | task | flush | * | 2438 // | task | ordered | + | 2439 // | task | atomic | * | 2440 // | task | target | * | 2441 // | task | target parallel | * | 2442 // | task | target parallel | * | 2443 // | | for | | 2444 // | task | target enter | * | 2445 // | | data | | 2446 // | task | target exit | * | 2447 // | | data | | 2448 // | task | teams | + | 2449 // | task | cancellation | | 2450 // | | point | ! | 2451 // | task | cancel | ! | 2452 // | task | taskloop | * | 2453 // | task | taskloop simd | * | 2454 // | task | distribute | | 2455 // +------------------+-----------------+------------------------------------+ 2456 // | ordered | parallel | * | 2457 // | ordered | for | + | 2458 // | ordered | for simd | + | 2459 // | ordered | master | * | 2460 // | ordered | critical | * | 2461 // | ordered | simd | * | 2462 // | ordered | sections | + | 2463 // | ordered | section | + | 2464 // | ordered | single | + | 2465 // | ordered | parallel for | * | 2466 // | ordered |parallel for simd| * | 2467 // | ordered |parallel sections| * | 2468 // | ordered | task | * | 2469 // | ordered | taskyield | * | 2470 // | ordered | barrier | + | 2471 // | ordered | taskwait | * | 2472 // | ordered | taskgroup | * | 2473 // | ordered | flush | * | 2474 // | ordered | ordered | + | 2475 // | ordered | atomic | * | 2476 // | ordered | target | * | 2477 // | ordered | target parallel | * | 2478 // | ordered | target parallel | * | 2479 // | | for | | 2480 // | ordered | target enter | * | 2481 // | | data | | 2482 // | ordered | target exit | * | 2483 // | | data | | 2484 // | ordered | teams | + | 2485 // | ordered | cancellation | | 2486 // | | point | | 2487 // | ordered | cancel | | 2488 // | ordered | taskloop | * | 2489 // | ordered | taskloop simd | * | 2490 // | ordered | distribute | | 2491 // +------------------+-----------------+------------------------------------+ 2492 // | atomic | parallel | | 2493 // | atomic | for | | 2494 // | atomic | for simd | | 2495 // | atomic | master | | 2496 // | atomic | critical | | 2497 // | atomic | simd | | 2498 // | atomic | sections | | 2499 // | atomic | section | | 2500 // | atomic | single | | 2501 // | atomic | parallel for | | 2502 // | atomic |parallel for simd| | 2503 // | atomic |parallel sections| | 2504 // | atomic | task | | 2505 // | atomic | taskyield | | 2506 // | atomic | barrier | | 2507 // | atomic | taskwait | | 2508 // | atomic | taskgroup | | 2509 // | atomic | flush | | 2510 // | atomic | ordered | | 2511 // | atomic | atomic | | 2512 // | atomic | target | | 2513 // | atomic | target parallel | | 2514 // | atomic | target parallel | | 2515 // | | for | | 2516 // | atomic | target enter | | 2517 // | | data | | 2518 // | atomic | target exit | | 2519 // | | data | | 2520 // | atomic | teams | | 2521 // | atomic | cancellation | | 2522 // | | point | | 2523 // | atomic | cancel | | 2524 // | atomic | taskloop | | 2525 // | atomic | taskloop simd | | 2526 // | atomic | distribute | | 2527 // +------------------+-----------------+------------------------------------+ 2528 // | target | parallel | * | 2529 // | target | for | * | 2530 // | target | for simd | * | 2531 // | target | master | * | 2532 // | target | critical | * | 2533 // | target | simd | * | 2534 // | target | sections | * | 2535 // | target | section | * | 2536 // | target | single | * | 2537 // | target | parallel for | * | 2538 // | target |parallel for simd| * | 2539 // | target |parallel sections| * | 2540 // | target | task | * | 2541 // | target | taskyield | * | 2542 // | target | barrier | * | 2543 // | target | taskwait | * | 2544 // | target | taskgroup | * | 2545 // | target | flush | * | 2546 // | target | ordered | * | 2547 // | target | atomic | * | 2548 // | target | target | | 2549 // | target | target parallel | | 2550 // | target | target parallel | | 2551 // | | for | | 2552 // | target | target enter | | 2553 // | | data | | 2554 // | target | target exit | | 2555 // | | data | | 2556 // | target | teams | * | 2557 // | target | cancellation | | 2558 // | | point | | 2559 // | target | cancel | | 2560 // | target | taskloop | * | 2561 // | target | taskloop simd | * | 2562 // | target | distribute | | 2563 // +------------------+-----------------+------------------------------------+ 2564 // | target parallel | parallel | * | 2565 // | target parallel | for | * | 2566 // | target parallel | for simd | * | 2567 // | target parallel | master | * | 2568 // | target parallel | critical | * | 2569 // | target parallel | simd | * | 2570 // | target parallel | sections | * | 2571 // | target parallel | section | * | 2572 // | target parallel | single | * | 2573 // | target parallel | parallel for | * | 2574 // | target parallel |parallel for simd| * | 2575 // | target parallel |parallel sections| * | 2576 // | target parallel | task | * | 2577 // | target parallel | taskyield | * | 2578 // | target parallel | barrier | * | 2579 // | target parallel | taskwait | * | 2580 // | target parallel | taskgroup | * | 2581 // | target parallel | flush | * | 2582 // | target parallel | ordered | * | 2583 // | target parallel | atomic | * | 2584 // | target parallel | target | | 2585 // | target parallel | target parallel | | 2586 // | target parallel | target parallel | | 2587 // | | for | | 2588 // | target parallel | target enter | | 2589 // | | data | | 2590 // | target parallel | target exit | | 2591 // | | data | | 2592 // | target parallel | teams | | 2593 // | target parallel | cancellation | | 2594 // | | point | ! | 2595 // | target parallel | cancel | ! | 2596 // | target parallel | taskloop | * | 2597 // | target parallel | taskloop simd | * | 2598 // | target parallel | distribute | | 2599 // +------------------+-----------------+------------------------------------+ 2600 // | target parallel | parallel | * | 2601 // | for | | | 2602 // | target parallel | for | * | 2603 // | for | | | 2604 // | target parallel | for simd | * | 2605 // | for | | | 2606 // | target parallel | master | * | 2607 // | for | | | 2608 // | target parallel | critical | * | 2609 // | for | | | 2610 // | target parallel | simd | * | 2611 // | for | | | 2612 // | target parallel | sections | * | 2613 // | for | | | 2614 // | target parallel | section | * | 2615 // | for | | | 2616 // | target parallel | single | * | 2617 // | for | | | 2618 // | target parallel | parallel for | * | 2619 // | for | | | 2620 // | target parallel |parallel for simd| * | 2621 // | for | | | 2622 // | target parallel |parallel sections| * | 2623 // | for | | | 2624 // | target parallel | task | * | 2625 // | for | | | 2626 // | target parallel | taskyield | * | 2627 // | for | | | 2628 // | target parallel | barrier | * | 2629 // | for | | | 2630 // | target parallel | taskwait | * | 2631 // | for | | | 2632 // | target parallel | taskgroup | * | 2633 // | for | | | 2634 // | target parallel | flush | * | 2635 // | for | | | 2636 // | target parallel | ordered | * | 2637 // | for | | | 2638 // | target parallel | atomic | * | 2639 // | for | | | 2640 // | target parallel | target | | 2641 // | for | | | 2642 // | target parallel | target parallel | | 2643 // | for | | | 2644 // | target parallel | target parallel | | 2645 // | for | for | | 2646 // | target parallel | target enter | | 2647 // | for | data | | 2648 // | target parallel | target exit | | 2649 // | for | data | | 2650 // | target parallel | teams | | 2651 // | for | | | 2652 // | target parallel | cancellation | | 2653 // | for | point | ! | 2654 // | target parallel | cancel | ! | 2655 // | for | | | 2656 // | target parallel | taskloop | * | 2657 // | for | | | 2658 // | target parallel | taskloop simd | * | 2659 // | for | | | 2660 // | target parallel | distribute | | 2661 // | for | | | 2662 // +------------------+-----------------+------------------------------------+ 2663 // | teams | parallel | * | 2664 // | teams | for | + | 2665 // | teams | for simd | + | 2666 // | teams | master | + | 2667 // | teams | critical | + | 2668 // | teams | simd | + | 2669 // | teams | sections | + | 2670 // | teams | section | + | 2671 // | teams | single | + | 2672 // | teams | parallel for | * | 2673 // | teams |parallel for simd| * | 2674 // | teams |parallel sections| * | 2675 // | teams | task | + | 2676 // | teams | taskyield | + | 2677 // | teams | barrier | + | 2678 // | teams | taskwait | + | 2679 // | teams | taskgroup | + | 2680 // | teams | flush | + | 2681 // | teams | ordered | + | 2682 // | teams | atomic | + | 2683 // | teams | target | + | 2684 // | teams | target parallel | + | 2685 // | teams | target parallel | + | 2686 // | | for | | 2687 // | teams | target enter | + | 2688 // | | data | | 2689 // | teams | target exit | + | 2690 // | | data | | 2691 // | teams | teams | + | 2692 // | teams | cancellation | | 2693 // | | point | | 2694 // | teams | cancel | | 2695 // | teams | taskloop | + | 2696 // | teams | taskloop simd | + | 2697 // | teams | distribute | ! | 2698 // +------------------+-----------------+------------------------------------+ 2699 // | taskloop | parallel | * | 2700 // | taskloop | for | + | 2701 // | taskloop | for simd | + | 2702 // | taskloop | master | + | 2703 // | taskloop | critical | * | 2704 // | taskloop | simd | * | 2705 // | taskloop | sections | + | 2706 // | taskloop | section | + | 2707 // | taskloop | single | + | 2708 // | taskloop | parallel for | * | 2709 // | taskloop |parallel for simd| * | 2710 // | taskloop |parallel sections| * | 2711 // | taskloop | task | * | 2712 // | taskloop | taskyield | * | 2713 // | taskloop | barrier | + | 2714 // | taskloop | taskwait | * | 2715 // | taskloop | taskgroup | * | 2716 // | taskloop | flush | * | 2717 // | taskloop | ordered | + | 2718 // | taskloop | atomic | * | 2719 // | taskloop | target | * | 2720 // | taskloop | target parallel | * | 2721 // | taskloop | target parallel | * | 2722 // | | for | | 2723 // | taskloop | target enter | * | 2724 // | | data | | 2725 // | taskloop | target exit | * | 2726 // | | data | | 2727 // | taskloop | teams | + | 2728 // | taskloop | cancellation | | 2729 // | | point | | 2730 // | taskloop | cancel | | 2731 // | taskloop | taskloop | * | 2732 // | taskloop | distribute | | 2733 // +------------------+-----------------+------------------------------------+ 2734 // | taskloop simd | parallel | | 2735 // | taskloop simd | for | | 2736 // | taskloop simd | for simd | | 2737 // | taskloop simd | master | | 2738 // | taskloop simd | critical | | 2739 // | taskloop simd | simd | * | 2740 // | taskloop simd | sections | | 2741 // | taskloop simd | section | | 2742 // | taskloop simd | single | | 2743 // | taskloop simd | parallel for | | 2744 // | taskloop simd |parallel for simd| | 2745 // | taskloop simd |parallel sections| | 2746 // | taskloop simd | task | | 2747 // | taskloop simd | taskyield | | 2748 // | taskloop simd | barrier | | 2749 // | taskloop simd | taskwait | | 2750 // | taskloop simd | taskgroup | | 2751 // | taskloop simd | flush | | 2752 // | taskloop simd | ordered | + (with simd clause) | 2753 // | taskloop simd | atomic | | 2754 // | taskloop simd | target | | 2755 // | taskloop simd | target parallel | | 2756 // | taskloop simd | target parallel | | 2757 // | | for | | 2758 // | taskloop simd | target enter | | 2759 // | | data | | 2760 // | taskloop simd | target exit | | 2761 // | | data | | 2762 // | taskloop simd | teams | | 2763 // | taskloop simd | cancellation | | 2764 // | | point | | 2765 // | taskloop simd | cancel | | 2766 // | taskloop simd | taskloop | | 2767 // | taskloop simd | taskloop simd | | 2768 // | taskloop simd | distribute | | 2769 // +------------------+-----------------+------------------------------------+ 2770 // | distribute | parallel | * | 2771 // | distribute | for | * | 2772 // | distribute | for simd | * | 2773 // | distribute | master | * | 2774 // | distribute | critical | * | 2775 // | distribute | simd | * | 2776 // | distribute | sections | * | 2777 // | distribute | section | * | 2778 // | distribute | single | * | 2779 // | distribute | parallel for | * | 2780 // | distribute |parallel for simd| * | 2781 // | distribute |parallel sections| * | 2782 // | distribute | task | * | 2783 // | distribute | taskyield | * | 2784 // | distribute | barrier | * | 2785 // | distribute | taskwait | * | 2786 // | distribute | taskgroup | * | 2787 // | distribute | flush | * | 2788 // | distribute | ordered | + | 2789 // | distribute | atomic | * | 2790 // | distribute | target | | 2791 // | distribute | target parallel | | 2792 // | distribute | target parallel | | 2793 // | | for | | 2794 // | distribute | target enter | | 2795 // | | data | | 2796 // | distribute | target exit | | 2797 // | | data | | 2798 // | distribute | teams | | 2799 // | distribute | cancellation | + | 2800 // | | point | | 2801 // | distribute | cancel | + | 2802 // | distribute | taskloop | * | 2803 // | distribute | taskloop simd | * | 2804 // | distribute | distribute | | 2805 // +------------------+-----------------+------------------------------------+ 2806 if (Stack->getCurScope()) { 2807 auto ParentRegion = Stack->getParentDirective(); 2808 auto OffendingRegion = ParentRegion; 2809 bool NestingProhibited = false; 2810 bool CloseNesting = true; 2811 enum { 2812 NoRecommend, 2813 ShouldBeInParallelRegion, 2814 ShouldBeInOrderedRegion, 2815 ShouldBeInTargetRegion, 2816 ShouldBeInTeamsRegion 2817 } Recommend = NoRecommend; 2818 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered && 2819 CurrentRegion != OMPD_simd) { 2820 // OpenMP [2.16, Nesting of Regions] 2821 // OpenMP constructs may not be nested inside a simd region. 2822 // OpenMP [2.8.1,simd Construct, Restrictions] 2823 // An ordered construct with the simd clause is the only OpenMP construct 2824 // that can appear in the simd region. 2825 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd); 2826 return true; 2827 } 2828 if (ParentRegion == OMPD_atomic) { 2829 // OpenMP [2.16, Nesting of Regions] 2830 // OpenMP constructs may not be nested inside an atomic region. 2831 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 2832 return true; 2833 } 2834 if (CurrentRegion == OMPD_section) { 2835 // OpenMP [2.7.2, sections Construct, Restrictions] 2836 // Orphaned section directives are prohibited. That is, the section 2837 // directives must appear within the sections construct and must not be 2838 // encountered elsewhere in the sections region. 2839 if (ParentRegion != OMPD_sections && 2840 ParentRegion != OMPD_parallel_sections) { 2841 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 2842 << (ParentRegion != OMPD_unknown) 2843 << getOpenMPDirectiveName(ParentRegion); 2844 return true; 2845 } 2846 return false; 2847 } 2848 // Allow some constructs to be orphaned (they could be used in functions, 2849 // called from OpenMP regions with the required preconditions). 2850 if (ParentRegion == OMPD_unknown) 2851 return false; 2852 if (CurrentRegion == OMPD_cancellation_point || 2853 CurrentRegion == OMPD_cancel) { 2854 // OpenMP [2.16, Nesting of Regions] 2855 // A cancellation point construct for which construct-type-clause is 2856 // taskgroup must be nested inside a task construct. A cancellation 2857 // point construct for which construct-type-clause is not taskgroup must 2858 // be closely nested inside an OpenMP construct that matches the type 2859 // specified in construct-type-clause. 2860 // A cancel construct for which construct-type-clause is taskgroup must be 2861 // nested inside a task construct. A cancel construct for which 2862 // construct-type-clause is not taskgroup must be closely nested inside an 2863 // OpenMP construct that matches the type specified in 2864 // construct-type-clause. 2865 NestingProhibited = 2866 !((CancelRegion == OMPD_parallel && 2867 (ParentRegion == OMPD_parallel || 2868 ParentRegion == OMPD_target_parallel)) || 2869 (CancelRegion == OMPD_for && 2870 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 2871 ParentRegion == OMPD_target_parallel_for)) || 2872 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 2873 (CancelRegion == OMPD_sections && 2874 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 2875 ParentRegion == OMPD_parallel_sections))); 2876 } else if (CurrentRegion == OMPD_master) { 2877 // OpenMP [2.16, Nesting of Regions] 2878 // A master region may not be closely nested inside a worksharing, 2879 // atomic, or explicit task region. 2880 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2881 isOpenMPTaskingDirective(ParentRegion); 2882 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 2883 // OpenMP [2.16, Nesting of Regions] 2884 // A critical region may not be nested (closely or otherwise) inside a 2885 // critical region with the same name. Note that this restriction is not 2886 // sufficient to prevent deadlock. 2887 SourceLocation PreviousCriticalLoc; 2888 bool DeadLock = 2889 Stack->hasDirective([CurrentName, &PreviousCriticalLoc]( 2890 OpenMPDirectiveKind K, 2891 const DeclarationNameInfo &DNI, 2892 SourceLocation Loc) 2893 ->bool { 2894 if (K == OMPD_critical && 2895 DNI.getName() == CurrentName.getName()) { 2896 PreviousCriticalLoc = Loc; 2897 return true; 2898 } else 2899 return false; 2900 }, 2901 false /* skip top directive */); 2902 if (DeadLock) { 2903 SemaRef.Diag(StartLoc, 2904 diag::err_omp_prohibited_region_critical_same_name) 2905 << CurrentName.getName(); 2906 if (PreviousCriticalLoc.isValid()) 2907 SemaRef.Diag(PreviousCriticalLoc, 2908 diag::note_omp_previous_critical_region); 2909 return true; 2910 } 2911 } else if (CurrentRegion == OMPD_barrier) { 2912 // OpenMP [2.16, Nesting of Regions] 2913 // A barrier region may not be closely nested inside a worksharing, 2914 // explicit task, critical, ordered, atomic, or master region. 2915 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2916 isOpenMPTaskingDirective(ParentRegion) || 2917 ParentRegion == OMPD_master || 2918 ParentRegion == OMPD_critical || 2919 ParentRegion == OMPD_ordered; 2920 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 2921 !isOpenMPParallelDirective(CurrentRegion)) { 2922 // OpenMP [2.16, Nesting of Regions] 2923 // A worksharing region may not be closely nested inside a worksharing, 2924 // explicit task, critical, ordered, atomic, or master region. 2925 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2926 isOpenMPTaskingDirective(ParentRegion) || 2927 ParentRegion == OMPD_master || 2928 ParentRegion == OMPD_critical || 2929 ParentRegion == OMPD_ordered; 2930 Recommend = ShouldBeInParallelRegion; 2931 } else if (CurrentRegion == OMPD_ordered) { 2932 // OpenMP [2.16, Nesting of Regions] 2933 // An ordered region may not be closely nested inside a critical, 2934 // atomic, or explicit task region. 2935 // An ordered region must be closely nested inside a loop region (or 2936 // parallel loop region) with an ordered clause. 2937 // OpenMP [2.8.1,simd Construct, Restrictions] 2938 // An ordered construct with the simd clause is the only OpenMP construct 2939 // that can appear in the simd region. 2940 NestingProhibited = ParentRegion == OMPD_critical || 2941 isOpenMPTaskingDirective(ParentRegion) || 2942 !(isOpenMPSimdDirective(ParentRegion) || 2943 Stack->isParentOrderedRegion()); 2944 Recommend = ShouldBeInOrderedRegion; 2945 } else if (isOpenMPTeamsDirective(CurrentRegion)) { 2946 // OpenMP [2.16, Nesting of Regions] 2947 // If specified, a teams construct must be contained within a target 2948 // construct. 2949 NestingProhibited = ParentRegion != OMPD_target; 2950 Recommend = ShouldBeInTargetRegion; 2951 Stack->setParentTeamsRegionLoc(Stack->getConstructLoc()); 2952 } 2953 if (!NestingProhibited && isOpenMPTeamsDirective(ParentRegion)) { 2954 // OpenMP [2.16, Nesting of Regions] 2955 // distribute, parallel, parallel sections, parallel workshare, and the 2956 // parallel loop and parallel loop SIMD constructs are the only OpenMP 2957 // constructs that can be closely nested in the teams region. 2958 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 2959 !isOpenMPDistributeDirective(CurrentRegion); 2960 Recommend = ShouldBeInParallelRegion; 2961 } 2962 if (!NestingProhibited && isOpenMPDistributeDirective(CurrentRegion)) { 2963 // OpenMP 4.5 [2.17 Nesting of Regions] 2964 // The region associated with the distribute construct must be strictly 2965 // nested inside a teams region 2966 NestingProhibited = !isOpenMPTeamsDirective(ParentRegion); 2967 Recommend = ShouldBeInTeamsRegion; 2968 } 2969 if (!NestingProhibited && 2970 (isOpenMPTargetExecutionDirective(CurrentRegion) || 2971 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 2972 // OpenMP 4.5 [2.17 Nesting of Regions] 2973 // If a target, target update, target data, target enter data, or 2974 // target exit data construct is encountered during execution of a 2975 // target region, the behavior is unspecified. 2976 NestingProhibited = Stack->hasDirective( 2977 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2978 SourceLocation) -> bool { 2979 if (isOpenMPTargetExecutionDirective(K)) { 2980 OffendingRegion = K; 2981 return true; 2982 } else 2983 return false; 2984 }, 2985 false /* don't skip top directive */); 2986 CloseNesting = false; 2987 } 2988 if (NestingProhibited) { 2989 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 2990 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 2991 << Recommend << getOpenMPDirectiveName(CurrentRegion); 2992 return true; 2993 } 2994 } 2995 return false; 2996 } 2997 2998 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 2999 ArrayRef<OMPClause *> Clauses, 3000 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3001 bool ErrorFound = false; 3002 unsigned NamedModifiersNumber = 0; 3003 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3004 OMPD_unknown + 1); 3005 SmallVector<SourceLocation, 4> NameModifierLoc; 3006 for (const auto *C : Clauses) { 3007 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3008 // At most one if clause without a directive-name-modifier can appear on 3009 // the directive. 3010 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3011 if (FoundNameModifiers[CurNM]) { 3012 S.Diag(C->getLocStart(), diag::err_omp_more_one_clause) 3013 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3014 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3015 ErrorFound = true; 3016 } else if (CurNM != OMPD_unknown) { 3017 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3018 ++NamedModifiersNumber; 3019 } 3020 FoundNameModifiers[CurNM] = IC; 3021 if (CurNM == OMPD_unknown) 3022 continue; 3023 // Check if the specified name modifier is allowed for the current 3024 // directive. 3025 // At most one if clause with the particular directive-name-modifier can 3026 // appear on the directive. 3027 bool MatchFound = false; 3028 for (auto NM : AllowedNameModifiers) { 3029 if (CurNM == NM) { 3030 MatchFound = true; 3031 break; 3032 } 3033 } 3034 if (!MatchFound) { 3035 S.Diag(IC->getNameModifierLoc(), 3036 diag::err_omp_wrong_if_directive_name_modifier) 3037 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3038 ErrorFound = true; 3039 } 3040 } 3041 } 3042 // If any if clause on the directive includes a directive-name-modifier then 3043 // all if clauses on the directive must include a directive-name-modifier. 3044 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3045 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3046 S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(), 3047 diag::err_omp_no_more_if_clause); 3048 } else { 3049 std::string Values; 3050 std::string Sep(", "); 3051 unsigned AllowedCnt = 0; 3052 unsigned TotalAllowedNum = 3053 AllowedNameModifiers.size() - NamedModifiersNumber; 3054 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3055 ++Cnt) { 3056 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3057 if (!FoundNameModifiers[NM]) { 3058 Values += "'"; 3059 Values += getOpenMPDirectiveName(NM); 3060 Values += "'"; 3061 if (AllowedCnt + 2 == TotalAllowedNum) 3062 Values += " or "; 3063 else if (AllowedCnt + 1 != TotalAllowedNum) 3064 Values += Sep; 3065 ++AllowedCnt; 3066 } 3067 } 3068 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(), 3069 diag::err_omp_unnamed_if_clause) 3070 << (TotalAllowedNum > 1) << Values; 3071 } 3072 for (auto Loc : NameModifierLoc) { 3073 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3074 } 3075 ErrorFound = true; 3076 } 3077 return ErrorFound; 3078 } 3079 3080 StmtResult Sema::ActOnOpenMPExecutableDirective( 3081 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3082 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3083 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3084 StmtResult Res = StmtError(); 3085 if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 3086 StartLoc)) 3087 return StmtError(); 3088 3089 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 3090 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 3091 bool ErrorFound = false; 3092 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 3093 if (AStmt) { 3094 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3095 3096 // Check default data sharing attributes for referenced variables. 3097 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 3098 DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt()); 3099 if (DSAChecker.isErrorFound()) 3100 return StmtError(); 3101 // Generate list of implicitly defined firstprivate variables. 3102 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 3103 3104 if (!DSAChecker.getImplicitFirstprivate().empty()) { 3105 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 3106 DSAChecker.getImplicitFirstprivate(), SourceLocation(), 3107 SourceLocation(), SourceLocation())) { 3108 ClausesWithImplicit.push_back(Implicit); 3109 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 3110 DSAChecker.getImplicitFirstprivate().size(); 3111 } else 3112 ErrorFound = true; 3113 } 3114 } 3115 3116 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 3117 switch (Kind) { 3118 case OMPD_parallel: 3119 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 3120 EndLoc); 3121 AllowedNameModifiers.push_back(OMPD_parallel); 3122 break; 3123 case OMPD_simd: 3124 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3125 VarsWithInheritedDSA); 3126 break; 3127 case OMPD_for: 3128 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3129 VarsWithInheritedDSA); 3130 break; 3131 case OMPD_for_simd: 3132 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3133 EndLoc, VarsWithInheritedDSA); 3134 break; 3135 case OMPD_sections: 3136 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 3137 EndLoc); 3138 break; 3139 case OMPD_section: 3140 assert(ClausesWithImplicit.empty() && 3141 "No clauses are allowed for 'omp section' directive"); 3142 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 3143 break; 3144 case OMPD_single: 3145 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 3146 EndLoc); 3147 break; 3148 case OMPD_master: 3149 assert(ClausesWithImplicit.empty() && 3150 "No clauses are allowed for 'omp master' directive"); 3151 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 3152 break; 3153 case OMPD_critical: 3154 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 3155 StartLoc, EndLoc); 3156 break; 3157 case OMPD_parallel_for: 3158 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 3159 EndLoc, VarsWithInheritedDSA); 3160 AllowedNameModifiers.push_back(OMPD_parallel); 3161 break; 3162 case OMPD_parallel_for_simd: 3163 Res = ActOnOpenMPParallelForSimdDirective( 3164 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3165 AllowedNameModifiers.push_back(OMPD_parallel); 3166 break; 3167 case OMPD_parallel_sections: 3168 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 3169 StartLoc, EndLoc); 3170 AllowedNameModifiers.push_back(OMPD_parallel); 3171 break; 3172 case OMPD_task: 3173 Res = 3174 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3175 AllowedNameModifiers.push_back(OMPD_task); 3176 break; 3177 case OMPD_taskyield: 3178 assert(ClausesWithImplicit.empty() && 3179 "No clauses are allowed for 'omp taskyield' directive"); 3180 assert(AStmt == nullptr && 3181 "No associated statement allowed for 'omp taskyield' directive"); 3182 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 3183 break; 3184 case OMPD_barrier: 3185 assert(ClausesWithImplicit.empty() && 3186 "No clauses are allowed for 'omp barrier' directive"); 3187 assert(AStmt == nullptr && 3188 "No associated statement allowed for 'omp barrier' directive"); 3189 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 3190 break; 3191 case OMPD_taskwait: 3192 assert(ClausesWithImplicit.empty() && 3193 "No clauses are allowed for 'omp taskwait' directive"); 3194 assert(AStmt == nullptr && 3195 "No associated statement allowed for 'omp taskwait' directive"); 3196 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 3197 break; 3198 case OMPD_taskgroup: 3199 assert(ClausesWithImplicit.empty() && 3200 "No clauses are allowed for 'omp taskgroup' directive"); 3201 Res = ActOnOpenMPTaskgroupDirective(AStmt, StartLoc, EndLoc); 3202 break; 3203 case OMPD_flush: 3204 assert(AStmt == nullptr && 3205 "No associated statement allowed for 'omp flush' directive"); 3206 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 3207 break; 3208 case OMPD_ordered: 3209 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 3210 EndLoc); 3211 break; 3212 case OMPD_atomic: 3213 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 3214 EndLoc); 3215 break; 3216 case OMPD_teams: 3217 Res = 3218 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3219 break; 3220 case OMPD_target: 3221 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 3222 EndLoc); 3223 AllowedNameModifiers.push_back(OMPD_target); 3224 break; 3225 case OMPD_target_parallel: 3226 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 3227 StartLoc, EndLoc); 3228 AllowedNameModifiers.push_back(OMPD_target); 3229 AllowedNameModifiers.push_back(OMPD_parallel); 3230 break; 3231 case OMPD_target_parallel_for: 3232 Res = ActOnOpenMPTargetParallelForDirective( 3233 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3234 AllowedNameModifiers.push_back(OMPD_target); 3235 AllowedNameModifiers.push_back(OMPD_parallel); 3236 break; 3237 case OMPD_cancellation_point: 3238 assert(ClausesWithImplicit.empty() && 3239 "No clauses are allowed for 'omp cancellation point' directive"); 3240 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 3241 "cancellation point' directive"); 3242 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 3243 break; 3244 case OMPD_cancel: 3245 assert(AStmt == nullptr && 3246 "No associated statement allowed for 'omp cancel' directive"); 3247 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 3248 CancelRegion); 3249 AllowedNameModifiers.push_back(OMPD_cancel); 3250 break; 3251 case OMPD_target_data: 3252 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 3253 EndLoc); 3254 AllowedNameModifiers.push_back(OMPD_target_data); 3255 break; 3256 case OMPD_target_enter_data: 3257 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 3258 EndLoc); 3259 AllowedNameModifiers.push_back(OMPD_target_enter_data); 3260 break; 3261 case OMPD_target_exit_data: 3262 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 3263 EndLoc); 3264 AllowedNameModifiers.push_back(OMPD_target_exit_data); 3265 break; 3266 case OMPD_taskloop: 3267 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 3268 EndLoc, VarsWithInheritedDSA); 3269 AllowedNameModifiers.push_back(OMPD_taskloop); 3270 break; 3271 case OMPD_taskloop_simd: 3272 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3273 EndLoc, VarsWithInheritedDSA); 3274 AllowedNameModifiers.push_back(OMPD_taskloop); 3275 break; 3276 case OMPD_distribute: 3277 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 3278 EndLoc, VarsWithInheritedDSA); 3279 break; 3280 case OMPD_target_update: 3281 assert(!AStmt && "Statement is not allowed for target update"); 3282 Res = 3283 ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, EndLoc); 3284 AllowedNameModifiers.push_back(OMPD_target_update); 3285 break; 3286 case OMPD_declare_target: 3287 case OMPD_end_declare_target: 3288 case OMPD_threadprivate: 3289 case OMPD_declare_reduction: 3290 case OMPD_declare_simd: 3291 llvm_unreachable("OpenMP Directive is not allowed"); 3292 case OMPD_unknown: 3293 llvm_unreachable("Unknown OpenMP directive"); 3294 } 3295 3296 for (auto P : VarsWithInheritedDSA) { 3297 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 3298 << P.first << P.second->getSourceRange(); 3299 } 3300 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 3301 3302 if (!AllowedNameModifiers.empty()) 3303 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 3304 ErrorFound; 3305 3306 if (ErrorFound) 3307 return StmtError(); 3308 return Res; 3309 } 3310 3311 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 3312 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 3313 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 3314 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 3315 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 3316 assert(Aligneds.size() == Alignments.size()); 3317 assert(Linears.size() == LinModifiers.size()); 3318 assert(Linears.size() == Steps.size()); 3319 if (!DG || DG.get().isNull()) 3320 return DeclGroupPtrTy(); 3321 3322 if (!DG.get().isSingleDecl()) { 3323 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 3324 return DG; 3325 } 3326 auto *ADecl = DG.get().getSingleDecl(); 3327 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 3328 ADecl = FTD->getTemplatedDecl(); 3329 3330 auto *FD = dyn_cast<FunctionDecl>(ADecl); 3331 if (!FD) { 3332 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 3333 return DeclGroupPtrTy(); 3334 } 3335 3336 // OpenMP [2.8.2, declare simd construct, Description] 3337 // The parameter of the simdlen clause must be a constant positive integer 3338 // expression. 3339 ExprResult SL; 3340 if (Simdlen) 3341 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 3342 // OpenMP [2.8.2, declare simd construct, Description] 3343 // The special this pointer can be used as if was one of the arguments to the 3344 // function in any of the linear, aligned, or uniform clauses. 3345 // The uniform clause declares one or more arguments to have an invariant 3346 // value for all concurrent invocations of the function in the execution of a 3347 // single SIMD loop. 3348 llvm::DenseMap<Decl *, Expr *> UniformedArgs; 3349 Expr *UniformedLinearThis = nullptr; 3350 for (auto *E : Uniforms) { 3351 E = E->IgnoreParenImpCasts(); 3352 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3353 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 3354 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3355 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3356 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 3357 UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E)); 3358 continue; 3359 } 3360 if (isa<CXXThisExpr>(E)) { 3361 UniformedLinearThis = E; 3362 continue; 3363 } 3364 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3365 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3366 } 3367 // OpenMP [2.8.2, declare simd construct, Description] 3368 // The aligned clause declares that the object to which each list item points 3369 // is aligned to the number of bytes expressed in the optional parameter of 3370 // the aligned clause. 3371 // The special this pointer can be used as if was one of the arguments to the 3372 // function in any of the linear, aligned, or uniform clauses. 3373 // The type of list items appearing in the aligned clause must be array, 3374 // pointer, reference to array, or reference to pointer. 3375 llvm::DenseMap<Decl *, Expr *> AlignedArgs; 3376 Expr *AlignedThis = nullptr; 3377 for (auto *E : Aligneds) { 3378 E = E->IgnoreParenImpCasts(); 3379 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3380 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3381 auto *CanonPVD = PVD->getCanonicalDecl(); 3382 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3383 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3384 ->getCanonicalDecl() == CanonPVD) { 3385 // OpenMP [2.8.1, simd construct, Restrictions] 3386 // A list-item cannot appear in more than one aligned clause. 3387 if (AlignedArgs.count(CanonPVD) > 0) { 3388 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3389 << 1 << E->getSourceRange(); 3390 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 3391 diag::note_omp_explicit_dsa) 3392 << getOpenMPClauseName(OMPC_aligned); 3393 continue; 3394 } 3395 AlignedArgs[CanonPVD] = E; 3396 QualType QTy = PVD->getType() 3397 .getNonReferenceType() 3398 .getUnqualifiedType() 3399 .getCanonicalType(); 3400 const Type *Ty = QTy.getTypePtrOrNull(); 3401 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 3402 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 3403 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 3404 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 3405 } 3406 continue; 3407 } 3408 } 3409 if (isa<CXXThisExpr>(E)) { 3410 if (AlignedThis) { 3411 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 3412 << 2 << E->getSourceRange(); 3413 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 3414 << getOpenMPClauseName(OMPC_aligned); 3415 } 3416 AlignedThis = E; 3417 continue; 3418 } 3419 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3420 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3421 } 3422 // The optional parameter of the aligned clause, alignment, must be a constant 3423 // positive integer expression. If no optional parameter is specified, 3424 // implementation-defined default alignments for SIMD instructions on the 3425 // target platforms are assumed. 3426 SmallVector<Expr *, 4> NewAligns; 3427 for (auto *E : Alignments) { 3428 ExprResult Align; 3429 if (E) 3430 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 3431 NewAligns.push_back(Align.get()); 3432 } 3433 // OpenMP [2.8.2, declare simd construct, Description] 3434 // The linear clause declares one or more list items to be private to a SIMD 3435 // lane and to have a linear relationship with respect to the iteration space 3436 // of a loop. 3437 // The special this pointer can be used as if was one of the arguments to the 3438 // function in any of the linear, aligned, or uniform clauses. 3439 // When a linear-step expression is specified in a linear clause it must be 3440 // either a constant integer expression or an integer-typed parameter that is 3441 // specified in a uniform clause on the directive. 3442 llvm::DenseMap<Decl *, Expr *> LinearArgs; 3443 const bool IsUniformedThis = UniformedLinearThis != nullptr; 3444 auto MI = LinModifiers.begin(); 3445 for (auto *E : Linears) { 3446 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 3447 ++MI; 3448 E = E->IgnoreParenImpCasts(); 3449 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3450 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3451 auto *CanonPVD = PVD->getCanonicalDecl(); 3452 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3453 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3454 ->getCanonicalDecl() == CanonPVD) { 3455 // OpenMP [2.15.3.7, linear Clause, Restrictions] 3456 // A list-item cannot appear in more than one linear clause. 3457 if (LinearArgs.count(CanonPVD) > 0) { 3458 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3459 << getOpenMPClauseName(OMPC_linear) 3460 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 3461 Diag(LinearArgs[CanonPVD]->getExprLoc(), 3462 diag::note_omp_explicit_dsa) 3463 << getOpenMPClauseName(OMPC_linear); 3464 continue; 3465 } 3466 // Each argument can appear in at most one uniform or linear clause. 3467 if (UniformedArgs.count(CanonPVD) > 0) { 3468 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3469 << getOpenMPClauseName(OMPC_linear) 3470 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 3471 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 3472 diag::note_omp_explicit_dsa) 3473 << getOpenMPClauseName(OMPC_uniform); 3474 continue; 3475 } 3476 LinearArgs[CanonPVD] = E; 3477 if (E->isValueDependent() || E->isTypeDependent() || 3478 E->isInstantiationDependent() || 3479 E->containsUnexpandedParameterPack()) 3480 continue; 3481 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 3482 PVD->getOriginalType()); 3483 continue; 3484 } 3485 } 3486 if (isa<CXXThisExpr>(E)) { 3487 if (UniformedLinearThis) { 3488 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 3489 << getOpenMPClauseName(OMPC_linear) 3490 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 3491 << E->getSourceRange(); 3492 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 3493 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 3494 : OMPC_linear); 3495 continue; 3496 } 3497 UniformedLinearThis = E; 3498 if (E->isValueDependent() || E->isTypeDependent() || 3499 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 3500 continue; 3501 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 3502 E->getType()); 3503 continue; 3504 } 3505 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3506 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3507 } 3508 Expr *Step = nullptr; 3509 Expr *NewStep = nullptr; 3510 SmallVector<Expr *, 4> NewSteps; 3511 for (auto *E : Steps) { 3512 // Skip the same step expression, it was checked already. 3513 if (Step == E || !E) { 3514 NewSteps.push_back(E ? NewStep : nullptr); 3515 continue; 3516 } 3517 Step = E; 3518 if (auto *DRE = dyn_cast<DeclRefExpr>(Step)) 3519 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 3520 auto *CanonPVD = PVD->getCanonicalDecl(); 3521 if (UniformedArgs.count(CanonPVD) == 0) { 3522 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 3523 << Step->getSourceRange(); 3524 } else if (E->isValueDependent() || E->isTypeDependent() || 3525 E->isInstantiationDependent() || 3526 E->containsUnexpandedParameterPack() || 3527 CanonPVD->getType()->hasIntegerRepresentation()) 3528 NewSteps.push_back(Step); 3529 else { 3530 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 3531 << Step->getSourceRange(); 3532 } 3533 continue; 3534 } 3535 NewStep = Step; 3536 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 3537 !Step->isInstantiationDependent() && 3538 !Step->containsUnexpandedParameterPack()) { 3539 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 3540 .get(); 3541 if (NewStep) 3542 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 3543 } 3544 NewSteps.push_back(NewStep); 3545 } 3546 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 3547 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 3548 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 3549 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 3550 const_cast<Expr **>(Linears.data()), Linears.size(), 3551 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 3552 NewSteps.data(), NewSteps.size(), SR); 3553 ADecl->addAttr(NewAttr); 3554 return ConvertDeclToDeclGroup(ADecl); 3555 } 3556 3557 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 3558 Stmt *AStmt, 3559 SourceLocation StartLoc, 3560 SourceLocation EndLoc) { 3561 if (!AStmt) 3562 return StmtError(); 3563 3564 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 3565 // 1.2.2 OpenMP Language Terminology 3566 // Structured block - An executable statement with a single entry at the 3567 // top and a single exit at the bottom. 3568 // The point of exit cannot be a branch out of the structured block. 3569 // longjmp() and throw() must not violate the entry/exit criteria. 3570 CS->getCapturedDecl()->setNothrow(); 3571 3572 getCurFunction()->setHasBranchProtectedScope(); 3573 3574 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 3575 DSAStack->isCancelRegion()); 3576 } 3577 3578 namespace { 3579 /// \brief Helper class for checking canonical form of the OpenMP loops and 3580 /// extracting iteration space of each loop in the loop nest, that will be used 3581 /// for IR generation. 3582 class OpenMPIterationSpaceChecker { 3583 /// \brief Reference to Sema. 3584 Sema &SemaRef; 3585 /// \brief A location for diagnostics (when there is no some better location). 3586 SourceLocation DefaultLoc; 3587 /// \brief A location for diagnostics (when increment is not compatible). 3588 SourceLocation ConditionLoc; 3589 /// \brief A source location for referring to loop init later. 3590 SourceRange InitSrcRange; 3591 /// \brief A source location for referring to condition later. 3592 SourceRange ConditionSrcRange; 3593 /// \brief A source location for referring to increment later. 3594 SourceRange IncrementSrcRange; 3595 /// \brief Loop variable. 3596 ValueDecl *LCDecl = nullptr; 3597 /// \brief Reference to loop variable. 3598 Expr *LCRef = nullptr; 3599 /// \brief Lower bound (initializer for the var). 3600 Expr *LB = nullptr; 3601 /// \brief Upper bound. 3602 Expr *UB = nullptr; 3603 /// \brief Loop step (increment). 3604 Expr *Step = nullptr; 3605 /// \brief This flag is true when condition is one of: 3606 /// Var < UB 3607 /// Var <= UB 3608 /// UB > Var 3609 /// UB >= Var 3610 bool TestIsLessOp = false; 3611 /// \brief This flag is true when condition is strict ( < or > ). 3612 bool TestIsStrictOp = false; 3613 /// \brief This flag is true when step is subtracted on each iteration. 3614 bool SubtractStep = false; 3615 3616 public: 3617 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 3618 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 3619 /// \brief Check init-expr for canonical loop form and save loop counter 3620 /// variable - #Var and its initialization value - #LB. 3621 bool CheckInit(Stmt *S, bool EmitDiags = true); 3622 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags 3623 /// for less/greater and for strict/non-strict comparison. 3624 bool CheckCond(Expr *S); 3625 /// \brief Check incr-expr for canonical loop form and return true if it 3626 /// does not conform, otherwise save loop step (#Step). 3627 bool CheckInc(Expr *S); 3628 /// \brief Return the loop counter variable. 3629 ValueDecl *GetLoopDecl() const { return LCDecl; } 3630 /// \brief Return the reference expression to loop counter variable. 3631 Expr *GetLoopDeclRefExpr() const { return LCRef; } 3632 /// \brief Source range of the loop init. 3633 SourceRange GetInitSrcRange() const { return InitSrcRange; } 3634 /// \brief Source range of the loop condition. 3635 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; } 3636 /// \brief Source range of the loop increment. 3637 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; } 3638 /// \brief True if the step should be subtracted. 3639 bool ShouldSubtractStep() const { return SubtractStep; } 3640 /// \brief Build the expression to calculate the number of iterations. 3641 Expr * 3642 BuildNumIterations(Scope *S, const bool LimitedType, 3643 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3644 /// \brief Build the precondition expression for the loops. 3645 Expr *BuildPreCond(Scope *S, Expr *Cond, 3646 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3647 /// \brief Build reference expression to the counter be used for codegen. 3648 DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures, 3649 DSAStackTy &DSA) const; 3650 /// \brief Build reference expression to the private counter be used for 3651 /// codegen. 3652 Expr *BuildPrivateCounterVar() const; 3653 /// \brief Build initization of the counter be used for codegen. 3654 Expr *BuildCounterInit() const; 3655 /// \brief Build step of the counter be used for codegen. 3656 Expr *BuildCounterStep() const; 3657 /// \brief Return true if any expression is dependent. 3658 bool Dependent() const; 3659 3660 private: 3661 /// \brief Check the right-hand side of an assignment in the increment 3662 /// expression. 3663 bool CheckIncRHS(Expr *RHS); 3664 /// \brief Helper to set loop counter variable and its initializer. 3665 bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); 3666 /// \brief Helper to set upper bound. 3667 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR, 3668 SourceLocation SL); 3669 /// \brief Helper to set loop increment. 3670 bool SetStep(Expr *NewStep, bool Subtract); 3671 }; 3672 3673 bool OpenMPIterationSpaceChecker::Dependent() const { 3674 if (!LCDecl) { 3675 assert(!LB && !UB && !Step); 3676 return false; 3677 } 3678 return LCDecl->getType()->isDependentType() || 3679 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 3680 (Step && Step->isValueDependent()); 3681 } 3682 3683 static Expr *getExprAsWritten(Expr *E) { 3684 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) 3685 E = ExprTemp->getSubExpr(); 3686 3687 if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 3688 E = MTE->GetTemporaryExpr(); 3689 3690 while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 3691 E = Binder->getSubExpr(); 3692 3693 if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 3694 E = ICE->getSubExprAsWritten(); 3695 return E->IgnoreParens(); 3696 } 3697 3698 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl, 3699 Expr *NewLCRefExpr, 3700 Expr *NewLB) { 3701 // State consistency checking to ensure correct usage. 3702 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 3703 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3704 if (!NewLCDecl || !NewLB) 3705 return true; 3706 LCDecl = getCanonicalDecl(NewLCDecl); 3707 LCRef = NewLCRefExpr; 3708 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 3709 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3710 if ((Ctor->isCopyOrMoveConstructor() || 3711 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3712 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3713 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 3714 LB = NewLB; 3715 return false; 3716 } 3717 3718 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp, 3719 SourceRange SR, SourceLocation SL) { 3720 // State consistency checking to ensure correct usage. 3721 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 3722 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3723 if (!NewUB) 3724 return true; 3725 UB = NewUB; 3726 TestIsLessOp = LessOp; 3727 TestIsStrictOp = StrictOp; 3728 ConditionSrcRange = SR; 3729 ConditionLoc = SL; 3730 return false; 3731 } 3732 3733 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) { 3734 // State consistency checking to ensure correct usage. 3735 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 3736 if (!NewStep) 3737 return true; 3738 if (!NewStep->isValueDependent()) { 3739 // Check that the step is integer expression. 3740 SourceLocation StepLoc = NewStep->getLocStart(); 3741 ExprResult Val = 3742 SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep); 3743 if (Val.isInvalid()) 3744 return true; 3745 NewStep = Val.get(); 3746 3747 // OpenMP [2.6, Canonical Loop Form, Restrictions] 3748 // If test-expr is of form var relational-op b and relational-op is < or 3749 // <= then incr-expr must cause var to increase on each iteration of the 3750 // loop. If test-expr is of form var relational-op b and relational-op is 3751 // > or >= then incr-expr must cause var to decrease on each iteration of 3752 // the loop. 3753 // If test-expr is of form b relational-op var and relational-op is < or 3754 // <= then incr-expr must cause var to decrease on each iteration of the 3755 // loop. If test-expr is of form b relational-op var and relational-op is 3756 // > or >= then incr-expr must cause var to increase on each iteration of 3757 // the loop. 3758 llvm::APSInt Result; 3759 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 3760 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 3761 bool IsConstNeg = 3762 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 3763 bool IsConstPos = 3764 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 3765 bool IsConstZero = IsConstant && !Result.getBoolValue(); 3766 if (UB && (IsConstZero || 3767 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 3768 : (IsConstPos || (IsUnsigned && !Subtract))))) { 3769 SemaRef.Diag(NewStep->getExprLoc(), 3770 diag::err_omp_loop_incr_not_compatible) 3771 << LCDecl << TestIsLessOp << NewStep->getSourceRange(); 3772 SemaRef.Diag(ConditionLoc, 3773 diag::note_omp_loop_cond_requres_compatible_incr) 3774 << TestIsLessOp << ConditionSrcRange; 3775 return true; 3776 } 3777 if (TestIsLessOp == Subtract) { 3778 NewStep = SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, 3779 NewStep).get(); 3780 Subtract = !Subtract; 3781 } 3782 } 3783 3784 Step = NewStep; 3785 SubtractStep = Subtract; 3786 return false; 3787 } 3788 3789 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { 3790 // Check init-expr for canonical loop form and save loop counter 3791 // variable - #Var and its initialization value - #LB. 3792 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 3793 // var = lb 3794 // integer-type var = lb 3795 // random-access-iterator-type var = lb 3796 // pointer-type var = lb 3797 // 3798 if (!S) { 3799 if (EmitDiags) { 3800 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 3801 } 3802 return true; 3803 } 3804 InitSrcRange = S->getSourceRange(); 3805 if (Expr *E = dyn_cast<Expr>(S)) 3806 S = E->IgnoreParens(); 3807 if (auto BO = dyn_cast<BinaryOperator>(S)) { 3808 if (BO->getOpcode() == BO_Assign) { 3809 auto *LHS = BO->getLHS()->IgnoreParens(); 3810 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 3811 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3812 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3813 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3814 return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); 3815 } 3816 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3817 if (ME->isArrow() && 3818 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3819 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3820 } 3821 } 3822 } else if (auto DS = dyn_cast<DeclStmt>(S)) { 3823 if (DS->isSingleDecl()) { 3824 if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 3825 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 3826 // Accept non-canonical init form here but emit ext. warning. 3827 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 3828 SemaRef.Diag(S->getLocStart(), 3829 diag::ext_omp_loop_not_canonical_init) 3830 << S->getSourceRange(); 3831 return SetLCDeclAndLB(Var, nullptr, Var->getInit()); 3832 } 3833 } 3834 } 3835 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3836 if (CE->getOperator() == OO_Equal) { 3837 auto *LHS = CE->getArg(0); 3838 if (auto DRE = dyn_cast<DeclRefExpr>(LHS)) { 3839 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3840 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3841 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3842 return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); 3843 } 3844 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3845 if (ME->isArrow() && 3846 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3847 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3848 } 3849 } 3850 } 3851 3852 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3853 return false; 3854 if (EmitDiags) { 3855 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init) 3856 << S->getSourceRange(); 3857 } 3858 return true; 3859 } 3860 3861 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the 3862 /// variable (which may be the loop variable) if possible. 3863 static const ValueDecl *GetInitLCDecl(Expr *E) { 3864 if (!E) 3865 return nullptr; 3866 E = getExprAsWritten(E); 3867 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 3868 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3869 if ((Ctor->isCopyOrMoveConstructor() || 3870 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3871 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3872 E = CE->getArg(0)->IgnoreParenImpCasts(); 3873 if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 3874 if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 3875 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3876 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3877 return getCanonicalDecl(ME->getMemberDecl()); 3878 return getCanonicalDecl(VD); 3879 } 3880 } 3881 if (auto *ME = dyn_cast_or_null<MemberExpr>(E)) 3882 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3883 return getCanonicalDecl(ME->getMemberDecl()); 3884 return nullptr; 3885 } 3886 3887 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { 3888 // Check test-expr for canonical form, save upper-bound UB, flags for 3889 // less/greater and for strict/non-strict comparison. 3890 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3891 // var relational-op b 3892 // b relational-op var 3893 // 3894 if (!S) { 3895 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 3896 return true; 3897 } 3898 S = getExprAsWritten(S); 3899 SourceLocation CondLoc = S->getLocStart(); 3900 if (auto BO = dyn_cast<BinaryOperator>(S)) { 3901 if (BO->isRelationalOp()) { 3902 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3903 return SetUB(BO->getRHS(), 3904 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 3905 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3906 BO->getSourceRange(), BO->getOperatorLoc()); 3907 if (GetInitLCDecl(BO->getRHS()) == LCDecl) 3908 return SetUB(BO->getLHS(), 3909 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 3910 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3911 BO->getSourceRange(), BO->getOperatorLoc()); 3912 } 3913 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3914 if (CE->getNumArgs() == 2) { 3915 auto Op = CE->getOperator(); 3916 switch (Op) { 3917 case OO_Greater: 3918 case OO_GreaterEqual: 3919 case OO_Less: 3920 case OO_LessEqual: 3921 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3922 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 3923 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3924 CE->getOperatorLoc()); 3925 if (GetInitLCDecl(CE->getArg(1)) == LCDecl) 3926 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 3927 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3928 CE->getOperatorLoc()); 3929 break; 3930 default: 3931 break; 3932 } 3933 } 3934 } 3935 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3936 return false; 3937 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 3938 << S->getSourceRange() << LCDecl; 3939 return true; 3940 } 3941 3942 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) { 3943 // RHS of canonical loop form increment can be: 3944 // var + incr 3945 // incr + var 3946 // var - incr 3947 // 3948 RHS = RHS->IgnoreParenImpCasts(); 3949 if (auto BO = dyn_cast<BinaryOperator>(RHS)) { 3950 if (BO->isAdditiveOp()) { 3951 bool IsAdd = BO->getOpcode() == BO_Add; 3952 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3953 return SetStep(BO->getRHS(), !IsAdd); 3954 if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl) 3955 return SetStep(BO->getLHS(), false); 3956 } 3957 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 3958 bool IsAdd = CE->getOperator() == OO_Plus; 3959 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 3960 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3961 return SetStep(CE->getArg(1), !IsAdd); 3962 if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl) 3963 return SetStep(CE->getArg(0), false); 3964 } 3965 } 3966 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3967 return false; 3968 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr) 3969 << RHS->getSourceRange() << LCDecl; 3970 return true; 3971 } 3972 3973 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { 3974 // Check incr-expr for canonical loop form and return true if it 3975 // does not conform. 3976 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3977 // ++var 3978 // var++ 3979 // --var 3980 // var-- 3981 // var += incr 3982 // var -= incr 3983 // var = var + incr 3984 // var = incr + var 3985 // var = var - incr 3986 // 3987 if (!S) { 3988 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 3989 return true; 3990 } 3991 IncrementSrcRange = S->getSourceRange(); 3992 S = S->IgnoreParens(); 3993 if (auto UO = dyn_cast<UnaryOperator>(S)) { 3994 if (UO->isIncrementDecrementOp() && 3995 GetInitLCDecl(UO->getSubExpr()) == LCDecl) 3996 return SetStep( 3997 SemaRef.ActOnIntegerConstant(UO->getLocStart(), 3998 (UO->isDecrementOp() ? -1 : 1)).get(), 3999 false); 4000 } else if (auto BO = dyn_cast<BinaryOperator>(S)) { 4001 switch (BO->getOpcode()) { 4002 case BO_AddAssign: 4003 case BO_SubAssign: 4004 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 4005 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 4006 break; 4007 case BO_Assign: 4008 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 4009 return CheckIncRHS(BO->getRHS()); 4010 break; 4011 default: 4012 break; 4013 } 4014 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4015 switch (CE->getOperator()) { 4016 case OO_PlusPlus: 4017 case OO_MinusMinus: 4018 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 4019 return SetStep( 4020 SemaRef.ActOnIntegerConstant( 4021 CE->getLocStart(), 4022 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).get(), 4023 false); 4024 break; 4025 case OO_PlusEqual: 4026 case OO_MinusEqual: 4027 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 4028 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 4029 break; 4030 case OO_Equal: 4031 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 4032 return CheckIncRHS(CE->getArg(1)); 4033 break; 4034 default: 4035 break; 4036 } 4037 } 4038 if (Dependent() || SemaRef.CurContext->isDependentContext()) 4039 return false; 4040 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr) 4041 << S->getSourceRange() << LCDecl; 4042 return true; 4043 } 4044 4045 static ExprResult 4046 tryBuildCapture(Sema &SemaRef, Expr *Capture, 4047 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4048 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 4049 return SemaRef.PerformImplicitConversion( 4050 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 4051 /*AllowExplicit=*/true); 4052 auto I = Captures.find(Capture); 4053 if (I != Captures.end()) 4054 return buildCapture(SemaRef, Capture, I->second); 4055 DeclRefExpr *Ref = nullptr; 4056 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 4057 Captures[Capture] = Ref; 4058 return Res; 4059 } 4060 4061 /// \brief Build the expression to calculate the number of iterations. 4062 Expr *OpenMPIterationSpaceChecker::BuildNumIterations( 4063 Scope *S, const bool LimitedType, 4064 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 4065 ExprResult Diff; 4066 auto VarType = LCDecl->getType().getNonReferenceType(); 4067 if (VarType->isIntegerType() || VarType->isPointerType() || 4068 SemaRef.getLangOpts().CPlusPlus) { 4069 // Upper - Lower 4070 auto *UBExpr = TestIsLessOp ? UB : LB; 4071 auto *LBExpr = TestIsLessOp ? LB : UB; 4072 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 4073 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 4074 if (!Upper || !Lower) 4075 return nullptr; 4076 4077 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4078 4079 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4080 // BuildBinOp already emitted error, this one is to point user to upper 4081 // and lower bound, and to tell what is passed to 'operator-'. 4082 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) 4083 << Upper->getSourceRange() << Lower->getSourceRange(); 4084 return nullptr; 4085 } 4086 } 4087 4088 if (!Diff.isUsable()) 4089 return nullptr; 4090 4091 // Upper - Lower [- 1] 4092 if (TestIsStrictOp) 4093 Diff = SemaRef.BuildBinOp( 4094 S, DefaultLoc, BO_Sub, Diff.get(), 4095 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4096 if (!Diff.isUsable()) 4097 return nullptr; 4098 4099 // Upper - Lower [- 1] + Step 4100 auto NewStep = tryBuildCapture(SemaRef, Step, Captures); 4101 if (!NewStep.isUsable()) 4102 return nullptr; 4103 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 4104 if (!Diff.isUsable()) 4105 return nullptr; 4106 4107 // Parentheses (for dumping/debugging purposes only). 4108 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4109 if (!Diff.isUsable()) 4110 return nullptr; 4111 4112 // (Upper - Lower [- 1] + Step) / Step 4113 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4114 if (!Diff.isUsable()) 4115 return nullptr; 4116 4117 // OpenMP runtime requires 32-bit or 64-bit loop variables. 4118 QualType Type = Diff.get()->getType(); 4119 auto &C = SemaRef.Context; 4120 bool UseVarType = VarType->hasIntegerRepresentation() && 4121 C.getTypeSize(Type) > C.getTypeSize(VarType); 4122 if (!Type->isIntegerType() || UseVarType) { 4123 unsigned NewSize = 4124 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 4125 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 4126 : Type->hasSignedIntegerRepresentation(); 4127 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 4128 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 4129 Diff = SemaRef.PerformImplicitConversion( 4130 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 4131 if (!Diff.isUsable()) 4132 return nullptr; 4133 } 4134 } 4135 if (LimitedType) { 4136 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 4137 if (NewSize != C.getTypeSize(Type)) { 4138 if (NewSize < C.getTypeSize(Type)) { 4139 assert(NewSize == 64 && "incorrect loop var size"); 4140 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 4141 << InitSrcRange << ConditionSrcRange; 4142 } 4143 QualType NewType = C.getIntTypeForBitwidth( 4144 NewSize, Type->hasSignedIntegerRepresentation() || 4145 C.getTypeSize(Type) < NewSize); 4146 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 4147 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 4148 Sema::AA_Converting, true); 4149 if (!Diff.isUsable()) 4150 return nullptr; 4151 } 4152 } 4153 } 4154 4155 return Diff.get(); 4156 } 4157 4158 Expr *OpenMPIterationSpaceChecker::BuildPreCond( 4159 Scope *S, Expr *Cond, 4160 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 4161 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 4162 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4163 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4164 4165 auto NewLB = tryBuildCapture(SemaRef, LB, Captures); 4166 auto NewUB = tryBuildCapture(SemaRef, UB, Captures); 4167 if (!NewLB.isUsable() || !NewUB.isUsable()) 4168 return nullptr; 4169 4170 auto CondExpr = SemaRef.BuildBinOp( 4171 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) 4172 : (TestIsStrictOp ? BO_GT : BO_GE), 4173 NewLB.get(), NewUB.get()); 4174 if (CondExpr.isUsable()) { 4175 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 4176 SemaRef.Context.BoolTy)) 4177 CondExpr = SemaRef.PerformImplicitConversion( 4178 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 4179 /*AllowExplicit=*/true); 4180 } 4181 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4182 // Otherwise use original loop conditon and evaluate it in runtime. 4183 return CondExpr.isUsable() ? CondExpr.get() : Cond; 4184 } 4185 4186 /// \brief Build reference expression to the counter be used for codegen. 4187 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar( 4188 llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const { 4189 auto *VD = dyn_cast<VarDecl>(LCDecl); 4190 if (!VD) { 4191 VD = SemaRef.IsOpenMPCapturedDecl(LCDecl); 4192 auto *Ref = buildDeclRefExpr( 4193 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 4194 DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl, /*FromParent=*/false); 4195 // If the loop control decl is explicitly marked as private, do not mark it 4196 // as captured again. 4197 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 4198 Captures.insert(std::make_pair(LCRef, Ref)); 4199 return Ref; 4200 } 4201 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(), 4202 DefaultLoc); 4203 } 4204 4205 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const { 4206 if (LCDecl && !LCDecl->isInvalidDecl()) { 4207 auto Type = LCDecl->getType().getNonReferenceType(); 4208 auto *PrivateVar = 4209 buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(), 4210 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr); 4211 if (PrivateVar->isInvalidDecl()) 4212 return nullptr; 4213 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 4214 } 4215 return nullptr; 4216 } 4217 4218 /// \brief Build initization of the counter be used for codegen. 4219 Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; } 4220 4221 /// \brief Build step of the counter be used for codegen. 4222 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; } 4223 4224 /// \brief Iteration space of a single for loop. 4225 struct LoopIterationSpace final { 4226 /// \brief Condition of the loop. 4227 Expr *PreCond = nullptr; 4228 /// \brief This expression calculates the number of iterations in the loop. 4229 /// It is always possible to calculate it before starting the loop. 4230 Expr *NumIterations = nullptr; 4231 /// \brief The loop counter variable. 4232 Expr *CounterVar = nullptr; 4233 /// \brief Private loop counter variable. 4234 Expr *PrivateCounterVar = nullptr; 4235 /// \brief This is initializer for the initial value of #CounterVar. 4236 Expr *CounterInit = nullptr; 4237 /// \brief This is step for the #CounterVar used to generate its update: 4238 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4239 Expr *CounterStep = nullptr; 4240 /// \brief Should step be subtracted? 4241 bool Subtract = false; 4242 /// \brief Source range of the loop init. 4243 SourceRange InitSrcRange; 4244 /// \brief Source range of the loop condition. 4245 SourceRange CondSrcRange; 4246 /// \brief Source range of the loop increment. 4247 SourceRange IncSrcRange; 4248 }; 4249 4250 } // namespace 4251 4252 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 4253 assert(getLangOpts().OpenMP && "OpenMP is not active."); 4254 assert(Init && "Expected loop in canonical form."); 4255 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 4256 if (AssociatedLoops > 0 && 4257 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 4258 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 4259 if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) { 4260 if (auto *D = ISC.GetLoopDecl()) { 4261 auto *VD = dyn_cast<VarDecl>(D); 4262 if (!VD) { 4263 if (auto *Private = IsOpenMPCapturedDecl(D)) 4264 VD = Private; 4265 else { 4266 auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(), 4267 /*WithInit=*/false); 4268 VD = cast<VarDecl>(Ref->getDecl()); 4269 } 4270 } 4271 DSAStack->addLoopControlVariable(D, VD); 4272 } 4273 } 4274 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 4275 } 4276 } 4277 4278 /// \brief Called on a for stmt to check and extract its iteration space 4279 /// for further processing (such as collapsing). 4280 static bool CheckOpenMPIterationSpace( 4281 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 4282 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 4283 Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, 4284 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 4285 LoopIterationSpace &ResultIterSpace, 4286 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4287 // OpenMP [2.6, Canonical Loop Form] 4288 // for (init-expr; test-expr; incr-expr) structured-block 4289 auto For = dyn_cast_or_null<ForStmt>(S); 4290 if (!For) { 4291 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for) 4292 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 4293 << getOpenMPDirectiveName(DKind) << NestedLoopCount 4294 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 4295 if (NestedLoopCount > 1) { 4296 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 4297 SemaRef.Diag(DSA.getConstructLoc(), 4298 diag::note_omp_collapse_ordered_expr) 4299 << 2 << CollapseLoopCountExpr->getSourceRange() 4300 << OrderedLoopCountExpr->getSourceRange(); 4301 else if (CollapseLoopCountExpr) 4302 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4303 diag::note_omp_collapse_ordered_expr) 4304 << 0 << CollapseLoopCountExpr->getSourceRange(); 4305 else 4306 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4307 diag::note_omp_collapse_ordered_expr) 4308 << 1 << OrderedLoopCountExpr->getSourceRange(); 4309 } 4310 return true; 4311 } 4312 assert(For->getBody()); 4313 4314 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 4315 4316 // Check init. 4317 auto Init = For->getInit(); 4318 if (ISC.CheckInit(Init)) 4319 return true; 4320 4321 bool HasErrors = false; 4322 4323 // Check loop variable's type. 4324 if (auto *LCDecl = ISC.GetLoopDecl()) { 4325 auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr(); 4326 4327 // OpenMP [2.6, Canonical Loop Form] 4328 // Var is one of the following: 4329 // A variable of signed or unsigned integer type. 4330 // For C++, a variable of a random access iterator type. 4331 // For C, a variable of a pointer type. 4332 auto VarType = LCDecl->getType().getNonReferenceType(); 4333 if (!VarType->isDependentType() && !VarType->isIntegerType() && 4334 !VarType->isPointerType() && 4335 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 4336 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type) 4337 << SemaRef.getLangOpts().CPlusPlus; 4338 HasErrors = true; 4339 } 4340 4341 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 4342 // a Construct 4343 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4344 // parallel for construct is (are) private. 4345 // The loop iteration variable in the associated for-loop of a simd 4346 // construct with just one associated for-loop is linear with a 4347 // constant-linear-step that is the increment of the associated for-loop. 4348 // Exclude loop var from the list of variables with implicitly defined data 4349 // sharing attributes. 4350 VarsWithImplicitDSA.erase(LCDecl); 4351 4352 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 4353 // in a Construct, C/C++]. 4354 // The loop iteration variable in the associated for-loop of a simd 4355 // construct with just one associated for-loop may be listed in a linear 4356 // clause with a constant-linear-step that is the increment of the 4357 // associated for-loop. 4358 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4359 // parallel for construct may be listed in a private or lastprivate clause. 4360 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 4361 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 4362 // declared in the loop and it is predetermined as a private. 4363 auto PredeterminedCKind = 4364 isOpenMPSimdDirective(DKind) 4365 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 4366 : OMPC_private; 4367 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4368 DVar.CKind != PredeterminedCKind) || 4369 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 4370 isOpenMPDistributeDirective(DKind)) && 4371 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 4372 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 4373 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 4374 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa) 4375 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 4376 << getOpenMPClauseName(PredeterminedCKind); 4377 if (DVar.RefExpr == nullptr) 4378 DVar.CKind = PredeterminedCKind; 4379 ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 4380 HasErrors = true; 4381 } else if (LoopDeclRefExpr != nullptr) { 4382 // Make the loop iteration variable private (for worksharing constructs), 4383 // linear (for simd directives with the only one associated loop) or 4384 // lastprivate (for simd directives with several collapsed or ordered 4385 // loops). 4386 if (DVar.CKind == OMPC_unknown) 4387 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate, 4388 [](OpenMPDirectiveKind) -> bool { return true; }, 4389 /*FromParent=*/false); 4390 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 4391 } 4392 4393 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 4394 4395 // Check test-expr. 4396 HasErrors |= ISC.CheckCond(For->getCond()); 4397 4398 // Check incr-expr. 4399 HasErrors |= ISC.CheckInc(For->getInc()); 4400 } 4401 4402 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 4403 return HasErrors; 4404 4405 // Build the loop's iteration space representation. 4406 ResultIterSpace.PreCond = 4407 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures); 4408 ResultIterSpace.NumIterations = ISC.BuildNumIterations( 4409 DSA.getCurScope(), 4410 (isOpenMPWorksharingDirective(DKind) || 4411 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 4412 Captures); 4413 ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA); 4414 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); 4415 ResultIterSpace.CounterInit = ISC.BuildCounterInit(); 4416 ResultIterSpace.CounterStep = ISC.BuildCounterStep(); 4417 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); 4418 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange(); 4419 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange(); 4420 ResultIterSpace.Subtract = ISC.ShouldSubtractStep(); 4421 4422 HasErrors |= (ResultIterSpace.PreCond == nullptr || 4423 ResultIterSpace.NumIterations == nullptr || 4424 ResultIterSpace.CounterVar == nullptr || 4425 ResultIterSpace.PrivateCounterVar == nullptr || 4426 ResultIterSpace.CounterInit == nullptr || 4427 ResultIterSpace.CounterStep == nullptr); 4428 4429 return HasErrors; 4430 } 4431 4432 /// \brief Build 'VarRef = Start. 4433 static ExprResult 4434 BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 4435 ExprResult Start, 4436 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4437 // Build 'VarRef = Start. 4438 auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 4439 if (!NewStart.isUsable()) 4440 return ExprError(); 4441 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 4442 VarRef.get()->getType())) { 4443 NewStart = SemaRef.PerformImplicitConversion( 4444 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 4445 /*AllowExplicit=*/true); 4446 if (!NewStart.isUsable()) 4447 return ExprError(); 4448 } 4449 4450 auto Init = 4451 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4452 return Init; 4453 } 4454 4455 /// \brief Build 'VarRef = Start + Iter * Step'. 4456 static ExprResult 4457 BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, 4458 ExprResult VarRef, ExprResult Start, ExprResult Iter, 4459 ExprResult Step, bool Subtract, 4460 llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) { 4461 // Add parentheses (for debugging purposes only). 4462 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 4463 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 4464 !Step.isUsable()) 4465 return ExprError(); 4466 4467 ExprResult NewStep = Step; 4468 if (Captures) 4469 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 4470 if (NewStep.isInvalid()) 4471 return ExprError(); 4472 ExprResult Update = 4473 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 4474 if (!Update.isUsable()) 4475 return ExprError(); 4476 4477 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 4478 // 'VarRef = Start (+|-) Iter * Step'. 4479 ExprResult NewStart = Start; 4480 if (Captures) 4481 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 4482 if (NewStart.isInvalid()) 4483 return ExprError(); 4484 4485 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 4486 ExprResult SavedUpdate = Update; 4487 ExprResult UpdateVal; 4488 if (VarRef.get()->getType()->isOverloadableType() || 4489 NewStart.get()->getType()->isOverloadableType() || 4490 Update.get()->getType()->isOverloadableType()) { 4491 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4492 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4493 Update = 4494 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 4495 if (Update.isUsable()) { 4496 UpdateVal = 4497 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 4498 VarRef.get(), SavedUpdate.get()); 4499 if (UpdateVal.isUsable()) { 4500 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 4501 UpdateVal.get()); 4502 } 4503 } 4504 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4505 } 4506 4507 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 4508 if (!Update.isUsable() || !UpdateVal.isUsable()) { 4509 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 4510 NewStart.get(), SavedUpdate.get()); 4511 if (!Update.isUsable()) 4512 return ExprError(); 4513 4514 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 4515 VarRef.get()->getType())) { 4516 Update = SemaRef.PerformImplicitConversion( 4517 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 4518 if (!Update.isUsable()) 4519 return ExprError(); 4520 } 4521 4522 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 4523 } 4524 return Update; 4525 } 4526 4527 /// \brief Convert integer expression \a E to make it have at least \a Bits 4528 /// bits. 4529 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, 4530 Sema &SemaRef) { 4531 if (E == nullptr) 4532 return ExprError(); 4533 auto &C = SemaRef.Context; 4534 QualType OldType = E->getType(); 4535 unsigned HasBits = C.getTypeSize(OldType); 4536 if (HasBits >= Bits) 4537 return ExprResult(E); 4538 // OK to convert to signed, because new type has more bits than old. 4539 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 4540 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 4541 true); 4542 } 4543 4544 /// \brief Check if the given expression \a E is a constant integer that fits 4545 /// into \a Bits bits. 4546 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { 4547 if (E == nullptr) 4548 return false; 4549 llvm::APSInt Result; 4550 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 4551 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 4552 return false; 4553 } 4554 4555 /// Build preinits statement for the given declarations. 4556 static Stmt *buildPreInits(ASTContext &Context, 4557 SmallVectorImpl<Decl *> &PreInits) { 4558 if (!PreInits.empty()) { 4559 return new (Context) DeclStmt( 4560 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 4561 SourceLocation(), SourceLocation()); 4562 } 4563 return nullptr; 4564 } 4565 4566 /// Build preinits statement for the given declarations. 4567 static Stmt *buildPreInits(ASTContext &Context, 4568 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4569 if (!Captures.empty()) { 4570 SmallVector<Decl *, 16> PreInits; 4571 for (auto &Pair : Captures) 4572 PreInits.push_back(Pair.second->getDecl()); 4573 return buildPreInits(Context, PreInits); 4574 } 4575 return nullptr; 4576 } 4577 4578 /// Build postupdate expression for the given list of postupdates expressions. 4579 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 4580 Expr *PostUpdate = nullptr; 4581 if (!PostUpdates.empty()) { 4582 for (auto *E : PostUpdates) { 4583 Expr *ConvE = S.BuildCStyleCastExpr( 4584 E->getExprLoc(), 4585 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 4586 E->getExprLoc(), E) 4587 .get(); 4588 PostUpdate = PostUpdate 4589 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 4590 PostUpdate, ConvE) 4591 .get() 4592 : ConvE; 4593 } 4594 } 4595 return PostUpdate; 4596 } 4597 4598 /// \brief Called on a for stmt to check itself and nested loops (if any). 4599 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 4600 /// number of collapsed loops otherwise. 4601 static unsigned 4602 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 4603 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 4604 DSAStackTy &DSA, 4605 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 4606 OMPLoopDirective::HelperExprs &Built) { 4607 unsigned NestedLoopCount = 1; 4608 if (CollapseLoopCountExpr) { 4609 // Found 'collapse' clause - calculate collapse number. 4610 llvm::APSInt Result; 4611 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 4612 NestedLoopCount = Result.getLimitedValue(); 4613 } 4614 if (OrderedLoopCountExpr) { 4615 // Found 'ordered' clause - calculate collapse number. 4616 llvm::APSInt Result; 4617 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 4618 if (Result.getLimitedValue() < NestedLoopCount) { 4619 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4620 diag::err_omp_wrong_ordered_loop_count) 4621 << OrderedLoopCountExpr->getSourceRange(); 4622 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4623 diag::note_collapse_loop_count) 4624 << CollapseLoopCountExpr->getSourceRange(); 4625 } 4626 NestedLoopCount = Result.getLimitedValue(); 4627 } 4628 } 4629 // This is helper routine for loop directives (e.g., 'for', 'simd', 4630 // 'for simd', etc.). 4631 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 4632 SmallVector<LoopIterationSpace, 4> IterSpaces; 4633 IterSpaces.resize(NestedLoopCount); 4634 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 4635 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 4636 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, 4637 NestedLoopCount, CollapseLoopCountExpr, 4638 OrderedLoopCountExpr, VarsWithImplicitDSA, 4639 IterSpaces[Cnt], Captures)) 4640 return 0; 4641 // Move on to the next nested for loop, or to the loop body. 4642 // OpenMP [2.8.1, simd construct, Restrictions] 4643 // All loops associated with the construct must be perfectly nested; that 4644 // is, there must be no intervening code nor any OpenMP directive between 4645 // any two loops. 4646 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 4647 } 4648 4649 Built.clear(/* size */ NestedLoopCount); 4650 4651 if (SemaRef.CurContext->isDependentContext()) 4652 return NestedLoopCount; 4653 4654 // An example of what is generated for the following code: 4655 // 4656 // #pragma omp simd collapse(2) ordered(2) 4657 // for (i = 0; i < NI; ++i) 4658 // for (k = 0; k < NK; ++k) 4659 // for (j = J0; j < NJ; j+=2) { 4660 // <loop body> 4661 // } 4662 // 4663 // We generate the code below. 4664 // Note: the loop body may be outlined in CodeGen. 4665 // Note: some counters may be C++ classes, operator- is used to find number of 4666 // iterations and operator+= to calculate counter value. 4667 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 4668 // or i64 is currently supported). 4669 // 4670 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 4671 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 4672 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 4673 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 4674 // // similar updates for vars in clauses (e.g. 'linear') 4675 // <loop body (using local i and j)> 4676 // } 4677 // i = NI; // assign final values of counters 4678 // j = NJ; 4679 // 4680 4681 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 4682 // the iteration counts of the collapsed for loops. 4683 // Precondition tests if there is at least one iteration (all conditions are 4684 // true). 4685 auto PreCond = ExprResult(IterSpaces[0].PreCond); 4686 auto N0 = IterSpaces[0].NumIterations; 4687 ExprResult LastIteration32 = WidenIterationCount( 4688 32 /* Bits */, SemaRef.PerformImplicitConversion( 4689 N0->IgnoreImpCasts(), N0->getType(), 4690 Sema::AA_Converting, /*AllowExplicit=*/true) 4691 .get(), 4692 SemaRef); 4693 ExprResult LastIteration64 = WidenIterationCount( 4694 64 /* Bits */, SemaRef.PerformImplicitConversion( 4695 N0->IgnoreImpCasts(), N0->getType(), 4696 Sema::AA_Converting, /*AllowExplicit=*/true) 4697 .get(), 4698 SemaRef); 4699 4700 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 4701 return NestedLoopCount; 4702 4703 auto &C = SemaRef.Context; 4704 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 4705 4706 Scope *CurScope = DSA.getCurScope(); 4707 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 4708 if (PreCond.isUsable()) { 4709 PreCond = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_LAnd, 4710 PreCond.get(), IterSpaces[Cnt].PreCond); 4711 } 4712 auto N = IterSpaces[Cnt].NumIterations; 4713 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 4714 if (LastIteration32.isUsable()) 4715 LastIteration32 = SemaRef.BuildBinOp( 4716 CurScope, SourceLocation(), BO_Mul, LastIteration32.get(), 4717 SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4718 Sema::AA_Converting, 4719 /*AllowExplicit=*/true) 4720 .get()); 4721 if (LastIteration64.isUsable()) 4722 LastIteration64 = SemaRef.BuildBinOp( 4723 CurScope, SourceLocation(), BO_Mul, LastIteration64.get(), 4724 SemaRef.PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4725 Sema::AA_Converting, 4726 /*AllowExplicit=*/true) 4727 .get()); 4728 } 4729 4730 // Choose either the 32-bit or 64-bit version. 4731 ExprResult LastIteration = LastIteration64; 4732 if (LastIteration32.isUsable() && 4733 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 4734 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 4735 FitsInto( 4736 32 /* Bits */, 4737 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 4738 LastIteration64.get(), SemaRef))) 4739 LastIteration = LastIteration32; 4740 QualType VType = LastIteration.get()->getType(); 4741 QualType RealVType = VType; 4742 QualType StrideVType = VType; 4743 if (isOpenMPTaskLoopDirective(DKind)) { 4744 VType = 4745 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 4746 StrideVType = 4747 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 4748 } 4749 4750 if (!LastIteration.isUsable()) 4751 return 0; 4752 4753 // Save the number of iterations. 4754 ExprResult NumIterations = LastIteration; 4755 { 4756 LastIteration = SemaRef.BuildBinOp( 4757 CurScope, SourceLocation(), BO_Sub, LastIteration.get(), 4758 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4759 if (!LastIteration.isUsable()) 4760 return 0; 4761 } 4762 4763 // Calculate the last iteration number beforehand instead of doing this on 4764 // each iteration. Do not do this if the number of iterations may be kfold-ed. 4765 llvm::APSInt Result; 4766 bool IsConstant = 4767 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 4768 ExprResult CalcLastIteration; 4769 if (!IsConstant) { 4770 ExprResult SaveRef = 4771 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 4772 LastIteration = SaveRef; 4773 4774 // Prepare SaveRef + 1. 4775 NumIterations = SemaRef.BuildBinOp( 4776 CurScope, SourceLocation(), BO_Add, SaveRef.get(), 4777 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4778 if (!NumIterations.isUsable()) 4779 return 0; 4780 } 4781 4782 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 4783 4784 // Build variables passed into runtime, nesessary for worksharing directives. 4785 ExprResult LB, UB, IL, ST, EUB; 4786 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4787 isOpenMPDistributeDirective(DKind)) { 4788 // Lower bound variable, initialized with zero. 4789 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 4790 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 4791 SemaRef.AddInitializerToDecl( 4792 LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4793 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 4794 4795 // Upper bound variable, initialized with last iteration number. 4796 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 4797 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 4798 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 4799 /*DirectInit*/ false, 4800 /*TypeMayContainAuto*/ false); 4801 4802 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 4803 // This will be used to implement clause 'lastprivate'. 4804 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 4805 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 4806 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 4807 SemaRef.AddInitializerToDecl( 4808 ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4809 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 4810 4811 // Stride variable returned by runtime (we initialize it to 1 by default). 4812 VarDecl *STDecl = 4813 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 4814 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 4815 SemaRef.AddInitializerToDecl( 4816 STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 4817 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 4818 4819 // Build expression: UB = min(UB, LastIteration) 4820 // It is nesessary for CodeGen of directives with static scheduling. 4821 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 4822 UB.get(), LastIteration.get()); 4823 ExprResult CondOp = SemaRef.ActOnConditionalOp( 4824 InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get()); 4825 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 4826 CondOp.get()); 4827 EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); 4828 } 4829 4830 // Build the iteration variable and its initialization before loop. 4831 ExprResult IV; 4832 ExprResult Init; 4833 { 4834 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 4835 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 4836 Expr *RHS = (isOpenMPWorksharingDirective(DKind) || 4837 isOpenMPTaskLoopDirective(DKind) || 4838 isOpenMPDistributeDirective(DKind)) 4839 ? LB.get() 4840 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 4841 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 4842 Init = SemaRef.ActOnFinishFullExpr(Init.get()); 4843 } 4844 4845 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. 4846 SourceLocation CondLoc; 4847 ExprResult Cond = 4848 (isOpenMPWorksharingDirective(DKind) || 4849 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 4850 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) 4851 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 4852 NumIterations.get()); 4853 4854 // Loop increment (IV = IV + 1) 4855 SourceLocation IncLoc; 4856 ExprResult Inc = 4857 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 4858 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 4859 if (!Inc.isUsable()) 4860 return 0; 4861 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 4862 Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); 4863 if (!Inc.isUsable()) 4864 return 0; 4865 4866 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 4867 // Used for directives with static scheduling. 4868 ExprResult NextLB, NextUB; 4869 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4870 isOpenMPDistributeDirective(DKind)) { 4871 // LB + ST 4872 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 4873 if (!NextLB.isUsable()) 4874 return 0; 4875 // LB = LB + ST 4876 NextLB = 4877 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 4878 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); 4879 if (!NextLB.isUsable()) 4880 return 0; 4881 // UB + ST 4882 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 4883 if (!NextUB.isUsable()) 4884 return 0; 4885 // UB = UB + ST 4886 NextUB = 4887 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 4888 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); 4889 if (!NextUB.isUsable()) 4890 return 0; 4891 } 4892 4893 // Build updates and final values of the loop counters. 4894 bool HasErrors = false; 4895 Built.Counters.resize(NestedLoopCount); 4896 Built.Inits.resize(NestedLoopCount); 4897 Built.Updates.resize(NestedLoopCount); 4898 Built.Finals.resize(NestedLoopCount); 4899 SmallVector<Expr *, 4> LoopMultipliers; 4900 { 4901 ExprResult Div; 4902 // Go from inner nested loop to outer. 4903 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 4904 LoopIterationSpace &IS = IterSpaces[Cnt]; 4905 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 4906 // Build: Iter = (IV / Div) % IS.NumIters 4907 // where Div is product of previous iterations' IS.NumIters. 4908 ExprResult Iter; 4909 if (Div.isUsable()) { 4910 Iter = 4911 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); 4912 } else { 4913 Iter = IV; 4914 assert((Cnt == (int)NestedLoopCount - 1) && 4915 "unusable div expected on first iteration only"); 4916 } 4917 4918 if (Cnt != 0 && Iter.isUsable()) 4919 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), 4920 IS.NumIterations); 4921 if (!Iter.isUsable()) { 4922 HasErrors = true; 4923 break; 4924 } 4925 4926 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 4927 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 4928 auto *CounterVar = buildDeclRefExpr(SemaRef, VD, IS.CounterVar->getType(), 4929 IS.CounterVar->getExprLoc(), 4930 /*RefersToCapture=*/true); 4931 ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 4932 IS.CounterInit, Captures); 4933 if (!Init.isUsable()) { 4934 HasErrors = true; 4935 break; 4936 } 4937 ExprResult Update = BuildCounterUpdate( 4938 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 4939 IS.CounterStep, IS.Subtract, &Captures); 4940 if (!Update.isUsable()) { 4941 HasErrors = true; 4942 break; 4943 } 4944 4945 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 4946 ExprResult Final = BuildCounterUpdate( 4947 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 4948 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 4949 if (!Final.isUsable()) { 4950 HasErrors = true; 4951 break; 4952 } 4953 4954 // Build Div for the next iteration: Div <- Div * IS.NumIters 4955 if (Cnt != 0) { 4956 if (Div.isUnset()) 4957 Div = IS.NumIterations; 4958 else 4959 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), 4960 IS.NumIterations); 4961 4962 // Add parentheses (for debugging purposes only). 4963 if (Div.isUsable()) 4964 Div = tryBuildCapture(SemaRef, Div.get(), Captures); 4965 if (!Div.isUsable()) { 4966 HasErrors = true; 4967 break; 4968 } 4969 LoopMultipliers.push_back(Div.get()); 4970 } 4971 if (!Update.isUsable() || !Final.isUsable()) { 4972 HasErrors = true; 4973 break; 4974 } 4975 // Save results 4976 Built.Counters[Cnt] = IS.CounterVar; 4977 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 4978 Built.Inits[Cnt] = Init.get(); 4979 Built.Updates[Cnt] = Update.get(); 4980 Built.Finals[Cnt] = Final.get(); 4981 } 4982 } 4983 4984 if (HasErrors) 4985 return 0; 4986 4987 // Save results 4988 Built.IterationVarRef = IV.get(); 4989 Built.LastIteration = LastIteration.get(); 4990 Built.NumIterations = NumIterations.get(); 4991 Built.CalcLastIteration = 4992 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); 4993 Built.PreCond = PreCond.get(); 4994 Built.PreInits = buildPreInits(C, Captures); 4995 Built.Cond = Cond.get(); 4996 Built.Init = Init.get(); 4997 Built.Inc = Inc.get(); 4998 Built.LB = LB.get(); 4999 Built.UB = UB.get(); 5000 Built.IL = IL.get(); 5001 Built.ST = ST.get(); 5002 Built.EUB = EUB.get(); 5003 Built.NLB = NextLB.get(); 5004 Built.NUB = NextUB.get(); 5005 5006 Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get(); 5007 // Fill data for doacross depend clauses. 5008 for (auto Pair : DSA.getDoacrossDependClauses()) { 5009 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 5010 Pair.first->setCounterValue(CounterVal); 5011 else { 5012 if (NestedLoopCount != Pair.second.size() || 5013 NestedLoopCount != LoopMultipliers.size() + 1) { 5014 // Erroneous case - clause has some problems. 5015 Pair.first->setCounterValue(CounterVal); 5016 continue; 5017 } 5018 assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink); 5019 auto I = Pair.second.rbegin(); 5020 auto IS = IterSpaces.rbegin(); 5021 auto ILM = LoopMultipliers.rbegin(); 5022 Expr *UpCounterVal = CounterVal; 5023 Expr *Multiplier = nullptr; 5024 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 5025 if (I->first) { 5026 assert(IS->CounterStep); 5027 Expr *NormalizedOffset = 5028 SemaRef 5029 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div, 5030 I->first, IS->CounterStep) 5031 .get(); 5032 if (Multiplier) { 5033 NormalizedOffset = 5034 SemaRef 5035 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul, 5036 NormalizedOffset, Multiplier) 5037 .get(); 5038 } 5039 assert(I->second == OO_Plus || I->second == OO_Minus); 5040 BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : BO_Sub; 5041 UpCounterVal = 5042 SemaRef.BuildBinOp(CurScope, I->first->getExprLoc(), BOK, 5043 UpCounterVal, NormalizedOffset).get(); 5044 } 5045 Multiplier = *ILM; 5046 ++I; 5047 ++IS; 5048 ++ILM; 5049 } 5050 Pair.first->setCounterValue(UpCounterVal); 5051 } 5052 } 5053 5054 return NestedLoopCount; 5055 } 5056 5057 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 5058 auto CollapseClauses = 5059 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 5060 if (CollapseClauses.begin() != CollapseClauses.end()) 5061 return (*CollapseClauses.begin())->getNumForLoops(); 5062 return nullptr; 5063 } 5064 5065 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 5066 auto OrderedClauses = 5067 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 5068 if (OrderedClauses.begin() != OrderedClauses.end()) 5069 return (*OrderedClauses.begin())->getNumForLoops(); 5070 return nullptr; 5071 } 5072 5073 static bool checkSimdlenSafelenValues(Sema &S, const Expr *Simdlen, 5074 const Expr *Safelen) { 5075 llvm::APSInt SimdlenRes, SafelenRes; 5076 if (Simdlen->isValueDependent() || Simdlen->isTypeDependent() || 5077 Simdlen->isInstantiationDependent() || 5078 Simdlen->containsUnexpandedParameterPack()) 5079 return false; 5080 if (Safelen->isValueDependent() || Safelen->isTypeDependent() || 5081 Safelen->isInstantiationDependent() || 5082 Safelen->containsUnexpandedParameterPack()) 5083 return false; 5084 Simdlen->EvaluateAsInt(SimdlenRes, S.Context); 5085 Safelen->EvaluateAsInt(SafelenRes, S.Context); 5086 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 5087 // If both simdlen and safelen clauses are specified, the value of the simdlen 5088 // parameter must be less than or equal to the value of the safelen parameter. 5089 if (SimdlenRes > SafelenRes) { 5090 S.Diag(Simdlen->getExprLoc(), diag::err_omp_wrong_simdlen_safelen_values) 5091 << Simdlen->getSourceRange() << Safelen->getSourceRange(); 5092 return true; 5093 } 5094 return false; 5095 } 5096 5097 StmtResult Sema::ActOnOpenMPSimdDirective( 5098 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5099 SourceLocation EndLoc, 5100 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5101 if (!AStmt) 5102 return StmtError(); 5103 5104 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5105 OMPLoopDirective::HelperExprs B; 5106 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5107 // define the nested loops number. 5108 unsigned NestedLoopCount = CheckOpenMPLoop( 5109 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5110 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5111 if (NestedLoopCount == 0) 5112 return StmtError(); 5113 5114 assert((CurContext->isDependentContext() || B.builtAll()) && 5115 "omp simd loop exprs were not built"); 5116 5117 if (!CurContext->isDependentContext()) { 5118 // Finalize the clauses that need pre-built expressions for CodeGen. 5119 for (auto C : Clauses) { 5120 if (auto LC = dyn_cast<OMPLinearClause>(C)) 5121 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5122 B.NumIterations, *this, CurScope, 5123 DSAStack)) 5124 return StmtError(); 5125 } 5126 } 5127 5128 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 5129 // If both simdlen and safelen clauses are specified, the value of the simdlen 5130 // parameter must be less than or equal to the value of the safelen parameter. 5131 OMPSafelenClause *Safelen = nullptr; 5132 OMPSimdlenClause *Simdlen = nullptr; 5133 for (auto *Clause : Clauses) { 5134 if (Clause->getClauseKind() == OMPC_safelen) 5135 Safelen = cast<OMPSafelenClause>(Clause); 5136 else if (Clause->getClauseKind() == OMPC_simdlen) 5137 Simdlen = cast<OMPSimdlenClause>(Clause); 5138 if (Safelen && Simdlen) 5139 break; 5140 } 5141 if (Simdlen && Safelen && 5142 checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), 5143 Safelen->getSafelen())) 5144 return StmtError(); 5145 5146 getCurFunction()->setHasBranchProtectedScope(); 5147 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5148 Clauses, AStmt, B); 5149 } 5150 5151 StmtResult Sema::ActOnOpenMPForDirective( 5152 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5153 SourceLocation EndLoc, 5154 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5155 if (!AStmt) 5156 return StmtError(); 5157 5158 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5159 OMPLoopDirective::HelperExprs B; 5160 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5161 // define the nested loops number. 5162 unsigned NestedLoopCount = CheckOpenMPLoop( 5163 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5164 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5165 if (NestedLoopCount == 0) 5166 return StmtError(); 5167 5168 assert((CurContext->isDependentContext() || B.builtAll()) && 5169 "omp for loop exprs were not built"); 5170 5171 if (!CurContext->isDependentContext()) { 5172 // Finalize the clauses that need pre-built expressions for CodeGen. 5173 for (auto C : Clauses) { 5174 if (auto LC = dyn_cast<OMPLinearClause>(C)) 5175 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5176 B.NumIterations, *this, CurScope, 5177 DSAStack)) 5178 return StmtError(); 5179 } 5180 } 5181 5182 getCurFunction()->setHasBranchProtectedScope(); 5183 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5184 Clauses, AStmt, B, DSAStack->isCancelRegion()); 5185 } 5186 5187 StmtResult Sema::ActOnOpenMPForSimdDirective( 5188 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5189 SourceLocation EndLoc, 5190 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5191 if (!AStmt) 5192 return StmtError(); 5193 5194 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5195 OMPLoopDirective::HelperExprs B; 5196 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5197 // define the nested loops number. 5198 unsigned NestedLoopCount = 5199 CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 5200 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5201 VarsWithImplicitDSA, B); 5202 if (NestedLoopCount == 0) 5203 return StmtError(); 5204 5205 assert((CurContext->isDependentContext() || B.builtAll()) && 5206 "omp for simd loop exprs were not built"); 5207 5208 if (!CurContext->isDependentContext()) { 5209 // Finalize the clauses that need pre-built expressions for CodeGen. 5210 for (auto C : Clauses) { 5211 if (auto LC = dyn_cast<OMPLinearClause>(C)) 5212 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5213 B.NumIterations, *this, CurScope, 5214 DSAStack)) 5215 return StmtError(); 5216 } 5217 } 5218 5219 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 5220 // If both simdlen and safelen clauses are specified, the value of the simdlen 5221 // parameter must be less than or equal to the value of the safelen parameter. 5222 OMPSafelenClause *Safelen = nullptr; 5223 OMPSimdlenClause *Simdlen = nullptr; 5224 for (auto *Clause : Clauses) { 5225 if (Clause->getClauseKind() == OMPC_safelen) 5226 Safelen = cast<OMPSafelenClause>(Clause); 5227 else if (Clause->getClauseKind() == OMPC_simdlen) 5228 Simdlen = cast<OMPSimdlenClause>(Clause); 5229 if (Safelen && Simdlen) 5230 break; 5231 } 5232 if (Simdlen && Safelen && 5233 checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), 5234 Safelen->getSafelen())) 5235 return StmtError(); 5236 5237 getCurFunction()->setHasBranchProtectedScope(); 5238 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5239 Clauses, AStmt, B); 5240 } 5241 5242 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 5243 Stmt *AStmt, 5244 SourceLocation StartLoc, 5245 SourceLocation EndLoc) { 5246 if (!AStmt) 5247 return StmtError(); 5248 5249 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5250 auto BaseStmt = AStmt; 5251 while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5252 BaseStmt = CS->getCapturedStmt(); 5253 if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5254 auto S = C->children(); 5255 if (S.begin() == S.end()) 5256 return StmtError(); 5257 // All associated statements must be '#pragma omp section' except for 5258 // the first one. 5259 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5260 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5261 if (SectionStmt) 5262 Diag(SectionStmt->getLocStart(), 5263 diag::err_omp_sections_substmt_not_section); 5264 return StmtError(); 5265 } 5266 cast<OMPSectionDirective>(SectionStmt) 5267 ->setHasCancel(DSAStack->isCancelRegion()); 5268 } 5269 } else { 5270 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt); 5271 return StmtError(); 5272 } 5273 5274 getCurFunction()->setHasBranchProtectedScope(); 5275 5276 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5277 DSAStack->isCancelRegion()); 5278 } 5279 5280 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 5281 SourceLocation StartLoc, 5282 SourceLocation EndLoc) { 5283 if (!AStmt) 5284 return StmtError(); 5285 5286 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5287 5288 getCurFunction()->setHasBranchProtectedScope(); 5289 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 5290 5291 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 5292 DSAStack->isCancelRegion()); 5293 } 5294 5295 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 5296 Stmt *AStmt, 5297 SourceLocation StartLoc, 5298 SourceLocation EndLoc) { 5299 if (!AStmt) 5300 return StmtError(); 5301 5302 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5303 5304 getCurFunction()->setHasBranchProtectedScope(); 5305 5306 // OpenMP [2.7.3, single Construct, Restrictions] 5307 // The copyprivate clause must not be used with the nowait clause. 5308 OMPClause *Nowait = nullptr; 5309 OMPClause *Copyprivate = nullptr; 5310 for (auto *Clause : Clauses) { 5311 if (Clause->getClauseKind() == OMPC_nowait) 5312 Nowait = Clause; 5313 else if (Clause->getClauseKind() == OMPC_copyprivate) 5314 Copyprivate = Clause; 5315 if (Copyprivate && Nowait) { 5316 Diag(Copyprivate->getLocStart(), 5317 diag::err_omp_single_copyprivate_with_nowait); 5318 Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here); 5319 return StmtError(); 5320 } 5321 } 5322 5323 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5324 } 5325 5326 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 5327 SourceLocation StartLoc, 5328 SourceLocation EndLoc) { 5329 if (!AStmt) 5330 return StmtError(); 5331 5332 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5333 5334 getCurFunction()->setHasBranchProtectedScope(); 5335 5336 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 5337 } 5338 5339 StmtResult Sema::ActOnOpenMPCriticalDirective( 5340 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 5341 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 5342 if (!AStmt) 5343 return StmtError(); 5344 5345 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5346 5347 bool ErrorFound = false; 5348 llvm::APSInt Hint; 5349 SourceLocation HintLoc; 5350 bool DependentHint = false; 5351 for (auto *C : Clauses) { 5352 if (C->getClauseKind() == OMPC_hint) { 5353 if (!DirName.getName()) { 5354 Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name); 5355 ErrorFound = true; 5356 } 5357 Expr *E = cast<OMPHintClause>(C)->getHint(); 5358 if (E->isTypeDependent() || E->isValueDependent() || 5359 E->isInstantiationDependent()) 5360 DependentHint = true; 5361 else { 5362 Hint = E->EvaluateKnownConstInt(Context); 5363 HintLoc = C->getLocStart(); 5364 } 5365 } 5366 } 5367 if (ErrorFound) 5368 return StmtError(); 5369 auto Pair = DSAStack->getCriticalWithHint(DirName); 5370 if (Pair.first && DirName.getName() && !DependentHint) { 5371 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 5372 Diag(StartLoc, diag::err_omp_critical_with_hint); 5373 if (HintLoc.isValid()) { 5374 Diag(HintLoc, diag::note_omp_critical_hint_here) 5375 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 5376 } else 5377 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 5378 if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 5379 Diag(C->getLocStart(), diag::note_omp_critical_hint_here) 5380 << 1 5381 << C->getHint()->EvaluateKnownConstInt(Context).toString( 5382 /*Radix=*/10, /*Signed=*/false); 5383 } else 5384 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1; 5385 } 5386 } 5387 5388 getCurFunction()->setHasBranchProtectedScope(); 5389 5390 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 5391 Clauses, AStmt); 5392 if (!Pair.first && DirName.getName() && !DependentHint) 5393 DSAStack->addCriticalWithHint(Dir, Hint); 5394 return Dir; 5395 } 5396 5397 StmtResult Sema::ActOnOpenMPParallelForDirective( 5398 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5399 SourceLocation EndLoc, 5400 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5401 if (!AStmt) 5402 return StmtError(); 5403 5404 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5405 // 1.2.2 OpenMP Language Terminology 5406 // Structured block - An executable statement with a single entry at the 5407 // top and a single exit at the bottom. 5408 // The point of exit cannot be a branch out of the structured block. 5409 // longjmp() and throw() must not violate the entry/exit criteria. 5410 CS->getCapturedDecl()->setNothrow(); 5411 5412 OMPLoopDirective::HelperExprs B; 5413 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5414 // define the nested loops number. 5415 unsigned NestedLoopCount = 5416 CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 5417 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5418 VarsWithImplicitDSA, B); 5419 if (NestedLoopCount == 0) 5420 return StmtError(); 5421 5422 assert((CurContext->isDependentContext() || B.builtAll()) && 5423 "omp parallel for loop exprs were not built"); 5424 5425 if (!CurContext->isDependentContext()) { 5426 // Finalize the clauses that need pre-built expressions for CodeGen. 5427 for (auto C : Clauses) { 5428 if (auto LC = dyn_cast<OMPLinearClause>(C)) 5429 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5430 B.NumIterations, *this, CurScope, 5431 DSAStack)) 5432 return StmtError(); 5433 } 5434 } 5435 5436 getCurFunction()->setHasBranchProtectedScope(); 5437 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 5438 NestedLoopCount, Clauses, AStmt, B, 5439 DSAStack->isCancelRegion()); 5440 } 5441 5442 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 5443 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5444 SourceLocation EndLoc, 5445 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5446 if (!AStmt) 5447 return StmtError(); 5448 5449 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5450 // 1.2.2 OpenMP Language Terminology 5451 // Structured block - An executable statement with a single entry at the 5452 // top and a single exit at the bottom. 5453 // The point of exit cannot be a branch out of the structured block. 5454 // longjmp() and throw() must not violate the entry/exit criteria. 5455 CS->getCapturedDecl()->setNothrow(); 5456 5457 OMPLoopDirective::HelperExprs B; 5458 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5459 // define the nested loops number. 5460 unsigned NestedLoopCount = 5461 CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 5462 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5463 VarsWithImplicitDSA, B); 5464 if (NestedLoopCount == 0) 5465 return StmtError(); 5466 5467 if (!CurContext->isDependentContext()) { 5468 // Finalize the clauses that need pre-built expressions for CodeGen. 5469 for (auto C : Clauses) { 5470 if (auto LC = dyn_cast<OMPLinearClause>(C)) 5471 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5472 B.NumIterations, *this, CurScope, 5473 DSAStack)) 5474 return StmtError(); 5475 } 5476 } 5477 5478 // OpenMP 4.1 [2.8.1, simd Construct, Restrictions] 5479 // If both simdlen and safelen clauses are specified, the value of the simdlen 5480 // parameter must be less than or equal to the value of the safelen parameter. 5481 OMPSafelenClause *Safelen = nullptr; 5482 OMPSimdlenClause *Simdlen = nullptr; 5483 for (auto *Clause : Clauses) { 5484 if (Clause->getClauseKind() == OMPC_safelen) 5485 Safelen = cast<OMPSafelenClause>(Clause); 5486 else if (Clause->getClauseKind() == OMPC_simdlen) 5487 Simdlen = cast<OMPSimdlenClause>(Clause); 5488 if (Safelen && Simdlen) 5489 break; 5490 } 5491 if (Simdlen && Safelen && 5492 checkSimdlenSafelenValues(*this, Simdlen->getSimdlen(), 5493 Safelen->getSafelen())) 5494 return StmtError(); 5495 5496 getCurFunction()->setHasBranchProtectedScope(); 5497 return OMPParallelForSimdDirective::Create( 5498 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 5499 } 5500 5501 StmtResult 5502 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 5503 Stmt *AStmt, SourceLocation StartLoc, 5504 SourceLocation EndLoc) { 5505 if (!AStmt) 5506 return StmtError(); 5507 5508 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5509 auto BaseStmt = AStmt; 5510 while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5511 BaseStmt = CS->getCapturedStmt(); 5512 if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5513 auto S = C->children(); 5514 if (S.begin() == S.end()) 5515 return StmtError(); 5516 // All associated statements must be '#pragma omp section' except for 5517 // the first one. 5518 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5519 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5520 if (SectionStmt) 5521 Diag(SectionStmt->getLocStart(), 5522 diag::err_omp_parallel_sections_substmt_not_section); 5523 return StmtError(); 5524 } 5525 cast<OMPSectionDirective>(SectionStmt) 5526 ->setHasCancel(DSAStack->isCancelRegion()); 5527 } 5528 } else { 5529 Diag(AStmt->getLocStart(), 5530 diag::err_omp_parallel_sections_not_compound_stmt); 5531 return StmtError(); 5532 } 5533 5534 getCurFunction()->setHasBranchProtectedScope(); 5535 5536 return OMPParallelSectionsDirective::Create( 5537 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 5538 } 5539 5540 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 5541 Stmt *AStmt, SourceLocation StartLoc, 5542 SourceLocation EndLoc) { 5543 if (!AStmt) 5544 return StmtError(); 5545 5546 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5547 // 1.2.2 OpenMP Language Terminology 5548 // Structured block - An executable statement with a single entry at the 5549 // top and a single exit at the bottom. 5550 // The point of exit cannot be a branch out of the structured block. 5551 // longjmp() and throw() must not violate the entry/exit criteria. 5552 CS->getCapturedDecl()->setNothrow(); 5553 5554 getCurFunction()->setHasBranchProtectedScope(); 5555 5556 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5557 DSAStack->isCancelRegion()); 5558 } 5559 5560 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 5561 SourceLocation EndLoc) { 5562 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 5563 } 5564 5565 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 5566 SourceLocation EndLoc) { 5567 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 5568 } 5569 5570 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 5571 SourceLocation EndLoc) { 5572 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 5573 } 5574 5575 StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt, 5576 SourceLocation StartLoc, 5577 SourceLocation EndLoc) { 5578 if (!AStmt) 5579 return StmtError(); 5580 5581 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5582 5583 getCurFunction()->setHasBranchProtectedScope(); 5584 5585 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, AStmt); 5586 } 5587 5588 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 5589 SourceLocation StartLoc, 5590 SourceLocation EndLoc) { 5591 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 5592 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 5593 } 5594 5595 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 5596 Stmt *AStmt, 5597 SourceLocation StartLoc, 5598 SourceLocation EndLoc) { 5599 OMPClause *DependFound = nullptr; 5600 OMPClause *DependSourceClause = nullptr; 5601 OMPClause *DependSinkClause = nullptr; 5602 bool ErrorFound = false; 5603 OMPThreadsClause *TC = nullptr; 5604 OMPSIMDClause *SC = nullptr; 5605 for (auto *C : Clauses) { 5606 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 5607 DependFound = C; 5608 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 5609 if (DependSourceClause) { 5610 Diag(C->getLocStart(), diag::err_omp_more_one_clause) 5611 << getOpenMPDirectiveName(OMPD_ordered) 5612 << getOpenMPClauseName(OMPC_depend) << 2; 5613 ErrorFound = true; 5614 } else 5615 DependSourceClause = C; 5616 if (DependSinkClause) { 5617 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5618 << 0; 5619 ErrorFound = true; 5620 } 5621 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 5622 if (DependSourceClause) { 5623 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5624 << 1; 5625 ErrorFound = true; 5626 } 5627 DependSinkClause = C; 5628 } 5629 } else if (C->getClauseKind() == OMPC_threads) 5630 TC = cast<OMPThreadsClause>(C); 5631 else if (C->getClauseKind() == OMPC_simd) 5632 SC = cast<OMPSIMDClause>(C); 5633 } 5634 if (!ErrorFound && !SC && 5635 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 5636 // OpenMP [2.8.1,simd Construct, Restrictions] 5637 // An ordered construct with the simd clause is the only OpenMP construct 5638 // that can appear in the simd region. 5639 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 5640 ErrorFound = true; 5641 } else if (DependFound && (TC || SC)) { 5642 Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd) 5643 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 5644 ErrorFound = true; 5645 } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) { 5646 Diag(DependFound->getLocStart(), 5647 diag::err_omp_ordered_directive_without_param); 5648 ErrorFound = true; 5649 } else if (TC || Clauses.empty()) { 5650 if (auto *Param = DSAStack->getParentOrderedRegionParam()) { 5651 SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc; 5652 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 5653 << (TC != nullptr); 5654 Diag(Param->getLocStart(), diag::note_omp_ordered_param); 5655 ErrorFound = true; 5656 } 5657 } 5658 if ((!AStmt && !DependFound) || ErrorFound) 5659 return StmtError(); 5660 5661 if (AStmt) { 5662 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5663 5664 getCurFunction()->setHasBranchProtectedScope(); 5665 } 5666 5667 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5668 } 5669 5670 namespace { 5671 /// \brief Helper class for checking expression in 'omp atomic [update]' 5672 /// construct. 5673 class OpenMPAtomicUpdateChecker { 5674 /// \brief Error results for atomic update expressions. 5675 enum ExprAnalysisErrorCode { 5676 /// \brief A statement is not an expression statement. 5677 NotAnExpression, 5678 /// \brief Expression is not builtin binary or unary operation. 5679 NotABinaryOrUnaryExpression, 5680 /// \brief Unary operation is not post-/pre- increment/decrement operation. 5681 NotAnUnaryIncDecExpression, 5682 /// \brief An expression is not of scalar type. 5683 NotAScalarType, 5684 /// \brief A binary operation is not an assignment operation. 5685 NotAnAssignmentOp, 5686 /// \brief RHS part of the binary operation is not a binary expression. 5687 NotABinaryExpression, 5688 /// \brief RHS part is not additive/multiplicative/shift/biwise binary 5689 /// expression. 5690 NotABinaryOperator, 5691 /// \brief RHS binary operation does not have reference to the updated LHS 5692 /// part. 5693 NotAnUpdateExpression, 5694 /// \brief No errors is found. 5695 NoError 5696 }; 5697 /// \brief Reference to Sema. 5698 Sema &SemaRef; 5699 /// \brief A location for note diagnostics (when error is found). 5700 SourceLocation NoteLoc; 5701 /// \brief 'x' lvalue part of the source atomic expression. 5702 Expr *X; 5703 /// \brief 'expr' rvalue part of the source atomic expression. 5704 Expr *E; 5705 /// \brief Helper expression of the form 5706 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5707 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5708 Expr *UpdateExpr; 5709 /// \brief Is 'x' a LHS in a RHS part of full update expression. It is 5710 /// important for non-associative operations. 5711 bool IsXLHSInRHSPart; 5712 BinaryOperatorKind Op; 5713 SourceLocation OpLoc; 5714 /// \brief true if the source expression is a postfix unary operation, false 5715 /// if it is a prefix unary operation. 5716 bool IsPostfixUpdate; 5717 5718 public: 5719 OpenMPAtomicUpdateChecker(Sema &SemaRef) 5720 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 5721 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 5722 /// \brief Check specified statement that it is suitable for 'atomic update' 5723 /// constructs and extract 'x', 'expr' and Operation from the original 5724 /// expression. If DiagId and NoteId == 0, then only check is performed 5725 /// without error notification. 5726 /// \param DiagId Diagnostic which should be emitted if error is found. 5727 /// \param NoteId Diagnostic note for the main error message. 5728 /// \return true if statement is not an update expression, false otherwise. 5729 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 5730 /// \brief Return the 'x' lvalue part of the source atomic expression. 5731 Expr *getX() const { return X; } 5732 /// \brief Return the 'expr' rvalue part of the source atomic expression. 5733 Expr *getExpr() const { return E; } 5734 /// \brief Return the update expression used in calculation of the updated 5735 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5736 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5737 Expr *getUpdateExpr() const { return UpdateExpr; } 5738 /// \brief Return true if 'x' is LHS in RHS part of full update expression, 5739 /// false otherwise. 5740 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 5741 5742 /// \brief true if the source expression is a postfix unary operation, false 5743 /// if it is a prefix unary operation. 5744 bool isPostfixUpdate() const { return IsPostfixUpdate; } 5745 5746 private: 5747 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 5748 unsigned NoteId = 0); 5749 }; 5750 } // namespace 5751 5752 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 5753 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 5754 ExprAnalysisErrorCode ErrorFound = NoError; 5755 SourceLocation ErrorLoc, NoteLoc; 5756 SourceRange ErrorRange, NoteRange; 5757 // Allowed constructs are: 5758 // x = x binop expr; 5759 // x = expr binop x; 5760 if (AtomicBinOp->getOpcode() == BO_Assign) { 5761 X = AtomicBinOp->getLHS(); 5762 if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 5763 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 5764 if (AtomicInnerBinOp->isMultiplicativeOp() || 5765 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 5766 AtomicInnerBinOp->isBitwiseOp()) { 5767 Op = AtomicInnerBinOp->getOpcode(); 5768 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 5769 auto *LHS = AtomicInnerBinOp->getLHS(); 5770 auto *RHS = AtomicInnerBinOp->getRHS(); 5771 llvm::FoldingSetNodeID XId, LHSId, RHSId; 5772 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 5773 /*Canonical=*/true); 5774 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 5775 /*Canonical=*/true); 5776 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 5777 /*Canonical=*/true); 5778 if (XId == LHSId) { 5779 E = RHS; 5780 IsXLHSInRHSPart = true; 5781 } else if (XId == RHSId) { 5782 E = LHS; 5783 IsXLHSInRHSPart = false; 5784 } else { 5785 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5786 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5787 NoteLoc = X->getExprLoc(); 5788 NoteRange = X->getSourceRange(); 5789 ErrorFound = NotAnUpdateExpression; 5790 } 5791 } else { 5792 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5793 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5794 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 5795 NoteRange = SourceRange(NoteLoc, NoteLoc); 5796 ErrorFound = NotABinaryOperator; 5797 } 5798 } else { 5799 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 5800 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 5801 ErrorFound = NotABinaryExpression; 5802 } 5803 } else { 5804 ErrorLoc = AtomicBinOp->getExprLoc(); 5805 ErrorRange = AtomicBinOp->getSourceRange(); 5806 NoteLoc = AtomicBinOp->getOperatorLoc(); 5807 NoteRange = SourceRange(NoteLoc, NoteLoc); 5808 ErrorFound = NotAnAssignmentOp; 5809 } 5810 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5811 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5812 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5813 return true; 5814 } else if (SemaRef.CurContext->isDependentContext()) 5815 E = X = UpdateExpr = nullptr; 5816 return ErrorFound != NoError; 5817 } 5818 5819 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 5820 unsigned NoteId) { 5821 ExprAnalysisErrorCode ErrorFound = NoError; 5822 SourceLocation ErrorLoc, NoteLoc; 5823 SourceRange ErrorRange, NoteRange; 5824 // Allowed constructs are: 5825 // x++; 5826 // x--; 5827 // ++x; 5828 // --x; 5829 // x binop= expr; 5830 // x = x binop expr; 5831 // x = expr binop x; 5832 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 5833 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 5834 if (AtomicBody->getType()->isScalarType() || 5835 AtomicBody->isInstantiationDependent()) { 5836 if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 5837 AtomicBody->IgnoreParenImpCasts())) { 5838 // Check for Compound Assignment Operation 5839 Op = BinaryOperator::getOpForCompoundAssignment( 5840 AtomicCompAssignOp->getOpcode()); 5841 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 5842 E = AtomicCompAssignOp->getRHS(); 5843 X = AtomicCompAssignOp->getLHS(); 5844 IsXLHSInRHSPart = true; 5845 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 5846 AtomicBody->IgnoreParenImpCasts())) { 5847 // Check for Binary Operation 5848 if(checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 5849 return true; 5850 } else if (auto *AtomicUnaryOp = 5851 dyn_cast<UnaryOperator>(AtomicBody->IgnoreParenImpCasts())) { 5852 // Check for Unary Operation 5853 if (AtomicUnaryOp->isIncrementDecrementOp()) { 5854 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 5855 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 5856 OpLoc = AtomicUnaryOp->getOperatorLoc(); 5857 X = AtomicUnaryOp->getSubExpr(); 5858 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 5859 IsXLHSInRHSPart = true; 5860 } else { 5861 ErrorFound = NotAnUnaryIncDecExpression; 5862 ErrorLoc = AtomicUnaryOp->getExprLoc(); 5863 ErrorRange = AtomicUnaryOp->getSourceRange(); 5864 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 5865 NoteRange = SourceRange(NoteLoc, NoteLoc); 5866 } 5867 } else if (!AtomicBody->isInstantiationDependent()) { 5868 ErrorFound = NotABinaryOrUnaryExpression; 5869 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 5870 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 5871 } 5872 } else { 5873 ErrorFound = NotAScalarType; 5874 NoteLoc = ErrorLoc = AtomicBody->getLocStart(); 5875 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5876 } 5877 } else { 5878 ErrorFound = NotAnExpression; 5879 NoteLoc = ErrorLoc = S->getLocStart(); 5880 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5881 } 5882 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5883 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5884 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5885 return true; 5886 } else if (SemaRef.CurContext->isDependentContext()) 5887 E = X = UpdateExpr = nullptr; 5888 if (ErrorFound == NoError && E && X) { 5889 // Build an update expression of form 'OpaqueValueExpr(x) binop 5890 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 5891 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 5892 auto *OVEX = new (SemaRef.getASTContext()) 5893 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 5894 auto *OVEExpr = new (SemaRef.getASTContext()) 5895 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 5896 auto Update = 5897 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 5898 IsXLHSInRHSPart ? OVEExpr : OVEX); 5899 if (Update.isInvalid()) 5900 return true; 5901 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 5902 Sema::AA_Casting); 5903 if (Update.isInvalid()) 5904 return true; 5905 UpdateExpr = Update.get(); 5906 } 5907 return ErrorFound != NoError; 5908 } 5909 5910 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 5911 Stmt *AStmt, 5912 SourceLocation StartLoc, 5913 SourceLocation EndLoc) { 5914 if (!AStmt) 5915 return StmtError(); 5916 5917 auto CS = cast<CapturedStmt>(AStmt); 5918 // 1.2.2 OpenMP Language Terminology 5919 // Structured block - An executable statement with a single entry at the 5920 // top and a single exit at the bottom. 5921 // The point of exit cannot be a branch out of the structured block. 5922 // longjmp() and throw() must not violate the entry/exit criteria. 5923 OpenMPClauseKind AtomicKind = OMPC_unknown; 5924 SourceLocation AtomicKindLoc; 5925 for (auto *C : Clauses) { 5926 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 5927 C->getClauseKind() == OMPC_update || 5928 C->getClauseKind() == OMPC_capture) { 5929 if (AtomicKind != OMPC_unknown) { 5930 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) 5931 << SourceRange(C->getLocStart(), C->getLocEnd()); 5932 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 5933 << getOpenMPClauseName(AtomicKind); 5934 } else { 5935 AtomicKind = C->getClauseKind(); 5936 AtomicKindLoc = C->getLocStart(); 5937 } 5938 } 5939 } 5940 5941 auto Body = CS->getCapturedStmt(); 5942 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 5943 Body = EWC->getSubExpr(); 5944 5945 Expr *X = nullptr; 5946 Expr *V = nullptr; 5947 Expr *E = nullptr; 5948 Expr *UE = nullptr; 5949 bool IsXLHSInRHSPart = false; 5950 bool IsPostfixUpdate = false; 5951 // OpenMP [2.12.6, atomic Construct] 5952 // In the next expressions: 5953 // * x and v (as applicable) are both l-value expressions with scalar type. 5954 // * During the execution of an atomic region, multiple syntactic 5955 // occurrences of x must designate the same storage location. 5956 // * Neither of v and expr (as applicable) may access the storage location 5957 // designated by x. 5958 // * Neither of x and expr (as applicable) may access the storage location 5959 // designated by v. 5960 // * expr is an expression with scalar type. 5961 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 5962 // * binop, binop=, ++, and -- are not overloaded operators. 5963 // * The expression x binop expr must be numerically equivalent to x binop 5964 // (expr). This requirement is satisfied if the operators in expr have 5965 // precedence greater than binop, or by using parentheses around expr or 5966 // subexpressions of expr. 5967 // * The expression expr binop x must be numerically equivalent to (expr) 5968 // binop x. This requirement is satisfied if the operators in expr have 5969 // precedence equal to or greater than binop, or by using parentheses around 5970 // expr or subexpressions of expr. 5971 // * For forms that allow multiple occurrences of x, the number of times 5972 // that x is evaluated is unspecified. 5973 if (AtomicKind == OMPC_read) { 5974 enum { 5975 NotAnExpression, 5976 NotAnAssignmentOp, 5977 NotAScalarType, 5978 NotAnLValue, 5979 NoError 5980 } ErrorFound = NoError; 5981 SourceLocation ErrorLoc, NoteLoc; 5982 SourceRange ErrorRange, NoteRange; 5983 // If clause is read: 5984 // v = x; 5985 if (auto AtomicBody = dyn_cast<Expr>(Body)) { 5986 auto AtomicBinOp = 5987 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5988 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5989 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 5990 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 5991 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 5992 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 5993 if (!X->isLValue() || !V->isLValue()) { 5994 auto NotLValueExpr = X->isLValue() ? V : X; 5995 ErrorFound = NotAnLValue; 5996 ErrorLoc = AtomicBinOp->getExprLoc(); 5997 ErrorRange = AtomicBinOp->getSourceRange(); 5998 NoteLoc = NotLValueExpr->getExprLoc(); 5999 NoteRange = NotLValueExpr->getSourceRange(); 6000 } 6001 } else if (!X->isInstantiationDependent() || 6002 !V->isInstantiationDependent()) { 6003 auto NotScalarExpr = 6004 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6005 ? V 6006 : X; 6007 ErrorFound = NotAScalarType; 6008 ErrorLoc = AtomicBinOp->getExprLoc(); 6009 ErrorRange = AtomicBinOp->getSourceRange(); 6010 NoteLoc = NotScalarExpr->getExprLoc(); 6011 NoteRange = NotScalarExpr->getSourceRange(); 6012 } 6013 } else if (!AtomicBody->isInstantiationDependent()) { 6014 ErrorFound = NotAnAssignmentOp; 6015 ErrorLoc = AtomicBody->getExprLoc(); 6016 ErrorRange = AtomicBody->getSourceRange(); 6017 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6018 : AtomicBody->getExprLoc(); 6019 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6020 : AtomicBody->getSourceRange(); 6021 } 6022 } else { 6023 ErrorFound = NotAnExpression; 6024 NoteLoc = ErrorLoc = Body->getLocStart(); 6025 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6026 } 6027 if (ErrorFound != NoError) { 6028 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 6029 << ErrorRange; 6030 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 6031 << NoteRange; 6032 return StmtError(); 6033 } else if (CurContext->isDependentContext()) 6034 V = X = nullptr; 6035 } else if (AtomicKind == OMPC_write) { 6036 enum { 6037 NotAnExpression, 6038 NotAnAssignmentOp, 6039 NotAScalarType, 6040 NotAnLValue, 6041 NoError 6042 } ErrorFound = NoError; 6043 SourceLocation ErrorLoc, NoteLoc; 6044 SourceRange ErrorRange, NoteRange; 6045 // If clause is write: 6046 // x = expr; 6047 if (auto AtomicBody = dyn_cast<Expr>(Body)) { 6048 auto AtomicBinOp = 6049 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6050 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6051 X = AtomicBinOp->getLHS(); 6052 E = AtomicBinOp->getRHS(); 6053 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6054 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 6055 if (!X->isLValue()) { 6056 ErrorFound = NotAnLValue; 6057 ErrorLoc = AtomicBinOp->getExprLoc(); 6058 ErrorRange = AtomicBinOp->getSourceRange(); 6059 NoteLoc = X->getExprLoc(); 6060 NoteRange = X->getSourceRange(); 6061 } 6062 } else if (!X->isInstantiationDependent() || 6063 !E->isInstantiationDependent()) { 6064 auto NotScalarExpr = 6065 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6066 ? E 6067 : X; 6068 ErrorFound = NotAScalarType; 6069 ErrorLoc = AtomicBinOp->getExprLoc(); 6070 ErrorRange = AtomicBinOp->getSourceRange(); 6071 NoteLoc = NotScalarExpr->getExprLoc(); 6072 NoteRange = NotScalarExpr->getSourceRange(); 6073 } 6074 } else if (!AtomicBody->isInstantiationDependent()) { 6075 ErrorFound = NotAnAssignmentOp; 6076 ErrorLoc = AtomicBody->getExprLoc(); 6077 ErrorRange = AtomicBody->getSourceRange(); 6078 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6079 : AtomicBody->getExprLoc(); 6080 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6081 : AtomicBody->getSourceRange(); 6082 } 6083 } else { 6084 ErrorFound = NotAnExpression; 6085 NoteLoc = ErrorLoc = Body->getLocStart(); 6086 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6087 } 6088 if (ErrorFound != NoError) { 6089 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 6090 << ErrorRange; 6091 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 6092 << NoteRange; 6093 return StmtError(); 6094 } else if (CurContext->isDependentContext()) 6095 E = X = nullptr; 6096 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 6097 // If clause is update: 6098 // x++; 6099 // x--; 6100 // ++x; 6101 // --x; 6102 // x binop= expr; 6103 // x = x binop expr; 6104 // x = expr binop x; 6105 OpenMPAtomicUpdateChecker Checker(*this); 6106 if (Checker.checkStatement( 6107 Body, (AtomicKind == OMPC_update) 6108 ? diag::err_omp_atomic_update_not_expression_statement 6109 : diag::err_omp_atomic_not_expression_statement, 6110 diag::note_omp_atomic_update)) 6111 return StmtError(); 6112 if (!CurContext->isDependentContext()) { 6113 E = Checker.getExpr(); 6114 X = Checker.getX(); 6115 UE = Checker.getUpdateExpr(); 6116 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6117 } 6118 } else if (AtomicKind == OMPC_capture) { 6119 enum { 6120 NotAnAssignmentOp, 6121 NotACompoundStatement, 6122 NotTwoSubstatements, 6123 NotASpecificExpression, 6124 NoError 6125 } ErrorFound = NoError; 6126 SourceLocation ErrorLoc, NoteLoc; 6127 SourceRange ErrorRange, NoteRange; 6128 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 6129 // If clause is a capture: 6130 // v = x++; 6131 // v = x--; 6132 // v = ++x; 6133 // v = --x; 6134 // v = x binop= expr; 6135 // v = x = x binop expr; 6136 // v = x = expr binop x; 6137 auto *AtomicBinOp = 6138 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6139 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6140 V = AtomicBinOp->getLHS(); 6141 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6142 OpenMPAtomicUpdateChecker Checker(*this); 6143 if (Checker.checkStatement( 6144 Body, diag::err_omp_atomic_capture_not_expression_statement, 6145 diag::note_omp_atomic_update)) 6146 return StmtError(); 6147 E = Checker.getExpr(); 6148 X = Checker.getX(); 6149 UE = Checker.getUpdateExpr(); 6150 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6151 IsPostfixUpdate = Checker.isPostfixUpdate(); 6152 } else if (!AtomicBody->isInstantiationDependent()) { 6153 ErrorLoc = AtomicBody->getExprLoc(); 6154 ErrorRange = AtomicBody->getSourceRange(); 6155 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6156 : AtomicBody->getExprLoc(); 6157 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6158 : AtomicBody->getSourceRange(); 6159 ErrorFound = NotAnAssignmentOp; 6160 } 6161 if (ErrorFound != NoError) { 6162 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 6163 << ErrorRange; 6164 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6165 return StmtError(); 6166 } else if (CurContext->isDependentContext()) { 6167 UE = V = E = X = nullptr; 6168 } 6169 } else { 6170 // If clause is a capture: 6171 // { v = x; x = expr; } 6172 // { v = x; x++; } 6173 // { v = x; x--; } 6174 // { v = x; ++x; } 6175 // { v = x; --x; } 6176 // { v = x; x binop= expr; } 6177 // { v = x; x = x binop expr; } 6178 // { v = x; x = expr binop x; } 6179 // { x++; v = x; } 6180 // { x--; v = x; } 6181 // { ++x; v = x; } 6182 // { --x; v = x; } 6183 // { x binop= expr; v = x; } 6184 // { x = x binop expr; v = x; } 6185 // { x = expr binop x; v = x; } 6186 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 6187 // Check that this is { expr1; expr2; } 6188 if (CS->size() == 2) { 6189 auto *First = CS->body_front(); 6190 auto *Second = CS->body_back(); 6191 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 6192 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 6193 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 6194 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 6195 // Need to find what subexpression is 'v' and what is 'x'. 6196 OpenMPAtomicUpdateChecker Checker(*this); 6197 bool IsUpdateExprFound = !Checker.checkStatement(Second); 6198 BinaryOperator *BinOp = nullptr; 6199 if (IsUpdateExprFound) { 6200 BinOp = dyn_cast<BinaryOperator>(First); 6201 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6202 } 6203 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6204 // { v = x; x++; } 6205 // { v = x; x--; } 6206 // { v = x; ++x; } 6207 // { v = x; --x; } 6208 // { v = x; x binop= expr; } 6209 // { v = x; x = x binop expr; } 6210 // { v = x; x = expr binop x; } 6211 // Check that the first expression has form v = x. 6212 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6213 llvm::FoldingSetNodeID XId, PossibleXId; 6214 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6215 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6216 IsUpdateExprFound = XId == PossibleXId; 6217 if (IsUpdateExprFound) { 6218 V = BinOp->getLHS(); 6219 X = Checker.getX(); 6220 E = Checker.getExpr(); 6221 UE = Checker.getUpdateExpr(); 6222 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6223 IsPostfixUpdate = true; 6224 } 6225 } 6226 if (!IsUpdateExprFound) { 6227 IsUpdateExprFound = !Checker.checkStatement(First); 6228 BinOp = nullptr; 6229 if (IsUpdateExprFound) { 6230 BinOp = dyn_cast<BinaryOperator>(Second); 6231 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6232 } 6233 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6234 // { x++; v = x; } 6235 // { x--; v = x; } 6236 // { ++x; v = x; } 6237 // { --x; v = x; } 6238 // { x binop= expr; v = x; } 6239 // { x = x binop expr; v = x; } 6240 // { x = expr binop x; v = x; } 6241 // Check that the second expression has form v = x. 6242 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6243 llvm::FoldingSetNodeID XId, PossibleXId; 6244 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6245 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6246 IsUpdateExprFound = XId == PossibleXId; 6247 if (IsUpdateExprFound) { 6248 V = BinOp->getLHS(); 6249 X = Checker.getX(); 6250 E = Checker.getExpr(); 6251 UE = Checker.getUpdateExpr(); 6252 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6253 IsPostfixUpdate = false; 6254 } 6255 } 6256 } 6257 if (!IsUpdateExprFound) { 6258 // { v = x; x = expr; } 6259 auto *FirstExpr = dyn_cast<Expr>(First); 6260 auto *SecondExpr = dyn_cast<Expr>(Second); 6261 if (!FirstExpr || !SecondExpr || 6262 !(FirstExpr->isInstantiationDependent() || 6263 SecondExpr->isInstantiationDependent())) { 6264 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 6265 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 6266 ErrorFound = NotAnAssignmentOp; 6267 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 6268 : First->getLocStart(); 6269 NoteRange = ErrorRange = FirstBinOp 6270 ? FirstBinOp->getSourceRange() 6271 : SourceRange(ErrorLoc, ErrorLoc); 6272 } else { 6273 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 6274 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 6275 ErrorFound = NotAnAssignmentOp; 6276 NoteLoc = ErrorLoc = SecondBinOp 6277 ? SecondBinOp->getOperatorLoc() 6278 : Second->getLocStart(); 6279 NoteRange = ErrorRange = 6280 SecondBinOp ? SecondBinOp->getSourceRange() 6281 : SourceRange(ErrorLoc, ErrorLoc); 6282 } else { 6283 auto *PossibleXRHSInFirst = 6284 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 6285 auto *PossibleXLHSInSecond = 6286 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 6287 llvm::FoldingSetNodeID X1Id, X2Id; 6288 PossibleXRHSInFirst->Profile(X1Id, Context, 6289 /*Canonical=*/true); 6290 PossibleXLHSInSecond->Profile(X2Id, Context, 6291 /*Canonical=*/true); 6292 IsUpdateExprFound = X1Id == X2Id; 6293 if (IsUpdateExprFound) { 6294 V = FirstBinOp->getLHS(); 6295 X = SecondBinOp->getLHS(); 6296 E = SecondBinOp->getRHS(); 6297 UE = nullptr; 6298 IsXLHSInRHSPart = false; 6299 IsPostfixUpdate = true; 6300 } else { 6301 ErrorFound = NotASpecificExpression; 6302 ErrorLoc = FirstBinOp->getExprLoc(); 6303 ErrorRange = FirstBinOp->getSourceRange(); 6304 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 6305 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 6306 } 6307 } 6308 } 6309 } 6310 } 6311 } else { 6312 NoteLoc = ErrorLoc = Body->getLocStart(); 6313 NoteRange = ErrorRange = 6314 SourceRange(Body->getLocStart(), Body->getLocStart()); 6315 ErrorFound = NotTwoSubstatements; 6316 } 6317 } else { 6318 NoteLoc = ErrorLoc = Body->getLocStart(); 6319 NoteRange = ErrorRange = 6320 SourceRange(Body->getLocStart(), Body->getLocStart()); 6321 ErrorFound = NotACompoundStatement; 6322 } 6323 if (ErrorFound != NoError) { 6324 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 6325 << ErrorRange; 6326 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6327 return StmtError(); 6328 } else if (CurContext->isDependentContext()) { 6329 UE = V = E = X = nullptr; 6330 } 6331 } 6332 } 6333 6334 getCurFunction()->setHasBranchProtectedScope(); 6335 6336 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6337 X, V, E, UE, IsXLHSInRHSPart, 6338 IsPostfixUpdate); 6339 } 6340 6341 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 6342 Stmt *AStmt, 6343 SourceLocation StartLoc, 6344 SourceLocation EndLoc) { 6345 if (!AStmt) 6346 return StmtError(); 6347 6348 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6349 // 1.2.2 OpenMP Language Terminology 6350 // Structured block - An executable statement with a single entry at the 6351 // top and a single exit at the bottom. 6352 // The point of exit cannot be a branch out of the structured block. 6353 // longjmp() and throw() must not violate the entry/exit criteria. 6354 CS->getCapturedDecl()->setNothrow(); 6355 6356 // OpenMP [2.16, Nesting of Regions] 6357 // If specified, a teams construct must be contained within a target 6358 // construct. That target construct must contain no statements or directives 6359 // outside of the teams construct. 6360 if (DSAStack->hasInnerTeamsRegion()) { 6361 auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true); 6362 bool OMPTeamsFound = true; 6363 if (auto *CS = dyn_cast<CompoundStmt>(S)) { 6364 auto I = CS->body_begin(); 6365 while (I != CS->body_end()) { 6366 auto OED = dyn_cast<OMPExecutableDirective>(*I); 6367 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { 6368 OMPTeamsFound = false; 6369 break; 6370 } 6371 ++I; 6372 } 6373 assert(I != CS->body_end() && "Not found statement"); 6374 S = *I; 6375 } 6376 if (!OMPTeamsFound) { 6377 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 6378 Diag(DSAStack->getInnerTeamsRegionLoc(), 6379 diag::note_omp_nested_teams_construct_here); 6380 Diag(S->getLocStart(), diag::note_omp_nested_statement_here) 6381 << isa<OMPExecutableDirective>(S); 6382 return StmtError(); 6383 } 6384 } 6385 6386 getCurFunction()->setHasBranchProtectedScope(); 6387 6388 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6389 } 6390 6391 StmtResult 6392 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 6393 Stmt *AStmt, SourceLocation StartLoc, 6394 SourceLocation EndLoc) { 6395 if (!AStmt) 6396 return StmtError(); 6397 6398 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6399 // 1.2.2 OpenMP Language Terminology 6400 // Structured block - An executable statement with a single entry at the 6401 // top and a single exit at the bottom. 6402 // The point of exit cannot be a branch out of the structured block. 6403 // longjmp() and throw() must not violate the entry/exit criteria. 6404 CS->getCapturedDecl()->setNothrow(); 6405 6406 getCurFunction()->setHasBranchProtectedScope(); 6407 6408 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6409 AStmt); 6410 } 6411 6412 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 6413 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6414 SourceLocation EndLoc, 6415 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6416 if (!AStmt) 6417 return StmtError(); 6418 6419 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6420 // 1.2.2 OpenMP Language Terminology 6421 // Structured block - An executable statement with a single entry at the 6422 // top and a single exit at the bottom. 6423 // The point of exit cannot be a branch out of the structured block. 6424 // longjmp() and throw() must not violate the entry/exit criteria. 6425 CS->getCapturedDecl()->setNothrow(); 6426 6427 OMPLoopDirective::HelperExprs B; 6428 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6429 // define the nested loops number. 6430 unsigned NestedLoopCount = 6431 CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 6432 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6433 VarsWithImplicitDSA, B); 6434 if (NestedLoopCount == 0) 6435 return StmtError(); 6436 6437 assert((CurContext->isDependentContext() || B.builtAll()) && 6438 "omp target parallel for loop exprs were not built"); 6439 6440 if (!CurContext->isDependentContext()) { 6441 // Finalize the clauses that need pre-built expressions for CodeGen. 6442 for (auto C : Clauses) { 6443 if (auto LC = dyn_cast<OMPLinearClause>(C)) 6444 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6445 B.NumIterations, *this, CurScope, 6446 DSAStack)) 6447 return StmtError(); 6448 } 6449 } 6450 6451 getCurFunction()->setHasBranchProtectedScope(); 6452 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 6453 NestedLoopCount, Clauses, AStmt, 6454 B, DSAStack->isCancelRegion()); 6455 } 6456 6457 /// \brief Check for existence of a map clause in the list of clauses. 6458 static bool HasMapClause(ArrayRef<OMPClause *> Clauses) { 6459 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end(); 6460 I != E; ++I) { 6461 if (*I != nullptr && (*I)->getClauseKind() == OMPC_map) { 6462 return true; 6463 } 6464 } 6465 6466 return false; 6467 } 6468 6469 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 6470 Stmt *AStmt, 6471 SourceLocation StartLoc, 6472 SourceLocation EndLoc) { 6473 if (!AStmt) 6474 return StmtError(); 6475 6476 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6477 6478 // OpenMP [2.10.1, Restrictions, p. 97] 6479 // At least one map clause must appear on the directive. 6480 if (!HasMapClause(Clauses)) { 6481 Diag(StartLoc, diag::err_omp_no_map_for_directive) << 6482 getOpenMPDirectiveName(OMPD_target_data); 6483 return StmtError(); 6484 } 6485 6486 getCurFunction()->setHasBranchProtectedScope(); 6487 6488 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 6489 AStmt); 6490 } 6491 6492 StmtResult 6493 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 6494 SourceLocation StartLoc, 6495 SourceLocation EndLoc) { 6496 // OpenMP [2.10.2, Restrictions, p. 99] 6497 // At least one map clause must appear on the directive. 6498 if (!HasMapClause(Clauses)) { 6499 Diag(StartLoc, diag::err_omp_no_map_for_directive) 6500 << getOpenMPDirectiveName(OMPD_target_enter_data); 6501 return StmtError(); 6502 } 6503 6504 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, 6505 Clauses); 6506 } 6507 6508 StmtResult 6509 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 6510 SourceLocation StartLoc, 6511 SourceLocation EndLoc) { 6512 // OpenMP [2.10.3, Restrictions, p. 102] 6513 // At least one map clause must appear on the directive. 6514 if (!HasMapClause(Clauses)) { 6515 Diag(StartLoc, diag::err_omp_no_map_for_directive) 6516 << getOpenMPDirectiveName(OMPD_target_exit_data); 6517 return StmtError(); 6518 } 6519 6520 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses); 6521 } 6522 6523 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 6524 SourceLocation StartLoc, 6525 SourceLocation EndLoc) { 6526 bool seenMotionClause = false; 6527 for (auto *C : Clauses) { 6528 if (C->getClauseKind() == OMPC_to || C->getClauseKind() == OMPC_from) 6529 seenMotionClause = true; 6530 } 6531 if (!seenMotionClause) { 6532 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 6533 return StmtError(); 6534 } 6535 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses); 6536 } 6537 6538 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 6539 Stmt *AStmt, SourceLocation StartLoc, 6540 SourceLocation EndLoc) { 6541 if (!AStmt) 6542 return StmtError(); 6543 6544 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6545 // 1.2.2 OpenMP Language Terminology 6546 // Structured block - An executable statement with a single entry at the 6547 // top and a single exit at the bottom. 6548 // The point of exit cannot be a branch out of the structured block. 6549 // longjmp() and throw() must not violate the entry/exit criteria. 6550 CS->getCapturedDecl()->setNothrow(); 6551 6552 getCurFunction()->setHasBranchProtectedScope(); 6553 6554 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6555 } 6556 6557 StmtResult 6558 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 6559 SourceLocation EndLoc, 6560 OpenMPDirectiveKind CancelRegion) { 6561 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for && 6562 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) { 6563 Diag(StartLoc, diag::err_omp_wrong_cancel_region) 6564 << getOpenMPDirectiveName(CancelRegion); 6565 return StmtError(); 6566 } 6567 if (DSAStack->isParentNowaitRegion()) { 6568 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 6569 return StmtError(); 6570 } 6571 if (DSAStack->isParentOrderedRegion()) { 6572 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 6573 return StmtError(); 6574 } 6575 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 6576 CancelRegion); 6577 } 6578 6579 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 6580 SourceLocation StartLoc, 6581 SourceLocation EndLoc, 6582 OpenMPDirectiveKind CancelRegion) { 6583 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for && 6584 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) { 6585 Diag(StartLoc, diag::err_omp_wrong_cancel_region) 6586 << getOpenMPDirectiveName(CancelRegion); 6587 return StmtError(); 6588 } 6589 if (DSAStack->isParentNowaitRegion()) { 6590 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 6591 return StmtError(); 6592 } 6593 if (DSAStack->isParentOrderedRegion()) { 6594 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 6595 return StmtError(); 6596 } 6597 DSAStack->setParentCancelRegion(/*Cancel=*/true); 6598 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6599 CancelRegion); 6600 } 6601 6602 static bool checkGrainsizeNumTasksClauses(Sema &S, 6603 ArrayRef<OMPClause *> Clauses) { 6604 OMPClause *PrevClause = nullptr; 6605 bool ErrorFound = false; 6606 for (auto *C : Clauses) { 6607 if (C->getClauseKind() == OMPC_grainsize || 6608 C->getClauseKind() == OMPC_num_tasks) { 6609 if (!PrevClause) 6610 PrevClause = C; 6611 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 6612 S.Diag(C->getLocStart(), 6613 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 6614 << getOpenMPClauseName(C->getClauseKind()) 6615 << getOpenMPClauseName(PrevClause->getClauseKind()); 6616 S.Diag(PrevClause->getLocStart(), 6617 diag::note_omp_previous_grainsize_num_tasks) 6618 << getOpenMPClauseName(PrevClause->getClauseKind()); 6619 ErrorFound = true; 6620 } 6621 } 6622 } 6623 return ErrorFound; 6624 } 6625 6626 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 6627 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6628 SourceLocation EndLoc, 6629 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6630 if (!AStmt) 6631 return StmtError(); 6632 6633 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6634 OMPLoopDirective::HelperExprs B; 6635 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6636 // define the nested loops number. 6637 unsigned NestedLoopCount = 6638 CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 6639 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6640 VarsWithImplicitDSA, B); 6641 if (NestedLoopCount == 0) 6642 return StmtError(); 6643 6644 assert((CurContext->isDependentContext() || B.builtAll()) && 6645 "omp for loop exprs were not built"); 6646 6647 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6648 // The grainsize clause and num_tasks clause are mutually exclusive and may 6649 // not appear on the same taskloop directive. 6650 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6651 return StmtError(); 6652 6653 getCurFunction()->setHasBranchProtectedScope(); 6654 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 6655 NestedLoopCount, Clauses, AStmt, B); 6656 } 6657 6658 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 6659 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6660 SourceLocation EndLoc, 6661 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6662 if (!AStmt) 6663 return StmtError(); 6664 6665 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6666 OMPLoopDirective::HelperExprs B; 6667 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6668 // define the nested loops number. 6669 unsigned NestedLoopCount = 6670 CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 6671 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6672 VarsWithImplicitDSA, B); 6673 if (NestedLoopCount == 0) 6674 return StmtError(); 6675 6676 assert((CurContext->isDependentContext() || B.builtAll()) && 6677 "omp for loop exprs were not built"); 6678 6679 if (!CurContext->isDependentContext()) { 6680 // Finalize the clauses that need pre-built expressions for CodeGen. 6681 for (auto C : Clauses) { 6682 if (auto LC = dyn_cast<OMPLinearClause>(C)) 6683 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6684 B.NumIterations, *this, CurScope, 6685 DSAStack)) 6686 return StmtError(); 6687 } 6688 } 6689 6690 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6691 // The grainsize clause and num_tasks clause are mutually exclusive and may 6692 // not appear on the same taskloop directive. 6693 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6694 return StmtError(); 6695 6696 getCurFunction()->setHasBranchProtectedScope(); 6697 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 6698 NestedLoopCount, Clauses, AStmt, B); 6699 } 6700 6701 StmtResult Sema::ActOnOpenMPDistributeDirective( 6702 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6703 SourceLocation EndLoc, 6704 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6705 if (!AStmt) 6706 return StmtError(); 6707 6708 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6709 OMPLoopDirective::HelperExprs B; 6710 // In presence of clause 'collapse' with number of loops, it will 6711 // define the nested loops number. 6712 unsigned NestedLoopCount = 6713 CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 6714 nullptr /*ordered not a clause on distribute*/, AStmt, 6715 *this, *DSAStack, VarsWithImplicitDSA, B); 6716 if (NestedLoopCount == 0) 6717 return StmtError(); 6718 6719 assert((CurContext->isDependentContext() || B.builtAll()) && 6720 "omp for loop exprs were not built"); 6721 6722 getCurFunction()->setHasBranchProtectedScope(); 6723 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 6724 NestedLoopCount, Clauses, AStmt, B); 6725 } 6726 6727 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 6728 SourceLocation StartLoc, 6729 SourceLocation LParenLoc, 6730 SourceLocation EndLoc) { 6731 OMPClause *Res = nullptr; 6732 switch (Kind) { 6733 case OMPC_final: 6734 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 6735 break; 6736 case OMPC_num_threads: 6737 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 6738 break; 6739 case OMPC_safelen: 6740 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 6741 break; 6742 case OMPC_simdlen: 6743 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 6744 break; 6745 case OMPC_collapse: 6746 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 6747 break; 6748 case OMPC_ordered: 6749 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 6750 break; 6751 case OMPC_device: 6752 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 6753 break; 6754 case OMPC_num_teams: 6755 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 6756 break; 6757 case OMPC_thread_limit: 6758 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 6759 break; 6760 case OMPC_priority: 6761 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 6762 break; 6763 case OMPC_grainsize: 6764 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 6765 break; 6766 case OMPC_num_tasks: 6767 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 6768 break; 6769 case OMPC_hint: 6770 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 6771 break; 6772 case OMPC_if: 6773 case OMPC_default: 6774 case OMPC_proc_bind: 6775 case OMPC_schedule: 6776 case OMPC_private: 6777 case OMPC_firstprivate: 6778 case OMPC_lastprivate: 6779 case OMPC_shared: 6780 case OMPC_reduction: 6781 case OMPC_linear: 6782 case OMPC_aligned: 6783 case OMPC_copyin: 6784 case OMPC_copyprivate: 6785 case OMPC_nowait: 6786 case OMPC_untied: 6787 case OMPC_mergeable: 6788 case OMPC_threadprivate: 6789 case OMPC_flush: 6790 case OMPC_read: 6791 case OMPC_write: 6792 case OMPC_update: 6793 case OMPC_capture: 6794 case OMPC_seq_cst: 6795 case OMPC_depend: 6796 case OMPC_threads: 6797 case OMPC_simd: 6798 case OMPC_map: 6799 case OMPC_nogroup: 6800 case OMPC_dist_schedule: 6801 case OMPC_defaultmap: 6802 case OMPC_unknown: 6803 case OMPC_uniform: 6804 case OMPC_to: 6805 case OMPC_from: 6806 llvm_unreachable("Clause is not allowed."); 6807 } 6808 return Res; 6809 } 6810 6811 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 6812 Expr *Condition, SourceLocation StartLoc, 6813 SourceLocation LParenLoc, 6814 SourceLocation NameModifierLoc, 6815 SourceLocation ColonLoc, 6816 SourceLocation EndLoc) { 6817 Expr *ValExpr = Condition; 6818 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 6819 !Condition->isInstantiationDependent() && 6820 !Condition->containsUnexpandedParameterPack()) { 6821 ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(), 6822 Condition->getExprLoc(), Condition); 6823 if (Val.isInvalid()) 6824 return nullptr; 6825 6826 ValExpr = Val.get(); 6827 } 6828 6829 return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc, 6830 NameModifierLoc, ColonLoc, EndLoc); 6831 } 6832 6833 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 6834 SourceLocation StartLoc, 6835 SourceLocation LParenLoc, 6836 SourceLocation EndLoc) { 6837 Expr *ValExpr = Condition; 6838 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 6839 !Condition->isInstantiationDependent() && 6840 !Condition->containsUnexpandedParameterPack()) { 6841 ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(), 6842 Condition->getExprLoc(), Condition); 6843 if (Val.isInvalid()) 6844 return nullptr; 6845 6846 ValExpr = Val.get(); 6847 } 6848 6849 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 6850 } 6851 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 6852 Expr *Op) { 6853 if (!Op) 6854 return ExprError(); 6855 6856 class IntConvertDiagnoser : public ICEConvertDiagnoser { 6857 public: 6858 IntConvertDiagnoser() 6859 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 6860 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 6861 QualType T) override { 6862 return S.Diag(Loc, diag::err_omp_not_integral) << T; 6863 } 6864 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 6865 QualType T) override { 6866 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 6867 } 6868 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 6869 QualType T, 6870 QualType ConvTy) override { 6871 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 6872 } 6873 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 6874 QualType ConvTy) override { 6875 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 6876 << ConvTy->isEnumeralType() << ConvTy; 6877 } 6878 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 6879 QualType T) override { 6880 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 6881 } 6882 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 6883 QualType ConvTy) override { 6884 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 6885 << ConvTy->isEnumeralType() << ConvTy; 6886 } 6887 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 6888 QualType) override { 6889 llvm_unreachable("conversion functions are permitted"); 6890 } 6891 } ConvertDiagnoser; 6892 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 6893 } 6894 6895 static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 6896 OpenMPClauseKind CKind, 6897 bool StrictlyPositive) { 6898 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 6899 !ValExpr->isInstantiationDependent()) { 6900 SourceLocation Loc = ValExpr->getExprLoc(); 6901 ExprResult Value = 6902 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 6903 if (Value.isInvalid()) 6904 return false; 6905 6906 ValExpr = Value.get(); 6907 // The expression must evaluate to a non-negative integer value. 6908 llvm::APSInt Result; 6909 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 6910 Result.isSigned() && 6911 !((!StrictlyPositive && Result.isNonNegative()) || 6912 (StrictlyPositive && Result.isStrictlyPositive()))) { 6913 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 6914 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 6915 << ValExpr->getSourceRange(); 6916 return false; 6917 } 6918 } 6919 return true; 6920 } 6921 6922 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 6923 SourceLocation StartLoc, 6924 SourceLocation LParenLoc, 6925 SourceLocation EndLoc) { 6926 Expr *ValExpr = NumThreads; 6927 6928 // OpenMP [2.5, Restrictions] 6929 // The num_threads expression must evaluate to a positive integer value. 6930 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 6931 /*StrictlyPositive=*/true)) 6932 return nullptr; 6933 6934 return new (Context) 6935 OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc); 6936 } 6937 6938 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 6939 OpenMPClauseKind CKind, 6940 bool StrictlyPositive) { 6941 if (!E) 6942 return ExprError(); 6943 if (E->isValueDependent() || E->isTypeDependent() || 6944 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 6945 return E; 6946 llvm::APSInt Result; 6947 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 6948 if (ICE.isInvalid()) 6949 return ExprError(); 6950 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 6951 (!StrictlyPositive && !Result.isNonNegative())) { 6952 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 6953 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 6954 << E->getSourceRange(); 6955 return ExprError(); 6956 } 6957 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 6958 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 6959 << E->getSourceRange(); 6960 return ExprError(); 6961 } 6962 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 6963 DSAStack->setAssociatedLoops(Result.getExtValue()); 6964 else if (CKind == OMPC_ordered) 6965 DSAStack->setAssociatedLoops(Result.getExtValue()); 6966 return ICE; 6967 } 6968 6969 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 6970 SourceLocation LParenLoc, 6971 SourceLocation EndLoc) { 6972 // OpenMP [2.8.1, simd construct, Description] 6973 // The parameter of the safelen clause must be a constant 6974 // positive integer expression. 6975 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 6976 if (Safelen.isInvalid()) 6977 return nullptr; 6978 return new (Context) 6979 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 6980 } 6981 6982 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 6983 SourceLocation LParenLoc, 6984 SourceLocation EndLoc) { 6985 // OpenMP [2.8.1, simd construct, Description] 6986 // The parameter of the simdlen clause must be a constant 6987 // positive integer expression. 6988 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 6989 if (Simdlen.isInvalid()) 6990 return nullptr; 6991 return new (Context) 6992 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 6993 } 6994 6995 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 6996 SourceLocation StartLoc, 6997 SourceLocation LParenLoc, 6998 SourceLocation EndLoc) { 6999 // OpenMP [2.7.1, loop construct, Description] 7000 // OpenMP [2.8.1, simd construct, Description] 7001 // OpenMP [2.9.6, distribute construct, Description] 7002 // The parameter of the collapse clause must be a constant 7003 // positive integer expression. 7004 ExprResult NumForLoopsResult = 7005 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 7006 if (NumForLoopsResult.isInvalid()) 7007 return nullptr; 7008 return new (Context) 7009 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 7010 } 7011 7012 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 7013 SourceLocation EndLoc, 7014 SourceLocation LParenLoc, 7015 Expr *NumForLoops) { 7016 // OpenMP [2.7.1, loop construct, Description] 7017 // OpenMP [2.8.1, simd construct, Description] 7018 // OpenMP [2.9.6, distribute construct, Description] 7019 // The parameter of the ordered clause must be a constant 7020 // positive integer expression if any. 7021 if (NumForLoops && LParenLoc.isValid()) { 7022 ExprResult NumForLoopsResult = 7023 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 7024 if (NumForLoopsResult.isInvalid()) 7025 return nullptr; 7026 NumForLoops = NumForLoopsResult.get(); 7027 } else 7028 NumForLoops = nullptr; 7029 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops); 7030 return new (Context) 7031 OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc); 7032 } 7033 7034 OMPClause *Sema::ActOnOpenMPSimpleClause( 7035 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 7036 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 7037 OMPClause *Res = nullptr; 7038 switch (Kind) { 7039 case OMPC_default: 7040 Res = 7041 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 7042 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 7043 break; 7044 case OMPC_proc_bind: 7045 Res = ActOnOpenMPProcBindClause( 7046 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 7047 LParenLoc, EndLoc); 7048 break; 7049 case OMPC_if: 7050 case OMPC_final: 7051 case OMPC_num_threads: 7052 case OMPC_safelen: 7053 case OMPC_simdlen: 7054 case OMPC_collapse: 7055 case OMPC_schedule: 7056 case OMPC_private: 7057 case OMPC_firstprivate: 7058 case OMPC_lastprivate: 7059 case OMPC_shared: 7060 case OMPC_reduction: 7061 case OMPC_linear: 7062 case OMPC_aligned: 7063 case OMPC_copyin: 7064 case OMPC_copyprivate: 7065 case OMPC_ordered: 7066 case OMPC_nowait: 7067 case OMPC_untied: 7068 case OMPC_mergeable: 7069 case OMPC_threadprivate: 7070 case OMPC_flush: 7071 case OMPC_read: 7072 case OMPC_write: 7073 case OMPC_update: 7074 case OMPC_capture: 7075 case OMPC_seq_cst: 7076 case OMPC_depend: 7077 case OMPC_device: 7078 case OMPC_threads: 7079 case OMPC_simd: 7080 case OMPC_map: 7081 case OMPC_num_teams: 7082 case OMPC_thread_limit: 7083 case OMPC_priority: 7084 case OMPC_grainsize: 7085 case OMPC_nogroup: 7086 case OMPC_num_tasks: 7087 case OMPC_hint: 7088 case OMPC_dist_schedule: 7089 case OMPC_defaultmap: 7090 case OMPC_unknown: 7091 case OMPC_uniform: 7092 case OMPC_to: 7093 case OMPC_from: 7094 llvm_unreachable("Clause is not allowed."); 7095 } 7096 return Res; 7097 } 7098 7099 static std::string 7100 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 7101 ArrayRef<unsigned> Exclude = llvm::None) { 7102 std::string Values; 7103 unsigned Bound = Last >= 2 ? Last - 2 : 0; 7104 unsigned Skipped = Exclude.size(); 7105 auto S = Exclude.begin(), E = Exclude.end(); 7106 for (unsigned i = First; i < Last; ++i) { 7107 if (std::find(S, E, i) != E) { 7108 --Skipped; 7109 continue; 7110 } 7111 Values += "'"; 7112 Values += getOpenMPSimpleClauseTypeName(K, i); 7113 Values += "'"; 7114 if (i == Bound - Skipped) 7115 Values += " or "; 7116 else if (i != Bound + 1 - Skipped) 7117 Values += ", "; 7118 } 7119 return Values; 7120 } 7121 7122 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 7123 SourceLocation KindKwLoc, 7124 SourceLocation StartLoc, 7125 SourceLocation LParenLoc, 7126 SourceLocation EndLoc) { 7127 if (Kind == OMPC_DEFAULT_unknown) { 7128 static_assert(OMPC_DEFAULT_unknown > 0, 7129 "OMPC_DEFAULT_unknown not greater than 0"); 7130 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 7131 << getListOfPossibleValues(OMPC_default, /*First=*/0, 7132 /*Last=*/OMPC_DEFAULT_unknown) 7133 << getOpenMPClauseName(OMPC_default); 7134 return nullptr; 7135 } 7136 switch (Kind) { 7137 case OMPC_DEFAULT_none: 7138 DSAStack->setDefaultDSANone(KindKwLoc); 7139 break; 7140 case OMPC_DEFAULT_shared: 7141 DSAStack->setDefaultDSAShared(KindKwLoc); 7142 break; 7143 case OMPC_DEFAULT_unknown: 7144 llvm_unreachable("Clause kind is not allowed."); 7145 break; 7146 } 7147 return new (Context) 7148 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 7149 } 7150 7151 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 7152 SourceLocation KindKwLoc, 7153 SourceLocation StartLoc, 7154 SourceLocation LParenLoc, 7155 SourceLocation EndLoc) { 7156 if (Kind == OMPC_PROC_BIND_unknown) { 7157 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 7158 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 7159 /*Last=*/OMPC_PROC_BIND_unknown) 7160 << getOpenMPClauseName(OMPC_proc_bind); 7161 return nullptr; 7162 } 7163 return new (Context) 7164 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 7165 } 7166 7167 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 7168 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 7169 SourceLocation StartLoc, SourceLocation LParenLoc, 7170 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 7171 SourceLocation EndLoc) { 7172 OMPClause *Res = nullptr; 7173 switch (Kind) { 7174 case OMPC_schedule: 7175 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 7176 assert(Argument.size() == NumberOfElements && 7177 ArgumentLoc.size() == NumberOfElements); 7178 Res = ActOnOpenMPScheduleClause( 7179 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 7180 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 7181 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 7182 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 7183 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 7184 break; 7185 case OMPC_if: 7186 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 7187 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 7188 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 7189 DelimLoc, EndLoc); 7190 break; 7191 case OMPC_dist_schedule: 7192 Res = ActOnOpenMPDistScheduleClause( 7193 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 7194 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 7195 break; 7196 case OMPC_defaultmap: 7197 enum { Modifier, DefaultmapKind }; 7198 Res = ActOnOpenMPDefaultmapClause( 7199 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 7200 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 7201 StartLoc, LParenLoc, ArgumentLoc[Modifier], 7202 ArgumentLoc[DefaultmapKind], EndLoc); 7203 break; 7204 case OMPC_final: 7205 case OMPC_num_threads: 7206 case OMPC_safelen: 7207 case OMPC_simdlen: 7208 case OMPC_collapse: 7209 case OMPC_default: 7210 case OMPC_proc_bind: 7211 case OMPC_private: 7212 case OMPC_firstprivate: 7213 case OMPC_lastprivate: 7214 case OMPC_shared: 7215 case OMPC_reduction: 7216 case OMPC_linear: 7217 case OMPC_aligned: 7218 case OMPC_copyin: 7219 case OMPC_copyprivate: 7220 case OMPC_ordered: 7221 case OMPC_nowait: 7222 case OMPC_untied: 7223 case OMPC_mergeable: 7224 case OMPC_threadprivate: 7225 case OMPC_flush: 7226 case OMPC_read: 7227 case OMPC_write: 7228 case OMPC_update: 7229 case OMPC_capture: 7230 case OMPC_seq_cst: 7231 case OMPC_depend: 7232 case OMPC_device: 7233 case OMPC_threads: 7234 case OMPC_simd: 7235 case OMPC_map: 7236 case OMPC_num_teams: 7237 case OMPC_thread_limit: 7238 case OMPC_priority: 7239 case OMPC_grainsize: 7240 case OMPC_nogroup: 7241 case OMPC_num_tasks: 7242 case OMPC_hint: 7243 case OMPC_unknown: 7244 case OMPC_uniform: 7245 case OMPC_to: 7246 case OMPC_from: 7247 llvm_unreachable("Clause is not allowed."); 7248 } 7249 return Res; 7250 } 7251 7252 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 7253 OpenMPScheduleClauseModifier M2, 7254 SourceLocation M1Loc, SourceLocation M2Loc) { 7255 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 7256 SmallVector<unsigned, 2> Excluded; 7257 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 7258 Excluded.push_back(M2); 7259 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 7260 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 7261 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 7262 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 7263 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 7264 << getListOfPossibleValues(OMPC_schedule, 7265 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 7266 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 7267 Excluded) 7268 << getOpenMPClauseName(OMPC_schedule); 7269 return true; 7270 } 7271 return false; 7272 } 7273 7274 OMPClause *Sema::ActOnOpenMPScheduleClause( 7275 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 7276 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 7277 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 7278 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 7279 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 7280 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 7281 return nullptr; 7282 // OpenMP, 2.7.1, Loop Construct, Restrictions 7283 // Either the monotonic modifier or the nonmonotonic modifier can be specified 7284 // but not both. 7285 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 7286 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 7287 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 7288 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 7289 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 7290 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 7291 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 7292 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 7293 return nullptr; 7294 } 7295 if (Kind == OMPC_SCHEDULE_unknown) { 7296 std::string Values; 7297 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 7298 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 7299 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 7300 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 7301 Exclude); 7302 } else { 7303 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 7304 /*Last=*/OMPC_SCHEDULE_unknown); 7305 } 7306 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 7307 << Values << getOpenMPClauseName(OMPC_schedule); 7308 return nullptr; 7309 } 7310 // OpenMP, 2.7.1, Loop Construct, Restrictions 7311 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 7312 // schedule(guided). 7313 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 7314 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 7315 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 7316 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 7317 diag::err_omp_schedule_nonmonotonic_static); 7318 return nullptr; 7319 } 7320 Expr *ValExpr = ChunkSize; 7321 Stmt *HelperValStmt = nullptr; 7322 if (ChunkSize) { 7323 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 7324 !ChunkSize->isInstantiationDependent() && 7325 !ChunkSize->containsUnexpandedParameterPack()) { 7326 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 7327 ExprResult Val = 7328 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 7329 if (Val.isInvalid()) 7330 return nullptr; 7331 7332 ValExpr = Val.get(); 7333 7334 // OpenMP [2.7.1, Restrictions] 7335 // chunk_size must be a loop invariant integer expression with a positive 7336 // value. 7337 llvm::APSInt Result; 7338 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 7339 if (Result.isSigned() && !Result.isStrictlyPositive()) { 7340 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 7341 << "schedule" << 1 << ChunkSize->getSourceRange(); 7342 return nullptr; 7343 } 7344 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 7345 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 7346 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 7347 HelperValStmt = buildPreInits(Context, Captures); 7348 } 7349 } 7350 } 7351 7352 return new (Context) 7353 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 7354 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 7355 } 7356 7357 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 7358 SourceLocation StartLoc, 7359 SourceLocation EndLoc) { 7360 OMPClause *Res = nullptr; 7361 switch (Kind) { 7362 case OMPC_ordered: 7363 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 7364 break; 7365 case OMPC_nowait: 7366 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 7367 break; 7368 case OMPC_untied: 7369 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 7370 break; 7371 case OMPC_mergeable: 7372 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 7373 break; 7374 case OMPC_read: 7375 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 7376 break; 7377 case OMPC_write: 7378 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 7379 break; 7380 case OMPC_update: 7381 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 7382 break; 7383 case OMPC_capture: 7384 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 7385 break; 7386 case OMPC_seq_cst: 7387 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 7388 break; 7389 case OMPC_threads: 7390 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 7391 break; 7392 case OMPC_simd: 7393 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 7394 break; 7395 case OMPC_nogroup: 7396 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 7397 break; 7398 case OMPC_if: 7399 case OMPC_final: 7400 case OMPC_num_threads: 7401 case OMPC_safelen: 7402 case OMPC_simdlen: 7403 case OMPC_collapse: 7404 case OMPC_schedule: 7405 case OMPC_private: 7406 case OMPC_firstprivate: 7407 case OMPC_lastprivate: 7408 case OMPC_shared: 7409 case OMPC_reduction: 7410 case OMPC_linear: 7411 case OMPC_aligned: 7412 case OMPC_copyin: 7413 case OMPC_copyprivate: 7414 case OMPC_default: 7415 case OMPC_proc_bind: 7416 case OMPC_threadprivate: 7417 case OMPC_flush: 7418 case OMPC_depend: 7419 case OMPC_device: 7420 case OMPC_map: 7421 case OMPC_num_teams: 7422 case OMPC_thread_limit: 7423 case OMPC_priority: 7424 case OMPC_grainsize: 7425 case OMPC_num_tasks: 7426 case OMPC_hint: 7427 case OMPC_dist_schedule: 7428 case OMPC_defaultmap: 7429 case OMPC_unknown: 7430 case OMPC_uniform: 7431 case OMPC_to: 7432 case OMPC_from: 7433 llvm_unreachable("Clause is not allowed."); 7434 } 7435 return Res; 7436 } 7437 7438 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 7439 SourceLocation EndLoc) { 7440 DSAStack->setNowaitRegion(); 7441 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 7442 } 7443 7444 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 7445 SourceLocation EndLoc) { 7446 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 7447 } 7448 7449 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 7450 SourceLocation EndLoc) { 7451 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 7452 } 7453 7454 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 7455 SourceLocation EndLoc) { 7456 return new (Context) OMPReadClause(StartLoc, EndLoc); 7457 } 7458 7459 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 7460 SourceLocation EndLoc) { 7461 return new (Context) OMPWriteClause(StartLoc, EndLoc); 7462 } 7463 7464 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 7465 SourceLocation EndLoc) { 7466 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 7467 } 7468 7469 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 7470 SourceLocation EndLoc) { 7471 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 7472 } 7473 7474 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 7475 SourceLocation EndLoc) { 7476 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 7477 } 7478 7479 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 7480 SourceLocation EndLoc) { 7481 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 7482 } 7483 7484 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 7485 SourceLocation EndLoc) { 7486 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 7487 } 7488 7489 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 7490 SourceLocation EndLoc) { 7491 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 7492 } 7493 7494 OMPClause *Sema::ActOnOpenMPVarListClause( 7495 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 7496 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 7497 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 7498 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, 7499 OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, 7500 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 7501 SourceLocation DepLinMapLoc) { 7502 OMPClause *Res = nullptr; 7503 switch (Kind) { 7504 case OMPC_private: 7505 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7506 break; 7507 case OMPC_firstprivate: 7508 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7509 break; 7510 case OMPC_lastprivate: 7511 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7512 break; 7513 case OMPC_shared: 7514 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 7515 break; 7516 case OMPC_reduction: 7517 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 7518 EndLoc, ReductionIdScopeSpec, ReductionId); 7519 break; 7520 case OMPC_linear: 7521 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 7522 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 7523 break; 7524 case OMPC_aligned: 7525 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 7526 ColonLoc, EndLoc); 7527 break; 7528 case OMPC_copyin: 7529 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 7530 break; 7531 case OMPC_copyprivate: 7532 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7533 break; 7534 case OMPC_flush: 7535 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 7536 break; 7537 case OMPC_depend: 7538 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 7539 StartLoc, LParenLoc, EndLoc); 7540 break; 7541 case OMPC_map: 7542 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, 7543 DepLinMapLoc, ColonLoc, VarList, StartLoc, 7544 LParenLoc, EndLoc); 7545 break; 7546 case OMPC_to: 7547 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc); 7548 break; 7549 case OMPC_from: 7550 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc); 7551 break; 7552 case OMPC_if: 7553 case OMPC_final: 7554 case OMPC_num_threads: 7555 case OMPC_safelen: 7556 case OMPC_simdlen: 7557 case OMPC_collapse: 7558 case OMPC_default: 7559 case OMPC_proc_bind: 7560 case OMPC_schedule: 7561 case OMPC_ordered: 7562 case OMPC_nowait: 7563 case OMPC_untied: 7564 case OMPC_mergeable: 7565 case OMPC_threadprivate: 7566 case OMPC_read: 7567 case OMPC_write: 7568 case OMPC_update: 7569 case OMPC_capture: 7570 case OMPC_seq_cst: 7571 case OMPC_device: 7572 case OMPC_threads: 7573 case OMPC_simd: 7574 case OMPC_num_teams: 7575 case OMPC_thread_limit: 7576 case OMPC_priority: 7577 case OMPC_grainsize: 7578 case OMPC_nogroup: 7579 case OMPC_num_tasks: 7580 case OMPC_hint: 7581 case OMPC_dist_schedule: 7582 case OMPC_defaultmap: 7583 case OMPC_unknown: 7584 case OMPC_uniform: 7585 llvm_unreachable("Clause is not allowed."); 7586 } 7587 return Res; 7588 } 7589 7590 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 7591 ExprObjectKind OK, SourceLocation Loc) { 7592 ExprResult Res = BuildDeclRefExpr( 7593 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 7594 if (!Res.isUsable()) 7595 return ExprError(); 7596 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 7597 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 7598 if (!Res.isUsable()) 7599 return ExprError(); 7600 } 7601 if (VK != VK_LValue && Res.get()->isGLValue()) { 7602 Res = DefaultLvalueConversion(Res.get()); 7603 if (!Res.isUsable()) 7604 return ExprError(); 7605 } 7606 return Res; 7607 } 7608 7609 static std::pair<ValueDecl *, bool> 7610 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 7611 SourceRange &ERange, bool AllowArraySection = false) { 7612 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 7613 RefExpr->containsUnexpandedParameterPack()) 7614 return std::make_pair(nullptr, true); 7615 7616 // OpenMP [3.1, C/C++] 7617 // A list item is a variable name. 7618 // OpenMP [2.9.3.3, Restrictions, p.1] 7619 // A variable that is part of another variable (as an array or 7620 // structure element) cannot appear in a private clause. 7621 RefExpr = RefExpr->IgnoreParens(); 7622 enum { 7623 NoArrayExpr = -1, 7624 ArraySubscript = 0, 7625 OMPArraySection = 1 7626 } IsArrayExpr = NoArrayExpr; 7627 if (AllowArraySection) { 7628 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 7629 auto *Base = ASE->getBase()->IgnoreParenImpCasts(); 7630 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 7631 Base = TempASE->getBase()->IgnoreParenImpCasts(); 7632 RefExpr = Base; 7633 IsArrayExpr = ArraySubscript; 7634 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 7635 auto *Base = OASE->getBase()->IgnoreParenImpCasts(); 7636 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 7637 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 7638 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 7639 Base = TempASE->getBase()->IgnoreParenImpCasts(); 7640 RefExpr = Base; 7641 IsArrayExpr = OMPArraySection; 7642 } 7643 } 7644 ELoc = RefExpr->getExprLoc(); 7645 ERange = RefExpr->getSourceRange(); 7646 RefExpr = RefExpr->IgnoreParenImpCasts(); 7647 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 7648 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 7649 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 7650 (S.getCurrentThisType().isNull() || !ME || 7651 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 7652 !isa<FieldDecl>(ME->getMemberDecl()))) { 7653 if (IsArrayExpr != NoArrayExpr) 7654 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 7655 << ERange; 7656 else { 7657 S.Diag(ELoc, 7658 AllowArraySection 7659 ? diag::err_omp_expected_var_name_member_expr_or_array_item 7660 : diag::err_omp_expected_var_name_member_expr) 7661 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 7662 } 7663 return std::make_pair(nullptr, false); 7664 } 7665 return std::make_pair(DE ? DE->getDecl() : ME->getMemberDecl(), false); 7666 } 7667 7668 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 7669 SourceLocation StartLoc, 7670 SourceLocation LParenLoc, 7671 SourceLocation EndLoc) { 7672 SmallVector<Expr *, 8> Vars; 7673 SmallVector<Expr *, 8> PrivateCopies; 7674 for (auto &RefExpr : VarList) { 7675 assert(RefExpr && "NULL expr in OpenMP private clause."); 7676 SourceLocation ELoc; 7677 SourceRange ERange; 7678 Expr *SimpleRefExpr = RefExpr; 7679 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 7680 if (Res.second) { 7681 // It will be analyzed later. 7682 Vars.push_back(RefExpr); 7683 PrivateCopies.push_back(nullptr); 7684 } 7685 ValueDecl *D = Res.first; 7686 if (!D) 7687 continue; 7688 7689 QualType Type = D->getType(); 7690 auto *VD = dyn_cast<VarDecl>(D); 7691 7692 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 7693 // A variable that appears in a private clause must not have an incomplete 7694 // type or a reference type. 7695 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 7696 continue; 7697 Type = Type.getNonReferenceType(); 7698 7699 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7700 // in a Construct] 7701 // Variables with the predetermined data-sharing attributes may not be 7702 // listed in data-sharing attributes clauses, except for the cases 7703 // listed below. For these exceptions only, listing a predetermined 7704 // variable in a data-sharing attribute clause is allowed and overrides 7705 // the variable's predetermined data-sharing attributes. 7706 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7707 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 7708 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 7709 << getOpenMPClauseName(OMPC_private); 7710 ReportOriginalDSA(*this, DSAStack, D, DVar); 7711 continue; 7712 } 7713 7714 // Variably modified types are not supported for tasks. 7715 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 7716 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 7717 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 7718 << getOpenMPClauseName(OMPC_private) << Type 7719 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7720 bool IsDecl = 7721 !VD || 7722 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 7723 Diag(D->getLocation(), 7724 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 7725 << D; 7726 continue; 7727 } 7728 7729 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 7730 // A list item cannot appear in both a map clause and a data-sharing 7731 // attribute clause on the same construct 7732 if (DSAStack->getCurrentDirective() == OMPD_target) { 7733 if (DSAStack->checkMappableExprComponentListsForDecl( 7734 VD, /* CurrentRegionOnly = */ true, 7735 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef) 7736 -> bool { return true; })) { 7737 Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) 7738 << getOpenMPClauseName(OMPC_private) 7739 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7740 ReportOriginalDSA(*this, DSAStack, D, DVar); 7741 continue; 7742 } 7743 } 7744 7745 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 7746 // A variable of class type (or array thereof) that appears in a private 7747 // clause requires an accessible, unambiguous default constructor for the 7748 // class type. 7749 // Generate helper private variable and initialize it with the default 7750 // value. The address of the original variable is replaced by the address of 7751 // the new private variable in CodeGen. This new variable is not added to 7752 // IdResolver, so the code in the OpenMP region uses original variable for 7753 // proper diagnostics. 7754 Type = Type.getUnqualifiedType(); 7755 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 7756 D->hasAttrs() ? &D->getAttrs() : nullptr); 7757 ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); 7758 if (VDPrivate->isInvalidDecl()) 7759 continue; 7760 auto VDPrivateRefExpr = buildDeclRefExpr( 7761 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 7762 7763 DeclRefExpr *Ref = nullptr; 7764 if (!VD) 7765 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 7766 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 7767 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 7768 PrivateCopies.push_back(VDPrivateRefExpr); 7769 } 7770 7771 if (Vars.empty()) 7772 return nullptr; 7773 7774 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 7775 PrivateCopies); 7776 } 7777 7778 namespace { 7779 class DiagsUninitializedSeveretyRAII { 7780 private: 7781 DiagnosticsEngine &Diags; 7782 SourceLocation SavedLoc; 7783 bool IsIgnored; 7784 7785 public: 7786 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 7787 bool IsIgnored) 7788 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 7789 if (!IsIgnored) { 7790 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 7791 /*Map*/ diag::Severity::Ignored, Loc); 7792 } 7793 } 7794 ~DiagsUninitializedSeveretyRAII() { 7795 if (!IsIgnored) 7796 Diags.popMappings(SavedLoc); 7797 } 7798 }; 7799 } 7800 7801 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 7802 SourceLocation StartLoc, 7803 SourceLocation LParenLoc, 7804 SourceLocation EndLoc) { 7805 SmallVector<Expr *, 8> Vars; 7806 SmallVector<Expr *, 8> PrivateCopies; 7807 SmallVector<Expr *, 8> Inits; 7808 SmallVector<Decl *, 4> ExprCaptures; 7809 bool IsImplicitClause = 7810 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 7811 auto ImplicitClauseLoc = DSAStack->getConstructLoc(); 7812 7813 for (auto &RefExpr : VarList) { 7814 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 7815 SourceLocation ELoc; 7816 SourceRange ERange; 7817 Expr *SimpleRefExpr = RefExpr; 7818 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 7819 if (Res.second) { 7820 // It will be analyzed later. 7821 Vars.push_back(RefExpr); 7822 PrivateCopies.push_back(nullptr); 7823 Inits.push_back(nullptr); 7824 } 7825 ValueDecl *D = Res.first; 7826 if (!D) 7827 continue; 7828 7829 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 7830 QualType Type = D->getType(); 7831 auto *VD = dyn_cast<VarDecl>(D); 7832 7833 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 7834 // A variable that appears in a private clause must not have an incomplete 7835 // type or a reference type. 7836 if (RequireCompleteType(ELoc, Type, 7837 diag::err_omp_firstprivate_incomplete_type)) 7838 continue; 7839 Type = Type.getNonReferenceType(); 7840 7841 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 7842 // A variable of class type (or array thereof) that appears in a private 7843 // clause requires an accessible, unambiguous copy constructor for the 7844 // class type. 7845 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 7846 7847 // If an implicit firstprivate variable found it was checked already. 7848 DSAStackTy::DSAVarData TopDVar; 7849 if (!IsImplicitClause) { 7850 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7851 TopDVar = DVar; 7852 bool IsConstant = ElemType.isConstant(Context); 7853 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 7854 // A list item that specifies a given variable may not appear in more 7855 // than one clause on the same directive, except that a variable may be 7856 // specified in both firstprivate and lastprivate clauses. 7857 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 7858 DVar.CKind != OMPC_lastprivate && DVar.RefExpr) { 7859 Diag(ELoc, diag::err_omp_wrong_dsa) 7860 << getOpenMPClauseName(DVar.CKind) 7861 << getOpenMPClauseName(OMPC_firstprivate); 7862 ReportOriginalDSA(*this, DSAStack, D, DVar); 7863 continue; 7864 } 7865 7866 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7867 // in a Construct] 7868 // Variables with the predetermined data-sharing attributes may not be 7869 // listed in data-sharing attributes clauses, except for the cases 7870 // listed below. For these exceptions only, listing a predetermined 7871 // variable in a data-sharing attribute clause is allowed and overrides 7872 // the variable's predetermined data-sharing attributes. 7873 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7874 // in a Construct, C/C++, p.2] 7875 // Variables with const-qualified type having no mutable member may be 7876 // listed in a firstprivate clause, even if they are static data members. 7877 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 7878 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 7879 Diag(ELoc, diag::err_omp_wrong_dsa) 7880 << getOpenMPClauseName(DVar.CKind) 7881 << getOpenMPClauseName(OMPC_firstprivate); 7882 ReportOriginalDSA(*this, DSAStack, D, DVar); 7883 continue; 7884 } 7885 7886 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 7887 // OpenMP [2.9.3.4, Restrictions, p.2] 7888 // A list item that is private within a parallel region must not appear 7889 // in a firstprivate clause on a worksharing construct if any of the 7890 // worksharing regions arising from the worksharing construct ever bind 7891 // to any of the parallel regions arising from the parallel construct. 7892 if (isOpenMPWorksharingDirective(CurrDir) && 7893 !isOpenMPParallelDirective(CurrDir)) { 7894 DVar = DSAStack->getImplicitDSA(D, true); 7895 if (DVar.CKind != OMPC_shared && 7896 (isOpenMPParallelDirective(DVar.DKind) || 7897 DVar.DKind == OMPD_unknown)) { 7898 Diag(ELoc, diag::err_omp_required_access) 7899 << getOpenMPClauseName(OMPC_firstprivate) 7900 << getOpenMPClauseName(OMPC_shared); 7901 ReportOriginalDSA(*this, DSAStack, D, DVar); 7902 continue; 7903 } 7904 } 7905 // OpenMP [2.9.3.4, Restrictions, p.3] 7906 // A list item that appears in a reduction clause of a parallel construct 7907 // must not appear in a firstprivate clause on a worksharing or task 7908 // construct if any of the worksharing or task regions arising from the 7909 // worksharing or task construct ever bind to any of the parallel regions 7910 // arising from the parallel construct. 7911 // OpenMP [2.9.3.4, Restrictions, p.4] 7912 // A list item that appears in a reduction clause in worksharing 7913 // construct must not appear in a firstprivate clause in a task construct 7914 // encountered during execution of any of the worksharing regions arising 7915 // from the worksharing construct. 7916 if (isOpenMPTaskingDirective(CurrDir)) { 7917 DVar = DSAStack->hasInnermostDSA( 7918 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 7919 [](OpenMPDirectiveKind K) -> bool { 7920 return isOpenMPParallelDirective(K) || 7921 isOpenMPWorksharingDirective(K); 7922 }, 7923 false); 7924 if (DVar.CKind == OMPC_reduction && 7925 (isOpenMPParallelDirective(DVar.DKind) || 7926 isOpenMPWorksharingDirective(DVar.DKind))) { 7927 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 7928 << getOpenMPDirectiveName(DVar.DKind); 7929 ReportOriginalDSA(*this, DSAStack, D, DVar); 7930 continue; 7931 } 7932 } 7933 7934 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 7935 // A list item that is private within a teams region must not appear in a 7936 // firstprivate clause on a distribute construct if any of the distribute 7937 // regions arising from the distribute construct ever bind to any of the 7938 // teams regions arising from the teams construct. 7939 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 7940 // A list item that appears in a reduction clause of a teams construct 7941 // must not appear in a firstprivate clause on a distribute construct if 7942 // any of the distribute regions arising from the distribute construct 7943 // ever bind to any of the teams regions arising from the teams construct. 7944 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 7945 // A list item may appear in a firstprivate or lastprivate clause but not 7946 // both. 7947 if (CurrDir == OMPD_distribute) { 7948 DVar = DSAStack->hasInnermostDSA( 7949 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_private; }, 7950 [](OpenMPDirectiveKind K) -> bool { 7951 return isOpenMPTeamsDirective(K); 7952 }, 7953 false); 7954 if (DVar.CKind == OMPC_private && isOpenMPTeamsDirective(DVar.DKind)) { 7955 Diag(ELoc, diag::err_omp_firstprivate_distribute_private_teams); 7956 ReportOriginalDSA(*this, DSAStack, D, DVar); 7957 continue; 7958 } 7959 DVar = DSAStack->hasInnermostDSA( 7960 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 7961 [](OpenMPDirectiveKind K) -> bool { 7962 return isOpenMPTeamsDirective(K); 7963 }, 7964 false); 7965 if (DVar.CKind == OMPC_reduction && 7966 isOpenMPTeamsDirective(DVar.DKind)) { 7967 Diag(ELoc, diag::err_omp_firstprivate_distribute_in_teams_reduction); 7968 ReportOriginalDSA(*this, DSAStack, D, DVar); 7969 continue; 7970 } 7971 DVar = DSAStack->getTopDSA(D, false); 7972 if (DVar.CKind == OMPC_lastprivate) { 7973 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); 7974 ReportOriginalDSA(*this, DSAStack, D, DVar); 7975 continue; 7976 } 7977 } 7978 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 7979 // A list item cannot appear in both a map clause and a data-sharing 7980 // attribute clause on the same construct 7981 if (CurrDir == OMPD_target) { 7982 if (DSAStack->checkMappableExprComponentListsForDecl( 7983 VD, /* CurrentRegionOnly = */ true, 7984 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef) 7985 -> bool { return true; })) { 7986 Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) 7987 << getOpenMPClauseName(OMPC_firstprivate) 7988 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7989 ReportOriginalDSA(*this, DSAStack, D, DVar); 7990 continue; 7991 } 7992 } 7993 } 7994 7995 // Variably modified types are not supported for tasks. 7996 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 7997 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 7998 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 7999 << getOpenMPClauseName(OMPC_firstprivate) << Type 8000 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 8001 bool IsDecl = 8002 !VD || 8003 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8004 Diag(D->getLocation(), 8005 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8006 << D; 8007 continue; 8008 } 8009 8010 Type = Type.getUnqualifiedType(); 8011 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 8012 D->hasAttrs() ? &D->getAttrs() : nullptr); 8013 // Generate helper private variable and initialize it with the value of the 8014 // original variable. The address of the original variable is replaced by 8015 // the address of the new private variable in the CodeGen. This new variable 8016 // is not added to IdResolver, so the code in the OpenMP region uses 8017 // original variable for proper diagnostics and variable capturing. 8018 Expr *VDInitRefExpr = nullptr; 8019 // For arrays generate initializer for single element and replace it by the 8020 // original array element in CodeGen. 8021 if (Type->isArrayType()) { 8022 auto VDInit = 8023 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 8024 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 8025 auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); 8026 ElemType = ElemType.getUnqualifiedType(); 8027 auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 8028 ".firstprivate.temp"); 8029 InitializedEntity Entity = 8030 InitializedEntity::InitializeVariable(VDInitTemp); 8031 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 8032 8033 InitializationSequence InitSeq(*this, Entity, Kind, Init); 8034 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 8035 if (Result.isInvalid()) 8036 VDPrivate->setInvalidDecl(); 8037 else 8038 VDPrivate->setInit(Result.getAs<Expr>()); 8039 // Remove temp variable declaration. 8040 Context.Deallocate(VDInitTemp); 8041 } else { 8042 auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 8043 ".firstprivate.temp"); 8044 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 8045 RefExpr->getExprLoc()); 8046 AddInitializerToDecl(VDPrivate, 8047 DefaultLvalueConversion(VDInitRefExpr).get(), 8048 /*DirectInit=*/false, /*TypeMayContainAuto=*/false); 8049 } 8050 if (VDPrivate->isInvalidDecl()) { 8051 if (IsImplicitClause) { 8052 Diag(RefExpr->getExprLoc(), 8053 diag::note_omp_task_predetermined_firstprivate_here); 8054 } 8055 continue; 8056 } 8057 CurContext->addDecl(VDPrivate); 8058 auto VDPrivateRefExpr = buildDeclRefExpr( 8059 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 8060 RefExpr->getExprLoc()); 8061 DeclRefExpr *Ref = nullptr; 8062 if (!VD) { 8063 if (TopDVar.CKind == OMPC_lastprivate) 8064 Ref = TopDVar.PrivateCopy; 8065 else { 8066 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 8067 if (!IsOpenMPCapturedDecl(D)) 8068 ExprCaptures.push_back(Ref->getDecl()); 8069 } 8070 } 8071 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 8072 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 8073 PrivateCopies.push_back(VDPrivateRefExpr); 8074 Inits.push_back(VDInitRefExpr); 8075 } 8076 8077 if (Vars.empty()) 8078 return nullptr; 8079 8080 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 8081 Vars, PrivateCopies, Inits, 8082 buildPreInits(Context, ExprCaptures)); 8083 } 8084 8085 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 8086 SourceLocation StartLoc, 8087 SourceLocation LParenLoc, 8088 SourceLocation EndLoc) { 8089 SmallVector<Expr *, 8> Vars; 8090 SmallVector<Expr *, 8> SrcExprs; 8091 SmallVector<Expr *, 8> DstExprs; 8092 SmallVector<Expr *, 8> AssignmentOps; 8093 SmallVector<Decl *, 4> ExprCaptures; 8094 SmallVector<Expr *, 4> ExprPostUpdates; 8095 for (auto &RefExpr : VarList) { 8096 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 8097 SourceLocation ELoc; 8098 SourceRange ERange; 8099 Expr *SimpleRefExpr = RefExpr; 8100 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8101 if (Res.second) { 8102 // It will be analyzed later. 8103 Vars.push_back(RefExpr); 8104 SrcExprs.push_back(nullptr); 8105 DstExprs.push_back(nullptr); 8106 AssignmentOps.push_back(nullptr); 8107 } 8108 ValueDecl *D = Res.first; 8109 if (!D) 8110 continue; 8111 8112 QualType Type = D->getType(); 8113 auto *VD = dyn_cast<VarDecl>(D); 8114 8115 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 8116 // A variable that appears in a lastprivate clause must not have an 8117 // incomplete type or a reference type. 8118 if (RequireCompleteType(ELoc, Type, 8119 diag::err_omp_lastprivate_incomplete_type)) 8120 continue; 8121 Type = Type.getNonReferenceType(); 8122 8123 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 8124 // in a Construct] 8125 // Variables with the predetermined data-sharing attributes may not be 8126 // listed in data-sharing attributes clauses, except for the cases 8127 // listed below. 8128 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8129 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 8130 DVar.CKind != OMPC_firstprivate && 8131 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 8132 Diag(ELoc, diag::err_omp_wrong_dsa) 8133 << getOpenMPClauseName(DVar.CKind) 8134 << getOpenMPClauseName(OMPC_lastprivate); 8135 ReportOriginalDSA(*this, DSAStack, D, DVar); 8136 continue; 8137 } 8138 8139 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 8140 // OpenMP [2.14.3.5, Restrictions, p.2] 8141 // A list item that is private within a parallel region, or that appears in 8142 // the reduction clause of a parallel construct, must not appear in a 8143 // lastprivate clause on a worksharing construct if any of the corresponding 8144 // worksharing regions ever binds to any of the corresponding parallel 8145 // regions. 8146 DSAStackTy::DSAVarData TopDVar = DVar; 8147 if (isOpenMPWorksharingDirective(CurrDir) && 8148 !isOpenMPParallelDirective(CurrDir)) { 8149 DVar = DSAStack->getImplicitDSA(D, true); 8150 if (DVar.CKind != OMPC_shared) { 8151 Diag(ELoc, diag::err_omp_required_access) 8152 << getOpenMPClauseName(OMPC_lastprivate) 8153 << getOpenMPClauseName(OMPC_shared); 8154 ReportOriginalDSA(*this, DSAStack, D, DVar); 8155 continue; 8156 } 8157 } 8158 8159 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 8160 // A list item may appear in a firstprivate or lastprivate clause but not 8161 // both. 8162 if (CurrDir == OMPD_distribute) { 8163 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8164 if (DVar.CKind == OMPC_firstprivate) { 8165 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); 8166 ReportOriginalDSA(*this, DSAStack, D, DVar); 8167 continue; 8168 } 8169 } 8170 8171 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 8172 // A variable of class type (or array thereof) that appears in a 8173 // lastprivate clause requires an accessible, unambiguous default 8174 // constructor for the class type, unless the list item is also specified 8175 // in a firstprivate clause. 8176 // A variable of class type (or array thereof) that appears in a 8177 // lastprivate clause requires an accessible, unambiguous copy assignment 8178 // operator for the class type. 8179 Type = Context.getBaseElementType(Type).getNonReferenceType(); 8180 auto *SrcVD = buildVarDecl(*this, ERange.getBegin(), 8181 Type.getUnqualifiedType(), ".lastprivate.src", 8182 D->hasAttrs() ? &D->getAttrs() : nullptr); 8183 auto *PseudoSrcExpr = 8184 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 8185 auto *DstVD = 8186 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 8187 D->hasAttrs() ? &D->getAttrs() : nullptr); 8188 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 8189 // For arrays generate assignment operation for single element and replace 8190 // it by the original array element in CodeGen. 8191 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 8192 PseudoDstExpr, PseudoSrcExpr); 8193 if (AssignmentOp.isInvalid()) 8194 continue; 8195 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 8196 /*DiscardedValue=*/true); 8197 if (AssignmentOp.isInvalid()) 8198 continue; 8199 8200 DeclRefExpr *Ref = nullptr; 8201 if (!VD) { 8202 if (TopDVar.CKind == OMPC_firstprivate) 8203 Ref = TopDVar.PrivateCopy; 8204 else { 8205 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 8206 if (!IsOpenMPCapturedDecl(D)) 8207 ExprCaptures.push_back(Ref->getDecl()); 8208 } 8209 if (TopDVar.CKind == OMPC_firstprivate || 8210 (!IsOpenMPCapturedDecl(D) && 8211 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 8212 ExprResult RefRes = DefaultLvalueConversion(Ref); 8213 if (!RefRes.isUsable()) 8214 continue; 8215 ExprResult PostUpdateRes = 8216 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 8217 RefRes.get()); 8218 if (!PostUpdateRes.isUsable()) 8219 continue; 8220 ExprPostUpdates.push_back( 8221 IgnoredValueConversions(PostUpdateRes.get()).get()); 8222 } 8223 } 8224 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 8225 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 8226 SrcExprs.push_back(PseudoSrcExpr); 8227 DstExprs.push_back(PseudoDstExpr); 8228 AssignmentOps.push_back(AssignmentOp.get()); 8229 } 8230 8231 if (Vars.empty()) 8232 return nullptr; 8233 8234 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 8235 Vars, SrcExprs, DstExprs, AssignmentOps, 8236 buildPreInits(Context, ExprCaptures), 8237 buildPostUpdate(*this, ExprPostUpdates)); 8238 } 8239 8240 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 8241 SourceLocation StartLoc, 8242 SourceLocation LParenLoc, 8243 SourceLocation EndLoc) { 8244 SmallVector<Expr *, 8> Vars; 8245 for (auto &RefExpr : VarList) { 8246 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 8247 SourceLocation ELoc; 8248 SourceRange ERange; 8249 Expr *SimpleRefExpr = RefExpr; 8250 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8251 if (Res.second) { 8252 // It will be analyzed later. 8253 Vars.push_back(RefExpr); 8254 } 8255 ValueDecl *D = Res.first; 8256 if (!D) 8257 continue; 8258 8259 auto *VD = dyn_cast<VarDecl>(D); 8260 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8261 // in a Construct] 8262 // Variables with the predetermined data-sharing attributes may not be 8263 // listed in data-sharing attributes clauses, except for the cases 8264 // listed below. For these exceptions only, listing a predetermined 8265 // variable in a data-sharing attribute clause is allowed and overrides 8266 // the variable's predetermined data-sharing attributes. 8267 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8268 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 8269 DVar.RefExpr) { 8270 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 8271 << getOpenMPClauseName(OMPC_shared); 8272 ReportOriginalDSA(*this, DSAStack, D, DVar); 8273 continue; 8274 } 8275 8276 DeclRefExpr *Ref = nullptr; 8277 if (!VD && IsOpenMPCapturedDecl(D)) 8278 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 8279 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 8280 Vars.push_back((VD || !Ref) ? RefExpr->IgnoreParens() : Ref); 8281 } 8282 8283 if (Vars.empty()) 8284 return nullptr; 8285 8286 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 8287 } 8288 8289 namespace { 8290 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 8291 DSAStackTy *Stack; 8292 8293 public: 8294 bool VisitDeclRefExpr(DeclRefExpr *E) { 8295 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { 8296 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false); 8297 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 8298 return false; 8299 if (DVar.CKind != OMPC_unknown) 8300 return true; 8301 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 8302 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, 8303 false); 8304 if (DVarPrivate.CKind != OMPC_unknown) 8305 return true; 8306 return false; 8307 } 8308 return false; 8309 } 8310 bool VisitStmt(Stmt *S) { 8311 for (auto Child : S->children()) { 8312 if (Child && Visit(Child)) 8313 return true; 8314 } 8315 return false; 8316 } 8317 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 8318 }; 8319 } // namespace 8320 8321 namespace { 8322 // Transform MemberExpression for specified FieldDecl of current class to 8323 // DeclRefExpr to specified OMPCapturedExprDecl. 8324 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 8325 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 8326 ValueDecl *Field; 8327 DeclRefExpr *CapturedExpr; 8328 8329 public: 8330 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 8331 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 8332 8333 ExprResult TransformMemberExpr(MemberExpr *E) { 8334 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 8335 E->getMemberDecl() == Field) { 8336 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 8337 return CapturedExpr; 8338 } 8339 return BaseTransform::TransformMemberExpr(E); 8340 } 8341 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 8342 }; 8343 } // namespace 8344 8345 template <typename T> 8346 static T filterLookupForUDR(SmallVectorImpl<UnresolvedSet<8>> &Lookups, 8347 const llvm::function_ref<T(ValueDecl *)> &Gen) { 8348 for (auto &Set : Lookups) { 8349 for (auto *D : Set) { 8350 if (auto Res = Gen(cast<ValueDecl>(D))) 8351 return Res; 8352 } 8353 } 8354 return T(); 8355 } 8356 8357 static ExprResult 8358 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 8359 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 8360 const DeclarationNameInfo &ReductionId, QualType Ty, 8361 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 8362 if (ReductionIdScopeSpec.isInvalid()) 8363 return ExprError(); 8364 SmallVector<UnresolvedSet<8>, 4> Lookups; 8365 if (S) { 8366 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 8367 Lookup.suppressDiagnostics(); 8368 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 8369 auto *D = Lookup.getRepresentativeDecl(); 8370 do { 8371 S = S->getParent(); 8372 } while (S && !S->isDeclScope(D)); 8373 if (S) 8374 S = S->getParent(); 8375 Lookups.push_back(UnresolvedSet<8>()); 8376 Lookups.back().append(Lookup.begin(), Lookup.end()); 8377 Lookup.clear(); 8378 } 8379 } else if (auto *ULE = 8380 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 8381 Lookups.push_back(UnresolvedSet<8>()); 8382 Decl *PrevD = nullptr; 8383 for(auto *D : ULE->decls()) { 8384 if (D == PrevD) 8385 Lookups.push_back(UnresolvedSet<8>()); 8386 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) 8387 Lookups.back().addDecl(DRD); 8388 PrevD = D; 8389 } 8390 } 8391 if (Ty->isDependentType() || Ty->isInstantiationDependentType() || 8392 Ty->containsUnexpandedParameterPack() || 8393 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool { 8394 return !D->isInvalidDecl() && 8395 (D->getType()->isDependentType() || 8396 D->getType()->isInstantiationDependentType() || 8397 D->getType()->containsUnexpandedParameterPack()); 8398 })) { 8399 UnresolvedSet<8> ResSet; 8400 for (auto &Set : Lookups) { 8401 ResSet.append(Set.begin(), Set.end()); 8402 // The last item marks the end of all declarations at the specified scope. 8403 ResSet.addDecl(Set[Set.size() - 1]); 8404 } 8405 return UnresolvedLookupExpr::Create( 8406 SemaRef.Context, /*NamingClass=*/nullptr, 8407 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 8408 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 8409 } 8410 if (auto *VD = filterLookupForUDR<ValueDecl *>( 8411 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 8412 if (!D->isInvalidDecl() && 8413 SemaRef.Context.hasSameType(D->getType(), Ty)) 8414 return D; 8415 return nullptr; 8416 })) 8417 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 8418 if (auto *VD = filterLookupForUDR<ValueDecl *>( 8419 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 8420 if (!D->isInvalidDecl() && 8421 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 8422 !Ty.isMoreQualifiedThan(D->getType())) 8423 return D; 8424 return nullptr; 8425 })) { 8426 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 8427 /*DetectVirtual=*/false); 8428 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 8429 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 8430 VD->getType().getUnqualifiedType()))) { 8431 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), 8432 /*DiagID=*/0) != 8433 Sema::AR_inaccessible) { 8434 SemaRef.BuildBasePathArray(Paths, BasePath); 8435 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 8436 } 8437 } 8438 } 8439 } 8440 if (ReductionIdScopeSpec.isSet()) { 8441 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 8442 return ExprError(); 8443 } 8444 return ExprEmpty(); 8445 } 8446 8447 OMPClause *Sema::ActOnOpenMPReductionClause( 8448 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 8449 SourceLocation ColonLoc, SourceLocation EndLoc, 8450 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 8451 ArrayRef<Expr *> UnresolvedReductions) { 8452 auto DN = ReductionId.getName(); 8453 auto OOK = DN.getCXXOverloadedOperator(); 8454 BinaryOperatorKind BOK = BO_Comma; 8455 8456 // OpenMP [2.14.3.6, reduction clause] 8457 // C 8458 // reduction-identifier is either an identifier or one of the following 8459 // operators: +, -, *, &, |, ^, && and || 8460 // C++ 8461 // reduction-identifier is either an id-expression or one of the following 8462 // operators: +, -, *, &, |, ^, && and || 8463 // FIXME: Only 'min' and 'max' identifiers are supported for now. 8464 switch (OOK) { 8465 case OO_Plus: 8466 case OO_Minus: 8467 BOK = BO_Add; 8468 break; 8469 case OO_Star: 8470 BOK = BO_Mul; 8471 break; 8472 case OO_Amp: 8473 BOK = BO_And; 8474 break; 8475 case OO_Pipe: 8476 BOK = BO_Or; 8477 break; 8478 case OO_Caret: 8479 BOK = BO_Xor; 8480 break; 8481 case OO_AmpAmp: 8482 BOK = BO_LAnd; 8483 break; 8484 case OO_PipePipe: 8485 BOK = BO_LOr; 8486 break; 8487 case OO_New: 8488 case OO_Delete: 8489 case OO_Array_New: 8490 case OO_Array_Delete: 8491 case OO_Slash: 8492 case OO_Percent: 8493 case OO_Tilde: 8494 case OO_Exclaim: 8495 case OO_Equal: 8496 case OO_Less: 8497 case OO_Greater: 8498 case OO_LessEqual: 8499 case OO_GreaterEqual: 8500 case OO_PlusEqual: 8501 case OO_MinusEqual: 8502 case OO_StarEqual: 8503 case OO_SlashEqual: 8504 case OO_PercentEqual: 8505 case OO_CaretEqual: 8506 case OO_AmpEqual: 8507 case OO_PipeEqual: 8508 case OO_LessLess: 8509 case OO_GreaterGreater: 8510 case OO_LessLessEqual: 8511 case OO_GreaterGreaterEqual: 8512 case OO_EqualEqual: 8513 case OO_ExclaimEqual: 8514 case OO_PlusPlus: 8515 case OO_MinusMinus: 8516 case OO_Comma: 8517 case OO_ArrowStar: 8518 case OO_Arrow: 8519 case OO_Call: 8520 case OO_Subscript: 8521 case OO_Conditional: 8522 case OO_Coawait: 8523 case NUM_OVERLOADED_OPERATORS: 8524 llvm_unreachable("Unexpected reduction identifier"); 8525 case OO_None: 8526 if (auto II = DN.getAsIdentifierInfo()) { 8527 if (II->isStr("max")) 8528 BOK = BO_GT; 8529 else if (II->isStr("min")) 8530 BOK = BO_LT; 8531 } 8532 break; 8533 } 8534 SourceRange ReductionIdRange; 8535 if (ReductionIdScopeSpec.isValid()) 8536 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 8537 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 8538 8539 SmallVector<Expr *, 8> Vars; 8540 SmallVector<Expr *, 8> Privates; 8541 SmallVector<Expr *, 8> LHSs; 8542 SmallVector<Expr *, 8> RHSs; 8543 SmallVector<Expr *, 8> ReductionOps; 8544 SmallVector<Decl *, 4> ExprCaptures; 8545 SmallVector<Expr *, 4> ExprPostUpdates; 8546 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 8547 bool FirstIter = true; 8548 for (auto RefExpr : VarList) { 8549 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 8550 // OpenMP [2.1, C/C++] 8551 // A list item is a variable or array section, subject to the restrictions 8552 // specified in Section 2.4 on page 42 and in each of the sections 8553 // describing clauses and directives for which a list appears. 8554 // OpenMP [2.14.3.3, Restrictions, p.1] 8555 // A variable that is part of another variable (as an array or 8556 // structure element) cannot appear in a private clause. 8557 if (!FirstIter && IR != ER) 8558 ++IR; 8559 FirstIter = false; 8560 SourceLocation ELoc; 8561 SourceRange ERange; 8562 Expr *SimpleRefExpr = RefExpr; 8563 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 8564 /*AllowArraySection=*/true); 8565 if (Res.second) { 8566 // It will be analyzed later. 8567 Vars.push_back(RefExpr); 8568 Privates.push_back(nullptr); 8569 LHSs.push_back(nullptr); 8570 RHSs.push_back(nullptr); 8571 // Try to find 'declare reduction' corresponding construct before using 8572 // builtin/overloaded operators. 8573 QualType Type = Context.DependentTy; 8574 CXXCastPath BasePath; 8575 ExprResult DeclareReductionRef = buildDeclareReductionRef( 8576 *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, 8577 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 8578 if (CurContext->isDependentContext() && 8579 (DeclareReductionRef.isUnset() || 8580 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 8581 ReductionOps.push_back(DeclareReductionRef.get()); 8582 else 8583 ReductionOps.push_back(nullptr); 8584 } 8585 ValueDecl *D = Res.first; 8586 if (!D) 8587 continue; 8588 8589 QualType Type; 8590 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 8591 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 8592 if (ASE) 8593 Type = ASE->getType().getNonReferenceType(); 8594 else if (OASE) { 8595 auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 8596 if (auto *ATy = BaseType->getAsArrayTypeUnsafe()) 8597 Type = ATy->getElementType(); 8598 else 8599 Type = BaseType->getPointeeType(); 8600 Type = Type.getNonReferenceType(); 8601 } else 8602 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 8603 auto *VD = dyn_cast<VarDecl>(D); 8604 8605 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 8606 // A variable that appears in a private clause must not have an incomplete 8607 // type or a reference type. 8608 if (RequireCompleteType(ELoc, Type, 8609 diag::err_omp_reduction_incomplete_type)) 8610 continue; 8611 // OpenMP [2.14.3.6, reduction clause, Restrictions] 8612 // A list item that appears in a reduction clause must not be 8613 // const-qualified. 8614 if (Type.getNonReferenceType().isConstant(Context)) { 8615 Diag(ELoc, diag::err_omp_const_reduction_list_item) 8616 << getOpenMPClauseName(OMPC_reduction) << Type << ERange; 8617 if (!ASE && !OASE) { 8618 bool IsDecl = !VD || 8619 VD->isThisDeclarationADefinition(Context) == 8620 VarDecl::DeclarationOnly; 8621 Diag(D->getLocation(), 8622 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8623 << D; 8624 } 8625 continue; 8626 } 8627 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 8628 // If a list-item is a reference type then it must bind to the same object 8629 // for all threads of the team. 8630 if (!ASE && !OASE && VD) { 8631 VarDecl *VDDef = VD->getDefinition(); 8632 if (VD->getType()->isReferenceType() && VDDef) { 8633 DSARefChecker Check(DSAStack); 8634 if (Check.Visit(VDDef->getInit())) { 8635 Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; 8636 Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 8637 continue; 8638 } 8639 } 8640 } 8641 8642 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 8643 // in a Construct] 8644 // Variables with the predetermined data-sharing attributes may not be 8645 // listed in data-sharing attributes clauses, except for the cases 8646 // listed below. For these exceptions only, listing a predetermined 8647 // variable in a data-sharing attribute clause is allowed and overrides 8648 // the variable's predetermined data-sharing attributes. 8649 // OpenMP [2.14.3.6, Restrictions, p.3] 8650 // Any number of reduction clauses can be specified on the directive, 8651 // but a list item can appear only once in the reduction clauses for that 8652 // directive. 8653 DSAStackTy::DSAVarData DVar; 8654 DVar = DSAStack->getTopDSA(D, false); 8655 if (DVar.CKind == OMPC_reduction) { 8656 Diag(ELoc, diag::err_omp_once_referenced) 8657 << getOpenMPClauseName(OMPC_reduction); 8658 if (DVar.RefExpr) 8659 Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 8660 } else if (DVar.CKind != OMPC_unknown) { 8661 Diag(ELoc, diag::err_omp_wrong_dsa) 8662 << getOpenMPClauseName(DVar.CKind) 8663 << getOpenMPClauseName(OMPC_reduction); 8664 ReportOriginalDSA(*this, DSAStack, D, DVar); 8665 continue; 8666 } 8667 8668 // OpenMP [2.14.3.6, Restrictions, p.1] 8669 // A list item that appears in a reduction clause of a worksharing 8670 // construct must be shared in the parallel regions to which any of the 8671 // worksharing regions arising from the worksharing construct bind. 8672 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 8673 if (isOpenMPWorksharingDirective(CurrDir) && 8674 !isOpenMPParallelDirective(CurrDir)) { 8675 DVar = DSAStack->getImplicitDSA(D, true); 8676 if (DVar.CKind != OMPC_shared) { 8677 Diag(ELoc, diag::err_omp_required_access) 8678 << getOpenMPClauseName(OMPC_reduction) 8679 << getOpenMPClauseName(OMPC_shared); 8680 ReportOriginalDSA(*this, DSAStack, D, DVar); 8681 continue; 8682 } 8683 } 8684 8685 // Try to find 'declare reduction' corresponding construct before using 8686 // builtin/overloaded operators. 8687 CXXCastPath BasePath; 8688 ExprResult DeclareReductionRef = buildDeclareReductionRef( 8689 *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, 8690 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 8691 if (DeclareReductionRef.isInvalid()) 8692 continue; 8693 if (CurContext->isDependentContext() && 8694 (DeclareReductionRef.isUnset() || 8695 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 8696 Vars.push_back(RefExpr); 8697 Privates.push_back(nullptr); 8698 LHSs.push_back(nullptr); 8699 RHSs.push_back(nullptr); 8700 ReductionOps.push_back(DeclareReductionRef.get()); 8701 continue; 8702 } 8703 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 8704 // Not allowed reduction identifier is found. 8705 Diag(ReductionId.getLocStart(), 8706 diag::err_omp_unknown_reduction_identifier) 8707 << Type << ReductionIdRange; 8708 continue; 8709 } 8710 8711 // OpenMP [2.14.3.6, reduction clause, Restrictions] 8712 // The type of a list item that appears in a reduction clause must be valid 8713 // for the reduction-identifier. For a max or min reduction in C, the type 8714 // of the list item must be an allowed arithmetic data type: char, int, 8715 // float, double, or _Bool, possibly modified with long, short, signed, or 8716 // unsigned. For a max or min reduction in C++, the type of the list item 8717 // must be an allowed arithmetic data type: char, wchar_t, int, float, 8718 // double, or bool, possibly modified with long, short, signed, or unsigned. 8719 if (DeclareReductionRef.isUnset()) { 8720 if ((BOK == BO_GT || BOK == BO_LT) && 8721 !(Type->isScalarType() || 8722 (getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 8723 Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 8724 << getLangOpts().CPlusPlus; 8725 if (!ASE && !OASE) { 8726 bool IsDecl = !VD || 8727 VD->isThisDeclarationADefinition(Context) == 8728 VarDecl::DeclarationOnly; 8729 Diag(D->getLocation(), 8730 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8731 << D; 8732 } 8733 continue; 8734 } 8735 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 8736 !getLangOpts().CPlusPlus && Type->isFloatingType()) { 8737 Diag(ELoc, diag::err_omp_clause_floating_type_arg); 8738 if (!ASE && !OASE) { 8739 bool IsDecl = !VD || 8740 VD->isThisDeclarationADefinition(Context) == 8741 VarDecl::DeclarationOnly; 8742 Diag(D->getLocation(), 8743 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8744 << D; 8745 } 8746 continue; 8747 } 8748 } 8749 8750 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 8751 auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs", 8752 D->hasAttrs() ? &D->getAttrs() : nullptr); 8753 auto *RHSVD = buildVarDecl(*this, ELoc, Type, D->getName(), 8754 D->hasAttrs() ? &D->getAttrs() : nullptr); 8755 auto PrivateTy = Type; 8756 if (OASE || 8757 (!ASE && 8758 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 8759 // For arays/array sections only: 8760 // Create pseudo array type for private copy. The size for this array will 8761 // be generated during codegen. 8762 // For array subscripts or single variables Private Ty is the same as Type 8763 // (type of the variable or single array element). 8764 PrivateTy = Context.getVariableArrayType( 8765 Type, new (Context) OpaqueValueExpr(SourceLocation(), 8766 Context.getSizeType(), VK_RValue), 8767 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 8768 } else if (!ASE && !OASE && 8769 Context.getAsArrayType(D->getType().getNonReferenceType())) 8770 PrivateTy = D->getType().getNonReferenceType(); 8771 // Private copy. 8772 auto *PrivateVD = buildVarDecl(*this, ELoc, PrivateTy, D->getName(), 8773 D->hasAttrs() ? &D->getAttrs() : nullptr); 8774 // Add initializer for private variable. 8775 Expr *Init = nullptr; 8776 auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc); 8777 auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc); 8778 if (DeclareReductionRef.isUsable()) { 8779 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 8780 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 8781 if (DRD->getInitializer()) { 8782 Init = DRDRef; 8783 RHSVD->setInit(DRDRef); 8784 RHSVD->setInitStyle(VarDecl::CallInit); 8785 } 8786 } else { 8787 switch (BOK) { 8788 case BO_Add: 8789 case BO_Xor: 8790 case BO_Or: 8791 case BO_LOr: 8792 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 8793 if (Type->isScalarType() || Type->isAnyComplexType()) 8794 Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 8795 break; 8796 case BO_Mul: 8797 case BO_LAnd: 8798 if (Type->isScalarType() || Type->isAnyComplexType()) { 8799 // '*' and '&&' reduction ops - initializer is '1'. 8800 Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 8801 } 8802 break; 8803 case BO_And: { 8804 // '&' reduction op - initializer is '~0'. 8805 QualType OrigType = Type; 8806 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 8807 Type = ComplexTy->getElementType(); 8808 if (Type->isRealFloatingType()) { 8809 llvm::APFloat InitValue = 8810 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 8811 /*isIEEE=*/true); 8812 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 8813 Type, ELoc); 8814 } else if (Type->isScalarType()) { 8815 auto Size = Context.getTypeSize(Type); 8816 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 8817 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 8818 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 8819 } 8820 if (Init && OrigType->isAnyComplexType()) { 8821 // Init = 0xFFFF + 0xFFFFi; 8822 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 8823 Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 8824 } 8825 Type = OrigType; 8826 break; 8827 } 8828 case BO_LT: 8829 case BO_GT: { 8830 // 'min' reduction op - initializer is 'Largest representable number in 8831 // the reduction list item type'. 8832 // 'max' reduction op - initializer is 'Least representable number in 8833 // the reduction list item type'. 8834 if (Type->isIntegerType() || Type->isPointerType()) { 8835 bool IsSigned = Type->hasSignedIntegerRepresentation(); 8836 auto Size = Context.getTypeSize(Type); 8837 QualType IntTy = 8838 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 8839 llvm::APInt InitValue = 8840 (BOK != BO_LT) 8841 ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 8842 : llvm::APInt::getMinValue(Size) 8843 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 8844 : llvm::APInt::getMaxValue(Size); 8845 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 8846 if (Type->isPointerType()) { 8847 // Cast to pointer type. 8848 auto CastExpr = BuildCStyleCastExpr( 8849 SourceLocation(), Context.getTrivialTypeSourceInfo(Type, ELoc), 8850 SourceLocation(), Init); 8851 if (CastExpr.isInvalid()) 8852 continue; 8853 Init = CastExpr.get(); 8854 } 8855 } else if (Type->isRealFloatingType()) { 8856 llvm::APFloat InitValue = llvm::APFloat::getLargest( 8857 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 8858 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 8859 Type, ELoc); 8860 } 8861 break; 8862 } 8863 case BO_PtrMemD: 8864 case BO_PtrMemI: 8865 case BO_MulAssign: 8866 case BO_Div: 8867 case BO_Rem: 8868 case BO_Sub: 8869 case BO_Shl: 8870 case BO_Shr: 8871 case BO_LE: 8872 case BO_GE: 8873 case BO_EQ: 8874 case BO_NE: 8875 case BO_AndAssign: 8876 case BO_XorAssign: 8877 case BO_OrAssign: 8878 case BO_Assign: 8879 case BO_AddAssign: 8880 case BO_SubAssign: 8881 case BO_DivAssign: 8882 case BO_RemAssign: 8883 case BO_ShlAssign: 8884 case BO_ShrAssign: 8885 case BO_Comma: 8886 llvm_unreachable("Unexpected reduction operation"); 8887 } 8888 } 8889 if (Init && DeclareReductionRef.isUnset()) { 8890 AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false, 8891 /*TypeMayContainAuto=*/false); 8892 } else if (!Init) 8893 ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false); 8894 if (RHSVD->isInvalidDecl()) 8895 continue; 8896 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 8897 Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type 8898 << ReductionIdRange; 8899 bool IsDecl = 8900 !VD || 8901 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8902 Diag(D->getLocation(), 8903 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8904 << D; 8905 continue; 8906 } 8907 // Store initializer for single element in private copy. Will be used during 8908 // codegen. 8909 PrivateVD->setInit(RHSVD->getInit()); 8910 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 8911 auto *PrivateDRE = buildDeclRefExpr(*this, PrivateVD, PrivateTy, ELoc); 8912 ExprResult ReductionOp; 8913 if (DeclareReductionRef.isUsable()) { 8914 QualType RedTy = DeclareReductionRef.get()->getType(); 8915 QualType PtrRedTy = Context.getPointerType(RedTy); 8916 ExprResult LHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 8917 ExprResult RHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 8918 if (!BasePath.empty()) { 8919 LHS = DefaultLvalueConversion(LHS.get()); 8920 RHS = DefaultLvalueConversion(RHS.get()); 8921 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 8922 CK_UncheckedDerivedToBase, LHS.get(), 8923 &BasePath, LHS.get()->getValueKind()); 8924 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 8925 CK_UncheckedDerivedToBase, RHS.get(), 8926 &BasePath, RHS.get()->getValueKind()); 8927 } 8928 FunctionProtoType::ExtProtoInfo EPI; 8929 QualType Params[] = {PtrRedTy, PtrRedTy}; 8930 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 8931 auto *OVE = new (Context) OpaqueValueExpr( 8932 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 8933 DefaultLvalueConversion(DeclareReductionRef.get()).get()); 8934 Expr *Args[] = {LHS.get(), RHS.get()}; 8935 ReductionOp = new (Context) 8936 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 8937 } else { 8938 ReductionOp = BuildBinOp(DSAStack->getCurScope(), 8939 ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE); 8940 if (ReductionOp.isUsable()) { 8941 if (BOK != BO_LT && BOK != BO_GT) { 8942 ReductionOp = 8943 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 8944 BO_Assign, LHSDRE, ReductionOp.get()); 8945 } else { 8946 auto *ConditionalOp = new (Context) ConditionalOperator( 8947 ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(), 8948 RHSDRE, Type, VK_LValue, OK_Ordinary); 8949 ReductionOp = 8950 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 8951 BO_Assign, LHSDRE, ConditionalOp); 8952 } 8953 ReductionOp = ActOnFinishFullExpr(ReductionOp.get()); 8954 } 8955 if (ReductionOp.isInvalid()) 8956 continue; 8957 } 8958 8959 DeclRefExpr *Ref = nullptr; 8960 Expr *VarsExpr = RefExpr->IgnoreParens(); 8961 if (!VD) { 8962 if (ASE || OASE) { 8963 TransformExprToCaptures RebuildToCapture(*this, D); 8964 VarsExpr = 8965 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 8966 Ref = RebuildToCapture.getCapturedExpr(); 8967 } else { 8968 VarsExpr = Ref = 8969 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 8970 } 8971 if (!IsOpenMPCapturedDecl(D)) { 8972 ExprCaptures.push_back(Ref->getDecl()); 8973 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 8974 ExprResult RefRes = DefaultLvalueConversion(Ref); 8975 if (!RefRes.isUsable()) 8976 continue; 8977 ExprResult PostUpdateRes = 8978 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 8979 SimpleRefExpr, RefRes.get()); 8980 if (!PostUpdateRes.isUsable()) 8981 continue; 8982 ExprPostUpdates.push_back( 8983 IgnoredValueConversions(PostUpdateRes.get()).get()); 8984 } 8985 } 8986 } 8987 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 8988 Vars.push_back(VarsExpr); 8989 Privates.push_back(PrivateDRE); 8990 LHSs.push_back(LHSDRE); 8991 RHSs.push_back(RHSDRE); 8992 ReductionOps.push_back(ReductionOp.get()); 8993 } 8994 8995 if (Vars.empty()) 8996 return nullptr; 8997 8998 return OMPReductionClause::Create( 8999 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars, 9000 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates, 9001 LHSs, RHSs, ReductionOps, buildPreInits(Context, ExprCaptures), 9002 buildPostUpdate(*this, ExprPostUpdates)); 9003 } 9004 9005 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 9006 SourceLocation LinLoc) { 9007 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 9008 LinKind == OMPC_LINEAR_unknown) { 9009 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 9010 return true; 9011 } 9012 return false; 9013 } 9014 9015 bool Sema::CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, 9016 OpenMPLinearClauseKind LinKind, 9017 QualType Type) { 9018 auto *VD = dyn_cast_or_null<VarDecl>(D); 9019 // A variable must not have an incomplete type or a reference type. 9020 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 9021 return true; 9022 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 9023 !Type->isReferenceType()) { 9024 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 9025 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 9026 return true; 9027 } 9028 Type = Type.getNonReferenceType(); 9029 9030 // A list item must not be const-qualified. 9031 if (Type.isConstant(Context)) { 9032 Diag(ELoc, diag::err_omp_const_variable) 9033 << getOpenMPClauseName(OMPC_linear); 9034 if (D) { 9035 bool IsDecl = 9036 !VD || 9037 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9038 Diag(D->getLocation(), 9039 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9040 << D; 9041 } 9042 return true; 9043 } 9044 9045 // A list item must be of integral or pointer type. 9046 Type = Type.getUnqualifiedType().getCanonicalType(); 9047 const auto *Ty = Type.getTypePtrOrNull(); 9048 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 9049 !Ty->isPointerType())) { 9050 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 9051 if (D) { 9052 bool IsDecl = 9053 !VD || 9054 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9055 Diag(D->getLocation(), 9056 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9057 << D; 9058 } 9059 return true; 9060 } 9061 return false; 9062 } 9063 9064 OMPClause *Sema::ActOnOpenMPLinearClause( 9065 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 9066 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 9067 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 9068 SmallVector<Expr *, 8> Vars; 9069 SmallVector<Expr *, 8> Privates; 9070 SmallVector<Expr *, 8> Inits; 9071 SmallVector<Decl *, 4> ExprCaptures; 9072 SmallVector<Expr *, 4> ExprPostUpdates; 9073 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 9074 LinKind = OMPC_LINEAR_val; 9075 for (auto &RefExpr : VarList) { 9076 assert(RefExpr && "NULL expr in OpenMP linear clause."); 9077 SourceLocation ELoc; 9078 SourceRange ERange; 9079 Expr *SimpleRefExpr = RefExpr; 9080 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 9081 /*AllowArraySection=*/false); 9082 if (Res.second) { 9083 // It will be analyzed later. 9084 Vars.push_back(RefExpr); 9085 Privates.push_back(nullptr); 9086 Inits.push_back(nullptr); 9087 } 9088 ValueDecl *D = Res.first; 9089 if (!D) 9090 continue; 9091 9092 QualType Type = D->getType(); 9093 auto *VD = dyn_cast<VarDecl>(D); 9094 9095 // OpenMP [2.14.3.7, linear clause] 9096 // A list-item cannot appear in more than one linear clause. 9097 // A list-item that appears in a linear clause cannot appear in any 9098 // other data-sharing attribute clause. 9099 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 9100 if (DVar.RefExpr) { 9101 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 9102 << getOpenMPClauseName(OMPC_linear); 9103 ReportOriginalDSA(*this, DSAStack, D, DVar); 9104 continue; 9105 } 9106 9107 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 9108 continue; 9109 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 9110 9111 // Build private copy of original var. 9112 auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(), 9113 D->hasAttrs() ? &D->getAttrs() : nullptr); 9114 auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 9115 // Build var to save initial value. 9116 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 9117 Expr *InitExpr; 9118 DeclRefExpr *Ref = nullptr; 9119 if (!VD) { 9120 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 9121 if (!IsOpenMPCapturedDecl(D)) { 9122 ExprCaptures.push_back(Ref->getDecl()); 9123 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 9124 ExprResult RefRes = DefaultLvalueConversion(Ref); 9125 if (!RefRes.isUsable()) 9126 continue; 9127 ExprResult PostUpdateRes = 9128 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 9129 SimpleRefExpr, RefRes.get()); 9130 if (!PostUpdateRes.isUsable()) 9131 continue; 9132 ExprPostUpdates.push_back( 9133 IgnoredValueConversions(PostUpdateRes.get()).get()); 9134 } 9135 } 9136 } 9137 if (LinKind == OMPC_LINEAR_uval) 9138 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 9139 else 9140 InitExpr = VD ? SimpleRefExpr : Ref; 9141 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 9142 /*DirectInit=*/false, /*TypeMayContainAuto=*/false); 9143 auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 9144 9145 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 9146 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 9147 Privates.push_back(PrivateRef); 9148 Inits.push_back(InitRef); 9149 } 9150 9151 if (Vars.empty()) 9152 return nullptr; 9153 9154 Expr *StepExpr = Step; 9155 Expr *CalcStepExpr = nullptr; 9156 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 9157 !Step->isInstantiationDependent() && 9158 !Step->containsUnexpandedParameterPack()) { 9159 SourceLocation StepLoc = Step->getLocStart(); 9160 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 9161 if (Val.isInvalid()) 9162 return nullptr; 9163 StepExpr = Val.get(); 9164 9165 // Build var to save the step value. 9166 VarDecl *SaveVar = 9167 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 9168 ExprResult SaveRef = 9169 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 9170 ExprResult CalcStep = 9171 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 9172 CalcStep = ActOnFinishFullExpr(CalcStep.get()); 9173 9174 // Warn about zero linear step (it would be probably better specified as 9175 // making corresponding variables 'const'). 9176 llvm::APSInt Result; 9177 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 9178 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 9179 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 9180 << (Vars.size() > 1); 9181 if (!IsConstant && CalcStep.isUsable()) { 9182 // Calculate the step beforehand instead of doing this on each iteration. 9183 // (This is not used if the number of iterations may be kfold-ed). 9184 CalcStepExpr = CalcStep.get(); 9185 } 9186 } 9187 9188 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 9189 ColonLoc, EndLoc, Vars, Privates, Inits, 9190 StepExpr, CalcStepExpr, 9191 buildPreInits(Context, ExprCaptures), 9192 buildPostUpdate(*this, ExprPostUpdates)); 9193 } 9194 9195 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 9196 Expr *NumIterations, Sema &SemaRef, 9197 Scope *S, DSAStackTy *Stack) { 9198 // Walk the vars and build update/final expressions for the CodeGen. 9199 SmallVector<Expr *, 8> Updates; 9200 SmallVector<Expr *, 8> Finals; 9201 Expr *Step = Clause.getStep(); 9202 Expr *CalcStep = Clause.getCalcStep(); 9203 // OpenMP [2.14.3.7, linear clause] 9204 // If linear-step is not specified it is assumed to be 1. 9205 if (Step == nullptr) 9206 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 9207 else if (CalcStep) { 9208 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 9209 } 9210 bool HasErrors = false; 9211 auto CurInit = Clause.inits().begin(); 9212 auto CurPrivate = Clause.privates().begin(); 9213 auto LinKind = Clause.getModifier(); 9214 for (auto &RefExpr : Clause.varlists()) { 9215 SourceLocation ELoc; 9216 SourceRange ERange; 9217 Expr *SimpleRefExpr = RefExpr; 9218 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange, 9219 /*AllowArraySection=*/false); 9220 ValueDecl *D = Res.first; 9221 if (Res.second || !D) { 9222 Updates.push_back(nullptr); 9223 Finals.push_back(nullptr); 9224 HasErrors = true; 9225 continue; 9226 } 9227 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) { 9228 D = cast<MemberExpr>(CED->getInit()->IgnoreParenImpCasts()) 9229 ->getMemberDecl(); 9230 } 9231 auto &&Info = Stack->isLoopControlVariable(D); 9232 Expr *InitExpr = *CurInit; 9233 9234 // Build privatized reference to the current linear var. 9235 auto DE = cast<DeclRefExpr>(SimpleRefExpr); 9236 Expr *CapturedRef; 9237 if (LinKind == OMPC_LINEAR_uval) 9238 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 9239 else 9240 CapturedRef = 9241 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 9242 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 9243 /*RefersToCapture=*/true); 9244 9245 // Build update: Var = InitExpr + IV * Step 9246 ExprResult Update; 9247 if (!Info.first) { 9248 Update = 9249 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 9250 InitExpr, IV, Step, /* Subtract */ false); 9251 } else 9252 Update = *CurPrivate; 9253 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(), 9254 /*DiscardedValue=*/true); 9255 9256 // Build final: Var = InitExpr + NumIterations * Step 9257 ExprResult Final; 9258 if (!Info.first) { 9259 Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 9260 InitExpr, NumIterations, Step, 9261 /* Subtract */ false); 9262 } else 9263 Final = *CurPrivate; 9264 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(), 9265 /*DiscardedValue=*/true); 9266 9267 if (!Update.isUsable() || !Final.isUsable()) { 9268 Updates.push_back(nullptr); 9269 Finals.push_back(nullptr); 9270 HasErrors = true; 9271 } else { 9272 Updates.push_back(Update.get()); 9273 Finals.push_back(Final.get()); 9274 } 9275 ++CurInit; 9276 ++CurPrivate; 9277 } 9278 Clause.setUpdates(Updates); 9279 Clause.setFinals(Finals); 9280 return HasErrors; 9281 } 9282 9283 OMPClause *Sema::ActOnOpenMPAlignedClause( 9284 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 9285 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 9286 9287 SmallVector<Expr *, 8> Vars; 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 } 9299 ValueDecl *D = Res.first; 9300 if (!D) 9301 continue; 9302 9303 QualType QType = D->getType(); 9304 auto *VD = dyn_cast<VarDecl>(D); 9305 9306 // OpenMP [2.8.1, simd construct, Restrictions] 9307 // The type of list items appearing in the aligned clause must be 9308 // array, pointer, reference to array, or reference to pointer. 9309 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 9310 const Type *Ty = QType.getTypePtrOrNull(); 9311 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 9312 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 9313 << QType << getLangOpts().CPlusPlus << ERange; 9314 bool IsDecl = 9315 !VD || 9316 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9317 Diag(D->getLocation(), 9318 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9319 << D; 9320 continue; 9321 } 9322 9323 // OpenMP [2.8.1, simd construct, Restrictions] 9324 // A list-item cannot appear in more than one aligned clause. 9325 if (Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 9326 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 9327 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 9328 << getOpenMPClauseName(OMPC_aligned); 9329 continue; 9330 } 9331 9332 DeclRefExpr *Ref = nullptr; 9333 if (!VD && IsOpenMPCapturedDecl(D)) 9334 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 9335 Vars.push_back(DefaultFunctionArrayConversion( 9336 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 9337 .get()); 9338 } 9339 9340 // OpenMP [2.8.1, simd construct, Description] 9341 // The parameter of the aligned clause, alignment, must be a constant 9342 // positive integer expression. 9343 // If no optional parameter is specified, implementation-defined default 9344 // alignments for SIMD instructions on the target platforms are assumed. 9345 if (Alignment != nullptr) { 9346 ExprResult AlignResult = 9347 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 9348 if (AlignResult.isInvalid()) 9349 return nullptr; 9350 Alignment = AlignResult.get(); 9351 } 9352 if (Vars.empty()) 9353 return nullptr; 9354 9355 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 9356 EndLoc, Vars, Alignment); 9357 } 9358 9359 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 9360 SourceLocation StartLoc, 9361 SourceLocation LParenLoc, 9362 SourceLocation EndLoc) { 9363 SmallVector<Expr *, 8> Vars; 9364 SmallVector<Expr *, 8> SrcExprs; 9365 SmallVector<Expr *, 8> DstExprs; 9366 SmallVector<Expr *, 8> AssignmentOps; 9367 for (auto &RefExpr : VarList) { 9368 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 9369 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 9370 // It will be analyzed later. 9371 Vars.push_back(RefExpr); 9372 SrcExprs.push_back(nullptr); 9373 DstExprs.push_back(nullptr); 9374 AssignmentOps.push_back(nullptr); 9375 continue; 9376 } 9377 9378 SourceLocation ELoc = RefExpr->getExprLoc(); 9379 // OpenMP [2.1, C/C++] 9380 // A list item is a variable name. 9381 // OpenMP [2.14.4.1, Restrictions, p.1] 9382 // A list item that appears in a copyin clause must be threadprivate. 9383 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 9384 if (!DE || !isa<VarDecl>(DE->getDecl())) { 9385 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 9386 << 0 << RefExpr->getSourceRange(); 9387 continue; 9388 } 9389 9390 Decl *D = DE->getDecl(); 9391 VarDecl *VD = cast<VarDecl>(D); 9392 9393 QualType Type = VD->getType(); 9394 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 9395 // It will be analyzed later. 9396 Vars.push_back(DE); 9397 SrcExprs.push_back(nullptr); 9398 DstExprs.push_back(nullptr); 9399 AssignmentOps.push_back(nullptr); 9400 continue; 9401 } 9402 9403 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 9404 // A list item that appears in a copyin clause must be threadprivate. 9405 if (!DSAStack->isThreadPrivate(VD)) { 9406 Diag(ELoc, diag::err_omp_required_access) 9407 << getOpenMPClauseName(OMPC_copyin) 9408 << getOpenMPDirectiveName(OMPD_threadprivate); 9409 continue; 9410 } 9411 9412 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 9413 // A variable of class type (or array thereof) that appears in a 9414 // copyin clause requires an accessible, unambiguous copy assignment 9415 // operator for the class type. 9416 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 9417 auto *SrcVD = 9418 buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(), 9419 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 9420 auto *PseudoSrcExpr = buildDeclRefExpr( 9421 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 9422 auto *DstVD = 9423 buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst", 9424 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 9425 auto *PseudoDstExpr = 9426 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 9427 // For arrays generate assignment operation for single element and replace 9428 // it by the original array element in CodeGen. 9429 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 9430 PseudoDstExpr, PseudoSrcExpr); 9431 if (AssignmentOp.isInvalid()) 9432 continue; 9433 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 9434 /*DiscardedValue=*/true); 9435 if (AssignmentOp.isInvalid()) 9436 continue; 9437 9438 DSAStack->addDSA(VD, DE, OMPC_copyin); 9439 Vars.push_back(DE); 9440 SrcExprs.push_back(PseudoSrcExpr); 9441 DstExprs.push_back(PseudoDstExpr); 9442 AssignmentOps.push_back(AssignmentOp.get()); 9443 } 9444 9445 if (Vars.empty()) 9446 return nullptr; 9447 9448 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 9449 SrcExprs, DstExprs, AssignmentOps); 9450 } 9451 9452 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 9453 SourceLocation StartLoc, 9454 SourceLocation LParenLoc, 9455 SourceLocation EndLoc) { 9456 SmallVector<Expr *, 8> Vars; 9457 SmallVector<Expr *, 8> SrcExprs; 9458 SmallVector<Expr *, 8> DstExprs; 9459 SmallVector<Expr *, 8> AssignmentOps; 9460 for (auto &RefExpr : VarList) { 9461 assert(RefExpr && "NULL expr in OpenMP linear clause."); 9462 SourceLocation ELoc; 9463 SourceRange ERange; 9464 Expr *SimpleRefExpr = RefExpr; 9465 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 9466 /*AllowArraySection=*/false); 9467 if (Res.second) { 9468 // It will be analyzed later. 9469 Vars.push_back(RefExpr); 9470 SrcExprs.push_back(nullptr); 9471 DstExprs.push_back(nullptr); 9472 AssignmentOps.push_back(nullptr); 9473 } 9474 ValueDecl *D = Res.first; 9475 if (!D) 9476 continue; 9477 9478 QualType Type = D->getType(); 9479 auto *VD = dyn_cast<VarDecl>(D); 9480 9481 // OpenMP [2.14.4.2, Restrictions, p.2] 9482 // A list item that appears in a copyprivate clause may not appear in a 9483 // private or firstprivate clause on the single construct. 9484 if (!VD || !DSAStack->isThreadPrivate(VD)) { 9485 auto DVar = DSAStack->getTopDSA(D, false); 9486 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 9487 DVar.RefExpr) { 9488 Diag(ELoc, diag::err_omp_wrong_dsa) 9489 << getOpenMPClauseName(DVar.CKind) 9490 << getOpenMPClauseName(OMPC_copyprivate); 9491 ReportOriginalDSA(*this, DSAStack, D, DVar); 9492 continue; 9493 } 9494 9495 // OpenMP [2.11.4.2, Restrictions, p.1] 9496 // All list items that appear in a copyprivate clause must be either 9497 // threadprivate or private in the enclosing context. 9498 if (DVar.CKind == OMPC_unknown) { 9499 DVar = DSAStack->getImplicitDSA(D, false); 9500 if (DVar.CKind == OMPC_shared) { 9501 Diag(ELoc, diag::err_omp_required_access) 9502 << getOpenMPClauseName(OMPC_copyprivate) 9503 << "threadprivate or private in the enclosing context"; 9504 ReportOriginalDSA(*this, DSAStack, D, DVar); 9505 continue; 9506 } 9507 } 9508 } 9509 9510 // Variably modified types are not supported. 9511 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 9512 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 9513 << getOpenMPClauseName(OMPC_copyprivate) << Type 9514 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 9515 bool IsDecl = 9516 !VD || 9517 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9518 Diag(D->getLocation(), 9519 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9520 << D; 9521 continue; 9522 } 9523 9524 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 9525 // A variable of class type (or array thereof) that appears in a 9526 // copyin clause requires an accessible, unambiguous copy assignment 9527 // operator for the class type. 9528 Type = Context.getBaseElementType(Type.getNonReferenceType()) 9529 .getUnqualifiedType(); 9530 auto *SrcVD = 9531 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src", 9532 D->hasAttrs() ? &D->getAttrs() : nullptr); 9533 auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 9534 auto *DstVD = 9535 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst", 9536 D->hasAttrs() ? &D->getAttrs() : nullptr); 9537 auto *PseudoDstExpr = 9538 buildDeclRefExpr(*this, DstVD, Type, ELoc); 9539 auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 9540 PseudoDstExpr, PseudoSrcExpr); 9541 if (AssignmentOp.isInvalid()) 9542 continue; 9543 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 9544 /*DiscardedValue=*/true); 9545 if (AssignmentOp.isInvalid()) 9546 continue; 9547 9548 // No need to mark vars as copyprivate, they are already threadprivate or 9549 // implicitly private. 9550 assert(VD || IsOpenMPCapturedDecl(D)); 9551 Vars.push_back( 9552 VD ? RefExpr->IgnoreParens() 9553 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 9554 SrcExprs.push_back(PseudoSrcExpr); 9555 DstExprs.push_back(PseudoDstExpr); 9556 AssignmentOps.push_back(AssignmentOp.get()); 9557 } 9558 9559 if (Vars.empty()) 9560 return nullptr; 9561 9562 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9563 Vars, SrcExprs, DstExprs, AssignmentOps); 9564 } 9565 9566 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 9567 SourceLocation StartLoc, 9568 SourceLocation LParenLoc, 9569 SourceLocation EndLoc) { 9570 if (VarList.empty()) 9571 return nullptr; 9572 9573 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 9574 } 9575 9576 OMPClause * 9577 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 9578 SourceLocation DepLoc, SourceLocation ColonLoc, 9579 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 9580 SourceLocation LParenLoc, SourceLocation EndLoc) { 9581 if (DSAStack->getCurrentDirective() == OMPD_ordered && 9582 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 9583 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 9584 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 9585 return nullptr; 9586 } 9587 if (DSAStack->getCurrentDirective() != OMPD_ordered && 9588 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 9589 DepKind == OMPC_DEPEND_sink)) { 9590 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 9591 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 9592 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 9593 /*Last=*/OMPC_DEPEND_unknown, Except) 9594 << getOpenMPClauseName(OMPC_depend); 9595 return nullptr; 9596 } 9597 SmallVector<Expr *, 8> Vars; 9598 DSAStackTy::OperatorOffsetTy OpsOffs; 9599 llvm::APSInt DepCounter(/*BitWidth=*/32); 9600 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 9601 if (DepKind == OMPC_DEPEND_sink) { 9602 if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) { 9603 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 9604 TotalDepCount.setIsUnsigned(/*Val=*/true); 9605 } 9606 } 9607 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) || 9608 DSAStack->getParentOrderedRegionParam()) { 9609 for (auto &RefExpr : VarList) { 9610 assert(RefExpr && "NULL expr in OpenMP shared clause."); 9611 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 9612 // It will be analyzed later. 9613 Vars.push_back(RefExpr); 9614 continue; 9615 } 9616 9617 SourceLocation ELoc = RefExpr->getExprLoc(); 9618 auto *SimpleExpr = RefExpr->IgnoreParenCasts(); 9619 if (DepKind == OMPC_DEPEND_sink) { 9620 if (DepCounter >= TotalDepCount) { 9621 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 9622 continue; 9623 } 9624 ++DepCounter; 9625 // OpenMP [2.13.9, Summary] 9626 // depend(dependence-type : vec), where dependence-type is: 9627 // 'sink' and where vec is the iteration vector, which has the form: 9628 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 9629 // where n is the value specified by the ordered clause in the loop 9630 // directive, xi denotes the loop iteration variable of the i-th nested 9631 // loop associated with the loop directive, and di is a constant 9632 // non-negative integer. 9633 if (CurContext->isDependentContext()) { 9634 // It will be analyzed later. 9635 Vars.push_back(RefExpr); 9636 continue; 9637 } 9638 SimpleExpr = SimpleExpr->IgnoreImplicit(); 9639 OverloadedOperatorKind OOK = OO_None; 9640 SourceLocation OOLoc; 9641 Expr *LHS = SimpleExpr; 9642 Expr *RHS = nullptr; 9643 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 9644 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 9645 OOLoc = BO->getOperatorLoc(); 9646 LHS = BO->getLHS()->IgnoreParenImpCasts(); 9647 RHS = BO->getRHS()->IgnoreParenImpCasts(); 9648 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 9649 OOK = OCE->getOperator(); 9650 OOLoc = OCE->getOperatorLoc(); 9651 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 9652 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 9653 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 9654 OOK = MCE->getMethodDecl() 9655 ->getNameInfo() 9656 .getName() 9657 .getCXXOverloadedOperator(); 9658 OOLoc = MCE->getCallee()->getExprLoc(); 9659 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 9660 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 9661 } 9662 SourceLocation ELoc; 9663 SourceRange ERange; 9664 auto Res = getPrivateItem(*this, LHS, ELoc, ERange, 9665 /*AllowArraySection=*/false); 9666 if (Res.second) { 9667 // It will be analyzed later. 9668 Vars.push_back(RefExpr); 9669 } 9670 ValueDecl *D = Res.first; 9671 if (!D) 9672 continue; 9673 9674 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 9675 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 9676 continue; 9677 } 9678 if (RHS) { 9679 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 9680 RHS, OMPC_depend, /*StrictlyPositive=*/false); 9681 if (RHSRes.isInvalid()) 9682 continue; 9683 } 9684 if (!CurContext->isDependentContext() && 9685 DSAStack->getParentOrderedRegionParam() && 9686 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 9687 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 9688 << DSAStack->getParentLoopControlVariable( 9689 DepCounter.getZExtValue()); 9690 continue; 9691 } 9692 OpsOffs.push_back({RHS, OOK}); 9693 } else { 9694 // OpenMP [2.11.1.1, Restrictions, p.3] 9695 // A variable that is part of another variable (such as a field of a 9696 // structure) but is not an array element or an array section cannot 9697 // appear in a depend clause. 9698 auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr); 9699 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 9700 auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 9701 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 9702 (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) || 9703 (ASE && 9704 !ASE->getBase() 9705 ->getType() 9706 .getNonReferenceType() 9707 ->isPointerType() && 9708 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 9709 Diag(ELoc, diag::err_omp_expected_var_name_member_expr_or_array_item) 9710 << 0 << RefExpr->getSourceRange(); 9711 continue; 9712 } 9713 } 9714 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 9715 } 9716 9717 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 9718 TotalDepCount > VarList.size() && 9719 DSAStack->getParentOrderedRegionParam()) { 9720 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 9721 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 9722 } 9723 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 9724 Vars.empty()) 9725 return nullptr; 9726 } 9727 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9728 DepKind, DepLoc, ColonLoc, Vars); 9729 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) 9730 DSAStack->addDoacrossDependClause(C, OpsOffs); 9731 return C; 9732 } 9733 9734 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 9735 SourceLocation LParenLoc, 9736 SourceLocation EndLoc) { 9737 Expr *ValExpr = Device; 9738 9739 // OpenMP [2.9.1, Restrictions] 9740 // The device expression must evaluate to a non-negative integer value. 9741 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 9742 /*StrictlyPositive=*/false)) 9743 return nullptr; 9744 9745 return new (Context) OMPDeviceClause(ValExpr, StartLoc, LParenLoc, EndLoc); 9746 } 9747 9748 static bool IsCXXRecordForMappable(Sema &SemaRef, SourceLocation Loc, 9749 DSAStackTy *Stack, CXXRecordDecl *RD) { 9750 if (!RD || RD->isInvalidDecl()) 9751 return true; 9752 9753 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) 9754 if (auto *CTD = CTSD->getSpecializedTemplate()) 9755 RD = CTD->getTemplatedDecl(); 9756 auto QTy = SemaRef.Context.getRecordType(RD); 9757 if (RD->isDynamicClass()) { 9758 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 9759 SemaRef.Diag(RD->getLocation(), diag::note_omp_polymorphic_in_target); 9760 return false; 9761 } 9762 auto *DC = RD; 9763 bool IsCorrect = true; 9764 for (auto *I : DC->decls()) { 9765 if (I) { 9766 if (auto *MD = dyn_cast<CXXMethodDecl>(I)) { 9767 if (MD->isStatic()) { 9768 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 9769 SemaRef.Diag(MD->getLocation(), 9770 diag::note_omp_static_member_in_target); 9771 IsCorrect = false; 9772 } 9773 } else if (auto *VD = dyn_cast<VarDecl>(I)) { 9774 if (VD->isStaticDataMember()) { 9775 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 9776 SemaRef.Diag(VD->getLocation(), 9777 diag::note_omp_static_member_in_target); 9778 IsCorrect = false; 9779 } 9780 } 9781 } 9782 } 9783 9784 for (auto &I : RD->bases()) { 9785 if (!IsCXXRecordForMappable(SemaRef, I.getLocStart(), Stack, 9786 I.getType()->getAsCXXRecordDecl())) 9787 IsCorrect = false; 9788 } 9789 return IsCorrect; 9790 } 9791 9792 static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 9793 DSAStackTy *Stack, QualType QTy) { 9794 NamedDecl *ND; 9795 if (QTy->isIncompleteType(&ND)) { 9796 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 9797 return false; 9798 } else if (CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(ND)) { 9799 if (!RD->isInvalidDecl() && 9800 !IsCXXRecordForMappable(SemaRef, SL, Stack, RD)) 9801 return false; 9802 } 9803 return true; 9804 } 9805 9806 /// \brief Return true if it can be proven that the provided array expression 9807 /// (array section or array subscript) does NOT specify the whole size of the 9808 /// array whose base type is \a BaseQTy. 9809 static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 9810 const Expr *E, 9811 QualType BaseQTy) { 9812 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 9813 9814 // If this is an array subscript, it refers to the whole size if the size of 9815 // the dimension is constant and equals 1. Also, an array section assumes the 9816 // format of an array subscript if no colon is used. 9817 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 9818 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 9819 return ATy->getSize().getSExtValue() != 1; 9820 // Size can't be evaluated statically. 9821 return false; 9822 } 9823 9824 assert(OASE && "Expecting array section if not an array subscript."); 9825 auto *LowerBound = OASE->getLowerBound(); 9826 auto *Length = OASE->getLength(); 9827 9828 // If there is a lower bound that does not evaluates to zero, we are not 9829 // convering the whole dimension. 9830 if (LowerBound) { 9831 llvm::APSInt ConstLowerBound; 9832 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) 9833 return false; // Can't get the integer value as a constant. 9834 if (ConstLowerBound.getSExtValue()) 9835 return true; 9836 } 9837 9838 // If we don't have a length we covering the whole dimension. 9839 if (!Length) 9840 return false; 9841 9842 // If the base is a pointer, we don't have a way to get the size of the 9843 // pointee. 9844 if (BaseQTy->isPointerType()) 9845 return false; 9846 9847 // We can only check if the length is the same as the size of the dimension 9848 // if we have a constant array. 9849 auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 9850 if (!CATy) 9851 return false; 9852 9853 llvm::APSInt ConstLength; 9854 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 9855 return false; // Can't get the integer value as a constant. 9856 9857 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 9858 } 9859 9860 // Return true if it can be proven that the provided array expression (array 9861 // section or array subscript) does NOT specify a single element of the array 9862 // whose base type is \a BaseQTy. 9863 static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 9864 const Expr *E, 9865 QualType BaseQTy) { 9866 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 9867 9868 // An array subscript always refer to a single element. Also, an array section 9869 // assumes the format of an array subscript if no colon is used. 9870 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 9871 return false; 9872 9873 assert(OASE && "Expecting array section if not an array subscript."); 9874 auto *Length = OASE->getLength(); 9875 9876 // If we don't have a length we have to check if the array has unitary size 9877 // for this dimension. Also, we should always expect a length if the base type 9878 // is pointer. 9879 if (!Length) { 9880 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 9881 return ATy->getSize().getSExtValue() != 1; 9882 // We cannot assume anything. 9883 return false; 9884 } 9885 9886 // Check if the length evaluates to 1. 9887 llvm::APSInt ConstLength; 9888 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 9889 return false; // Can't get the integer value as a constant. 9890 9891 return ConstLength.getSExtValue() != 1; 9892 } 9893 9894 // Return the expression of the base of the mappable expression or null if it 9895 // cannot be determined and do all the necessary checks to see if the expression 9896 // is valid as a standalone mappable expression. In the process, record all the 9897 // components of the expression. 9898 static Expr *CheckMapClauseExpressionBase( 9899 Sema &SemaRef, Expr *E, 9900 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 9901 OpenMPClauseKind CKind) { 9902 SourceLocation ELoc = E->getExprLoc(); 9903 SourceRange ERange = E->getSourceRange(); 9904 9905 // The base of elements of list in a map clause have to be either: 9906 // - a reference to variable or field. 9907 // - a member expression. 9908 // - an array expression. 9909 // 9910 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 9911 // reference to 'r'. 9912 // 9913 // If we have: 9914 // 9915 // struct SS { 9916 // Bla S; 9917 // foo() { 9918 // #pragma omp target map (S.Arr[:12]); 9919 // } 9920 // } 9921 // 9922 // We want to retrieve the member expression 'this->S'; 9923 9924 Expr *RelevantExpr = nullptr; 9925 9926 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 9927 // If a list item is an array section, it must specify contiguous storage. 9928 // 9929 // For this restriction it is sufficient that we make sure only references 9930 // to variables or fields and array expressions, and that no array sections 9931 // exist except in the rightmost expression (unless they cover the whole 9932 // dimension of the array). E.g. these would be invalid: 9933 // 9934 // r.ArrS[3:5].Arr[6:7] 9935 // 9936 // r.ArrS[3:5].x 9937 // 9938 // but these would be valid: 9939 // r.ArrS[3].Arr[6:7] 9940 // 9941 // r.ArrS[3].x 9942 9943 bool AllowUnitySizeArraySection = true; 9944 bool AllowWholeSizeArraySection = true; 9945 9946 while (!RelevantExpr) { 9947 E = E->IgnoreParenImpCasts(); 9948 9949 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 9950 if (!isa<VarDecl>(CurE->getDecl())) 9951 break; 9952 9953 RelevantExpr = CurE; 9954 9955 // If we got a reference to a declaration, we should not expect any array 9956 // section before that. 9957 AllowUnitySizeArraySection = false; 9958 AllowWholeSizeArraySection = false; 9959 9960 // Record the component. 9961 CurComponents.push_back(OMPClauseMappableExprCommon::MappableComponent( 9962 CurE, CurE->getDecl())); 9963 continue; 9964 } 9965 9966 if (auto *CurE = dyn_cast<MemberExpr>(E)) { 9967 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 9968 9969 if (isa<CXXThisExpr>(BaseE)) 9970 // We found a base expression: this->Val. 9971 RelevantExpr = CurE; 9972 else 9973 E = BaseE; 9974 9975 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 9976 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 9977 << CurE->getSourceRange(); 9978 break; 9979 } 9980 9981 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 9982 9983 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 9984 // A bit-field cannot appear in a map clause. 9985 // 9986 if (FD->isBitField()) { 9987 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 9988 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 9989 break; 9990 } 9991 9992 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 9993 // If the type of a list item is a reference to a type T then the type 9994 // will be considered to be T for all purposes of this clause. 9995 QualType CurType = BaseE->getType().getNonReferenceType(); 9996 9997 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 9998 // A list item cannot be a variable that is a member of a structure with 9999 // a union type. 10000 // 10001 if (auto *RT = CurType->getAs<RecordType>()) 10002 if (RT->isUnionType()) { 10003 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 10004 << CurE->getSourceRange(); 10005 break; 10006 } 10007 10008 // If we got a member expression, we should not expect any array section 10009 // before that: 10010 // 10011 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 10012 // If a list item is an element of a structure, only the rightmost symbol 10013 // of the variable reference can be an array section. 10014 // 10015 AllowUnitySizeArraySection = false; 10016 AllowWholeSizeArraySection = false; 10017 10018 // Record the component. 10019 CurComponents.push_back( 10020 OMPClauseMappableExprCommon::MappableComponent(CurE, FD)); 10021 continue; 10022 } 10023 10024 if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 10025 E = CurE->getBase()->IgnoreParenImpCasts(); 10026 10027 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 10028 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 10029 << 0 << CurE->getSourceRange(); 10030 break; 10031 } 10032 10033 // If we got an array subscript that express the whole dimension we 10034 // can have any array expressions before. If it only expressing part of 10035 // the dimension, we can only have unitary-size array expressions. 10036 if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 10037 E->getType())) 10038 AllowWholeSizeArraySection = false; 10039 10040 // Record the component - we don't have any declaration associated. 10041 CurComponents.push_back( 10042 OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); 10043 continue; 10044 } 10045 10046 if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 10047 E = CurE->getBase()->IgnoreParenImpCasts(); 10048 10049 auto CurType = 10050 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 10051 10052 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 10053 // If the type of a list item is a reference to a type T then the type 10054 // will be considered to be T for all purposes of this clause. 10055 if (CurType->isReferenceType()) 10056 CurType = CurType->getPointeeType(); 10057 10058 bool IsPointer = CurType->isAnyPointerType(); 10059 10060 if (!IsPointer && !CurType->isArrayType()) { 10061 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 10062 << 0 << CurE->getSourceRange(); 10063 break; 10064 } 10065 10066 bool NotWhole = 10067 CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 10068 bool NotUnity = 10069 CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 10070 10071 if (AllowWholeSizeArraySection && AllowUnitySizeArraySection) { 10072 // Any array section is currently allowed. 10073 // 10074 // If this array section refers to the whole dimension we can still 10075 // accept other array sections before this one, except if the base is a 10076 // pointer. Otherwise, only unitary sections are accepted. 10077 if (NotWhole || IsPointer) 10078 AllowWholeSizeArraySection = false; 10079 } else if ((AllowUnitySizeArraySection && NotUnity) || 10080 (AllowWholeSizeArraySection && NotWhole)) { 10081 // A unity or whole array section is not allowed and that is not 10082 // compatible with the properties of the current array section. 10083 SemaRef.Diag( 10084 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 10085 << CurE->getSourceRange(); 10086 break; 10087 } 10088 10089 // Record the component - we don't have any declaration associated. 10090 CurComponents.push_back( 10091 OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); 10092 continue; 10093 } 10094 10095 // If nothing else worked, this is not a valid map clause expression. 10096 SemaRef.Diag(ELoc, 10097 diag::err_omp_expected_named_var_member_or_array_expression) 10098 << ERange; 10099 break; 10100 } 10101 10102 return RelevantExpr; 10103 } 10104 10105 // Return true if expression E associated with value VD has conflicts with other 10106 // map information. 10107 static bool CheckMapConflicts( 10108 Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E, 10109 bool CurrentRegionOnly, 10110 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 10111 OpenMPClauseKind CKind) { 10112 assert(VD && E); 10113 SourceLocation ELoc = E->getExprLoc(); 10114 SourceRange ERange = E->getSourceRange(); 10115 10116 // In order to easily check the conflicts we need to match each component of 10117 // the expression under test with the components of the expressions that are 10118 // already in the stack. 10119 10120 assert(!CurComponents.empty() && "Map clause expression with no components!"); 10121 assert(CurComponents.back().getAssociatedDeclaration() == VD && 10122 "Map clause expression with unexpected base!"); 10123 10124 // Variables to help detecting enclosing problems in data environment nests. 10125 bool IsEnclosedByDataEnvironmentExpr = false; 10126 const Expr *EnclosingExpr = nullptr; 10127 10128 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 10129 VD, CurrentRegionOnly, 10130 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef 10131 StackComponents) -> bool { 10132 10133 assert(!StackComponents.empty() && 10134 "Map clause expression with no components!"); 10135 assert(StackComponents.back().getAssociatedDeclaration() == VD && 10136 "Map clause expression with unexpected base!"); 10137 10138 // The whole expression in the stack. 10139 auto *RE = StackComponents.front().getAssociatedExpression(); 10140 10141 // Expressions must start from the same base. Here we detect at which 10142 // point both expressions diverge from each other and see if we can 10143 // detect if the memory referred to both expressions is contiguous and 10144 // do not overlap. 10145 auto CI = CurComponents.rbegin(); 10146 auto CE = CurComponents.rend(); 10147 auto SI = StackComponents.rbegin(); 10148 auto SE = StackComponents.rend(); 10149 for (; CI != CE && SI != SE; ++CI, ++SI) { 10150 10151 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 10152 // At most one list item can be an array item derived from a given 10153 // variable in map clauses of the same construct. 10154 if (CurrentRegionOnly && 10155 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 10156 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 10157 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 10158 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 10159 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 10160 diag::err_omp_multiple_array_items_in_map_clause) 10161 << CI->getAssociatedExpression()->getSourceRange(); 10162 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 10163 diag::note_used_here) 10164 << SI->getAssociatedExpression()->getSourceRange(); 10165 return true; 10166 } 10167 10168 // Do both expressions have the same kind? 10169 if (CI->getAssociatedExpression()->getStmtClass() != 10170 SI->getAssociatedExpression()->getStmtClass()) 10171 break; 10172 10173 // Are we dealing with different variables/fields? 10174 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 10175 break; 10176 } 10177 10178 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 10179 // List items of map clauses in the same construct must not share 10180 // original storage. 10181 // 10182 // If the expressions are exactly the same or one is a subset of the 10183 // other, it means they are sharing storage. 10184 if (CI == CE && SI == SE) { 10185 if (CurrentRegionOnly) { 10186 if (CKind == OMPC_map) 10187 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 10188 else { 10189 assert(CKind == OMPC_to || CKind == OMPC_from); 10190 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 10191 << ERange; 10192 } 10193 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 10194 << RE->getSourceRange(); 10195 return true; 10196 } else { 10197 // If we find the same expression in the enclosing data environment, 10198 // that is legal. 10199 IsEnclosedByDataEnvironmentExpr = true; 10200 return false; 10201 } 10202 } 10203 10204 QualType DerivedType = 10205 std::prev(CI)->getAssociatedDeclaration()->getType(); 10206 SourceLocation DerivedLoc = 10207 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 10208 10209 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 10210 // If the type of a list item is a reference to a type T then the type 10211 // will be considered to be T for all purposes of this clause. 10212 DerivedType = DerivedType.getNonReferenceType(); 10213 10214 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 10215 // A variable for which the type is pointer and an array section 10216 // derived from that variable must not appear as list items of map 10217 // clauses of the same construct. 10218 // 10219 // Also, cover one of the cases in: 10220 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 10221 // If any part of the original storage of a list item has corresponding 10222 // storage in the device data environment, all of the original storage 10223 // must have corresponding storage in the device data environment. 10224 // 10225 if (DerivedType->isAnyPointerType()) { 10226 if (CI == CE || SI == SE) { 10227 SemaRef.Diag( 10228 DerivedLoc, 10229 diag::err_omp_pointer_mapped_along_with_derived_section) 10230 << DerivedLoc; 10231 } else { 10232 assert(CI != CE && SI != SE); 10233 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced) 10234 << DerivedLoc; 10235 } 10236 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 10237 << RE->getSourceRange(); 10238 return true; 10239 } 10240 10241 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 10242 // List items of map clauses in the same construct must not share 10243 // original storage. 10244 // 10245 // An expression is a subset of the other. 10246 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 10247 if (CKind == OMPC_map) 10248 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 10249 else { 10250 assert(CKind == OMPC_to || CKind == OMPC_from); 10251 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 10252 << ERange; 10253 } 10254 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 10255 << RE->getSourceRange(); 10256 return true; 10257 } 10258 10259 // The current expression uses the same base as other expression in the 10260 // data environment but does not contain it completely. 10261 if (!CurrentRegionOnly && SI != SE) 10262 EnclosingExpr = RE; 10263 10264 // The current expression is a subset of the expression in the data 10265 // environment. 10266 IsEnclosedByDataEnvironmentExpr |= 10267 (!CurrentRegionOnly && CI != CE && SI == SE); 10268 10269 return false; 10270 }); 10271 10272 if (CurrentRegionOnly) 10273 return FoundError; 10274 10275 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 10276 // If any part of the original storage of a list item has corresponding 10277 // storage in the device data environment, all of the original storage must 10278 // have corresponding storage in the device data environment. 10279 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 10280 // If a list item is an element of a structure, and a different element of 10281 // the structure has a corresponding list item in the device data environment 10282 // prior to a task encountering the construct associated with the map clause, 10283 // then the list item must also have a corresponding list item in the device 10284 // data environment prior to the task encountering the construct. 10285 // 10286 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 10287 SemaRef.Diag(ELoc, 10288 diag::err_omp_original_storage_is_shared_and_does_not_contain) 10289 << ERange; 10290 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 10291 << EnclosingExpr->getSourceRange(); 10292 return true; 10293 } 10294 10295 return FoundError; 10296 } 10297 10298 namespace { 10299 // Utility struct that gathers all the related lists associated with a mappable 10300 // expression. 10301 struct MappableVarListInfo final { 10302 // The list of expressions. 10303 ArrayRef<Expr *> VarList; 10304 // The list of processed expressions. 10305 SmallVector<Expr *, 16> ProcessedVarList; 10306 // The mappble components for each expression. 10307 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 10308 // The base declaration of the variable. 10309 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 10310 10311 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 10312 // We have a list of components and base declarations for each entry in the 10313 // variable list. 10314 VarComponents.reserve(VarList.size()); 10315 VarBaseDeclarations.reserve(VarList.size()); 10316 } 10317 }; 10318 } 10319 10320 // Check the validity of the provided variable list for the provided clause kind 10321 // \a CKind. In the check process the valid expressions, and mappable expression 10322 // components and variables are extracted and used to fill \a Vars, 10323 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and 10324 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'. 10325 static void 10326 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, 10327 OpenMPClauseKind CKind, MappableVarListInfo &MVLI, 10328 SourceLocation StartLoc, 10329 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 10330 bool IsMapTypeImplicit = false) { 10331 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 10332 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 10333 "Unexpected clause kind with mappable expressions!"); 10334 10335 // Keep track of the mappable components and base declarations in this clause. 10336 // Each entry in the list is going to have a list of components associated. We 10337 // record each set of the components so that we can build the clause later on. 10338 // In the end we should have the same amount of declarations and component 10339 // lists. 10340 10341 for (auto &RE : MVLI.VarList) { 10342 assert(RE && "Null expr in omp to/from/map clause"); 10343 SourceLocation ELoc = RE->getExprLoc(); 10344 10345 auto *VE = RE->IgnoreParenLValueCasts(); 10346 10347 if (VE->isValueDependent() || VE->isTypeDependent() || 10348 VE->isInstantiationDependent() || 10349 VE->containsUnexpandedParameterPack()) { 10350 // We can only analyze this information once the missing information is 10351 // resolved. 10352 MVLI.ProcessedVarList.push_back(RE); 10353 continue; 10354 } 10355 10356 auto *SimpleExpr = RE->IgnoreParenCasts(); 10357 10358 if (!RE->IgnoreParenImpCasts()->isLValue()) { 10359 SemaRef.Diag(ELoc, 10360 diag::err_omp_expected_named_var_member_or_array_expression) 10361 << RE->getSourceRange(); 10362 continue; 10363 } 10364 10365 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 10366 ValueDecl *CurDeclaration = nullptr; 10367 10368 // Obtain the array or member expression bases if required. Also, fill the 10369 // components array with all the components identified in the process. 10370 auto *BE = 10371 CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind); 10372 if (!BE) 10373 continue; 10374 10375 assert(!CurComponents.empty() && 10376 "Invalid mappable expression information."); 10377 10378 // For the following checks, we rely on the base declaration which is 10379 // expected to be associated with the last component. The declaration is 10380 // expected to be a variable or a field (if 'this' is being mapped). 10381 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 10382 assert(CurDeclaration && "Null decl on map clause."); 10383 assert( 10384 CurDeclaration->isCanonicalDecl() && 10385 "Expecting components to have associated only canonical declarations."); 10386 10387 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 10388 auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 10389 10390 assert((VD || FD) && "Only variables or fields are expected here!"); 10391 (void)FD; 10392 10393 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 10394 // threadprivate variables cannot appear in a map clause. 10395 // OpenMP 4.5 [2.10.5, target update Construct] 10396 // threadprivate variables cannot appear in a from clause. 10397 if (VD && DSAS->isThreadPrivate(VD)) { 10398 auto DVar = DSAS->getTopDSA(VD, false); 10399 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 10400 << getOpenMPClauseName(CKind); 10401 ReportOriginalDSA(SemaRef, DSAS, VD, DVar); 10402 continue; 10403 } 10404 10405 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 10406 // A list item cannot appear in both a map clause and a data-sharing 10407 // attribute clause on the same construct. 10408 10409 // Check conflicts with other map clause expressions. We check the conflicts 10410 // with the current construct separately from the enclosing data 10411 // environment, because the restrictions are different. We only have to 10412 // check conflicts across regions for the map clauses. 10413 if (CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 10414 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 10415 break; 10416 if (CKind == OMPC_map && 10417 CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 10418 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 10419 break; 10420 10421 // OpenMP 4.5 [2.10.5, target update Construct] 10422 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 10423 // If the type of a list item is a reference to a type T then the type will 10424 // be considered to be T for all purposes of this clause. 10425 QualType Type = CurDeclaration->getType().getNonReferenceType(); 10426 10427 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 10428 // A list item in a to or from clause must have a mappable type. 10429 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 10430 // A list item must have a mappable type. 10431 if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 10432 DSAS, Type)) 10433 continue; 10434 10435 if (CKind == OMPC_map) { 10436 // target enter data 10437 // OpenMP [2.10.2, Restrictions, p. 99] 10438 // A map-type must be specified in all map clauses and must be either 10439 // to or alloc. 10440 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 10441 if (DKind == OMPD_target_enter_data && 10442 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 10443 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 10444 << (IsMapTypeImplicit ? 1 : 0) 10445 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 10446 << getOpenMPDirectiveName(DKind); 10447 continue; 10448 } 10449 10450 // target exit_data 10451 // OpenMP [2.10.3, Restrictions, p. 102] 10452 // A map-type must be specified in all map clauses and must be either 10453 // from, release, or delete. 10454 if (DKind == OMPD_target_exit_data && 10455 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 10456 MapType == OMPC_MAP_delete)) { 10457 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 10458 << (IsMapTypeImplicit ? 1 : 0) 10459 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 10460 << getOpenMPDirectiveName(DKind); 10461 continue; 10462 } 10463 10464 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10465 // A list item cannot appear in both a map clause and a data-sharing 10466 // attribute clause on the same construct 10467 if (DKind == OMPD_target && VD) { 10468 auto DVar = DSAS->getTopDSA(VD, false); 10469 if (isOpenMPPrivate(DVar.CKind)) { 10470 SemaRef.Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) 10471 << getOpenMPClauseName(DVar.CKind) 10472 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 10473 ReportOriginalDSA(SemaRef, DSAS, CurDeclaration, DVar); 10474 continue; 10475 } 10476 } 10477 } 10478 10479 // Save the current expression. 10480 MVLI.ProcessedVarList.push_back(RE); 10481 10482 // Store the components in the stack so that they can be used to check 10483 // against other clauses later on. 10484 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents); 10485 10486 // Save the components and declaration to create the clause. For purposes of 10487 // the clause creation, any component list that has has base 'this' uses 10488 // null as base declaration. 10489 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 10490 MVLI.VarComponents.back().append(CurComponents.begin(), 10491 CurComponents.end()); 10492 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 10493 : CurDeclaration); 10494 } 10495 } 10496 10497 OMPClause * 10498 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, 10499 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 10500 SourceLocation MapLoc, SourceLocation ColonLoc, 10501 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 10502 SourceLocation LParenLoc, SourceLocation EndLoc) { 10503 MappableVarListInfo MVLI(VarList); 10504 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc, 10505 MapType, IsMapTypeImplicit); 10506 10507 // We need to produce a map clause even if we don't have variables so that 10508 // other diagnostics related with non-existing map clauses are accurate. 10509 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10510 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 10511 MVLI.VarComponents, MapTypeModifier, MapType, 10512 IsMapTypeImplicit, MapLoc); 10513 } 10514 10515 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 10516 TypeResult ParsedType) { 10517 assert(ParsedType.isUsable()); 10518 10519 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 10520 if (ReductionType.isNull()) 10521 return QualType(); 10522 10523 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 10524 // A type name in a declare reduction directive cannot be a function type, an 10525 // array type, a reference type, or a type qualified with const, volatile or 10526 // restrict. 10527 if (ReductionType.hasQualifiers()) { 10528 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 10529 return QualType(); 10530 } 10531 10532 if (ReductionType->isFunctionType()) { 10533 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 10534 return QualType(); 10535 } 10536 if (ReductionType->isReferenceType()) { 10537 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 10538 return QualType(); 10539 } 10540 if (ReductionType->isArrayType()) { 10541 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 10542 return QualType(); 10543 } 10544 return ReductionType; 10545 } 10546 10547 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 10548 Scope *S, DeclContext *DC, DeclarationName Name, 10549 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 10550 AccessSpecifier AS, Decl *PrevDeclInScope) { 10551 SmallVector<Decl *, 8> Decls; 10552 Decls.reserve(ReductionTypes.size()); 10553 10554 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 10555 ForRedeclaration); 10556 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 10557 // A reduction-identifier may not be re-declared in the current scope for the 10558 // same type or for a type that is compatible according to the base language 10559 // rules. 10560 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 10561 OMPDeclareReductionDecl *PrevDRD = nullptr; 10562 bool InCompoundScope = true; 10563 if (S != nullptr) { 10564 // Find previous declaration with the same name not referenced in other 10565 // declarations. 10566 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 10567 InCompoundScope = 10568 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 10569 LookupName(Lookup, S); 10570 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 10571 /*AllowInlineNamespace=*/false); 10572 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 10573 auto Filter = Lookup.makeFilter(); 10574 while (Filter.hasNext()) { 10575 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 10576 if (InCompoundScope) { 10577 auto I = UsedAsPrevious.find(PrevDecl); 10578 if (I == UsedAsPrevious.end()) 10579 UsedAsPrevious[PrevDecl] = false; 10580 if (auto *D = PrevDecl->getPrevDeclInScope()) 10581 UsedAsPrevious[D] = true; 10582 } 10583 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 10584 PrevDecl->getLocation(); 10585 } 10586 Filter.done(); 10587 if (InCompoundScope) { 10588 for (auto &PrevData : UsedAsPrevious) { 10589 if (!PrevData.second) { 10590 PrevDRD = PrevData.first; 10591 break; 10592 } 10593 } 10594 } 10595 } else if (PrevDeclInScope != nullptr) { 10596 auto *PrevDRDInScope = PrevDRD = 10597 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 10598 do { 10599 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 10600 PrevDRDInScope->getLocation(); 10601 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 10602 } while (PrevDRDInScope != nullptr); 10603 } 10604 for (auto &TyData : ReductionTypes) { 10605 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 10606 bool Invalid = false; 10607 if (I != PreviousRedeclTypes.end()) { 10608 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 10609 << TyData.first; 10610 Diag(I->second, diag::note_previous_definition); 10611 Invalid = true; 10612 } 10613 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 10614 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 10615 Name, TyData.first, PrevDRD); 10616 DC->addDecl(DRD); 10617 DRD->setAccess(AS); 10618 Decls.push_back(DRD); 10619 if (Invalid) 10620 DRD->setInvalidDecl(); 10621 else 10622 PrevDRD = DRD; 10623 } 10624 10625 return DeclGroupPtrTy::make( 10626 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 10627 } 10628 10629 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 10630 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10631 10632 // Enter new function scope. 10633 PushFunctionScope(); 10634 getCurFunction()->setHasBranchProtectedScope(); 10635 getCurFunction()->setHasOMPDeclareReductionCombiner(); 10636 10637 if (S != nullptr) 10638 PushDeclContext(S, DRD); 10639 else 10640 CurContext = DRD; 10641 10642 PushExpressionEvaluationContext(PotentiallyEvaluated); 10643 10644 QualType ReductionType = DRD->getType(); 10645 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 10646 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 10647 // uses semantics of argument handles by value, but it should be passed by 10648 // reference. C lang does not support references, so pass all parameters as 10649 // pointers. 10650 // Create 'T omp_in;' variable. 10651 auto *OmpInParm = 10652 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 10653 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 10654 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 10655 // uses semantics of argument handles by value, but it should be passed by 10656 // reference. C lang does not support references, so pass all parameters as 10657 // pointers. 10658 // Create 'T omp_out;' variable. 10659 auto *OmpOutParm = 10660 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 10661 if (S != nullptr) { 10662 PushOnScopeChains(OmpInParm, S); 10663 PushOnScopeChains(OmpOutParm, S); 10664 } else { 10665 DRD->addDecl(OmpInParm); 10666 DRD->addDecl(OmpOutParm); 10667 } 10668 } 10669 10670 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 10671 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10672 DiscardCleanupsInEvaluationContext(); 10673 PopExpressionEvaluationContext(); 10674 10675 PopDeclContext(); 10676 PopFunctionScopeInfo(); 10677 10678 if (Combiner != nullptr) 10679 DRD->setCombiner(Combiner); 10680 else 10681 DRD->setInvalidDecl(); 10682 } 10683 10684 void Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 10685 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10686 10687 // Enter new function scope. 10688 PushFunctionScope(); 10689 getCurFunction()->setHasBranchProtectedScope(); 10690 10691 if (S != nullptr) 10692 PushDeclContext(S, DRD); 10693 else 10694 CurContext = DRD; 10695 10696 PushExpressionEvaluationContext(PotentiallyEvaluated); 10697 10698 QualType ReductionType = DRD->getType(); 10699 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 10700 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 10701 // uses semantics of argument handles by value, but it should be passed by 10702 // reference. C lang does not support references, so pass all parameters as 10703 // pointers. 10704 // Create 'T omp_priv;' variable. 10705 auto *OmpPrivParm = 10706 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 10707 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 10708 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 10709 // uses semantics of argument handles by value, but it should be passed by 10710 // reference. C lang does not support references, so pass all parameters as 10711 // pointers. 10712 // Create 'T omp_orig;' variable. 10713 auto *OmpOrigParm = 10714 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 10715 if (S != nullptr) { 10716 PushOnScopeChains(OmpPrivParm, S); 10717 PushOnScopeChains(OmpOrigParm, S); 10718 } else { 10719 DRD->addDecl(OmpPrivParm); 10720 DRD->addDecl(OmpOrigParm); 10721 } 10722 } 10723 10724 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, 10725 Expr *Initializer) { 10726 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10727 DiscardCleanupsInEvaluationContext(); 10728 PopExpressionEvaluationContext(); 10729 10730 PopDeclContext(); 10731 PopFunctionScopeInfo(); 10732 10733 if (Initializer != nullptr) 10734 DRD->setInitializer(Initializer); 10735 else 10736 DRD->setInvalidDecl(); 10737 } 10738 10739 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 10740 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 10741 for (auto *D : DeclReductions.get()) { 10742 if (IsValid) { 10743 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10744 if (S != nullptr) 10745 PushOnScopeChains(DRD, S, /*AddToContext=*/false); 10746 } else 10747 D->setInvalidDecl(); 10748 } 10749 return DeclReductions; 10750 } 10751 10752 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 10753 SourceLocation StartLoc, 10754 SourceLocation LParenLoc, 10755 SourceLocation EndLoc) { 10756 Expr *ValExpr = NumTeams; 10757 10758 // OpenMP [teams Constrcut, Restrictions] 10759 // The num_teams expression must evaluate to a positive integer value. 10760 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 10761 /*StrictlyPositive=*/true)) 10762 return nullptr; 10763 10764 return new (Context) OMPNumTeamsClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10765 } 10766 10767 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 10768 SourceLocation StartLoc, 10769 SourceLocation LParenLoc, 10770 SourceLocation EndLoc) { 10771 Expr *ValExpr = ThreadLimit; 10772 10773 // OpenMP [teams Constrcut, Restrictions] 10774 // The thread_limit expression must evaluate to a positive integer value. 10775 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 10776 /*StrictlyPositive=*/true)) 10777 return nullptr; 10778 10779 return new (Context) OMPThreadLimitClause(ValExpr, StartLoc, LParenLoc, 10780 EndLoc); 10781 } 10782 10783 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 10784 SourceLocation StartLoc, 10785 SourceLocation LParenLoc, 10786 SourceLocation EndLoc) { 10787 Expr *ValExpr = Priority; 10788 10789 // OpenMP [2.9.1, task Constrcut] 10790 // The priority-value is a non-negative numerical scalar expression. 10791 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 10792 /*StrictlyPositive=*/false)) 10793 return nullptr; 10794 10795 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10796 } 10797 10798 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 10799 SourceLocation StartLoc, 10800 SourceLocation LParenLoc, 10801 SourceLocation EndLoc) { 10802 Expr *ValExpr = Grainsize; 10803 10804 // OpenMP [2.9.2, taskloop Constrcut] 10805 // The parameter of the grainsize clause must be a positive integer 10806 // expression. 10807 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 10808 /*StrictlyPositive=*/true)) 10809 return nullptr; 10810 10811 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10812 } 10813 10814 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 10815 SourceLocation StartLoc, 10816 SourceLocation LParenLoc, 10817 SourceLocation EndLoc) { 10818 Expr *ValExpr = NumTasks; 10819 10820 // OpenMP [2.9.2, taskloop Constrcut] 10821 // The parameter of the num_tasks clause must be a positive integer 10822 // expression. 10823 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 10824 /*StrictlyPositive=*/true)) 10825 return nullptr; 10826 10827 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10828 } 10829 10830 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 10831 SourceLocation LParenLoc, 10832 SourceLocation EndLoc) { 10833 // OpenMP [2.13.2, critical construct, Description] 10834 // ... where hint-expression is an integer constant expression that evaluates 10835 // to a valid lock hint. 10836 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 10837 if (HintExpr.isInvalid()) 10838 return nullptr; 10839 return new (Context) 10840 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 10841 } 10842 10843 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 10844 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10845 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 10846 SourceLocation EndLoc) { 10847 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 10848 std::string Values; 10849 Values += "'"; 10850 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 10851 Values += "'"; 10852 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 10853 << Values << getOpenMPClauseName(OMPC_dist_schedule); 10854 return nullptr; 10855 } 10856 Expr *ValExpr = ChunkSize; 10857 Stmt *HelperValStmt = nullptr; 10858 if (ChunkSize) { 10859 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 10860 !ChunkSize->isInstantiationDependent() && 10861 !ChunkSize->containsUnexpandedParameterPack()) { 10862 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 10863 ExprResult Val = 10864 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 10865 if (Val.isInvalid()) 10866 return nullptr; 10867 10868 ValExpr = Val.get(); 10869 10870 // OpenMP [2.7.1, Restrictions] 10871 // chunk_size must be a loop invariant integer expression with a positive 10872 // value. 10873 llvm::APSInt Result; 10874 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 10875 if (Result.isSigned() && !Result.isStrictlyPositive()) { 10876 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 10877 << "dist_schedule" << ChunkSize->getSourceRange(); 10878 return nullptr; 10879 } 10880 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 10881 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 10882 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10883 HelperValStmt = buildPreInits(Context, Captures); 10884 } 10885 } 10886 } 10887 10888 return new (Context) 10889 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 10890 Kind, ValExpr, HelperValStmt); 10891 } 10892 10893 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 10894 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 10895 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 10896 SourceLocation KindLoc, SourceLocation EndLoc) { 10897 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 10898 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 10899 Kind != OMPC_DEFAULTMAP_scalar) { 10900 std::string Value; 10901 SourceLocation Loc; 10902 Value += "'"; 10903 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 10904 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 10905 OMPC_DEFAULTMAP_MODIFIER_tofrom); 10906 Loc = MLoc; 10907 } else { 10908 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 10909 OMPC_DEFAULTMAP_scalar); 10910 Loc = KindLoc; 10911 } 10912 Value += "'"; 10913 Diag(Loc, diag::err_omp_unexpected_clause_value) 10914 << Value << getOpenMPClauseName(OMPC_defaultmap); 10915 return nullptr; 10916 } 10917 10918 return new (Context) 10919 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 10920 } 10921 10922 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 10923 DeclContext *CurLexicalContext = getCurLexicalContext(); 10924 if (!CurLexicalContext->isFileContext() && 10925 !CurLexicalContext->isExternCContext() && 10926 !CurLexicalContext->isExternCXXContext()) { 10927 Diag(Loc, diag::err_omp_region_not_file_context); 10928 return false; 10929 } 10930 if (IsInOpenMPDeclareTargetContext) { 10931 Diag(Loc, diag::err_omp_enclosed_declare_target); 10932 return false; 10933 } 10934 10935 IsInOpenMPDeclareTargetContext = true; 10936 return true; 10937 } 10938 10939 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 10940 assert(IsInOpenMPDeclareTargetContext && 10941 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 10942 10943 IsInOpenMPDeclareTargetContext = false; 10944 } 10945 10946 void 10947 Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 10948 const DeclarationNameInfo &Id, 10949 OMPDeclareTargetDeclAttr::MapTypeTy MT, 10950 NamedDeclSetType &SameDirectiveDecls) { 10951 LookupResult Lookup(*this, Id, LookupOrdinaryName); 10952 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 10953 10954 if (Lookup.isAmbiguous()) 10955 return; 10956 Lookup.suppressDiagnostics(); 10957 10958 if (!Lookup.isSingleResult()) { 10959 if (TypoCorrection Corrected = 10960 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, 10961 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), 10962 CTK_ErrorRecovery)) { 10963 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 10964 << Id.getName()); 10965 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 10966 return; 10967 } 10968 10969 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 10970 return; 10971 } 10972 10973 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 10974 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { 10975 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 10976 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 10977 10978 if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) { 10979 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 10980 ND->addAttr(A); 10981 if (ASTMutationListener *ML = Context.getASTMutationListener()) 10982 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 10983 checkDeclIsAllowedInOpenMPTarget(nullptr, ND); 10984 } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) { 10985 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 10986 << Id.getName(); 10987 } 10988 } else 10989 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 10990 } 10991 10992 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 10993 Sema &SemaRef, Decl *D) { 10994 if (!D) 10995 return; 10996 Decl *LD = nullptr; 10997 if (isa<TagDecl>(D)) { 10998 LD = cast<TagDecl>(D)->getDefinition(); 10999 } else if (isa<VarDecl>(D)) { 11000 LD = cast<VarDecl>(D)->getDefinition(); 11001 11002 // If this is an implicit variable that is legal and we do not need to do 11003 // anything. 11004 if (cast<VarDecl>(D)->isImplicit()) { 11005 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11006 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 11007 D->addAttr(A); 11008 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 11009 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 11010 return; 11011 } 11012 11013 } else if (isa<FunctionDecl>(D)) { 11014 const FunctionDecl *FD = nullptr; 11015 if (cast<FunctionDecl>(D)->hasBody(FD)) 11016 LD = const_cast<FunctionDecl *>(FD); 11017 11018 // If the definition is associated with the current declaration in the 11019 // target region (it can be e.g. a lambda) that is legal and we do not need 11020 // to do anything else. 11021 if (LD == D) { 11022 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11023 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 11024 D->addAttr(A); 11025 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 11026 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 11027 return; 11028 } 11029 } 11030 if (!LD) 11031 LD = D; 11032 if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() && 11033 (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) { 11034 // Outlined declaration is not declared target. 11035 if (LD->isOutOfLine()) { 11036 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 11037 SemaRef.Diag(SL, diag::note_used_here) << SR; 11038 } else { 11039 DeclContext *DC = LD->getDeclContext(); 11040 while (DC) { 11041 if (isa<FunctionDecl>(DC) && 11042 cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>()) 11043 break; 11044 DC = DC->getParent(); 11045 } 11046 if (DC) 11047 return; 11048 11049 // Is not declared in target context. 11050 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 11051 SemaRef.Diag(SL, diag::note_used_here) << SR; 11052 } 11053 // Mark decl as declared target to prevent further diagnostic. 11054 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11055 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 11056 D->addAttr(A); 11057 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 11058 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 11059 } 11060 } 11061 11062 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 11063 Sema &SemaRef, DSAStackTy *Stack, 11064 ValueDecl *VD) { 11065 if (VD->hasAttr<OMPDeclareTargetDeclAttr>()) 11066 return true; 11067 if (!CheckTypeMappable(SL, SR, SemaRef, Stack, VD->getType())) 11068 return false; 11069 return true; 11070 } 11071 11072 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D) { 11073 if (!D || D->isInvalidDecl()) 11074 return; 11075 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 11076 SourceLocation SL = E ? E->getLocStart() : D->getLocation(); 11077 // 2.10.6: threadprivate variable cannot appear in a declare target directive. 11078 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 11079 if (DSAStack->isThreadPrivate(VD)) { 11080 Diag(SL, diag::err_omp_threadprivate_in_target); 11081 ReportOriginalDSA(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 11082 return; 11083 } 11084 } 11085 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 11086 // Problem if any with var declared with incomplete type will be reported 11087 // as normal, so no need to check it here. 11088 if ((E || !VD->getType()->isIncompleteType()) && 11089 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) { 11090 // Mark decl as declared target to prevent further diagnostic. 11091 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) { 11092 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11093 Context, OMPDeclareTargetDeclAttr::MT_To); 11094 VD->addAttr(A); 11095 if (ASTMutationListener *ML = Context.getASTMutationListener()) 11096 ML->DeclarationMarkedOpenMPDeclareTarget(VD, A); 11097 } 11098 return; 11099 } 11100 } 11101 if (!E) { 11102 // Checking declaration inside declare target region. 11103 if (!D->hasAttr<OMPDeclareTargetDeclAttr>() && 11104 (isa<VarDecl>(D) || isa<FunctionDecl>(D))) { 11105 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11106 Context, OMPDeclareTargetDeclAttr::MT_To); 11107 D->addAttr(A); 11108 if (ASTMutationListener *ML = Context.getASTMutationListener()) 11109 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 11110 } 11111 return; 11112 } 11113 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 11114 } 11115 11116 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 11117 SourceLocation StartLoc, 11118 SourceLocation LParenLoc, 11119 SourceLocation EndLoc) { 11120 MappableVarListInfo MVLI(VarList); 11121 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc); 11122 if (MVLI.ProcessedVarList.empty()) 11123 return nullptr; 11124 11125 return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11126 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 11127 MVLI.VarComponents); 11128 } 11129 11130 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 11131 SourceLocation StartLoc, 11132 SourceLocation LParenLoc, 11133 SourceLocation EndLoc) { 11134 MappableVarListInfo MVLI(VarList); 11135 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc); 11136 if (MVLI.ProcessedVarList.empty()) 11137 return nullptr; 11138 11139 return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11140 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 11141 MVLI.VarComponents); 11142 } 11143