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 !CurContext->isDependentContext()) { 7346 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 7347 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 7348 HelperValStmt = buildPreInits(Context, Captures); 7349 } 7350 } 7351 } 7352 7353 return new (Context) 7354 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 7355 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 7356 } 7357 7358 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 7359 SourceLocation StartLoc, 7360 SourceLocation EndLoc) { 7361 OMPClause *Res = nullptr; 7362 switch (Kind) { 7363 case OMPC_ordered: 7364 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 7365 break; 7366 case OMPC_nowait: 7367 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 7368 break; 7369 case OMPC_untied: 7370 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 7371 break; 7372 case OMPC_mergeable: 7373 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 7374 break; 7375 case OMPC_read: 7376 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 7377 break; 7378 case OMPC_write: 7379 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 7380 break; 7381 case OMPC_update: 7382 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 7383 break; 7384 case OMPC_capture: 7385 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 7386 break; 7387 case OMPC_seq_cst: 7388 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 7389 break; 7390 case OMPC_threads: 7391 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 7392 break; 7393 case OMPC_simd: 7394 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 7395 break; 7396 case OMPC_nogroup: 7397 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 7398 break; 7399 case OMPC_if: 7400 case OMPC_final: 7401 case OMPC_num_threads: 7402 case OMPC_safelen: 7403 case OMPC_simdlen: 7404 case OMPC_collapse: 7405 case OMPC_schedule: 7406 case OMPC_private: 7407 case OMPC_firstprivate: 7408 case OMPC_lastprivate: 7409 case OMPC_shared: 7410 case OMPC_reduction: 7411 case OMPC_linear: 7412 case OMPC_aligned: 7413 case OMPC_copyin: 7414 case OMPC_copyprivate: 7415 case OMPC_default: 7416 case OMPC_proc_bind: 7417 case OMPC_threadprivate: 7418 case OMPC_flush: 7419 case OMPC_depend: 7420 case OMPC_device: 7421 case OMPC_map: 7422 case OMPC_num_teams: 7423 case OMPC_thread_limit: 7424 case OMPC_priority: 7425 case OMPC_grainsize: 7426 case OMPC_num_tasks: 7427 case OMPC_hint: 7428 case OMPC_dist_schedule: 7429 case OMPC_defaultmap: 7430 case OMPC_unknown: 7431 case OMPC_uniform: 7432 case OMPC_to: 7433 case OMPC_from: 7434 llvm_unreachable("Clause is not allowed."); 7435 } 7436 return Res; 7437 } 7438 7439 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 7440 SourceLocation EndLoc) { 7441 DSAStack->setNowaitRegion(); 7442 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 7443 } 7444 7445 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 7446 SourceLocation EndLoc) { 7447 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 7448 } 7449 7450 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 7451 SourceLocation EndLoc) { 7452 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 7453 } 7454 7455 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 7456 SourceLocation EndLoc) { 7457 return new (Context) OMPReadClause(StartLoc, EndLoc); 7458 } 7459 7460 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 7461 SourceLocation EndLoc) { 7462 return new (Context) OMPWriteClause(StartLoc, EndLoc); 7463 } 7464 7465 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 7466 SourceLocation EndLoc) { 7467 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 7468 } 7469 7470 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 7471 SourceLocation EndLoc) { 7472 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 7473 } 7474 7475 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 7476 SourceLocation EndLoc) { 7477 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 7478 } 7479 7480 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 7481 SourceLocation EndLoc) { 7482 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 7483 } 7484 7485 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 7486 SourceLocation EndLoc) { 7487 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 7488 } 7489 7490 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 7491 SourceLocation EndLoc) { 7492 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 7493 } 7494 7495 OMPClause *Sema::ActOnOpenMPVarListClause( 7496 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 7497 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 7498 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 7499 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, 7500 OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, 7501 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 7502 SourceLocation DepLinMapLoc) { 7503 OMPClause *Res = nullptr; 7504 switch (Kind) { 7505 case OMPC_private: 7506 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7507 break; 7508 case OMPC_firstprivate: 7509 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7510 break; 7511 case OMPC_lastprivate: 7512 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7513 break; 7514 case OMPC_shared: 7515 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 7516 break; 7517 case OMPC_reduction: 7518 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 7519 EndLoc, ReductionIdScopeSpec, ReductionId); 7520 break; 7521 case OMPC_linear: 7522 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 7523 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 7524 break; 7525 case OMPC_aligned: 7526 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 7527 ColonLoc, EndLoc); 7528 break; 7529 case OMPC_copyin: 7530 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 7531 break; 7532 case OMPC_copyprivate: 7533 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7534 break; 7535 case OMPC_flush: 7536 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 7537 break; 7538 case OMPC_depend: 7539 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 7540 StartLoc, LParenLoc, EndLoc); 7541 break; 7542 case OMPC_map: 7543 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, 7544 DepLinMapLoc, ColonLoc, VarList, StartLoc, 7545 LParenLoc, EndLoc); 7546 break; 7547 case OMPC_to: 7548 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc); 7549 break; 7550 case OMPC_from: 7551 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc); 7552 break; 7553 case OMPC_if: 7554 case OMPC_final: 7555 case OMPC_num_threads: 7556 case OMPC_safelen: 7557 case OMPC_simdlen: 7558 case OMPC_collapse: 7559 case OMPC_default: 7560 case OMPC_proc_bind: 7561 case OMPC_schedule: 7562 case OMPC_ordered: 7563 case OMPC_nowait: 7564 case OMPC_untied: 7565 case OMPC_mergeable: 7566 case OMPC_threadprivate: 7567 case OMPC_read: 7568 case OMPC_write: 7569 case OMPC_update: 7570 case OMPC_capture: 7571 case OMPC_seq_cst: 7572 case OMPC_device: 7573 case OMPC_threads: 7574 case OMPC_simd: 7575 case OMPC_num_teams: 7576 case OMPC_thread_limit: 7577 case OMPC_priority: 7578 case OMPC_grainsize: 7579 case OMPC_nogroup: 7580 case OMPC_num_tasks: 7581 case OMPC_hint: 7582 case OMPC_dist_schedule: 7583 case OMPC_defaultmap: 7584 case OMPC_unknown: 7585 case OMPC_uniform: 7586 llvm_unreachable("Clause is not allowed."); 7587 } 7588 return Res; 7589 } 7590 7591 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 7592 ExprObjectKind OK, SourceLocation Loc) { 7593 ExprResult Res = BuildDeclRefExpr( 7594 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 7595 if (!Res.isUsable()) 7596 return ExprError(); 7597 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 7598 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 7599 if (!Res.isUsable()) 7600 return ExprError(); 7601 } 7602 if (VK != VK_LValue && Res.get()->isGLValue()) { 7603 Res = DefaultLvalueConversion(Res.get()); 7604 if (!Res.isUsable()) 7605 return ExprError(); 7606 } 7607 return Res; 7608 } 7609 7610 static std::pair<ValueDecl *, bool> 7611 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 7612 SourceRange &ERange, bool AllowArraySection = false) { 7613 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 7614 RefExpr->containsUnexpandedParameterPack()) 7615 return std::make_pair(nullptr, true); 7616 7617 // OpenMP [3.1, C/C++] 7618 // A list item is a variable name. 7619 // OpenMP [2.9.3.3, Restrictions, p.1] 7620 // A variable that is part of another variable (as an array or 7621 // structure element) cannot appear in a private clause. 7622 RefExpr = RefExpr->IgnoreParens(); 7623 enum { 7624 NoArrayExpr = -1, 7625 ArraySubscript = 0, 7626 OMPArraySection = 1 7627 } IsArrayExpr = NoArrayExpr; 7628 if (AllowArraySection) { 7629 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 7630 auto *Base = ASE->getBase()->IgnoreParenImpCasts(); 7631 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 7632 Base = TempASE->getBase()->IgnoreParenImpCasts(); 7633 RefExpr = Base; 7634 IsArrayExpr = ArraySubscript; 7635 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 7636 auto *Base = OASE->getBase()->IgnoreParenImpCasts(); 7637 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 7638 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 7639 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 7640 Base = TempASE->getBase()->IgnoreParenImpCasts(); 7641 RefExpr = Base; 7642 IsArrayExpr = OMPArraySection; 7643 } 7644 } 7645 ELoc = RefExpr->getExprLoc(); 7646 ERange = RefExpr->getSourceRange(); 7647 RefExpr = RefExpr->IgnoreParenImpCasts(); 7648 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 7649 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 7650 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 7651 (S.getCurrentThisType().isNull() || !ME || 7652 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 7653 !isa<FieldDecl>(ME->getMemberDecl()))) { 7654 if (IsArrayExpr != NoArrayExpr) 7655 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 7656 << ERange; 7657 else { 7658 S.Diag(ELoc, 7659 AllowArraySection 7660 ? diag::err_omp_expected_var_name_member_expr_or_array_item 7661 : diag::err_omp_expected_var_name_member_expr) 7662 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 7663 } 7664 return std::make_pair(nullptr, false); 7665 } 7666 return std::make_pair(DE ? DE->getDecl() : ME->getMemberDecl(), false); 7667 } 7668 7669 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 7670 SourceLocation StartLoc, 7671 SourceLocation LParenLoc, 7672 SourceLocation EndLoc) { 7673 SmallVector<Expr *, 8> Vars; 7674 SmallVector<Expr *, 8> PrivateCopies; 7675 for (auto &RefExpr : VarList) { 7676 assert(RefExpr && "NULL expr in OpenMP private clause."); 7677 SourceLocation ELoc; 7678 SourceRange ERange; 7679 Expr *SimpleRefExpr = RefExpr; 7680 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 7681 if (Res.second) { 7682 // It will be analyzed later. 7683 Vars.push_back(RefExpr); 7684 PrivateCopies.push_back(nullptr); 7685 } 7686 ValueDecl *D = Res.first; 7687 if (!D) 7688 continue; 7689 7690 QualType Type = D->getType(); 7691 auto *VD = dyn_cast<VarDecl>(D); 7692 7693 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 7694 // A variable that appears in a private clause must not have an incomplete 7695 // type or a reference type. 7696 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 7697 continue; 7698 Type = Type.getNonReferenceType(); 7699 7700 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7701 // in a Construct] 7702 // Variables with the predetermined data-sharing attributes may not be 7703 // listed in data-sharing attributes clauses, except for the cases 7704 // listed below. For these exceptions only, listing a predetermined 7705 // variable in a data-sharing attribute clause is allowed and overrides 7706 // the variable's predetermined data-sharing attributes. 7707 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7708 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 7709 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 7710 << getOpenMPClauseName(OMPC_private); 7711 ReportOriginalDSA(*this, DSAStack, D, DVar); 7712 continue; 7713 } 7714 7715 // Variably modified types are not supported for tasks. 7716 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 7717 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 7718 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 7719 << getOpenMPClauseName(OMPC_private) << Type 7720 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7721 bool IsDecl = 7722 !VD || 7723 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 7724 Diag(D->getLocation(), 7725 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 7726 << D; 7727 continue; 7728 } 7729 7730 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 7731 // A list item cannot appear in both a map clause and a data-sharing 7732 // attribute clause on the same construct 7733 if (DSAStack->getCurrentDirective() == OMPD_target) { 7734 if (DSAStack->checkMappableExprComponentListsForDecl( 7735 VD, /* CurrentRegionOnly = */ true, 7736 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef) 7737 -> bool { return true; })) { 7738 Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) 7739 << getOpenMPClauseName(OMPC_private) 7740 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7741 ReportOriginalDSA(*this, DSAStack, D, DVar); 7742 continue; 7743 } 7744 } 7745 7746 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 7747 // A variable of class type (or array thereof) that appears in a private 7748 // clause requires an accessible, unambiguous default constructor for the 7749 // class type. 7750 // Generate helper private variable and initialize it with the default 7751 // value. The address of the original variable is replaced by the address of 7752 // the new private variable in CodeGen. This new variable is not added to 7753 // IdResolver, so the code in the OpenMP region uses original variable for 7754 // proper diagnostics. 7755 Type = Type.getUnqualifiedType(); 7756 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 7757 D->hasAttrs() ? &D->getAttrs() : nullptr); 7758 ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); 7759 if (VDPrivate->isInvalidDecl()) 7760 continue; 7761 auto VDPrivateRefExpr = buildDeclRefExpr( 7762 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 7763 7764 DeclRefExpr *Ref = nullptr; 7765 if (!VD) 7766 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 7767 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 7768 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 7769 PrivateCopies.push_back(VDPrivateRefExpr); 7770 } 7771 7772 if (Vars.empty()) 7773 return nullptr; 7774 7775 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 7776 PrivateCopies); 7777 } 7778 7779 namespace { 7780 class DiagsUninitializedSeveretyRAII { 7781 private: 7782 DiagnosticsEngine &Diags; 7783 SourceLocation SavedLoc; 7784 bool IsIgnored; 7785 7786 public: 7787 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 7788 bool IsIgnored) 7789 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 7790 if (!IsIgnored) { 7791 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 7792 /*Map*/ diag::Severity::Ignored, Loc); 7793 } 7794 } 7795 ~DiagsUninitializedSeveretyRAII() { 7796 if (!IsIgnored) 7797 Diags.popMappings(SavedLoc); 7798 } 7799 }; 7800 } 7801 7802 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 7803 SourceLocation StartLoc, 7804 SourceLocation LParenLoc, 7805 SourceLocation EndLoc) { 7806 SmallVector<Expr *, 8> Vars; 7807 SmallVector<Expr *, 8> PrivateCopies; 7808 SmallVector<Expr *, 8> Inits; 7809 SmallVector<Decl *, 4> ExprCaptures; 7810 bool IsImplicitClause = 7811 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 7812 auto ImplicitClauseLoc = DSAStack->getConstructLoc(); 7813 7814 for (auto &RefExpr : VarList) { 7815 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 7816 SourceLocation ELoc; 7817 SourceRange ERange; 7818 Expr *SimpleRefExpr = RefExpr; 7819 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 7820 if (Res.second) { 7821 // It will be analyzed later. 7822 Vars.push_back(RefExpr); 7823 PrivateCopies.push_back(nullptr); 7824 Inits.push_back(nullptr); 7825 } 7826 ValueDecl *D = Res.first; 7827 if (!D) 7828 continue; 7829 7830 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 7831 QualType Type = D->getType(); 7832 auto *VD = dyn_cast<VarDecl>(D); 7833 7834 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 7835 // A variable that appears in a private clause must not have an incomplete 7836 // type or a reference type. 7837 if (RequireCompleteType(ELoc, Type, 7838 diag::err_omp_firstprivate_incomplete_type)) 7839 continue; 7840 Type = Type.getNonReferenceType(); 7841 7842 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 7843 // A variable of class type (or array thereof) that appears in a private 7844 // clause requires an accessible, unambiguous copy constructor for the 7845 // class type. 7846 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 7847 7848 // If an implicit firstprivate variable found it was checked already. 7849 DSAStackTy::DSAVarData TopDVar; 7850 if (!IsImplicitClause) { 7851 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 7852 TopDVar = DVar; 7853 bool IsConstant = ElemType.isConstant(Context); 7854 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 7855 // A list item that specifies a given variable may not appear in more 7856 // than one clause on the same directive, except that a variable may be 7857 // specified in both firstprivate and lastprivate clauses. 7858 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 7859 DVar.CKind != OMPC_lastprivate && DVar.RefExpr) { 7860 Diag(ELoc, diag::err_omp_wrong_dsa) 7861 << getOpenMPClauseName(DVar.CKind) 7862 << getOpenMPClauseName(OMPC_firstprivate); 7863 ReportOriginalDSA(*this, DSAStack, D, DVar); 7864 continue; 7865 } 7866 7867 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7868 // in a Construct] 7869 // Variables with the predetermined data-sharing attributes may not be 7870 // listed in data-sharing attributes clauses, except for the cases 7871 // listed below. For these exceptions only, listing a predetermined 7872 // variable in a data-sharing attribute clause is allowed and overrides 7873 // the variable's predetermined data-sharing attributes. 7874 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 7875 // in a Construct, C/C++, p.2] 7876 // Variables with const-qualified type having no mutable member may be 7877 // listed in a firstprivate clause, even if they are static data members. 7878 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 7879 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 7880 Diag(ELoc, diag::err_omp_wrong_dsa) 7881 << getOpenMPClauseName(DVar.CKind) 7882 << getOpenMPClauseName(OMPC_firstprivate); 7883 ReportOriginalDSA(*this, DSAStack, D, DVar); 7884 continue; 7885 } 7886 7887 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 7888 // OpenMP [2.9.3.4, Restrictions, p.2] 7889 // A list item that is private within a parallel region must not appear 7890 // in a firstprivate clause on a worksharing construct if any of the 7891 // worksharing regions arising from the worksharing construct ever bind 7892 // to any of the parallel regions arising from the parallel construct. 7893 if (isOpenMPWorksharingDirective(CurrDir) && 7894 !isOpenMPParallelDirective(CurrDir)) { 7895 DVar = DSAStack->getImplicitDSA(D, true); 7896 if (DVar.CKind != OMPC_shared && 7897 (isOpenMPParallelDirective(DVar.DKind) || 7898 DVar.DKind == OMPD_unknown)) { 7899 Diag(ELoc, diag::err_omp_required_access) 7900 << getOpenMPClauseName(OMPC_firstprivate) 7901 << getOpenMPClauseName(OMPC_shared); 7902 ReportOriginalDSA(*this, DSAStack, D, DVar); 7903 continue; 7904 } 7905 } 7906 // OpenMP [2.9.3.4, Restrictions, p.3] 7907 // A list item that appears in a reduction clause of a parallel construct 7908 // must not appear in a firstprivate clause on a worksharing or task 7909 // construct if any of the worksharing or task regions arising from the 7910 // worksharing or task construct ever bind to any of the parallel regions 7911 // arising from the parallel construct. 7912 // OpenMP [2.9.3.4, Restrictions, p.4] 7913 // A list item that appears in a reduction clause in worksharing 7914 // construct must not appear in a firstprivate clause in a task construct 7915 // encountered during execution of any of the worksharing regions arising 7916 // from the worksharing construct. 7917 if (isOpenMPTaskingDirective(CurrDir)) { 7918 DVar = DSAStack->hasInnermostDSA( 7919 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 7920 [](OpenMPDirectiveKind K) -> bool { 7921 return isOpenMPParallelDirective(K) || 7922 isOpenMPWorksharingDirective(K); 7923 }, 7924 false); 7925 if (DVar.CKind == OMPC_reduction && 7926 (isOpenMPParallelDirective(DVar.DKind) || 7927 isOpenMPWorksharingDirective(DVar.DKind))) { 7928 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 7929 << getOpenMPDirectiveName(DVar.DKind); 7930 ReportOriginalDSA(*this, DSAStack, D, DVar); 7931 continue; 7932 } 7933 } 7934 7935 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 7936 // A list item that is private within a teams region must not appear in a 7937 // firstprivate clause on a distribute construct if any of the distribute 7938 // regions arising from the distribute construct ever bind to any of the 7939 // teams regions arising from the teams construct. 7940 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 7941 // A list item that appears in a reduction clause of a teams construct 7942 // must not appear in a firstprivate clause on a distribute construct if 7943 // any of the distribute regions arising from the distribute construct 7944 // ever bind to any of the teams regions arising from the teams construct. 7945 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 7946 // A list item may appear in a firstprivate or lastprivate clause but not 7947 // both. 7948 if (CurrDir == OMPD_distribute) { 7949 DVar = DSAStack->hasInnermostDSA( 7950 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_private; }, 7951 [](OpenMPDirectiveKind K) -> bool { 7952 return isOpenMPTeamsDirective(K); 7953 }, 7954 false); 7955 if (DVar.CKind == OMPC_private && isOpenMPTeamsDirective(DVar.DKind)) { 7956 Diag(ELoc, diag::err_omp_firstprivate_distribute_private_teams); 7957 ReportOriginalDSA(*this, DSAStack, D, DVar); 7958 continue; 7959 } 7960 DVar = DSAStack->hasInnermostDSA( 7961 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 7962 [](OpenMPDirectiveKind K) -> bool { 7963 return isOpenMPTeamsDirective(K); 7964 }, 7965 false); 7966 if (DVar.CKind == OMPC_reduction && 7967 isOpenMPTeamsDirective(DVar.DKind)) { 7968 Diag(ELoc, diag::err_omp_firstprivate_distribute_in_teams_reduction); 7969 ReportOriginalDSA(*this, DSAStack, D, DVar); 7970 continue; 7971 } 7972 DVar = DSAStack->getTopDSA(D, false); 7973 if (DVar.CKind == OMPC_lastprivate) { 7974 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); 7975 ReportOriginalDSA(*this, DSAStack, D, DVar); 7976 continue; 7977 } 7978 } 7979 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 7980 // A list item cannot appear in both a map clause and a data-sharing 7981 // attribute clause on the same construct 7982 if (CurrDir == OMPD_target) { 7983 if (DSAStack->checkMappableExprComponentListsForDecl( 7984 VD, /* CurrentRegionOnly = */ true, 7985 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef) 7986 -> bool { return true; })) { 7987 Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) 7988 << getOpenMPClauseName(OMPC_firstprivate) 7989 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 7990 ReportOriginalDSA(*this, DSAStack, D, DVar); 7991 continue; 7992 } 7993 } 7994 } 7995 7996 // Variably modified types are not supported for tasks. 7997 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 7998 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 7999 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 8000 << getOpenMPClauseName(OMPC_firstprivate) << Type 8001 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 8002 bool IsDecl = 8003 !VD || 8004 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8005 Diag(D->getLocation(), 8006 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8007 << D; 8008 continue; 8009 } 8010 8011 Type = Type.getUnqualifiedType(); 8012 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 8013 D->hasAttrs() ? &D->getAttrs() : nullptr); 8014 // Generate helper private variable and initialize it with the value of the 8015 // original variable. The address of the original variable is replaced by 8016 // the address of the new private variable in the CodeGen. This new variable 8017 // is not added to IdResolver, so the code in the OpenMP region uses 8018 // original variable for proper diagnostics and variable capturing. 8019 Expr *VDInitRefExpr = nullptr; 8020 // For arrays generate initializer for single element and replace it by the 8021 // original array element in CodeGen. 8022 if (Type->isArrayType()) { 8023 auto VDInit = 8024 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 8025 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 8026 auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); 8027 ElemType = ElemType.getUnqualifiedType(); 8028 auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 8029 ".firstprivate.temp"); 8030 InitializedEntity Entity = 8031 InitializedEntity::InitializeVariable(VDInitTemp); 8032 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 8033 8034 InitializationSequence InitSeq(*this, Entity, Kind, Init); 8035 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 8036 if (Result.isInvalid()) 8037 VDPrivate->setInvalidDecl(); 8038 else 8039 VDPrivate->setInit(Result.getAs<Expr>()); 8040 // Remove temp variable declaration. 8041 Context.Deallocate(VDInitTemp); 8042 } else { 8043 auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 8044 ".firstprivate.temp"); 8045 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 8046 RefExpr->getExprLoc()); 8047 AddInitializerToDecl(VDPrivate, 8048 DefaultLvalueConversion(VDInitRefExpr).get(), 8049 /*DirectInit=*/false, /*TypeMayContainAuto=*/false); 8050 } 8051 if (VDPrivate->isInvalidDecl()) { 8052 if (IsImplicitClause) { 8053 Diag(RefExpr->getExprLoc(), 8054 diag::note_omp_task_predetermined_firstprivate_here); 8055 } 8056 continue; 8057 } 8058 CurContext->addDecl(VDPrivate); 8059 auto VDPrivateRefExpr = buildDeclRefExpr( 8060 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 8061 RefExpr->getExprLoc()); 8062 DeclRefExpr *Ref = nullptr; 8063 if (!VD) { 8064 if (TopDVar.CKind == OMPC_lastprivate) 8065 Ref = TopDVar.PrivateCopy; 8066 else { 8067 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 8068 if (!IsOpenMPCapturedDecl(D)) 8069 ExprCaptures.push_back(Ref->getDecl()); 8070 } 8071 } 8072 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 8073 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 8074 PrivateCopies.push_back(VDPrivateRefExpr); 8075 Inits.push_back(VDInitRefExpr); 8076 } 8077 8078 if (Vars.empty()) 8079 return nullptr; 8080 8081 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 8082 Vars, PrivateCopies, Inits, 8083 buildPreInits(Context, ExprCaptures)); 8084 } 8085 8086 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 8087 SourceLocation StartLoc, 8088 SourceLocation LParenLoc, 8089 SourceLocation EndLoc) { 8090 SmallVector<Expr *, 8> Vars; 8091 SmallVector<Expr *, 8> SrcExprs; 8092 SmallVector<Expr *, 8> DstExprs; 8093 SmallVector<Expr *, 8> AssignmentOps; 8094 SmallVector<Decl *, 4> ExprCaptures; 8095 SmallVector<Expr *, 4> ExprPostUpdates; 8096 for (auto &RefExpr : VarList) { 8097 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 8098 SourceLocation ELoc; 8099 SourceRange ERange; 8100 Expr *SimpleRefExpr = RefExpr; 8101 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8102 if (Res.second) { 8103 // It will be analyzed later. 8104 Vars.push_back(RefExpr); 8105 SrcExprs.push_back(nullptr); 8106 DstExprs.push_back(nullptr); 8107 AssignmentOps.push_back(nullptr); 8108 } 8109 ValueDecl *D = Res.first; 8110 if (!D) 8111 continue; 8112 8113 QualType Type = D->getType(); 8114 auto *VD = dyn_cast<VarDecl>(D); 8115 8116 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 8117 // A variable that appears in a lastprivate clause must not have an 8118 // incomplete type or a reference type. 8119 if (RequireCompleteType(ELoc, Type, 8120 diag::err_omp_lastprivate_incomplete_type)) 8121 continue; 8122 Type = Type.getNonReferenceType(); 8123 8124 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 8125 // in a Construct] 8126 // Variables with the predetermined data-sharing attributes may not be 8127 // listed in data-sharing attributes clauses, except for the cases 8128 // listed below. 8129 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8130 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 8131 DVar.CKind != OMPC_firstprivate && 8132 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 8133 Diag(ELoc, diag::err_omp_wrong_dsa) 8134 << getOpenMPClauseName(DVar.CKind) 8135 << getOpenMPClauseName(OMPC_lastprivate); 8136 ReportOriginalDSA(*this, DSAStack, D, DVar); 8137 continue; 8138 } 8139 8140 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 8141 // OpenMP [2.14.3.5, Restrictions, p.2] 8142 // A list item that is private within a parallel region, or that appears in 8143 // the reduction clause of a parallel construct, must not appear in a 8144 // lastprivate clause on a worksharing construct if any of the corresponding 8145 // worksharing regions ever binds to any of the corresponding parallel 8146 // regions. 8147 DSAStackTy::DSAVarData TopDVar = DVar; 8148 if (isOpenMPWorksharingDirective(CurrDir) && 8149 !isOpenMPParallelDirective(CurrDir)) { 8150 DVar = DSAStack->getImplicitDSA(D, true); 8151 if (DVar.CKind != OMPC_shared) { 8152 Diag(ELoc, diag::err_omp_required_access) 8153 << getOpenMPClauseName(OMPC_lastprivate) 8154 << getOpenMPClauseName(OMPC_shared); 8155 ReportOriginalDSA(*this, DSAStack, D, DVar); 8156 continue; 8157 } 8158 } 8159 8160 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 8161 // A list item may appear in a firstprivate or lastprivate clause but not 8162 // both. 8163 if (CurrDir == OMPD_distribute) { 8164 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8165 if (DVar.CKind == OMPC_firstprivate) { 8166 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); 8167 ReportOriginalDSA(*this, DSAStack, D, DVar); 8168 continue; 8169 } 8170 } 8171 8172 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 8173 // A variable of class type (or array thereof) that appears in a 8174 // lastprivate clause requires an accessible, unambiguous default 8175 // constructor for the class type, unless the list item is also specified 8176 // in a firstprivate clause. 8177 // A variable of class type (or array thereof) that appears in a 8178 // lastprivate clause requires an accessible, unambiguous copy assignment 8179 // operator for the class type. 8180 Type = Context.getBaseElementType(Type).getNonReferenceType(); 8181 auto *SrcVD = buildVarDecl(*this, ERange.getBegin(), 8182 Type.getUnqualifiedType(), ".lastprivate.src", 8183 D->hasAttrs() ? &D->getAttrs() : nullptr); 8184 auto *PseudoSrcExpr = 8185 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 8186 auto *DstVD = 8187 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 8188 D->hasAttrs() ? &D->getAttrs() : nullptr); 8189 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 8190 // For arrays generate assignment operation for single element and replace 8191 // it by the original array element in CodeGen. 8192 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 8193 PseudoDstExpr, PseudoSrcExpr); 8194 if (AssignmentOp.isInvalid()) 8195 continue; 8196 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 8197 /*DiscardedValue=*/true); 8198 if (AssignmentOp.isInvalid()) 8199 continue; 8200 8201 DeclRefExpr *Ref = nullptr; 8202 if (!VD) { 8203 if (TopDVar.CKind == OMPC_firstprivate) 8204 Ref = TopDVar.PrivateCopy; 8205 else { 8206 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 8207 if (!IsOpenMPCapturedDecl(D)) 8208 ExprCaptures.push_back(Ref->getDecl()); 8209 } 8210 if (TopDVar.CKind == OMPC_firstprivate || 8211 (!IsOpenMPCapturedDecl(D) && 8212 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 8213 ExprResult RefRes = DefaultLvalueConversion(Ref); 8214 if (!RefRes.isUsable()) 8215 continue; 8216 ExprResult PostUpdateRes = 8217 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 8218 RefRes.get()); 8219 if (!PostUpdateRes.isUsable()) 8220 continue; 8221 ExprPostUpdates.push_back( 8222 IgnoredValueConversions(PostUpdateRes.get()).get()); 8223 } 8224 } 8225 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 8226 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 8227 SrcExprs.push_back(PseudoSrcExpr); 8228 DstExprs.push_back(PseudoDstExpr); 8229 AssignmentOps.push_back(AssignmentOp.get()); 8230 } 8231 8232 if (Vars.empty()) 8233 return nullptr; 8234 8235 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 8236 Vars, SrcExprs, DstExprs, AssignmentOps, 8237 buildPreInits(Context, ExprCaptures), 8238 buildPostUpdate(*this, ExprPostUpdates)); 8239 } 8240 8241 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 8242 SourceLocation StartLoc, 8243 SourceLocation LParenLoc, 8244 SourceLocation EndLoc) { 8245 SmallVector<Expr *, 8> Vars; 8246 for (auto &RefExpr : VarList) { 8247 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 8248 SourceLocation ELoc; 8249 SourceRange ERange; 8250 Expr *SimpleRefExpr = RefExpr; 8251 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8252 if (Res.second) { 8253 // It will be analyzed later. 8254 Vars.push_back(RefExpr); 8255 } 8256 ValueDecl *D = Res.first; 8257 if (!D) 8258 continue; 8259 8260 auto *VD = dyn_cast<VarDecl>(D); 8261 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8262 // in a Construct] 8263 // Variables with the predetermined data-sharing attributes may not be 8264 // listed in data-sharing attributes clauses, except for the cases 8265 // listed below. For these exceptions only, listing a predetermined 8266 // variable in a data-sharing attribute clause is allowed and overrides 8267 // the variable's predetermined data-sharing attributes. 8268 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8269 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 8270 DVar.RefExpr) { 8271 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 8272 << getOpenMPClauseName(OMPC_shared); 8273 ReportOriginalDSA(*this, DSAStack, D, DVar); 8274 continue; 8275 } 8276 8277 DeclRefExpr *Ref = nullptr; 8278 if (!VD && IsOpenMPCapturedDecl(D)) 8279 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 8280 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 8281 Vars.push_back((VD || !Ref) ? RefExpr->IgnoreParens() : Ref); 8282 } 8283 8284 if (Vars.empty()) 8285 return nullptr; 8286 8287 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 8288 } 8289 8290 namespace { 8291 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 8292 DSAStackTy *Stack; 8293 8294 public: 8295 bool VisitDeclRefExpr(DeclRefExpr *E) { 8296 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { 8297 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false); 8298 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 8299 return false; 8300 if (DVar.CKind != OMPC_unknown) 8301 return true; 8302 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 8303 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, 8304 false); 8305 if (DVarPrivate.CKind != OMPC_unknown) 8306 return true; 8307 return false; 8308 } 8309 return false; 8310 } 8311 bool VisitStmt(Stmt *S) { 8312 for (auto Child : S->children()) { 8313 if (Child && Visit(Child)) 8314 return true; 8315 } 8316 return false; 8317 } 8318 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 8319 }; 8320 } // namespace 8321 8322 namespace { 8323 // Transform MemberExpression for specified FieldDecl of current class to 8324 // DeclRefExpr to specified OMPCapturedExprDecl. 8325 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 8326 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 8327 ValueDecl *Field; 8328 DeclRefExpr *CapturedExpr; 8329 8330 public: 8331 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 8332 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 8333 8334 ExprResult TransformMemberExpr(MemberExpr *E) { 8335 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 8336 E->getMemberDecl() == Field) { 8337 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 8338 return CapturedExpr; 8339 } 8340 return BaseTransform::TransformMemberExpr(E); 8341 } 8342 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 8343 }; 8344 } // namespace 8345 8346 template <typename T> 8347 static T filterLookupForUDR(SmallVectorImpl<UnresolvedSet<8>> &Lookups, 8348 const llvm::function_ref<T(ValueDecl *)> &Gen) { 8349 for (auto &Set : Lookups) { 8350 for (auto *D : Set) { 8351 if (auto Res = Gen(cast<ValueDecl>(D))) 8352 return Res; 8353 } 8354 } 8355 return T(); 8356 } 8357 8358 static ExprResult 8359 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 8360 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 8361 const DeclarationNameInfo &ReductionId, QualType Ty, 8362 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 8363 if (ReductionIdScopeSpec.isInvalid()) 8364 return ExprError(); 8365 SmallVector<UnresolvedSet<8>, 4> Lookups; 8366 if (S) { 8367 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 8368 Lookup.suppressDiagnostics(); 8369 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 8370 auto *D = Lookup.getRepresentativeDecl(); 8371 do { 8372 S = S->getParent(); 8373 } while (S && !S->isDeclScope(D)); 8374 if (S) 8375 S = S->getParent(); 8376 Lookups.push_back(UnresolvedSet<8>()); 8377 Lookups.back().append(Lookup.begin(), Lookup.end()); 8378 Lookup.clear(); 8379 } 8380 } else if (auto *ULE = 8381 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 8382 Lookups.push_back(UnresolvedSet<8>()); 8383 Decl *PrevD = nullptr; 8384 for(auto *D : ULE->decls()) { 8385 if (D == PrevD) 8386 Lookups.push_back(UnresolvedSet<8>()); 8387 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) 8388 Lookups.back().addDecl(DRD); 8389 PrevD = D; 8390 } 8391 } 8392 if (Ty->isDependentType() || Ty->isInstantiationDependentType() || 8393 Ty->containsUnexpandedParameterPack() || 8394 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool { 8395 return !D->isInvalidDecl() && 8396 (D->getType()->isDependentType() || 8397 D->getType()->isInstantiationDependentType() || 8398 D->getType()->containsUnexpandedParameterPack()); 8399 })) { 8400 UnresolvedSet<8> ResSet; 8401 for (auto &Set : Lookups) { 8402 ResSet.append(Set.begin(), Set.end()); 8403 // The last item marks the end of all declarations at the specified scope. 8404 ResSet.addDecl(Set[Set.size() - 1]); 8405 } 8406 return UnresolvedLookupExpr::Create( 8407 SemaRef.Context, /*NamingClass=*/nullptr, 8408 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 8409 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 8410 } 8411 if (auto *VD = filterLookupForUDR<ValueDecl *>( 8412 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 8413 if (!D->isInvalidDecl() && 8414 SemaRef.Context.hasSameType(D->getType(), Ty)) 8415 return D; 8416 return nullptr; 8417 })) 8418 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 8419 if (auto *VD = filterLookupForUDR<ValueDecl *>( 8420 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 8421 if (!D->isInvalidDecl() && 8422 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 8423 !Ty.isMoreQualifiedThan(D->getType())) 8424 return D; 8425 return nullptr; 8426 })) { 8427 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 8428 /*DetectVirtual=*/false); 8429 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 8430 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 8431 VD->getType().getUnqualifiedType()))) { 8432 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), 8433 /*DiagID=*/0) != 8434 Sema::AR_inaccessible) { 8435 SemaRef.BuildBasePathArray(Paths, BasePath); 8436 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 8437 } 8438 } 8439 } 8440 } 8441 if (ReductionIdScopeSpec.isSet()) { 8442 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 8443 return ExprError(); 8444 } 8445 return ExprEmpty(); 8446 } 8447 8448 OMPClause *Sema::ActOnOpenMPReductionClause( 8449 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 8450 SourceLocation ColonLoc, SourceLocation EndLoc, 8451 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 8452 ArrayRef<Expr *> UnresolvedReductions) { 8453 auto DN = ReductionId.getName(); 8454 auto OOK = DN.getCXXOverloadedOperator(); 8455 BinaryOperatorKind BOK = BO_Comma; 8456 8457 // OpenMP [2.14.3.6, reduction clause] 8458 // C 8459 // reduction-identifier is either an identifier or one of the following 8460 // operators: +, -, *, &, |, ^, && and || 8461 // C++ 8462 // reduction-identifier is either an id-expression or one of the following 8463 // operators: +, -, *, &, |, ^, && and || 8464 // FIXME: Only 'min' and 'max' identifiers are supported for now. 8465 switch (OOK) { 8466 case OO_Plus: 8467 case OO_Minus: 8468 BOK = BO_Add; 8469 break; 8470 case OO_Star: 8471 BOK = BO_Mul; 8472 break; 8473 case OO_Amp: 8474 BOK = BO_And; 8475 break; 8476 case OO_Pipe: 8477 BOK = BO_Or; 8478 break; 8479 case OO_Caret: 8480 BOK = BO_Xor; 8481 break; 8482 case OO_AmpAmp: 8483 BOK = BO_LAnd; 8484 break; 8485 case OO_PipePipe: 8486 BOK = BO_LOr; 8487 break; 8488 case OO_New: 8489 case OO_Delete: 8490 case OO_Array_New: 8491 case OO_Array_Delete: 8492 case OO_Slash: 8493 case OO_Percent: 8494 case OO_Tilde: 8495 case OO_Exclaim: 8496 case OO_Equal: 8497 case OO_Less: 8498 case OO_Greater: 8499 case OO_LessEqual: 8500 case OO_GreaterEqual: 8501 case OO_PlusEqual: 8502 case OO_MinusEqual: 8503 case OO_StarEqual: 8504 case OO_SlashEqual: 8505 case OO_PercentEqual: 8506 case OO_CaretEqual: 8507 case OO_AmpEqual: 8508 case OO_PipeEqual: 8509 case OO_LessLess: 8510 case OO_GreaterGreater: 8511 case OO_LessLessEqual: 8512 case OO_GreaterGreaterEqual: 8513 case OO_EqualEqual: 8514 case OO_ExclaimEqual: 8515 case OO_PlusPlus: 8516 case OO_MinusMinus: 8517 case OO_Comma: 8518 case OO_ArrowStar: 8519 case OO_Arrow: 8520 case OO_Call: 8521 case OO_Subscript: 8522 case OO_Conditional: 8523 case OO_Coawait: 8524 case NUM_OVERLOADED_OPERATORS: 8525 llvm_unreachable("Unexpected reduction identifier"); 8526 case OO_None: 8527 if (auto II = DN.getAsIdentifierInfo()) { 8528 if (II->isStr("max")) 8529 BOK = BO_GT; 8530 else if (II->isStr("min")) 8531 BOK = BO_LT; 8532 } 8533 break; 8534 } 8535 SourceRange ReductionIdRange; 8536 if (ReductionIdScopeSpec.isValid()) 8537 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 8538 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 8539 8540 SmallVector<Expr *, 8> Vars; 8541 SmallVector<Expr *, 8> Privates; 8542 SmallVector<Expr *, 8> LHSs; 8543 SmallVector<Expr *, 8> RHSs; 8544 SmallVector<Expr *, 8> ReductionOps; 8545 SmallVector<Decl *, 4> ExprCaptures; 8546 SmallVector<Expr *, 4> ExprPostUpdates; 8547 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 8548 bool FirstIter = true; 8549 for (auto RefExpr : VarList) { 8550 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 8551 // OpenMP [2.1, C/C++] 8552 // A list item is a variable or array section, subject to the restrictions 8553 // specified in Section 2.4 on page 42 and in each of the sections 8554 // describing clauses and directives for which a list appears. 8555 // OpenMP [2.14.3.3, Restrictions, p.1] 8556 // A variable that is part of another variable (as an array or 8557 // structure element) cannot appear in a private clause. 8558 if (!FirstIter && IR != ER) 8559 ++IR; 8560 FirstIter = false; 8561 SourceLocation ELoc; 8562 SourceRange ERange; 8563 Expr *SimpleRefExpr = RefExpr; 8564 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 8565 /*AllowArraySection=*/true); 8566 if (Res.second) { 8567 // It will be analyzed later. 8568 Vars.push_back(RefExpr); 8569 Privates.push_back(nullptr); 8570 LHSs.push_back(nullptr); 8571 RHSs.push_back(nullptr); 8572 // Try to find 'declare reduction' corresponding construct before using 8573 // builtin/overloaded operators. 8574 QualType Type = Context.DependentTy; 8575 CXXCastPath BasePath; 8576 ExprResult DeclareReductionRef = buildDeclareReductionRef( 8577 *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, 8578 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 8579 if (CurContext->isDependentContext() && 8580 (DeclareReductionRef.isUnset() || 8581 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 8582 ReductionOps.push_back(DeclareReductionRef.get()); 8583 else 8584 ReductionOps.push_back(nullptr); 8585 } 8586 ValueDecl *D = Res.first; 8587 if (!D) 8588 continue; 8589 8590 QualType Type; 8591 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 8592 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 8593 if (ASE) 8594 Type = ASE->getType().getNonReferenceType(); 8595 else if (OASE) { 8596 auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 8597 if (auto *ATy = BaseType->getAsArrayTypeUnsafe()) 8598 Type = ATy->getElementType(); 8599 else 8600 Type = BaseType->getPointeeType(); 8601 Type = Type.getNonReferenceType(); 8602 } else 8603 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 8604 auto *VD = dyn_cast<VarDecl>(D); 8605 8606 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 8607 // A variable that appears in a private clause must not have an incomplete 8608 // type or a reference type. 8609 if (RequireCompleteType(ELoc, Type, 8610 diag::err_omp_reduction_incomplete_type)) 8611 continue; 8612 // OpenMP [2.14.3.6, reduction clause, Restrictions] 8613 // A list item that appears in a reduction clause must not be 8614 // const-qualified. 8615 if (Type.getNonReferenceType().isConstant(Context)) { 8616 Diag(ELoc, diag::err_omp_const_reduction_list_item) 8617 << getOpenMPClauseName(OMPC_reduction) << Type << ERange; 8618 if (!ASE && !OASE) { 8619 bool IsDecl = !VD || 8620 VD->isThisDeclarationADefinition(Context) == 8621 VarDecl::DeclarationOnly; 8622 Diag(D->getLocation(), 8623 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8624 << D; 8625 } 8626 continue; 8627 } 8628 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 8629 // If a list-item is a reference type then it must bind to the same object 8630 // for all threads of the team. 8631 if (!ASE && !OASE && VD) { 8632 VarDecl *VDDef = VD->getDefinition(); 8633 if (VD->getType()->isReferenceType() && VDDef) { 8634 DSARefChecker Check(DSAStack); 8635 if (Check.Visit(VDDef->getInit())) { 8636 Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; 8637 Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 8638 continue; 8639 } 8640 } 8641 } 8642 8643 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 8644 // in a Construct] 8645 // Variables with the predetermined data-sharing attributes may not be 8646 // listed in data-sharing attributes clauses, except for the cases 8647 // listed below. For these exceptions only, listing a predetermined 8648 // variable in a data-sharing attribute clause is allowed and overrides 8649 // the variable's predetermined data-sharing attributes. 8650 // OpenMP [2.14.3.6, Restrictions, p.3] 8651 // Any number of reduction clauses can be specified on the directive, 8652 // but a list item can appear only once in the reduction clauses for that 8653 // directive. 8654 DSAStackTy::DSAVarData DVar; 8655 DVar = DSAStack->getTopDSA(D, false); 8656 if (DVar.CKind == OMPC_reduction) { 8657 Diag(ELoc, diag::err_omp_once_referenced) 8658 << getOpenMPClauseName(OMPC_reduction); 8659 if (DVar.RefExpr) 8660 Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 8661 } else if (DVar.CKind != OMPC_unknown) { 8662 Diag(ELoc, diag::err_omp_wrong_dsa) 8663 << getOpenMPClauseName(DVar.CKind) 8664 << getOpenMPClauseName(OMPC_reduction); 8665 ReportOriginalDSA(*this, DSAStack, D, DVar); 8666 continue; 8667 } 8668 8669 // OpenMP [2.14.3.6, Restrictions, p.1] 8670 // A list item that appears in a reduction clause of a worksharing 8671 // construct must be shared in the parallel regions to which any of the 8672 // worksharing regions arising from the worksharing construct bind. 8673 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 8674 if (isOpenMPWorksharingDirective(CurrDir) && 8675 !isOpenMPParallelDirective(CurrDir)) { 8676 DVar = DSAStack->getImplicitDSA(D, true); 8677 if (DVar.CKind != OMPC_shared) { 8678 Diag(ELoc, diag::err_omp_required_access) 8679 << getOpenMPClauseName(OMPC_reduction) 8680 << getOpenMPClauseName(OMPC_shared); 8681 ReportOriginalDSA(*this, DSAStack, D, DVar); 8682 continue; 8683 } 8684 } 8685 8686 // Try to find 'declare reduction' corresponding construct before using 8687 // builtin/overloaded operators. 8688 CXXCastPath BasePath; 8689 ExprResult DeclareReductionRef = buildDeclareReductionRef( 8690 *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, 8691 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 8692 if (DeclareReductionRef.isInvalid()) 8693 continue; 8694 if (CurContext->isDependentContext() && 8695 (DeclareReductionRef.isUnset() || 8696 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 8697 Vars.push_back(RefExpr); 8698 Privates.push_back(nullptr); 8699 LHSs.push_back(nullptr); 8700 RHSs.push_back(nullptr); 8701 ReductionOps.push_back(DeclareReductionRef.get()); 8702 continue; 8703 } 8704 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 8705 // Not allowed reduction identifier is found. 8706 Diag(ReductionId.getLocStart(), 8707 diag::err_omp_unknown_reduction_identifier) 8708 << Type << ReductionIdRange; 8709 continue; 8710 } 8711 8712 // OpenMP [2.14.3.6, reduction clause, Restrictions] 8713 // The type of a list item that appears in a reduction clause must be valid 8714 // for the reduction-identifier. For a max or min reduction in C, the type 8715 // of the list item must be an allowed arithmetic data type: char, int, 8716 // float, double, or _Bool, possibly modified with long, short, signed, or 8717 // unsigned. For a max or min reduction in C++, the type of the list item 8718 // must be an allowed arithmetic data type: char, wchar_t, int, float, 8719 // double, or bool, possibly modified with long, short, signed, or unsigned. 8720 if (DeclareReductionRef.isUnset()) { 8721 if ((BOK == BO_GT || BOK == BO_LT) && 8722 !(Type->isScalarType() || 8723 (getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 8724 Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 8725 << getLangOpts().CPlusPlus; 8726 if (!ASE && !OASE) { 8727 bool IsDecl = !VD || 8728 VD->isThisDeclarationADefinition(Context) == 8729 VarDecl::DeclarationOnly; 8730 Diag(D->getLocation(), 8731 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8732 << D; 8733 } 8734 continue; 8735 } 8736 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 8737 !getLangOpts().CPlusPlus && Type->isFloatingType()) { 8738 Diag(ELoc, diag::err_omp_clause_floating_type_arg); 8739 if (!ASE && !OASE) { 8740 bool IsDecl = !VD || 8741 VD->isThisDeclarationADefinition(Context) == 8742 VarDecl::DeclarationOnly; 8743 Diag(D->getLocation(), 8744 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8745 << D; 8746 } 8747 continue; 8748 } 8749 } 8750 8751 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 8752 auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs", 8753 D->hasAttrs() ? &D->getAttrs() : nullptr); 8754 auto *RHSVD = buildVarDecl(*this, ELoc, Type, D->getName(), 8755 D->hasAttrs() ? &D->getAttrs() : nullptr); 8756 auto PrivateTy = Type; 8757 if (OASE || 8758 (!ASE && 8759 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 8760 // For arays/array sections only: 8761 // Create pseudo array type for private copy. The size for this array will 8762 // be generated during codegen. 8763 // For array subscripts or single variables Private Ty is the same as Type 8764 // (type of the variable or single array element). 8765 PrivateTy = Context.getVariableArrayType( 8766 Type, new (Context) OpaqueValueExpr(SourceLocation(), 8767 Context.getSizeType(), VK_RValue), 8768 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 8769 } else if (!ASE && !OASE && 8770 Context.getAsArrayType(D->getType().getNonReferenceType())) 8771 PrivateTy = D->getType().getNonReferenceType(); 8772 // Private copy. 8773 auto *PrivateVD = buildVarDecl(*this, ELoc, PrivateTy, D->getName(), 8774 D->hasAttrs() ? &D->getAttrs() : nullptr); 8775 // Add initializer for private variable. 8776 Expr *Init = nullptr; 8777 auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc); 8778 auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc); 8779 if (DeclareReductionRef.isUsable()) { 8780 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 8781 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 8782 if (DRD->getInitializer()) { 8783 Init = DRDRef; 8784 RHSVD->setInit(DRDRef); 8785 RHSVD->setInitStyle(VarDecl::CallInit); 8786 } 8787 } else { 8788 switch (BOK) { 8789 case BO_Add: 8790 case BO_Xor: 8791 case BO_Or: 8792 case BO_LOr: 8793 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 8794 if (Type->isScalarType() || Type->isAnyComplexType()) 8795 Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 8796 break; 8797 case BO_Mul: 8798 case BO_LAnd: 8799 if (Type->isScalarType() || Type->isAnyComplexType()) { 8800 // '*' and '&&' reduction ops - initializer is '1'. 8801 Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 8802 } 8803 break; 8804 case BO_And: { 8805 // '&' reduction op - initializer is '~0'. 8806 QualType OrigType = Type; 8807 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 8808 Type = ComplexTy->getElementType(); 8809 if (Type->isRealFloatingType()) { 8810 llvm::APFloat InitValue = 8811 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 8812 /*isIEEE=*/true); 8813 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 8814 Type, ELoc); 8815 } else if (Type->isScalarType()) { 8816 auto Size = Context.getTypeSize(Type); 8817 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 8818 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 8819 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 8820 } 8821 if (Init && OrigType->isAnyComplexType()) { 8822 // Init = 0xFFFF + 0xFFFFi; 8823 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 8824 Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 8825 } 8826 Type = OrigType; 8827 break; 8828 } 8829 case BO_LT: 8830 case BO_GT: { 8831 // 'min' reduction op - initializer is 'Largest representable number in 8832 // the reduction list item type'. 8833 // 'max' reduction op - initializer is 'Least representable number in 8834 // the reduction list item type'. 8835 if (Type->isIntegerType() || Type->isPointerType()) { 8836 bool IsSigned = Type->hasSignedIntegerRepresentation(); 8837 auto Size = Context.getTypeSize(Type); 8838 QualType IntTy = 8839 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 8840 llvm::APInt InitValue = 8841 (BOK != BO_LT) 8842 ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 8843 : llvm::APInt::getMinValue(Size) 8844 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 8845 : llvm::APInt::getMaxValue(Size); 8846 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 8847 if (Type->isPointerType()) { 8848 // Cast to pointer type. 8849 auto CastExpr = BuildCStyleCastExpr( 8850 SourceLocation(), Context.getTrivialTypeSourceInfo(Type, ELoc), 8851 SourceLocation(), Init); 8852 if (CastExpr.isInvalid()) 8853 continue; 8854 Init = CastExpr.get(); 8855 } 8856 } else if (Type->isRealFloatingType()) { 8857 llvm::APFloat InitValue = llvm::APFloat::getLargest( 8858 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 8859 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 8860 Type, ELoc); 8861 } 8862 break; 8863 } 8864 case BO_PtrMemD: 8865 case BO_PtrMemI: 8866 case BO_MulAssign: 8867 case BO_Div: 8868 case BO_Rem: 8869 case BO_Sub: 8870 case BO_Shl: 8871 case BO_Shr: 8872 case BO_LE: 8873 case BO_GE: 8874 case BO_EQ: 8875 case BO_NE: 8876 case BO_AndAssign: 8877 case BO_XorAssign: 8878 case BO_OrAssign: 8879 case BO_Assign: 8880 case BO_AddAssign: 8881 case BO_SubAssign: 8882 case BO_DivAssign: 8883 case BO_RemAssign: 8884 case BO_ShlAssign: 8885 case BO_ShrAssign: 8886 case BO_Comma: 8887 llvm_unreachable("Unexpected reduction operation"); 8888 } 8889 } 8890 if (Init && DeclareReductionRef.isUnset()) { 8891 AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false, 8892 /*TypeMayContainAuto=*/false); 8893 } else if (!Init) 8894 ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false); 8895 if (RHSVD->isInvalidDecl()) 8896 continue; 8897 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 8898 Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type 8899 << ReductionIdRange; 8900 bool IsDecl = 8901 !VD || 8902 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8903 Diag(D->getLocation(), 8904 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8905 << D; 8906 continue; 8907 } 8908 // Store initializer for single element in private copy. Will be used during 8909 // codegen. 8910 PrivateVD->setInit(RHSVD->getInit()); 8911 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 8912 auto *PrivateDRE = buildDeclRefExpr(*this, PrivateVD, PrivateTy, ELoc); 8913 ExprResult ReductionOp; 8914 if (DeclareReductionRef.isUsable()) { 8915 QualType RedTy = DeclareReductionRef.get()->getType(); 8916 QualType PtrRedTy = Context.getPointerType(RedTy); 8917 ExprResult LHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 8918 ExprResult RHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 8919 if (!BasePath.empty()) { 8920 LHS = DefaultLvalueConversion(LHS.get()); 8921 RHS = DefaultLvalueConversion(RHS.get()); 8922 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 8923 CK_UncheckedDerivedToBase, LHS.get(), 8924 &BasePath, LHS.get()->getValueKind()); 8925 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 8926 CK_UncheckedDerivedToBase, RHS.get(), 8927 &BasePath, RHS.get()->getValueKind()); 8928 } 8929 FunctionProtoType::ExtProtoInfo EPI; 8930 QualType Params[] = {PtrRedTy, PtrRedTy}; 8931 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 8932 auto *OVE = new (Context) OpaqueValueExpr( 8933 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 8934 DefaultLvalueConversion(DeclareReductionRef.get()).get()); 8935 Expr *Args[] = {LHS.get(), RHS.get()}; 8936 ReductionOp = new (Context) 8937 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 8938 } else { 8939 ReductionOp = BuildBinOp(DSAStack->getCurScope(), 8940 ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE); 8941 if (ReductionOp.isUsable()) { 8942 if (BOK != BO_LT && BOK != BO_GT) { 8943 ReductionOp = 8944 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 8945 BO_Assign, LHSDRE, ReductionOp.get()); 8946 } else { 8947 auto *ConditionalOp = new (Context) ConditionalOperator( 8948 ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(), 8949 RHSDRE, Type, VK_LValue, OK_Ordinary); 8950 ReductionOp = 8951 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 8952 BO_Assign, LHSDRE, ConditionalOp); 8953 } 8954 ReductionOp = ActOnFinishFullExpr(ReductionOp.get()); 8955 } 8956 if (ReductionOp.isInvalid()) 8957 continue; 8958 } 8959 8960 DeclRefExpr *Ref = nullptr; 8961 Expr *VarsExpr = RefExpr->IgnoreParens(); 8962 if (!VD) { 8963 if (ASE || OASE) { 8964 TransformExprToCaptures RebuildToCapture(*this, D); 8965 VarsExpr = 8966 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 8967 Ref = RebuildToCapture.getCapturedExpr(); 8968 } else { 8969 VarsExpr = Ref = 8970 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 8971 } 8972 if (!IsOpenMPCapturedDecl(D)) { 8973 ExprCaptures.push_back(Ref->getDecl()); 8974 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 8975 ExprResult RefRes = DefaultLvalueConversion(Ref); 8976 if (!RefRes.isUsable()) 8977 continue; 8978 ExprResult PostUpdateRes = 8979 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 8980 SimpleRefExpr, RefRes.get()); 8981 if (!PostUpdateRes.isUsable()) 8982 continue; 8983 ExprPostUpdates.push_back( 8984 IgnoredValueConversions(PostUpdateRes.get()).get()); 8985 } 8986 } 8987 } 8988 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 8989 Vars.push_back(VarsExpr); 8990 Privates.push_back(PrivateDRE); 8991 LHSs.push_back(LHSDRE); 8992 RHSs.push_back(RHSDRE); 8993 ReductionOps.push_back(ReductionOp.get()); 8994 } 8995 8996 if (Vars.empty()) 8997 return nullptr; 8998 8999 return OMPReductionClause::Create( 9000 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars, 9001 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates, 9002 LHSs, RHSs, ReductionOps, buildPreInits(Context, ExprCaptures), 9003 buildPostUpdate(*this, ExprPostUpdates)); 9004 } 9005 9006 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 9007 SourceLocation LinLoc) { 9008 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 9009 LinKind == OMPC_LINEAR_unknown) { 9010 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 9011 return true; 9012 } 9013 return false; 9014 } 9015 9016 bool Sema::CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, 9017 OpenMPLinearClauseKind LinKind, 9018 QualType Type) { 9019 auto *VD = dyn_cast_or_null<VarDecl>(D); 9020 // A variable must not have an incomplete type or a reference type. 9021 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 9022 return true; 9023 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 9024 !Type->isReferenceType()) { 9025 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 9026 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 9027 return true; 9028 } 9029 Type = Type.getNonReferenceType(); 9030 9031 // A list item must not be const-qualified. 9032 if (Type.isConstant(Context)) { 9033 Diag(ELoc, diag::err_omp_const_variable) 9034 << getOpenMPClauseName(OMPC_linear); 9035 if (D) { 9036 bool IsDecl = 9037 !VD || 9038 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9039 Diag(D->getLocation(), 9040 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9041 << D; 9042 } 9043 return true; 9044 } 9045 9046 // A list item must be of integral or pointer type. 9047 Type = Type.getUnqualifiedType().getCanonicalType(); 9048 const auto *Ty = Type.getTypePtrOrNull(); 9049 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 9050 !Ty->isPointerType())) { 9051 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 9052 if (D) { 9053 bool IsDecl = 9054 !VD || 9055 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9056 Diag(D->getLocation(), 9057 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9058 << D; 9059 } 9060 return true; 9061 } 9062 return false; 9063 } 9064 9065 OMPClause *Sema::ActOnOpenMPLinearClause( 9066 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 9067 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 9068 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 9069 SmallVector<Expr *, 8> Vars; 9070 SmallVector<Expr *, 8> Privates; 9071 SmallVector<Expr *, 8> Inits; 9072 SmallVector<Decl *, 4> ExprCaptures; 9073 SmallVector<Expr *, 4> ExprPostUpdates; 9074 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 9075 LinKind = OMPC_LINEAR_val; 9076 for (auto &RefExpr : VarList) { 9077 assert(RefExpr && "NULL expr in OpenMP linear clause."); 9078 SourceLocation ELoc; 9079 SourceRange ERange; 9080 Expr *SimpleRefExpr = RefExpr; 9081 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 9082 /*AllowArraySection=*/false); 9083 if (Res.second) { 9084 // It will be analyzed later. 9085 Vars.push_back(RefExpr); 9086 Privates.push_back(nullptr); 9087 Inits.push_back(nullptr); 9088 } 9089 ValueDecl *D = Res.first; 9090 if (!D) 9091 continue; 9092 9093 QualType Type = D->getType(); 9094 auto *VD = dyn_cast<VarDecl>(D); 9095 9096 // OpenMP [2.14.3.7, linear clause] 9097 // A list-item cannot appear in more than one linear clause. 9098 // A list-item that appears in a linear clause cannot appear in any 9099 // other data-sharing attribute clause. 9100 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 9101 if (DVar.RefExpr) { 9102 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 9103 << getOpenMPClauseName(OMPC_linear); 9104 ReportOriginalDSA(*this, DSAStack, D, DVar); 9105 continue; 9106 } 9107 9108 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 9109 continue; 9110 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 9111 9112 // Build private copy of original var. 9113 auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(), 9114 D->hasAttrs() ? &D->getAttrs() : nullptr); 9115 auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 9116 // Build var to save initial value. 9117 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 9118 Expr *InitExpr; 9119 DeclRefExpr *Ref = nullptr; 9120 if (!VD) { 9121 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 9122 if (!IsOpenMPCapturedDecl(D)) { 9123 ExprCaptures.push_back(Ref->getDecl()); 9124 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 9125 ExprResult RefRes = DefaultLvalueConversion(Ref); 9126 if (!RefRes.isUsable()) 9127 continue; 9128 ExprResult PostUpdateRes = 9129 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 9130 SimpleRefExpr, RefRes.get()); 9131 if (!PostUpdateRes.isUsable()) 9132 continue; 9133 ExprPostUpdates.push_back( 9134 IgnoredValueConversions(PostUpdateRes.get()).get()); 9135 } 9136 } 9137 } 9138 if (LinKind == OMPC_LINEAR_uval) 9139 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 9140 else 9141 InitExpr = VD ? SimpleRefExpr : Ref; 9142 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 9143 /*DirectInit=*/false, /*TypeMayContainAuto=*/false); 9144 auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 9145 9146 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 9147 Vars.push_back(VD ? RefExpr->IgnoreParens() : Ref); 9148 Privates.push_back(PrivateRef); 9149 Inits.push_back(InitRef); 9150 } 9151 9152 if (Vars.empty()) 9153 return nullptr; 9154 9155 Expr *StepExpr = Step; 9156 Expr *CalcStepExpr = nullptr; 9157 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 9158 !Step->isInstantiationDependent() && 9159 !Step->containsUnexpandedParameterPack()) { 9160 SourceLocation StepLoc = Step->getLocStart(); 9161 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 9162 if (Val.isInvalid()) 9163 return nullptr; 9164 StepExpr = Val.get(); 9165 9166 // Build var to save the step value. 9167 VarDecl *SaveVar = 9168 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 9169 ExprResult SaveRef = 9170 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 9171 ExprResult CalcStep = 9172 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 9173 CalcStep = ActOnFinishFullExpr(CalcStep.get()); 9174 9175 // Warn about zero linear step (it would be probably better specified as 9176 // making corresponding variables 'const'). 9177 llvm::APSInt Result; 9178 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 9179 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 9180 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 9181 << (Vars.size() > 1); 9182 if (!IsConstant && CalcStep.isUsable()) { 9183 // Calculate the step beforehand instead of doing this on each iteration. 9184 // (This is not used if the number of iterations may be kfold-ed). 9185 CalcStepExpr = CalcStep.get(); 9186 } 9187 } 9188 9189 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 9190 ColonLoc, EndLoc, Vars, Privates, Inits, 9191 StepExpr, CalcStepExpr, 9192 buildPreInits(Context, ExprCaptures), 9193 buildPostUpdate(*this, ExprPostUpdates)); 9194 } 9195 9196 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 9197 Expr *NumIterations, Sema &SemaRef, 9198 Scope *S, DSAStackTy *Stack) { 9199 // Walk the vars and build update/final expressions for the CodeGen. 9200 SmallVector<Expr *, 8> Updates; 9201 SmallVector<Expr *, 8> Finals; 9202 Expr *Step = Clause.getStep(); 9203 Expr *CalcStep = Clause.getCalcStep(); 9204 // OpenMP [2.14.3.7, linear clause] 9205 // If linear-step is not specified it is assumed to be 1. 9206 if (Step == nullptr) 9207 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 9208 else if (CalcStep) { 9209 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 9210 } 9211 bool HasErrors = false; 9212 auto CurInit = Clause.inits().begin(); 9213 auto CurPrivate = Clause.privates().begin(); 9214 auto LinKind = Clause.getModifier(); 9215 for (auto &RefExpr : Clause.varlists()) { 9216 SourceLocation ELoc; 9217 SourceRange ERange; 9218 Expr *SimpleRefExpr = RefExpr; 9219 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange, 9220 /*AllowArraySection=*/false); 9221 ValueDecl *D = Res.first; 9222 if (Res.second || !D) { 9223 Updates.push_back(nullptr); 9224 Finals.push_back(nullptr); 9225 HasErrors = true; 9226 continue; 9227 } 9228 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) { 9229 D = cast<MemberExpr>(CED->getInit()->IgnoreParenImpCasts()) 9230 ->getMemberDecl(); 9231 } 9232 auto &&Info = Stack->isLoopControlVariable(D); 9233 Expr *InitExpr = *CurInit; 9234 9235 // Build privatized reference to the current linear var. 9236 auto DE = cast<DeclRefExpr>(SimpleRefExpr); 9237 Expr *CapturedRef; 9238 if (LinKind == OMPC_LINEAR_uval) 9239 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 9240 else 9241 CapturedRef = 9242 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 9243 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 9244 /*RefersToCapture=*/true); 9245 9246 // Build update: Var = InitExpr + IV * Step 9247 ExprResult Update; 9248 if (!Info.first) { 9249 Update = 9250 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 9251 InitExpr, IV, Step, /* Subtract */ false); 9252 } else 9253 Update = *CurPrivate; 9254 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(), 9255 /*DiscardedValue=*/true); 9256 9257 // Build final: Var = InitExpr + NumIterations * Step 9258 ExprResult Final; 9259 if (!Info.first) { 9260 Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 9261 InitExpr, NumIterations, Step, 9262 /* Subtract */ false); 9263 } else 9264 Final = *CurPrivate; 9265 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(), 9266 /*DiscardedValue=*/true); 9267 9268 if (!Update.isUsable() || !Final.isUsable()) { 9269 Updates.push_back(nullptr); 9270 Finals.push_back(nullptr); 9271 HasErrors = true; 9272 } else { 9273 Updates.push_back(Update.get()); 9274 Finals.push_back(Final.get()); 9275 } 9276 ++CurInit; 9277 ++CurPrivate; 9278 } 9279 Clause.setUpdates(Updates); 9280 Clause.setFinals(Finals); 9281 return HasErrors; 9282 } 9283 9284 OMPClause *Sema::ActOnOpenMPAlignedClause( 9285 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 9286 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 9287 9288 SmallVector<Expr *, 8> Vars; 9289 for (auto &RefExpr : VarList) { 9290 assert(RefExpr && "NULL expr in OpenMP linear clause."); 9291 SourceLocation ELoc; 9292 SourceRange ERange; 9293 Expr *SimpleRefExpr = RefExpr; 9294 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 9295 /*AllowArraySection=*/false); 9296 if (Res.second) { 9297 // It will be analyzed later. 9298 Vars.push_back(RefExpr); 9299 } 9300 ValueDecl *D = Res.first; 9301 if (!D) 9302 continue; 9303 9304 QualType QType = D->getType(); 9305 auto *VD = dyn_cast<VarDecl>(D); 9306 9307 // OpenMP [2.8.1, simd construct, Restrictions] 9308 // The type of list items appearing in the aligned clause must be 9309 // array, pointer, reference to array, or reference to pointer. 9310 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 9311 const Type *Ty = QType.getTypePtrOrNull(); 9312 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 9313 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 9314 << QType << getLangOpts().CPlusPlus << ERange; 9315 bool IsDecl = 9316 !VD || 9317 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9318 Diag(D->getLocation(), 9319 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9320 << D; 9321 continue; 9322 } 9323 9324 // OpenMP [2.8.1, simd construct, Restrictions] 9325 // A list-item cannot appear in more than one aligned clause. 9326 if (Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 9327 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 9328 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 9329 << getOpenMPClauseName(OMPC_aligned); 9330 continue; 9331 } 9332 9333 DeclRefExpr *Ref = nullptr; 9334 if (!VD && IsOpenMPCapturedDecl(D)) 9335 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 9336 Vars.push_back(DefaultFunctionArrayConversion( 9337 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 9338 .get()); 9339 } 9340 9341 // OpenMP [2.8.1, simd construct, Description] 9342 // The parameter of the aligned clause, alignment, must be a constant 9343 // positive integer expression. 9344 // If no optional parameter is specified, implementation-defined default 9345 // alignments for SIMD instructions on the target platforms are assumed. 9346 if (Alignment != nullptr) { 9347 ExprResult AlignResult = 9348 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 9349 if (AlignResult.isInvalid()) 9350 return nullptr; 9351 Alignment = AlignResult.get(); 9352 } 9353 if (Vars.empty()) 9354 return nullptr; 9355 9356 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 9357 EndLoc, Vars, Alignment); 9358 } 9359 9360 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 9361 SourceLocation StartLoc, 9362 SourceLocation LParenLoc, 9363 SourceLocation EndLoc) { 9364 SmallVector<Expr *, 8> Vars; 9365 SmallVector<Expr *, 8> SrcExprs; 9366 SmallVector<Expr *, 8> DstExprs; 9367 SmallVector<Expr *, 8> AssignmentOps; 9368 for (auto &RefExpr : VarList) { 9369 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 9370 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 9371 // It will be analyzed later. 9372 Vars.push_back(RefExpr); 9373 SrcExprs.push_back(nullptr); 9374 DstExprs.push_back(nullptr); 9375 AssignmentOps.push_back(nullptr); 9376 continue; 9377 } 9378 9379 SourceLocation ELoc = RefExpr->getExprLoc(); 9380 // OpenMP [2.1, C/C++] 9381 // A list item is a variable name. 9382 // OpenMP [2.14.4.1, Restrictions, p.1] 9383 // A list item that appears in a copyin clause must be threadprivate. 9384 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 9385 if (!DE || !isa<VarDecl>(DE->getDecl())) { 9386 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 9387 << 0 << RefExpr->getSourceRange(); 9388 continue; 9389 } 9390 9391 Decl *D = DE->getDecl(); 9392 VarDecl *VD = cast<VarDecl>(D); 9393 9394 QualType Type = VD->getType(); 9395 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 9396 // It will be analyzed later. 9397 Vars.push_back(DE); 9398 SrcExprs.push_back(nullptr); 9399 DstExprs.push_back(nullptr); 9400 AssignmentOps.push_back(nullptr); 9401 continue; 9402 } 9403 9404 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 9405 // A list item that appears in a copyin clause must be threadprivate. 9406 if (!DSAStack->isThreadPrivate(VD)) { 9407 Diag(ELoc, diag::err_omp_required_access) 9408 << getOpenMPClauseName(OMPC_copyin) 9409 << getOpenMPDirectiveName(OMPD_threadprivate); 9410 continue; 9411 } 9412 9413 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 9414 // A variable of class type (or array thereof) that appears in a 9415 // copyin clause requires an accessible, unambiguous copy assignment 9416 // operator for the class type. 9417 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 9418 auto *SrcVD = 9419 buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(), 9420 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 9421 auto *PseudoSrcExpr = buildDeclRefExpr( 9422 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 9423 auto *DstVD = 9424 buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst", 9425 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 9426 auto *PseudoDstExpr = 9427 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 9428 // For arrays generate assignment operation for single element and replace 9429 // it by the original array element in CodeGen. 9430 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 9431 PseudoDstExpr, PseudoSrcExpr); 9432 if (AssignmentOp.isInvalid()) 9433 continue; 9434 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 9435 /*DiscardedValue=*/true); 9436 if (AssignmentOp.isInvalid()) 9437 continue; 9438 9439 DSAStack->addDSA(VD, DE, OMPC_copyin); 9440 Vars.push_back(DE); 9441 SrcExprs.push_back(PseudoSrcExpr); 9442 DstExprs.push_back(PseudoDstExpr); 9443 AssignmentOps.push_back(AssignmentOp.get()); 9444 } 9445 9446 if (Vars.empty()) 9447 return nullptr; 9448 9449 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 9450 SrcExprs, DstExprs, AssignmentOps); 9451 } 9452 9453 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 9454 SourceLocation StartLoc, 9455 SourceLocation LParenLoc, 9456 SourceLocation EndLoc) { 9457 SmallVector<Expr *, 8> Vars; 9458 SmallVector<Expr *, 8> SrcExprs; 9459 SmallVector<Expr *, 8> DstExprs; 9460 SmallVector<Expr *, 8> AssignmentOps; 9461 for (auto &RefExpr : VarList) { 9462 assert(RefExpr && "NULL expr in OpenMP linear clause."); 9463 SourceLocation ELoc; 9464 SourceRange ERange; 9465 Expr *SimpleRefExpr = RefExpr; 9466 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 9467 /*AllowArraySection=*/false); 9468 if (Res.second) { 9469 // It will be analyzed later. 9470 Vars.push_back(RefExpr); 9471 SrcExprs.push_back(nullptr); 9472 DstExprs.push_back(nullptr); 9473 AssignmentOps.push_back(nullptr); 9474 } 9475 ValueDecl *D = Res.first; 9476 if (!D) 9477 continue; 9478 9479 QualType Type = D->getType(); 9480 auto *VD = dyn_cast<VarDecl>(D); 9481 9482 // OpenMP [2.14.4.2, Restrictions, p.2] 9483 // A list item that appears in a copyprivate clause may not appear in a 9484 // private or firstprivate clause on the single construct. 9485 if (!VD || !DSAStack->isThreadPrivate(VD)) { 9486 auto DVar = DSAStack->getTopDSA(D, false); 9487 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 9488 DVar.RefExpr) { 9489 Diag(ELoc, diag::err_omp_wrong_dsa) 9490 << getOpenMPClauseName(DVar.CKind) 9491 << getOpenMPClauseName(OMPC_copyprivate); 9492 ReportOriginalDSA(*this, DSAStack, D, DVar); 9493 continue; 9494 } 9495 9496 // OpenMP [2.11.4.2, Restrictions, p.1] 9497 // All list items that appear in a copyprivate clause must be either 9498 // threadprivate or private in the enclosing context. 9499 if (DVar.CKind == OMPC_unknown) { 9500 DVar = DSAStack->getImplicitDSA(D, false); 9501 if (DVar.CKind == OMPC_shared) { 9502 Diag(ELoc, diag::err_omp_required_access) 9503 << getOpenMPClauseName(OMPC_copyprivate) 9504 << "threadprivate or private in the enclosing context"; 9505 ReportOriginalDSA(*this, DSAStack, D, DVar); 9506 continue; 9507 } 9508 } 9509 } 9510 9511 // Variably modified types are not supported. 9512 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 9513 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 9514 << getOpenMPClauseName(OMPC_copyprivate) << Type 9515 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 9516 bool IsDecl = 9517 !VD || 9518 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9519 Diag(D->getLocation(), 9520 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9521 << D; 9522 continue; 9523 } 9524 9525 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 9526 // A variable of class type (or array thereof) that appears in a 9527 // copyin clause requires an accessible, unambiguous copy assignment 9528 // operator for the class type. 9529 Type = Context.getBaseElementType(Type.getNonReferenceType()) 9530 .getUnqualifiedType(); 9531 auto *SrcVD = 9532 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src", 9533 D->hasAttrs() ? &D->getAttrs() : nullptr); 9534 auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 9535 auto *DstVD = 9536 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst", 9537 D->hasAttrs() ? &D->getAttrs() : nullptr); 9538 auto *PseudoDstExpr = 9539 buildDeclRefExpr(*this, DstVD, Type, ELoc); 9540 auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 9541 PseudoDstExpr, PseudoSrcExpr); 9542 if (AssignmentOp.isInvalid()) 9543 continue; 9544 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 9545 /*DiscardedValue=*/true); 9546 if (AssignmentOp.isInvalid()) 9547 continue; 9548 9549 // No need to mark vars as copyprivate, they are already threadprivate or 9550 // implicitly private. 9551 assert(VD || IsOpenMPCapturedDecl(D)); 9552 Vars.push_back( 9553 VD ? RefExpr->IgnoreParens() 9554 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 9555 SrcExprs.push_back(PseudoSrcExpr); 9556 DstExprs.push_back(PseudoDstExpr); 9557 AssignmentOps.push_back(AssignmentOp.get()); 9558 } 9559 9560 if (Vars.empty()) 9561 return nullptr; 9562 9563 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9564 Vars, SrcExprs, DstExprs, AssignmentOps); 9565 } 9566 9567 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 9568 SourceLocation StartLoc, 9569 SourceLocation LParenLoc, 9570 SourceLocation EndLoc) { 9571 if (VarList.empty()) 9572 return nullptr; 9573 9574 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 9575 } 9576 9577 OMPClause * 9578 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 9579 SourceLocation DepLoc, SourceLocation ColonLoc, 9580 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 9581 SourceLocation LParenLoc, SourceLocation EndLoc) { 9582 if (DSAStack->getCurrentDirective() == OMPD_ordered && 9583 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 9584 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 9585 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 9586 return nullptr; 9587 } 9588 if (DSAStack->getCurrentDirective() != OMPD_ordered && 9589 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 9590 DepKind == OMPC_DEPEND_sink)) { 9591 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 9592 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 9593 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 9594 /*Last=*/OMPC_DEPEND_unknown, Except) 9595 << getOpenMPClauseName(OMPC_depend); 9596 return nullptr; 9597 } 9598 SmallVector<Expr *, 8> Vars; 9599 DSAStackTy::OperatorOffsetTy OpsOffs; 9600 llvm::APSInt DepCounter(/*BitWidth=*/32); 9601 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 9602 if (DepKind == OMPC_DEPEND_sink) { 9603 if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) { 9604 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 9605 TotalDepCount.setIsUnsigned(/*Val=*/true); 9606 } 9607 } 9608 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) || 9609 DSAStack->getParentOrderedRegionParam()) { 9610 for (auto &RefExpr : VarList) { 9611 assert(RefExpr && "NULL expr in OpenMP shared clause."); 9612 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 9613 // It will be analyzed later. 9614 Vars.push_back(RefExpr); 9615 continue; 9616 } 9617 9618 SourceLocation ELoc = RefExpr->getExprLoc(); 9619 auto *SimpleExpr = RefExpr->IgnoreParenCasts(); 9620 if (DepKind == OMPC_DEPEND_sink) { 9621 if (DepCounter >= TotalDepCount) { 9622 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 9623 continue; 9624 } 9625 ++DepCounter; 9626 // OpenMP [2.13.9, Summary] 9627 // depend(dependence-type : vec), where dependence-type is: 9628 // 'sink' and where vec is the iteration vector, which has the form: 9629 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 9630 // where n is the value specified by the ordered clause in the loop 9631 // directive, xi denotes the loop iteration variable of the i-th nested 9632 // loop associated with the loop directive, and di is a constant 9633 // non-negative integer. 9634 if (CurContext->isDependentContext()) { 9635 // It will be analyzed later. 9636 Vars.push_back(RefExpr); 9637 continue; 9638 } 9639 SimpleExpr = SimpleExpr->IgnoreImplicit(); 9640 OverloadedOperatorKind OOK = OO_None; 9641 SourceLocation OOLoc; 9642 Expr *LHS = SimpleExpr; 9643 Expr *RHS = nullptr; 9644 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 9645 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 9646 OOLoc = BO->getOperatorLoc(); 9647 LHS = BO->getLHS()->IgnoreParenImpCasts(); 9648 RHS = BO->getRHS()->IgnoreParenImpCasts(); 9649 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 9650 OOK = OCE->getOperator(); 9651 OOLoc = OCE->getOperatorLoc(); 9652 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 9653 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 9654 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 9655 OOK = MCE->getMethodDecl() 9656 ->getNameInfo() 9657 .getName() 9658 .getCXXOverloadedOperator(); 9659 OOLoc = MCE->getCallee()->getExprLoc(); 9660 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 9661 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 9662 } 9663 SourceLocation ELoc; 9664 SourceRange ERange; 9665 auto Res = getPrivateItem(*this, LHS, ELoc, ERange, 9666 /*AllowArraySection=*/false); 9667 if (Res.second) { 9668 // It will be analyzed later. 9669 Vars.push_back(RefExpr); 9670 } 9671 ValueDecl *D = Res.first; 9672 if (!D) 9673 continue; 9674 9675 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 9676 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 9677 continue; 9678 } 9679 if (RHS) { 9680 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 9681 RHS, OMPC_depend, /*StrictlyPositive=*/false); 9682 if (RHSRes.isInvalid()) 9683 continue; 9684 } 9685 if (!CurContext->isDependentContext() && 9686 DSAStack->getParentOrderedRegionParam() && 9687 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 9688 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 9689 << DSAStack->getParentLoopControlVariable( 9690 DepCounter.getZExtValue()); 9691 continue; 9692 } 9693 OpsOffs.push_back({RHS, OOK}); 9694 } else { 9695 // OpenMP [2.11.1.1, Restrictions, p.3] 9696 // A variable that is part of another variable (such as a field of a 9697 // structure) but is not an array element or an array section cannot 9698 // appear in a depend clause. 9699 auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr); 9700 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 9701 auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 9702 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 9703 (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) || 9704 (ASE && 9705 !ASE->getBase() 9706 ->getType() 9707 .getNonReferenceType() 9708 ->isPointerType() && 9709 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 9710 Diag(ELoc, diag::err_omp_expected_var_name_member_expr_or_array_item) 9711 << 0 << RefExpr->getSourceRange(); 9712 continue; 9713 } 9714 } 9715 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 9716 } 9717 9718 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 9719 TotalDepCount > VarList.size() && 9720 DSAStack->getParentOrderedRegionParam()) { 9721 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 9722 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 9723 } 9724 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 9725 Vars.empty()) 9726 return nullptr; 9727 } 9728 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9729 DepKind, DepLoc, ColonLoc, Vars); 9730 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) 9731 DSAStack->addDoacrossDependClause(C, OpsOffs); 9732 return C; 9733 } 9734 9735 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 9736 SourceLocation LParenLoc, 9737 SourceLocation EndLoc) { 9738 Expr *ValExpr = Device; 9739 9740 // OpenMP [2.9.1, Restrictions] 9741 // The device expression must evaluate to a non-negative integer value. 9742 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 9743 /*StrictlyPositive=*/false)) 9744 return nullptr; 9745 9746 return new (Context) OMPDeviceClause(ValExpr, StartLoc, LParenLoc, EndLoc); 9747 } 9748 9749 static bool IsCXXRecordForMappable(Sema &SemaRef, SourceLocation Loc, 9750 DSAStackTy *Stack, CXXRecordDecl *RD) { 9751 if (!RD || RD->isInvalidDecl()) 9752 return true; 9753 9754 if (auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) 9755 if (auto *CTD = CTSD->getSpecializedTemplate()) 9756 RD = CTD->getTemplatedDecl(); 9757 auto QTy = SemaRef.Context.getRecordType(RD); 9758 if (RD->isDynamicClass()) { 9759 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 9760 SemaRef.Diag(RD->getLocation(), diag::note_omp_polymorphic_in_target); 9761 return false; 9762 } 9763 auto *DC = RD; 9764 bool IsCorrect = true; 9765 for (auto *I : DC->decls()) { 9766 if (I) { 9767 if (auto *MD = dyn_cast<CXXMethodDecl>(I)) { 9768 if (MD->isStatic()) { 9769 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 9770 SemaRef.Diag(MD->getLocation(), 9771 diag::note_omp_static_member_in_target); 9772 IsCorrect = false; 9773 } 9774 } else if (auto *VD = dyn_cast<VarDecl>(I)) { 9775 if (VD->isStaticDataMember()) { 9776 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 9777 SemaRef.Diag(VD->getLocation(), 9778 diag::note_omp_static_member_in_target); 9779 IsCorrect = false; 9780 } 9781 } 9782 } 9783 } 9784 9785 for (auto &I : RD->bases()) { 9786 if (!IsCXXRecordForMappable(SemaRef, I.getLocStart(), Stack, 9787 I.getType()->getAsCXXRecordDecl())) 9788 IsCorrect = false; 9789 } 9790 return IsCorrect; 9791 } 9792 9793 static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 9794 DSAStackTy *Stack, QualType QTy) { 9795 NamedDecl *ND; 9796 if (QTy->isIncompleteType(&ND)) { 9797 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 9798 return false; 9799 } else if (CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(ND)) { 9800 if (!RD->isInvalidDecl() && 9801 !IsCXXRecordForMappable(SemaRef, SL, Stack, RD)) 9802 return false; 9803 } 9804 return true; 9805 } 9806 9807 /// \brief Return true if it can be proven that the provided array expression 9808 /// (array section or array subscript) does NOT specify the whole size of the 9809 /// array whose base type is \a BaseQTy. 9810 static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 9811 const Expr *E, 9812 QualType BaseQTy) { 9813 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 9814 9815 // If this is an array subscript, it refers to the whole size if the size of 9816 // the dimension is constant and equals 1. Also, an array section assumes the 9817 // format of an array subscript if no colon is used. 9818 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 9819 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 9820 return ATy->getSize().getSExtValue() != 1; 9821 // Size can't be evaluated statically. 9822 return false; 9823 } 9824 9825 assert(OASE && "Expecting array section if not an array subscript."); 9826 auto *LowerBound = OASE->getLowerBound(); 9827 auto *Length = OASE->getLength(); 9828 9829 // If there is a lower bound that does not evaluates to zero, we are not 9830 // convering the whole dimension. 9831 if (LowerBound) { 9832 llvm::APSInt ConstLowerBound; 9833 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) 9834 return false; // Can't get the integer value as a constant. 9835 if (ConstLowerBound.getSExtValue()) 9836 return true; 9837 } 9838 9839 // If we don't have a length we covering the whole dimension. 9840 if (!Length) 9841 return false; 9842 9843 // If the base is a pointer, we don't have a way to get the size of the 9844 // pointee. 9845 if (BaseQTy->isPointerType()) 9846 return false; 9847 9848 // We can only check if the length is the same as the size of the dimension 9849 // if we have a constant array. 9850 auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 9851 if (!CATy) 9852 return false; 9853 9854 llvm::APSInt ConstLength; 9855 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 9856 return false; // Can't get the integer value as a constant. 9857 9858 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 9859 } 9860 9861 // Return true if it can be proven that the provided array expression (array 9862 // section or array subscript) does NOT specify a single element of the array 9863 // whose base type is \a BaseQTy. 9864 static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 9865 const Expr *E, 9866 QualType BaseQTy) { 9867 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 9868 9869 // An array subscript always refer to a single element. Also, an array section 9870 // assumes the format of an array subscript if no colon is used. 9871 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 9872 return false; 9873 9874 assert(OASE && "Expecting array section if not an array subscript."); 9875 auto *Length = OASE->getLength(); 9876 9877 // If we don't have a length we have to check if the array has unitary size 9878 // for this dimension. Also, we should always expect a length if the base type 9879 // is pointer. 9880 if (!Length) { 9881 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 9882 return ATy->getSize().getSExtValue() != 1; 9883 // We cannot assume anything. 9884 return false; 9885 } 9886 9887 // Check if the length evaluates to 1. 9888 llvm::APSInt ConstLength; 9889 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 9890 return false; // Can't get the integer value as a constant. 9891 9892 return ConstLength.getSExtValue() != 1; 9893 } 9894 9895 // Return the expression of the base of the mappable expression or null if it 9896 // cannot be determined and do all the necessary checks to see if the expression 9897 // is valid as a standalone mappable expression. In the process, record all the 9898 // components of the expression. 9899 static Expr *CheckMapClauseExpressionBase( 9900 Sema &SemaRef, Expr *E, 9901 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 9902 OpenMPClauseKind CKind) { 9903 SourceLocation ELoc = E->getExprLoc(); 9904 SourceRange ERange = E->getSourceRange(); 9905 9906 // The base of elements of list in a map clause have to be either: 9907 // - a reference to variable or field. 9908 // - a member expression. 9909 // - an array expression. 9910 // 9911 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 9912 // reference to 'r'. 9913 // 9914 // If we have: 9915 // 9916 // struct SS { 9917 // Bla S; 9918 // foo() { 9919 // #pragma omp target map (S.Arr[:12]); 9920 // } 9921 // } 9922 // 9923 // We want to retrieve the member expression 'this->S'; 9924 9925 Expr *RelevantExpr = nullptr; 9926 9927 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 9928 // If a list item is an array section, it must specify contiguous storage. 9929 // 9930 // For this restriction it is sufficient that we make sure only references 9931 // to variables or fields and array expressions, and that no array sections 9932 // exist except in the rightmost expression (unless they cover the whole 9933 // dimension of the array). E.g. these would be invalid: 9934 // 9935 // r.ArrS[3:5].Arr[6:7] 9936 // 9937 // r.ArrS[3:5].x 9938 // 9939 // but these would be valid: 9940 // r.ArrS[3].Arr[6:7] 9941 // 9942 // r.ArrS[3].x 9943 9944 bool AllowUnitySizeArraySection = true; 9945 bool AllowWholeSizeArraySection = true; 9946 9947 while (!RelevantExpr) { 9948 E = E->IgnoreParenImpCasts(); 9949 9950 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 9951 if (!isa<VarDecl>(CurE->getDecl())) 9952 break; 9953 9954 RelevantExpr = CurE; 9955 9956 // If we got a reference to a declaration, we should not expect any array 9957 // section before that. 9958 AllowUnitySizeArraySection = false; 9959 AllowWholeSizeArraySection = false; 9960 9961 // Record the component. 9962 CurComponents.push_back(OMPClauseMappableExprCommon::MappableComponent( 9963 CurE, CurE->getDecl())); 9964 continue; 9965 } 9966 9967 if (auto *CurE = dyn_cast<MemberExpr>(E)) { 9968 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 9969 9970 if (isa<CXXThisExpr>(BaseE)) 9971 // We found a base expression: this->Val. 9972 RelevantExpr = CurE; 9973 else 9974 E = BaseE; 9975 9976 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 9977 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 9978 << CurE->getSourceRange(); 9979 break; 9980 } 9981 9982 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 9983 9984 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 9985 // A bit-field cannot appear in a map clause. 9986 // 9987 if (FD->isBitField()) { 9988 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 9989 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 9990 break; 9991 } 9992 9993 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 9994 // If the type of a list item is a reference to a type T then the type 9995 // will be considered to be T for all purposes of this clause. 9996 QualType CurType = BaseE->getType().getNonReferenceType(); 9997 9998 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 9999 // A list item cannot be a variable that is a member of a structure with 10000 // a union type. 10001 // 10002 if (auto *RT = CurType->getAs<RecordType>()) 10003 if (RT->isUnionType()) { 10004 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 10005 << CurE->getSourceRange(); 10006 break; 10007 } 10008 10009 // If we got a member expression, we should not expect any array section 10010 // before that: 10011 // 10012 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 10013 // If a list item is an element of a structure, only the rightmost symbol 10014 // of the variable reference can be an array section. 10015 // 10016 AllowUnitySizeArraySection = false; 10017 AllowWholeSizeArraySection = false; 10018 10019 // Record the component. 10020 CurComponents.push_back( 10021 OMPClauseMappableExprCommon::MappableComponent(CurE, FD)); 10022 continue; 10023 } 10024 10025 if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 10026 E = CurE->getBase()->IgnoreParenImpCasts(); 10027 10028 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 10029 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 10030 << 0 << CurE->getSourceRange(); 10031 break; 10032 } 10033 10034 // If we got an array subscript that express the whole dimension we 10035 // can have any array expressions before. If it only expressing part of 10036 // the dimension, we can only have unitary-size array expressions. 10037 if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 10038 E->getType())) 10039 AllowWholeSizeArraySection = false; 10040 10041 // Record the component - we don't have any declaration associated. 10042 CurComponents.push_back( 10043 OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); 10044 continue; 10045 } 10046 10047 if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 10048 E = CurE->getBase()->IgnoreParenImpCasts(); 10049 10050 auto CurType = 10051 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 10052 10053 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 10054 // If the type of a list item is a reference to a type T then the type 10055 // will be considered to be T for all purposes of this clause. 10056 if (CurType->isReferenceType()) 10057 CurType = CurType->getPointeeType(); 10058 10059 bool IsPointer = CurType->isAnyPointerType(); 10060 10061 if (!IsPointer && !CurType->isArrayType()) { 10062 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 10063 << 0 << CurE->getSourceRange(); 10064 break; 10065 } 10066 10067 bool NotWhole = 10068 CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 10069 bool NotUnity = 10070 CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 10071 10072 if (AllowWholeSizeArraySection && AllowUnitySizeArraySection) { 10073 // Any array section is currently allowed. 10074 // 10075 // If this array section refers to the whole dimension we can still 10076 // accept other array sections before this one, except if the base is a 10077 // pointer. Otherwise, only unitary sections are accepted. 10078 if (NotWhole || IsPointer) 10079 AllowWholeSizeArraySection = false; 10080 } else if ((AllowUnitySizeArraySection && NotUnity) || 10081 (AllowWholeSizeArraySection && NotWhole)) { 10082 // A unity or whole array section is not allowed and that is not 10083 // compatible with the properties of the current array section. 10084 SemaRef.Diag( 10085 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 10086 << CurE->getSourceRange(); 10087 break; 10088 } 10089 10090 // Record the component - we don't have any declaration associated. 10091 CurComponents.push_back( 10092 OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); 10093 continue; 10094 } 10095 10096 // If nothing else worked, this is not a valid map clause expression. 10097 SemaRef.Diag(ELoc, 10098 diag::err_omp_expected_named_var_member_or_array_expression) 10099 << ERange; 10100 break; 10101 } 10102 10103 return RelevantExpr; 10104 } 10105 10106 // Return true if expression E associated with value VD has conflicts with other 10107 // map information. 10108 static bool CheckMapConflicts( 10109 Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E, 10110 bool CurrentRegionOnly, 10111 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 10112 OpenMPClauseKind CKind) { 10113 assert(VD && E); 10114 SourceLocation ELoc = E->getExprLoc(); 10115 SourceRange ERange = E->getSourceRange(); 10116 10117 // In order to easily check the conflicts we need to match each component of 10118 // the expression under test with the components of the expressions that are 10119 // already in the stack. 10120 10121 assert(!CurComponents.empty() && "Map clause expression with no components!"); 10122 assert(CurComponents.back().getAssociatedDeclaration() == VD && 10123 "Map clause expression with unexpected base!"); 10124 10125 // Variables to help detecting enclosing problems in data environment nests. 10126 bool IsEnclosedByDataEnvironmentExpr = false; 10127 const Expr *EnclosingExpr = nullptr; 10128 10129 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 10130 VD, CurrentRegionOnly, 10131 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef 10132 StackComponents) -> bool { 10133 10134 assert(!StackComponents.empty() && 10135 "Map clause expression with no components!"); 10136 assert(StackComponents.back().getAssociatedDeclaration() == VD && 10137 "Map clause expression with unexpected base!"); 10138 10139 // The whole expression in the stack. 10140 auto *RE = StackComponents.front().getAssociatedExpression(); 10141 10142 // Expressions must start from the same base. Here we detect at which 10143 // point both expressions diverge from each other and see if we can 10144 // detect if the memory referred to both expressions is contiguous and 10145 // do not overlap. 10146 auto CI = CurComponents.rbegin(); 10147 auto CE = CurComponents.rend(); 10148 auto SI = StackComponents.rbegin(); 10149 auto SE = StackComponents.rend(); 10150 for (; CI != CE && SI != SE; ++CI, ++SI) { 10151 10152 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 10153 // At most one list item can be an array item derived from a given 10154 // variable in map clauses of the same construct. 10155 if (CurrentRegionOnly && 10156 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 10157 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 10158 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 10159 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 10160 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 10161 diag::err_omp_multiple_array_items_in_map_clause) 10162 << CI->getAssociatedExpression()->getSourceRange(); 10163 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 10164 diag::note_used_here) 10165 << SI->getAssociatedExpression()->getSourceRange(); 10166 return true; 10167 } 10168 10169 // Do both expressions have the same kind? 10170 if (CI->getAssociatedExpression()->getStmtClass() != 10171 SI->getAssociatedExpression()->getStmtClass()) 10172 break; 10173 10174 // Are we dealing with different variables/fields? 10175 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 10176 break; 10177 } 10178 10179 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 10180 // List items of map clauses in the same construct must not share 10181 // original storage. 10182 // 10183 // If the expressions are exactly the same or one is a subset of the 10184 // other, it means they are sharing storage. 10185 if (CI == CE && SI == SE) { 10186 if (CurrentRegionOnly) { 10187 if (CKind == OMPC_map) 10188 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 10189 else { 10190 assert(CKind == OMPC_to || CKind == OMPC_from); 10191 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 10192 << ERange; 10193 } 10194 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 10195 << RE->getSourceRange(); 10196 return true; 10197 } else { 10198 // If we find the same expression in the enclosing data environment, 10199 // that is legal. 10200 IsEnclosedByDataEnvironmentExpr = true; 10201 return false; 10202 } 10203 } 10204 10205 QualType DerivedType = 10206 std::prev(CI)->getAssociatedDeclaration()->getType(); 10207 SourceLocation DerivedLoc = 10208 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 10209 10210 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 10211 // If the type of a list item is a reference to a type T then the type 10212 // will be considered to be T for all purposes of this clause. 10213 DerivedType = DerivedType.getNonReferenceType(); 10214 10215 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 10216 // A variable for which the type is pointer and an array section 10217 // derived from that variable must not appear as list items of map 10218 // clauses of the same construct. 10219 // 10220 // Also, cover one of the cases in: 10221 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 10222 // If any part of the original storage of a list item has corresponding 10223 // storage in the device data environment, all of the original storage 10224 // must have corresponding storage in the device data environment. 10225 // 10226 if (DerivedType->isAnyPointerType()) { 10227 if (CI == CE || SI == SE) { 10228 SemaRef.Diag( 10229 DerivedLoc, 10230 diag::err_omp_pointer_mapped_along_with_derived_section) 10231 << DerivedLoc; 10232 } else { 10233 assert(CI != CE && SI != SE); 10234 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced) 10235 << DerivedLoc; 10236 } 10237 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 10238 << RE->getSourceRange(); 10239 return true; 10240 } 10241 10242 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 10243 // List items of map clauses in the same construct must not share 10244 // original storage. 10245 // 10246 // An expression is a subset of the other. 10247 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 10248 if (CKind == OMPC_map) 10249 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 10250 else { 10251 assert(CKind == OMPC_to || CKind == OMPC_from); 10252 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 10253 << ERange; 10254 } 10255 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 10256 << RE->getSourceRange(); 10257 return true; 10258 } 10259 10260 // The current expression uses the same base as other expression in the 10261 // data environment but does not contain it completely. 10262 if (!CurrentRegionOnly && SI != SE) 10263 EnclosingExpr = RE; 10264 10265 // The current expression is a subset of the expression in the data 10266 // environment. 10267 IsEnclosedByDataEnvironmentExpr |= 10268 (!CurrentRegionOnly && CI != CE && SI == SE); 10269 10270 return false; 10271 }); 10272 10273 if (CurrentRegionOnly) 10274 return FoundError; 10275 10276 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 10277 // If any part of the original storage of a list item has corresponding 10278 // storage in the device data environment, all of the original storage must 10279 // have corresponding storage in the device data environment. 10280 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 10281 // If a list item is an element of a structure, and a different element of 10282 // the structure has a corresponding list item in the device data environment 10283 // prior to a task encountering the construct associated with the map clause, 10284 // then the list item must also have a corresponding list item in the device 10285 // data environment prior to the task encountering the construct. 10286 // 10287 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 10288 SemaRef.Diag(ELoc, 10289 diag::err_omp_original_storage_is_shared_and_does_not_contain) 10290 << ERange; 10291 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 10292 << EnclosingExpr->getSourceRange(); 10293 return true; 10294 } 10295 10296 return FoundError; 10297 } 10298 10299 namespace { 10300 // Utility struct that gathers all the related lists associated with a mappable 10301 // expression. 10302 struct MappableVarListInfo final { 10303 // The list of expressions. 10304 ArrayRef<Expr *> VarList; 10305 // The list of processed expressions. 10306 SmallVector<Expr *, 16> ProcessedVarList; 10307 // The mappble components for each expression. 10308 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 10309 // The base declaration of the variable. 10310 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 10311 10312 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 10313 // We have a list of components and base declarations for each entry in the 10314 // variable list. 10315 VarComponents.reserve(VarList.size()); 10316 VarBaseDeclarations.reserve(VarList.size()); 10317 } 10318 }; 10319 } 10320 10321 // Check the validity of the provided variable list for the provided clause kind 10322 // \a CKind. In the check process the valid expressions, and mappable expression 10323 // components and variables are extracted and used to fill \a Vars, 10324 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and 10325 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'. 10326 static void 10327 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, 10328 OpenMPClauseKind CKind, MappableVarListInfo &MVLI, 10329 SourceLocation StartLoc, 10330 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 10331 bool IsMapTypeImplicit = false) { 10332 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 10333 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 10334 "Unexpected clause kind with mappable expressions!"); 10335 10336 // Keep track of the mappable components and base declarations in this clause. 10337 // Each entry in the list is going to have a list of components associated. We 10338 // record each set of the components so that we can build the clause later on. 10339 // In the end we should have the same amount of declarations and component 10340 // lists. 10341 10342 for (auto &RE : MVLI.VarList) { 10343 assert(RE && "Null expr in omp to/from/map clause"); 10344 SourceLocation ELoc = RE->getExprLoc(); 10345 10346 auto *VE = RE->IgnoreParenLValueCasts(); 10347 10348 if (VE->isValueDependent() || VE->isTypeDependent() || 10349 VE->isInstantiationDependent() || 10350 VE->containsUnexpandedParameterPack()) { 10351 // We can only analyze this information once the missing information is 10352 // resolved. 10353 MVLI.ProcessedVarList.push_back(RE); 10354 continue; 10355 } 10356 10357 auto *SimpleExpr = RE->IgnoreParenCasts(); 10358 10359 if (!RE->IgnoreParenImpCasts()->isLValue()) { 10360 SemaRef.Diag(ELoc, 10361 diag::err_omp_expected_named_var_member_or_array_expression) 10362 << RE->getSourceRange(); 10363 continue; 10364 } 10365 10366 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 10367 ValueDecl *CurDeclaration = nullptr; 10368 10369 // Obtain the array or member expression bases if required. Also, fill the 10370 // components array with all the components identified in the process. 10371 auto *BE = 10372 CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind); 10373 if (!BE) 10374 continue; 10375 10376 assert(!CurComponents.empty() && 10377 "Invalid mappable expression information."); 10378 10379 // For the following checks, we rely on the base declaration which is 10380 // expected to be associated with the last component. The declaration is 10381 // expected to be a variable or a field (if 'this' is being mapped). 10382 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 10383 assert(CurDeclaration && "Null decl on map clause."); 10384 assert( 10385 CurDeclaration->isCanonicalDecl() && 10386 "Expecting components to have associated only canonical declarations."); 10387 10388 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 10389 auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 10390 10391 assert((VD || FD) && "Only variables or fields are expected here!"); 10392 (void)FD; 10393 10394 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 10395 // threadprivate variables cannot appear in a map clause. 10396 // OpenMP 4.5 [2.10.5, target update Construct] 10397 // threadprivate variables cannot appear in a from clause. 10398 if (VD && DSAS->isThreadPrivate(VD)) { 10399 auto DVar = DSAS->getTopDSA(VD, false); 10400 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 10401 << getOpenMPClauseName(CKind); 10402 ReportOriginalDSA(SemaRef, DSAS, VD, DVar); 10403 continue; 10404 } 10405 10406 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 10407 // A list item cannot appear in both a map clause and a data-sharing 10408 // attribute clause on the same construct. 10409 10410 // Check conflicts with other map clause expressions. We check the conflicts 10411 // with the current construct separately from the enclosing data 10412 // environment, because the restrictions are different. We only have to 10413 // check conflicts across regions for the map clauses. 10414 if (CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 10415 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 10416 break; 10417 if (CKind == OMPC_map && 10418 CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 10419 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 10420 break; 10421 10422 // OpenMP 4.5 [2.10.5, target update Construct] 10423 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 10424 // If the type of a list item is a reference to a type T then the type will 10425 // be considered to be T for all purposes of this clause. 10426 QualType Type = CurDeclaration->getType().getNonReferenceType(); 10427 10428 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 10429 // A list item in a to or from clause must have a mappable type. 10430 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 10431 // A list item must have a mappable type. 10432 if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 10433 DSAS, Type)) 10434 continue; 10435 10436 if (CKind == OMPC_map) { 10437 // target enter data 10438 // OpenMP [2.10.2, Restrictions, p. 99] 10439 // A map-type must be specified in all map clauses and must be either 10440 // to or alloc. 10441 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 10442 if (DKind == OMPD_target_enter_data && 10443 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 10444 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 10445 << (IsMapTypeImplicit ? 1 : 0) 10446 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 10447 << getOpenMPDirectiveName(DKind); 10448 continue; 10449 } 10450 10451 // target exit_data 10452 // OpenMP [2.10.3, Restrictions, p. 102] 10453 // A map-type must be specified in all map clauses and must be either 10454 // from, release, or delete. 10455 if (DKind == OMPD_target_exit_data && 10456 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 10457 MapType == OMPC_MAP_delete)) { 10458 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 10459 << (IsMapTypeImplicit ? 1 : 0) 10460 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 10461 << getOpenMPDirectiveName(DKind); 10462 continue; 10463 } 10464 10465 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10466 // A list item cannot appear in both a map clause and a data-sharing 10467 // attribute clause on the same construct 10468 if (DKind == OMPD_target && VD) { 10469 auto DVar = DSAS->getTopDSA(VD, false); 10470 if (isOpenMPPrivate(DVar.CKind)) { 10471 SemaRef.Diag(ELoc, diag::err_omp_variable_in_map_and_dsa) 10472 << getOpenMPClauseName(DVar.CKind) 10473 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 10474 ReportOriginalDSA(SemaRef, DSAS, CurDeclaration, DVar); 10475 continue; 10476 } 10477 } 10478 } 10479 10480 // Save the current expression. 10481 MVLI.ProcessedVarList.push_back(RE); 10482 10483 // Store the components in the stack so that they can be used to check 10484 // against other clauses later on. 10485 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents); 10486 10487 // Save the components and declaration to create the clause. For purposes of 10488 // the clause creation, any component list that has has base 'this' uses 10489 // null as base declaration. 10490 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 10491 MVLI.VarComponents.back().append(CurComponents.begin(), 10492 CurComponents.end()); 10493 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 10494 : CurDeclaration); 10495 } 10496 } 10497 10498 OMPClause * 10499 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, 10500 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 10501 SourceLocation MapLoc, SourceLocation ColonLoc, 10502 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 10503 SourceLocation LParenLoc, SourceLocation EndLoc) { 10504 MappableVarListInfo MVLI(VarList); 10505 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc, 10506 MapType, IsMapTypeImplicit); 10507 10508 // We need to produce a map clause even if we don't have variables so that 10509 // other diagnostics related with non-existing map clauses are accurate. 10510 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10511 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 10512 MVLI.VarComponents, MapTypeModifier, MapType, 10513 IsMapTypeImplicit, MapLoc); 10514 } 10515 10516 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 10517 TypeResult ParsedType) { 10518 assert(ParsedType.isUsable()); 10519 10520 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 10521 if (ReductionType.isNull()) 10522 return QualType(); 10523 10524 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 10525 // A type name in a declare reduction directive cannot be a function type, an 10526 // array type, a reference type, or a type qualified with const, volatile or 10527 // restrict. 10528 if (ReductionType.hasQualifiers()) { 10529 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 10530 return QualType(); 10531 } 10532 10533 if (ReductionType->isFunctionType()) { 10534 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 10535 return QualType(); 10536 } 10537 if (ReductionType->isReferenceType()) { 10538 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 10539 return QualType(); 10540 } 10541 if (ReductionType->isArrayType()) { 10542 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 10543 return QualType(); 10544 } 10545 return ReductionType; 10546 } 10547 10548 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 10549 Scope *S, DeclContext *DC, DeclarationName Name, 10550 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 10551 AccessSpecifier AS, Decl *PrevDeclInScope) { 10552 SmallVector<Decl *, 8> Decls; 10553 Decls.reserve(ReductionTypes.size()); 10554 10555 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 10556 ForRedeclaration); 10557 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 10558 // A reduction-identifier may not be re-declared in the current scope for the 10559 // same type or for a type that is compatible according to the base language 10560 // rules. 10561 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 10562 OMPDeclareReductionDecl *PrevDRD = nullptr; 10563 bool InCompoundScope = true; 10564 if (S != nullptr) { 10565 // Find previous declaration with the same name not referenced in other 10566 // declarations. 10567 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 10568 InCompoundScope = 10569 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 10570 LookupName(Lookup, S); 10571 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 10572 /*AllowInlineNamespace=*/false); 10573 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 10574 auto Filter = Lookup.makeFilter(); 10575 while (Filter.hasNext()) { 10576 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 10577 if (InCompoundScope) { 10578 auto I = UsedAsPrevious.find(PrevDecl); 10579 if (I == UsedAsPrevious.end()) 10580 UsedAsPrevious[PrevDecl] = false; 10581 if (auto *D = PrevDecl->getPrevDeclInScope()) 10582 UsedAsPrevious[D] = true; 10583 } 10584 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 10585 PrevDecl->getLocation(); 10586 } 10587 Filter.done(); 10588 if (InCompoundScope) { 10589 for (auto &PrevData : UsedAsPrevious) { 10590 if (!PrevData.second) { 10591 PrevDRD = PrevData.first; 10592 break; 10593 } 10594 } 10595 } 10596 } else if (PrevDeclInScope != nullptr) { 10597 auto *PrevDRDInScope = PrevDRD = 10598 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 10599 do { 10600 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 10601 PrevDRDInScope->getLocation(); 10602 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 10603 } while (PrevDRDInScope != nullptr); 10604 } 10605 for (auto &TyData : ReductionTypes) { 10606 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 10607 bool Invalid = false; 10608 if (I != PreviousRedeclTypes.end()) { 10609 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 10610 << TyData.first; 10611 Diag(I->second, diag::note_previous_definition); 10612 Invalid = true; 10613 } 10614 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 10615 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 10616 Name, TyData.first, PrevDRD); 10617 DC->addDecl(DRD); 10618 DRD->setAccess(AS); 10619 Decls.push_back(DRD); 10620 if (Invalid) 10621 DRD->setInvalidDecl(); 10622 else 10623 PrevDRD = DRD; 10624 } 10625 10626 return DeclGroupPtrTy::make( 10627 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 10628 } 10629 10630 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 10631 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10632 10633 // Enter new function scope. 10634 PushFunctionScope(); 10635 getCurFunction()->setHasBranchProtectedScope(); 10636 getCurFunction()->setHasOMPDeclareReductionCombiner(); 10637 10638 if (S != nullptr) 10639 PushDeclContext(S, DRD); 10640 else 10641 CurContext = DRD; 10642 10643 PushExpressionEvaluationContext(PotentiallyEvaluated); 10644 10645 QualType ReductionType = DRD->getType(); 10646 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 10647 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 10648 // uses semantics of argument handles by value, but it should be passed by 10649 // reference. C lang does not support references, so pass all parameters as 10650 // pointers. 10651 // Create 'T omp_in;' variable. 10652 auto *OmpInParm = 10653 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 10654 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 10655 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 10656 // uses semantics of argument handles by value, but it should be passed by 10657 // reference. C lang does not support references, so pass all parameters as 10658 // pointers. 10659 // Create 'T omp_out;' variable. 10660 auto *OmpOutParm = 10661 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 10662 if (S != nullptr) { 10663 PushOnScopeChains(OmpInParm, S); 10664 PushOnScopeChains(OmpOutParm, S); 10665 } else { 10666 DRD->addDecl(OmpInParm); 10667 DRD->addDecl(OmpOutParm); 10668 } 10669 } 10670 10671 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 10672 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10673 DiscardCleanupsInEvaluationContext(); 10674 PopExpressionEvaluationContext(); 10675 10676 PopDeclContext(); 10677 PopFunctionScopeInfo(); 10678 10679 if (Combiner != nullptr) 10680 DRD->setCombiner(Combiner); 10681 else 10682 DRD->setInvalidDecl(); 10683 } 10684 10685 void Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 10686 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10687 10688 // Enter new function scope. 10689 PushFunctionScope(); 10690 getCurFunction()->setHasBranchProtectedScope(); 10691 10692 if (S != nullptr) 10693 PushDeclContext(S, DRD); 10694 else 10695 CurContext = DRD; 10696 10697 PushExpressionEvaluationContext(PotentiallyEvaluated); 10698 10699 QualType ReductionType = DRD->getType(); 10700 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 10701 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 10702 // uses semantics of argument handles by value, but it should be passed by 10703 // reference. C lang does not support references, so pass all parameters as 10704 // pointers. 10705 // Create 'T omp_priv;' variable. 10706 auto *OmpPrivParm = 10707 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 10708 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 10709 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 10710 // uses semantics of argument handles by value, but it should be passed by 10711 // reference. C lang does not support references, so pass all parameters as 10712 // pointers. 10713 // Create 'T omp_orig;' variable. 10714 auto *OmpOrigParm = 10715 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 10716 if (S != nullptr) { 10717 PushOnScopeChains(OmpPrivParm, S); 10718 PushOnScopeChains(OmpOrigParm, S); 10719 } else { 10720 DRD->addDecl(OmpPrivParm); 10721 DRD->addDecl(OmpOrigParm); 10722 } 10723 } 10724 10725 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, 10726 Expr *Initializer) { 10727 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10728 DiscardCleanupsInEvaluationContext(); 10729 PopExpressionEvaluationContext(); 10730 10731 PopDeclContext(); 10732 PopFunctionScopeInfo(); 10733 10734 if (Initializer != nullptr) 10735 DRD->setInitializer(Initializer); 10736 else 10737 DRD->setInvalidDecl(); 10738 } 10739 10740 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 10741 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 10742 for (auto *D : DeclReductions.get()) { 10743 if (IsValid) { 10744 auto *DRD = cast<OMPDeclareReductionDecl>(D); 10745 if (S != nullptr) 10746 PushOnScopeChains(DRD, S, /*AddToContext=*/false); 10747 } else 10748 D->setInvalidDecl(); 10749 } 10750 return DeclReductions; 10751 } 10752 10753 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 10754 SourceLocation StartLoc, 10755 SourceLocation LParenLoc, 10756 SourceLocation EndLoc) { 10757 Expr *ValExpr = NumTeams; 10758 10759 // OpenMP [teams Constrcut, Restrictions] 10760 // The num_teams expression must evaluate to a positive integer value. 10761 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 10762 /*StrictlyPositive=*/true)) 10763 return nullptr; 10764 10765 return new (Context) OMPNumTeamsClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10766 } 10767 10768 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 10769 SourceLocation StartLoc, 10770 SourceLocation LParenLoc, 10771 SourceLocation EndLoc) { 10772 Expr *ValExpr = ThreadLimit; 10773 10774 // OpenMP [teams Constrcut, Restrictions] 10775 // The thread_limit expression must evaluate to a positive integer value. 10776 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 10777 /*StrictlyPositive=*/true)) 10778 return nullptr; 10779 10780 return new (Context) OMPThreadLimitClause(ValExpr, StartLoc, LParenLoc, 10781 EndLoc); 10782 } 10783 10784 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 10785 SourceLocation StartLoc, 10786 SourceLocation LParenLoc, 10787 SourceLocation EndLoc) { 10788 Expr *ValExpr = Priority; 10789 10790 // OpenMP [2.9.1, task Constrcut] 10791 // The priority-value is a non-negative numerical scalar expression. 10792 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 10793 /*StrictlyPositive=*/false)) 10794 return nullptr; 10795 10796 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10797 } 10798 10799 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 10800 SourceLocation StartLoc, 10801 SourceLocation LParenLoc, 10802 SourceLocation EndLoc) { 10803 Expr *ValExpr = Grainsize; 10804 10805 // OpenMP [2.9.2, taskloop Constrcut] 10806 // The parameter of the grainsize clause must be a positive integer 10807 // expression. 10808 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 10809 /*StrictlyPositive=*/true)) 10810 return nullptr; 10811 10812 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10813 } 10814 10815 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 10816 SourceLocation StartLoc, 10817 SourceLocation LParenLoc, 10818 SourceLocation EndLoc) { 10819 Expr *ValExpr = NumTasks; 10820 10821 // OpenMP [2.9.2, taskloop Constrcut] 10822 // The parameter of the num_tasks clause must be a positive integer 10823 // expression. 10824 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 10825 /*StrictlyPositive=*/true)) 10826 return nullptr; 10827 10828 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10829 } 10830 10831 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 10832 SourceLocation LParenLoc, 10833 SourceLocation EndLoc) { 10834 // OpenMP [2.13.2, critical construct, Description] 10835 // ... where hint-expression is an integer constant expression that evaluates 10836 // to a valid lock hint. 10837 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 10838 if (HintExpr.isInvalid()) 10839 return nullptr; 10840 return new (Context) 10841 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 10842 } 10843 10844 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 10845 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 10846 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 10847 SourceLocation EndLoc) { 10848 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 10849 std::string Values; 10850 Values += "'"; 10851 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 10852 Values += "'"; 10853 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 10854 << Values << getOpenMPClauseName(OMPC_dist_schedule); 10855 return nullptr; 10856 } 10857 Expr *ValExpr = ChunkSize; 10858 Stmt *HelperValStmt = nullptr; 10859 if (ChunkSize) { 10860 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 10861 !ChunkSize->isInstantiationDependent() && 10862 !ChunkSize->containsUnexpandedParameterPack()) { 10863 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 10864 ExprResult Val = 10865 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 10866 if (Val.isInvalid()) 10867 return nullptr; 10868 10869 ValExpr = Val.get(); 10870 10871 // OpenMP [2.7.1, Restrictions] 10872 // chunk_size must be a loop invariant integer expression with a positive 10873 // value. 10874 llvm::APSInt Result; 10875 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 10876 if (Result.isSigned() && !Result.isStrictlyPositive()) { 10877 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 10878 << "dist_schedule" << ChunkSize->getSourceRange(); 10879 return nullptr; 10880 } 10881 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) && 10882 !CurContext->isDependentContext()) { 10883 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 10884 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 10885 HelperValStmt = buildPreInits(Context, Captures); 10886 } 10887 } 10888 } 10889 10890 return new (Context) 10891 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 10892 Kind, ValExpr, HelperValStmt); 10893 } 10894 10895 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 10896 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 10897 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 10898 SourceLocation KindLoc, SourceLocation EndLoc) { 10899 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 10900 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || 10901 Kind != OMPC_DEFAULTMAP_scalar) { 10902 std::string Value; 10903 SourceLocation Loc; 10904 Value += "'"; 10905 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 10906 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 10907 OMPC_DEFAULTMAP_MODIFIER_tofrom); 10908 Loc = MLoc; 10909 } else { 10910 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 10911 OMPC_DEFAULTMAP_scalar); 10912 Loc = KindLoc; 10913 } 10914 Value += "'"; 10915 Diag(Loc, diag::err_omp_unexpected_clause_value) 10916 << Value << getOpenMPClauseName(OMPC_defaultmap); 10917 return nullptr; 10918 } 10919 10920 return new (Context) 10921 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 10922 } 10923 10924 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 10925 DeclContext *CurLexicalContext = getCurLexicalContext(); 10926 if (!CurLexicalContext->isFileContext() && 10927 !CurLexicalContext->isExternCContext() && 10928 !CurLexicalContext->isExternCXXContext()) { 10929 Diag(Loc, diag::err_omp_region_not_file_context); 10930 return false; 10931 } 10932 if (IsInOpenMPDeclareTargetContext) { 10933 Diag(Loc, diag::err_omp_enclosed_declare_target); 10934 return false; 10935 } 10936 10937 IsInOpenMPDeclareTargetContext = true; 10938 return true; 10939 } 10940 10941 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 10942 assert(IsInOpenMPDeclareTargetContext && 10943 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 10944 10945 IsInOpenMPDeclareTargetContext = false; 10946 } 10947 10948 void 10949 Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, CXXScopeSpec &ScopeSpec, 10950 const DeclarationNameInfo &Id, 10951 OMPDeclareTargetDeclAttr::MapTypeTy MT, 10952 NamedDeclSetType &SameDirectiveDecls) { 10953 LookupResult Lookup(*this, Id, LookupOrdinaryName); 10954 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 10955 10956 if (Lookup.isAmbiguous()) 10957 return; 10958 Lookup.suppressDiagnostics(); 10959 10960 if (!Lookup.isSingleResult()) { 10961 if (TypoCorrection Corrected = 10962 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, 10963 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), 10964 CTK_ErrorRecovery)) { 10965 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 10966 << Id.getName()); 10967 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 10968 return; 10969 } 10970 10971 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 10972 return; 10973 } 10974 10975 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 10976 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { 10977 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 10978 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 10979 10980 if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) { 10981 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 10982 ND->addAttr(A); 10983 if (ASTMutationListener *ML = Context.getASTMutationListener()) 10984 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 10985 checkDeclIsAllowedInOpenMPTarget(nullptr, ND); 10986 } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) { 10987 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 10988 << Id.getName(); 10989 } 10990 } else 10991 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 10992 } 10993 10994 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 10995 Sema &SemaRef, Decl *D) { 10996 if (!D) 10997 return; 10998 Decl *LD = nullptr; 10999 if (isa<TagDecl>(D)) { 11000 LD = cast<TagDecl>(D)->getDefinition(); 11001 } else if (isa<VarDecl>(D)) { 11002 LD = cast<VarDecl>(D)->getDefinition(); 11003 11004 // If this is an implicit variable that is legal and we do not need to do 11005 // anything. 11006 if (cast<VarDecl>(D)->isImplicit()) { 11007 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11008 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 11009 D->addAttr(A); 11010 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 11011 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 11012 return; 11013 } 11014 11015 } else if (isa<FunctionDecl>(D)) { 11016 const FunctionDecl *FD = nullptr; 11017 if (cast<FunctionDecl>(D)->hasBody(FD)) 11018 LD = const_cast<FunctionDecl *>(FD); 11019 11020 // If the definition is associated with the current declaration in the 11021 // target region (it can be e.g. a lambda) that is legal and we do not need 11022 // to do anything else. 11023 if (LD == D) { 11024 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11025 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 11026 D->addAttr(A); 11027 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 11028 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 11029 return; 11030 } 11031 } 11032 if (!LD) 11033 LD = D; 11034 if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() && 11035 (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) { 11036 // Outlined declaration is not declared target. 11037 if (LD->isOutOfLine()) { 11038 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 11039 SemaRef.Diag(SL, diag::note_used_here) << SR; 11040 } else { 11041 DeclContext *DC = LD->getDeclContext(); 11042 while (DC) { 11043 if (isa<FunctionDecl>(DC) && 11044 cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>()) 11045 break; 11046 DC = DC->getParent(); 11047 } 11048 if (DC) 11049 return; 11050 11051 // Is not declared in target context. 11052 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 11053 SemaRef.Diag(SL, diag::note_used_here) << SR; 11054 } 11055 // Mark decl as declared target to prevent further diagnostic. 11056 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11057 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 11058 D->addAttr(A); 11059 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 11060 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 11061 } 11062 } 11063 11064 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 11065 Sema &SemaRef, DSAStackTy *Stack, 11066 ValueDecl *VD) { 11067 if (VD->hasAttr<OMPDeclareTargetDeclAttr>()) 11068 return true; 11069 if (!CheckTypeMappable(SL, SR, SemaRef, Stack, VD->getType())) 11070 return false; 11071 return true; 11072 } 11073 11074 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D) { 11075 if (!D || D->isInvalidDecl()) 11076 return; 11077 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 11078 SourceLocation SL = E ? E->getLocStart() : D->getLocation(); 11079 // 2.10.6: threadprivate variable cannot appear in a declare target directive. 11080 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 11081 if (DSAStack->isThreadPrivate(VD)) { 11082 Diag(SL, diag::err_omp_threadprivate_in_target); 11083 ReportOriginalDSA(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 11084 return; 11085 } 11086 } 11087 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 11088 // Problem if any with var declared with incomplete type will be reported 11089 // as normal, so no need to check it here. 11090 if ((E || !VD->getType()->isIncompleteType()) && 11091 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) { 11092 // Mark decl as declared target to prevent further diagnostic. 11093 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) { 11094 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11095 Context, OMPDeclareTargetDeclAttr::MT_To); 11096 VD->addAttr(A); 11097 if (ASTMutationListener *ML = Context.getASTMutationListener()) 11098 ML->DeclarationMarkedOpenMPDeclareTarget(VD, A); 11099 } 11100 return; 11101 } 11102 } 11103 if (!E) { 11104 // Checking declaration inside declare target region. 11105 if (!D->hasAttr<OMPDeclareTargetDeclAttr>() && 11106 (isa<VarDecl>(D) || isa<FunctionDecl>(D))) { 11107 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11108 Context, OMPDeclareTargetDeclAttr::MT_To); 11109 D->addAttr(A); 11110 if (ASTMutationListener *ML = Context.getASTMutationListener()) 11111 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 11112 } 11113 return; 11114 } 11115 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 11116 } 11117 11118 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 11119 SourceLocation StartLoc, 11120 SourceLocation LParenLoc, 11121 SourceLocation EndLoc) { 11122 MappableVarListInfo MVLI(VarList); 11123 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc); 11124 if (MVLI.ProcessedVarList.empty()) 11125 return nullptr; 11126 11127 return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11128 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 11129 MVLI.VarComponents); 11130 } 11131 11132 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 11133 SourceLocation StartLoc, 11134 SourceLocation LParenLoc, 11135 SourceLocation EndLoc) { 11136 MappableVarListInfo MVLI(VarList); 11137 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc); 11138 if (MVLI.ProcessedVarList.empty()) 11139 return nullptr; 11140 11141 return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11142 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 11143 MVLI.VarComponents); 11144 } 11145