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 /// Struct that associates a component with the clause kind where they are 76 /// found. 77 struct MappedExprComponentTy { 78 OMPClauseMappableExprCommon::MappableExprComponentLists Components; 79 OpenMPClauseKind Kind = OMPC_unknown; 80 }; 81 typedef llvm::DenseMap<ValueDecl *, MappedExprComponentTy> 82 MappedExprComponentsTy; 83 typedef llvm::StringMap<std::pair<OMPCriticalDirective *, llvm::APSInt>> 84 CriticalsWithHintsTy; 85 typedef llvm::DenseMap<OMPDependClause *, OperatorOffsetTy> 86 DoacrossDependMapTy; 87 88 struct SharingMapTy final { 89 DeclSAMapTy SharingMap; 90 AlignedMapTy AlignedMap; 91 MappedExprComponentsTy MappedExprComponents; 92 LoopControlVariablesMapTy LCVMap; 93 DefaultDataSharingAttributes DefaultAttr = DSA_unspecified; 94 SourceLocation DefaultAttrLoc; 95 OpenMPDirectiveKind Directive = OMPD_unknown; 96 DeclarationNameInfo DirectiveName; 97 Scope *CurScope = nullptr; 98 SourceLocation ConstructLoc; 99 /// Set of 'depend' clauses with 'sink|source' dependence kind. Required to 100 /// get the data (loop counters etc.) about enclosing loop-based construct. 101 /// This data is required during codegen. 102 DoacrossDependMapTy DoacrossDepends; 103 /// \brief first argument (Expr *) contains optional argument of the 104 /// 'ordered' clause, the second one is true if the regions has 'ordered' 105 /// clause, false otherwise. 106 llvm::PointerIntPair<Expr *, 1, bool> OrderedRegion; 107 bool NowaitRegion = false; 108 bool CancelRegion = false; 109 unsigned AssociatedLoops = 1; 110 SourceLocation InnerTeamsRegionLoc; 111 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 112 Scope *CurScope, SourceLocation Loc) 113 : Directive(DKind), DirectiveName(Name), CurScope(CurScope), 114 ConstructLoc(Loc) {} 115 SharingMapTy() {} 116 }; 117 118 typedef SmallVector<SharingMapTy, 4> StackTy; 119 120 /// \brief Stack of used declaration and their data-sharing attributes. 121 StackTy Stack; 122 /// \brief true, if check for DSA must be from parent directive, false, if 123 /// from current directive. 124 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 125 Sema &SemaRef; 126 bool ForceCapturing = false; 127 CriticalsWithHintsTy Criticals; 128 129 typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; 130 131 DSAVarData getDSA(StackTy::reverse_iterator &Iter, ValueDecl *D); 132 133 /// \brief Checks if the variable is a local for OpenMP region. 134 bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter); 135 136 public: 137 explicit DSAStackTy(Sema &S) : Stack(1), SemaRef(S) {} 138 139 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 140 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 141 142 bool isForceVarCapturing() const { return ForceCapturing; } 143 void setForceVarCapturing(bool V) { ForceCapturing = V; } 144 145 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 146 Scope *CurScope, SourceLocation Loc) { 147 Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc)); 148 Stack.back().DefaultAttrLoc = Loc; 149 } 150 151 void pop() { 152 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!"); 153 Stack.pop_back(); 154 } 155 156 void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) { 157 Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint); 158 } 159 const std::pair<OMPCriticalDirective *, llvm::APSInt> 160 getCriticalWithHint(const DeclarationNameInfo &Name) const { 161 auto I = Criticals.find(Name.getAsString()); 162 if (I != Criticals.end()) 163 return I->second; 164 return std::make_pair(nullptr, llvm::APSInt()); 165 } 166 /// \brief If 'aligned' declaration for given variable \a D was not seen yet, 167 /// add it and return NULL; otherwise return previous occurrence's expression 168 /// for diagnostics. 169 Expr *addUniqueAligned(ValueDecl *D, Expr *NewDE); 170 171 /// \brief Register specified variable as loop control variable. 172 void addLoopControlVariable(ValueDecl *D, VarDecl *Capture); 173 /// \brief Check if the specified variable is a loop control variable for 174 /// current region. 175 /// \return The index of the loop control variable in the list of associated 176 /// for-loops (from outer to inner). 177 LCDeclInfo isLoopControlVariable(ValueDecl *D); 178 /// \brief Check if the specified variable is a loop control variable for 179 /// parent region. 180 /// \return The index of the loop control variable in the list of associated 181 /// for-loops (from outer to inner). 182 LCDeclInfo isParentLoopControlVariable(ValueDecl *D); 183 /// \brief Get the loop control variable for the I-th loop (or nullptr) in 184 /// parent directive. 185 ValueDecl *getParentLoopControlVariable(unsigned I); 186 187 /// \brief Adds explicit data sharing attribute to the specified declaration. 188 void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 189 DeclRefExpr *PrivateCopy = nullptr); 190 191 /// \brief Returns data sharing attributes from top of the stack for the 192 /// specified declaration. 193 DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 194 /// \brief Returns data-sharing attributes for the specified declaration. 195 DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent); 196 /// \brief Checks if the specified variables has data-sharing attributes which 197 /// match specified \a CPred predicate in any directive which matches \a DPred 198 /// predicate. 199 DSAVarData hasDSA(ValueDecl *D, 200 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 201 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 202 bool FromParent); 203 /// \brief Checks if the specified variables has data-sharing attributes which 204 /// match specified \a CPred predicate in any innermost directive which 205 /// matches \a DPred predicate. 206 DSAVarData 207 hasInnermostDSA(ValueDecl *D, 208 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 209 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 210 bool FromParent); 211 /// \brief Checks if the specified variables has explicit data-sharing 212 /// attributes which match specified \a CPred predicate at the specified 213 /// OpenMP region. 214 bool hasExplicitDSA(ValueDecl *D, 215 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 216 unsigned Level, bool NotLastprivate = false); 217 218 /// \brief Returns true if the directive at level \Level matches in the 219 /// specified \a DPred predicate. 220 bool hasExplicitDirective( 221 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 222 unsigned Level); 223 224 /// \brief Finds a directive which matches specified \a DPred predicate. 225 bool hasDirective(const llvm::function_ref<bool(OpenMPDirectiveKind, 226 const DeclarationNameInfo &, 227 SourceLocation)> &DPred, 228 bool FromParent); 229 230 /// \brief Returns currently analyzed directive. 231 OpenMPDirectiveKind getCurrentDirective() const { 232 return Stack.back().Directive; 233 } 234 /// \brief Returns parent directive. 235 OpenMPDirectiveKind getParentDirective() const { 236 if (Stack.size() > 2) 237 return Stack[Stack.size() - 2].Directive; 238 return OMPD_unknown; 239 } 240 241 /// \brief Set default data sharing attribute to none. 242 void setDefaultDSANone(SourceLocation Loc) { 243 Stack.back().DefaultAttr = DSA_none; 244 Stack.back().DefaultAttrLoc = Loc; 245 } 246 /// \brief Set default data sharing attribute to shared. 247 void setDefaultDSAShared(SourceLocation Loc) { 248 Stack.back().DefaultAttr = DSA_shared; 249 Stack.back().DefaultAttrLoc = Loc; 250 } 251 252 DefaultDataSharingAttributes getDefaultDSA() const { 253 return Stack.back().DefaultAttr; 254 } 255 SourceLocation getDefaultDSALocation() const { 256 return Stack.back().DefaultAttrLoc; 257 } 258 259 /// \brief Checks if the specified variable is a threadprivate. 260 bool isThreadPrivate(VarDecl *D) { 261 DSAVarData DVar = getTopDSA(D, false); 262 return isOpenMPThreadPrivate(DVar.CKind); 263 } 264 265 /// \brief Marks current region as ordered (it has an 'ordered' clause). 266 void setOrderedRegion(bool IsOrdered, Expr *Param) { 267 Stack.back().OrderedRegion.setInt(IsOrdered); 268 Stack.back().OrderedRegion.setPointer(Param); 269 } 270 /// \brief Returns true, if parent region is ordered (has associated 271 /// 'ordered' clause), false - otherwise. 272 bool isParentOrderedRegion() const { 273 if (Stack.size() > 2) 274 return Stack[Stack.size() - 2].OrderedRegion.getInt(); 275 return false; 276 } 277 /// \brief Returns optional parameter for the ordered region. 278 Expr *getParentOrderedRegionParam() const { 279 if (Stack.size() > 2) 280 return Stack[Stack.size() - 2].OrderedRegion.getPointer(); 281 return nullptr; 282 } 283 /// \brief Marks current region as nowait (it has a 'nowait' clause). 284 void setNowaitRegion(bool IsNowait = true) { 285 Stack.back().NowaitRegion = IsNowait; 286 } 287 /// \brief Returns true, if parent region is nowait (has associated 288 /// 'nowait' clause), false - otherwise. 289 bool isParentNowaitRegion() const { 290 if (Stack.size() > 2) 291 return Stack[Stack.size() - 2].NowaitRegion; 292 return false; 293 } 294 /// \brief Marks parent region as cancel region. 295 void setParentCancelRegion(bool Cancel = true) { 296 if (Stack.size() > 2) 297 Stack[Stack.size() - 2].CancelRegion = 298 Stack[Stack.size() - 2].CancelRegion || Cancel; 299 } 300 /// \brief Return true if current region has inner cancel construct. 301 bool isCancelRegion() const { return Stack.back().CancelRegion; } 302 303 /// \brief Set collapse value for the region. 304 void setAssociatedLoops(unsigned Val) { Stack.back().AssociatedLoops = Val; } 305 /// \brief Return collapse value for region. 306 unsigned getAssociatedLoops() const { return Stack.back().AssociatedLoops; } 307 308 /// \brief Marks current target region as one with closely nested teams 309 /// region. 310 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 311 if (Stack.size() > 2) 312 Stack[Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc; 313 } 314 /// \brief Returns true, if current region has closely nested teams region. 315 bool hasInnerTeamsRegion() const { 316 return getInnerTeamsRegionLoc().isValid(); 317 } 318 /// \brief Returns location of the nested teams region (if any). 319 SourceLocation getInnerTeamsRegionLoc() const { 320 if (Stack.size() > 1) 321 return Stack.back().InnerTeamsRegionLoc; 322 return SourceLocation(); 323 } 324 325 Scope *getCurScope() const { return Stack.back().CurScope; } 326 Scope *getCurScope() { return Stack.back().CurScope; } 327 SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; } 328 329 // Do the check specified in \a Check to all component lists and return true 330 // if any issue is found. 331 bool checkMappableExprComponentListsForDecl( 332 ValueDecl *VD, bool CurrentRegionOnly, 333 const llvm::function_ref< 334 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 335 OpenMPClauseKind)> &Check) { 336 auto SI = Stack.rbegin(); 337 auto SE = Stack.rend(); 338 339 if (SI == SE) 340 return false; 341 342 if (CurrentRegionOnly) { 343 SE = std::next(SI); 344 } else { 345 ++SI; 346 } 347 348 for (; SI != SE; ++SI) { 349 auto MI = SI->MappedExprComponents.find(VD); 350 if (MI != SI->MappedExprComponents.end()) 351 for (auto &L : MI->second.Components) 352 if (Check(L, MI->second.Kind)) 353 return true; 354 } 355 return false; 356 } 357 358 // Create a new mappable expression component list associated with a given 359 // declaration and initialize it with the provided list of components. 360 void addMappableExpressionComponents( 361 ValueDecl *VD, 362 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 363 OpenMPClauseKind WhereFoundClauseKind) { 364 assert(Stack.size() > 1 && 365 "Not expecting to retrieve components from a empty stack!"); 366 auto &MEC = Stack.back().MappedExprComponents[VD]; 367 // Create new entry and append the new components there. 368 MEC.Components.resize(MEC.Components.size() + 1); 369 MEC.Components.back().append(Components.begin(), Components.end()); 370 MEC.Kind = WhereFoundClauseKind; 371 } 372 373 unsigned getNestingLevel() const { 374 assert(Stack.size() > 1); 375 return Stack.size() - 2; 376 } 377 void addDoacrossDependClause(OMPDependClause *C, OperatorOffsetTy &OpsOffs) { 378 assert(Stack.size() > 2); 379 assert(isOpenMPWorksharingDirective(Stack[Stack.size() - 2].Directive)); 380 Stack[Stack.size() - 2].DoacrossDepends.insert({C, OpsOffs}); 381 } 382 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 383 getDoacrossDependClauses() const { 384 assert(Stack.size() > 1); 385 if (isOpenMPWorksharingDirective(Stack[Stack.size() - 1].Directive)) { 386 auto &Ref = Stack[Stack.size() - 1].DoacrossDepends; 387 return llvm::make_range(Ref.begin(), Ref.end()); 388 } 389 return llvm::make_range(Stack[0].DoacrossDepends.end(), 390 Stack[0].DoacrossDepends.end()); 391 } 392 }; 393 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { 394 return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) || 395 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; 396 } 397 } // namespace 398 399 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 400 auto *VD = dyn_cast<VarDecl>(D); 401 auto *FD = dyn_cast<FieldDecl>(D); 402 if (VD != nullptr) { 403 VD = VD->getCanonicalDecl(); 404 D = VD; 405 } else { 406 assert(FD); 407 FD = FD->getCanonicalDecl(); 408 D = FD; 409 } 410 return D; 411 } 412 413 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter, 414 ValueDecl *D) { 415 D = getCanonicalDecl(D); 416 auto *VD = dyn_cast<VarDecl>(D); 417 auto *FD = dyn_cast<FieldDecl>(D); 418 DSAVarData DVar; 419 if (Iter == std::prev(Stack.rend())) { 420 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 421 // in a region but not in construct] 422 // File-scope or namespace-scope variables referenced in called routines 423 // in the region are shared unless they appear in a threadprivate 424 // directive. 425 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D)) 426 DVar.CKind = OMPC_shared; 427 428 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 429 // in a region but not in construct] 430 // Variables with static storage duration that are declared in called 431 // routines in the region are shared. 432 if (VD && VD->hasGlobalStorage()) 433 DVar.CKind = OMPC_shared; 434 435 // Non-static data members are shared by default. 436 if (FD) 437 DVar.CKind = OMPC_shared; 438 439 return DVar; 440 } 441 442 DVar.DKind = Iter->Directive; 443 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 444 // in a Construct, C/C++, predetermined, p.1] 445 // Variables with automatic storage duration that are declared in a scope 446 // inside the construct are private. 447 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 448 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 449 DVar.CKind = OMPC_private; 450 return DVar; 451 } 452 453 // Explicitly specified attributes and local variables with predetermined 454 // attributes. 455 if (Iter->SharingMap.count(D)) { 456 DVar.RefExpr = Iter->SharingMap[D].RefExpr.getPointer(); 457 DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy; 458 DVar.CKind = Iter->SharingMap[D].Attributes; 459 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 460 return DVar; 461 } 462 463 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 464 // in a Construct, C/C++, implicitly determined, p.1] 465 // In a parallel or task construct, the data-sharing attributes of these 466 // variables are determined by the default clause, if present. 467 switch (Iter->DefaultAttr) { 468 case DSA_shared: 469 DVar.CKind = OMPC_shared; 470 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 471 return DVar; 472 case DSA_none: 473 return DVar; 474 case DSA_unspecified: 475 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 476 // in a Construct, implicitly determined, p.2] 477 // In a parallel construct, if no default clause is present, these 478 // variables are shared. 479 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 480 if (isOpenMPParallelDirective(DVar.DKind) || 481 isOpenMPTeamsDirective(DVar.DKind)) { 482 DVar.CKind = OMPC_shared; 483 return DVar; 484 } 485 486 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 487 // in a Construct, implicitly determined, p.4] 488 // In a task construct, if no default clause is present, a variable that in 489 // the enclosing context is determined to be shared by all implicit tasks 490 // bound to the current team is shared. 491 if (isOpenMPTaskingDirective(DVar.DKind)) { 492 DSAVarData DVarTemp; 493 for (StackTy::reverse_iterator I = std::next(Iter), EE = Stack.rend(); 494 I != EE; ++I) { 495 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 496 // Referenced in a Construct, implicitly determined, p.6] 497 // In a task construct, if no default clause is present, a variable 498 // whose data-sharing attribute is not determined by the rules above is 499 // firstprivate. 500 DVarTemp = getDSA(I, D); 501 if (DVarTemp.CKind != OMPC_shared) { 502 DVar.RefExpr = nullptr; 503 DVar.CKind = OMPC_firstprivate; 504 return DVar; 505 } 506 if (isParallelOrTaskRegion(I->Directive)) 507 break; 508 } 509 DVar.CKind = 510 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 511 return DVar; 512 } 513 } 514 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 515 // in a Construct, implicitly determined, p.3] 516 // For constructs other than task, if no default clause is present, these 517 // variables inherit their data-sharing attributes from the enclosing 518 // context. 519 return getDSA(++Iter, D); 520 } 521 522 Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) { 523 assert(Stack.size() > 1 && "Data sharing attributes stack is empty"); 524 D = getCanonicalDecl(D); 525 auto It = Stack.back().AlignedMap.find(D); 526 if (It == Stack.back().AlignedMap.end()) { 527 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 528 Stack.back().AlignedMap[D] = NewDE; 529 return nullptr; 530 } else { 531 assert(It->second && "Unexpected nullptr expr in the aligned map"); 532 return It->second; 533 } 534 return nullptr; 535 } 536 537 void DSAStackTy::addLoopControlVariable(ValueDecl *D, VarDecl *Capture) { 538 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 539 D = getCanonicalDecl(D); 540 Stack.back().LCVMap.insert( 541 std::make_pair(D, LCDeclInfo(Stack.back().LCVMap.size() + 1, Capture))); 542 } 543 544 DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(ValueDecl *D) { 545 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 546 D = getCanonicalDecl(D); 547 return Stack.back().LCVMap.count(D) > 0 ? Stack.back().LCVMap[D] 548 : LCDeclInfo(0, nullptr); 549 } 550 551 DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(ValueDecl *D) { 552 assert(Stack.size() > 2 && "Data-sharing attributes stack is empty"); 553 D = getCanonicalDecl(D); 554 return Stack[Stack.size() - 2].LCVMap.count(D) > 0 555 ? Stack[Stack.size() - 2].LCVMap[D] 556 : LCDeclInfo(0, nullptr); 557 } 558 559 ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) { 560 assert(Stack.size() > 2 && "Data-sharing attributes stack is empty"); 561 if (Stack[Stack.size() - 2].LCVMap.size() < I) 562 return nullptr; 563 for (auto &Pair : Stack[Stack.size() - 2].LCVMap) { 564 if (Pair.second.first == I) 565 return Pair.first; 566 } 567 return nullptr; 568 } 569 570 void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 571 DeclRefExpr *PrivateCopy) { 572 D = getCanonicalDecl(D); 573 if (A == OMPC_threadprivate) { 574 auto &Data = Stack[0].SharingMap[D]; 575 Data.Attributes = A; 576 Data.RefExpr.setPointer(E); 577 Data.PrivateCopy = nullptr; 578 } else { 579 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 580 auto &Data = Stack.back().SharingMap[D]; 581 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 582 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 583 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 584 (isLoopControlVariable(D).first && A == OMPC_private)); 585 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 586 Data.RefExpr.setInt(/*IntVal=*/true); 587 return; 588 } 589 const bool IsLastprivate = 590 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 591 Data.Attributes = A; 592 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 593 Data.PrivateCopy = PrivateCopy; 594 if (PrivateCopy) { 595 auto &Data = Stack.back().SharingMap[PrivateCopy->getDecl()]; 596 Data.Attributes = A; 597 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 598 Data.PrivateCopy = nullptr; 599 } 600 } 601 } 602 603 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) { 604 D = D->getCanonicalDecl(); 605 if (Stack.size() > 2) { 606 reverse_iterator I = Iter, E = std::prev(Stack.rend()); 607 Scope *TopScope = nullptr; 608 while (I != E && !isParallelOrTaskRegion(I->Directive)) { 609 ++I; 610 } 611 if (I == E) 612 return false; 613 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 614 Scope *CurScope = getCurScope(); 615 while (CurScope != TopScope && !CurScope->isDeclScope(D)) { 616 CurScope = CurScope->getParent(); 617 } 618 return CurScope != TopScope; 619 } 620 return false; 621 } 622 623 /// \brief Build a variable declaration for OpenMP loop iteration variable. 624 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 625 StringRef Name, const AttrVec *Attrs = nullptr) { 626 DeclContext *DC = SemaRef.CurContext; 627 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 628 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 629 VarDecl *Decl = 630 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 631 if (Attrs) { 632 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 633 I != E; ++I) 634 Decl->addAttr(*I); 635 } 636 Decl->setImplicit(); 637 return Decl; 638 } 639 640 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 641 SourceLocation Loc, 642 bool RefersToCapture = false) { 643 D->setReferenced(); 644 D->markUsed(S.Context); 645 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 646 SourceLocation(), D, RefersToCapture, Loc, Ty, 647 VK_LValue); 648 } 649 650 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) { 651 D = getCanonicalDecl(D); 652 DSAVarData DVar; 653 654 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 655 // in a Construct, C/C++, predetermined, p.1] 656 // Variables appearing in threadprivate directives are threadprivate. 657 auto *VD = dyn_cast<VarDecl>(D); 658 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 659 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 660 SemaRef.getLangOpts().OpenMPUseTLS && 661 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 662 (VD && VD->getStorageClass() == SC_Register && 663 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 664 addDSA(D, buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 665 D->getLocation()), 666 OMPC_threadprivate); 667 } 668 if (Stack[0].SharingMap.count(D)) { 669 DVar.RefExpr = Stack[0].SharingMap[D].RefExpr.getPointer(); 670 DVar.CKind = OMPC_threadprivate; 671 return DVar; 672 } 673 674 if (Stack.size() == 1) { 675 // Not in OpenMP execution region and top scope was already checked. 676 return DVar; 677 } 678 679 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 680 // in a Construct, C/C++, predetermined, p.4] 681 // Static data members are shared. 682 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 683 // in a Construct, C/C++, predetermined, p.7] 684 // Variables with static storage duration that are declared in a scope 685 // inside the construct are shared. 686 auto &&MatchesAlways = [](OpenMPDirectiveKind) -> bool { return true; }; 687 if (VD && VD->isStaticDataMember()) { 688 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 689 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 690 return DVar; 691 692 DVar.CKind = OMPC_shared; 693 return DVar; 694 } 695 696 QualType Type = D->getType().getNonReferenceType().getCanonicalType(); 697 bool IsConstant = Type.isConstant(SemaRef.getASTContext()); 698 Type = SemaRef.getASTContext().getBaseElementType(Type); 699 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 700 // in a Construct, C/C++, predetermined, p.6] 701 // Variables with const qualified type having no mutable member are 702 // shared. 703 CXXRecordDecl *RD = 704 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 705 if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 706 if (auto *CTD = CTSD->getSpecializedTemplate()) 707 RD = CTD->getTemplatedDecl(); 708 if (IsConstant && 709 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() && 710 RD->hasMutableFields())) { 711 // Variables with const-qualified type having no mutable member may be 712 // listed in a firstprivate clause, even if they are static data members. 713 DSAVarData DVarTemp = hasDSA( 714 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_firstprivate; }, 715 MatchesAlways, FromParent); 716 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 717 return DVar; 718 719 DVar.CKind = OMPC_shared; 720 return DVar; 721 } 722 723 // Explicitly specified attributes and local variables with predetermined 724 // attributes. 725 auto StartI = std::next(Stack.rbegin()); 726 auto EndI = std::prev(Stack.rend()); 727 if (FromParent && StartI != EndI) { 728 StartI = std::next(StartI); 729 } 730 auto I = std::prev(StartI); 731 if (I->SharingMap.count(D)) { 732 DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer(); 733 DVar.PrivateCopy = I->SharingMap[D].PrivateCopy; 734 DVar.CKind = I->SharingMap[D].Attributes; 735 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 736 } 737 738 return DVar; 739 } 740 741 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 742 bool FromParent) { 743 D = getCanonicalDecl(D); 744 auto StartI = Stack.rbegin(); 745 auto EndI = std::prev(Stack.rend()); 746 if (FromParent && StartI != EndI) { 747 StartI = std::next(StartI); 748 } 749 return getDSA(StartI, D); 750 } 751 752 DSAStackTy::DSAVarData 753 DSAStackTy::hasDSA(ValueDecl *D, 754 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 755 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 756 bool FromParent) { 757 D = getCanonicalDecl(D); 758 auto StartI = std::next(Stack.rbegin()); 759 auto EndI = Stack.rend(); 760 if (FromParent && StartI != EndI) { 761 StartI = std::next(StartI); 762 } 763 for (auto I = StartI, EE = EndI; I != EE; ++I) { 764 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) 765 continue; 766 DSAVarData DVar = getDSA(I, D); 767 if (CPred(DVar.CKind)) 768 return DVar; 769 } 770 return DSAVarData(); 771 } 772 773 DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 774 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 775 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 776 bool FromParent) { 777 D = getCanonicalDecl(D); 778 auto StartI = std::next(Stack.rbegin()); 779 auto EndI = Stack.rend(); 780 if (FromParent && StartI != EndI) 781 StartI = std::next(StartI); 782 if (StartI == EndI || !DPred(StartI->Directive)) 783 return DSAVarData(); 784 DSAVarData DVar = getDSA(StartI, D); 785 return CPred(DVar.CKind) ? DVar : 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 if (Ty->isReferenceType()) 907 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 908 909 // Locate map clauses and see if the variable being captured is referred to 910 // in any of those clauses. Here we only care about variables, not fields, 911 // because fields are part of aggregates. 912 bool IsVariableUsedInMapClause = false; 913 bool IsVariableAssociatedWithSection = false; 914 915 DSAStack->checkMappableExprComponentListsForDecl( 916 D, /*CurrentRegionOnly=*/true, 917 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef 918 MapExprComponents, 919 OpenMPClauseKind WhereFoundClauseKind) { 920 // Only the map clause information influences how a variable is 921 // captured. E.g. is_device_ptr does not require changing the default 922 // behaviour. 923 if (WhereFoundClauseKind != OMPC_map) 924 return false; 925 926 auto EI = MapExprComponents.rbegin(); 927 auto EE = MapExprComponents.rend(); 928 929 assert(EI != EE && "Invalid map expression!"); 930 931 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 932 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 933 934 ++EI; 935 if (EI == EE) 936 return false; 937 938 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 939 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 940 isa<MemberExpr>(EI->getAssociatedExpression())) { 941 IsVariableAssociatedWithSection = true; 942 // There is nothing more we need to know about this variable. 943 return true; 944 } 945 946 // Keep looking for more map info. 947 return false; 948 }); 949 950 if (IsVariableUsedInMapClause) { 951 // If variable is identified in a map clause it is always captured by 952 // reference except if it is a pointer that is dereferenced somehow. 953 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 954 } else { 955 // By default, all the data that has a scalar type is mapped by copy. 956 IsByRef = !Ty->isScalarType(); 957 } 958 } 959 960 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 961 IsByRef = !DSAStack->hasExplicitDSA( 962 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 963 Level, /*NotLastprivate=*/true); 964 } 965 966 // When passing data by copy, we need to make sure it fits the uintptr size 967 // and alignment, because the runtime library only deals with uintptr types. 968 // If it does not fit the uintptr size, we need to pass the data by reference 969 // instead. 970 if (!IsByRef && 971 (Ctx.getTypeSizeInChars(Ty) > 972 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 973 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 974 IsByRef = true; 975 } 976 977 return IsByRef; 978 } 979 980 unsigned Sema::getOpenMPNestingLevel() const { 981 assert(getLangOpts().OpenMP); 982 return DSAStack->getNestingLevel(); 983 } 984 985 VarDecl *Sema::IsOpenMPCapturedDecl(ValueDecl *D) { 986 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 987 D = getCanonicalDecl(D); 988 989 // If we are attempting to capture a global variable in a directive with 990 // 'target' we return true so that this global is also mapped to the device. 991 // 992 // FIXME: If the declaration is enclosed in a 'declare target' directive, 993 // then it should not be captured. Therefore, an extra check has to be 994 // inserted here once support for 'declare target' is added. 995 // 996 auto *VD = dyn_cast<VarDecl>(D); 997 if (VD && !VD->hasLocalStorage()) { 998 if (DSAStack->getCurrentDirective() == OMPD_target && 999 !DSAStack->isClauseParsingMode()) 1000 return VD; 1001 if (DSAStack->hasDirective( 1002 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1003 SourceLocation) -> bool { 1004 return isOpenMPTargetExecutionDirective(K); 1005 }, 1006 false)) 1007 return VD; 1008 } 1009 1010 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1011 (!DSAStack->isClauseParsingMode() || 1012 DSAStack->getParentDirective() != OMPD_unknown)) { 1013 auto &&Info = DSAStack->isLoopControlVariable(D); 1014 if (Info.first || 1015 (VD && VD->hasLocalStorage() && 1016 isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || 1017 (VD && DSAStack->isForceVarCapturing())) 1018 return VD ? VD : Info.second; 1019 auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1020 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1021 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1022 DVarPrivate = DSAStack->hasDSA( 1023 D, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, 1024 DSAStack->isClauseParsingMode()); 1025 if (DVarPrivate.CKind != OMPC_unknown) 1026 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1027 } 1028 return nullptr; 1029 } 1030 1031 bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) { 1032 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1033 return DSAStack->hasExplicitDSA( 1034 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, Level); 1035 } 1036 1037 bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) { 1038 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1039 // Return true if the current level is no longer enclosed in a target region. 1040 1041 auto *VD = dyn_cast<VarDecl>(D); 1042 return VD && !VD->hasLocalStorage() && 1043 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1044 Level); 1045 } 1046 1047 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1048 1049 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1050 const DeclarationNameInfo &DirName, 1051 Scope *CurScope, SourceLocation Loc) { 1052 DSAStack->push(DKind, DirName, CurScope, Loc); 1053 PushExpressionEvaluationContext(PotentiallyEvaluated); 1054 } 1055 1056 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1057 DSAStack->setClauseParsingMode(K); 1058 } 1059 1060 void Sema::EndOpenMPClause() { 1061 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1062 } 1063 1064 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1065 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1066 // A variable of class type (or array thereof) that appears in a lastprivate 1067 // clause requires an accessible, unambiguous default constructor for the 1068 // class type, unless the list item is also specified in a firstprivate 1069 // clause. 1070 if (auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1071 for (auto *C : D->clauses()) { 1072 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1073 SmallVector<Expr *, 8> PrivateCopies; 1074 for (auto *DE : Clause->varlists()) { 1075 if (DE->isValueDependent() || DE->isTypeDependent()) { 1076 PrivateCopies.push_back(nullptr); 1077 continue; 1078 } 1079 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1080 VarDecl *VD = cast<VarDecl>(DRE->getDecl()); 1081 QualType Type = VD->getType().getNonReferenceType(); 1082 auto DVar = DSAStack->getTopDSA(VD, false); 1083 if (DVar.CKind == OMPC_lastprivate) { 1084 // Generate helper private variable and initialize it with the 1085 // default value. The address of the original variable is replaced 1086 // by the address of the new private variable in CodeGen. This new 1087 // variable is not added to IdResolver, so the code in the OpenMP 1088 // region uses original variable for proper diagnostics. 1089 auto *VDPrivate = buildVarDecl( 1090 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1091 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr); 1092 ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); 1093 if (VDPrivate->isInvalidDecl()) 1094 continue; 1095 PrivateCopies.push_back(buildDeclRefExpr( 1096 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1097 } else { 1098 // The variable is also a firstprivate, so initialization sequence 1099 // for private copy is generated already. 1100 PrivateCopies.push_back(nullptr); 1101 } 1102 } 1103 // Set initializers to private copies if no errors were found. 1104 if (PrivateCopies.size() == Clause->varlist_size()) 1105 Clause->setPrivateCopies(PrivateCopies); 1106 } 1107 } 1108 } 1109 1110 DSAStack->pop(); 1111 DiscardCleanupsInEvaluationContext(); 1112 PopExpressionEvaluationContext(); 1113 } 1114 1115 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1116 Expr *NumIterations, Sema &SemaRef, 1117 Scope *S, DSAStackTy *Stack); 1118 1119 namespace { 1120 1121 class VarDeclFilterCCC : public CorrectionCandidateCallback { 1122 private: 1123 Sema &SemaRef; 1124 1125 public: 1126 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1127 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1128 NamedDecl *ND = Candidate.getCorrectionDecl(); 1129 if (auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 1130 return VD->hasGlobalStorage() && 1131 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1132 SemaRef.getCurScope()); 1133 } 1134 return false; 1135 } 1136 }; 1137 1138 class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback { 1139 private: 1140 Sema &SemaRef; 1141 1142 public: 1143 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 1144 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1145 NamedDecl *ND = Candidate.getCorrectionDecl(); 1146 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { 1147 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1148 SemaRef.getCurScope()); 1149 } 1150 return false; 1151 } 1152 }; 1153 1154 } // namespace 1155 1156 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 1157 CXXScopeSpec &ScopeSpec, 1158 const DeclarationNameInfo &Id) { 1159 LookupResult Lookup(*this, Id, LookupOrdinaryName); 1160 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 1161 1162 if (Lookup.isAmbiguous()) 1163 return ExprError(); 1164 1165 VarDecl *VD; 1166 if (!Lookup.isSingleResult()) { 1167 if (TypoCorrection Corrected = CorrectTypo( 1168 Id, LookupOrdinaryName, CurScope, nullptr, 1169 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 1170 diagnoseTypo(Corrected, 1171 PDiag(Lookup.empty() 1172 ? diag::err_undeclared_var_use_suggest 1173 : diag::err_omp_expected_var_arg_suggest) 1174 << Id.getName()); 1175 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 1176 } else { 1177 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 1178 : diag::err_omp_expected_var_arg) 1179 << Id.getName(); 1180 return ExprError(); 1181 } 1182 } else { 1183 if (!(VD = Lookup.getAsSingle<VarDecl>())) { 1184 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 1185 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 1186 return ExprError(); 1187 } 1188 } 1189 Lookup.suppressDiagnostics(); 1190 1191 // OpenMP [2.9.2, Syntax, C/C++] 1192 // Variables must be file-scope, namespace-scope, or static block-scope. 1193 if (!VD->hasGlobalStorage()) { 1194 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 1195 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); 1196 bool IsDecl = 1197 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1198 Diag(VD->getLocation(), 1199 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1200 << VD; 1201 return ExprError(); 1202 } 1203 1204 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 1205 NamedDecl *ND = cast<NamedDecl>(CanonicalVD); 1206 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 1207 // A threadprivate directive for file-scope variables must appear outside 1208 // any definition or declaration. 1209 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 1210 !getCurLexicalContext()->isTranslationUnit()) { 1211 Diag(Id.getLoc(), diag::err_omp_var_scope) 1212 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1213 bool IsDecl = 1214 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1215 Diag(VD->getLocation(), 1216 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1217 << VD; 1218 return ExprError(); 1219 } 1220 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 1221 // A threadprivate directive for static class member variables must appear 1222 // in the class definition, in the same scope in which the member 1223 // variables are declared. 1224 if (CanonicalVD->isStaticDataMember() && 1225 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 1226 Diag(Id.getLoc(), diag::err_omp_var_scope) 1227 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1228 bool IsDecl = 1229 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1230 Diag(VD->getLocation(), 1231 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1232 << VD; 1233 return ExprError(); 1234 } 1235 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 1236 // A threadprivate directive for namespace-scope variables must appear 1237 // outside any definition or declaration other than the namespace 1238 // definition itself. 1239 if (CanonicalVD->getDeclContext()->isNamespace() && 1240 (!getCurLexicalContext()->isFileContext() || 1241 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 1242 Diag(Id.getLoc(), diag::err_omp_var_scope) 1243 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1244 bool IsDecl = 1245 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1246 Diag(VD->getLocation(), 1247 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1248 << VD; 1249 return ExprError(); 1250 } 1251 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 1252 // A threadprivate directive for static block-scope variables must appear 1253 // in the scope of the variable and not in a nested scope. 1254 if (CanonicalVD->isStaticLocal() && CurScope && 1255 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 1256 Diag(Id.getLoc(), diag::err_omp_var_scope) 1257 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1258 bool IsDecl = 1259 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1260 Diag(VD->getLocation(), 1261 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1262 << VD; 1263 return ExprError(); 1264 } 1265 1266 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 1267 // A threadprivate directive must lexically precede all references to any 1268 // of the variables in its list. 1269 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { 1270 Diag(Id.getLoc(), diag::err_omp_var_used) 1271 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1272 return ExprError(); 1273 } 1274 1275 QualType ExprType = VD->getType().getNonReferenceType(); 1276 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 1277 SourceLocation(), VD, 1278 /*RefersToEnclosingVariableOrCapture=*/false, 1279 Id.getLoc(), ExprType, VK_LValue); 1280 } 1281 1282 Sema::DeclGroupPtrTy 1283 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 1284 ArrayRef<Expr *> VarList) { 1285 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 1286 CurContext->addDecl(D); 1287 return DeclGroupPtrTy::make(DeclGroupRef(D)); 1288 } 1289 return nullptr; 1290 } 1291 1292 namespace { 1293 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> { 1294 Sema &SemaRef; 1295 1296 public: 1297 bool VisitDeclRefExpr(const DeclRefExpr *E) { 1298 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1299 if (VD->hasLocalStorage()) { 1300 SemaRef.Diag(E->getLocStart(), 1301 diag::err_omp_local_var_in_threadprivate_init) 1302 << E->getSourceRange(); 1303 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 1304 << VD << VD->getSourceRange(); 1305 return true; 1306 } 1307 } 1308 return false; 1309 } 1310 bool VisitStmt(const Stmt *S) { 1311 for (auto Child : S->children()) { 1312 if (Child && Visit(Child)) 1313 return true; 1314 } 1315 return false; 1316 } 1317 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 1318 }; 1319 } // namespace 1320 1321 OMPThreadPrivateDecl * 1322 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 1323 SmallVector<Expr *, 8> Vars; 1324 for (auto &RefExpr : VarList) { 1325 DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr); 1326 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 1327 SourceLocation ILoc = DE->getExprLoc(); 1328 1329 // Mark variable as used. 1330 VD->setReferenced(); 1331 VD->markUsed(Context); 1332 1333 QualType QType = VD->getType(); 1334 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 1335 // It will be analyzed later. 1336 Vars.push_back(DE); 1337 continue; 1338 } 1339 1340 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1341 // A threadprivate variable must not have an incomplete type. 1342 if (RequireCompleteType(ILoc, VD->getType(), 1343 diag::err_omp_threadprivate_incomplete_type)) { 1344 continue; 1345 } 1346 1347 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1348 // A threadprivate variable must not have a reference type. 1349 if (VD->getType()->isReferenceType()) { 1350 Diag(ILoc, diag::err_omp_ref_type_arg) 1351 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 1352 bool IsDecl = 1353 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1354 Diag(VD->getLocation(), 1355 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1356 << VD; 1357 continue; 1358 } 1359 1360 // Check if this is a TLS variable. If TLS is not being supported, produce 1361 // the corresponding diagnostic. 1362 if ((VD->getTLSKind() != VarDecl::TLS_None && 1363 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1364 getLangOpts().OpenMPUseTLS && 1365 getASTContext().getTargetInfo().isTLSSupported())) || 1366 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 1367 !VD->isLocalVarDecl())) { 1368 Diag(ILoc, diag::err_omp_var_thread_local) 1369 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 1370 bool IsDecl = 1371 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1372 Diag(VD->getLocation(), 1373 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1374 << VD; 1375 continue; 1376 } 1377 1378 // Check if initial value of threadprivate variable reference variable with 1379 // local storage (it is not supported by runtime). 1380 if (auto Init = VD->getAnyInitializer()) { 1381 LocalVarRefChecker Checker(*this); 1382 if (Checker.Visit(Init)) 1383 continue; 1384 } 1385 1386 Vars.push_back(RefExpr); 1387 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 1388 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 1389 Context, SourceRange(Loc, Loc))); 1390 if (auto *ML = Context.getASTMutationListener()) 1391 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 1392 } 1393 OMPThreadPrivateDecl *D = nullptr; 1394 if (!Vars.empty()) { 1395 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 1396 Vars); 1397 D->setAccess(AS_public); 1398 } 1399 return D; 1400 } 1401 1402 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, 1403 const ValueDecl *D, DSAStackTy::DSAVarData DVar, 1404 bool IsLoopIterVar = false) { 1405 if (DVar.RefExpr) { 1406 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 1407 << getOpenMPClauseName(DVar.CKind); 1408 return; 1409 } 1410 enum { 1411 PDSA_StaticMemberShared, 1412 PDSA_StaticLocalVarShared, 1413 PDSA_LoopIterVarPrivate, 1414 PDSA_LoopIterVarLinear, 1415 PDSA_LoopIterVarLastprivate, 1416 PDSA_ConstVarShared, 1417 PDSA_GlobalVarShared, 1418 PDSA_TaskVarFirstprivate, 1419 PDSA_LocalVarPrivate, 1420 PDSA_Implicit 1421 } Reason = PDSA_Implicit; 1422 bool ReportHint = false; 1423 auto ReportLoc = D->getLocation(); 1424 auto *VD = dyn_cast<VarDecl>(D); 1425 if (IsLoopIterVar) { 1426 if (DVar.CKind == OMPC_private) 1427 Reason = PDSA_LoopIterVarPrivate; 1428 else if (DVar.CKind == OMPC_lastprivate) 1429 Reason = PDSA_LoopIterVarLastprivate; 1430 else 1431 Reason = PDSA_LoopIterVarLinear; 1432 } else if (isOpenMPTaskingDirective(DVar.DKind) && 1433 DVar.CKind == OMPC_firstprivate) { 1434 Reason = PDSA_TaskVarFirstprivate; 1435 ReportLoc = DVar.ImplicitDSALoc; 1436 } else if (VD && VD->isStaticLocal()) 1437 Reason = PDSA_StaticLocalVarShared; 1438 else if (VD && VD->isStaticDataMember()) 1439 Reason = PDSA_StaticMemberShared; 1440 else if (VD && VD->isFileVarDecl()) 1441 Reason = PDSA_GlobalVarShared; 1442 else if (D->getType().isConstant(SemaRef.getASTContext())) 1443 Reason = PDSA_ConstVarShared; 1444 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 1445 ReportHint = true; 1446 Reason = PDSA_LocalVarPrivate; 1447 } 1448 if (Reason != PDSA_Implicit) { 1449 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 1450 << Reason << ReportHint 1451 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 1452 } else if (DVar.ImplicitDSALoc.isValid()) { 1453 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 1454 << getOpenMPClauseName(DVar.CKind); 1455 } 1456 } 1457 1458 namespace { 1459 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> { 1460 DSAStackTy *Stack; 1461 Sema &SemaRef; 1462 bool ErrorFound; 1463 CapturedStmt *CS; 1464 llvm::SmallVector<Expr *, 8> ImplicitFirstprivate; 1465 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 1466 1467 public: 1468 void VisitDeclRefExpr(DeclRefExpr *E) { 1469 if (E->isTypeDependent() || E->isValueDependent() || 1470 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 1471 return; 1472 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1473 // Skip internally declared variables. 1474 if (VD->isLocalVarDecl() && !CS->capturesVariable(VD)) 1475 return; 1476 1477 auto DVar = Stack->getTopDSA(VD, false); 1478 // Check if the variable has explicit DSA set and stop analysis if it so. 1479 if (DVar.RefExpr) 1480 return; 1481 1482 auto ELoc = E->getExprLoc(); 1483 auto DKind = Stack->getCurrentDirective(); 1484 // The default(none) clause requires that each variable that is referenced 1485 // in the construct, and does not have a predetermined data-sharing 1486 // attribute, must have its data-sharing attribute explicitly determined 1487 // by being listed in a data-sharing attribute clause. 1488 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 1489 isParallelOrTaskRegion(DKind) && 1490 VarsWithInheritedDSA.count(VD) == 0) { 1491 VarsWithInheritedDSA[VD] = E; 1492 return; 1493 } 1494 1495 // OpenMP [2.9.3.6, Restrictions, p.2] 1496 // A list item that appears in a reduction clause of the innermost 1497 // enclosing worksharing or parallel construct may not be accessed in an 1498 // explicit task. 1499 DVar = Stack->hasInnermostDSA( 1500 VD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 1501 [](OpenMPDirectiveKind K) -> bool { 1502 return isOpenMPParallelDirective(K) || 1503 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 1504 }, 1505 false); 1506 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 1507 ErrorFound = true; 1508 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1509 ReportOriginalDSA(SemaRef, Stack, VD, DVar); 1510 return; 1511 } 1512 1513 // Define implicit data-sharing attributes for task. 1514 DVar = Stack->getImplicitDSA(VD, false); 1515 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 1516 !Stack->isLoopControlVariable(VD).first) 1517 ImplicitFirstprivate.push_back(E); 1518 } 1519 } 1520 void VisitMemberExpr(MemberExpr *E) { 1521 if (E->isTypeDependent() || E->isValueDependent() || 1522 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 1523 return; 1524 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 1525 if (auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl())) { 1526 auto DVar = Stack->getTopDSA(FD, false); 1527 // Check if the variable has explicit DSA set and stop analysis if it 1528 // so. 1529 if (DVar.RefExpr) 1530 return; 1531 1532 auto ELoc = E->getExprLoc(); 1533 auto DKind = Stack->getCurrentDirective(); 1534 // OpenMP [2.9.3.6, Restrictions, p.2] 1535 // A list item that appears in a reduction clause of the innermost 1536 // enclosing worksharing or parallel construct may not be accessed in 1537 // an explicit task. 1538 DVar = Stack->hasInnermostDSA( 1539 FD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 1540 [](OpenMPDirectiveKind K) -> bool { 1541 return isOpenMPParallelDirective(K) || 1542 isOpenMPWorksharingDirective(K) || 1543 isOpenMPTeamsDirective(K); 1544 }, 1545 false); 1546 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 1547 ErrorFound = true; 1548 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1549 ReportOriginalDSA(SemaRef, Stack, FD, DVar); 1550 return; 1551 } 1552 1553 // Define implicit data-sharing attributes for task. 1554 DVar = Stack->getImplicitDSA(FD, false); 1555 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 1556 !Stack->isLoopControlVariable(FD).first) 1557 ImplicitFirstprivate.push_back(E); 1558 } 1559 } 1560 } 1561 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 1562 for (auto *C : S->clauses()) { 1563 // Skip analysis of arguments of implicitly defined firstprivate clause 1564 // for task directives. 1565 if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid())) 1566 for (auto *CC : C->children()) { 1567 if (CC) 1568 Visit(CC); 1569 } 1570 } 1571 } 1572 void VisitStmt(Stmt *S) { 1573 for (auto *C : S->children()) { 1574 if (C && !isa<OMPExecutableDirective>(C)) 1575 Visit(C); 1576 } 1577 } 1578 1579 bool isErrorFound() { return ErrorFound; } 1580 ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; } 1581 llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() { 1582 return VarsWithInheritedDSA; 1583 } 1584 1585 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 1586 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} 1587 }; 1588 } // namespace 1589 1590 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 1591 switch (DKind) { 1592 case OMPD_parallel: 1593 case OMPD_parallel_for: 1594 case OMPD_parallel_for_simd: 1595 case OMPD_parallel_sections: 1596 case OMPD_teams: { 1597 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1598 QualType KmpInt32PtrTy = 1599 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1600 Sema::CapturedParamNameType Params[] = { 1601 std::make_pair(".global_tid.", KmpInt32PtrTy), 1602 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1603 std::make_pair(StringRef(), QualType()) // __context with shared vars 1604 }; 1605 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1606 Params); 1607 break; 1608 } 1609 case OMPD_simd: 1610 case OMPD_for: 1611 case OMPD_for_simd: 1612 case OMPD_sections: 1613 case OMPD_section: 1614 case OMPD_single: 1615 case OMPD_master: 1616 case OMPD_critical: 1617 case OMPD_taskgroup: 1618 case OMPD_distribute: 1619 case OMPD_ordered: 1620 case OMPD_atomic: 1621 case OMPD_target_data: 1622 case OMPD_target: 1623 case OMPD_target_parallel: 1624 case OMPD_target_parallel_for: 1625 case OMPD_target_parallel_for_simd: 1626 case OMPD_target_simd: { 1627 Sema::CapturedParamNameType Params[] = { 1628 std::make_pair(StringRef(), QualType()) // __context with shared vars 1629 }; 1630 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1631 Params); 1632 break; 1633 } 1634 case OMPD_task: { 1635 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1636 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 1637 FunctionProtoType::ExtProtoInfo EPI; 1638 EPI.Variadic = true; 1639 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 1640 Sema::CapturedParamNameType Params[] = { 1641 std::make_pair(".global_tid.", KmpInt32Ty), 1642 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), 1643 std::make_pair(".privates.", Context.VoidPtrTy.withConst()), 1644 std::make_pair(".copy_fn.", 1645 Context.getPointerType(CopyFnType).withConst()), 1646 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 1647 std::make_pair(StringRef(), QualType()) // __context with shared vars 1648 }; 1649 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1650 Params); 1651 // Mark this captured region as inlined, because we don't use outlined 1652 // function directly. 1653 getCurCapturedRegion()->TheCapturedDecl->addAttr( 1654 AlwaysInlineAttr::CreateImplicit( 1655 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 1656 break; 1657 } 1658 case OMPD_taskloop: 1659 case OMPD_taskloop_simd: { 1660 QualType KmpInt32Ty = 1661 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1); 1662 QualType KmpUInt64Ty = 1663 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 1664 QualType KmpInt64Ty = 1665 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 1666 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 1667 FunctionProtoType::ExtProtoInfo EPI; 1668 EPI.Variadic = true; 1669 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 1670 Sema::CapturedParamNameType Params[] = { 1671 std::make_pair(".global_tid.", KmpInt32Ty), 1672 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), 1673 std::make_pair(".privates.", 1674 Context.VoidPtrTy.withConst().withRestrict()), 1675 std::make_pair( 1676 ".copy_fn.", 1677 Context.getPointerType(CopyFnType).withConst().withRestrict()), 1678 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 1679 std::make_pair(".lb.", KmpUInt64Ty), 1680 std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty), 1681 std::make_pair(".liter.", KmpInt32Ty), 1682 std::make_pair(StringRef(), QualType()) // __context with shared vars 1683 }; 1684 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1685 Params); 1686 // Mark this captured region as inlined, because we don't use outlined 1687 // function directly. 1688 getCurCapturedRegion()->TheCapturedDecl->addAttr( 1689 AlwaysInlineAttr::CreateImplicit( 1690 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 1691 break; 1692 } 1693 case OMPD_distribute_parallel_for_simd: 1694 case OMPD_distribute_simd: 1695 case OMPD_distribute_parallel_for: 1696 case OMPD_teams_distribute: 1697 case OMPD_teams_distribute_simd: { 1698 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1699 QualType KmpInt32PtrTy = 1700 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1701 Sema::CapturedParamNameType Params[] = { 1702 std::make_pair(".global_tid.", KmpInt32PtrTy), 1703 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1704 std::make_pair(".previous.lb.", Context.getSizeType()), 1705 std::make_pair(".previous.ub.", Context.getSizeType()), 1706 std::make_pair(StringRef(), QualType()) // __context with shared vars 1707 }; 1708 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1709 Params); 1710 break; 1711 } 1712 case OMPD_threadprivate: 1713 case OMPD_taskyield: 1714 case OMPD_barrier: 1715 case OMPD_taskwait: 1716 case OMPD_cancellation_point: 1717 case OMPD_cancel: 1718 case OMPD_flush: 1719 case OMPD_target_enter_data: 1720 case OMPD_target_exit_data: 1721 case OMPD_declare_reduction: 1722 case OMPD_declare_simd: 1723 case OMPD_declare_target: 1724 case OMPD_end_declare_target: 1725 case OMPD_target_update: 1726 llvm_unreachable("OpenMP Directive is not allowed"); 1727 case OMPD_unknown: 1728 llvm_unreachable("Unknown OpenMP directive"); 1729 } 1730 } 1731 1732 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 1733 Expr *CaptureExpr, bool WithInit, 1734 bool AsExpression) { 1735 assert(CaptureExpr); 1736 ASTContext &C = S.getASTContext(); 1737 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 1738 QualType Ty = Init->getType(); 1739 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 1740 if (S.getLangOpts().CPlusPlus) 1741 Ty = C.getLValueReferenceType(Ty); 1742 else { 1743 Ty = C.getPointerType(Ty); 1744 ExprResult Res = 1745 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 1746 if (!Res.isUsable()) 1747 return nullptr; 1748 Init = Res.get(); 1749 } 1750 WithInit = true; 1751 } 1752 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty); 1753 if (!WithInit) 1754 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange())); 1755 S.CurContext->addHiddenDecl(CED); 1756 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false, 1757 /*TypeMayContainAuto=*/true); 1758 return CED; 1759 } 1760 1761 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 1762 bool WithInit) { 1763 OMPCapturedExprDecl *CD; 1764 if (auto *VD = S.IsOpenMPCapturedDecl(D)) 1765 CD = cast<OMPCapturedExprDecl>(VD); 1766 else 1767 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 1768 /*AsExpression=*/false); 1769 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 1770 CaptureExpr->getExprLoc()); 1771 } 1772 1773 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 1774 if (!Ref) { 1775 auto *CD = 1776 buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."), 1777 CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true); 1778 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 1779 CaptureExpr->getExprLoc()); 1780 } 1781 ExprResult Res = Ref; 1782 if (!S.getLangOpts().CPlusPlus && 1783 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 1784 Ref->getType()->isPointerType()) 1785 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 1786 if (!Res.isUsable()) 1787 return ExprError(); 1788 return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get()); 1789 } 1790 1791 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 1792 ArrayRef<OMPClause *> Clauses) { 1793 if (!S.isUsable()) { 1794 ActOnCapturedRegionError(); 1795 return StmtError(); 1796 } 1797 1798 OMPOrderedClause *OC = nullptr; 1799 OMPScheduleClause *SC = nullptr; 1800 SmallVector<OMPLinearClause *, 4> LCs; 1801 // This is required for proper codegen. 1802 for (auto *Clause : Clauses) { 1803 if (isOpenMPPrivate(Clause->getClauseKind()) || 1804 Clause->getClauseKind() == OMPC_copyprivate || 1805 (getLangOpts().OpenMPUseTLS && 1806 getASTContext().getTargetInfo().isTLSSupported() && 1807 Clause->getClauseKind() == OMPC_copyin)) { 1808 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 1809 // Mark all variables in private list clauses as used in inner region. 1810 for (auto *VarRef : Clause->children()) { 1811 if (auto *E = cast_or_null<Expr>(VarRef)) { 1812 MarkDeclarationsReferencedInExpr(E); 1813 } 1814 } 1815 DSAStack->setForceVarCapturing(/*V=*/false); 1816 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 1817 // Mark all variables in private list clauses as used in inner region. 1818 // Required for proper codegen of combined directives. 1819 // TODO: add processing for other clauses. 1820 if (auto *C = OMPClauseWithPreInit::get(Clause)) { 1821 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 1822 for (auto *D : DS->decls()) 1823 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 1824 } 1825 } 1826 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 1827 if (auto *E = C->getPostUpdateExpr()) 1828 MarkDeclarationsReferencedInExpr(E); 1829 } 1830 } 1831 if (Clause->getClauseKind() == OMPC_schedule) 1832 SC = cast<OMPScheduleClause>(Clause); 1833 else if (Clause->getClauseKind() == OMPC_ordered) 1834 OC = cast<OMPOrderedClause>(Clause); 1835 else if (Clause->getClauseKind() == OMPC_linear) 1836 LCs.push_back(cast<OMPLinearClause>(Clause)); 1837 } 1838 bool ErrorFound = false; 1839 // OpenMP, 2.7.1 Loop Construct, Restrictions 1840 // The nonmonotonic modifier cannot be specified if an ordered clause is 1841 // specified. 1842 if (SC && 1843 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 1844 SC->getSecondScheduleModifier() == 1845 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 1846 OC) { 1847 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 1848 ? SC->getFirstScheduleModifierLoc() 1849 : SC->getSecondScheduleModifierLoc(), 1850 diag::err_omp_schedule_nonmonotonic_ordered) 1851 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 1852 ErrorFound = true; 1853 } 1854 if (!LCs.empty() && OC && OC->getNumForLoops()) { 1855 for (auto *C : LCs) { 1856 Diag(C->getLocStart(), diag::err_omp_linear_ordered) 1857 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 1858 } 1859 ErrorFound = true; 1860 } 1861 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 1862 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 1863 OC->getNumForLoops()) { 1864 Diag(OC->getLocStart(), diag::err_omp_ordered_simd) 1865 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 1866 ErrorFound = true; 1867 } 1868 if (ErrorFound) { 1869 ActOnCapturedRegionError(); 1870 return StmtError(); 1871 } 1872 return ActOnCapturedRegionEnd(S.get()); 1873 } 1874 1875 static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, 1876 OpenMPDirectiveKind CurrentRegion, 1877 const DeclarationNameInfo &CurrentName, 1878 OpenMPDirectiveKind CancelRegion, 1879 SourceLocation StartLoc) { 1880 // Allowed nesting of constructs 1881 // +------------------+-----------------+------------------------------------+ 1882 // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)| 1883 // +------------------+-----------------+------------------------------------+ 1884 // | parallel | parallel | * | 1885 // | parallel | for | * | 1886 // | parallel | for simd | * | 1887 // | parallel | master | * | 1888 // | parallel | critical | * | 1889 // | parallel | simd | * | 1890 // | parallel | sections | * | 1891 // | parallel | section | + | 1892 // | parallel | single | * | 1893 // | parallel | parallel for | * | 1894 // | parallel |parallel for simd| * | 1895 // | parallel |parallel sections| * | 1896 // | parallel | task | * | 1897 // | parallel | taskyield | * | 1898 // | parallel | barrier | * | 1899 // | parallel | taskwait | * | 1900 // | parallel | taskgroup | * | 1901 // | parallel | flush | * | 1902 // | parallel | ordered | + | 1903 // | parallel | atomic | * | 1904 // | parallel | target | * | 1905 // | parallel | target parallel | * | 1906 // | parallel | target parallel | * | 1907 // | | for | | 1908 // | parallel | target enter | * | 1909 // | | data | | 1910 // | parallel | target exit | * | 1911 // | | data | | 1912 // | parallel | teams | + | 1913 // | parallel | cancellation | | 1914 // | | point | ! | 1915 // | parallel | cancel | ! | 1916 // | parallel | taskloop | * | 1917 // | parallel | taskloop simd | * | 1918 // | parallel | distribute | + | 1919 // | parallel | distribute | + | 1920 // | | parallel for | | 1921 // | parallel | distribute | + | 1922 // | |parallel for simd| | 1923 // | parallel | distribute simd | + | 1924 // | parallel | target simd | * | 1925 // | parallel | teams distribute| + | 1926 // | parallel | teams distribute| | 1927 // | | simd | + | 1928 // +------------------+-----------------+------------------------------------+ 1929 // | for | parallel | * | 1930 // | for | for | + | 1931 // | for | for simd | + | 1932 // | for | master | + | 1933 // | for | critical | * | 1934 // | for | simd | * | 1935 // | for | sections | + | 1936 // | for | section | + | 1937 // | for | single | + | 1938 // | for | parallel for | * | 1939 // | for |parallel for simd| * | 1940 // | for |parallel sections| * | 1941 // | for | task | * | 1942 // | for | taskyield | * | 1943 // | for | barrier | + | 1944 // | for | taskwait | * | 1945 // | for | taskgroup | * | 1946 // | for | flush | * | 1947 // | for | ordered | * (if construct is ordered) | 1948 // | for | atomic | * | 1949 // | for | target | * | 1950 // | for | target parallel | * | 1951 // | for | target parallel | * | 1952 // | | for | | 1953 // | for | target enter | * | 1954 // | | data | | 1955 // | for | target exit | * | 1956 // | | data | | 1957 // | for | teams | + | 1958 // | for | cancellation | | 1959 // | | point | ! | 1960 // | for | cancel | ! | 1961 // | for | taskloop | * | 1962 // | for | taskloop simd | * | 1963 // | for | distribute | + | 1964 // | for | distribute | + | 1965 // | | parallel for | | 1966 // | for | distribute | + | 1967 // | |parallel for simd| | 1968 // | for | distribute simd | + | 1969 // | for | target parallel | + | 1970 // | | for simd | | 1971 // | for | target simd | * | 1972 // | for | teams distribute| + | 1973 // | for | teams distribute| | 1974 // | | simd | + | 1975 // +------------------+-----------------+------------------------------------+ 1976 // | master | parallel | * | 1977 // | master | for | + | 1978 // | master | for simd | + | 1979 // | master | master | * | 1980 // | master | critical | * | 1981 // | master | simd | * | 1982 // | master | sections | + | 1983 // | master | section | + | 1984 // | master | single | + | 1985 // | master | parallel for | * | 1986 // | master |parallel for simd| * | 1987 // | master |parallel sections| * | 1988 // | master | task | * | 1989 // | master | taskyield | * | 1990 // | master | barrier | + | 1991 // | master | taskwait | * | 1992 // | master | taskgroup | * | 1993 // | master | flush | * | 1994 // | master | ordered | + | 1995 // | master | atomic | * | 1996 // | master | target | * | 1997 // | master | target parallel | * | 1998 // | master | target parallel | * | 1999 // | | for | | 2000 // | master | target enter | * | 2001 // | | data | | 2002 // | master | target exit | * | 2003 // | | data | | 2004 // | master | teams | + | 2005 // | master | cancellation | | 2006 // | | point | | 2007 // | master | cancel | | 2008 // | master | taskloop | * | 2009 // | master | taskloop simd | * | 2010 // | master | distribute | + | 2011 // | master | distribute | + | 2012 // | | parallel for | | 2013 // | master | distribute | + | 2014 // | |parallel for simd| | 2015 // | master | distribute simd | + | 2016 // | master | target parallel | + | 2017 // | | for simd | | 2018 // | master | target simd | * | 2019 // | master | teams distribute| + | 2020 // | master | teams distribute| | 2021 // | | simd | + | 2022 // +------------------+-----------------+------------------------------------+ 2023 // | critical | parallel | * | 2024 // | critical | for | + | 2025 // | critical | for simd | + | 2026 // | critical | master | * | 2027 // | critical | critical | * (should have different names) | 2028 // | critical | simd | * | 2029 // | critical | sections | + | 2030 // | critical | section | + | 2031 // | critical | single | + | 2032 // | critical | parallel for | * | 2033 // | critical |parallel for simd| * | 2034 // | critical |parallel sections| * | 2035 // | critical | task | * | 2036 // | critical | taskyield | * | 2037 // | critical | barrier | + | 2038 // | critical | taskwait | * | 2039 // | critical | taskgroup | * | 2040 // | critical | ordered | + | 2041 // | critical | atomic | * | 2042 // | critical | target | * | 2043 // | critical | target parallel | * | 2044 // | critical | target parallel | * | 2045 // | | for | | 2046 // | critical | target enter | * | 2047 // | | data | | 2048 // | critical | target exit | * | 2049 // | | data | | 2050 // | critical | teams | + | 2051 // | critical | cancellation | | 2052 // | | point | | 2053 // | critical | cancel | | 2054 // | critical | taskloop | * | 2055 // | critical | taskloop simd | * | 2056 // | critical | distribute | + | 2057 // | critical | distribute | + | 2058 // | | parallel for | | 2059 // | critical | distribute | + | 2060 // | |parallel for simd| | 2061 // | critical | distribute simd | + | 2062 // | critical | target parallel | + | 2063 // | | for simd | | 2064 // | critical | target simd | * | 2065 // | critical | teams distribute| + | 2066 // | critical | teams distribute| | 2067 // | | simd | + | 2068 // +------------------+-----------------+------------------------------------+ 2069 // | simd | parallel | | 2070 // | simd | for | | 2071 // | simd | for simd | | 2072 // | simd | master | | 2073 // | simd | critical | | 2074 // | simd | simd | * | 2075 // | simd | sections | | 2076 // | simd | section | | 2077 // | simd | single | | 2078 // | simd | parallel for | | 2079 // | simd |parallel for simd| | 2080 // | simd |parallel sections| | 2081 // | simd | task | | 2082 // | simd | taskyield | | 2083 // | simd | barrier | | 2084 // | simd | taskwait | | 2085 // | simd | taskgroup | | 2086 // | simd | flush | | 2087 // | simd | ordered | + (with simd clause) | 2088 // | simd | atomic | | 2089 // | simd | target | | 2090 // | simd | target parallel | | 2091 // | simd | target parallel | | 2092 // | | for | | 2093 // | simd | target enter | | 2094 // | | data | | 2095 // | simd | target exit | | 2096 // | | data | | 2097 // | simd | teams | | 2098 // | simd | cancellation | | 2099 // | | point | | 2100 // | simd | cancel | | 2101 // | simd | taskloop | | 2102 // | simd | taskloop simd | | 2103 // | simd | distribute | | 2104 // | simd | distribute | | 2105 // | | parallel for | | 2106 // | simd | distribute | | 2107 // | |parallel for simd| | 2108 // | simd | distribute simd | | 2109 // | simd | target parallel | | 2110 // | | for simd | | 2111 // | simd | target simd | | 2112 // | simd | teams distribute| | 2113 // | simd | teams distribute| | 2114 // | | simd | | 2115 // +------------------+-----------------+------------------------------------+ 2116 // | for simd | parallel | | 2117 // | for simd | for | | 2118 // | for simd | for simd | | 2119 // | for simd | master | | 2120 // | for simd | critical | | 2121 // | for simd | simd | * | 2122 // | for simd | sections | | 2123 // | for simd | section | | 2124 // | for simd | single | | 2125 // | for simd | parallel for | | 2126 // | for simd |parallel for simd| | 2127 // | for simd |parallel sections| | 2128 // | for simd | task | | 2129 // | for simd | taskyield | | 2130 // | for simd | barrier | | 2131 // | for simd | taskwait | | 2132 // | for simd | taskgroup | | 2133 // | for simd | flush | | 2134 // | for simd | ordered | + (with simd clause) | 2135 // | for simd | atomic | | 2136 // | for simd | target | | 2137 // | for simd | target parallel | | 2138 // | for simd | target parallel | | 2139 // | | for | | 2140 // | for simd | target enter | | 2141 // | | data | | 2142 // | for simd | target exit | | 2143 // | | data | | 2144 // | for simd | teams | | 2145 // | for simd | cancellation | | 2146 // | | point | | 2147 // | for simd | cancel | | 2148 // | for simd | taskloop | | 2149 // | for simd | taskloop simd | | 2150 // | for simd | distribute | | 2151 // | for simd | distribute | | 2152 // | | parallel for | | 2153 // | for simd | distribute | | 2154 // | |parallel for simd| | 2155 // | for simd | distribute simd | | 2156 // | for simd | target parallel | | 2157 // | | for simd | | 2158 // | for simd | target simd | | 2159 // | for simd | teams distribute| | 2160 // | for simd | teams distribute| | 2161 // | | simd | | 2162 // +------------------+-----------------+------------------------------------+ 2163 // | parallel for simd| parallel | | 2164 // | parallel for simd| for | | 2165 // | parallel for simd| for simd | | 2166 // | parallel for simd| master | | 2167 // | parallel for simd| critical | | 2168 // | parallel for simd| simd | * | 2169 // | parallel for simd| sections | | 2170 // | parallel for simd| section | | 2171 // | parallel for simd| single | | 2172 // | parallel for simd| parallel for | | 2173 // | parallel for simd|parallel for simd| | 2174 // | parallel for simd|parallel sections| | 2175 // | parallel for simd| task | | 2176 // | parallel for simd| taskyield | | 2177 // | parallel for simd| barrier | | 2178 // | parallel for simd| taskwait | | 2179 // | parallel for simd| taskgroup | | 2180 // | parallel for simd| flush | | 2181 // | parallel for simd| ordered | + (with simd clause) | 2182 // | parallel for simd| atomic | | 2183 // | parallel for simd| target | | 2184 // | parallel for simd| target parallel | | 2185 // | parallel for simd| target parallel | | 2186 // | | for | | 2187 // | parallel for simd| target enter | | 2188 // | | data | | 2189 // | parallel for simd| target exit | | 2190 // | | data | | 2191 // | parallel for simd| teams | | 2192 // | parallel for simd| cancellation | | 2193 // | | point | | 2194 // | parallel for simd| cancel | | 2195 // | parallel for simd| taskloop | | 2196 // | parallel for simd| taskloop simd | | 2197 // | parallel for simd| distribute | | 2198 // | parallel for simd| distribute | | 2199 // | | parallel for | | 2200 // | parallel for simd| distribute | | 2201 // | |parallel for simd| | 2202 // | parallel for simd| distribute simd | | 2203 // | | for simd | | 2204 // | parallel for simd| target simd | | 2205 // | parallel for simd| teams distribute| | 2206 // | parallel for simd| teams distribute| | 2207 // | | simd | | 2208 // +------------------+-----------------+------------------------------------+ 2209 // | sections | parallel | * | 2210 // | sections | for | + | 2211 // | sections | for simd | + | 2212 // | sections | master | + | 2213 // | sections | critical | * | 2214 // | sections | simd | * | 2215 // | sections | sections | + | 2216 // | sections | section | * | 2217 // | sections | single | + | 2218 // | sections | parallel for | * | 2219 // | sections |parallel for simd| * | 2220 // | sections |parallel sections| * | 2221 // | sections | task | * | 2222 // | sections | taskyield | * | 2223 // | sections | barrier | + | 2224 // | sections | taskwait | * | 2225 // | sections | taskgroup | * | 2226 // | sections | flush | * | 2227 // | sections | ordered | + | 2228 // | sections | atomic | * | 2229 // | sections | target | * | 2230 // | sections | target parallel | * | 2231 // | sections | target parallel | * | 2232 // | | for | | 2233 // | sections | target enter | * | 2234 // | | data | | 2235 // | sections | target exit | * | 2236 // | | data | | 2237 // | sections | teams | + | 2238 // | sections | cancellation | | 2239 // | | point | ! | 2240 // | sections | cancel | ! | 2241 // | sections | taskloop | * | 2242 // | sections | taskloop simd | * | 2243 // | sections | distribute | + | 2244 // | sections | distribute | + | 2245 // | | parallel for | | 2246 // | sections | distribute | + | 2247 // | |parallel for simd| | 2248 // | sections | distribute simd | + | 2249 // | sections | target parallel | + | 2250 // | | for simd | | 2251 // | sections | target simd | * | 2252 // | sections | teams distribute| | 2253 // | | simd | | 2254 // +------------------+-----------------+------------------------------------+ 2255 // | section | parallel | * | 2256 // | section | for | + | 2257 // | section | for simd | + | 2258 // | section | master | + | 2259 // | section | critical | * | 2260 // | section | simd | * | 2261 // | section | sections | + | 2262 // | section | section | + | 2263 // | section | single | + | 2264 // | section | parallel for | * | 2265 // | section |parallel for simd| * | 2266 // | section |parallel sections| * | 2267 // | section | task | * | 2268 // | section | taskyield | * | 2269 // | section | barrier | + | 2270 // | section | taskwait | * | 2271 // | section | taskgroup | * | 2272 // | section | flush | * | 2273 // | section | ordered | + | 2274 // | section | atomic | * | 2275 // | section | target | * | 2276 // | section | target parallel | * | 2277 // | section | target parallel | * | 2278 // | | for | | 2279 // | section | target enter | * | 2280 // | | data | | 2281 // | section | target exit | * | 2282 // | | data | | 2283 // | section | teams | + | 2284 // | section | cancellation | | 2285 // | | point | ! | 2286 // | section | cancel | ! | 2287 // | section | taskloop | * | 2288 // | section | taskloop simd | * | 2289 // | section | distribute | + | 2290 // | section | distribute | + | 2291 // | | parallel for | | 2292 // | section | distribute | + | 2293 // | |parallel for simd| | 2294 // | section | distribute simd | + | 2295 // | section | target parallel | + | 2296 // | | for simd | | 2297 // | section | target simd | * | 2298 // | section | teams distrubte | + | 2299 // | section | teams distribute| | 2300 // | | simd | + | 2301 // +------------------+-----------------+------------------------------------+ 2302 // | single | parallel | * | 2303 // | single | for | + | 2304 // | single | for simd | + | 2305 // | single | master | + | 2306 // | single | critical | * | 2307 // | single | simd | * | 2308 // | single | sections | + | 2309 // | single | section | + | 2310 // | single | single | + | 2311 // | single | parallel for | * | 2312 // | single |parallel for simd| * | 2313 // | single |parallel sections| * | 2314 // | single | task | * | 2315 // | single | taskyield | * | 2316 // | single | barrier | + | 2317 // | single | taskwait | * | 2318 // | single | taskgroup | * | 2319 // | single | flush | * | 2320 // | single | ordered | + | 2321 // | single | atomic | * | 2322 // | single | target | * | 2323 // | single | target parallel | * | 2324 // | single | target parallel | * | 2325 // | | for | | 2326 // | single | target enter | * | 2327 // | | data | | 2328 // | single | target exit | * | 2329 // | | data | | 2330 // | single | teams | + | 2331 // | single | cancellation | | 2332 // | | point | | 2333 // | single | cancel | | 2334 // | single | taskloop | * | 2335 // | single | taskloop simd | * | 2336 // | single | distribute | + | 2337 // | single | distribute | + | 2338 // | | parallel for | | 2339 // | single | distribute | + | 2340 // | |parallel for simd| | 2341 // | single | distribute simd | + | 2342 // | single | target parallel | + | 2343 // | | for simd | | 2344 // | single | target simd | * | 2345 // | single | teams distrubte | + | 2346 // | single | teams distribute| | 2347 // | | simd | + | 2348 // +------------------+-----------------+------------------------------------+ 2349 // | parallel for | parallel | * | 2350 // | parallel for | for | + | 2351 // | parallel for | for simd | + | 2352 // | parallel for | master | + | 2353 // | parallel for | critical | * | 2354 // | parallel for | simd | * | 2355 // | parallel for | sections | + | 2356 // | parallel for | section | + | 2357 // | parallel for | single | + | 2358 // | parallel for | parallel for | * | 2359 // | parallel for |parallel for simd| * | 2360 // | parallel for |parallel sections| * | 2361 // | parallel for | task | * | 2362 // | parallel for | taskyield | * | 2363 // | parallel for | barrier | + | 2364 // | parallel for | taskwait | * | 2365 // | parallel for | taskgroup | * | 2366 // | parallel for | flush | * | 2367 // | parallel for | ordered | * (if construct is ordered) | 2368 // | parallel for | atomic | * | 2369 // | parallel for | target | * | 2370 // | parallel for | target parallel | * | 2371 // | parallel for | target parallel | * | 2372 // | | for | | 2373 // | parallel for | target enter | * | 2374 // | | data | | 2375 // | parallel for | target exit | * | 2376 // | | data | | 2377 // | parallel for | teams | + | 2378 // | parallel for | cancellation | | 2379 // | | point | ! | 2380 // | parallel for | cancel | ! | 2381 // | parallel for | taskloop | * | 2382 // | parallel for | taskloop simd | * | 2383 // | parallel for | distribute | + | 2384 // | parallel for | distribute | + | 2385 // | | parallel for | | 2386 // | parallel for | distribute | + | 2387 // | |parallel for simd| | 2388 // | parallel for | distribute simd | + | 2389 // | parallel for | target parallel | + | 2390 // | | for simd | | 2391 // | parallel for | target simd | * | 2392 // | parallel for | teams distribute| + | 2393 // | parallel for | teams distribute| | 2394 // | | simd | + | 2395 // +------------------+-----------------+------------------------------------+ 2396 // | parallel sections| parallel | * | 2397 // | parallel sections| for | + | 2398 // | parallel sections| for simd | + | 2399 // | parallel sections| master | + | 2400 // | parallel sections| critical | + | 2401 // | parallel sections| simd | * | 2402 // | parallel sections| sections | + | 2403 // | parallel sections| section | * | 2404 // | parallel sections| single | + | 2405 // | parallel sections| parallel for | * | 2406 // | parallel sections|parallel for simd| * | 2407 // | parallel sections|parallel sections| * | 2408 // | parallel sections| task | * | 2409 // | parallel sections| taskyield | * | 2410 // | parallel sections| barrier | + | 2411 // | parallel sections| taskwait | * | 2412 // | parallel sections| taskgroup | * | 2413 // | parallel sections| flush | * | 2414 // | parallel sections| ordered | + | 2415 // | parallel sections| atomic | * | 2416 // | parallel sections| target | * | 2417 // | parallel sections| target parallel | * | 2418 // | parallel sections| target parallel | * | 2419 // | | for | | 2420 // | parallel sections| target enter | * | 2421 // | | data | | 2422 // | parallel sections| target exit | * | 2423 // | | data | | 2424 // | parallel sections| teams | + | 2425 // | parallel sections| cancellation | | 2426 // | | point | ! | 2427 // | parallel sections| cancel | ! | 2428 // | parallel sections| taskloop | * | 2429 // | parallel sections| taskloop simd | * | 2430 // | parallel sections| distribute | + | 2431 // | parallel sections| distribute | + | 2432 // | | parallel for | | 2433 // | parallel sections| distribute | + | 2434 // | |parallel for simd| | 2435 // | parallel sections| distribute simd | + | 2436 // | parallel sections| target parallel | + | 2437 // | | for simd | | 2438 // | parallel sections| target simd | * | 2439 // | parallel sections| teams distribute| + | 2440 // | parallel sections| teams distribute| | 2441 // | | simd | + | 2442 // +------------------+-----------------+------------------------------------+ 2443 // | task | parallel | * | 2444 // | task | for | + | 2445 // | task | for simd | + | 2446 // | task | master | + | 2447 // | task | critical | * | 2448 // | task | simd | * | 2449 // | task | sections | + | 2450 // | task | section | + | 2451 // | task | single | + | 2452 // | task | parallel for | * | 2453 // | task |parallel for simd| * | 2454 // | task |parallel sections| * | 2455 // | task | task | * | 2456 // | task | taskyield | * | 2457 // | task | barrier | + | 2458 // | task | taskwait | * | 2459 // | task | taskgroup | * | 2460 // | task | flush | * | 2461 // | task | ordered | + | 2462 // | task | atomic | * | 2463 // | task | target | * | 2464 // | task | target parallel | * | 2465 // | task | target parallel | * | 2466 // | | for | | 2467 // | task | target enter | * | 2468 // | | data | | 2469 // | task | target exit | * | 2470 // | | data | | 2471 // | task | teams | + | 2472 // | task | cancellation | | 2473 // | | point | ! | 2474 // | task | cancel | ! | 2475 // | task | taskloop | * | 2476 // | task | taskloop simd | * | 2477 // | task | distribute | + | 2478 // | task | distribute | + | 2479 // | | parallel for | | 2480 // | task | distribute | + | 2481 // | |parallel for simd| | 2482 // | task | distribute simd | + | 2483 // | task | target parallel | + | 2484 // | | for simd | | 2485 // | task | target simd | * | 2486 // | task | teams distribute| + | 2487 // | task | teams distribute| | 2488 // | | simd | + | 2489 // +------------------+-----------------+------------------------------------+ 2490 // | ordered | parallel | * | 2491 // | ordered | for | + | 2492 // | ordered | for simd | + | 2493 // | ordered | master | * | 2494 // | ordered | critical | * | 2495 // | ordered | simd | * | 2496 // | ordered | sections | + | 2497 // | ordered | section | + | 2498 // | ordered | single | + | 2499 // | ordered | parallel for | * | 2500 // | ordered |parallel for simd| * | 2501 // | ordered |parallel sections| * | 2502 // | ordered | task | * | 2503 // | ordered | taskyield | * | 2504 // | ordered | barrier | + | 2505 // | ordered | taskwait | * | 2506 // | ordered | taskgroup | * | 2507 // | ordered | flush | * | 2508 // | ordered | ordered | + | 2509 // | ordered | atomic | * | 2510 // | ordered | target | * | 2511 // | ordered | target parallel | * | 2512 // | ordered | target parallel | * | 2513 // | | for | | 2514 // | ordered | target enter | * | 2515 // | | data | | 2516 // | ordered | target exit | * | 2517 // | | data | | 2518 // | ordered | teams | + | 2519 // | ordered | cancellation | | 2520 // | | point | | 2521 // | ordered | cancel | | 2522 // | ordered | taskloop | * | 2523 // | ordered | taskloop simd | * | 2524 // | ordered | distribute | + | 2525 // | ordered | distribute | + | 2526 // | | parallel for | | 2527 // | ordered | distribute | + | 2528 // | |parallel for simd| | 2529 // | ordered | distribute simd | + | 2530 // | ordered | target parallel | + | 2531 // | | for simd | | 2532 // | ordered | target simd | * | 2533 // | ordered | teams distribute| + | 2534 // | ordered | teams distribute| | 2535 // | | simd | + | 2536 // +------------------+-----------------+------------------------------------+ 2537 // | atomic | parallel | | 2538 // | atomic | for | | 2539 // | atomic | for simd | | 2540 // | atomic | master | | 2541 // | atomic | critical | | 2542 // | atomic | simd | | 2543 // | atomic | sections | | 2544 // | atomic | section | | 2545 // | atomic | single | | 2546 // | atomic | parallel for | | 2547 // | atomic |parallel for simd| | 2548 // | atomic |parallel sections| | 2549 // | atomic | task | | 2550 // | atomic | taskyield | | 2551 // | atomic | barrier | | 2552 // | atomic | taskwait | | 2553 // | atomic | taskgroup | | 2554 // | atomic | flush | | 2555 // | atomic | ordered | | 2556 // | atomic | atomic | | 2557 // | atomic | target | | 2558 // | atomic | target parallel | | 2559 // | atomic | target parallel | | 2560 // | | for | | 2561 // | atomic | target enter | | 2562 // | | data | | 2563 // | atomic | target exit | | 2564 // | | data | | 2565 // | atomic | teams | | 2566 // | atomic | cancellation | | 2567 // | | point | | 2568 // | atomic | cancel | | 2569 // | atomic | taskloop | | 2570 // | atomic | taskloop simd | | 2571 // | atomic | distribute | | 2572 // | atomic | distribute | | 2573 // | | parallel for | | 2574 // | atomic | distribute | | 2575 // | |parallel for simd| | 2576 // | atomic | distribute simd | | 2577 // | atomic | target parallel | | 2578 // | | for simd | | 2579 // | atomic | target simd | | 2580 // | atomic | teams distribute| | 2581 // | atomic | teams distribute| | 2582 // | | simd | | 2583 // +------------------+-----------------+------------------------------------+ 2584 // | target | parallel | * | 2585 // | target | for | * | 2586 // | target | for simd | * | 2587 // | target | master | * | 2588 // | target | critical | * | 2589 // | target | simd | * | 2590 // | target | sections | * | 2591 // | target | section | * | 2592 // | target | single | * | 2593 // | target | parallel for | * | 2594 // | target |parallel for simd| * | 2595 // | target |parallel sections| * | 2596 // | target | task | * | 2597 // | target | taskyield | * | 2598 // | target | barrier | * | 2599 // | target | taskwait | * | 2600 // | target | taskgroup | * | 2601 // | target | flush | * | 2602 // | target | ordered | * | 2603 // | target | atomic | * | 2604 // | target | target | | 2605 // | target | target parallel | | 2606 // | target | target parallel | | 2607 // | | for | | 2608 // | target | target enter | | 2609 // | | data | | 2610 // | target | target exit | | 2611 // | | data | | 2612 // | target | teams | * | 2613 // | target | cancellation | | 2614 // | | point | | 2615 // | target | cancel | | 2616 // | target | taskloop | * | 2617 // | target | taskloop simd | * | 2618 // | target | distribute | + | 2619 // | target | distribute | + | 2620 // | | parallel for | | 2621 // | target | distribute | + | 2622 // | |parallel for simd| | 2623 // | target | distribute simd | + | 2624 // | target | target parallel | | 2625 // | | for simd | | 2626 // | target | target simd | | 2627 // | target | teams distribute| | 2628 // | target | teams distribute| | 2629 // | | simd | | 2630 // +------------------+-----------------+------------------------------------+ 2631 // | target parallel | parallel | * | 2632 // | target parallel | for | * | 2633 // | target parallel | for simd | * | 2634 // | target parallel | master | * | 2635 // | target parallel | critical | * | 2636 // | target parallel | simd | * | 2637 // | target parallel | sections | * | 2638 // | target parallel | section | * | 2639 // | target parallel | single | * | 2640 // | target parallel | parallel for | * | 2641 // | target parallel |parallel for simd| * | 2642 // | target parallel |parallel sections| * | 2643 // | target parallel | task | * | 2644 // | target parallel | taskyield | * | 2645 // | target parallel | barrier | * | 2646 // | target parallel | taskwait | * | 2647 // | target parallel | taskgroup | * | 2648 // | target parallel | flush | * | 2649 // | target parallel | ordered | * | 2650 // | target parallel | atomic | * | 2651 // | target parallel | target | | 2652 // | target parallel | target parallel | | 2653 // | target parallel | target parallel | | 2654 // | | for | | 2655 // | target parallel | target enter | | 2656 // | | data | | 2657 // | target parallel | target exit | | 2658 // | | data | | 2659 // | target parallel | teams | | 2660 // | target parallel | cancellation | | 2661 // | | point | ! | 2662 // | target parallel | cancel | ! | 2663 // | target parallel | taskloop | * | 2664 // | target parallel | taskloop simd | * | 2665 // | target parallel | distribute | | 2666 // | target parallel | distribute | | 2667 // | | parallel for | | 2668 // | target parallel | distribute | | 2669 // | |parallel for simd| | 2670 // | target parallel | distribute simd | | 2671 // | target parallel | target parallel | | 2672 // | | for simd | | 2673 // | target parallel | target simd | | 2674 // | target parallel | teams distribute| + | 2675 // | target parallel | teams distribute| + | 2676 // | | simd | | 2677 // +------------------+-----------------+------------------------------------+ 2678 // | target parallel | parallel | * | 2679 // | for | | | 2680 // | target parallel | for | * | 2681 // | for | | | 2682 // | target parallel | for simd | * | 2683 // | for | | | 2684 // | target parallel | master | * | 2685 // | for | | | 2686 // | target parallel | critical | * | 2687 // | for | | | 2688 // | target parallel | simd | * | 2689 // | for | | | 2690 // | target parallel | sections | * | 2691 // | for | | | 2692 // | target parallel | section | * | 2693 // | for | | | 2694 // | target parallel | single | * | 2695 // | for | | | 2696 // | target parallel | parallel for | * | 2697 // | for | | | 2698 // | target parallel |parallel for simd| * | 2699 // | for | | | 2700 // | target parallel |parallel sections| * | 2701 // | for | | | 2702 // | target parallel | task | * | 2703 // | for | | | 2704 // | target parallel | taskyield | * | 2705 // | for | | | 2706 // | target parallel | barrier | * | 2707 // | for | | | 2708 // | target parallel | taskwait | * | 2709 // | for | | | 2710 // | target parallel | taskgroup | * | 2711 // | for | | | 2712 // | target parallel | flush | * | 2713 // | for | | | 2714 // | target parallel | ordered | * | 2715 // | for | | | 2716 // | target parallel | atomic | * | 2717 // | for | | | 2718 // | target parallel | target | | 2719 // | for | | | 2720 // | target parallel | target parallel | | 2721 // | for | | | 2722 // | target parallel | target parallel | | 2723 // | for | for | | 2724 // | target parallel | target enter | | 2725 // | for | data | | 2726 // | target parallel | target exit | | 2727 // | for | data | | 2728 // | target parallel | teams | | 2729 // | for | | | 2730 // | target parallel | cancellation | | 2731 // | for | point | ! | 2732 // | target parallel | cancel | ! | 2733 // | for | | | 2734 // | target parallel | taskloop | * | 2735 // | for | | | 2736 // | target parallel | taskloop simd | * | 2737 // | for | | | 2738 // | target parallel | distribute | | 2739 // | for | | | 2740 // | target parallel | distribute | | 2741 // | for | parallel for | | 2742 // | target parallel | distribute | | 2743 // | for |parallel for simd| | 2744 // | target parallel | distribute simd | | 2745 // | for | | | 2746 // | target parallel | target parallel | | 2747 // | for | for simd | | 2748 // | target parallel | target simd | | 2749 // | for | | | 2750 // | target parallel | teams distribute| | 2751 // | for | | | 2752 // | target parallel | teams distribute| | 2753 // | for | simd | | 2754 // +------------------+-----------------+------------------------------------+ 2755 // | teams | parallel | * | 2756 // | teams | for | + | 2757 // | teams | for simd | + | 2758 // | teams | master | + | 2759 // | teams | critical | + | 2760 // | teams | simd | + | 2761 // | teams | sections | + | 2762 // | teams | section | + | 2763 // | teams | single | + | 2764 // | teams | parallel for | * | 2765 // | teams |parallel for simd| * | 2766 // | teams |parallel sections| * | 2767 // | teams | task | + | 2768 // | teams | taskyield | + | 2769 // | teams | barrier | + | 2770 // | teams | taskwait | + | 2771 // | teams | taskgroup | + | 2772 // | teams | flush | + | 2773 // | teams | ordered | + | 2774 // | teams | atomic | + | 2775 // | teams | target | + | 2776 // | teams | target parallel | + | 2777 // | teams | target parallel | + | 2778 // | | for | | 2779 // | teams | target enter | + | 2780 // | | data | | 2781 // | teams | target exit | + | 2782 // | | data | | 2783 // | teams | teams | + | 2784 // | teams | cancellation | | 2785 // | | point | | 2786 // | teams | cancel | | 2787 // | teams | taskloop | + | 2788 // | teams | taskloop simd | + | 2789 // | teams | distribute | ! | 2790 // | teams | distribute | ! | 2791 // | | parallel for | | 2792 // | teams | distribute | ! | 2793 // | |parallel for simd| | 2794 // | teams | distribute simd | ! | 2795 // | teams | target parallel | + | 2796 // | | for simd | | 2797 // | teams | target simd | + | 2798 // | teams | teams distribute| + | 2799 // | teams | teams distribute| + | 2800 // | | simd | | 2801 // +------------------+-----------------+------------------------------------+ 2802 // | taskloop | parallel | * | 2803 // | taskloop | for | + | 2804 // | taskloop | for simd | + | 2805 // | taskloop | master | + | 2806 // | taskloop | critical | * | 2807 // | taskloop | simd | * | 2808 // | taskloop | sections | + | 2809 // | taskloop | section | + | 2810 // | taskloop | single | + | 2811 // | taskloop | parallel for | * | 2812 // | taskloop |parallel for simd| * | 2813 // | taskloop |parallel sections| * | 2814 // | taskloop | task | * | 2815 // | taskloop | taskyield | * | 2816 // | taskloop | barrier | + | 2817 // | taskloop | taskwait | * | 2818 // | taskloop | taskgroup | * | 2819 // | taskloop | flush | * | 2820 // | taskloop | ordered | + | 2821 // | taskloop | atomic | * | 2822 // | taskloop | target | * | 2823 // | taskloop | target parallel | * | 2824 // | taskloop | target parallel | * | 2825 // | | for | | 2826 // | taskloop | target enter | * | 2827 // | | data | | 2828 // | taskloop | target exit | * | 2829 // | | data | | 2830 // | taskloop | teams | + | 2831 // | taskloop | cancellation | | 2832 // | | point | | 2833 // | taskloop | cancel | | 2834 // | taskloop | taskloop | * | 2835 // | taskloop | distribute | + | 2836 // | taskloop | distribute | + | 2837 // | | parallel for | | 2838 // | taskloop | distribute | + | 2839 // | |parallel for simd| | 2840 // | taskloop | distribute simd | + | 2841 // | taskloop | target parallel | * | 2842 // | | for simd | | 2843 // | taskloop | target simd | * | 2844 // | taskloop | teams distribute| + | 2845 // | taskloop | teams distribute| + | 2846 // | | simd | | 2847 // +------------------+-----------------+------------------------------------+ 2848 // | taskloop simd | parallel | | 2849 // | taskloop simd | for | | 2850 // | taskloop simd | for simd | | 2851 // | taskloop simd | master | | 2852 // | taskloop simd | critical | | 2853 // | taskloop simd | simd | * | 2854 // | taskloop simd | sections | | 2855 // | taskloop simd | section | | 2856 // | taskloop simd | single | | 2857 // | taskloop simd | parallel for | | 2858 // | taskloop simd |parallel for simd| | 2859 // | taskloop simd |parallel sections| | 2860 // | taskloop simd | task | | 2861 // | taskloop simd | taskyield | | 2862 // | taskloop simd | barrier | | 2863 // | taskloop simd | taskwait | | 2864 // | taskloop simd | taskgroup | | 2865 // | taskloop simd | flush | | 2866 // | taskloop simd | ordered | + (with simd clause) | 2867 // | taskloop simd | atomic | | 2868 // | taskloop simd | target | | 2869 // | taskloop simd | target parallel | | 2870 // | taskloop simd | target parallel | | 2871 // | | for | | 2872 // | taskloop simd | target enter | | 2873 // | | data | | 2874 // | taskloop simd | target exit | | 2875 // | | data | | 2876 // | taskloop simd | teams | | 2877 // | taskloop simd | cancellation | | 2878 // | | point | | 2879 // | taskloop simd | cancel | | 2880 // | taskloop simd | taskloop | | 2881 // | taskloop simd | taskloop simd | | 2882 // | taskloop simd | distribute | | 2883 // | taskloop simd | distribute | | 2884 // | | parallel for | | 2885 // | taskloop simd | distribute | | 2886 // | |parallel for simd| | 2887 // | taskloop simd | distribute simd | | 2888 // | taskloop simd | target parallel | | 2889 // | | for simd | | 2890 // | taskloop simd | target simd | | 2891 // | taskloop simd | teams distribute| | 2892 // | taskloop simd | teams distribute| | 2893 // | | simd | | 2894 // +------------------+-----------------+------------------------------------+ 2895 // | distribute | parallel | * | 2896 // | distribute | for | * | 2897 // | distribute | for simd | * | 2898 // | distribute | master | * | 2899 // | distribute | critical | * | 2900 // | distribute | simd | * | 2901 // | distribute | sections | * | 2902 // | distribute | section | * | 2903 // | distribute | single | * | 2904 // | distribute | parallel for | * | 2905 // | distribute |parallel for simd| * | 2906 // | distribute |parallel sections| * | 2907 // | distribute | task | * | 2908 // | distribute | taskyield | * | 2909 // | distribute | barrier | * | 2910 // | distribute | taskwait | * | 2911 // | distribute | taskgroup | * | 2912 // | distribute | flush | * | 2913 // | distribute | ordered | + | 2914 // | distribute | atomic | * | 2915 // | distribute | target | | 2916 // | distribute | target parallel | | 2917 // | distribute | target parallel | | 2918 // | | for | | 2919 // | distribute | target enter | | 2920 // | | data | | 2921 // | distribute | target exit | | 2922 // | | data | | 2923 // | distribute | teams | | 2924 // | distribute | cancellation | + | 2925 // | | point | | 2926 // | distribute | cancel | + | 2927 // | distribute | taskloop | * | 2928 // | distribute | taskloop simd | * | 2929 // | distribute | distribute | | 2930 // | distribute | distribute | | 2931 // | | parallel for | | 2932 // | distribute | distribute | | 2933 // | |parallel for simd| | 2934 // | distribute | distribute simd | | 2935 // | distribute | target parallel | | 2936 // | | for simd | | 2937 // | distribute | target simd | | 2938 // | distribute | teams distribute| | 2939 // | distribute | teams distribute| | 2940 // | | simd | | 2941 // +------------------+-----------------+------------------------------------+ 2942 // | distribute | parallel | * | 2943 // | parallel for | | | 2944 // | distribute | for | * | 2945 // | parallel for | | | 2946 // | distribute | for simd | * | 2947 // | parallel for | | | 2948 // | distribute | master | * | 2949 // | parallel for | | | 2950 // | distribute | critical | * | 2951 // | parallel for | | | 2952 // | distribute | simd | * | 2953 // | parallel for | | | 2954 // | distribute | sections | * | 2955 // | parallel for | | | 2956 // | distribute | section | * | 2957 // | parallel for | | | 2958 // | distribute | single | * | 2959 // | parallel for | | | 2960 // | distribute | parallel for | * | 2961 // | parallel for | | | 2962 // | distribute |parallel for simd| * | 2963 // | parallel for | | | 2964 // | distribute |parallel sections| * | 2965 // | parallel for | | | 2966 // | distribute | task | * | 2967 // | parallel for | | | 2968 // | parallel for | | | 2969 // | distribute | taskyield | * | 2970 // | parallel for | | | 2971 // | distribute | barrier | * | 2972 // | parallel for | | | 2973 // | distribute | taskwait | * | 2974 // | parallel for | | | 2975 // | distribute | taskgroup | * | 2976 // | parallel for | | | 2977 // | distribute | flush | * | 2978 // | parallel for | | | 2979 // | distribute | ordered | + | 2980 // | parallel for | | | 2981 // | distribute | atomic | * | 2982 // | parallel for | | | 2983 // | distribute | target | | 2984 // | parallel for | | | 2985 // | distribute | target parallel | | 2986 // | parallel for | | | 2987 // | distribute | target parallel | | 2988 // | parallel for | for | | 2989 // | distribute | target enter | | 2990 // | parallel for | data | | 2991 // | distribute | target exit | | 2992 // | parallel for | data | | 2993 // | distribute | teams | | 2994 // | parallel for | | | 2995 // | distribute | cancellation | + | 2996 // | parallel for | point | | 2997 // | distribute | cancel | + | 2998 // | parallel for | | | 2999 // | distribute | taskloop | * | 3000 // | parallel for | | | 3001 // | distribute | taskloop simd | * | 3002 // | parallel for | | | 3003 // | distribute | distribute | | 3004 // | parallel for | | | 3005 // | distribute | distribute | | 3006 // | parallel for | parallel for | | 3007 // | distribute | distribute | | 3008 // | parallel for |parallel for simd| | 3009 // | distribute | distribute simd | | 3010 // | parallel for | | | 3011 // | distribute | target parallel | | 3012 // | parallel for | for simd | | 3013 // | distribute | target simd | | 3014 // | parallel for | | | 3015 // | distribute | teams distribute| | 3016 // | parallel for | | | 3017 // | distribute | teams distribute| | 3018 // | parallel for | simd | | 3019 // +------------------+-----------------+------------------------------------+ 3020 // | distribute | parallel | * | 3021 // | parallel for simd| | | 3022 // | distribute | for | * | 3023 // | parallel for simd| | | 3024 // | distribute | for simd | * | 3025 // | parallel for simd| | | 3026 // | distribute | master | * | 3027 // | parallel for simd| | | 3028 // | distribute | critical | * | 3029 // | parallel for simd| | | 3030 // | distribute | simd | * | 3031 // | parallel for simd| | | 3032 // | distribute | sections | * | 3033 // | parallel for simd| | | 3034 // | distribute | section | * | 3035 // | parallel for simd| | | 3036 // | distribute | single | * | 3037 // | parallel for simd| | | 3038 // | distribute | parallel for | * | 3039 // | parallel for simd| | | 3040 // | distribute |parallel for simd| * | 3041 // | parallel for simd| | | 3042 // | distribute |parallel sections| * | 3043 // | parallel for simd| | | 3044 // | distribute | task | * | 3045 // | parallel for simd| | | 3046 // | distribute | taskyield | * | 3047 // | parallel for simd| | | 3048 // | distribute | barrier | * | 3049 // | parallel for simd| | | 3050 // | distribute | taskwait | * | 3051 // | parallel for simd| | | 3052 // | distribute | taskgroup | * | 3053 // | parallel for simd| | | 3054 // | distribute | flush | * | 3055 // | parallel for simd| | | 3056 // | distribute | ordered | + | 3057 // | parallel for simd| | | 3058 // | distribute | atomic | * | 3059 // | parallel for simd| | | 3060 // | distribute | target | | 3061 // | parallel for simd| | | 3062 // | distribute | target parallel | | 3063 // | parallel for simd| | | 3064 // | distribute | target parallel | | 3065 // | parallel for simd| for | | 3066 // | distribute | target enter | | 3067 // | parallel for simd| data | | 3068 // | distribute | target exit | | 3069 // | parallel for simd| data | | 3070 // | distribute | teams | | 3071 // | parallel for simd| | | 3072 // | distribute | cancellation | + | 3073 // | parallel for simd| point | | 3074 // | distribute | cancel | + | 3075 // | parallel for simd| | | 3076 // | distribute | taskloop | * | 3077 // | parallel for simd| | | 3078 // | distribute | taskloop simd | * | 3079 // | parallel for simd| | | 3080 // | distribute | distribute | | 3081 // | parallel for simd| | | 3082 // | distribute | distribute | * | 3083 // | parallel for simd| parallel for | | 3084 // | distribute | distribute | * | 3085 // | parallel for simd|parallel for simd| | 3086 // | distribute | distribute simd | * | 3087 // | parallel for simd| | | 3088 // | distribute | target parallel | | 3089 // | parallel for simd| for simd | | 3090 // | distribute | target simd | | 3091 // | parallel for simd| | | 3092 // | distribute | teams distribute| | 3093 // | parallel for simd| | | 3094 // | distribute | teams distribute| | 3095 // | parallel for simd| simd | | 3096 // +------------------+-----------------+------------------------------------+ 3097 // | distribute simd | parallel | * | 3098 // | distribute simd | for | * | 3099 // | distribute simd | for simd | * | 3100 // | distribute simd | master | * | 3101 // | distribute simd | critical | * | 3102 // | distribute simd | simd | * | 3103 // | distribute simd | sections | * | 3104 // | distribute simd | section | * | 3105 // | distribute simd | single | * | 3106 // | distribute simd | parallel for | * | 3107 // | distribute simd |parallel for simd| * | 3108 // | distribute simd |parallel sections| * | 3109 // | distribute simd | task | * | 3110 // | distribute simd | taskyield | * | 3111 // | distribute simd | barrier | * | 3112 // | distribute simd | taskwait | * | 3113 // | distribute simd | taskgroup | * | 3114 // | distribute simd | flush | * | 3115 // | distribute simd | ordered | + | 3116 // | distribute simd | atomic | * | 3117 // | distribute simd | target | * | 3118 // | distribute simd | target parallel | * | 3119 // | distribute simd | target parallel | * | 3120 // | | for | | 3121 // | distribute simd | target enter | * | 3122 // | | data | | 3123 // | distribute simd | target exit | * | 3124 // | | data | | 3125 // | distribute simd | teams | * | 3126 // | distribute simd | cancellation | + | 3127 // | | point | | 3128 // | distribute simd | cancel | + | 3129 // | distribute simd | taskloop | * | 3130 // | distribute simd | taskloop simd | * | 3131 // | distribute simd | distribute | | 3132 // | distribute simd | distribute | * | 3133 // | | parallel for | | 3134 // | distribute simd | distribute | * | 3135 // | |parallel for simd| | 3136 // | distribute simd | distribute simd | * | 3137 // | distribute simd | target parallel | * | 3138 // | | for simd | | 3139 // | distribute simd | target simd | * | 3140 // | distribute simd | teams distribute| * | 3141 // | distribute simd | teams distribute| | 3142 // | | simd | | 3143 // +------------------+-----------------+------------------------------------+ 3144 // | target parallel | parallel | * | 3145 // | for simd | | | 3146 // | target parallel | for | * | 3147 // | for simd | | | 3148 // | target parallel | for simd | * | 3149 // | for simd | | | 3150 // | target parallel | master | * | 3151 // | for simd | | | 3152 // | target parallel | critical | * | 3153 // | for simd | | | 3154 // | target parallel | simd | ! | 3155 // | for simd | | | 3156 // | target parallel | sections | * | 3157 // | for simd | | | 3158 // | target parallel | section | * | 3159 // | for simd | | | 3160 // | target parallel | single | * | 3161 // | for simd | | | 3162 // | target parallel | parallel for | * | 3163 // | for simd | | | 3164 // | target parallel |parallel for simd| * | 3165 // | for simd | | | 3166 // | target parallel |parallel sections| * | 3167 // | for simd | | | 3168 // | target parallel | task | * | 3169 // | for simd | | | 3170 // | target parallel | taskyield | * | 3171 // | for simd | | | 3172 // | target parallel | barrier | * | 3173 // | for simd | | | 3174 // | target parallel | taskwait | * | 3175 // | for simd | | | 3176 // | target parallel | taskgroup | * | 3177 // | for simd | | | 3178 // | target parallel | flush | * | 3179 // | for simd | | | 3180 // | target parallel | ordered | + (with simd clause) | 3181 // | for simd | | | 3182 // | target parallel | atomic | * | 3183 // | for simd | | | 3184 // | target parallel | target | * | 3185 // | for simd | | | 3186 // | target parallel | target parallel | * | 3187 // | for simd | | | 3188 // | target parallel | target parallel | * | 3189 // | for simd | for | | 3190 // | target parallel | target enter | * | 3191 // | for simd | data | | 3192 // | target parallel | target exit | * | 3193 // | for simd | data | | 3194 // | target parallel | teams | * | 3195 // | for simd | | | 3196 // | target parallel | cancellation | * | 3197 // | for simd | point | | 3198 // | target parallel | cancel | * | 3199 // | for simd | | | 3200 // | target parallel | taskloop | * | 3201 // | for simd | | | 3202 // | target parallel | taskloop simd | * | 3203 // | for simd | | | 3204 // | target parallel | distribute | * | 3205 // | for simd | | | 3206 // | target parallel | distribute | * | 3207 // | for simd | parallel for | | 3208 // | target parallel | distribute | * | 3209 // | for simd |parallel for simd| | 3210 // | target parallel | distribute simd | * | 3211 // | for simd | | | 3212 // | target parallel | target parallel | * | 3213 // | for simd | for simd | | 3214 // | target parallel | target simd | * | 3215 // | for simd | | | 3216 // | target parallel | teams distribute| * | 3217 // | for simd | | | 3218 // | target parallel | teams distribute| | 3219 // | for simd | simd | | 3220 // +------------------+-----------------+------------------------------------+ 3221 // | target simd | parallel | | 3222 // | target simd | for | | 3223 // | target simd | for simd | | 3224 // | target simd | master | | 3225 // | target simd | critical | | 3226 // | target simd | simd | | 3227 // | target simd | sections | | 3228 // | target simd | section | | 3229 // | target simd | single | | 3230 // | target simd | parallel for | | 3231 // | target simd |parallel for simd| | 3232 // | target simd |parallel sections| | 3233 // | target simd | task | | 3234 // | target simd | taskyield | | 3235 // | target simd | barrier | | 3236 // | target simd | taskwait | | 3237 // | target simd | taskgroup | | 3238 // | target simd | flush | | 3239 // | target simd | ordered | + (with simd clause) | 3240 // | target simd | atomic | | 3241 // | target simd | target | | 3242 // | target simd | target parallel | | 3243 // | target simd | target parallel | | 3244 // | | for | | 3245 // | target simd | target enter | | 3246 // | | data | | 3247 // | target simd | target exit | | 3248 // | | data | | 3249 // | target simd | teams | | 3250 // | target simd | cancellation | | 3251 // | | point | | 3252 // | target simd | cancel | | 3253 // | target simd | taskloop | | 3254 // | target simd | taskloop simd | | 3255 // | target simd | distribute | | 3256 // | target simd | distribute | | 3257 // | | parallel for | | 3258 // | target simd | distribute | | 3259 // | |parallel for simd| | 3260 // | target simd | distribute simd | | 3261 // | target simd | target parallel | | 3262 // | | for simd | | 3263 // | target simd | target simd | | 3264 // | target simd | teams distribute| | 3265 // | target simd | teams distribute| | 3266 // | | simd | | 3267 // +------------------+-----------------+------------------------------------+ 3268 // | teams distribute | parallel | | 3269 // | teams distribute | for | | 3270 // | teams distribute | for simd | | 3271 // | teams distribute | master | | 3272 // | teams distribute | critical | | 3273 // | teams distribute | simd | | 3274 // | teams distribute | sections | | 3275 // | teams distribute | section | | 3276 // | teams distribute | single | | 3277 // | teams distribute | parallel for | | 3278 // | teams distribute |parallel for simd| | 3279 // | teams distribute |parallel sections| | 3280 // | teams distribute | task | | 3281 // | teams distribute | taskyield | | 3282 // | teams distribute | barrier | | 3283 // | teams distribute | taskwait | | 3284 // | teams distribute | taskgroup | | 3285 // | teams distribute | flush | | 3286 // | teams distribute | ordered | + (with simd clause) | 3287 // | teams distribute | atomic | | 3288 // | teams distribute | target | | 3289 // | teams distribute | target parallel | | 3290 // | teams distribute | target parallel | | 3291 // | | for | | 3292 // | teams distribute | target enter | | 3293 // | | data | | 3294 // | teams distribute | target exit | | 3295 // | | data | | 3296 // | teams distribute | teams | | 3297 // | teams distribute | cancellation | | 3298 // | | point | | 3299 // | teams distribute | cancel | | 3300 // | teams distribute | taskloop | | 3301 // | teams distribute | taskloop simd | | 3302 // | teams distribute | distribute | | 3303 // | teams distribute | distribute | | 3304 // | | parallel for | | 3305 // | teams distribute | distribute | | 3306 // | |parallel for simd| | 3307 // | teams distribute | distribute simd | | 3308 // | teams distribute | target parallel | | 3309 // | | for simd | | 3310 // | teams distribute | teams distribute| | 3311 // | teams distribute | teams distribute| | 3312 // | | simd | | 3313 // +------------------+-----------------+------------------------------------+ 3314 // | teams distribute | parallel | | 3315 // | simd | | | 3316 // | teams distribute | for | | 3317 // | simd | | | 3318 // | teams distribute | for simd | | 3319 // | simd | | | 3320 // | teams distribute | master | | 3321 // | simd | | | 3322 // | teams distribute | critical | | 3323 // | simd | | | 3324 // | teams distribute | simd | | 3325 // | simd | | | 3326 // | teams distribute | sections | | 3327 // | simd | | | 3328 // | teams distribute | section | | 3329 // | simd | | | 3330 // | teams distribute | single | | 3331 // | simd | | | 3332 // | teams distribute | parallel for | | 3333 // | simd | | | 3334 // | teams distribute |parallel for simd| | 3335 // | simd | | | 3336 // | teams distribute |parallel sections| | 3337 // | simd | | | 3338 // | teams distribute | task | | 3339 // | simd | | | 3340 // | teams distribute | taskyield | | 3341 // | simd | | | 3342 // | teams distribute | barrier | | 3343 // | simd | | | 3344 // | teams distribute | taskwait | | 3345 // | simd | | | 3346 // | teams distribute | taskgroup | | 3347 // | simd | | | 3348 // | teams distribute | flush | | 3349 // | simd | | | 3350 // | teams distribute | ordered | + (with simd clause) | 3351 // | simd | | | 3352 // | teams distribute | atomic | | 3353 // | simd | | | 3354 // | teams distribute | target | | 3355 // | simd | | | 3356 // | teams distribute | target parallel | | 3357 // | simd | | | 3358 // | teams distribute | target parallel | | 3359 // | simd | for | | 3360 // | teams distribute | target enter | | 3361 // | simd | data | | 3362 // | teams distribute | target exit | | 3363 // | simd | data | | 3364 // | teams distribute | teams | | 3365 // | simd | | | 3366 // | teams distribute | cancellation | | 3367 // | simd | point | | 3368 // | teams distribute | cancel | | 3369 // | simd | | | 3370 // | teams distribute | taskloop | | 3371 // | simd | | | 3372 // | teams distribute | taskloop simd | | 3373 // | simd | | | 3374 // | teams distribute | distribute | | 3375 // | simd | | | 3376 // | teams distribute | distribute | | 3377 // | simd | parallel for | | 3378 // | teams distribute | distribute | | 3379 // | simd |parallel for simd| | 3380 // | teams distribute | distribute simd | | 3381 // | simd | | | 3382 // | teams distribute | target parallel | | 3383 // | simd | for simd | | 3384 // | teams distribute | teams distribute| | 3385 // | simd | | | 3386 // | teams distribute | teams distribute| | 3387 // | simd | simd | | 3388 // +------------------+-----------------+------------------------------------+ 3389 if (Stack->getCurScope()) { 3390 auto ParentRegion = Stack->getParentDirective(); 3391 auto OffendingRegion = ParentRegion; 3392 bool NestingProhibited = false; 3393 bool CloseNesting = true; 3394 bool OrphanSeen = false; 3395 enum { 3396 NoRecommend, 3397 ShouldBeInParallelRegion, 3398 ShouldBeInOrderedRegion, 3399 ShouldBeInTargetRegion, 3400 ShouldBeInTeamsRegion 3401 } Recommend = NoRecommend; 3402 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 3403 // OpenMP [2.16, Nesting of Regions] 3404 // OpenMP constructs may not be nested inside a simd region. 3405 // OpenMP [2.8.1,simd Construct, Restrictions] 3406 // An ordered construct with the simd clause is the only OpenMP 3407 // construct that can appear in the simd region. 3408 // Allowing a SIMD construct nested in another SIMD construct is an 3409 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 3410 // message. 3411 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 3412 ? diag::err_omp_prohibited_region_simd 3413 : diag::warn_omp_nesting_simd); 3414 return CurrentRegion != OMPD_simd; 3415 } 3416 if (ParentRegion == OMPD_atomic) { 3417 // OpenMP [2.16, Nesting of Regions] 3418 // OpenMP constructs may not be nested inside an atomic region. 3419 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 3420 return true; 3421 } 3422 if (CurrentRegion == OMPD_section) { 3423 // OpenMP [2.7.2, sections Construct, Restrictions] 3424 // Orphaned section directives are prohibited. That is, the section 3425 // directives must appear within the sections construct and must not be 3426 // encountered elsewhere in the sections region. 3427 if (ParentRegion != OMPD_sections && 3428 ParentRegion != OMPD_parallel_sections) { 3429 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 3430 << (ParentRegion != OMPD_unknown) 3431 << getOpenMPDirectiveName(ParentRegion); 3432 return true; 3433 } 3434 return false; 3435 } 3436 // Allow some constructs (except teams) to be orphaned (they could be 3437 // used in functions, called from OpenMP regions with the required 3438 // preconditions). 3439 if (ParentRegion == OMPD_unknown && !isOpenMPTeamsDirective(CurrentRegion)) 3440 return false; 3441 if (CurrentRegion == OMPD_cancellation_point || 3442 CurrentRegion == OMPD_cancel) { 3443 // OpenMP [2.16, Nesting of Regions] 3444 // A cancellation point construct for which construct-type-clause is 3445 // taskgroup must be nested inside a task construct. A cancellation 3446 // point construct for which construct-type-clause is not taskgroup must 3447 // be closely nested inside an OpenMP construct that matches the type 3448 // specified in construct-type-clause. 3449 // A cancel construct for which construct-type-clause is taskgroup must be 3450 // nested inside a task construct. A cancel construct for which 3451 // construct-type-clause is not taskgroup must be closely nested inside an 3452 // OpenMP construct that matches the type specified in 3453 // construct-type-clause. 3454 NestingProhibited = 3455 !((CancelRegion == OMPD_parallel && 3456 (ParentRegion == OMPD_parallel || 3457 ParentRegion == OMPD_target_parallel)) || 3458 (CancelRegion == OMPD_for && 3459 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 3460 ParentRegion == OMPD_target_parallel_for)) || 3461 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 3462 (CancelRegion == OMPD_sections && 3463 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 3464 ParentRegion == OMPD_parallel_sections))); 3465 } else if (CurrentRegion == OMPD_master) { 3466 // OpenMP [2.16, Nesting of Regions] 3467 // A master region may not be closely nested inside a worksharing, 3468 // atomic, or explicit task region. 3469 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3470 isOpenMPTaskingDirective(ParentRegion); 3471 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 3472 // OpenMP [2.16, Nesting of Regions] 3473 // A critical region may not be nested (closely or otherwise) inside a 3474 // critical region with the same name. Note that this restriction is not 3475 // sufficient to prevent deadlock. 3476 SourceLocation PreviousCriticalLoc; 3477 bool DeadLock = Stack->hasDirective( 3478 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 3479 const DeclarationNameInfo &DNI, 3480 SourceLocation Loc) -> bool { 3481 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 3482 PreviousCriticalLoc = Loc; 3483 return true; 3484 } else 3485 return false; 3486 }, 3487 false /* skip top directive */); 3488 if (DeadLock) { 3489 SemaRef.Diag(StartLoc, 3490 diag::err_omp_prohibited_region_critical_same_name) 3491 << CurrentName.getName(); 3492 if (PreviousCriticalLoc.isValid()) 3493 SemaRef.Diag(PreviousCriticalLoc, 3494 diag::note_omp_previous_critical_region); 3495 return true; 3496 } 3497 } else if (CurrentRegion == OMPD_barrier) { 3498 // OpenMP [2.16, Nesting of Regions] 3499 // A barrier region may not be closely nested inside a worksharing, 3500 // explicit task, critical, ordered, atomic, or master region. 3501 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3502 isOpenMPTaskingDirective(ParentRegion) || 3503 ParentRegion == OMPD_master || 3504 ParentRegion == OMPD_critical || 3505 ParentRegion == OMPD_ordered; 3506 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 3507 !isOpenMPParallelDirective(CurrentRegion)) { 3508 // OpenMP [2.16, Nesting of Regions] 3509 // A worksharing region may not be closely nested inside a worksharing, 3510 // explicit task, critical, ordered, atomic, or master region. 3511 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 3512 isOpenMPTaskingDirective(ParentRegion) || 3513 ParentRegion == OMPD_master || 3514 ParentRegion == OMPD_critical || 3515 ParentRegion == OMPD_ordered; 3516 Recommend = ShouldBeInParallelRegion; 3517 } else if (CurrentRegion == OMPD_ordered) { 3518 // OpenMP [2.16, Nesting of Regions] 3519 // An ordered region may not be closely nested inside a critical, 3520 // atomic, or explicit task region. 3521 // An ordered region must be closely nested inside a loop region (or 3522 // parallel loop region) with an ordered clause. 3523 // OpenMP [2.8.1,simd Construct, Restrictions] 3524 // An ordered construct with the simd clause is the only OpenMP construct 3525 // that can appear in the simd region. 3526 NestingProhibited = ParentRegion == OMPD_critical || 3527 isOpenMPTaskingDirective(ParentRegion) || 3528 !(isOpenMPSimdDirective(ParentRegion) || 3529 Stack->isParentOrderedRegion()); 3530 Recommend = ShouldBeInOrderedRegion; 3531 } else if (isOpenMPTeamsDirective(CurrentRegion)) { 3532 // OpenMP [2.16, Nesting of Regions] 3533 // If specified, a teams construct must be contained within a target 3534 // construct. 3535 NestingProhibited = ParentRegion != OMPD_target; 3536 OrphanSeen = ParentRegion == OMPD_unknown; 3537 Recommend = ShouldBeInTargetRegion; 3538 Stack->setParentTeamsRegionLoc(Stack->getConstructLoc()); 3539 } 3540 if (!NestingProhibited && ParentRegion == OMPD_teams) { 3541 // OpenMP [2.16, Nesting of Regions] 3542 // distribute, parallel, parallel sections, parallel workshare, and the 3543 // parallel loop and parallel loop SIMD constructs are the only OpenMP 3544 // constructs that can be closely nested in the teams region. 3545 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 3546 !isOpenMPDistributeDirective(CurrentRegion); 3547 Recommend = ShouldBeInParallelRegion; 3548 } 3549 if (!NestingProhibited && 3550 isOpenMPNestingDistributeDirective(CurrentRegion)) { 3551 // OpenMP 4.5 [2.17 Nesting of Regions] 3552 // The region associated with the distribute construct must be strictly 3553 // nested inside a teams region 3554 NestingProhibited = ParentRegion != OMPD_teams; 3555 Recommend = ShouldBeInTeamsRegion; 3556 } 3557 if (!NestingProhibited && 3558 (isOpenMPTargetExecutionDirective(CurrentRegion) || 3559 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 3560 // OpenMP 4.5 [2.17 Nesting of Regions] 3561 // If a target, target update, target data, target enter data, or 3562 // target exit data construct is encountered during execution of a 3563 // target region, the behavior is unspecified. 3564 NestingProhibited = Stack->hasDirective( 3565 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 3566 SourceLocation) -> bool { 3567 if (isOpenMPTargetExecutionDirective(K)) { 3568 OffendingRegion = K; 3569 return true; 3570 } else 3571 return false; 3572 }, 3573 false /* don't skip top directive */); 3574 CloseNesting = false; 3575 } 3576 if (NestingProhibited) { 3577 if (OrphanSeen) { 3578 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 3579 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 3580 } else { 3581 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 3582 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 3583 << Recommend << getOpenMPDirectiveName(CurrentRegion); 3584 } 3585 return true; 3586 } 3587 } 3588 return false; 3589 } 3590 3591 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 3592 ArrayRef<OMPClause *> Clauses, 3593 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 3594 bool ErrorFound = false; 3595 unsigned NamedModifiersNumber = 0; 3596 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 3597 OMPD_unknown + 1); 3598 SmallVector<SourceLocation, 4> NameModifierLoc; 3599 for (const auto *C : Clauses) { 3600 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 3601 // At most one if clause without a directive-name-modifier can appear on 3602 // the directive. 3603 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 3604 if (FoundNameModifiers[CurNM]) { 3605 S.Diag(C->getLocStart(), diag::err_omp_more_one_clause) 3606 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 3607 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 3608 ErrorFound = true; 3609 } else if (CurNM != OMPD_unknown) { 3610 NameModifierLoc.push_back(IC->getNameModifierLoc()); 3611 ++NamedModifiersNumber; 3612 } 3613 FoundNameModifiers[CurNM] = IC; 3614 if (CurNM == OMPD_unknown) 3615 continue; 3616 // Check if the specified name modifier is allowed for the current 3617 // directive. 3618 // At most one if clause with the particular directive-name-modifier can 3619 // appear on the directive. 3620 bool MatchFound = false; 3621 for (auto NM : AllowedNameModifiers) { 3622 if (CurNM == NM) { 3623 MatchFound = true; 3624 break; 3625 } 3626 } 3627 if (!MatchFound) { 3628 S.Diag(IC->getNameModifierLoc(), 3629 diag::err_omp_wrong_if_directive_name_modifier) 3630 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 3631 ErrorFound = true; 3632 } 3633 } 3634 } 3635 // If any if clause on the directive includes a directive-name-modifier then 3636 // all if clauses on the directive must include a directive-name-modifier. 3637 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 3638 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 3639 S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(), 3640 diag::err_omp_no_more_if_clause); 3641 } else { 3642 std::string Values; 3643 std::string Sep(", "); 3644 unsigned AllowedCnt = 0; 3645 unsigned TotalAllowedNum = 3646 AllowedNameModifiers.size() - NamedModifiersNumber; 3647 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 3648 ++Cnt) { 3649 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 3650 if (!FoundNameModifiers[NM]) { 3651 Values += "'"; 3652 Values += getOpenMPDirectiveName(NM); 3653 Values += "'"; 3654 if (AllowedCnt + 2 == TotalAllowedNum) 3655 Values += " or "; 3656 else if (AllowedCnt + 1 != TotalAllowedNum) 3657 Values += Sep; 3658 ++AllowedCnt; 3659 } 3660 } 3661 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(), 3662 diag::err_omp_unnamed_if_clause) 3663 << (TotalAllowedNum > 1) << Values; 3664 } 3665 for (auto Loc : NameModifierLoc) { 3666 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 3667 } 3668 ErrorFound = true; 3669 } 3670 return ErrorFound; 3671 } 3672 3673 StmtResult Sema::ActOnOpenMPExecutableDirective( 3674 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 3675 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 3676 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 3677 StmtResult Res = StmtError(); 3678 if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 3679 StartLoc)) 3680 return StmtError(); 3681 3682 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 3683 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 3684 bool ErrorFound = false; 3685 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 3686 if (AStmt) { 3687 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3688 3689 // Check default data sharing attributes for referenced variables. 3690 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 3691 DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt()); 3692 if (DSAChecker.isErrorFound()) 3693 return StmtError(); 3694 // Generate list of implicitly defined firstprivate variables. 3695 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 3696 3697 if (!DSAChecker.getImplicitFirstprivate().empty()) { 3698 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 3699 DSAChecker.getImplicitFirstprivate(), SourceLocation(), 3700 SourceLocation(), SourceLocation())) { 3701 ClausesWithImplicit.push_back(Implicit); 3702 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 3703 DSAChecker.getImplicitFirstprivate().size(); 3704 } else 3705 ErrorFound = true; 3706 } 3707 } 3708 3709 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 3710 switch (Kind) { 3711 case OMPD_parallel: 3712 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 3713 EndLoc); 3714 AllowedNameModifiers.push_back(OMPD_parallel); 3715 break; 3716 case OMPD_simd: 3717 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3718 VarsWithInheritedDSA); 3719 break; 3720 case OMPD_for: 3721 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 3722 VarsWithInheritedDSA); 3723 break; 3724 case OMPD_for_simd: 3725 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3726 EndLoc, VarsWithInheritedDSA); 3727 break; 3728 case OMPD_sections: 3729 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 3730 EndLoc); 3731 break; 3732 case OMPD_section: 3733 assert(ClausesWithImplicit.empty() && 3734 "No clauses are allowed for 'omp section' directive"); 3735 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 3736 break; 3737 case OMPD_single: 3738 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 3739 EndLoc); 3740 break; 3741 case OMPD_master: 3742 assert(ClausesWithImplicit.empty() && 3743 "No clauses are allowed for 'omp master' directive"); 3744 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 3745 break; 3746 case OMPD_critical: 3747 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 3748 StartLoc, EndLoc); 3749 break; 3750 case OMPD_parallel_for: 3751 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 3752 EndLoc, VarsWithInheritedDSA); 3753 AllowedNameModifiers.push_back(OMPD_parallel); 3754 break; 3755 case OMPD_parallel_for_simd: 3756 Res = ActOnOpenMPParallelForSimdDirective( 3757 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3758 AllowedNameModifiers.push_back(OMPD_parallel); 3759 break; 3760 case OMPD_parallel_sections: 3761 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 3762 StartLoc, EndLoc); 3763 AllowedNameModifiers.push_back(OMPD_parallel); 3764 break; 3765 case OMPD_task: 3766 Res = 3767 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3768 AllowedNameModifiers.push_back(OMPD_task); 3769 break; 3770 case OMPD_taskyield: 3771 assert(ClausesWithImplicit.empty() && 3772 "No clauses are allowed for 'omp taskyield' directive"); 3773 assert(AStmt == nullptr && 3774 "No associated statement allowed for 'omp taskyield' directive"); 3775 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 3776 break; 3777 case OMPD_barrier: 3778 assert(ClausesWithImplicit.empty() && 3779 "No clauses are allowed for 'omp barrier' directive"); 3780 assert(AStmt == nullptr && 3781 "No associated statement allowed for 'omp barrier' directive"); 3782 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 3783 break; 3784 case OMPD_taskwait: 3785 assert(ClausesWithImplicit.empty() && 3786 "No clauses are allowed for 'omp taskwait' directive"); 3787 assert(AStmt == nullptr && 3788 "No associated statement allowed for 'omp taskwait' directive"); 3789 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 3790 break; 3791 case OMPD_taskgroup: 3792 assert(ClausesWithImplicit.empty() && 3793 "No clauses are allowed for 'omp taskgroup' directive"); 3794 Res = ActOnOpenMPTaskgroupDirective(AStmt, StartLoc, EndLoc); 3795 break; 3796 case OMPD_flush: 3797 assert(AStmt == nullptr && 3798 "No associated statement allowed for 'omp flush' directive"); 3799 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 3800 break; 3801 case OMPD_ordered: 3802 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 3803 EndLoc); 3804 break; 3805 case OMPD_atomic: 3806 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 3807 EndLoc); 3808 break; 3809 case OMPD_teams: 3810 Res = 3811 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 3812 break; 3813 case OMPD_target: 3814 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 3815 EndLoc); 3816 AllowedNameModifiers.push_back(OMPD_target); 3817 break; 3818 case OMPD_target_parallel: 3819 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 3820 StartLoc, EndLoc); 3821 AllowedNameModifiers.push_back(OMPD_target); 3822 AllowedNameModifiers.push_back(OMPD_parallel); 3823 break; 3824 case OMPD_target_parallel_for: 3825 Res = ActOnOpenMPTargetParallelForDirective( 3826 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3827 AllowedNameModifiers.push_back(OMPD_target); 3828 AllowedNameModifiers.push_back(OMPD_parallel); 3829 break; 3830 case OMPD_cancellation_point: 3831 assert(ClausesWithImplicit.empty() && 3832 "No clauses are allowed for 'omp cancellation point' directive"); 3833 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 3834 "cancellation point' directive"); 3835 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 3836 break; 3837 case OMPD_cancel: 3838 assert(AStmt == nullptr && 3839 "No associated statement allowed for 'omp cancel' directive"); 3840 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 3841 CancelRegion); 3842 AllowedNameModifiers.push_back(OMPD_cancel); 3843 break; 3844 case OMPD_target_data: 3845 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 3846 EndLoc); 3847 AllowedNameModifiers.push_back(OMPD_target_data); 3848 break; 3849 case OMPD_target_enter_data: 3850 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 3851 EndLoc); 3852 AllowedNameModifiers.push_back(OMPD_target_enter_data); 3853 break; 3854 case OMPD_target_exit_data: 3855 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 3856 EndLoc); 3857 AllowedNameModifiers.push_back(OMPD_target_exit_data); 3858 break; 3859 case OMPD_taskloop: 3860 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 3861 EndLoc, VarsWithInheritedDSA); 3862 AllowedNameModifiers.push_back(OMPD_taskloop); 3863 break; 3864 case OMPD_taskloop_simd: 3865 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3866 EndLoc, VarsWithInheritedDSA); 3867 AllowedNameModifiers.push_back(OMPD_taskloop); 3868 break; 3869 case OMPD_distribute: 3870 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 3871 EndLoc, VarsWithInheritedDSA); 3872 break; 3873 case OMPD_target_update: 3874 assert(!AStmt && "Statement is not allowed for target update"); 3875 Res = 3876 ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, EndLoc); 3877 AllowedNameModifiers.push_back(OMPD_target_update); 3878 break; 3879 case OMPD_distribute_parallel_for: 3880 Res = ActOnOpenMPDistributeParallelForDirective( 3881 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3882 AllowedNameModifiers.push_back(OMPD_parallel); 3883 break; 3884 case OMPD_distribute_parallel_for_simd: 3885 Res = ActOnOpenMPDistributeParallelForSimdDirective( 3886 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3887 AllowedNameModifiers.push_back(OMPD_parallel); 3888 break; 3889 case OMPD_distribute_simd: 3890 Res = ActOnOpenMPDistributeSimdDirective( 3891 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3892 break; 3893 case OMPD_target_parallel_for_simd: 3894 Res = ActOnOpenMPTargetParallelForSimdDirective( 3895 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3896 AllowedNameModifiers.push_back(OMPD_target); 3897 AllowedNameModifiers.push_back(OMPD_parallel); 3898 break; 3899 case OMPD_target_simd: 3900 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 3901 EndLoc, VarsWithInheritedDSA); 3902 AllowedNameModifiers.push_back(OMPD_target); 3903 break; 3904 case OMPD_teams_distribute: 3905 Res = ActOnOpenMPTeamsDistributeDirective( 3906 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3907 break; 3908 case OMPD_teams_distribute_simd: 3909 Res = ActOnOpenMPTeamsDistributeSimdDirective( 3910 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 3911 break; 3912 case OMPD_declare_target: 3913 case OMPD_end_declare_target: 3914 case OMPD_threadprivate: 3915 case OMPD_declare_reduction: 3916 case OMPD_declare_simd: 3917 llvm_unreachable("OpenMP Directive is not allowed"); 3918 case OMPD_unknown: 3919 llvm_unreachable("Unknown OpenMP directive"); 3920 } 3921 3922 for (auto P : VarsWithInheritedDSA) { 3923 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 3924 << P.first << P.second->getSourceRange(); 3925 } 3926 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 3927 3928 if (!AllowedNameModifiers.empty()) 3929 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 3930 ErrorFound; 3931 3932 if (ErrorFound) 3933 return StmtError(); 3934 return Res; 3935 } 3936 3937 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 3938 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 3939 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 3940 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 3941 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 3942 assert(Aligneds.size() == Alignments.size()); 3943 assert(Linears.size() == LinModifiers.size()); 3944 assert(Linears.size() == Steps.size()); 3945 if (!DG || DG.get().isNull()) 3946 return DeclGroupPtrTy(); 3947 3948 if (!DG.get().isSingleDecl()) { 3949 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 3950 return DG; 3951 } 3952 auto *ADecl = DG.get().getSingleDecl(); 3953 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 3954 ADecl = FTD->getTemplatedDecl(); 3955 3956 auto *FD = dyn_cast<FunctionDecl>(ADecl); 3957 if (!FD) { 3958 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 3959 return DeclGroupPtrTy(); 3960 } 3961 3962 // OpenMP [2.8.2, declare simd construct, Description] 3963 // The parameter of the simdlen clause must be a constant positive integer 3964 // expression. 3965 ExprResult SL; 3966 if (Simdlen) 3967 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 3968 // OpenMP [2.8.2, declare simd construct, Description] 3969 // The special this pointer can be used as if was one of the arguments to the 3970 // function in any of the linear, aligned, or uniform clauses. 3971 // The uniform clause declares one or more arguments to have an invariant 3972 // value for all concurrent invocations of the function in the execution of a 3973 // single SIMD loop. 3974 llvm::DenseMap<Decl *, Expr *> UniformedArgs; 3975 Expr *UniformedLinearThis = nullptr; 3976 for (auto *E : Uniforms) { 3977 E = E->IgnoreParenImpCasts(); 3978 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 3979 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 3980 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 3981 FD->getParamDecl(PVD->getFunctionScopeIndex()) 3982 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 3983 UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E)); 3984 continue; 3985 } 3986 if (isa<CXXThisExpr>(E)) { 3987 UniformedLinearThis = E; 3988 continue; 3989 } 3990 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 3991 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 3992 } 3993 // OpenMP [2.8.2, declare simd construct, Description] 3994 // The aligned clause declares that the object to which each list item points 3995 // is aligned to the number of bytes expressed in the optional parameter of 3996 // the aligned clause. 3997 // The special this pointer can be used as if was one of the arguments to the 3998 // function in any of the linear, aligned, or uniform clauses. 3999 // The type of list items appearing in the aligned clause must be array, 4000 // pointer, reference to array, or reference to pointer. 4001 llvm::DenseMap<Decl *, Expr *> AlignedArgs; 4002 Expr *AlignedThis = nullptr; 4003 for (auto *E : Aligneds) { 4004 E = E->IgnoreParenImpCasts(); 4005 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 4006 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4007 auto *CanonPVD = PVD->getCanonicalDecl(); 4008 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4009 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4010 ->getCanonicalDecl() == CanonPVD) { 4011 // OpenMP [2.8.1, simd construct, Restrictions] 4012 // A list-item cannot appear in more than one aligned clause. 4013 if (AlignedArgs.count(CanonPVD) > 0) { 4014 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4015 << 1 << E->getSourceRange(); 4016 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 4017 diag::note_omp_explicit_dsa) 4018 << getOpenMPClauseName(OMPC_aligned); 4019 continue; 4020 } 4021 AlignedArgs[CanonPVD] = E; 4022 QualType QTy = PVD->getType() 4023 .getNonReferenceType() 4024 .getUnqualifiedType() 4025 .getCanonicalType(); 4026 const Type *Ty = QTy.getTypePtrOrNull(); 4027 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 4028 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 4029 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 4030 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 4031 } 4032 continue; 4033 } 4034 } 4035 if (isa<CXXThisExpr>(E)) { 4036 if (AlignedThis) { 4037 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 4038 << 2 << E->getSourceRange(); 4039 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 4040 << getOpenMPClauseName(OMPC_aligned); 4041 } 4042 AlignedThis = E; 4043 continue; 4044 } 4045 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4046 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4047 } 4048 // The optional parameter of the aligned clause, alignment, must be a constant 4049 // positive integer expression. If no optional parameter is specified, 4050 // implementation-defined default alignments for SIMD instructions on the 4051 // target platforms are assumed. 4052 SmallVector<Expr *, 4> NewAligns; 4053 for (auto *E : Alignments) { 4054 ExprResult Align; 4055 if (E) 4056 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 4057 NewAligns.push_back(Align.get()); 4058 } 4059 // OpenMP [2.8.2, declare simd construct, Description] 4060 // The linear clause declares one or more list items to be private to a SIMD 4061 // lane and to have a linear relationship with respect to the iteration space 4062 // of a loop. 4063 // The special this pointer can be used as if was one of the arguments to the 4064 // function in any of the linear, aligned, or uniform clauses. 4065 // When a linear-step expression is specified in a linear clause it must be 4066 // either a constant integer expression or an integer-typed parameter that is 4067 // specified in a uniform clause on the directive. 4068 llvm::DenseMap<Decl *, Expr *> LinearArgs; 4069 const bool IsUniformedThis = UniformedLinearThis != nullptr; 4070 auto MI = LinModifiers.begin(); 4071 for (auto *E : Linears) { 4072 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 4073 ++MI; 4074 E = E->IgnoreParenImpCasts(); 4075 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 4076 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4077 auto *CanonPVD = PVD->getCanonicalDecl(); 4078 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 4079 FD->getParamDecl(PVD->getFunctionScopeIndex()) 4080 ->getCanonicalDecl() == CanonPVD) { 4081 // OpenMP [2.15.3.7, linear Clause, Restrictions] 4082 // A list-item cannot appear in more than one linear clause. 4083 if (LinearArgs.count(CanonPVD) > 0) { 4084 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4085 << getOpenMPClauseName(OMPC_linear) 4086 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 4087 Diag(LinearArgs[CanonPVD]->getExprLoc(), 4088 diag::note_omp_explicit_dsa) 4089 << getOpenMPClauseName(OMPC_linear); 4090 continue; 4091 } 4092 // Each argument can appear in at most one uniform or linear clause. 4093 if (UniformedArgs.count(CanonPVD) > 0) { 4094 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4095 << getOpenMPClauseName(OMPC_linear) 4096 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 4097 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 4098 diag::note_omp_explicit_dsa) 4099 << getOpenMPClauseName(OMPC_uniform); 4100 continue; 4101 } 4102 LinearArgs[CanonPVD] = E; 4103 if (E->isValueDependent() || E->isTypeDependent() || 4104 E->isInstantiationDependent() || 4105 E->containsUnexpandedParameterPack()) 4106 continue; 4107 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 4108 PVD->getOriginalType()); 4109 continue; 4110 } 4111 } 4112 if (isa<CXXThisExpr>(E)) { 4113 if (UniformedLinearThis) { 4114 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 4115 << getOpenMPClauseName(OMPC_linear) 4116 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 4117 << E->getSourceRange(); 4118 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 4119 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 4120 : OMPC_linear); 4121 continue; 4122 } 4123 UniformedLinearThis = E; 4124 if (E->isValueDependent() || E->isTypeDependent() || 4125 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4126 continue; 4127 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 4128 E->getType()); 4129 continue; 4130 } 4131 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 4132 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 4133 } 4134 Expr *Step = nullptr; 4135 Expr *NewStep = nullptr; 4136 SmallVector<Expr *, 4> NewSteps; 4137 for (auto *E : Steps) { 4138 // Skip the same step expression, it was checked already. 4139 if (Step == E || !E) { 4140 NewSteps.push_back(E ? NewStep : nullptr); 4141 continue; 4142 } 4143 Step = E; 4144 if (auto *DRE = dyn_cast<DeclRefExpr>(Step)) 4145 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 4146 auto *CanonPVD = PVD->getCanonicalDecl(); 4147 if (UniformedArgs.count(CanonPVD) == 0) { 4148 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 4149 << Step->getSourceRange(); 4150 } else if (E->isValueDependent() || E->isTypeDependent() || 4151 E->isInstantiationDependent() || 4152 E->containsUnexpandedParameterPack() || 4153 CanonPVD->getType()->hasIntegerRepresentation()) 4154 NewSteps.push_back(Step); 4155 else { 4156 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 4157 << Step->getSourceRange(); 4158 } 4159 continue; 4160 } 4161 NewStep = Step; 4162 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 4163 !Step->isInstantiationDependent() && 4164 !Step->containsUnexpandedParameterPack()) { 4165 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 4166 .get(); 4167 if (NewStep) 4168 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 4169 } 4170 NewSteps.push_back(NewStep); 4171 } 4172 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 4173 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 4174 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 4175 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 4176 const_cast<Expr **>(Linears.data()), Linears.size(), 4177 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 4178 NewSteps.data(), NewSteps.size(), SR); 4179 ADecl->addAttr(NewAttr); 4180 return ConvertDeclToDeclGroup(ADecl); 4181 } 4182 4183 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 4184 Stmt *AStmt, 4185 SourceLocation StartLoc, 4186 SourceLocation EndLoc) { 4187 if (!AStmt) 4188 return StmtError(); 4189 4190 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 4191 // 1.2.2 OpenMP Language Terminology 4192 // Structured block - An executable statement with a single entry at the 4193 // top and a single exit at the bottom. 4194 // The point of exit cannot be a branch out of the structured block. 4195 // longjmp() and throw() must not violate the entry/exit criteria. 4196 CS->getCapturedDecl()->setNothrow(); 4197 4198 getCurFunction()->setHasBranchProtectedScope(); 4199 4200 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4201 DSAStack->isCancelRegion()); 4202 } 4203 4204 namespace { 4205 /// \brief Helper class for checking canonical form of the OpenMP loops and 4206 /// extracting iteration space of each loop in the loop nest, that will be used 4207 /// for IR generation. 4208 class OpenMPIterationSpaceChecker { 4209 /// \brief Reference to Sema. 4210 Sema &SemaRef; 4211 /// \brief A location for diagnostics (when there is no some better location). 4212 SourceLocation DefaultLoc; 4213 /// \brief A location for diagnostics (when increment is not compatible). 4214 SourceLocation ConditionLoc; 4215 /// \brief A source location for referring to loop init later. 4216 SourceRange InitSrcRange; 4217 /// \brief A source location for referring to condition later. 4218 SourceRange ConditionSrcRange; 4219 /// \brief A source location for referring to increment later. 4220 SourceRange IncrementSrcRange; 4221 /// \brief Loop variable. 4222 ValueDecl *LCDecl = nullptr; 4223 /// \brief Reference to loop variable. 4224 Expr *LCRef = nullptr; 4225 /// \brief Lower bound (initializer for the var). 4226 Expr *LB = nullptr; 4227 /// \brief Upper bound. 4228 Expr *UB = nullptr; 4229 /// \brief Loop step (increment). 4230 Expr *Step = nullptr; 4231 /// \brief This flag is true when condition is one of: 4232 /// Var < UB 4233 /// Var <= UB 4234 /// UB > Var 4235 /// UB >= Var 4236 bool TestIsLessOp = false; 4237 /// \brief This flag is true when condition is strict ( < or > ). 4238 bool TestIsStrictOp = false; 4239 /// \brief This flag is true when step is subtracted on each iteration. 4240 bool SubtractStep = false; 4241 4242 public: 4243 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 4244 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 4245 /// \brief Check init-expr for canonical loop form and save loop counter 4246 /// variable - #Var and its initialization value - #LB. 4247 bool CheckInit(Stmt *S, bool EmitDiags = true); 4248 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags 4249 /// for less/greater and for strict/non-strict comparison. 4250 bool CheckCond(Expr *S); 4251 /// \brief Check incr-expr for canonical loop form and return true if it 4252 /// does not conform, otherwise save loop step (#Step). 4253 bool CheckInc(Expr *S); 4254 /// \brief Return the loop counter variable. 4255 ValueDecl *GetLoopDecl() const { return LCDecl; } 4256 /// \brief Return the reference expression to loop counter variable. 4257 Expr *GetLoopDeclRefExpr() const { return LCRef; } 4258 /// \brief Source range of the loop init. 4259 SourceRange GetInitSrcRange() const { return InitSrcRange; } 4260 /// \brief Source range of the loop condition. 4261 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; } 4262 /// \brief Source range of the loop increment. 4263 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; } 4264 /// \brief True if the step should be subtracted. 4265 bool ShouldSubtractStep() const { return SubtractStep; } 4266 /// \brief Build the expression to calculate the number of iterations. 4267 Expr * 4268 BuildNumIterations(Scope *S, const bool LimitedType, 4269 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 4270 /// \brief Build the precondition expression for the loops. 4271 Expr *BuildPreCond(Scope *S, Expr *Cond, 4272 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 4273 /// \brief Build reference expression to the counter be used for codegen. 4274 DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures, 4275 DSAStackTy &DSA) const; 4276 /// \brief Build reference expression to the private counter be used for 4277 /// codegen. 4278 Expr *BuildPrivateCounterVar() const; 4279 /// \brief Build initialization of the counter be used for codegen. 4280 Expr *BuildCounterInit() const; 4281 /// \brief Build step of the counter be used for codegen. 4282 Expr *BuildCounterStep() const; 4283 /// \brief Return true if any expression is dependent. 4284 bool Dependent() const; 4285 4286 private: 4287 /// \brief Check the right-hand side of an assignment in the increment 4288 /// expression. 4289 bool CheckIncRHS(Expr *RHS); 4290 /// \brief Helper to set loop counter variable and its initializer. 4291 bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); 4292 /// \brief Helper to set upper bound. 4293 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR, 4294 SourceLocation SL); 4295 /// \brief Helper to set loop increment. 4296 bool SetStep(Expr *NewStep, bool Subtract); 4297 }; 4298 4299 bool OpenMPIterationSpaceChecker::Dependent() const { 4300 if (!LCDecl) { 4301 assert(!LB && !UB && !Step); 4302 return false; 4303 } 4304 return LCDecl->getType()->isDependentType() || 4305 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 4306 (Step && Step->isValueDependent()); 4307 } 4308 4309 static Expr *getExprAsWritten(Expr *E) { 4310 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) 4311 E = ExprTemp->getSubExpr(); 4312 4313 if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 4314 E = MTE->GetTemporaryExpr(); 4315 4316 while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 4317 E = Binder->getSubExpr(); 4318 4319 if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 4320 E = ICE->getSubExprAsWritten(); 4321 return E->IgnoreParens(); 4322 } 4323 4324 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl, 4325 Expr *NewLCRefExpr, 4326 Expr *NewLB) { 4327 // State consistency checking to ensure correct usage. 4328 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 4329 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4330 if (!NewLCDecl || !NewLB) 4331 return true; 4332 LCDecl = getCanonicalDecl(NewLCDecl); 4333 LCRef = NewLCRefExpr; 4334 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 4335 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4336 if ((Ctor->isCopyOrMoveConstructor() || 4337 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4338 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4339 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 4340 LB = NewLB; 4341 return false; 4342 } 4343 4344 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp, 4345 SourceRange SR, SourceLocation SL) { 4346 // State consistency checking to ensure correct usage. 4347 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 4348 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 4349 if (!NewUB) 4350 return true; 4351 UB = NewUB; 4352 TestIsLessOp = LessOp; 4353 TestIsStrictOp = StrictOp; 4354 ConditionSrcRange = SR; 4355 ConditionLoc = SL; 4356 return false; 4357 } 4358 4359 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) { 4360 // State consistency checking to ensure correct usage. 4361 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 4362 if (!NewStep) 4363 return true; 4364 if (!NewStep->isValueDependent()) { 4365 // Check that the step is integer expression. 4366 SourceLocation StepLoc = NewStep->getLocStart(); 4367 ExprResult Val = 4368 SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep); 4369 if (Val.isInvalid()) 4370 return true; 4371 NewStep = Val.get(); 4372 4373 // OpenMP [2.6, Canonical Loop Form, Restrictions] 4374 // If test-expr is of form var relational-op b and relational-op is < or 4375 // <= then incr-expr must cause var to increase on each iteration of the 4376 // loop. If test-expr is of form var relational-op b and relational-op is 4377 // > or >= then incr-expr must cause var to decrease on each iteration of 4378 // the loop. 4379 // If test-expr is of form b relational-op var and relational-op is < or 4380 // <= then incr-expr must cause var to decrease on each iteration of the 4381 // loop. If test-expr is of form b relational-op var and relational-op is 4382 // > or >= then incr-expr must cause var to increase on each iteration of 4383 // the loop. 4384 llvm::APSInt Result; 4385 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 4386 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 4387 bool IsConstNeg = 4388 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 4389 bool IsConstPos = 4390 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 4391 bool IsConstZero = IsConstant && !Result.getBoolValue(); 4392 if (UB && (IsConstZero || 4393 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 4394 : (IsConstPos || (IsUnsigned && !Subtract))))) { 4395 SemaRef.Diag(NewStep->getExprLoc(), 4396 diag::err_omp_loop_incr_not_compatible) 4397 << LCDecl << TestIsLessOp << NewStep->getSourceRange(); 4398 SemaRef.Diag(ConditionLoc, 4399 diag::note_omp_loop_cond_requres_compatible_incr) 4400 << TestIsLessOp << ConditionSrcRange; 4401 return true; 4402 } 4403 if (TestIsLessOp == Subtract) { 4404 NewStep = 4405 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 4406 .get(); 4407 Subtract = !Subtract; 4408 } 4409 } 4410 4411 Step = NewStep; 4412 SubtractStep = Subtract; 4413 return false; 4414 } 4415 4416 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { 4417 // Check init-expr for canonical loop form and save loop counter 4418 // variable - #Var and its initialization value - #LB. 4419 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 4420 // var = lb 4421 // integer-type var = lb 4422 // random-access-iterator-type var = lb 4423 // pointer-type var = lb 4424 // 4425 if (!S) { 4426 if (EmitDiags) { 4427 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 4428 } 4429 return true; 4430 } 4431 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4432 if (!ExprTemp->cleanupsHaveSideEffects()) 4433 S = ExprTemp->getSubExpr(); 4434 4435 InitSrcRange = S->getSourceRange(); 4436 if (Expr *E = dyn_cast<Expr>(S)) 4437 S = E->IgnoreParens(); 4438 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4439 if (BO->getOpcode() == BO_Assign) { 4440 auto *LHS = BO->getLHS()->IgnoreParens(); 4441 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4442 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4443 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4444 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4445 return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); 4446 } 4447 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4448 if (ME->isArrow() && 4449 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4450 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4451 } 4452 } 4453 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 4454 if (DS->isSingleDecl()) { 4455 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 4456 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 4457 // Accept non-canonical init form here but emit ext. warning. 4458 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 4459 SemaRef.Diag(S->getLocStart(), 4460 diag::ext_omp_loop_not_canonical_init) 4461 << S->getSourceRange(); 4462 return SetLCDeclAndLB(Var, nullptr, Var->getInit()); 4463 } 4464 } 4465 } 4466 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4467 if (CE->getOperator() == OO_Equal) { 4468 auto *LHS = CE->getArg(0); 4469 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 4470 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 4471 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4472 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4473 return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); 4474 } 4475 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 4476 if (ME->isArrow() && 4477 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4478 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 4479 } 4480 } 4481 } 4482 4483 if (Dependent() || SemaRef.CurContext->isDependentContext()) 4484 return false; 4485 if (EmitDiags) { 4486 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init) 4487 << S->getSourceRange(); 4488 } 4489 return true; 4490 } 4491 4492 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the 4493 /// variable (which may be the loop variable) if possible. 4494 static const ValueDecl *GetInitLCDecl(Expr *E) { 4495 if (!E) 4496 return nullptr; 4497 E = getExprAsWritten(E); 4498 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 4499 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 4500 if ((Ctor->isCopyOrMoveConstructor() || 4501 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 4502 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 4503 E = CE->getArg(0)->IgnoreParenImpCasts(); 4504 if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 4505 if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 4506 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 4507 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 4508 return getCanonicalDecl(ME->getMemberDecl()); 4509 return getCanonicalDecl(VD); 4510 } 4511 } 4512 if (auto *ME = dyn_cast_or_null<MemberExpr>(E)) 4513 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 4514 return getCanonicalDecl(ME->getMemberDecl()); 4515 return nullptr; 4516 } 4517 4518 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { 4519 // Check test-expr for canonical form, save upper-bound UB, flags for 4520 // less/greater and for strict/non-strict comparison. 4521 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4522 // var relational-op b 4523 // b relational-op var 4524 // 4525 if (!S) { 4526 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 4527 return true; 4528 } 4529 S = getExprAsWritten(S); 4530 SourceLocation CondLoc = S->getLocStart(); 4531 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4532 if (BO->isRelationalOp()) { 4533 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 4534 return SetUB(BO->getRHS(), 4535 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 4536 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4537 BO->getSourceRange(), BO->getOperatorLoc()); 4538 if (GetInitLCDecl(BO->getRHS()) == LCDecl) 4539 return SetUB(BO->getLHS(), 4540 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 4541 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 4542 BO->getSourceRange(), BO->getOperatorLoc()); 4543 } 4544 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4545 if (CE->getNumArgs() == 2) { 4546 auto Op = CE->getOperator(); 4547 switch (Op) { 4548 case OO_Greater: 4549 case OO_GreaterEqual: 4550 case OO_Less: 4551 case OO_LessEqual: 4552 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 4553 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 4554 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4555 CE->getOperatorLoc()); 4556 if (GetInitLCDecl(CE->getArg(1)) == LCDecl) 4557 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 4558 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 4559 CE->getOperatorLoc()); 4560 break; 4561 default: 4562 break; 4563 } 4564 } 4565 } 4566 if (Dependent() || SemaRef.CurContext->isDependentContext()) 4567 return false; 4568 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 4569 << S->getSourceRange() << LCDecl; 4570 return true; 4571 } 4572 4573 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) { 4574 // RHS of canonical loop form increment can be: 4575 // var + incr 4576 // incr + var 4577 // var - incr 4578 // 4579 RHS = RHS->IgnoreParenImpCasts(); 4580 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 4581 if (BO->isAdditiveOp()) { 4582 bool IsAdd = BO->getOpcode() == BO_Add; 4583 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 4584 return SetStep(BO->getRHS(), !IsAdd); 4585 if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl) 4586 return SetStep(BO->getLHS(), false); 4587 } 4588 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 4589 bool IsAdd = CE->getOperator() == OO_Plus; 4590 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 4591 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 4592 return SetStep(CE->getArg(1), !IsAdd); 4593 if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl) 4594 return SetStep(CE->getArg(0), false); 4595 } 4596 } 4597 if (Dependent() || SemaRef.CurContext->isDependentContext()) 4598 return false; 4599 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr) 4600 << RHS->getSourceRange() << LCDecl; 4601 return true; 4602 } 4603 4604 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { 4605 // Check incr-expr for canonical loop form and return true if it 4606 // does not conform. 4607 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 4608 // ++var 4609 // var++ 4610 // --var 4611 // var-- 4612 // var += incr 4613 // var -= incr 4614 // var = var + incr 4615 // var = incr + var 4616 // var = var - incr 4617 // 4618 if (!S) { 4619 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 4620 return true; 4621 } 4622 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 4623 if (!ExprTemp->cleanupsHaveSideEffects()) 4624 S = ExprTemp->getSubExpr(); 4625 4626 IncrementSrcRange = S->getSourceRange(); 4627 S = S->IgnoreParens(); 4628 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 4629 if (UO->isIncrementDecrementOp() && 4630 GetInitLCDecl(UO->getSubExpr()) == LCDecl) 4631 return SetStep(SemaRef 4632 .ActOnIntegerConstant(UO->getLocStart(), 4633 (UO->isDecrementOp() ? -1 : 1)) 4634 .get(), 4635 false); 4636 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 4637 switch (BO->getOpcode()) { 4638 case BO_AddAssign: 4639 case BO_SubAssign: 4640 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 4641 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 4642 break; 4643 case BO_Assign: 4644 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 4645 return CheckIncRHS(BO->getRHS()); 4646 break; 4647 default: 4648 break; 4649 } 4650 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 4651 switch (CE->getOperator()) { 4652 case OO_PlusPlus: 4653 case OO_MinusMinus: 4654 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 4655 return SetStep(SemaRef 4656 .ActOnIntegerConstant( 4657 CE->getLocStart(), 4658 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 4659 .get(), 4660 false); 4661 break; 4662 case OO_PlusEqual: 4663 case OO_MinusEqual: 4664 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 4665 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 4666 break; 4667 case OO_Equal: 4668 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 4669 return CheckIncRHS(CE->getArg(1)); 4670 break; 4671 default: 4672 break; 4673 } 4674 } 4675 if (Dependent() || SemaRef.CurContext->isDependentContext()) 4676 return false; 4677 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr) 4678 << S->getSourceRange() << LCDecl; 4679 return true; 4680 } 4681 4682 static ExprResult 4683 tryBuildCapture(Sema &SemaRef, Expr *Capture, 4684 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4685 if (SemaRef.CurContext->isDependentContext()) 4686 return ExprResult(Capture); 4687 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 4688 return SemaRef.PerformImplicitConversion( 4689 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 4690 /*AllowExplicit=*/true); 4691 auto I = Captures.find(Capture); 4692 if (I != Captures.end()) 4693 return buildCapture(SemaRef, Capture, I->second); 4694 DeclRefExpr *Ref = nullptr; 4695 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 4696 Captures[Capture] = Ref; 4697 return Res; 4698 } 4699 4700 /// \brief Build the expression to calculate the number of iterations. 4701 Expr *OpenMPIterationSpaceChecker::BuildNumIterations( 4702 Scope *S, const bool LimitedType, 4703 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 4704 ExprResult Diff; 4705 auto VarType = LCDecl->getType().getNonReferenceType(); 4706 if (VarType->isIntegerType() || VarType->isPointerType() || 4707 SemaRef.getLangOpts().CPlusPlus) { 4708 // Upper - Lower 4709 auto *UBExpr = TestIsLessOp ? UB : LB; 4710 auto *LBExpr = TestIsLessOp ? LB : UB; 4711 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 4712 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 4713 if (!Upper || !Lower) 4714 return nullptr; 4715 4716 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 4717 4718 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 4719 // BuildBinOp already emitted error, this one is to point user to upper 4720 // and lower bound, and to tell what is passed to 'operator-'. 4721 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) 4722 << Upper->getSourceRange() << Lower->getSourceRange(); 4723 return nullptr; 4724 } 4725 } 4726 4727 if (!Diff.isUsable()) 4728 return nullptr; 4729 4730 // Upper - Lower [- 1] 4731 if (TestIsStrictOp) 4732 Diff = SemaRef.BuildBinOp( 4733 S, DefaultLoc, BO_Sub, Diff.get(), 4734 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4735 if (!Diff.isUsable()) 4736 return nullptr; 4737 4738 // Upper - Lower [- 1] + Step 4739 auto NewStep = tryBuildCapture(SemaRef, Step, Captures); 4740 if (!NewStep.isUsable()) 4741 return nullptr; 4742 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 4743 if (!Diff.isUsable()) 4744 return nullptr; 4745 4746 // Parentheses (for dumping/debugging purposes only). 4747 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 4748 if (!Diff.isUsable()) 4749 return nullptr; 4750 4751 // (Upper - Lower [- 1] + Step) / Step 4752 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 4753 if (!Diff.isUsable()) 4754 return nullptr; 4755 4756 // OpenMP runtime requires 32-bit or 64-bit loop variables. 4757 QualType Type = Diff.get()->getType(); 4758 auto &C = SemaRef.Context; 4759 bool UseVarType = VarType->hasIntegerRepresentation() && 4760 C.getTypeSize(Type) > C.getTypeSize(VarType); 4761 if (!Type->isIntegerType() || UseVarType) { 4762 unsigned NewSize = 4763 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 4764 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 4765 : Type->hasSignedIntegerRepresentation(); 4766 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 4767 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 4768 Diff = SemaRef.PerformImplicitConversion( 4769 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 4770 if (!Diff.isUsable()) 4771 return nullptr; 4772 } 4773 } 4774 if (LimitedType) { 4775 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 4776 if (NewSize != C.getTypeSize(Type)) { 4777 if (NewSize < C.getTypeSize(Type)) { 4778 assert(NewSize == 64 && "incorrect loop var size"); 4779 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 4780 << InitSrcRange << ConditionSrcRange; 4781 } 4782 QualType NewType = C.getIntTypeForBitwidth( 4783 NewSize, Type->hasSignedIntegerRepresentation() || 4784 C.getTypeSize(Type) < NewSize); 4785 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 4786 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 4787 Sema::AA_Converting, true); 4788 if (!Diff.isUsable()) 4789 return nullptr; 4790 } 4791 } 4792 } 4793 4794 return Diff.get(); 4795 } 4796 4797 Expr *OpenMPIterationSpaceChecker::BuildPreCond( 4798 Scope *S, Expr *Cond, 4799 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 4800 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 4801 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 4802 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 4803 4804 auto NewLB = tryBuildCapture(SemaRef, LB, Captures); 4805 auto NewUB = tryBuildCapture(SemaRef, UB, Captures); 4806 if (!NewLB.isUsable() || !NewUB.isUsable()) 4807 return nullptr; 4808 4809 auto CondExpr = SemaRef.BuildBinOp( 4810 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) 4811 : (TestIsStrictOp ? BO_GT : BO_GE), 4812 NewLB.get(), NewUB.get()); 4813 if (CondExpr.isUsable()) { 4814 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 4815 SemaRef.Context.BoolTy)) 4816 CondExpr = SemaRef.PerformImplicitConversion( 4817 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 4818 /*AllowExplicit=*/true); 4819 } 4820 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 4821 // Otherwise use original loop conditon and evaluate it in runtime. 4822 return CondExpr.isUsable() ? CondExpr.get() : Cond; 4823 } 4824 4825 /// \brief Build reference expression to the counter be used for codegen. 4826 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar( 4827 llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const { 4828 auto *VD = dyn_cast<VarDecl>(LCDecl); 4829 if (!VD) { 4830 VD = SemaRef.IsOpenMPCapturedDecl(LCDecl); 4831 auto *Ref = buildDeclRefExpr( 4832 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 4833 DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl, /*FromParent=*/false); 4834 // If the loop control decl is explicitly marked as private, do not mark it 4835 // as captured again. 4836 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 4837 Captures.insert(std::make_pair(LCRef, Ref)); 4838 return Ref; 4839 } 4840 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(), 4841 DefaultLoc); 4842 } 4843 4844 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const { 4845 if (LCDecl && !LCDecl->isInvalidDecl()) { 4846 auto Type = LCDecl->getType().getNonReferenceType(); 4847 auto *PrivateVar = 4848 buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(), 4849 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr); 4850 if (PrivateVar->isInvalidDecl()) 4851 return nullptr; 4852 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 4853 } 4854 return nullptr; 4855 } 4856 4857 /// \brief Build instillation of the counter be used for codegen. 4858 Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; } 4859 4860 /// \brief Build step of the counter be used for codegen. 4861 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; } 4862 4863 /// \brief Iteration space of a single for loop. 4864 struct LoopIterationSpace final { 4865 /// \brief Condition of the loop. 4866 Expr *PreCond = nullptr; 4867 /// \brief This expression calculates the number of iterations in the loop. 4868 /// It is always possible to calculate it before starting the loop. 4869 Expr *NumIterations = nullptr; 4870 /// \brief The loop counter variable. 4871 Expr *CounterVar = nullptr; 4872 /// \brief Private loop counter variable. 4873 Expr *PrivateCounterVar = nullptr; 4874 /// \brief This is initializer for the initial value of #CounterVar. 4875 Expr *CounterInit = nullptr; 4876 /// \brief This is step for the #CounterVar used to generate its update: 4877 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 4878 Expr *CounterStep = nullptr; 4879 /// \brief Should step be subtracted? 4880 bool Subtract = false; 4881 /// \brief Source range of the loop init. 4882 SourceRange InitSrcRange; 4883 /// \brief Source range of the loop condition. 4884 SourceRange CondSrcRange; 4885 /// \brief Source range of the loop increment. 4886 SourceRange IncSrcRange; 4887 }; 4888 4889 } // namespace 4890 4891 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 4892 assert(getLangOpts().OpenMP && "OpenMP is not active."); 4893 assert(Init && "Expected loop in canonical form."); 4894 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 4895 if (AssociatedLoops > 0 && 4896 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 4897 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 4898 if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) { 4899 if (auto *D = ISC.GetLoopDecl()) { 4900 auto *VD = dyn_cast<VarDecl>(D); 4901 if (!VD) { 4902 if (auto *Private = IsOpenMPCapturedDecl(D)) 4903 VD = Private; 4904 else { 4905 auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(), 4906 /*WithInit=*/false); 4907 VD = cast<VarDecl>(Ref->getDecl()); 4908 } 4909 } 4910 DSAStack->addLoopControlVariable(D, VD); 4911 } 4912 } 4913 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 4914 } 4915 } 4916 4917 /// \brief Called on a for stmt to check and extract its iteration space 4918 /// for further processing (such as collapsing). 4919 static bool CheckOpenMPIterationSpace( 4920 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 4921 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 4922 Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, 4923 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 4924 LoopIterationSpace &ResultIterSpace, 4925 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 4926 // OpenMP [2.6, Canonical Loop Form] 4927 // for (init-expr; test-expr; incr-expr) structured-block 4928 auto *For = dyn_cast_or_null<ForStmt>(S); 4929 if (!For) { 4930 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for) 4931 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 4932 << getOpenMPDirectiveName(DKind) << NestedLoopCount 4933 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 4934 if (NestedLoopCount > 1) { 4935 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 4936 SemaRef.Diag(DSA.getConstructLoc(), 4937 diag::note_omp_collapse_ordered_expr) 4938 << 2 << CollapseLoopCountExpr->getSourceRange() 4939 << OrderedLoopCountExpr->getSourceRange(); 4940 else if (CollapseLoopCountExpr) 4941 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4942 diag::note_omp_collapse_ordered_expr) 4943 << 0 << CollapseLoopCountExpr->getSourceRange(); 4944 else 4945 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4946 diag::note_omp_collapse_ordered_expr) 4947 << 1 << OrderedLoopCountExpr->getSourceRange(); 4948 } 4949 return true; 4950 } 4951 assert(For->getBody()); 4952 4953 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 4954 4955 // Check init. 4956 auto Init = For->getInit(); 4957 if (ISC.CheckInit(Init)) 4958 return true; 4959 4960 bool HasErrors = false; 4961 4962 // Check loop variable's type. 4963 if (auto *LCDecl = ISC.GetLoopDecl()) { 4964 auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr(); 4965 4966 // OpenMP [2.6, Canonical Loop Form] 4967 // Var is one of the following: 4968 // A variable of signed or unsigned integer type. 4969 // For C++, a variable of a random access iterator type. 4970 // For C, a variable of a pointer type. 4971 auto VarType = LCDecl->getType().getNonReferenceType(); 4972 if (!VarType->isDependentType() && !VarType->isIntegerType() && 4973 !VarType->isPointerType() && 4974 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 4975 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type) 4976 << SemaRef.getLangOpts().CPlusPlus; 4977 HasErrors = true; 4978 } 4979 4980 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 4981 // a Construct 4982 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4983 // parallel for construct is (are) private. 4984 // The loop iteration variable in the associated for-loop of a simd 4985 // construct with just one associated for-loop is linear with a 4986 // constant-linear-step that is the increment of the associated for-loop. 4987 // Exclude loop var from the list of variables with implicitly defined data 4988 // sharing attributes. 4989 VarsWithImplicitDSA.erase(LCDecl); 4990 4991 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 4992 // in a Construct, C/C++]. 4993 // The loop iteration variable in the associated for-loop of a simd 4994 // construct with just one associated for-loop may be listed in a linear 4995 // clause with a constant-linear-step that is the increment of the 4996 // associated for-loop. 4997 // The loop iteration variable(s) in the associated for-loop(s) of a for or 4998 // parallel for construct may be listed in a private or lastprivate clause. 4999 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 5000 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 5001 // declared in the loop and it is predetermined as a private. 5002 auto PredeterminedCKind = 5003 isOpenMPSimdDirective(DKind) 5004 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 5005 : OMPC_private; 5006 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5007 DVar.CKind != PredeterminedCKind) || 5008 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 5009 isOpenMPDistributeDirective(DKind)) && 5010 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 5011 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 5012 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 5013 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa) 5014 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 5015 << getOpenMPClauseName(PredeterminedCKind); 5016 if (DVar.RefExpr == nullptr) 5017 DVar.CKind = PredeterminedCKind; 5018 ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 5019 HasErrors = true; 5020 } else if (LoopDeclRefExpr != nullptr) { 5021 // Make the loop iteration variable private (for worksharing constructs), 5022 // linear (for simd directives with the only one associated loop) or 5023 // lastprivate (for simd directives with several collapsed or ordered 5024 // loops). 5025 if (DVar.CKind == OMPC_unknown) 5026 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate, 5027 [](OpenMPDirectiveKind) -> bool { return true; }, 5028 /*FromParent=*/false); 5029 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 5030 } 5031 5032 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 5033 5034 // Check test-expr. 5035 HasErrors |= ISC.CheckCond(For->getCond()); 5036 5037 // Check incr-expr. 5038 HasErrors |= ISC.CheckInc(For->getInc()); 5039 } 5040 5041 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 5042 return HasErrors; 5043 5044 // Build the loop's iteration space representation. 5045 ResultIterSpace.PreCond = 5046 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures); 5047 ResultIterSpace.NumIterations = ISC.BuildNumIterations( 5048 DSA.getCurScope(), 5049 (isOpenMPWorksharingDirective(DKind) || 5050 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 5051 Captures); 5052 ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA); 5053 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); 5054 ResultIterSpace.CounterInit = ISC.BuildCounterInit(); 5055 ResultIterSpace.CounterStep = ISC.BuildCounterStep(); 5056 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); 5057 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange(); 5058 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange(); 5059 ResultIterSpace.Subtract = ISC.ShouldSubtractStep(); 5060 5061 HasErrors |= (ResultIterSpace.PreCond == nullptr || 5062 ResultIterSpace.NumIterations == nullptr || 5063 ResultIterSpace.CounterVar == nullptr || 5064 ResultIterSpace.PrivateCounterVar == nullptr || 5065 ResultIterSpace.CounterInit == nullptr || 5066 ResultIterSpace.CounterStep == nullptr); 5067 5068 return HasErrors; 5069 } 5070 5071 /// \brief Build 'VarRef = Start. 5072 static ExprResult 5073 BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 5074 ExprResult Start, 5075 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 5076 // Build 'VarRef = Start. 5077 auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 5078 if (!NewStart.isUsable()) 5079 return ExprError(); 5080 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 5081 VarRef.get()->getType())) { 5082 NewStart = SemaRef.PerformImplicitConversion( 5083 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 5084 /*AllowExplicit=*/true); 5085 if (!NewStart.isUsable()) 5086 return ExprError(); 5087 } 5088 5089 auto Init = 5090 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5091 return Init; 5092 } 5093 5094 /// \brief Build 'VarRef = Start + Iter * Step'. 5095 static ExprResult 5096 BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, 5097 ExprResult VarRef, ExprResult Start, ExprResult Iter, 5098 ExprResult Step, bool Subtract, 5099 llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) { 5100 // Add parentheses (for debugging purposes only). 5101 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 5102 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 5103 !Step.isUsable()) 5104 return ExprError(); 5105 5106 ExprResult NewStep = Step; 5107 if (Captures) 5108 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 5109 if (NewStep.isInvalid()) 5110 return ExprError(); 5111 ExprResult Update = 5112 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 5113 if (!Update.isUsable()) 5114 return ExprError(); 5115 5116 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 5117 // 'VarRef = Start (+|-) Iter * Step'. 5118 ExprResult NewStart = Start; 5119 if (Captures) 5120 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 5121 if (NewStart.isInvalid()) 5122 return ExprError(); 5123 5124 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 5125 ExprResult SavedUpdate = Update; 5126 ExprResult UpdateVal; 5127 if (VarRef.get()->getType()->isOverloadableType() || 5128 NewStart.get()->getType()->isOverloadableType() || 5129 Update.get()->getType()->isOverloadableType()) { 5130 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 5131 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 5132 Update = 5133 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 5134 if (Update.isUsable()) { 5135 UpdateVal = 5136 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 5137 VarRef.get(), SavedUpdate.get()); 5138 if (UpdateVal.isUsable()) { 5139 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 5140 UpdateVal.get()); 5141 } 5142 } 5143 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 5144 } 5145 5146 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 5147 if (!Update.isUsable() || !UpdateVal.isUsable()) { 5148 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 5149 NewStart.get(), SavedUpdate.get()); 5150 if (!Update.isUsable()) 5151 return ExprError(); 5152 5153 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 5154 VarRef.get()->getType())) { 5155 Update = SemaRef.PerformImplicitConversion( 5156 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 5157 if (!Update.isUsable()) 5158 return ExprError(); 5159 } 5160 5161 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 5162 } 5163 return Update; 5164 } 5165 5166 /// \brief Convert integer expression \a E to make it have at least \a Bits 5167 /// bits. 5168 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 5169 if (E == nullptr) 5170 return ExprError(); 5171 auto &C = SemaRef.Context; 5172 QualType OldType = E->getType(); 5173 unsigned HasBits = C.getTypeSize(OldType); 5174 if (HasBits >= Bits) 5175 return ExprResult(E); 5176 // OK to convert to signed, because new type has more bits than old. 5177 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 5178 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 5179 true); 5180 } 5181 5182 /// \brief Check if the given expression \a E is a constant integer that fits 5183 /// into \a Bits bits. 5184 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { 5185 if (E == nullptr) 5186 return false; 5187 llvm::APSInt Result; 5188 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 5189 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 5190 return false; 5191 } 5192 5193 /// Build preinits statement for the given declarations. 5194 static Stmt *buildPreInits(ASTContext &Context, 5195 SmallVectorImpl<Decl *> &PreInits) { 5196 if (!PreInits.empty()) { 5197 return new (Context) DeclStmt( 5198 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 5199 SourceLocation(), SourceLocation()); 5200 } 5201 return nullptr; 5202 } 5203 5204 /// Build preinits statement for the given declarations. 5205 static Stmt *buildPreInits(ASTContext &Context, 5206 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 5207 if (!Captures.empty()) { 5208 SmallVector<Decl *, 16> PreInits; 5209 for (auto &Pair : Captures) 5210 PreInits.push_back(Pair.second->getDecl()); 5211 return buildPreInits(Context, PreInits); 5212 } 5213 return nullptr; 5214 } 5215 5216 /// Build postupdate expression for the given list of postupdates expressions. 5217 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 5218 Expr *PostUpdate = nullptr; 5219 if (!PostUpdates.empty()) { 5220 for (auto *E : PostUpdates) { 5221 Expr *ConvE = S.BuildCStyleCastExpr( 5222 E->getExprLoc(), 5223 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 5224 E->getExprLoc(), E) 5225 .get(); 5226 PostUpdate = PostUpdate 5227 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 5228 PostUpdate, ConvE) 5229 .get() 5230 : ConvE; 5231 } 5232 } 5233 return PostUpdate; 5234 } 5235 5236 /// \brief Called on a for stmt to check itself and nested loops (if any). 5237 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 5238 /// number of collapsed loops otherwise. 5239 static unsigned 5240 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 5241 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 5242 DSAStackTy &DSA, 5243 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 5244 OMPLoopDirective::HelperExprs &Built) { 5245 unsigned NestedLoopCount = 1; 5246 if (CollapseLoopCountExpr) { 5247 // Found 'collapse' clause - calculate collapse number. 5248 llvm::APSInt Result; 5249 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 5250 NestedLoopCount = Result.getLimitedValue(); 5251 } 5252 if (OrderedLoopCountExpr) { 5253 // Found 'ordered' clause - calculate collapse number. 5254 llvm::APSInt Result; 5255 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 5256 if (Result.getLimitedValue() < NestedLoopCount) { 5257 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 5258 diag::err_omp_wrong_ordered_loop_count) 5259 << OrderedLoopCountExpr->getSourceRange(); 5260 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 5261 diag::note_collapse_loop_count) 5262 << CollapseLoopCountExpr->getSourceRange(); 5263 } 5264 NestedLoopCount = Result.getLimitedValue(); 5265 } 5266 } 5267 // This is helper routine for loop directives (e.g., 'for', 'simd', 5268 // 'for simd', etc.). 5269 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 5270 SmallVector<LoopIterationSpace, 4> IterSpaces; 5271 IterSpaces.resize(NestedLoopCount); 5272 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 5273 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 5274 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, 5275 NestedLoopCount, CollapseLoopCountExpr, 5276 OrderedLoopCountExpr, VarsWithImplicitDSA, 5277 IterSpaces[Cnt], Captures)) 5278 return 0; 5279 // Move on to the next nested for loop, or to the loop body. 5280 // OpenMP [2.8.1, simd construct, Restrictions] 5281 // All loops associated with the construct must be perfectly nested; that 5282 // is, there must be no intervening code nor any OpenMP directive between 5283 // any two loops. 5284 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 5285 } 5286 5287 Built.clear(/* size */ NestedLoopCount); 5288 5289 if (SemaRef.CurContext->isDependentContext()) 5290 return NestedLoopCount; 5291 5292 // An example of what is generated for the following code: 5293 // 5294 // #pragma omp simd collapse(2) ordered(2) 5295 // for (i = 0; i < NI; ++i) 5296 // for (k = 0; k < NK; ++k) 5297 // for (j = J0; j < NJ; j+=2) { 5298 // <loop body> 5299 // } 5300 // 5301 // We generate the code below. 5302 // Note: the loop body may be outlined in CodeGen. 5303 // Note: some counters may be C++ classes, operator- is used to find number of 5304 // iterations and operator+= to calculate counter value. 5305 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 5306 // or i64 is currently supported). 5307 // 5308 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 5309 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 5310 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 5311 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 5312 // // similar updates for vars in clauses (e.g. 'linear') 5313 // <loop body (using local i and j)> 5314 // } 5315 // i = NI; // assign final values of counters 5316 // j = NJ; 5317 // 5318 5319 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 5320 // the iteration counts of the collapsed for loops. 5321 // Precondition tests if there is at least one iteration (all conditions are 5322 // true). 5323 auto PreCond = ExprResult(IterSpaces[0].PreCond); 5324 auto N0 = IterSpaces[0].NumIterations; 5325 ExprResult LastIteration32 = WidenIterationCount( 5326 32 /* Bits */, SemaRef 5327 .PerformImplicitConversion( 5328 N0->IgnoreImpCasts(), N0->getType(), 5329 Sema::AA_Converting, /*AllowExplicit=*/true) 5330 .get(), 5331 SemaRef); 5332 ExprResult LastIteration64 = WidenIterationCount( 5333 64 /* Bits */, SemaRef 5334 .PerformImplicitConversion( 5335 N0->IgnoreImpCasts(), N0->getType(), 5336 Sema::AA_Converting, /*AllowExplicit=*/true) 5337 .get(), 5338 SemaRef); 5339 5340 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 5341 return NestedLoopCount; 5342 5343 auto &C = SemaRef.Context; 5344 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 5345 5346 Scope *CurScope = DSA.getCurScope(); 5347 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 5348 if (PreCond.isUsable()) { 5349 PreCond = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_LAnd, 5350 PreCond.get(), IterSpaces[Cnt].PreCond); 5351 } 5352 auto N = IterSpaces[Cnt].NumIterations; 5353 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 5354 if (LastIteration32.isUsable()) 5355 LastIteration32 = SemaRef.BuildBinOp( 5356 CurScope, SourceLocation(), BO_Mul, LastIteration32.get(), 5357 SemaRef 5358 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5359 Sema::AA_Converting, 5360 /*AllowExplicit=*/true) 5361 .get()); 5362 if (LastIteration64.isUsable()) 5363 LastIteration64 = SemaRef.BuildBinOp( 5364 CurScope, SourceLocation(), BO_Mul, LastIteration64.get(), 5365 SemaRef 5366 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 5367 Sema::AA_Converting, 5368 /*AllowExplicit=*/true) 5369 .get()); 5370 } 5371 5372 // Choose either the 32-bit or 64-bit version. 5373 ExprResult LastIteration = LastIteration64; 5374 if (LastIteration32.isUsable() && 5375 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 5376 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 5377 FitsInto( 5378 32 /* Bits */, 5379 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 5380 LastIteration64.get(), SemaRef))) 5381 LastIteration = LastIteration32; 5382 QualType VType = LastIteration.get()->getType(); 5383 QualType RealVType = VType; 5384 QualType StrideVType = VType; 5385 if (isOpenMPTaskLoopDirective(DKind)) { 5386 VType = 5387 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 5388 StrideVType = 5389 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 5390 } 5391 5392 if (!LastIteration.isUsable()) 5393 return 0; 5394 5395 // Save the number of iterations. 5396 ExprResult NumIterations = LastIteration; 5397 { 5398 LastIteration = SemaRef.BuildBinOp( 5399 CurScope, SourceLocation(), BO_Sub, LastIteration.get(), 5400 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5401 if (!LastIteration.isUsable()) 5402 return 0; 5403 } 5404 5405 // Calculate the last iteration number beforehand instead of doing this on 5406 // each iteration. Do not do this if the number of iterations may be kfold-ed. 5407 llvm::APSInt Result; 5408 bool IsConstant = 5409 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 5410 ExprResult CalcLastIteration; 5411 if (!IsConstant) { 5412 ExprResult SaveRef = 5413 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 5414 LastIteration = SaveRef; 5415 5416 // Prepare SaveRef + 1. 5417 NumIterations = SemaRef.BuildBinOp( 5418 CurScope, SourceLocation(), BO_Add, SaveRef.get(), 5419 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 5420 if (!NumIterations.isUsable()) 5421 return 0; 5422 } 5423 5424 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 5425 5426 // Build variables passed into runtime, necessary for worksharing directives. 5427 ExprResult LB, UB, IL, ST, EUB, PrevLB, PrevUB; 5428 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5429 isOpenMPDistributeDirective(DKind)) { 5430 // Lower bound variable, initialized with zero. 5431 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 5432 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 5433 SemaRef.AddInitializerToDecl( 5434 LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5435 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 5436 5437 // Upper bound variable, initialized with last iteration number. 5438 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 5439 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 5440 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 5441 /*DirectInit*/ false, 5442 /*TypeMayContainAuto*/ false); 5443 5444 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 5445 // This will be used to implement clause 'lastprivate'. 5446 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 5447 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 5448 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 5449 SemaRef.AddInitializerToDecl( 5450 ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 5451 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 5452 5453 // Stride variable returned by runtime (we initialize it to 1 by default). 5454 VarDecl *STDecl = 5455 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 5456 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 5457 SemaRef.AddInitializerToDecl( 5458 STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 5459 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 5460 5461 // Build expression: UB = min(UB, LastIteration) 5462 // It is necessary for CodeGen of directives with static scheduling. 5463 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 5464 UB.get(), LastIteration.get()); 5465 ExprResult CondOp = SemaRef.ActOnConditionalOp( 5466 InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get()); 5467 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 5468 CondOp.get()); 5469 EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); 5470 5471 // If we have a combined directive that combines 'distribute', 'for' or 5472 // 'simd' we need to be able to access the bounds of the schedule of the 5473 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 5474 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 5475 if (isOpenMPLoopBoundSharingDirective(DKind)) { 5476 auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 5477 5478 // We expect to have at least 2 more parameters than the 'parallel' 5479 // directive does - the lower and upper bounds of the previous schedule. 5480 assert(CD->getNumParams() >= 4 && 5481 "Unexpected number of parameters in loop combined directive"); 5482 5483 // Set the proper type for the bounds given what we learned from the 5484 // enclosed loops. 5485 auto *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 5486 auto *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 5487 5488 // Previous lower and upper bounds are obtained from the region 5489 // parameters. 5490 PrevLB = 5491 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 5492 PrevUB = 5493 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 5494 } 5495 } 5496 5497 // Build the iteration variable and its initialization before loop. 5498 ExprResult IV; 5499 ExprResult Init; 5500 { 5501 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 5502 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 5503 Expr *RHS = 5504 (isOpenMPWorksharingDirective(DKind) || 5505 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5506 ? LB.get() 5507 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 5508 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 5509 Init = SemaRef.ActOnFinishFullExpr(Init.get()); 5510 } 5511 5512 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. 5513 SourceLocation CondLoc; 5514 ExprResult Cond = 5515 (isOpenMPWorksharingDirective(DKind) || 5516 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 5517 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) 5518 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 5519 NumIterations.get()); 5520 5521 // Loop increment (IV = IV + 1) 5522 SourceLocation IncLoc; 5523 ExprResult Inc = 5524 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 5525 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 5526 if (!Inc.isUsable()) 5527 return 0; 5528 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 5529 Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); 5530 if (!Inc.isUsable()) 5531 return 0; 5532 5533 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 5534 // Used for directives with static scheduling. 5535 ExprResult NextLB, NextUB; 5536 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 5537 isOpenMPDistributeDirective(DKind)) { 5538 // LB + ST 5539 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 5540 if (!NextLB.isUsable()) 5541 return 0; 5542 // LB = LB + ST 5543 NextLB = 5544 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 5545 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); 5546 if (!NextLB.isUsable()) 5547 return 0; 5548 // UB + ST 5549 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 5550 if (!NextUB.isUsable()) 5551 return 0; 5552 // UB = UB + ST 5553 NextUB = 5554 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 5555 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); 5556 if (!NextUB.isUsable()) 5557 return 0; 5558 } 5559 5560 // Build updates and final values of the loop counters. 5561 bool HasErrors = false; 5562 Built.Counters.resize(NestedLoopCount); 5563 Built.Inits.resize(NestedLoopCount); 5564 Built.Updates.resize(NestedLoopCount); 5565 Built.Finals.resize(NestedLoopCount); 5566 SmallVector<Expr *, 4> LoopMultipliers; 5567 { 5568 ExprResult Div; 5569 // Go from inner nested loop to outer. 5570 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 5571 LoopIterationSpace &IS = IterSpaces[Cnt]; 5572 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 5573 // Build: Iter = (IV / Div) % IS.NumIters 5574 // where Div is product of previous iterations' IS.NumIters. 5575 ExprResult Iter; 5576 if (Div.isUsable()) { 5577 Iter = 5578 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); 5579 } else { 5580 Iter = IV; 5581 assert((Cnt == (int)NestedLoopCount - 1) && 5582 "unusable div expected on first iteration only"); 5583 } 5584 5585 if (Cnt != 0 && Iter.isUsable()) 5586 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), 5587 IS.NumIterations); 5588 if (!Iter.isUsable()) { 5589 HasErrors = true; 5590 break; 5591 } 5592 5593 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 5594 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 5595 auto *CounterVar = buildDeclRefExpr(SemaRef, VD, IS.CounterVar->getType(), 5596 IS.CounterVar->getExprLoc(), 5597 /*RefersToCapture=*/true); 5598 ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 5599 IS.CounterInit, Captures); 5600 if (!Init.isUsable()) { 5601 HasErrors = true; 5602 break; 5603 } 5604 ExprResult Update = BuildCounterUpdate( 5605 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 5606 IS.CounterStep, IS.Subtract, &Captures); 5607 if (!Update.isUsable()) { 5608 HasErrors = true; 5609 break; 5610 } 5611 5612 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 5613 ExprResult Final = BuildCounterUpdate( 5614 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 5615 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 5616 if (!Final.isUsable()) { 5617 HasErrors = true; 5618 break; 5619 } 5620 5621 // Build Div for the next iteration: Div <- Div * IS.NumIters 5622 if (Cnt != 0) { 5623 if (Div.isUnset()) 5624 Div = IS.NumIterations; 5625 else 5626 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), 5627 IS.NumIterations); 5628 5629 // Add parentheses (for debugging purposes only). 5630 if (Div.isUsable()) 5631 Div = tryBuildCapture(SemaRef, Div.get(), Captures); 5632 if (!Div.isUsable()) { 5633 HasErrors = true; 5634 break; 5635 } 5636 LoopMultipliers.push_back(Div.get()); 5637 } 5638 if (!Update.isUsable() || !Final.isUsable()) { 5639 HasErrors = true; 5640 break; 5641 } 5642 // Save results 5643 Built.Counters[Cnt] = IS.CounterVar; 5644 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 5645 Built.Inits[Cnt] = Init.get(); 5646 Built.Updates[Cnt] = Update.get(); 5647 Built.Finals[Cnt] = Final.get(); 5648 } 5649 } 5650 5651 if (HasErrors) 5652 return 0; 5653 5654 // Save results 5655 Built.IterationVarRef = IV.get(); 5656 Built.LastIteration = LastIteration.get(); 5657 Built.NumIterations = NumIterations.get(); 5658 Built.CalcLastIteration = 5659 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); 5660 Built.PreCond = PreCond.get(); 5661 Built.PreInits = buildPreInits(C, Captures); 5662 Built.Cond = Cond.get(); 5663 Built.Init = Init.get(); 5664 Built.Inc = Inc.get(); 5665 Built.LB = LB.get(); 5666 Built.UB = UB.get(); 5667 Built.IL = IL.get(); 5668 Built.ST = ST.get(); 5669 Built.EUB = EUB.get(); 5670 Built.NLB = NextLB.get(); 5671 Built.NUB = NextUB.get(); 5672 Built.PrevLB = PrevLB.get(); 5673 Built.PrevUB = PrevUB.get(); 5674 5675 Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get(); 5676 // Fill data for doacross depend clauses. 5677 for (auto Pair : DSA.getDoacrossDependClauses()) { 5678 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 5679 Pair.first->setCounterValue(CounterVal); 5680 else { 5681 if (NestedLoopCount != Pair.second.size() || 5682 NestedLoopCount != LoopMultipliers.size() + 1) { 5683 // Erroneous case - clause has some problems. 5684 Pair.first->setCounterValue(CounterVal); 5685 continue; 5686 } 5687 assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink); 5688 auto I = Pair.second.rbegin(); 5689 auto IS = IterSpaces.rbegin(); 5690 auto ILM = LoopMultipliers.rbegin(); 5691 Expr *UpCounterVal = CounterVal; 5692 Expr *Multiplier = nullptr; 5693 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 5694 if (I->first) { 5695 assert(IS->CounterStep); 5696 Expr *NormalizedOffset = 5697 SemaRef 5698 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div, 5699 I->first, IS->CounterStep) 5700 .get(); 5701 if (Multiplier) { 5702 NormalizedOffset = 5703 SemaRef 5704 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul, 5705 NormalizedOffset, Multiplier) 5706 .get(); 5707 } 5708 assert(I->second == OO_Plus || I->second == OO_Minus); 5709 BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : BO_Sub; 5710 UpCounterVal = SemaRef 5711 .BuildBinOp(CurScope, I->first->getExprLoc(), BOK, 5712 UpCounterVal, NormalizedOffset) 5713 .get(); 5714 } 5715 Multiplier = *ILM; 5716 ++I; 5717 ++IS; 5718 ++ILM; 5719 } 5720 Pair.first->setCounterValue(UpCounterVal); 5721 } 5722 } 5723 5724 return NestedLoopCount; 5725 } 5726 5727 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 5728 auto CollapseClauses = 5729 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 5730 if (CollapseClauses.begin() != CollapseClauses.end()) 5731 return (*CollapseClauses.begin())->getNumForLoops(); 5732 return nullptr; 5733 } 5734 5735 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 5736 auto OrderedClauses = 5737 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 5738 if (OrderedClauses.begin() != OrderedClauses.end()) 5739 return (*OrderedClauses.begin())->getNumForLoops(); 5740 return nullptr; 5741 } 5742 5743 static bool checkSimdlenSafelenSpecified(Sema &S, 5744 const ArrayRef<OMPClause *> Clauses) { 5745 OMPSafelenClause *Safelen = nullptr; 5746 OMPSimdlenClause *Simdlen = nullptr; 5747 5748 for (auto *Clause : Clauses) { 5749 if (Clause->getClauseKind() == OMPC_safelen) 5750 Safelen = cast<OMPSafelenClause>(Clause); 5751 else if (Clause->getClauseKind() == OMPC_simdlen) 5752 Simdlen = cast<OMPSimdlenClause>(Clause); 5753 if (Safelen && Simdlen) 5754 break; 5755 } 5756 5757 if (Simdlen && Safelen) { 5758 llvm::APSInt SimdlenRes, SafelenRes; 5759 auto SimdlenLength = Simdlen->getSimdlen(); 5760 auto SafelenLength = Safelen->getSafelen(); 5761 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 5762 SimdlenLength->isInstantiationDependent() || 5763 SimdlenLength->containsUnexpandedParameterPack()) 5764 return false; 5765 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 5766 SafelenLength->isInstantiationDependent() || 5767 SafelenLength->containsUnexpandedParameterPack()) 5768 return false; 5769 SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context); 5770 SafelenLength->EvaluateAsInt(SafelenRes, S.Context); 5771 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 5772 // If both simdlen and safelen clauses are specified, the value of the 5773 // simdlen parameter must be less than or equal to the value of the safelen 5774 // parameter. 5775 if (SimdlenRes > SafelenRes) { 5776 S.Diag(SimdlenLength->getExprLoc(), 5777 diag::err_omp_wrong_simdlen_safelen_values) 5778 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 5779 return true; 5780 } 5781 } 5782 return false; 5783 } 5784 5785 StmtResult Sema::ActOnOpenMPSimdDirective( 5786 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5787 SourceLocation EndLoc, 5788 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5789 if (!AStmt) 5790 return StmtError(); 5791 5792 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5793 OMPLoopDirective::HelperExprs B; 5794 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5795 // define the nested loops number. 5796 unsigned NestedLoopCount = CheckOpenMPLoop( 5797 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5798 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5799 if (NestedLoopCount == 0) 5800 return StmtError(); 5801 5802 assert((CurContext->isDependentContext() || B.builtAll()) && 5803 "omp simd loop exprs were not built"); 5804 5805 if (!CurContext->isDependentContext()) { 5806 // Finalize the clauses that need pre-built expressions for CodeGen. 5807 for (auto C : Clauses) { 5808 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5809 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5810 B.NumIterations, *this, CurScope, 5811 DSAStack)) 5812 return StmtError(); 5813 } 5814 } 5815 5816 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5817 return StmtError(); 5818 5819 getCurFunction()->setHasBranchProtectedScope(); 5820 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5821 Clauses, AStmt, B); 5822 } 5823 5824 StmtResult Sema::ActOnOpenMPForDirective( 5825 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5826 SourceLocation EndLoc, 5827 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5828 if (!AStmt) 5829 return StmtError(); 5830 5831 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5832 OMPLoopDirective::HelperExprs B; 5833 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5834 // define the nested loops number. 5835 unsigned NestedLoopCount = CheckOpenMPLoop( 5836 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 5837 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 5838 if (NestedLoopCount == 0) 5839 return StmtError(); 5840 5841 assert((CurContext->isDependentContext() || B.builtAll()) && 5842 "omp for loop exprs were not built"); 5843 5844 if (!CurContext->isDependentContext()) { 5845 // Finalize the clauses that need pre-built expressions for CodeGen. 5846 for (auto C : Clauses) { 5847 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5848 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5849 B.NumIterations, *this, CurScope, 5850 DSAStack)) 5851 return StmtError(); 5852 } 5853 } 5854 5855 getCurFunction()->setHasBranchProtectedScope(); 5856 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5857 Clauses, AStmt, B, DSAStack->isCancelRegion()); 5858 } 5859 5860 StmtResult Sema::ActOnOpenMPForSimdDirective( 5861 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5862 SourceLocation EndLoc, 5863 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5864 if (!AStmt) 5865 return StmtError(); 5866 5867 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5868 OMPLoopDirective::HelperExprs B; 5869 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5870 // define the nested loops number. 5871 unsigned NestedLoopCount = 5872 CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 5873 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5874 VarsWithImplicitDSA, B); 5875 if (NestedLoopCount == 0) 5876 return StmtError(); 5877 5878 assert((CurContext->isDependentContext() || B.builtAll()) && 5879 "omp for simd loop exprs were not built"); 5880 5881 if (!CurContext->isDependentContext()) { 5882 // Finalize the clauses that need pre-built expressions for CodeGen. 5883 for (auto C : Clauses) { 5884 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5885 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5886 B.NumIterations, *this, CurScope, 5887 DSAStack)) 5888 return StmtError(); 5889 } 5890 } 5891 5892 if (checkSimdlenSafelenSpecified(*this, Clauses)) 5893 return StmtError(); 5894 5895 getCurFunction()->setHasBranchProtectedScope(); 5896 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 5897 Clauses, AStmt, B); 5898 } 5899 5900 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 5901 Stmt *AStmt, 5902 SourceLocation StartLoc, 5903 SourceLocation EndLoc) { 5904 if (!AStmt) 5905 return StmtError(); 5906 5907 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5908 auto BaseStmt = AStmt; 5909 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5910 BaseStmt = CS->getCapturedStmt(); 5911 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5912 auto S = C->children(); 5913 if (S.begin() == S.end()) 5914 return StmtError(); 5915 // All associated statements must be '#pragma omp section' except for 5916 // the first one. 5917 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5918 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5919 if (SectionStmt) 5920 Diag(SectionStmt->getLocStart(), 5921 diag::err_omp_sections_substmt_not_section); 5922 return StmtError(); 5923 } 5924 cast<OMPSectionDirective>(SectionStmt) 5925 ->setHasCancel(DSAStack->isCancelRegion()); 5926 } 5927 } else { 5928 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt); 5929 return StmtError(); 5930 } 5931 5932 getCurFunction()->setHasBranchProtectedScope(); 5933 5934 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5935 DSAStack->isCancelRegion()); 5936 } 5937 5938 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 5939 SourceLocation StartLoc, 5940 SourceLocation EndLoc) { 5941 if (!AStmt) 5942 return StmtError(); 5943 5944 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5945 5946 getCurFunction()->setHasBranchProtectedScope(); 5947 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 5948 5949 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 5950 DSAStack->isCancelRegion()); 5951 } 5952 5953 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 5954 Stmt *AStmt, 5955 SourceLocation StartLoc, 5956 SourceLocation EndLoc) { 5957 if (!AStmt) 5958 return StmtError(); 5959 5960 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5961 5962 getCurFunction()->setHasBranchProtectedScope(); 5963 5964 // OpenMP [2.7.3, single Construct, Restrictions] 5965 // The copyprivate clause must not be used with the nowait clause. 5966 OMPClause *Nowait = nullptr; 5967 OMPClause *Copyprivate = nullptr; 5968 for (auto *Clause : Clauses) { 5969 if (Clause->getClauseKind() == OMPC_nowait) 5970 Nowait = Clause; 5971 else if (Clause->getClauseKind() == OMPC_copyprivate) 5972 Copyprivate = Clause; 5973 if (Copyprivate && Nowait) { 5974 Diag(Copyprivate->getLocStart(), 5975 diag::err_omp_single_copyprivate_with_nowait); 5976 Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here); 5977 return StmtError(); 5978 } 5979 } 5980 5981 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5982 } 5983 5984 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 5985 SourceLocation StartLoc, 5986 SourceLocation EndLoc) { 5987 if (!AStmt) 5988 return StmtError(); 5989 5990 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5991 5992 getCurFunction()->setHasBranchProtectedScope(); 5993 5994 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 5995 } 5996 5997 StmtResult Sema::ActOnOpenMPCriticalDirective( 5998 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 5999 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 6000 if (!AStmt) 6001 return StmtError(); 6002 6003 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6004 6005 bool ErrorFound = false; 6006 llvm::APSInt Hint; 6007 SourceLocation HintLoc; 6008 bool DependentHint = false; 6009 for (auto *C : Clauses) { 6010 if (C->getClauseKind() == OMPC_hint) { 6011 if (!DirName.getName()) { 6012 Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name); 6013 ErrorFound = true; 6014 } 6015 Expr *E = cast<OMPHintClause>(C)->getHint(); 6016 if (E->isTypeDependent() || E->isValueDependent() || 6017 E->isInstantiationDependent()) 6018 DependentHint = true; 6019 else { 6020 Hint = E->EvaluateKnownConstInt(Context); 6021 HintLoc = C->getLocStart(); 6022 } 6023 } 6024 } 6025 if (ErrorFound) 6026 return StmtError(); 6027 auto Pair = DSAStack->getCriticalWithHint(DirName); 6028 if (Pair.first && DirName.getName() && !DependentHint) { 6029 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 6030 Diag(StartLoc, diag::err_omp_critical_with_hint); 6031 if (HintLoc.isValid()) { 6032 Diag(HintLoc, diag::note_omp_critical_hint_here) 6033 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 6034 } else 6035 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 6036 if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 6037 Diag(C->getLocStart(), diag::note_omp_critical_hint_here) 6038 << 1 6039 << C->getHint()->EvaluateKnownConstInt(Context).toString( 6040 /*Radix=*/10, /*Signed=*/false); 6041 } else 6042 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1; 6043 } 6044 } 6045 6046 getCurFunction()->setHasBranchProtectedScope(); 6047 6048 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 6049 Clauses, AStmt); 6050 if (!Pair.first && DirName.getName() && !DependentHint) 6051 DSAStack->addCriticalWithHint(Dir, Hint); 6052 return Dir; 6053 } 6054 6055 StmtResult Sema::ActOnOpenMPParallelForDirective( 6056 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6057 SourceLocation EndLoc, 6058 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6059 if (!AStmt) 6060 return StmtError(); 6061 6062 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6063 // 1.2.2 OpenMP Language Terminology 6064 // Structured block - An executable statement with a single entry at the 6065 // top and a single exit at the bottom. 6066 // The point of exit cannot be a branch out of the structured block. 6067 // longjmp() and throw() must not violate the entry/exit criteria. 6068 CS->getCapturedDecl()->setNothrow(); 6069 6070 OMPLoopDirective::HelperExprs B; 6071 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6072 // define the nested loops number. 6073 unsigned NestedLoopCount = 6074 CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 6075 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6076 VarsWithImplicitDSA, B); 6077 if (NestedLoopCount == 0) 6078 return StmtError(); 6079 6080 assert((CurContext->isDependentContext() || B.builtAll()) && 6081 "omp parallel for loop exprs were not built"); 6082 6083 if (!CurContext->isDependentContext()) { 6084 // Finalize the clauses that need pre-built expressions for CodeGen. 6085 for (auto C : Clauses) { 6086 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6087 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6088 B.NumIterations, *this, CurScope, 6089 DSAStack)) 6090 return StmtError(); 6091 } 6092 } 6093 6094 getCurFunction()->setHasBranchProtectedScope(); 6095 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 6096 NestedLoopCount, Clauses, AStmt, B, 6097 DSAStack->isCancelRegion()); 6098 } 6099 6100 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 6101 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6102 SourceLocation EndLoc, 6103 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6104 if (!AStmt) 6105 return StmtError(); 6106 6107 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6108 // 1.2.2 OpenMP Language Terminology 6109 // Structured block - An executable statement with a single entry at the 6110 // top and a single exit at the bottom. 6111 // The point of exit cannot be a branch out of the structured block. 6112 // longjmp() and throw() must not violate the entry/exit criteria. 6113 CS->getCapturedDecl()->setNothrow(); 6114 6115 OMPLoopDirective::HelperExprs B; 6116 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6117 // define the nested loops number. 6118 unsigned NestedLoopCount = 6119 CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 6120 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6121 VarsWithImplicitDSA, B); 6122 if (NestedLoopCount == 0) 6123 return StmtError(); 6124 6125 if (!CurContext->isDependentContext()) { 6126 // Finalize the clauses that need pre-built expressions for CodeGen. 6127 for (auto C : Clauses) { 6128 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6129 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6130 B.NumIterations, *this, CurScope, 6131 DSAStack)) 6132 return StmtError(); 6133 } 6134 } 6135 6136 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6137 return StmtError(); 6138 6139 getCurFunction()->setHasBranchProtectedScope(); 6140 return OMPParallelForSimdDirective::Create( 6141 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6142 } 6143 6144 StmtResult 6145 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 6146 Stmt *AStmt, SourceLocation StartLoc, 6147 SourceLocation EndLoc) { 6148 if (!AStmt) 6149 return StmtError(); 6150 6151 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6152 auto BaseStmt = AStmt; 6153 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 6154 BaseStmt = CS->getCapturedStmt(); 6155 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 6156 auto S = C->children(); 6157 if (S.begin() == S.end()) 6158 return StmtError(); 6159 // All associated statements must be '#pragma omp section' except for 6160 // the first one. 6161 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 6162 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 6163 if (SectionStmt) 6164 Diag(SectionStmt->getLocStart(), 6165 diag::err_omp_parallel_sections_substmt_not_section); 6166 return StmtError(); 6167 } 6168 cast<OMPSectionDirective>(SectionStmt) 6169 ->setHasCancel(DSAStack->isCancelRegion()); 6170 } 6171 } else { 6172 Diag(AStmt->getLocStart(), 6173 diag::err_omp_parallel_sections_not_compound_stmt); 6174 return StmtError(); 6175 } 6176 6177 getCurFunction()->setHasBranchProtectedScope(); 6178 6179 return OMPParallelSectionsDirective::Create( 6180 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 6181 } 6182 6183 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 6184 Stmt *AStmt, SourceLocation StartLoc, 6185 SourceLocation EndLoc) { 6186 if (!AStmt) 6187 return StmtError(); 6188 6189 auto *CS = cast<CapturedStmt>(AStmt); 6190 // 1.2.2 OpenMP Language Terminology 6191 // Structured block - An executable statement with a single entry at the 6192 // top and a single exit at the bottom. 6193 // The point of exit cannot be a branch out of the structured block. 6194 // longjmp() and throw() must not violate the entry/exit criteria. 6195 CS->getCapturedDecl()->setNothrow(); 6196 6197 getCurFunction()->setHasBranchProtectedScope(); 6198 6199 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6200 DSAStack->isCancelRegion()); 6201 } 6202 6203 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 6204 SourceLocation EndLoc) { 6205 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 6206 } 6207 6208 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 6209 SourceLocation EndLoc) { 6210 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 6211 } 6212 6213 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 6214 SourceLocation EndLoc) { 6215 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 6216 } 6217 6218 StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt, 6219 SourceLocation StartLoc, 6220 SourceLocation EndLoc) { 6221 if (!AStmt) 6222 return StmtError(); 6223 6224 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6225 6226 getCurFunction()->setHasBranchProtectedScope(); 6227 6228 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, AStmt); 6229 } 6230 6231 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 6232 SourceLocation StartLoc, 6233 SourceLocation EndLoc) { 6234 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 6235 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 6236 } 6237 6238 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 6239 Stmt *AStmt, 6240 SourceLocation StartLoc, 6241 SourceLocation EndLoc) { 6242 OMPClause *DependFound = nullptr; 6243 OMPClause *DependSourceClause = nullptr; 6244 OMPClause *DependSinkClause = nullptr; 6245 bool ErrorFound = false; 6246 OMPThreadsClause *TC = nullptr; 6247 OMPSIMDClause *SC = nullptr; 6248 for (auto *C : Clauses) { 6249 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 6250 DependFound = C; 6251 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 6252 if (DependSourceClause) { 6253 Diag(C->getLocStart(), diag::err_omp_more_one_clause) 6254 << getOpenMPDirectiveName(OMPD_ordered) 6255 << getOpenMPClauseName(OMPC_depend) << 2; 6256 ErrorFound = true; 6257 } else 6258 DependSourceClause = C; 6259 if (DependSinkClause) { 6260 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 6261 << 0; 6262 ErrorFound = true; 6263 } 6264 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 6265 if (DependSourceClause) { 6266 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 6267 << 1; 6268 ErrorFound = true; 6269 } 6270 DependSinkClause = C; 6271 } 6272 } else if (C->getClauseKind() == OMPC_threads) 6273 TC = cast<OMPThreadsClause>(C); 6274 else if (C->getClauseKind() == OMPC_simd) 6275 SC = cast<OMPSIMDClause>(C); 6276 } 6277 if (!ErrorFound && !SC && 6278 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 6279 // OpenMP [2.8.1,simd Construct, Restrictions] 6280 // An ordered construct with the simd clause is the only OpenMP construct 6281 // that can appear in the simd region. 6282 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 6283 ErrorFound = true; 6284 } else if (DependFound && (TC || SC)) { 6285 Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd) 6286 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 6287 ErrorFound = true; 6288 } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) { 6289 Diag(DependFound->getLocStart(), 6290 diag::err_omp_ordered_directive_without_param); 6291 ErrorFound = true; 6292 } else if (TC || Clauses.empty()) { 6293 if (auto *Param = DSAStack->getParentOrderedRegionParam()) { 6294 SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc; 6295 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 6296 << (TC != nullptr); 6297 Diag(Param->getLocStart(), diag::note_omp_ordered_param); 6298 ErrorFound = true; 6299 } 6300 } 6301 if ((!AStmt && !DependFound) || ErrorFound) 6302 return StmtError(); 6303 6304 if (AStmt) { 6305 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6306 6307 getCurFunction()->setHasBranchProtectedScope(); 6308 } 6309 6310 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6311 } 6312 6313 namespace { 6314 /// \brief Helper class for checking expression in 'omp atomic [update]' 6315 /// construct. 6316 class OpenMPAtomicUpdateChecker { 6317 /// \brief Error results for atomic update expressions. 6318 enum ExprAnalysisErrorCode { 6319 /// \brief A statement is not an expression statement. 6320 NotAnExpression, 6321 /// \brief Expression is not builtin binary or unary operation. 6322 NotABinaryOrUnaryExpression, 6323 /// \brief Unary operation is not post-/pre- increment/decrement operation. 6324 NotAnUnaryIncDecExpression, 6325 /// \brief An expression is not of scalar type. 6326 NotAScalarType, 6327 /// \brief A binary operation is not an assignment operation. 6328 NotAnAssignmentOp, 6329 /// \brief RHS part of the binary operation is not a binary expression. 6330 NotABinaryExpression, 6331 /// \brief RHS part is not additive/multiplicative/shift/biwise binary 6332 /// expression. 6333 NotABinaryOperator, 6334 /// \brief RHS binary operation does not have reference to the updated LHS 6335 /// part. 6336 NotAnUpdateExpression, 6337 /// \brief No errors is found. 6338 NoError 6339 }; 6340 /// \brief Reference to Sema. 6341 Sema &SemaRef; 6342 /// \brief A location for note diagnostics (when error is found). 6343 SourceLocation NoteLoc; 6344 /// \brief 'x' lvalue part of the source atomic expression. 6345 Expr *X; 6346 /// \brief 'expr' rvalue part of the source atomic expression. 6347 Expr *E; 6348 /// \brief Helper expression of the form 6349 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 6350 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 6351 Expr *UpdateExpr; 6352 /// \brief Is 'x' a LHS in a RHS part of full update expression. It is 6353 /// important for non-associative operations. 6354 bool IsXLHSInRHSPart; 6355 BinaryOperatorKind Op; 6356 SourceLocation OpLoc; 6357 /// \brief true if the source expression is a postfix unary operation, false 6358 /// if it is a prefix unary operation. 6359 bool IsPostfixUpdate; 6360 6361 public: 6362 OpenMPAtomicUpdateChecker(Sema &SemaRef) 6363 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 6364 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 6365 /// \brief Check specified statement that it is suitable for 'atomic update' 6366 /// constructs and extract 'x', 'expr' and Operation from the original 6367 /// expression. If DiagId and NoteId == 0, then only check is performed 6368 /// without error notification. 6369 /// \param DiagId Diagnostic which should be emitted if error is found. 6370 /// \param NoteId Diagnostic note for the main error message. 6371 /// \return true if statement is not an update expression, false otherwise. 6372 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 6373 /// \brief Return the 'x' lvalue part of the source atomic expression. 6374 Expr *getX() const { return X; } 6375 /// \brief Return the 'expr' rvalue part of the source atomic expression. 6376 Expr *getExpr() const { return E; } 6377 /// \brief Return the update expression used in calculation of the updated 6378 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 6379 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 6380 Expr *getUpdateExpr() const { return UpdateExpr; } 6381 /// \brief Return true if 'x' is LHS in RHS part of full update expression, 6382 /// false otherwise. 6383 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 6384 6385 /// \brief true if the source expression is a postfix unary operation, false 6386 /// if it is a prefix unary operation. 6387 bool isPostfixUpdate() const { return IsPostfixUpdate; } 6388 6389 private: 6390 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 6391 unsigned NoteId = 0); 6392 }; 6393 } // namespace 6394 6395 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 6396 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 6397 ExprAnalysisErrorCode ErrorFound = NoError; 6398 SourceLocation ErrorLoc, NoteLoc; 6399 SourceRange ErrorRange, NoteRange; 6400 // Allowed constructs are: 6401 // x = x binop expr; 6402 // x = expr binop x; 6403 if (AtomicBinOp->getOpcode() == BO_Assign) { 6404 X = AtomicBinOp->getLHS(); 6405 if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 6406 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 6407 if (AtomicInnerBinOp->isMultiplicativeOp() || 6408 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 6409 AtomicInnerBinOp->isBitwiseOp()) { 6410 Op = AtomicInnerBinOp->getOpcode(); 6411 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 6412 auto *LHS = AtomicInnerBinOp->getLHS(); 6413 auto *RHS = AtomicInnerBinOp->getRHS(); 6414 llvm::FoldingSetNodeID XId, LHSId, RHSId; 6415 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 6416 /*Canonical=*/true); 6417 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 6418 /*Canonical=*/true); 6419 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 6420 /*Canonical=*/true); 6421 if (XId == LHSId) { 6422 E = RHS; 6423 IsXLHSInRHSPart = true; 6424 } else if (XId == RHSId) { 6425 E = LHS; 6426 IsXLHSInRHSPart = false; 6427 } else { 6428 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6429 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6430 NoteLoc = X->getExprLoc(); 6431 NoteRange = X->getSourceRange(); 6432 ErrorFound = NotAnUpdateExpression; 6433 } 6434 } else { 6435 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 6436 ErrorRange = AtomicInnerBinOp->getSourceRange(); 6437 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 6438 NoteRange = SourceRange(NoteLoc, NoteLoc); 6439 ErrorFound = NotABinaryOperator; 6440 } 6441 } else { 6442 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 6443 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 6444 ErrorFound = NotABinaryExpression; 6445 } 6446 } else { 6447 ErrorLoc = AtomicBinOp->getExprLoc(); 6448 ErrorRange = AtomicBinOp->getSourceRange(); 6449 NoteLoc = AtomicBinOp->getOperatorLoc(); 6450 NoteRange = SourceRange(NoteLoc, NoteLoc); 6451 ErrorFound = NotAnAssignmentOp; 6452 } 6453 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6454 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6455 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6456 return true; 6457 } else if (SemaRef.CurContext->isDependentContext()) 6458 E = X = UpdateExpr = nullptr; 6459 return ErrorFound != NoError; 6460 } 6461 6462 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 6463 unsigned NoteId) { 6464 ExprAnalysisErrorCode ErrorFound = NoError; 6465 SourceLocation ErrorLoc, NoteLoc; 6466 SourceRange ErrorRange, NoteRange; 6467 // Allowed constructs are: 6468 // x++; 6469 // x--; 6470 // ++x; 6471 // --x; 6472 // x binop= expr; 6473 // x = x binop expr; 6474 // x = expr binop x; 6475 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 6476 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 6477 if (AtomicBody->getType()->isScalarType() || 6478 AtomicBody->isInstantiationDependent()) { 6479 if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 6480 AtomicBody->IgnoreParenImpCasts())) { 6481 // Check for Compound Assignment Operation 6482 Op = BinaryOperator::getOpForCompoundAssignment( 6483 AtomicCompAssignOp->getOpcode()); 6484 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 6485 E = AtomicCompAssignOp->getRHS(); 6486 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 6487 IsXLHSInRHSPart = true; 6488 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 6489 AtomicBody->IgnoreParenImpCasts())) { 6490 // Check for Binary Operation 6491 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 6492 return true; 6493 } else if (auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 6494 AtomicBody->IgnoreParenImpCasts())) { 6495 // Check for Unary Operation 6496 if (AtomicUnaryOp->isIncrementDecrementOp()) { 6497 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 6498 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 6499 OpLoc = AtomicUnaryOp->getOperatorLoc(); 6500 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 6501 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 6502 IsXLHSInRHSPart = true; 6503 } else { 6504 ErrorFound = NotAnUnaryIncDecExpression; 6505 ErrorLoc = AtomicUnaryOp->getExprLoc(); 6506 ErrorRange = AtomicUnaryOp->getSourceRange(); 6507 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 6508 NoteRange = SourceRange(NoteLoc, NoteLoc); 6509 } 6510 } else if (!AtomicBody->isInstantiationDependent()) { 6511 ErrorFound = NotABinaryOrUnaryExpression; 6512 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 6513 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 6514 } 6515 } else { 6516 ErrorFound = NotAScalarType; 6517 NoteLoc = ErrorLoc = AtomicBody->getLocStart(); 6518 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6519 } 6520 } else { 6521 ErrorFound = NotAnExpression; 6522 NoteLoc = ErrorLoc = S->getLocStart(); 6523 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6524 } 6525 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 6526 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 6527 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 6528 return true; 6529 } else if (SemaRef.CurContext->isDependentContext()) 6530 E = X = UpdateExpr = nullptr; 6531 if (ErrorFound == NoError && E && X) { 6532 // Build an update expression of form 'OpaqueValueExpr(x) binop 6533 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 6534 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 6535 auto *OVEX = new (SemaRef.getASTContext()) 6536 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 6537 auto *OVEExpr = new (SemaRef.getASTContext()) 6538 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 6539 auto Update = 6540 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 6541 IsXLHSInRHSPart ? OVEExpr : OVEX); 6542 if (Update.isInvalid()) 6543 return true; 6544 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 6545 Sema::AA_Casting); 6546 if (Update.isInvalid()) 6547 return true; 6548 UpdateExpr = Update.get(); 6549 } 6550 return ErrorFound != NoError; 6551 } 6552 6553 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 6554 Stmt *AStmt, 6555 SourceLocation StartLoc, 6556 SourceLocation EndLoc) { 6557 if (!AStmt) 6558 return StmtError(); 6559 6560 auto *CS = cast<CapturedStmt>(AStmt); 6561 // 1.2.2 OpenMP Language Terminology 6562 // Structured block - An executable statement with a single entry at the 6563 // top and a single exit at the bottom. 6564 // The point of exit cannot be a branch out of the structured block. 6565 // longjmp() and throw() must not violate the entry/exit criteria. 6566 OpenMPClauseKind AtomicKind = OMPC_unknown; 6567 SourceLocation AtomicKindLoc; 6568 for (auto *C : Clauses) { 6569 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 6570 C->getClauseKind() == OMPC_update || 6571 C->getClauseKind() == OMPC_capture) { 6572 if (AtomicKind != OMPC_unknown) { 6573 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) 6574 << SourceRange(C->getLocStart(), C->getLocEnd()); 6575 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 6576 << getOpenMPClauseName(AtomicKind); 6577 } else { 6578 AtomicKind = C->getClauseKind(); 6579 AtomicKindLoc = C->getLocStart(); 6580 } 6581 } 6582 } 6583 6584 auto Body = CS->getCapturedStmt(); 6585 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 6586 Body = EWC->getSubExpr(); 6587 6588 Expr *X = nullptr; 6589 Expr *V = nullptr; 6590 Expr *E = nullptr; 6591 Expr *UE = nullptr; 6592 bool IsXLHSInRHSPart = false; 6593 bool IsPostfixUpdate = false; 6594 // OpenMP [2.12.6, atomic Construct] 6595 // In the next expressions: 6596 // * x and v (as applicable) are both l-value expressions with scalar type. 6597 // * During the execution of an atomic region, multiple syntactic 6598 // occurrences of x must designate the same storage location. 6599 // * Neither of v and expr (as applicable) may access the storage location 6600 // designated by x. 6601 // * Neither of x and expr (as applicable) may access the storage location 6602 // designated by v. 6603 // * expr is an expression with scalar type. 6604 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 6605 // * binop, binop=, ++, and -- are not overloaded operators. 6606 // * The expression x binop expr must be numerically equivalent to x binop 6607 // (expr). This requirement is satisfied if the operators in expr have 6608 // precedence greater than binop, or by using parentheses around expr or 6609 // subexpressions of expr. 6610 // * The expression expr binop x must be numerically equivalent to (expr) 6611 // binop x. This requirement is satisfied if the operators in expr have 6612 // precedence equal to or greater than binop, or by using parentheses around 6613 // expr or subexpressions of expr. 6614 // * For forms that allow multiple occurrences of x, the number of times 6615 // that x is evaluated is unspecified. 6616 if (AtomicKind == OMPC_read) { 6617 enum { 6618 NotAnExpression, 6619 NotAnAssignmentOp, 6620 NotAScalarType, 6621 NotAnLValue, 6622 NoError 6623 } ErrorFound = NoError; 6624 SourceLocation ErrorLoc, NoteLoc; 6625 SourceRange ErrorRange, NoteRange; 6626 // If clause is read: 6627 // v = x; 6628 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 6629 auto *AtomicBinOp = 6630 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6631 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6632 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6633 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 6634 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6635 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 6636 if (!X->isLValue() || !V->isLValue()) { 6637 auto NotLValueExpr = X->isLValue() ? V : X; 6638 ErrorFound = NotAnLValue; 6639 ErrorLoc = AtomicBinOp->getExprLoc(); 6640 ErrorRange = AtomicBinOp->getSourceRange(); 6641 NoteLoc = NotLValueExpr->getExprLoc(); 6642 NoteRange = NotLValueExpr->getSourceRange(); 6643 } 6644 } else if (!X->isInstantiationDependent() || 6645 !V->isInstantiationDependent()) { 6646 auto NotScalarExpr = 6647 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6648 ? V 6649 : X; 6650 ErrorFound = NotAScalarType; 6651 ErrorLoc = AtomicBinOp->getExprLoc(); 6652 ErrorRange = AtomicBinOp->getSourceRange(); 6653 NoteLoc = NotScalarExpr->getExprLoc(); 6654 NoteRange = NotScalarExpr->getSourceRange(); 6655 } 6656 } else if (!AtomicBody->isInstantiationDependent()) { 6657 ErrorFound = NotAnAssignmentOp; 6658 ErrorLoc = AtomicBody->getExprLoc(); 6659 ErrorRange = AtomicBody->getSourceRange(); 6660 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6661 : AtomicBody->getExprLoc(); 6662 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6663 : AtomicBody->getSourceRange(); 6664 } 6665 } else { 6666 ErrorFound = NotAnExpression; 6667 NoteLoc = ErrorLoc = Body->getLocStart(); 6668 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6669 } 6670 if (ErrorFound != NoError) { 6671 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 6672 << ErrorRange; 6673 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 6674 << NoteRange; 6675 return StmtError(); 6676 } else if (CurContext->isDependentContext()) 6677 V = X = nullptr; 6678 } else if (AtomicKind == OMPC_write) { 6679 enum { 6680 NotAnExpression, 6681 NotAnAssignmentOp, 6682 NotAScalarType, 6683 NotAnLValue, 6684 NoError 6685 } ErrorFound = NoError; 6686 SourceLocation ErrorLoc, NoteLoc; 6687 SourceRange ErrorRange, NoteRange; 6688 // If clause is write: 6689 // x = expr; 6690 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 6691 auto *AtomicBinOp = 6692 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6693 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6694 X = AtomicBinOp->getLHS(); 6695 E = AtomicBinOp->getRHS(); 6696 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 6697 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 6698 if (!X->isLValue()) { 6699 ErrorFound = NotAnLValue; 6700 ErrorLoc = AtomicBinOp->getExprLoc(); 6701 ErrorRange = AtomicBinOp->getSourceRange(); 6702 NoteLoc = X->getExprLoc(); 6703 NoteRange = X->getSourceRange(); 6704 } 6705 } else if (!X->isInstantiationDependent() || 6706 !E->isInstantiationDependent()) { 6707 auto NotScalarExpr = 6708 (X->isInstantiationDependent() || X->getType()->isScalarType()) 6709 ? E 6710 : X; 6711 ErrorFound = NotAScalarType; 6712 ErrorLoc = AtomicBinOp->getExprLoc(); 6713 ErrorRange = AtomicBinOp->getSourceRange(); 6714 NoteLoc = NotScalarExpr->getExprLoc(); 6715 NoteRange = NotScalarExpr->getSourceRange(); 6716 } 6717 } else if (!AtomicBody->isInstantiationDependent()) { 6718 ErrorFound = NotAnAssignmentOp; 6719 ErrorLoc = AtomicBody->getExprLoc(); 6720 ErrorRange = AtomicBody->getSourceRange(); 6721 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6722 : AtomicBody->getExprLoc(); 6723 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6724 : AtomicBody->getSourceRange(); 6725 } 6726 } else { 6727 ErrorFound = NotAnExpression; 6728 NoteLoc = ErrorLoc = Body->getLocStart(); 6729 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 6730 } 6731 if (ErrorFound != NoError) { 6732 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 6733 << ErrorRange; 6734 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 6735 << NoteRange; 6736 return StmtError(); 6737 } else if (CurContext->isDependentContext()) 6738 E = X = nullptr; 6739 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 6740 // If clause is update: 6741 // x++; 6742 // x--; 6743 // ++x; 6744 // --x; 6745 // x binop= expr; 6746 // x = x binop expr; 6747 // x = expr binop x; 6748 OpenMPAtomicUpdateChecker Checker(*this); 6749 if (Checker.checkStatement( 6750 Body, (AtomicKind == OMPC_update) 6751 ? diag::err_omp_atomic_update_not_expression_statement 6752 : diag::err_omp_atomic_not_expression_statement, 6753 diag::note_omp_atomic_update)) 6754 return StmtError(); 6755 if (!CurContext->isDependentContext()) { 6756 E = Checker.getExpr(); 6757 X = Checker.getX(); 6758 UE = Checker.getUpdateExpr(); 6759 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6760 } 6761 } else if (AtomicKind == OMPC_capture) { 6762 enum { 6763 NotAnAssignmentOp, 6764 NotACompoundStatement, 6765 NotTwoSubstatements, 6766 NotASpecificExpression, 6767 NoError 6768 } ErrorFound = NoError; 6769 SourceLocation ErrorLoc, NoteLoc; 6770 SourceRange ErrorRange, NoteRange; 6771 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 6772 // If clause is a capture: 6773 // v = x++; 6774 // v = x--; 6775 // v = ++x; 6776 // v = --x; 6777 // v = x binop= expr; 6778 // v = x = x binop expr; 6779 // v = x = expr binop x; 6780 auto *AtomicBinOp = 6781 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 6782 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 6783 V = AtomicBinOp->getLHS(); 6784 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 6785 OpenMPAtomicUpdateChecker Checker(*this); 6786 if (Checker.checkStatement( 6787 Body, diag::err_omp_atomic_capture_not_expression_statement, 6788 diag::note_omp_atomic_update)) 6789 return StmtError(); 6790 E = Checker.getExpr(); 6791 X = Checker.getX(); 6792 UE = Checker.getUpdateExpr(); 6793 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6794 IsPostfixUpdate = Checker.isPostfixUpdate(); 6795 } else if (!AtomicBody->isInstantiationDependent()) { 6796 ErrorLoc = AtomicBody->getExprLoc(); 6797 ErrorRange = AtomicBody->getSourceRange(); 6798 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 6799 : AtomicBody->getExprLoc(); 6800 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 6801 : AtomicBody->getSourceRange(); 6802 ErrorFound = NotAnAssignmentOp; 6803 } 6804 if (ErrorFound != NoError) { 6805 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 6806 << ErrorRange; 6807 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6808 return StmtError(); 6809 } else if (CurContext->isDependentContext()) { 6810 UE = V = E = X = nullptr; 6811 } 6812 } else { 6813 // If clause is a capture: 6814 // { v = x; x = expr; } 6815 // { v = x; x++; } 6816 // { v = x; x--; } 6817 // { v = x; ++x; } 6818 // { v = x; --x; } 6819 // { v = x; x binop= expr; } 6820 // { v = x; x = x binop expr; } 6821 // { v = x; x = expr binop x; } 6822 // { x++; v = x; } 6823 // { x--; v = x; } 6824 // { ++x; v = x; } 6825 // { --x; v = x; } 6826 // { x binop= expr; v = x; } 6827 // { x = x binop expr; v = x; } 6828 // { x = expr binop x; v = x; } 6829 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 6830 // Check that this is { expr1; expr2; } 6831 if (CS->size() == 2) { 6832 auto *First = CS->body_front(); 6833 auto *Second = CS->body_back(); 6834 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 6835 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 6836 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 6837 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 6838 // Need to find what subexpression is 'v' and what is 'x'. 6839 OpenMPAtomicUpdateChecker Checker(*this); 6840 bool IsUpdateExprFound = !Checker.checkStatement(Second); 6841 BinaryOperator *BinOp = nullptr; 6842 if (IsUpdateExprFound) { 6843 BinOp = dyn_cast<BinaryOperator>(First); 6844 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6845 } 6846 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6847 // { v = x; x++; } 6848 // { v = x; x--; } 6849 // { v = x; ++x; } 6850 // { v = x; --x; } 6851 // { v = x; x binop= expr; } 6852 // { v = x; x = x binop expr; } 6853 // { v = x; x = expr binop x; } 6854 // Check that the first expression has form v = x. 6855 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6856 llvm::FoldingSetNodeID XId, PossibleXId; 6857 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6858 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6859 IsUpdateExprFound = XId == PossibleXId; 6860 if (IsUpdateExprFound) { 6861 V = BinOp->getLHS(); 6862 X = Checker.getX(); 6863 E = Checker.getExpr(); 6864 UE = Checker.getUpdateExpr(); 6865 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6866 IsPostfixUpdate = true; 6867 } 6868 } 6869 if (!IsUpdateExprFound) { 6870 IsUpdateExprFound = !Checker.checkStatement(First); 6871 BinOp = nullptr; 6872 if (IsUpdateExprFound) { 6873 BinOp = dyn_cast<BinaryOperator>(Second); 6874 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 6875 } 6876 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 6877 // { x++; v = x; } 6878 // { x--; v = x; } 6879 // { ++x; v = x; } 6880 // { --x; v = x; } 6881 // { x binop= expr; v = x; } 6882 // { x = x binop expr; v = x; } 6883 // { x = expr binop x; v = x; } 6884 // Check that the second expression has form v = x. 6885 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 6886 llvm::FoldingSetNodeID XId, PossibleXId; 6887 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 6888 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 6889 IsUpdateExprFound = XId == PossibleXId; 6890 if (IsUpdateExprFound) { 6891 V = BinOp->getLHS(); 6892 X = Checker.getX(); 6893 E = Checker.getExpr(); 6894 UE = Checker.getUpdateExpr(); 6895 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 6896 IsPostfixUpdate = false; 6897 } 6898 } 6899 } 6900 if (!IsUpdateExprFound) { 6901 // { v = x; x = expr; } 6902 auto *FirstExpr = dyn_cast<Expr>(First); 6903 auto *SecondExpr = dyn_cast<Expr>(Second); 6904 if (!FirstExpr || !SecondExpr || 6905 !(FirstExpr->isInstantiationDependent() || 6906 SecondExpr->isInstantiationDependent())) { 6907 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 6908 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 6909 ErrorFound = NotAnAssignmentOp; 6910 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 6911 : First->getLocStart(); 6912 NoteRange = ErrorRange = FirstBinOp 6913 ? FirstBinOp->getSourceRange() 6914 : SourceRange(ErrorLoc, ErrorLoc); 6915 } else { 6916 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 6917 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 6918 ErrorFound = NotAnAssignmentOp; 6919 NoteLoc = ErrorLoc = SecondBinOp 6920 ? SecondBinOp->getOperatorLoc() 6921 : Second->getLocStart(); 6922 NoteRange = ErrorRange = 6923 SecondBinOp ? SecondBinOp->getSourceRange() 6924 : SourceRange(ErrorLoc, ErrorLoc); 6925 } else { 6926 auto *PossibleXRHSInFirst = 6927 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 6928 auto *PossibleXLHSInSecond = 6929 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 6930 llvm::FoldingSetNodeID X1Id, X2Id; 6931 PossibleXRHSInFirst->Profile(X1Id, Context, 6932 /*Canonical=*/true); 6933 PossibleXLHSInSecond->Profile(X2Id, Context, 6934 /*Canonical=*/true); 6935 IsUpdateExprFound = X1Id == X2Id; 6936 if (IsUpdateExprFound) { 6937 V = FirstBinOp->getLHS(); 6938 X = SecondBinOp->getLHS(); 6939 E = SecondBinOp->getRHS(); 6940 UE = nullptr; 6941 IsXLHSInRHSPart = false; 6942 IsPostfixUpdate = true; 6943 } else { 6944 ErrorFound = NotASpecificExpression; 6945 ErrorLoc = FirstBinOp->getExprLoc(); 6946 ErrorRange = FirstBinOp->getSourceRange(); 6947 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 6948 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 6949 } 6950 } 6951 } 6952 } 6953 } 6954 } else { 6955 NoteLoc = ErrorLoc = Body->getLocStart(); 6956 NoteRange = ErrorRange = 6957 SourceRange(Body->getLocStart(), Body->getLocStart()); 6958 ErrorFound = NotTwoSubstatements; 6959 } 6960 } else { 6961 NoteLoc = ErrorLoc = Body->getLocStart(); 6962 NoteRange = ErrorRange = 6963 SourceRange(Body->getLocStart(), Body->getLocStart()); 6964 ErrorFound = NotACompoundStatement; 6965 } 6966 if (ErrorFound != NoError) { 6967 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 6968 << ErrorRange; 6969 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 6970 return StmtError(); 6971 } else if (CurContext->isDependentContext()) { 6972 UE = V = E = X = nullptr; 6973 } 6974 } 6975 } 6976 6977 getCurFunction()->setHasBranchProtectedScope(); 6978 6979 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 6980 X, V, E, UE, IsXLHSInRHSPart, 6981 IsPostfixUpdate); 6982 } 6983 6984 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 6985 Stmt *AStmt, 6986 SourceLocation StartLoc, 6987 SourceLocation EndLoc) { 6988 if (!AStmt) 6989 return StmtError(); 6990 6991 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6992 // 1.2.2 OpenMP Language Terminology 6993 // Structured block - An executable statement with a single entry at the 6994 // top and a single exit at the bottom. 6995 // The point of exit cannot be a branch out of the structured block. 6996 // longjmp() and throw() must not violate the entry/exit criteria. 6997 CS->getCapturedDecl()->setNothrow(); 6998 6999 // OpenMP [2.16, Nesting of Regions] 7000 // If specified, a teams construct must be contained within a target 7001 // construct. That target construct must contain no statements or directives 7002 // outside of the teams construct. 7003 if (DSAStack->hasInnerTeamsRegion()) { 7004 auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true); 7005 bool OMPTeamsFound = true; 7006 if (auto *CS = dyn_cast<CompoundStmt>(S)) { 7007 auto I = CS->body_begin(); 7008 while (I != CS->body_end()) { 7009 auto *OED = dyn_cast<OMPExecutableDirective>(*I); 7010 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { 7011 OMPTeamsFound = false; 7012 break; 7013 } 7014 ++I; 7015 } 7016 assert(I != CS->body_end() && "Not found statement"); 7017 S = *I; 7018 } else { 7019 auto *OED = dyn_cast<OMPExecutableDirective>(S); 7020 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 7021 } 7022 if (!OMPTeamsFound) { 7023 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 7024 Diag(DSAStack->getInnerTeamsRegionLoc(), 7025 diag::note_omp_nested_teams_construct_here); 7026 Diag(S->getLocStart(), diag::note_omp_nested_statement_here) 7027 << isa<OMPExecutableDirective>(S); 7028 return StmtError(); 7029 } 7030 } 7031 7032 getCurFunction()->setHasBranchProtectedScope(); 7033 7034 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7035 } 7036 7037 StmtResult 7038 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 7039 Stmt *AStmt, SourceLocation StartLoc, 7040 SourceLocation EndLoc) { 7041 if (!AStmt) 7042 return StmtError(); 7043 7044 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7045 // 1.2.2 OpenMP Language Terminology 7046 // Structured block - An executable statement with a single entry at the 7047 // top and a single exit at the bottom. 7048 // The point of exit cannot be a branch out of the structured block. 7049 // longjmp() and throw() must not violate the entry/exit criteria. 7050 CS->getCapturedDecl()->setNothrow(); 7051 7052 getCurFunction()->setHasBranchProtectedScope(); 7053 7054 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7055 AStmt); 7056 } 7057 7058 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 7059 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7060 SourceLocation EndLoc, 7061 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7062 if (!AStmt) 7063 return StmtError(); 7064 7065 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7066 // 1.2.2 OpenMP Language Terminology 7067 // Structured block - An executable statement with a single entry at the 7068 // top and a single exit at the bottom. 7069 // The point of exit cannot be a branch out of the structured block. 7070 // longjmp() and throw() must not violate the entry/exit criteria. 7071 CS->getCapturedDecl()->setNothrow(); 7072 7073 OMPLoopDirective::HelperExprs B; 7074 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7075 // define the nested loops number. 7076 unsigned NestedLoopCount = 7077 CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 7078 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7079 VarsWithImplicitDSA, B); 7080 if (NestedLoopCount == 0) 7081 return StmtError(); 7082 7083 assert((CurContext->isDependentContext() || B.builtAll()) && 7084 "omp target parallel for loop exprs were not built"); 7085 7086 if (!CurContext->isDependentContext()) { 7087 // Finalize the clauses that need pre-built expressions for CodeGen. 7088 for (auto C : Clauses) { 7089 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7090 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7091 B.NumIterations, *this, CurScope, 7092 DSAStack)) 7093 return StmtError(); 7094 } 7095 } 7096 7097 getCurFunction()->setHasBranchProtectedScope(); 7098 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 7099 NestedLoopCount, Clauses, AStmt, 7100 B, DSAStack->isCancelRegion()); 7101 } 7102 7103 /// \brief Check for existence of a map clause in the list of clauses. 7104 static bool HasMapClause(ArrayRef<OMPClause *> Clauses) { 7105 for (ArrayRef<OMPClause *>::iterator I = Clauses.begin(), E = Clauses.end(); 7106 I != E; ++I) { 7107 if (*I != nullptr && (*I)->getClauseKind() == OMPC_map) { 7108 return true; 7109 } 7110 } 7111 7112 return false; 7113 } 7114 7115 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 7116 Stmt *AStmt, 7117 SourceLocation StartLoc, 7118 SourceLocation EndLoc) { 7119 if (!AStmt) 7120 return StmtError(); 7121 7122 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7123 7124 // OpenMP [2.10.1, Restrictions, p. 97] 7125 // At least one map clause must appear on the directive. 7126 if (!HasMapClause(Clauses)) { 7127 Diag(StartLoc, diag::err_omp_no_map_for_directive) 7128 << getOpenMPDirectiveName(OMPD_target_data); 7129 return StmtError(); 7130 } 7131 7132 getCurFunction()->setHasBranchProtectedScope(); 7133 7134 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 7135 AStmt); 7136 } 7137 7138 StmtResult 7139 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 7140 SourceLocation StartLoc, 7141 SourceLocation EndLoc) { 7142 // OpenMP [2.10.2, Restrictions, p. 99] 7143 // At least one map clause must appear on the directive. 7144 if (!HasMapClause(Clauses)) { 7145 Diag(StartLoc, diag::err_omp_no_map_for_directive) 7146 << getOpenMPDirectiveName(OMPD_target_enter_data); 7147 return StmtError(); 7148 } 7149 7150 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, 7151 Clauses); 7152 } 7153 7154 StmtResult 7155 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 7156 SourceLocation StartLoc, 7157 SourceLocation EndLoc) { 7158 // OpenMP [2.10.3, Restrictions, p. 102] 7159 // At least one map clause must appear on the directive. 7160 if (!HasMapClause(Clauses)) { 7161 Diag(StartLoc, diag::err_omp_no_map_for_directive) 7162 << getOpenMPDirectiveName(OMPD_target_exit_data); 7163 return StmtError(); 7164 } 7165 7166 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses); 7167 } 7168 7169 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 7170 SourceLocation StartLoc, 7171 SourceLocation EndLoc) { 7172 bool seenMotionClause = false; 7173 for (auto *C : Clauses) { 7174 if (C->getClauseKind() == OMPC_to || C->getClauseKind() == OMPC_from) 7175 seenMotionClause = true; 7176 } 7177 if (!seenMotionClause) { 7178 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 7179 return StmtError(); 7180 } 7181 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses); 7182 } 7183 7184 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 7185 Stmt *AStmt, SourceLocation StartLoc, 7186 SourceLocation EndLoc) { 7187 if (!AStmt) 7188 return StmtError(); 7189 7190 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7191 // 1.2.2 OpenMP Language Terminology 7192 // Structured block - An executable statement with a single entry at the 7193 // top and a single exit at the bottom. 7194 // The point of exit cannot be a branch out of the structured block. 7195 // longjmp() and throw() must not violate the entry/exit criteria. 7196 CS->getCapturedDecl()->setNothrow(); 7197 7198 getCurFunction()->setHasBranchProtectedScope(); 7199 7200 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 7201 } 7202 7203 StmtResult 7204 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 7205 SourceLocation EndLoc, 7206 OpenMPDirectiveKind CancelRegion) { 7207 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for && 7208 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) { 7209 Diag(StartLoc, diag::err_omp_wrong_cancel_region) 7210 << getOpenMPDirectiveName(CancelRegion); 7211 return StmtError(); 7212 } 7213 if (DSAStack->isParentNowaitRegion()) { 7214 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 7215 return StmtError(); 7216 } 7217 if (DSAStack->isParentOrderedRegion()) { 7218 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 7219 return StmtError(); 7220 } 7221 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 7222 CancelRegion); 7223 } 7224 7225 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 7226 SourceLocation StartLoc, 7227 SourceLocation EndLoc, 7228 OpenMPDirectiveKind CancelRegion) { 7229 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for && 7230 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) { 7231 Diag(StartLoc, diag::err_omp_wrong_cancel_region) 7232 << getOpenMPDirectiveName(CancelRegion); 7233 return StmtError(); 7234 } 7235 if (DSAStack->isParentNowaitRegion()) { 7236 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 7237 return StmtError(); 7238 } 7239 if (DSAStack->isParentOrderedRegion()) { 7240 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 7241 return StmtError(); 7242 } 7243 DSAStack->setParentCancelRegion(/*Cancel=*/true); 7244 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 7245 CancelRegion); 7246 } 7247 7248 static bool checkGrainsizeNumTasksClauses(Sema &S, 7249 ArrayRef<OMPClause *> Clauses) { 7250 OMPClause *PrevClause = nullptr; 7251 bool ErrorFound = false; 7252 for (auto *C : Clauses) { 7253 if (C->getClauseKind() == OMPC_grainsize || 7254 C->getClauseKind() == OMPC_num_tasks) { 7255 if (!PrevClause) 7256 PrevClause = C; 7257 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 7258 S.Diag(C->getLocStart(), 7259 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 7260 << getOpenMPClauseName(C->getClauseKind()) 7261 << getOpenMPClauseName(PrevClause->getClauseKind()); 7262 S.Diag(PrevClause->getLocStart(), 7263 diag::note_omp_previous_grainsize_num_tasks) 7264 << getOpenMPClauseName(PrevClause->getClauseKind()); 7265 ErrorFound = true; 7266 } 7267 } 7268 } 7269 return ErrorFound; 7270 } 7271 7272 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 7273 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7274 SourceLocation EndLoc, 7275 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7276 if (!AStmt) 7277 return StmtError(); 7278 7279 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7280 OMPLoopDirective::HelperExprs B; 7281 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7282 // define the nested loops number. 7283 unsigned NestedLoopCount = 7284 CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 7285 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7286 VarsWithImplicitDSA, B); 7287 if (NestedLoopCount == 0) 7288 return StmtError(); 7289 7290 assert((CurContext->isDependentContext() || B.builtAll()) && 7291 "omp for loop exprs were not built"); 7292 7293 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7294 // The grainsize clause and num_tasks clause are mutually exclusive and may 7295 // not appear on the same taskloop directive. 7296 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7297 return StmtError(); 7298 7299 getCurFunction()->setHasBranchProtectedScope(); 7300 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 7301 NestedLoopCount, Clauses, AStmt, B); 7302 } 7303 7304 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 7305 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7306 SourceLocation EndLoc, 7307 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7308 if (!AStmt) 7309 return StmtError(); 7310 7311 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7312 OMPLoopDirective::HelperExprs B; 7313 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7314 // define the nested loops number. 7315 unsigned NestedLoopCount = 7316 CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 7317 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 7318 VarsWithImplicitDSA, B); 7319 if (NestedLoopCount == 0) 7320 return StmtError(); 7321 7322 assert((CurContext->isDependentContext() || B.builtAll()) && 7323 "omp for loop exprs were not built"); 7324 7325 if (!CurContext->isDependentContext()) { 7326 // Finalize the clauses that need pre-built expressions for CodeGen. 7327 for (auto C : Clauses) { 7328 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7329 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7330 B.NumIterations, *this, CurScope, 7331 DSAStack)) 7332 return StmtError(); 7333 } 7334 } 7335 7336 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 7337 // The grainsize clause and num_tasks clause are mutually exclusive and may 7338 // not appear on the same taskloop directive. 7339 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 7340 return StmtError(); 7341 7342 getCurFunction()->setHasBranchProtectedScope(); 7343 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 7344 NestedLoopCount, Clauses, AStmt, B); 7345 } 7346 7347 StmtResult Sema::ActOnOpenMPDistributeDirective( 7348 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7349 SourceLocation EndLoc, 7350 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7351 if (!AStmt) 7352 return StmtError(); 7353 7354 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 7355 OMPLoopDirective::HelperExprs B; 7356 // In presence of clause 'collapse' with number of loops, it will 7357 // define the nested loops number. 7358 unsigned NestedLoopCount = 7359 CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 7360 nullptr /*ordered not a clause on distribute*/, AStmt, 7361 *this, *DSAStack, VarsWithImplicitDSA, B); 7362 if (NestedLoopCount == 0) 7363 return StmtError(); 7364 7365 assert((CurContext->isDependentContext() || B.builtAll()) && 7366 "omp for loop exprs were not built"); 7367 7368 getCurFunction()->setHasBranchProtectedScope(); 7369 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 7370 NestedLoopCount, Clauses, AStmt, B); 7371 } 7372 7373 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 7374 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7375 SourceLocation EndLoc, 7376 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7377 if (!AStmt) 7378 return StmtError(); 7379 7380 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7381 // 1.2.2 OpenMP Language Terminology 7382 // Structured block - An executable statement with a single entry at the 7383 // top and a single exit at the bottom. 7384 // The point of exit cannot be a branch out of the structured block. 7385 // longjmp() and throw() must not violate the entry/exit criteria. 7386 CS->getCapturedDecl()->setNothrow(); 7387 7388 OMPLoopDirective::HelperExprs B; 7389 // In presence of clause 'collapse' with number of loops, it will 7390 // define the nested loops number. 7391 unsigned NestedLoopCount = CheckOpenMPLoop( 7392 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 7393 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 7394 VarsWithImplicitDSA, B); 7395 if (NestedLoopCount == 0) 7396 return StmtError(); 7397 7398 assert((CurContext->isDependentContext() || B.builtAll()) && 7399 "omp for loop exprs were not built"); 7400 7401 getCurFunction()->setHasBranchProtectedScope(); 7402 return OMPDistributeParallelForDirective::Create( 7403 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7404 } 7405 7406 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 7407 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7408 SourceLocation EndLoc, 7409 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7410 if (!AStmt) 7411 return StmtError(); 7412 7413 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7414 // 1.2.2 OpenMP Language Terminology 7415 // Structured block - An executable statement with a single entry at the 7416 // top and a single exit at the bottom. 7417 // The point of exit cannot be a branch out of the structured block. 7418 // longjmp() and throw() must not violate the entry/exit criteria. 7419 CS->getCapturedDecl()->setNothrow(); 7420 7421 OMPLoopDirective::HelperExprs B; 7422 // In presence of clause 'collapse' with number of loops, it will 7423 // define the nested loops number. 7424 unsigned NestedLoopCount = CheckOpenMPLoop( 7425 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 7426 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 7427 VarsWithImplicitDSA, B); 7428 if (NestedLoopCount == 0) 7429 return StmtError(); 7430 7431 assert((CurContext->isDependentContext() || B.builtAll()) && 7432 "omp for loop exprs were not built"); 7433 7434 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7435 return StmtError(); 7436 7437 getCurFunction()->setHasBranchProtectedScope(); 7438 return OMPDistributeParallelForSimdDirective::Create( 7439 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7440 } 7441 7442 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 7443 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7444 SourceLocation EndLoc, 7445 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7446 if (!AStmt) 7447 return StmtError(); 7448 7449 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7450 // 1.2.2 OpenMP Language Terminology 7451 // Structured block - An executable statement with a single entry at the 7452 // top and a single exit at the bottom. 7453 // The point of exit cannot be a branch out of the structured block. 7454 // longjmp() and throw() must not violate the entry/exit criteria. 7455 CS->getCapturedDecl()->setNothrow(); 7456 7457 OMPLoopDirective::HelperExprs B; 7458 // In presence of clause 'collapse' with number of loops, it will 7459 // define the nested loops number. 7460 unsigned NestedLoopCount = 7461 CheckOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 7462 nullptr /*ordered not a clause on distribute*/, AStmt, 7463 *this, *DSAStack, VarsWithImplicitDSA, B); 7464 if (NestedLoopCount == 0) 7465 return StmtError(); 7466 7467 assert((CurContext->isDependentContext() || B.builtAll()) && 7468 "omp for loop exprs were not built"); 7469 7470 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7471 return StmtError(); 7472 7473 getCurFunction()->setHasBranchProtectedScope(); 7474 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 7475 NestedLoopCount, Clauses, AStmt, B); 7476 } 7477 7478 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 7479 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7480 SourceLocation EndLoc, 7481 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7482 if (!AStmt) 7483 return StmtError(); 7484 7485 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7486 // 1.2.2 OpenMP Language Terminology 7487 // Structured block - An executable statement with a single entry at the 7488 // top and a single exit at the bottom. 7489 // The point of exit cannot be a branch out of the structured block. 7490 // longjmp() and throw() must not violate the entry/exit criteria. 7491 CS->getCapturedDecl()->setNothrow(); 7492 7493 OMPLoopDirective::HelperExprs B; 7494 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 7495 // define the nested loops number. 7496 unsigned NestedLoopCount = CheckOpenMPLoop( 7497 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 7498 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7499 VarsWithImplicitDSA, B); 7500 if (NestedLoopCount == 0) 7501 return StmtError(); 7502 7503 assert((CurContext->isDependentContext() || B.builtAll()) && 7504 "omp target parallel for simd loop exprs were not built"); 7505 7506 if (!CurContext->isDependentContext()) { 7507 // Finalize the clauses that need pre-built expressions for CodeGen. 7508 for (auto C : Clauses) { 7509 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7510 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7511 B.NumIterations, *this, CurScope, 7512 DSAStack)) 7513 return StmtError(); 7514 } 7515 } 7516 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7517 return StmtError(); 7518 7519 getCurFunction()->setHasBranchProtectedScope(); 7520 return OMPTargetParallelForSimdDirective::Create( 7521 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7522 } 7523 7524 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 7525 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7526 SourceLocation EndLoc, 7527 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7528 if (!AStmt) 7529 return StmtError(); 7530 7531 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7532 // 1.2.2 OpenMP Language Terminology 7533 // Structured block - An executable statement with a single entry at the 7534 // top and a single exit at the bottom. 7535 // The point of exit cannot be a branch out of the structured block. 7536 // longjmp() and throw() must not violate the entry/exit criteria. 7537 CS->getCapturedDecl()->setNothrow(); 7538 7539 OMPLoopDirective::HelperExprs B; 7540 // In presence of clause 'collapse' with number of loops, it will define the 7541 // nested loops number. 7542 unsigned NestedLoopCount = 7543 CheckOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 7544 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 7545 VarsWithImplicitDSA, B); 7546 if (NestedLoopCount == 0) 7547 return StmtError(); 7548 7549 assert((CurContext->isDependentContext() || B.builtAll()) && 7550 "omp target simd loop exprs were not built"); 7551 7552 if (!CurContext->isDependentContext()) { 7553 // Finalize the clauses that need pre-built expressions for CodeGen. 7554 for (auto C : Clauses) { 7555 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7556 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7557 B.NumIterations, *this, CurScope, 7558 DSAStack)) 7559 return StmtError(); 7560 } 7561 } 7562 7563 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7564 return StmtError(); 7565 7566 getCurFunction()->setHasBranchProtectedScope(); 7567 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 7568 NestedLoopCount, Clauses, AStmt, B); 7569 } 7570 7571 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 7572 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7573 SourceLocation EndLoc, 7574 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7575 if (!AStmt) 7576 return StmtError(); 7577 7578 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7579 // 1.2.2 OpenMP Language Terminology 7580 // Structured block - An executable statement with a single entry at the 7581 // top and a single exit at the bottom. 7582 // The point of exit cannot be a branch out of the structured block. 7583 // longjmp() and throw() must not violate the entry/exit criteria. 7584 CS->getCapturedDecl()->setNothrow(); 7585 7586 OMPLoopDirective::HelperExprs B; 7587 // In presence of clause 'collapse' with number of loops, it will 7588 // define the nested loops number. 7589 unsigned NestedLoopCount = 7590 CheckOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 7591 nullptr /*ordered not a clause on distribute*/, AStmt, 7592 *this, *DSAStack, VarsWithImplicitDSA, B); 7593 if (NestedLoopCount == 0) 7594 return StmtError(); 7595 7596 assert((CurContext->isDependentContext() || B.builtAll()) && 7597 "omp teams distribute loop exprs were not built"); 7598 7599 getCurFunction()->setHasBranchProtectedScope(); 7600 return OMPTeamsDistributeDirective::Create( 7601 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7602 } 7603 7604 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 7605 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 7606 SourceLocation EndLoc, 7607 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 7608 if (!AStmt) 7609 return StmtError(); 7610 7611 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 7612 // 1.2.2 OpenMP Language Terminology 7613 // Structured block - An executable statement with a single entry at the 7614 // top and a single exit at the bottom. 7615 // The point of exit cannot be a branch out of the structured block. 7616 // longjmp() and throw() must not violate the entry/exit criteria. 7617 CS->getCapturedDecl()->setNothrow(); 7618 7619 OMPLoopDirective::HelperExprs B; 7620 // In presence of clause 'collapse' with number of loops, it will 7621 // define the nested loops number. 7622 unsigned NestedLoopCount = 7623 CheckOpenMPLoop(OMPD_teams_distribute_simd, 7624 getCollapseNumberExpr(Clauses), 7625 nullptr /*ordered not a clause on distribute*/, AStmt, 7626 *this, *DSAStack, VarsWithImplicitDSA, B); 7627 7628 if (NestedLoopCount == 0) 7629 return StmtError(); 7630 7631 assert((CurContext->isDependentContext() || B.builtAll()) && 7632 "omp teams distribute simd loop exprs were not built"); 7633 7634 if (!CurContext->isDependentContext()) { 7635 // Finalize the clauses that need pre-built expressions for CodeGen. 7636 for (auto C : Clauses) { 7637 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 7638 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 7639 B.NumIterations, *this, CurScope, 7640 DSAStack)) 7641 return StmtError(); 7642 } 7643 } 7644 7645 if (checkSimdlenSafelenSpecified(*this, Clauses)) 7646 return StmtError(); 7647 7648 getCurFunction()->setHasBranchProtectedScope(); 7649 return OMPTeamsDistributeSimdDirective::Create( 7650 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 7651 } 7652 7653 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 7654 SourceLocation StartLoc, 7655 SourceLocation LParenLoc, 7656 SourceLocation EndLoc) { 7657 OMPClause *Res = nullptr; 7658 switch (Kind) { 7659 case OMPC_final: 7660 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 7661 break; 7662 case OMPC_num_threads: 7663 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 7664 break; 7665 case OMPC_safelen: 7666 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 7667 break; 7668 case OMPC_simdlen: 7669 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 7670 break; 7671 case OMPC_collapse: 7672 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 7673 break; 7674 case OMPC_ordered: 7675 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 7676 break; 7677 case OMPC_device: 7678 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 7679 break; 7680 case OMPC_num_teams: 7681 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 7682 break; 7683 case OMPC_thread_limit: 7684 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 7685 break; 7686 case OMPC_priority: 7687 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 7688 break; 7689 case OMPC_grainsize: 7690 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 7691 break; 7692 case OMPC_num_tasks: 7693 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 7694 break; 7695 case OMPC_hint: 7696 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 7697 break; 7698 case OMPC_if: 7699 case OMPC_default: 7700 case OMPC_proc_bind: 7701 case OMPC_schedule: 7702 case OMPC_private: 7703 case OMPC_firstprivate: 7704 case OMPC_lastprivate: 7705 case OMPC_shared: 7706 case OMPC_reduction: 7707 case OMPC_linear: 7708 case OMPC_aligned: 7709 case OMPC_copyin: 7710 case OMPC_copyprivate: 7711 case OMPC_nowait: 7712 case OMPC_untied: 7713 case OMPC_mergeable: 7714 case OMPC_threadprivate: 7715 case OMPC_flush: 7716 case OMPC_read: 7717 case OMPC_write: 7718 case OMPC_update: 7719 case OMPC_capture: 7720 case OMPC_seq_cst: 7721 case OMPC_depend: 7722 case OMPC_threads: 7723 case OMPC_simd: 7724 case OMPC_map: 7725 case OMPC_nogroup: 7726 case OMPC_dist_schedule: 7727 case OMPC_defaultmap: 7728 case OMPC_unknown: 7729 case OMPC_uniform: 7730 case OMPC_to: 7731 case OMPC_from: 7732 case OMPC_use_device_ptr: 7733 case OMPC_is_device_ptr: 7734 llvm_unreachable("Clause is not allowed."); 7735 } 7736 return Res; 7737 } 7738 7739 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 7740 Expr *Condition, SourceLocation StartLoc, 7741 SourceLocation LParenLoc, 7742 SourceLocation NameModifierLoc, 7743 SourceLocation ColonLoc, 7744 SourceLocation EndLoc) { 7745 Expr *ValExpr = Condition; 7746 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 7747 !Condition->isInstantiationDependent() && 7748 !Condition->containsUnexpandedParameterPack()) { 7749 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 7750 if (Val.isInvalid()) 7751 return nullptr; 7752 7753 ValExpr = MakeFullExpr(Val.get()).get(); 7754 } 7755 7756 return new (Context) OMPIfClause(NameModifier, ValExpr, StartLoc, LParenLoc, 7757 NameModifierLoc, ColonLoc, EndLoc); 7758 } 7759 7760 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 7761 SourceLocation StartLoc, 7762 SourceLocation LParenLoc, 7763 SourceLocation EndLoc) { 7764 Expr *ValExpr = Condition; 7765 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 7766 !Condition->isInstantiationDependent() && 7767 !Condition->containsUnexpandedParameterPack()) { 7768 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 7769 if (Val.isInvalid()) 7770 return nullptr; 7771 7772 ValExpr = MakeFullExpr(Val.get()).get(); 7773 } 7774 7775 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 7776 } 7777 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 7778 Expr *Op) { 7779 if (!Op) 7780 return ExprError(); 7781 7782 class IntConvertDiagnoser : public ICEConvertDiagnoser { 7783 public: 7784 IntConvertDiagnoser() 7785 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 7786 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 7787 QualType T) override { 7788 return S.Diag(Loc, diag::err_omp_not_integral) << T; 7789 } 7790 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 7791 QualType T) override { 7792 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 7793 } 7794 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 7795 QualType T, 7796 QualType ConvTy) override { 7797 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 7798 } 7799 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 7800 QualType ConvTy) override { 7801 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 7802 << ConvTy->isEnumeralType() << ConvTy; 7803 } 7804 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 7805 QualType T) override { 7806 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 7807 } 7808 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 7809 QualType ConvTy) override { 7810 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 7811 << ConvTy->isEnumeralType() << ConvTy; 7812 } 7813 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 7814 QualType) override { 7815 llvm_unreachable("conversion functions are permitted"); 7816 } 7817 } ConvertDiagnoser; 7818 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 7819 } 7820 7821 static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 7822 OpenMPClauseKind CKind, 7823 bool StrictlyPositive) { 7824 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 7825 !ValExpr->isInstantiationDependent()) { 7826 SourceLocation Loc = ValExpr->getExprLoc(); 7827 ExprResult Value = 7828 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 7829 if (Value.isInvalid()) 7830 return false; 7831 7832 ValExpr = Value.get(); 7833 // The expression must evaluate to a non-negative integer value. 7834 llvm::APSInt Result; 7835 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 7836 Result.isSigned() && 7837 !((!StrictlyPositive && Result.isNonNegative()) || 7838 (StrictlyPositive && Result.isStrictlyPositive()))) { 7839 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 7840 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 7841 << ValExpr->getSourceRange(); 7842 return false; 7843 } 7844 } 7845 return true; 7846 } 7847 7848 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 7849 SourceLocation StartLoc, 7850 SourceLocation LParenLoc, 7851 SourceLocation EndLoc) { 7852 Expr *ValExpr = NumThreads; 7853 7854 // OpenMP [2.5, Restrictions] 7855 // The num_threads expression must evaluate to a positive integer value. 7856 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 7857 /*StrictlyPositive=*/true)) 7858 return nullptr; 7859 7860 return new (Context) 7861 OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc); 7862 } 7863 7864 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 7865 OpenMPClauseKind CKind, 7866 bool StrictlyPositive) { 7867 if (!E) 7868 return ExprError(); 7869 if (E->isValueDependent() || E->isTypeDependent() || 7870 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 7871 return E; 7872 llvm::APSInt Result; 7873 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 7874 if (ICE.isInvalid()) 7875 return ExprError(); 7876 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 7877 (!StrictlyPositive && !Result.isNonNegative())) { 7878 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 7879 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 7880 << E->getSourceRange(); 7881 return ExprError(); 7882 } 7883 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 7884 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 7885 << E->getSourceRange(); 7886 return ExprError(); 7887 } 7888 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 7889 DSAStack->setAssociatedLoops(Result.getExtValue()); 7890 else if (CKind == OMPC_ordered) 7891 DSAStack->setAssociatedLoops(Result.getExtValue()); 7892 return ICE; 7893 } 7894 7895 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 7896 SourceLocation LParenLoc, 7897 SourceLocation EndLoc) { 7898 // OpenMP [2.8.1, simd construct, Description] 7899 // The parameter of the safelen clause must be a constant 7900 // positive integer expression. 7901 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 7902 if (Safelen.isInvalid()) 7903 return nullptr; 7904 return new (Context) 7905 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 7906 } 7907 7908 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 7909 SourceLocation LParenLoc, 7910 SourceLocation EndLoc) { 7911 // OpenMP [2.8.1, simd construct, Description] 7912 // The parameter of the simdlen clause must be a constant 7913 // positive integer expression. 7914 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 7915 if (Simdlen.isInvalid()) 7916 return nullptr; 7917 return new (Context) 7918 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 7919 } 7920 7921 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 7922 SourceLocation StartLoc, 7923 SourceLocation LParenLoc, 7924 SourceLocation EndLoc) { 7925 // OpenMP [2.7.1, loop construct, Description] 7926 // OpenMP [2.8.1, simd construct, Description] 7927 // OpenMP [2.9.6, distribute construct, Description] 7928 // The parameter of the collapse clause must be a constant 7929 // positive integer expression. 7930 ExprResult NumForLoopsResult = 7931 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 7932 if (NumForLoopsResult.isInvalid()) 7933 return nullptr; 7934 return new (Context) 7935 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 7936 } 7937 7938 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 7939 SourceLocation EndLoc, 7940 SourceLocation LParenLoc, 7941 Expr *NumForLoops) { 7942 // OpenMP [2.7.1, loop construct, Description] 7943 // OpenMP [2.8.1, simd construct, Description] 7944 // OpenMP [2.9.6, distribute construct, Description] 7945 // The parameter of the ordered clause must be a constant 7946 // positive integer expression if any. 7947 if (NumForLoops && LParenLoc.isValid()) { 7948 ExprResult NumForLoopsResult = 7949 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 7950 if (NumForLoopsResult.isInvalid()) 7951 return nullptr; 7952 NumForLoops = NumForLoopsResult.get(); 7953 } else 7954 NumForLoops = nullptr; 7955 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops); 7956 return new (Context) 7957 OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc); 7958 } 7959 7960 OMPClause *Sema::ActOnOpenMPSimpleClause( 7961 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 7962 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 7963 OMPClause *Res = nullptr; 7964 switch (Kind) { 7965 case OMPC_default: 7966 Res = 7967 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 7968 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 7969 break; 7970 case OMPC_proc_bind: 7971 Res = ActOnOpenMPProcBindClause( 7972 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 7973 LParenLoc, EndLoc); 7974 break; 7975 case OMPC_if: 7976 case OMPC_final: 7977 case OMPC_num_threads: 7978 case OMPC_safelen: 7979 case OMPC_simdlen: 7980 case OMPC_collapse: 7981 case OMPC_schedule: 7982 case OMPC_private: 7983 case OMPC_firstprivate: 7984 case OMPC_lastprivate: 7985 case OMPC_shared: 7986 case OMPC_reduction: 7987 case OMPC_linear: 7988 case OMPC_aligned: 7989 case OMPC_copyin: 7990 case OMPC_copyprivate: 7991 case OMPC_ordered: 7992 case OMPC_nowait: 7993 case OMPC_untied: 7994 case OMPC_mergeable: 7995 case OMPC_threadprivate: 7996 case OMPC_flush: 7997 case OMPC_read: 7998 case OMPC_write: 7999 case OMPC_update: 8000 case OMPC_capture: 8001 case OMPC_seq_cst: 8002 case OMPC_depend: 8003 case OMPC_device: 8004 case OMPC_threads: 8005 case OMPC_simd: 8006 case OMPC_map: 8007 case OMPC_num_teams: 8008 case OMPC_thread_limit: 8009 case OMPC_priority: 8010 case OMPC_grainsize: 8011 case OMPC_nogroup: 8012 case OMPC_num_tasks: 8013 case OMPC_hint: 8014 case OMPC_dist_schedule: 8015 case OMPC_defaultmap: 8016 case OMPC_unknown: 8017 case OMPC_uniform: 8018 case OMPC_to: 8019 case OMPC_from: 8020 case OMPC_use_device_ptr: 8021 case OMPC_is_device_ptr: 8022 llvm_unreachable("Clause is not allowed."); 8023 } 8024 return Res; 8025 } 8026 8027 static std::string 8028 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 8029 ArrayRef<unsigned> Exclude = llvm::None) { 8030 std::string Values; 8031 unsigned Bound = Last >= 2 ? Last - 2 : 0; 8032 unsigned Skipped = Exclude.size(); 8033 auto S = Exclude.begin(), E = Exclude.end(); 8034 for (unsigned i = First; i < Last; ++i) { 8035 if (std::find(S, E, i) != E) { 8036 --Skipped; 8037 continue; 8038 } 8039 Values += "'"; 8040 Values += getOpenMPSimpleClauseTypeName(K, i); 8041 Values += "'"; 8042 if (i == Bound - Skipped) 8043 Values += " or "; 8044 else if (i != Bound + 1 - Skipped) 8045 Values += ", "; 8046 } 8047 return Values; 8048 } 8049 8050 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 8051 SourceLocation KindKwLoc, 8052 SourceLocation StartLoc, 8053 SourceLocation LParenLoc, 8054 SourceLocation EndLoc) { 8055 if (Kind == OMPC_DEFAULT_unknown) { 8056 static_assert(OMPC_DEFAULT_unknown > 0, 8057 "OMPC_DEFAULT_unknown not greater than 0"); 8058 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 8059 << getListOfPossibleValues(OMPC_default, /*First=*/0, 8060 /*Last=*/OMPC_DEFAULT_unknown) 8061 << getOpenMPClauseName(OMPC_default); 8062 return nullptr; 8063 } 8064 switch (Kind) { 8065 case OMPC_DEFAULT_none: 8066 DSAStack->setDefaultDSANone(KindKwLoc); 8067 break; 8068 case OMPC_DEFAULT_shared: 8069 DSAStack->setDefaultDSAShared(KindKwLoc); 8070 break; 8071 case OMPC_DEFAULT_unknown: 8072 llvm_unreachable("Clause kind is not allowed."); 8073 break; 8074 } 8075 return new (Context) 8076 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 8077 } 8078 8079 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 8080 SourceLocation KindKwLoc, 8081 SourceLocation StartLoc, 8082 SourceLocation LParenLoc, 8083 SourceLocation EndLoc) { 8084 if (Kind == OMPC_PROC_BIND_unknown) { 8085 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 8086 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 8087 /*Last=*/OMPC_PROC_BIND_unknown) 8088 << getOpenMPClauseName(OMPC_proc_bind); 8089 return nullptr; 8090 } 8091 return new (Context) 8092 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 8093 } 8094 8095 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 8096 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 8097 SourceLocation StartLoc, SourceLocation LParenLoc, 8098 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 8099 SourceLocation EndLoc) { 8100 OMPClause *Res = nullptr; 8101 switch (Kind) { 8102 case OMPC_schedule: 8103 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 8104 assert(Argument.size() == NumberOfElements && 8105 ArgumentLoc.size() == NumberOfElements); 8106 Res = ActOnOpenMPScheduleClause( 8107 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 8108 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 8109 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 8110 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 8111 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 8112 break; 8113 case OMPC_if: 8114 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 8115 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 8116 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 8117 DelimLoc, EndLoc); 8118 break; 8119 case OMPC_dist_schedule: 8120 Res = ActOnOpenMPDistScheduleClause( 8121 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 8122 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 8123 break; 8124 case OMPC_defaultmap: 8125 enum { Modifier, DefaultmapKind }; 8126 Res = ActOnOpenMPDefaultmapClause( 8127 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 8128 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 8129 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 8130 EndLoc); 8131 break; 8132 case OMPC_final: 8133 case OMPC_num_threads: 8134 case OMPC_safelen: 8135 case OMPC_simdlen: 8136 case OMPC_collapse: 8137 case OMPC_default: 8138 case OMPC_proc_bind: 8139 case OMPC_private: 8140 case OMPC_firstprivate: 8141 case OMPC_lastprivate: 8142 case OMPC_shared: 8143 case OMPC_reduction: 8144 case OMPC_linear: 8145 case OMPC_aligned: 8146 case OMPC_copyin: 8147 case OMPC_copyprivate: 8148 case OMPC_ordered: 8149 case OMPC_nowait: 8150 case OMPC_untied: 8151 case OMPC_mergeable: 8152 case OMPC_threadprivate: 8153 case OMPC_flush: 8154 case OMPC_read: 8155 case OMPC_write: 8156 case OMPC_update: 8157 case OMPC_capture: 8158 case OMPC_seq_cst: 8159 case OMPC_depend: 8160 case OMPC_device: 8161 case OMPC_threads: 8162 case OMPC_simd: 8163 case OMPC_map: 8164 case OMPC_num_teams: 8165 case OMPC_thread_limit: 8166 case OMPC_priority: 8167 case OMPC_grainsize: 8168 case OMPC_nogroup: 8169 case OMPC_num_tasks: 8170 case OMPC_hint: 8171 case OMPC_unknown: 8172 case OMPC_uniform: 8173 case OMPC_to: 8174 case OMPC_from: 8175 case OMPC_use_device_ptr: 8176 case OMPC_is_device_ptr: 8177 llvm_unreachable("Clause is not allowed."); 8178 } 8179 return Res; 8180 } 8181 8182 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 8183 OpenMPScheduleClauseModifier M2, 8184 SourceLocation M1Loc, SourceLocation M2Loc) { 8185 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 8186 SmallVector<unsigned, 2> Excluded; 8187 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 8188 Excluded.push_back(M2); 8189 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 8190 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 8191 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 8192 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 8193 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 8194 << getListOfPossibleValues(OMPC_schedule, 8195 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 8196 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 8197 Excluded) 8198 << getOpenMPClauseName(OMPC_schedule); 8199 return true; 8200 } 8201 return false; 8202 } 8203 8204 OMPClause *Sema::ActOnOpenMPScheduleClause( 8205 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 8206 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 8207 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 8208 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 8209 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 8210 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 8211 return nullptr; 8212 // OpenMP, 2.7.1, Loop Construct, Restrictions 8213 // Either the monotonic modifier or the nonmonotonic modifier can be specified 8214 // but not both. 8215 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 8216 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 8217 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 8218 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 8219 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 8220 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 8221 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 8222 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 8223 return nullptr; 8224 } 8225 if (Kind == OMPC_SCHEDULE_unknown) { 8226 std::string Values; 8227 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 8228 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 8229 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 8230 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 8231 Exclude); 8232 } else { 8233 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 8234 /*Last=*/OMPC_SCHEDULE_unknown); 8235 } 8236 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 8237 << Values << getOpenMPClauseName(OMPC_schedule); 8238 return nullptr; 8239 } 8240 // OpenMP, 2.7.1, Loop Construct, Restrictions 8241 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 8242 // schedule(guided). 8243 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 8244 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 8245 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 8246 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 8247 diag::err_omp_schedule_nonmonotonic_static); 8248 return nullptr; 8249 } 8250 Expr *ValExpr = ChunkSize; 8251 Stmt *HelperValStmt = nullptr; 8252 if (ChunkSize) { 8253 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 8254 !ChunkSize->isInstantiationDependent() && 8255 !ChunkSize->containsUnexpandedParameterPack()) { 8256 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 8257 ExprResult Val = 8258 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 8259 if (Val.isInvalid()) 8260 return nullptr; 8261 8262 ValExpr = Val.get(); 8263 8264 // OpenMP [2.7.1, Restrictions] 8265 // chunk_size must be a loop invariant integer expression with a positive 8266 // value. 8267 llvm::APSInt Result; 8268 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 8269 if (Result.isSigned() && !Result.isStrictlyPositive()) { 8270 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 8271 << "schedule" << 1 << ChunkSize->getSourceRange(); 8272 return nullptr; 8273 } 8274 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) && 8275 !CurContext->isDependentContext()) { 8276 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 8277 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 8278 HelperValStmt = buildPreInits(Context, Captures); 8279 } 8280 } 8281 } 8282 8283 return new (Context) 8284 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 8285 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 8286 } 8287 8288 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 8289 SourceLocation StartLoc, 8290 SourceLocation EndLoc) { 8291 OMPClause *Res = nullptr; 8292 switch (Kind) { 8293 case OMPC_ordered: 8294 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 8295 break; 8296 case OMPC_nowait: 8297 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 8298 break; 8299 case OMPC_untied: 8300 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 8301 break; 8302 case OMPC_mergeable: 8303 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 8304 break; 8305 case OMPC_read: 8306 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 8307 break; 8308 case OMPC_write: 8309 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 8310 break; 8311 case OMPC_update: 8312 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 8313 break; 8314 case OMPC_capture: 8315 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 8316 break; 8317 case OMPC_seq_cst: 8318 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 8319 break; 8320 case OMPC_threads: 8321 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 8322 break; 8323 case OMPC_simd: 8324 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 8325 break; 8326 case OMPC_nogroup: 8327 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 8328 break; 8329 case OMPC_if: 8330 case OMPC_final: 8331 case OMPC_num_threads: 8332 case OMPC_safelen: 8333 case OMPC_simdlen: 8334 case OMPC_collapse: 8335 case OMPC_schedule: 8336 case OMPC_private: 8337 case OMPC_firstprivate: 8338 case OMPC_lastprivate: 8339 case OMPC_shared: 8340 case OMPC_reduction: 8341 case OMPC_linear: 8342 case OMPC_aligned: 8343 case OMPC_copyin: 8344 case OMPC_copyprivate: 8345 case OMPC_default: 8346 case OMPC_proc_bind: 8347 case OMPC_threadprivate: 8348 case OMPC_flush: 8349 case OMPC_depend: 8350 case OMPC_device: 8351 case OMPC_map: 8352 case OMPC_num_teams: 8353 case OMPC_thread_limit: 8354 case OMPC_priority: 8355 case OMPC_grainsize: 8356 case OMPC_num_tasks: 8357 case OMPC_hint: 8358 case OMPC_dist_schedule: 8359 case OMPC_defaultmap: 8360 case OMPC_unknown: 8361 case OMPC_uniform: 8362 case OMPC_to: 8363 case OMPC_from: 8364 case OMPC_use_device_ptr: 8365 case OMPC_is_device_ptr: 8366 llvm_unreachable("Clause is not allowed."); 8367 } 8368 return Res; 8369 } 8370 8371 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 8372 SourceLocation EndLoc) { 8373 DSAStack->setNowaitRegion(); 8374 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 8375 } 8376 8377 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 8378 SourceLocation EndLoc) { 8379 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 8380 } 8381 8382 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 8383 SourceLocation EndLoc) { 8384 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 8385 } 8386 8387 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 8388 SourceLocation EndLoc) { 8389 return new (Context) OMPReadClause(StartLoc, EndLoc); 8390 } 8391 8392 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 8393 SourceLocation EndLoc) { 8394 return new (Context) OMPWriteClause(StartLoc, EndLoc); 8395 } 8396 8397 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 8398 SourceLocation EndLoc) { 8399 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 8400 } 8401 8402 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 8403 SourceLocation EndLoc) { 8404 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 8405 } 8406 8407 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 8408 SourceLocation EndLoc) { 8409 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 8410 } 8411 8412 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 8413 SourceLocation EndLoc) { 8414 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 8415 } 8416 8417 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 8418 SourceLocation EndLoc) { 8419 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 8420 } 8421 8422 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 8423 SourceLocation EndLoc) { 8424 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 8425 } 8426 8427 OMPClause *Sema::ActOnOpenMPVarListClause( 8428 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 8429 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 8430 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 8431 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, 8432 OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, 8433 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 8434 SourceLocation DepLinMapLoc) { 8435 OMPClause *Res = nullptr; 8436 switch (Kind) { 8437 case OMPC_private: 8438 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8439 break; 8440 case OMPC_firstprivate: 8441 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8442 break; 8443 case OMPC_lastprivate: 8444 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8445 break; 8446 case OMPC_shared: 8447 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 8448 break; 8449 case OMPC_reduction: 8450 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 8451 EndLoc, ReductionIdScopeSpec, ReductionId); 8452 break; 8453 case OMPC_linear: 8454 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 8455 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 8456 break; 8457 case OMPC_aligned: 8458 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 8459 ColonLoc, EndLoc); 8460 break; 8461 case OMPC_copyin: 8462 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 8463 break; 8464 case OMPC_copyprivate: 8465 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 8466 break; 8467 case OMPC_flush: 8468 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 8469 break; 8470 case OMPC_depend: 8471 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 8472 StartLoc, LParenLoc, EndLoc); 8473 break; 8474 case OMPC_map: 8475 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, 8476 DepLinMapLoc, ColonLoc, VarList, StartLoc, 8477 LParenLoc, EndLoc); 8478 break; 8479 case OMPC_to: 8480 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc); 8481 break; 8482 case OMPC_from: 8483 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc); 8484 break; 8485 case OMPC_use_device_ptr: 8486 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); 8487 break; 8488 case OMPC_is_device_ptr: 8489 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); 8490 break; 8491 case OMPC_if: 8492 case OMPC_final: 8493 case OMPC_num_threads: 8494 case OMPC_safelen: 8495 case OMPC_simdlen: 8496 case OMPC_collapse: 8497 case OMPC_default: 8498 case OMPC_proc_bind: 8499 case OMPC_schedule: 8500 case OMPC_ordered: 8501 case OMPC_nowait: 8502 case OMPC_untied: 8503 case OMPC_mergeable: 8504 case OMPC_threadprivate: 8505 case OMPC_read: 8506 case OMPC_write: 8507 case OMPC_update: 8508 case OMPC_capture: 8509 case OMPC_seq_cst: 8510 case OMPC_device: 8511 case OMPC_threads: 8512 case OMPC_simd: 8513 case OMPC_num_teams: 8514 case OMPC_thread_limit: 8515 case OMPC_priority: 8516 case OMPC_grainsize: 8517 case OMPC_nogroup: 8518 case OMPC_num_tasks: 8519 case OMPC_hint: 8520 case OMPC_dist_schedule: 8521 case OMPC_defaultmap: 8522 case OMPC_unknown: 8523 case OMPC_uniform: 8524 llvm_unreachable("Clause is not allowed."); 8525 } 8526 return Res; 8527 } 8528 8529 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 8530 ExprObjectKind OK, SourceLocation Loc) { 8531 ExprResult Res = BuildDeclRefExpr( 8532 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 8533 if (!Res.isUsable()) 8534 return ExprError(); 8535 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 8536 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 8537 if (!Res.isUsable()) 8538 return ExprError(); 8539 } 8540 if (VK != VK_LValue && Res.get()->isGLValue()) { 8541 Res = DefaultLvalueConversion(Res.get()); 8542 if (!Res.isUsable()) 8543 return ExprError(); 8544 } 8545 return Res; 8546 } 8547 8548 static std::pair<ValueDecl *, bool> 8549 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 8550 SourceRange &ERange, bool AllowArraySection = false) { 8551 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 8552 RefExpr->containsUnexpandedParameterPack()) 8553 return std::make_pair(nullptr, true); 8554 8555 // OpenMP [3.1, C/C++] 8556 // A list item is a variable name. 8557 // OpenMP [2.9.3.3, Restrictions, p.1] 8558 // A variable that is part of another variable (as an array or 8559 // structure element) cannot appear in a private clause. 8560 RefExpr = RefExpr->IgnoreParens(); 8561 enum { 8562 NoArrayExpr = -1, 8563 ArraySubscript = 0, 8564 OMPArraySection = 1 8565 } IsArrayExpr = NoArrayExpr; 8566 if (AllowArraySection) { 8567 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 8568 auto *Base = ASE->getBase()->IgnoreParenImpCasts(); 8569 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 8570 Base = TempASE->getBase()->IgnoreParenImpCasts(); 8571 RefExpr = Base; 8572 IsArrayExpr = ArraySubscript; 8573 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 8574 auto *Base = OASE->getBase()->IgnoreParenImpCasts(); 8575 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 8576 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 8577 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 8578 Base = TempASE->getBase()->IgnoreParenImpCasts(); 8579 RefExpr = Base; 8580 IsArrayExpr = OMPArraySection; 8581 } 8582 } 8583 ELoc = RefExpr->getExprLoc(); 8584 ERange = RefExpr->getSourceRange(); 8585 RefExpr = RefExpr->IgnoreParenImpCasts(); 8586 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 8587 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 8588 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 8589 (S.getCurrentThisType().isNull() || !ME || 8590 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 8591 !isa<FieldDecl>(ME->getMemberDecl()))) { 8592 if (IsArrayExpr != NoArrayExpr) 8593 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 8594 << ERange; 8595 else { 8596 S.Diag(ELoc, 8597 AllowArraySection 8598 ? diag::err_omp_expected_var_name_member_expr_or_array_item 8599 : diag::err_omp_expected_var_name_member_expr) 8600 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 8601 } 8602 return std::make_pair(nullptr, false); 8603 } 8604 return std::make_pair(DE ? DE->getDecl() : ME->getMemberDecl(), false); 8605 } 8606 8607 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 8608 SourceLocation StartLoc, 8609 SourceLocation LParenLoc, 8610 SourceLocation EndLoc) { 8611 SmallVector<Expr *, 8> Vars; 8612 SmallVector<Expr *, 8> PrivateCopies; 8613 for (auto &RefExpr : VarList) { 8614 assert(RefExpr && "NULL expr in OpenMP private clause."); 8615 SourceLocation ELoc; 8616 SourceRange ERange; 8617 Expr *SimpleRefExpr = RefExpr; 8618 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8619 if (Res.second) { 8620 // It will be analyzed later. 8621 Vars.push_back(RefExpr); 8622 PrivateCopies.push_back(nullptr); 8623 } 8624 ValueDecl *D = Res.first; 8625 if (!D) 8626 continue; 8627 8628 QualType Type = D->getType(); 8629 auto *VD = dyn_cast<VarDecl>(D); 8630 8631 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 8632 // A variable that appears in a private clause must not have an incomplete 8633 // type or a reference type. 8634 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 8635 continue; 8636 Type = Type.getNonReferenceType(); 8637 8638 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8639 // in a Construct] 8640 // Variables with the predetermined data-sharing attributes may not be 8641 // listed in data-sharing attributes clauses, except for the cases 8642 // listed below. For these exceptions only, listing a predetermined 8643 // variable in a data-sharing attribute clause is allowed and overrides 8644 // the variable's predetermined data-sharing attributes. 8645 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8646 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 8647 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 8648 << getOpenMPClauseName(OMPC_private); 8649 ReportOriginalDSA(*this, DSAStack, D, DVar); 8650 continue; 8651 } 8652 8653 // Variably modified types are not supported for tasks. 8654 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 8655 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 8656 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 8657 << getOpenMPClauseName(OMPC_private) << Type 8658 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 8659 bool IsDecl = 8660 !VD || 8661 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8662 Diag(D->getLocation(), 8663 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8664 << D; 8665 continue; 8666 } 8667 8668 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 8669 // A list item cannot appear in both a map clause and a data-sharing 8670 // attribute clause on the same construct 8671 if (DSAStack->getCurrentDirective() == OMPD_target) { 8672 OpenMPClauseKind ConflictKind; 8673 if (DSAStack->checkMappableExprComponentListsForDecl( 8674 VD, /*CurrentRegionOnly=*/true, 8675 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 8676 OpenMPClauseKind WhereFoundClauseKind) -> bool { 8677 ConflictKind = WhereFoundClauseKind; 8678 return true; 8679 })) { 8680 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 8681 << getOpenMPClauseName(OMPC_private) 8682 << getOpenMPClauseName(ConflictKind) 8683 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 8684 ReportOriginalDSA(*this, DSAStack, D, DVar); 8685 continue; 8686 } 8687 } 8688 8689 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 8690 // A variable of class type (or array thereof) that appears in a private 8691 // clause requires an accessible, unambiguous default constructor for the 8692 // class type. 8693 // Generate helper private variable and initialize it with the default 8694 // value. The address of the original variable is replaced by the address of 8695 // the new private variable in CodeGen. This new variable is not added to 8696 // IdResolver, so the code in the OpenMP region uses original variable for 8697 // proper diagnostics. 8698 Type = Type.getUnqualifiedType(); 8699 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 8700 D->hasAttrs() ? &D->getAttrs() : nullptr); 8701 ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); 8702 if (VDPrivate->isInvalidDecl()) 8703 continue; 8704 auto VDPrivateRefExpr = buildDeclRefExpr( 8705 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 8706 8707 DeclRefExpr *Ref = nullptr; 8708 if (!VD && !CurContext->isDependentContext()) 8709 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 8710 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 8711 Vars.push_back((VD || CurContext->isDependentContext()) 8712 ? RefExpr->IgnoreParens() 8713 : Ref); 8714 PrivateCopies.push_back(VDPrivateRefExpr); 8715 } 8716 8717 if (Vars.empty()) 8718 return nullptr; 8719 8720 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 8721 PrivateCopies); 8722 } 8723 8724 namespace { 8725 class DiagsUninitializedSeveretyRAII { 8726 private: 8727 DiagnosticsEngine &Diags; 8728 SourceLocation SavedLoc; 8729 bool IsIgnored; 8730 8731 public: 8732 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 8733 bool IsIgnored) 8734 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 8735 if (!IsIgnored) { 8736 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 8737 /*Map*/ diag::Severity::Ignored, Loc); 8738 } 8739 } 8740 ~DiagsUninitializedSeveretyRAII() { 8741 if (!IsIgnored) 8742 Diags.popMappings(SavedLoc); 8743 } 8744 }; 8745 } 8746 8747 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 8748 SourceLocation StartLoc, 8749 SourceLocation LParenLoc, 8750 SourceLocation EndLoc) { 8751 SmallVector<Expr *, 8> Vars; 8752 SmallVector<Expr *, 8> PrivateCopies; 8753 SmallVector<Expr *, 8> Inits; 8754 SmallVector<Decl *, 4> ExprCaptures; 8755 bool IsImplicitClause = 8756 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 8757 auto ImplicitClauseLoc = DSAStack->getConstructLoc(); 8758 8759 for (auto &RefExpr : VarList) { 8760 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 8761 SourceLocation ELoc; 8762 SourceRange ERange; 8763 Expr *SimpleRefExpr = RefExpr; 8764 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8765 if (Res.second) { 8766 // It will be analyzed later. 8767 Vars.push_back(RefExpr); 8768 PrivateCopies.push_back(nullptr); 8769 Inits.push_back(nullptr); 8770 } 8771 ValueDecl *D = Res.first; 8772 if (!D) 8773 continue; 8774 8775 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 8776 QualType Type = D->getType(); 8777 auto *VD = dyn_cast<VarDecl>(D); 8778 8779 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 8780 // A variable that appears in a private clause must not have an incomplete 8781 // type or a reference type. 8782 if (RequireCompleteType(ELoc, Type, 8783 diag::err_omp_firstprivate_incomplete_type)) 8784 continue; 8785 Type = Type.getNonReferenceType(); 8786 8787 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 8788 // A variable of class type (or array thereof) that appears in a private 8789 // clause requires an accessible, unambiguous copy constructor for the 8790 // class type. 8791 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 8792 8793 // If an implicit firstprivate variable found it was checked already. 8794 DSAStackTy::DSAVarData TopDVar; 8795 if (!IsImplicitClause) { 8796 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8797 TopDVar = DVar; 8798 bool IsConstant = ElemType.isConstant(Context); 8799 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 8800 // A list item that specifies a given variable may not appear in more 8801 // than one clause on the same directive, except that a variable may be 8802 // specified in both firstprivate and lastprivate clauses. 8803 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 8804 DVar.CKind != OMPC_lastprivate && DVar.RefExpr) { 8805 Diag(ELoc, diag::err_omp_wrong_dsa) 8806 << getOpenMPClauseName(DVar.CKind) 8807 << getOpenMPClauseName(OMPC_firstprivate); 8808 ReportOriginalDSA(*this, DSAStack, D, DVar); 8809 continue; 8810 } 8811 8812 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8813 // in a Construct] 8814 // Variables with the predetermined data-sharing attributes may not be 8815 // listed in data-sharing attributes clauses, except for the cases 8816 // listed below. For these exceptions only, listing a predetermined 8817 // variable in a data-sharing attribute clause is allowed and overrides 8818 // the variable's predetermined data-sharing attributes. 8819 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8820 // in a Construct, C/C++, p.2] 8821 // Variables with const-qualified type having no mutable member may be 8822 // listed in a firstprivate clause, even if they are static data members. 8823 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 8824 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 8825 Diag(ELoc, diag::err_omp_wrong_dsa) 8826 << getOpenMPClauseName(DVar.CKind) 8827 << getOpenMPClauseName(OMPC_firstprivate); 8828 ReportOriginalDSA(*this, DSAStack, D, DVar); 8829 continue; 8830 } 8831 8832 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 8833 // OpenMP [2.9.3.4, Restrictions, p.2] 8834 // A list item that is private within a parallel region must not appear 8835 // in a firstprivate clause on a worksharing construct if any of the 8836 // worksharing regions arising from the worksharing construct ever bind 8837 // to any of the parallel regions arising from the parallel construct. 8838 if (isOpenMPWorksharingDirective(CurrDir) && 8839 !isOpenMPParallelDirective(CurrDir)) { 8840 DVar = DSAStack->getImplicitDSA(D, true); 8841 if (DVar.CKind != OMPC_shared && 8842 (isOpenMPParallelDirective(DVar.DKind) || 8843 DVar.DKind == OMPD_unknown)) { 8844 Diag(ELoc, diag::err_omp_required_access) 8845 << getOpenMPClauseName(OMPC_firstprivate) 8846 << getOpenMPClauseName(OMPC_shared); 8847 ReportOriginalDSA(*this, DSAStack, D, DVar); 8848 continue; 8849 } 8850 } 8851 // OpenMP [2.9.3.4, Restrictions, p.3] 8852 // A list item that appears in a reduction clause of a parallel construct 8853 // must not appear in a firstprivate clause on a worksharing or task 8854 // construct if any of the worksharing or task regions arising from the 8855 // worksharing or task construct ever bind to any of the parallel regions 8856 // arising from the parallel construct. 8857 // OpenMP [2.9.3.4, Restrictions, p.4] 8858 // A list item that appears in a reduction clause in worksharing 8859 // construct must not appear in a firstprivate clause in a task construct 8860 // encountered during execution of any of the worksharing regions arising 8861 // from the worksharing construct. 8862 if (isOpenMPTaskingDirective(CurrDir)) { 8863 DVar = DSAStack->hasInnermostDSA( 8864 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 8865 [](OpenMPDirectiveKind K) -> bool { 8866 return isOpenMPParallelDirective(K) || 8867 isOpenMPWorksharingDirective(K); 8868 }, 8869 false); 8870 if (DVar.CKind == OMPC_reduction && 8871 (isOpenMPParallelDirective(DVar.DKind) || 8872 isOpenMPWorksharingDirective(DVar.DKind))) { 8873 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 8874 << getOpenMPDirectiveName(DVar.DKind); 8875 ReportOriginalDSA(*this, DSAStack, D, DVar); 8876 continue; 8877 } 8878 } 8879 8880 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 8881 // A list item that is private within a teams region must not appear in a 8882 // firstprivate clause on a distribute construct if any of the distribute 8883 // regions arising from the distribute construct ever bind to any of the 8884 // teams regions arising from the teams construct. 8885 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 8886 // A list item that appears in a reduction clause of a teams construct 8887 // must not appear in a firstprivate clause on a distribute construct if 8888 // any of the distribute regions arising from the distribute construct 8889 // ever bind to any of the teams regions arising from the teams construct. 8890 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 8891 // A list item may appear in a firstprivate or lastprivate clause but not 8892 // both. 8893 if (CurrDir == OMPD_distribute) { 8894 DVar = DSAStack->hasInnermostDSA( 8895 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_private; }, 8896 [](OpenMPDirectiveKind K) -> bool { 8897 return isOpenMPTeamsDirective(K); 8898 }, 8899 false); 8900 if (DVar.CKind == OMPC_private && isOpenMPTeamsDirective(DVar.DKind)) { 8901 Diag(ELoc, diag::err_omp_firstprivate_distribute_private_teams); 8902 ReportOriginalDSA(*this, DSAStack, D, DVar); 8903 continue; 8904 } 8905 DVar = DSAStack->hasInnermostDSA( 8906 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 8907 [](OpenMPDirectiveKind K) -> bool { 8908 return isOpenMPTeamsDirective(K); 8909 }, 8910 false); 8911 if (DVar.CKind == OMPC_reduction && 8912 isOpenMPTeamsDirective(DVar.DKind)) { 8913 Diag(ELoc, diag::err_omp_firstprivate_distribute_in_teams_reduction); 8914 ReportOriginalDSA(*this, DSAStack, D, DVar); 8915 continue; 8916 } 8917 DVar = DSAStack->getTopDSA(D, false); 8918 if (DVar.CKind == OMPC_lastprivate) { 8919 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); 8920 ReportOriginalDSA(*this, DSAStack, D, DVar); 8921 continue; 8922 } 8923 } 8924 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 8925 // A list item cannot appear in both a map clause and a data-sharing 8926 // attribute clause on the same construct 8927 if (CurrDir == OMPD_target) { 8928 OpenMPClauseKind ConflictKind; 8929 if (DSAStack->checkMappableExprComponentListsForDecl( 8930 VD, /*CurrentRegionOnly=*/true, 8931 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 8932 OpenMPClauseKind WhereFoundClauseKind) -> bool { 8933 ConflictKind = WhereFoundClauseKind; 8934 return true; 8935 })) { 8936 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 8937 << getOpenMPClauseName(OMPC_firstprivate) 8938 << getOpenMPClauseName(ConflictKind) 8939 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 8940 ReportOriginalDSA(*this, DSAStack, D, DVar); 8941 continue; 8942 } 8943 } 8944 } 8945 8946 // Variably modified types are not supported for tasks. 8947 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 8948 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 8949 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 8950 << getOpenMPClauseName(OMPC_firstprivate) << Type 8951 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 8952 bool IsDecl = 8953 !VD || 8954 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8955 Diag(D->getLocation(), 8956 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8957 << D; 8958 continue; 8959 } 8960 8961 Type = Type.getUnqualifiedType(); 8962 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 8963 D->hasAttrs() ? &D->getAttrs() : nullptr); 8964 // Generate helper private variable and initialize it with the value of the 8965 // original variable. The address of the original variable is replaced by 8966 // the address of the new private variable in the CodeGen. This new variable 8967 // is not added to IdResolver, so the code in the OpenMP region uses 8968 // original variable for proper diagnostics and variable capturing. 8969 Expr *VDInitRefExpr = nullptr; 8970 // For arrays generate initializer for single element and replace it by the 8971 // original array element in CodeGen. 8972 if (Type->isArrayType()) { 8973 auto VDInit = 8974 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 8975 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 8976 auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); 8977 ElemType = ElemType.getUnqualifiedType(); 8978 auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 8979 ".firstprivate.temp"); 8980 InitializedEntity Entity = 8981 InitializedEntity::InitializeVariable(VDInitTemp); 8982 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 8983 8984 InitializationSequence InitSeq(*this, Entity, Kind, Init); 8985 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 8986 if (Result.isInvalid()) 8987 VDPrivate->setInvalidDecl(); 8988 else 8989 VDPrivate->setInit(Result.getAs<Expr>()); 8990 // Remove temp variable declaration. 8991 Context.Deallocate(VDInitTemp); 8992 } else { 8993 auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 8994 ".firstprivate.temp"); 8995 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 8996 RefExpr->getExprLoc()); 8997 AddInitializerToDecl(VDPrivate, 8998 DefaultLvalueConversion(VDInitRefExpr).get(), 8999 /*DirectInit=*/false, /*TypeMayContainAuto=*/false); 9000 } 9001 if (VDPrivate->isInvalidDecl()) { 9002 if (IsImplicitClause) { 9003 Diag(RefExpr->getExprLoc(), 9004 diag::note_omp_task_predetermined_firstprivate_here); 9005 } 9006 continue; 9007 } 9008 CurContext->addDecl(VDPrivate); 9009 auto VDPrivateRefExpr = buildDeclRefExpr( 9010 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 9011 RefExpr->getExprLoc()); 9012 DeclRefExpr *Ref = nullptr; 9013 if (!VD && !CurContext->isDependentContext()) { 9014 if (TopDVar.CKind == OMPC_lastprivate) 9015 Ref = TopDVar.PrivateCopy; 9016 else { 9017 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 9018 if (!IsOpenMPCapturedDecl(D)) 9019 ExprCaptures.push_back(Ref->getDecl()); 9020 } 9021 } 9022 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 9023 Vars.push_back((VD || CurContext->isDependentContext()) 9024 ? RefExpr->IgnoreParens() 9025 : Ref); 9026 PrivateCopies.push_back(VDPrivateRefExpr); 9027 Inits.push_back(VDInitRefExpr); 9028 } 9029 9030 if (Vars.empty()) 9031 return nullptr; 9032 9033 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9034 Vars, PrivateCopies, Inits, 9035 buildPreInits(Context, ExprCaptures)); 9036 } 9037 9038 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 9039 SourceLocation StartLoc, 9040 SourceLocation LParenLoc, 9041 SourceLocation EndLoc) { 9042 SmallVector<Expr *, 8> Vars; 9043 SmallVector<Expr *, 8> SrcExprs; 9044 SmallVector<Expr *, 8> DstExprs; 9045 SmallVector<Expr *, 8> AssignmentOps; 9046 SmallVector<Decl *, 4> ExprCaptures; 9047 SmallVector<Expr *, 4> ExprPostUpdates; 9048 for (auto &RefExpr : VarList) { 9049 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 9050 SourceLocation ELoc; 9051 SourceRange ERange; 9052 Expr *SimpleRefExpr = RefExpr; 9053 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9054 if (Res.second) { 9055 // It will be analyzed later. 9056 Vars.push_back(RefExpr); 9057 SrcExprs.push_back(nullptr); 9058 DstExprs.push_back(nullptr); 9059 AssignmentOps.push_back(nullptr); 9060 } 9061 ValueDecl *D = Res.first; 9062 if (!D) 9063 continue; 9064 9065 QualType Type = D->getType(); 9066 auto *VD = dyn_cast<VarDecl>(D); 9067 9068 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 9069 // A variable that appears in a lastprivate clause must not have an 9070 // incomplete type or a reference type. 9071 if (RequireCompleteType(ELoc, Type, 9072 diag::err_omp_lastprivate_incomplete_type)) 9073 continue; 9074 Type = Type.getNonReferenceType(); 9075 9076 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 9077 // in a Construct] 9078 // Variables with the predetermined data-sharing attributes may not be 9079 // listed in data-sharing attributes clauses, except for the cases 9080 // listed below. 9081 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 9082 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 9083 DVar.CKind != OMPC_firstprivate && 9084 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 9085 Diag(ELoc, diag::err_omp_wrong_dsa) 9086 << getOpenMPClauseName(DVar.CKind) 9087 << getOpenMPClauseName(OMPC_lastprivate); 9088 ReportOriginalDSA(*this, DSAStack, D, DVar); 9089 continue; 9090 } 9091 9092 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 9093 // OpenMP [2.14.3.5, Restrictions, p.2] 9094 // A list item that is private within a parallel region, or that appears in 9095 // the reduction clause of a parallel construct, must not appear in a 9096 // lastprivate clause on a worksharing construct if any of the corresponding 9097 // worksharing regions ever binds to any of the corresponding parallel 9098 // regions. 9099 DSAStackTy::DSAVarData TopDVar = DVar; 9100 if (isOpenMPWorksharingDirective(CurrDir) && 9101 !isOpenMPParallelDirective(CurrDir)) { 9102 DVar = DSAStack->getImplicitDSA(D, true); 9103 if (DVar.CKind != OMPC_shared) { 9104 Diag(ELoc, diag::err_omp_required_access) 9105 << getOpenMPClauseName(OMPC_lastprivate) 9106 << getOpenMPClauseName(OMPC_shared); 9107 ReportOriginalDSA(*this, DSAStack, D, DVar); 9108 continue; 9109 } 9110 } 9111 9112 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 9113 // A list item may appear in a firstprivate or lastprivate clause but not 9114 // both. 9115 if (CurrDir == OMPD_distribute) { 9116 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 9117 if (DVar.CKind == OMPC_firstprivate) { 9118 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); 9119 ReportOriginalDSA(*this, DSAStack, D, DVar); 9120 continue; 9121 } 9122 } 9123 9124 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 9125 // A variable of class type (or array thereof) that appears in a 9126 // lastprivate clause requires an accessible, unambiguous default 9127 // constructor for the class type, unless the list item is also specified 9128 // in a firstprivate clause. 9129 // A variable of class type (or array thereof) that appears in a 9130 // lastprivate clause requires an accessible, unambiguous copy assignment 9131 // operator for the class type. 9132 Type = Context.getBaseElementType(Type).getNonReferenceType(); 9133 auto *SrcVD = buildVarDecl(*this, ERange.getBegin(), 9134 Type.getUnqualifiedType(), ".lastprivate.src", 9135 D->hasAttrs() ? &D->getAttrs() : nullptr); 9136 auto *PseudoSrcExpr = 9137 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 9138 auto *DstVD = 9139 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 9140 D->hasAttrs() ? &D->getAttrs() : nullptr); 9141 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 9142 // For arrays generate assignment operation for single element and replace 9143 // it by the original array element in CodeGen. 9144 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 9145 PseudoDstExpr, PseudoSrcExpr); 9146 if (AssignmentOp.isInvalid()) 9147 continue; 9148 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 9149 /*DiscardedValue=*/true); 9150 if (AssignmentOp.isInvalid()) 9151 continue; 9152 9153 DeclRefExpr *Ref = nullptr; 9154 if (!VD && !CurContext->isDependentContext()) { 9155 if (TopDVar.CKind == OMPC_firstprivate) 9156 Ref = TopDVar.PrivateCopy; 9157 else { 9158 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 9159 if (!IsOpenMPCapturedDecl(D)) 9160 ExprCaptures.push_back(Ref->getDecl()); 9161 } 9162 if (TopDVar.CKind == OMPC_firstprivate || 9163 (!IsOpenMPCapturedDecl(D) && 9164 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 9165 ExprResult RefRes = DefaultLvalueConversion(Ref); 9166 if (!RefRes.isUsable()) 9167 continue; 9168 ExprResult PostUpdateRes = 9169 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 9170 RefRes.get()); 9171 if (!PostUpdateRes.isUsable()) 9172 continue; 9173 ExprPostUpdates.push_back( 9174 IgnoredValueConversions(PostUpdateRes.get()).get()); 9175 } 9176 } 9177 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 9178 Vars.push_back((VD || CurContext->isDependentContext()) 9179 ? RefExpr->IgnoreParens() 9180 : Ref); 9181 SrcExprs.push_back(PseudoSrcExpr); 9182 DstExprs.push_back(PseudoDstExpr); 9183 AssignmentOps.push_back(AssignmentOp.get()); 9184 } 9185 9186 if (Vars.empty()) 9187 return nullptr; 9188 9189 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9190 Vars, SrcExprs, DstExprs, AssignmentOps, 9191 buildPreInits(Context, ExprCaptures), 9192 buildPostUpdate(*this, ExprPostUpdates)); 9193 } 9194 9195 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 9196 SourceLocation StartLoc, 9197 SourceLocation LParenLoc, 9198 SourceLocation EndLoc) { 9199 SmallVector<Expr *, 8> Vars; 9200 for (auto &RefExpr : VarList) { 9201 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 9202 SourceLocation ELoc; 9203 SourceRange ERange; 9204 Expr *SimpleRefExpr = RefExpr; 9205 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 9206 if (Res.second) { 9207 // It will be analyzed later. 9208 Vars.push_back(RefExpr); 9209 } 9210 ValueDecl *D = Res.first; 9211 if (!D) 9212 continue; 9213 9214 auto *VD = dyn_cast<VarDecl>(D); 9215 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 9216 // in a Construct] 9217 // Variables with the predetermined data-sharing attributes may not be 9218 // listed in data-sharing attributes clauses, except for the cases 9219 // listed below. For these exceptions only, listing a predetermined 9220 // variable in a data-sharing attribute clause is allowed and overrides 9221 // the variable's predetermined data-sharing attributes. 9222 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 9223 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 9224 DVar.RefExpr) { 9225 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 9226 << getOpenMPClauseName(OMPC_shared); 9227 ReportOriginalDSA(*this, DSAStack, D, DVar); 9228 continue; 9229 } 9230 9231 DeclRefExpr *Ref = nullptr; 9232 if (!VD && IsOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 9233 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 9234 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 9235 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 9236 ? RefExpr->IgnoreParens() 9237 : Ref); 9238 } 9239 9240 if (Vars.empty()) 9241 return nullptr; 9242 9243 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 9244 } 9245 9246 namespace { 9247 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 9248 DSAStackTy *Stack; 9249 9250 public: 9251 bool VisitDeclRefExpr(DeclRefExpr *E) { 9252 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { 9253 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false); 9254 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 9255 return false; 9256 if (DVar.CKind != OMPC_unknown) 9257 return true; 9258 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 9259 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, 9260 false); 9261 if (DVarPrivate.CKind != OMPC_unknown) 9262 return true; 9263 return false; 9264 } 9265 return false; 9266 } 9267 bool VisitStmt(Stmt *S) { 9268 for (auto Child : S->children()) { 9269 if (Child && Visit(Child)) 9270 return true; 9271 } 9272 return false; 9273 } 9274 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 9275 }; 9276 } // namespace 9277 9278 namespace { 9279 // Transform MemberExpression for specified FieldDecl of current class to 9280 // DeclRefExpr to specified OMPCapturedExprDecl. 9281 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 9282 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 9283 ValueDecl *Field; 9284 DeclRefExpr *CapturedExpr; 9285 9286 public: 9287 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 9288 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 9289 9290 ExprResult TransformMemberExpr(MemberExpr *E) { 9291 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 9292 E->getMemberDecl() == Field) { 9293 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 9294 return CapturedExpr; 9295 } 9296 return BaseTransform::TransformMemberExpr(E); 9297 } 9298 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 9299 }; 9300 } // namespace 9301 9302 template <typename T> 9303 static T filterLookupForUDR(SmallVectorImpl<UnresolvedSet<8>> &Lookups, 9304 const llvm::function_ref<T(ValueDecl *)> &Gen) { 9305 for (auto &Set : Lookups) { 9306 for (auto *D : Set) { 9307 if (auto Res = Gen(cast<ValueDecl>(D))) 9308 return Res; 9309 } 9310 } 9311 return T(); 9312 } 9313 9314 static ExprResult 9315 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 9316 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 9317 const DeclarationNameInfo &ReductionId, QualType Ty, 9318 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 9319 if (ReductionIdScopeSpec.isInvalid()) 9320 return ExprError(); 9321 SmallVector<UnresolvedSet<8>, 4> Lookups; 9322 if (S) { 9323 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 9324 Lookup.suppressDiagnostics(); 9325 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 9326 auto *D = Lookup.getRepresentativeDecl(); 9327 do { 9328 S = S->getParent(); 9329 } while (S && !S->isDeclScope(D)); 9330 if (S) 9331 S = S->getParent(); 9332 Lookups.push_back(UnresolvedSet<8>()); 9333 Lookups.back().append(Lookup.begin(), Lookup.end()); 9334 Lookup.clear(); 9335 } 9336 } else if (auto *ULE = 9337 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 9338 Lookups.push_back(UnresolvedSet<8>()); 9339 Decl *PrevD = nullptr; 9340 for (auto *D : ULE->decls()) { 9341 if (D == PrevD) 9342 Lookups.push_back(UnresolvedSet<8>()); 9343 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) 9344 Lookups.back().addDecl(DRD); 9345 PrevD = D; 9346 } 9347 } 9348 if (Ty->isDependentType() || Ty->isInstantiationDependentType() || 9349 Ty->containsUnexpandedParameterPack() || 9350 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool { 9351 return !D->isInvalidDecl() && 9352 (D->getType()->isDependentType() || 9353 D->getType()->isInstantiationDependentType() || 9354 D->getType()->containsUnexpandedParameterPack()); 9355 })) { 9356 UnresolvedSet<8> ResSet; 9357 for (auto &Set : Lookups) { 9358 ResSet.append(Set.begin(), Set.end()); 9359 // The last item marks the end of all declarations at the specified scope. 9360 ResSet.addDecl(Set[Set.size() - 1]); 9361 } 9362 return UnresolvedLookupExpr::Create( 9363 SemaRef.Context, /*NamingClass=*/nullptr, 9364 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 9365 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 9366 } 9367 if (auto *VD = filterLookupForUDR<ValueDecl *>( 9368 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 9369 if (!D->isInvalidDecl() && 9370 SemaRef.Context.hasSameType(D->getType(), Ty)) 9371 return D; 9372 return nullptr; 9373 })) 9374 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 9375 if (auto *VD = filterLookupForUDR<ValueDecl *>( 9376 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 9377 if (!D->isInvalidDecl() && 9378 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 9379 !Ty.isMoreQualifiedThan(D->getType())) 9380 return D; 9381 return nullptr; 9382 })) { 9383 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 9384 /*DetectVirtual=*/false); 9385 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 9386 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 9387 VD->getType().getUnqualifiedType()))) { 9388 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), 9389 /*DiagID=*/0) != 9390 Sema::AR_inaccessible) { 9391 SemaRef.BuildBasePathArray(Paths, BasePath); 9392 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 9393 } 9394 } 9395 } 9396 } 9397 if (ReductionIdScopeSpec.isSet()) { 9398 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 9399 return ExprError(); 9400 } 9401 return ExprEmpty(); 9402 } 9403 9404 OMPClause *Sema::ActOnOpenMPReductionClause( 9405 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 9406 SourceLocation ColonLoc, SourceLocation EndLoc, 9407 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 9408 ArrayRef<Expr *> UnresolvedReductions) { 9409 auto DN = ReductionId.getName(); 9410 auto OOK = DN.getCXXOverloadedOperator(); 9411 BinaryOperatorKind BOK = BO_Comma; 9412 9413 // OpenMP [2.14.3.6, reduction clause] 9414 // C 9415 // reduction-identifier is either an identifier or one of the following 9416 // operators: +, -, *, &, |, ^, && and || 9417 // C++ 9418 // reduction-identifier is either an id-expression or one of the following 9419 // operators: +, -, *, &, |, ^, && and || 9420 // FIXME: Only 'min' and 'max' identifiers are supported for now. 9421 switch (OOK) { 9422 case OO_Plus: 9423 case OO_Minus: 9424 BOK = BO_Add; 9425 break; 9426 case OO_Star: 9427 BOK = BO_Mul; 9428 break; 9429 case OO_Amp: 9430 BOK = BO_And; 9431 break; 9432 case OO_Pipe: 9433 BOK = BO_Or; 9434 break; 9435 case OO_Caret: 9436 BOK = BO_Xor; 9437 break; 9438 case OO_AmpAmp: 9439 BOK = BO_LAnd; 9440 break; 9441 case OO_PipePipe: 9442 BOK = BO_LOr; 9443 break; 9444 case OO_New: 9445 case OO_Delete: 9446 case OO_Array_New: 9447 case OO_Array_Delete: 9448 case OO_Slash: 9449 case OO_Percent: 9450 case OO_Tilde: 9451 case OO_Exclaim: 9452 case OO_Equal: 9453 case OO_Less: 9454 case OO_Greater: 9455 case OO_LessEqual: 9456 case OO_GreaterEqual: 9457 case OO_PlusEqual: 9458 case OO_MinusEqual: 9459 case OO_StarEqual: 9460 case OO_SlashEqual: 9461 case OO_PercentEqual: 9462 case OO_CaretEqual: 9463 case OO_AmpEqual: 9464 case OO_PipeEqual: 9465 case OO_LessLess: 9466 case OO_GreaterGreater: 9467 case OO_LessLessEqual: 9468 case OO_GreaterGreaterEqual: 9469 case OO_EqualEqual: 9470 case OO_ExclaimEqual: 9471 case OO_PlusPlus: 9472 case OO_MinusMinus: 9473 case OO_Comma: 9474 case OO_ArrowStar: 9475 case OO_Arrow: 9476 case OO_Call: 9477 case OO_Subscript: 9478 case OO_Conditional: 9479 case OO_Coawait: 9480 case NUM_OVERLOADED_OPERATORS: 9481 llvm_unreachable("Unexpected reduction identifier"); 9482 case OO_None: 9483 if (auto II = DN.getAsIdentifierInfo()) { 9484 if (II->isStr("max")) 9485 BOK = BO_GT; 9486 else if (II->isStr("min")) 9487 BOK = BO_LT; 9488 } 9489 break; 9490 } 9491 SourceRange ReductionIdRange; 9492 if (ReductionIdScopeSpec.isValid()) 9493 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 9494 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 9495 9496 SmallVector<Expr *, 8> Vars; 9497 SmallVector<Expr *, 8> Privates; 9498 SmallVector<Expr *, 8> LHSs; 9499 SmallVector<Expr *, 8> RHSs; 9500 SmallVector<Expr *, 8> ReductionOps; 9501 SmallVector<Decl *, 4> ExprCaptures; 9502 SmallVector<Expr *, 4> ExprPostUpdates; 9503 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 9504 bool FirstIter = true; 9505 for (auto RefExpr : VarList) { 9506 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 9507 // OpenMP [2.1, C/C++] 9508 // A list item is a variable or array section, subject to the restrictions 9509 // specified in Section 2.4 on page 42 and in each of the sections 9510 // describing clauses and directives for which a list appears. 9511 // OpenMP [2.14.3.3, Restrictions, p.1] 9512 // A variable that is part of another variable (as an array or 9513 // structure element) cannot appear in a private clause. 9514 if (!FirstIter && IR != ER) 9515 ++IR; 9516 FirstIter = false; 9517 SourceLocation ELoc; 9518 SourceRange ERange; 9519 Expr *SimpleRefExpr = RefExpr; 9520 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 9521 /*AllowArraySection=*/true); 9522 if (Res.second) { 9523 // It will be analyzed later. 9524 Vars.push_back(RefExpr); 9525 Privates.push_back(nullptr); 9526 LHSs.push_back(nullptr); 9527 RHSs.push_back(nullptr); 9528 // Try to find 'declare reduction' corresponding construct before using 9529 // builtin/overloaded operators. 9530 QualType Type = Context.DependentTy; 9531 CXXCastPath BasePath; 9532 ExprResult DeclareReductionRef = buildDeclareReductionRef( 9533 *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, 9534 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 9535 if (CurContext->isDependentContext() && 9536 (DeclareReductionRef.isUnset() || 9537 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 9538 ReductionOps.push_back(DeclareReductionRef.get()); 9539 else 9540 ReductionOps.push_back(nullptr); 9541 } 9542 ValueDecl *D = Res.first; 9543 if (!D) 9544 continue; 9545 9546 QualType Type; 9547 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 9548 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 9549 if (ASE) 9550 Type = ASE->getType().getNonReferenceType(); 9551 else if (OASE) { 9552 auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 9553 if (auto *ATy = BaseType->getAsArrayTypeUnsafe()) 9554 Type = ATy->getElementType(); 9555 else 9556 Type = BaseType->getPointeeType(); 9557 Type = Type.getNonReferenceType(); 9558 } else 9559 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 9560 auto *VD = dyn_cast<VarDecl>(D); 9561 9562 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 9563 // A variable that appears in a private clause must not have an incomplete 9564 // type or a reference type. 9565 if (RequireCompleteType(ELoc, Type, 9566 diag::err_omp_reduction_incomplete_type)) 9567 continue; 9568 // OpenMP [2.14.3.6, reduction clause, Restrictions] 9569 // A list item that appears in a reduction clause must not be 9570 // const-qualified. 9571 if (Type.getNonReferenceType().isConstant(Context)) { 9572 Diag(ELoc, diag::err_omp_const_reduction_list_item) 9573 << getOpenMPClauseName(OMPC_reduction) << Type << ERange; 9574 if (!ASE && !OASE) { 9575 bool IsDecl = !VD || 9576 VD->isThisDeclarationADefinition(Context) == 9577 VarDecl::DeclarationOnly; 9578 Diag(D->getLocation(), 9579 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9580 << D; 9581 } 9582 continue; 9583 } 9584 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 9585 // If a list-item is a reference type then it must bind to the same object 9586 // for all threads of the team. 9587 if (!ASE && !OASE && VD) { 9588 VarDecl *VDDef = VD->getDefinition(); 9589 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 9590 DSARefChecker Check(DSAStack); 9591 if (Check.Visit(VDDef->getInit())) { 9592 Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; 9593 Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 9594 continue; 9595 } 9596 } 9597 } 9598 9599 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 9600 // in a Construct] 9601 // Variables with the predetermined data-sharing attributes may not be 9602 // listed in data-sharing attributes clauses, except for the cases 9603 // listed below. For these exceptions only, listing a predetermined 9604 // variable in a data-sharing attribute clause is allowed and overrides 9605 // the variable's predetermined data-sharing attributes. 9606 // OpenMP [2.14.3.6, Restrictions, p.3] 9607 // Any number of reduction clauses can be specified on the directive, 9608 // but a list item can appear only once in the reduction clauses for that 9609 // directive. 9610 DSAStackTy::DSAVarData DVar; 9611 DVar = DSAStack->getTopDSA(D, false); 9612 if (DVar.CKind == OMPC_reduction) { 9613 Diag(ELoc, diag::err_omp_once_referenced) 9614 << getOpenMPClauseName(OMPC_reduction); 9615 if (DVar.RefExpr) 9616 Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 9617 } else if (DVar.CKind != OMPC_unknown) { 9618 Diag(ELoc, diag::err_omp_wrong_dsa) 9619 << getOpenMPClauseName(DVar.CKind) 9620 << getOpenMPClauseName(OMPC_reduction); 9621 ReportOriginalDSA(*this, DSAStack, D, DVar); 9622 continue; 9623 } 9624 9625 // OpenMP [2.14.3.6, Restrictions, p.1] 9626 // A list item that appears in a reduction clause of a worksharing 9627 // construct must be shared in the parallel regions to which any of the 9628 // worksharing regions arising from the worksharing construct bind. 9629 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 9630 if (isOpenMPWorksharingDirective(CurrDir) && 9631 !isOpenMPParallelDirective(CurrDir)) { 9632 DVar = DSAStack->getImplicitDSA(D, true); 9633 if (DVar.CKind != OMPC_shared) { 9634 Diag(ELoc, diag::err_omp_required_access) 9635 << getOpenMPClauseName(OMPC_reduction) 9636 << getOpenMPClauseName(OMPC_shared); 9637 ReportOriginalDSA(*this, DSAStack, D, DVar); 9638 continue; 9639 } 9640 } 9641 9642 // Try to find 'declare reduction' corresponding construct before using 9643 // builtin/overloaded operators. 9644 CXXCastPath BasePath; 9645 ExprResult DeclareReductionRef = buildDeclareReductionRef( 9646 *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, 9647 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 9648 if (DeclareReductionRef.isInvalid()) 9649 continue; 9650 if (CurContext->isDependentContext() && 9651 (DeclareReductionRef.isUnset() || 9652 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 9653 Vars.push_back(RefExpr); 9654 Privates.push_back(nullptr); 9655 LHSs.push_back(nullptr); 9656 RHSs.push_back(nullptr); 9657 ReductionOps.push_back(DeclareReductionRef.get()); 9658 continue; 9659 } 9660 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 9661 // Not allowed reduction identifier is found. 9662 Diag(ReductionId.getLocStart(), 9663 diag::err_omp_unknown_reduction_identifier) 9664 << Type << ReductionIdRange; 9665 continue; 9666 } 9667 9668 // OpenMP [2.14.3.6, reduction clause, Restrictions] 9669 // The type of a list item that appears in a reduction clause must be valid 9670 // for the reduction-identifier. For a max or min reduction in C, the type 9671 // of the list item must be an allowed arithmetic data type: char, int, 9672 // float, double, or _Bool, possibly modified with long, short, signed, or 9673 // unsigned. For a max or min reduction in C++, the type of the list item 9674 // must be an allowed arithmetic data type: char, wchar_t, int, float, 9675 // double, or bool, possibly modified with long, short, signed, or unsigned. 9676 if (DeclareReductionRef.isUnset()) { 9677 if ((BOK == BO_GT || BOK == BO_LT) && 9678 !(Type->isScalarType() || 9679 (getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 9680 Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 9681 << getLangOpts().CPlusPlus; 9682 if (!ASE && !OASE) { 9683 bool IsDecl = !VD || 9684 VD->isThisDeclarationADefinition(Context) == 9685 VarDecl::DeclarationOnly; 9686 Diag(D->getLocation(), 9687 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9688 << D; 9689 } 9690 continue; 9691 } 9692 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 9693 !getLangOpts().CPlusPlus && Type->isFloatingType()) { 9694 Diag(ELoc, diag::err_omp_clause_floating_type_arg); 9695 if (!ASE && !OASE) { 9696 bool IsDecl = !VD || 9697 VD->isThisDeclarationADefinition(Context) == 9698 VarDecl::DeclarationOnly; 9699 Diag(D->getLocation(), 9700 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9701 << D; 9702 } 9703 continue; 9704 } 9705 } 9706 9707 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 9708 auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs", 9709 D->hasAttrs() ? &D->getAttrs() : nullptr); 9710 auto *RHSVD = buildVarDecl(*this, ELoc, Type, D->getName(), 9711 D->hasAttrs() ? &D->getAttrs() : nullptr); 9712 auto PrivateTy = Type; 9713 if (OASE || 9714 (!ASE && 9715 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 9716 // For arrays/array sections only: 9717 // Create pseudo array type for private copy. The size for this array will 9718 // be generated during codegen. 9719 // For array subscripts or single variables Private Ty is the same as Type 9720 // (type of the variable or single array element). 9721 PrivateTy = Context.getVariableArrayType( 9722 Type, new (Context) OpaqueValueExpr(SourceLocation(), 9723 Context.getSizeType(), VK_RValue), 9724 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 9725 } else if (!ASE && !OASE && 9726 Context.getAsArrayType(D->getType().getNonReferenceType())) 9727 PrivateTy = D->getType().getNonReferenceType(); 9728 // Private copy. 9729 auto *PrivateVD = buildVarDecl(*this, ELoc, PrivateTy, D->getName(), 9730 D->hasAttrs() ? &D->getAttrs() : nullptr); 9731 // Add initializer for private variable. 9732 Expr *Init = nullptr; 9733 auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc); 9734 auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc); 9735 if (DeclareReductionRef.isUsable()) { 9736 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 9737 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 9738 if (DRD->getInitializer()) { 9739 Init = DRDRef; 9740 RHSVD->setInit(DRDRef); 9741 RHSVD->setInitStyle(VarDecl::CallInit); 9742 } 9743 } else { 9744 switch (BOK) { 9745 case BO_Add: 9746 case BO_Xor: 9747 case BO_Or: 9748 case BO_LOr: 9749 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 9750 if (Type->isScalarType() || Type->isAnyComplexType()) 9751 Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 9752 break; 9753 case BO_Mul: 9754 case BO_LAnd: 9755 if (Type->isScalarType() || Type->isAnyComplexType()) { 9756 // '*' and '&&' reduction ops - initializer is '1'. 9757 Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 9758 } 9759 break; 9760 case BO_And: { 9761 // '&' reduction op - initializer is '~0'. 9762 QualType OrigType = Type; 9763 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 9764 Type = ComplexTy->getElementType(); 9765 if (Type->isRealFloatingType()) { 9766 llvm::APFloat InitValue = 9767 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 9768 /*isIEEE=*/true); 9769 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 9770 Type, ELoc); 9771 } else if (Type->isScalarType()) { 9772 auto Size = Context.getTypeSize(Type); 9773 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 9774 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 9775 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 9776 } 9777 if (Init && OrigType->isAnyComplexType()) { 9778 // Init = 0xFFFF + 0xFFFFi; 9779 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 9780 Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 9781 } 9782 Type = OrigType; 9783 break; 9784 } 9785 case BO_LT: 9786 case BO_GT: { 9787 // 'min' reduction op - initializer is 'Largest representable number in 9788 // the reduction list item type'. 9789 // 'max' reduction op - initializer is 'Least representable number in 9790 // the reduction list item type'. 9791 if (Type->isIntegerType() || Type->isPointerType()) { 9792 bool IsSigned = Type->hasSignedIntegerRepresentation(); 9793 auto Size = Context.getTypeSize(Type); 9794 QualType IntTy = 9795 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 9796 llvm::APInt InitValue = 9797 (BOK != BO_LT) 9798 ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 9799 : llvm::APInt::getMinValue(Size) 9800 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 9801 : llvm::APInt::getMaxValue(Size); 9802 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 9803 if (Type->isPointerType()) { 9804 // Cast to pointer type. 9805 auto CastExpr = BuildCStyleCastExpr( 9806 SourceLocation(), Context.getTrivialTypeSourceInfo(Type, ELoc), 9807 SourceLocation(), Init); 9808 if (CastExpr.isInvalid()) 9809 continue; 9810 Init = CastExpr.get(); 9811 } 9812 } else if (Type->isRealFloatingType()) { 9813 llvm::APFloat InitValue = llvm::APFloat::getLargest( 9814 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 9815 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 9816 Type, ELoc); 9817 } 9818 break; 9819 } 9820 case BO_PtrMemD: 9821 case BO_PtrMemI: 9822 case BO_MulAssign: 9823 case BO_Div: 9824 case BO_Rem: 9825 case BO_Sub: 9826 case BO_Shl: 9827 case BO_Shr: 9828 case BO_LE: 9829 case BO_GE: 9830 case BO_EQ: 9831 case BO_NE: 9832 case BO_AndAssign: 9833 case BO_XorAssign: 9834 case BO_OrAssign: 9835 case BO_Assign: 9836 case BO_AddAssign: 9837 case BO_SubAssign: 9838 case BO_DivAssign: 9839 case BO_RemAssign: 9840 case BO_ShlAssign: 9841 case BO_ShrAssign: 9842 case BO_Comma: 9843 llvm_unreachable("Unexpected reduction operation"); 9844 } 9845 } 9846 if (Init && DeclareReductionRef.isUnset()) { 9847 AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false, 9848 /*TypeMayContainAuto=*/false); 9849 } else if (!Init) 9850 ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false); 9851 if (RHSVD->isInvalidDecl()) 9852 continue; 9853 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 9854 Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type 9855 << ReductionIdRange; 9856 bool IsDecl = 9857 !VD || 9858 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9859 Diag(D->getLocation(), 9860 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9861 << D; 9862 continue; 9863 } 9864 // Store initializer for single element in private copy. Will be used during 9865 // codegen. 9866 PrivateVD->setInit(RHSVD->getInit()); 9867 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 9868 auto *PrivateDRE = buildDeclRefExpr(*this, PrivateVD, PrivateTy, ELoc); 9869 ExprResult ReductionOp; 9870 if (DeclareReductionRef.isUsable()) { 9871 QualType RedTy = DeclareReductionRef.get()->getType(); 9872 QualType PtrRedTy = Context.getPointerType(RedTy); 9873 ExprResult LHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 9874 ExprResult RHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 9875 if (!BasePath.empty()) { 9876 LHS = DefaultLvalueConversion(LHS.get()); 9877 RHS = DefaultLvalueConversion(RHS.get()); 9878 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 9879 CK_UncheckedDerivedToBase, LHS.get(), 9880 &BasePath, LHS.get()->getValueKind()); 9881 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 9882 CK_UncheckedDerivedToBase, RHS.get(), 9883 &BasePath, RHS.get()->getValueKind()); 9884 } 9885 FunctionProtoType::ExtProtoInfo EPI; 9886 QualType Params[] = {PtrRedTy, PtrRedTy}; 9887 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 9888 auto *OVE = new (Context) OpaqueValueExpr( 9889 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 9890 DefaultLvalueConversion(DeclareReductionRef.get()).get()); 9891 Expr *Args[] = {LHS.get(), RHS.get()}; 9892 ReductionOp = new (Context) 9893 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 9894 } else { 9895 ReductionOp = BuildBinOp(DSAStack->getCurScope(), 9896 ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE); 9897 if (ReductionOp.isUsable()) { 9898 if (BOK != BO_LT && BOK != BO_GT) { 9899 ReductionOp = 9900 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 9901 BO_Assign, LHSDRE, ReductionOp.get()); 9902 } else { 9903 auto *ConditionalOp = new (Context) ConditionalOperator( 9904 ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(), 9905 RHSDRE, Type, VK_LValue, OK_Ordinary); 9906 ReductionOp = 9907 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 9908 BO_Assign, LHSDRE, ConditionalOp); 9909 } 9910 ReductionOp = ActOnFinishFullExpr(ReductionOp.get()); 9911 } 9912 if (ReductionOp.isInvalid()) 9913 continue; 9914 } 9915 9916 DeclRefExpr *Ref = nullptr; 9917 Expr *VarsExpr = RefExpr->IgnoreParens(); 9918 if (!VD && !CurContext->isDependentContext()) { 9919 if (ASE || OASE) { 9920 TransformExprToCaptures RebuildToCapture(*this, D); 9921 VarsExpr = 9922 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 9923 Ref = RebuildToCapture.getCapturedExpr(); 9924 } else { 9925 VarsExpr = Ref = 9926 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 9927 } 9928 if (!IsOpenMPCapturedDecl(D)) { 9929 ExprCaptures.push_back(Ref->getDecl()); 9930 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 9931 ExprResult RefRes = DefaultLvalueConversion(Ref); 9932 if (!RefRes.isUsable()) 9933 continue; 9934 ExprResult PostUpdateRes = 9935 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 9936 SimpleRefExpr, RefRes.get()); 9937 if (!PostUpdateRes.isUsable()) 9938 continue; 9939 ExprPostUpdates.push_back( 9940 IgnoredValueConversions(PostUpdateRes.get()).get()); 9941 } 9942 } 9943 } 9944 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 9945 Vars.push_back(VarsExpr); 9946 Privates.push_back(PrivateDRE); 9947 LHSs.push_back(LHSDRE); 9948 RHSs.push_back(RHSDRE); 9949 ReductionOps.push_back(ReductionOp.get()); 9950 } 9951 9952 if (Vars.empty()) 9953 return nullptr; 9954 9955 return OMPReductionClause::Create( 9956 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars, 9957 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates, 9958 LHSs, RHSs, ReductionOps, buildPreInits(Context, ExprCaptures), 9959 buildPostUpdate(*this, ExprPostUpdates)); 9960 } 9961 9962 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 9963 SourceLocation LinLoc) { 9964 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 9965 LinKind == OMPC_LINEAR_unknown) { 9966 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 9967 return true; 9968 } 9969 return false; 9970 } 9971 9972 bool Sema::CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, 9973 OpenMPLinearClauseKind LinKind, 9974 QualType Type) { 9975 auto *VD = dyn_cast_or_null<VarDecl>(D); 9976 // A variable must not have an incomplete type or a reference type. 9977 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 9978 return true; 9979 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 9980 !Type->isReferenceType()) { 9981 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 9982 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 9983 return true; 9984 } 9985 Type = Type.getNonReferenceType(); 9986 9987 // A list item must not be const-qualified. 9988 if (Type.isConstant(Context)) { 9989 Diag(ELoc, diag::err_omp_const_variable) 9990 << getOpenMPClauseName(OMPC_linear); 9991 if (D) { 9992 bool IsDecl = 9993 !VD || 9994 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9995 Diag(D->getLocation(), 9996 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9997 << D; 9998 } 9999 return true; 10000 } 10001 10002 // A list item must be of integral or pointer type. 10003 Type = Type.getUnqualifiedType().getCanonicalType(); 10004 const auto *Ty = Type.getTypePtrOrNull(); 10005 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 10006 !Ty->isPointerType())) { 10007 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 10008 if (D) { 10009 bool IsDecl = 10010 !VD || 10011 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10012 Diag(D->getLocation(), 10013 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10014 << D; 10015 } 10016 return true; 10017 } 10018 return false; 10019 } 10020 10021 OMPClause *Sema::ActOnOpenMPLinearClause( 10022 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 10023 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 10024 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 10025 SmallVector<Expr *, 8> Vars; 10026 SmallVector<Expr *, 8> Privates; 10027 SmallVector<Expr *, 8> Inits; 10028 SmallVector<Decl *, 4> ExprCaptures; 10029 SmallVector<Expr *, 4> ExprPostUpdates; 10030 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 10031 LinKind = OMPC_LINEAR_val; 10032 for (auto &RefExpr : VarList) { 10033 assert(RefExpr && "NULL expr in OpenMP linear clause."); 10034 SourceLocation ELoc; 10035 SourceRange ERange; 10036 Expr *SimpleRefExpr = RefExpr; 10037 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 10038 /*AllowArraySection=*/false); 10039 if (Res.second) { 10040 // It will be analyzed later. 10041 Vars.push_back(RefExpr); 10042 Privates.push_back(nullptr); 10043 Inits.push_back(nullptr); 10044 } 10045 ValueDecl *D = Res.first; 10046 if (!D) 10047 continue; 10048 10049 QualType Type = D->getType(); 10050 auto *VD = dyn_cast<VarDecl>(D); 10051 10052 // OpenMP [2.14.3.7, linear clause] 10053 // A list-item cannot appear in more than one linear clause. 10054 // A list-item that appears in a linear clause cannot appear in any 10055 // other data-sharing attribute clause. 10056 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 10057 if (DVar.RefExpr) { 10058 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 10059 << getOpenMPClauseName(OMPC_linear); 10060 ReportOriginalDSA(*this, DSAStack, D, DVar); 10061 continue; 10062 } 10063 10064 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 10065 continue; 10066 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 10067 10068 // Build private copy of original var. 10069 auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(), 10070 D->hasAttrs() ? &D->getAttrs() : nullptr); 10071 auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 10072 // Build var to save initial value. 10073 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 10074 Expr *InitExpr; 10075 DeclRefExpr *Ref = nullptr; 10076 if (!VD && !CurContext->isDependentContext()) { 10077 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 10078 if (!IsOpenMPCapturedDecl(D)) { 10079 ExprCaptures.push_back(Ref->getDecl()); 10080 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 10081 ExprResult RefRes = DefaultLvalueConversion(Ref); 10082 if (!RefRes.isUsable()) 10083 continue; 10084 ExprResult PostUpdateRes = 10085 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 10086 SimpleRefExpr, RefRes.get()); 10087 if (!PostUpdateRes.isUsable()) 10088 continue; 10089 ExprPostUpdates.push_back( 10090 IgnoredValueConversions(PostUpdateRes.get()).get()); 10091 } 10092 } 10093 } 10094 if (LinKind == OMPC_LINEAR_uval) 10095 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 10096 else 10097 InitExpr = VD ? SimpleRefExpr : Ref; 10098 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 10099 /*DirectInit=*/false, /*TypeMayContainAuto=*/false); 10100 auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 10101 10102 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 10103 Vars.push_back((VD || CurContext->isDependentContext()) 10104 ? RefExpr->IgnoreParens() 10105 : Ref); 10106 Privates.push_back(PrivateRef); 10107 Inits.push_back(InitRef); 10108 } 10109 10110 if (Vars.empty()) 10111 return nullptr; 10112 10113 Expr *StepExpr = Step; 10114 Expr *CalcStepExpr = nullptr; 10115 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 10116 !Step->isInstantiationDependent() && 10117 !Step->containsUnexpandedParameterPack()) { 10118 SourceLocation StepLoc = Step->getLocStart(); 10119 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 10120 if (Val.isInvalid()) 10121 return nullptr; 10122 StepExpr = Val.get(); 10123 10124 // Build var to save the step value. 10125 VarDecl *SaveVar = 10126 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 10127 ExprResult SaveRef = 10128 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 10129 ExprResult CalcStep = 10130 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 10131 CalcStep = ActOnFinishFullExpr(CalcStep.get()); 10132 10133 // Warn about zero linear step (it would be probably better specified as 10134 // making corresponding variables 'const'). 10135 llvm::APSInt Result; 10136 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 10137 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 10138 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 10139 << (Vars.size() > 1); 10140 if (!IsConstant && CalcStep.isUsable()) { 10141 // Calculate the step beforehand instead of doing this on each iteration. 10142 // (This is not used if the number of iterations may be kfold-ed). 10143 CalcStepExpr = CalcStep.get(); 10144 } 10145 } 10146 10147 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 10148 ColonLoc, EndLoc, Vars, Privates, Inits, 10149 StepExpr, CalcStepExpr, 10150 buildPreInits(Context, ExprCaptures), 10151 buildPostUpdate(*this, ExprPostUpdates)); 10152 } 10153 10154 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 10155 Expr *NumIterations, Sema &SemaRef, 10156 Scope *S, DSAStackTy *Stack) { 10157 // Walk the vars and build update/final expressions for the CodeGen. 10158 SmallVector<Expr *, 8> Updates; 10159 SmallVector<Expr *, 8> Finals; 10160 Expr *Step = Clause.getStep(); 10161 Expr *CalcStep = Clause.getCalcStep(); 10162 // OpenMP [2.14.3.7, linear clause] 10163 // If linear-step is not specified it is assumed to be 1. 10164 if (Step == nullptr) 10165 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 10166 else if (CalcStep) { 10167 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 10168 } 10169 bool HasErrors = false; 10170 auto CurInit = Clause.inits().begin(); 10171 auto CurPrivate = Clause.privates().begin(); 10172 auto LinKind = Clause.getModifier(); 10173 for (auto &RefExpr : Clause.varlists()) { 10174 SourceLocation ELoc; 10175 SourceRange ERange; 10176 Expr *SimpleRefExpr = RefExpr; 10177 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange, 10178 /*AllowArraySection=*/false); 10179 ValueDecl *D = Res.first; 10180 if (Res.second || !D) { 10181 Updates.push_back(nullptr); 10182 Finals.push_back(nullptr); 10183 HasErrors = true; 10184 continue; 10185 } 10186 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) { 10187 D = cast<MemberExpr>(CED->getInit()->IgnoreParenImpCasts()) 10188 ->getMemberDecl(); 10189 } 10190 auto &&Info = Stack->isLoopControlVariable(D); 10191 Expr *InitExpr = *CurInit; 10192 10193 // Build privatized reference to the current linear var. 10194 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 10195 Expr *CapturedRef; 10196 if (LinKind == OMPC_LINEAR_uval) 10197 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 10198 else 10199 CapturedRef = 10200 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 10201 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 10202 /*RefersToCapture=*/true); 10203 10204 // Build update: Var = InitExpr + IV * Step 10205 ExprResult Update; 10206 if (!Info.first) { 10207 Update = 10208 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 10209 InitExpr, IV, Step, /* Subtract */ false); 10210 } else 10211 Update = *CurPrivate; 10212 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(), 10213 /*DiscardedValue=*/true); 10214 10215 // Build final: Var = InitExpr + NumIterations * Step 10216 ExprResult Final; 10217 if (!Info.first) { 10218 Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 10219 InitExpr, NumIterations, Step, 10220 /* Subtract */ false); 10221 } else 10222 Final = *CurPrivate; 10223 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(), 10224 /*DiscardedValue=*/true); 10225 10226 if (!Update.isUsable() || !Final.isUsable()) { 10227 Updates.push_back(nullptr); 10228 Finals.push_back(nullptr); 10229 HasErrors = true; 10230 } else { 10231 Updates.push_back(Update.get()); 10232 Finals.push_back(Final.get()); 10233 } 10234 ++CurInit; 10235 ++CurPrivate; 10236 } 10237 Clause.setUpdates(Updates); 10238 Clause.setFinals(Finals); 10239 return HasErrors; 10240 } 10241 10242 OMPClause *Sema::ActOnOpenMPAlignedClause( 10243 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 10244 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 10245 10246 SmallVector<Expr *, 8> Vars; 10247 for (auto &RefExpr : VarList) { 10248 assert(RefExpr && "NULL expr in OpenMP linear clause."); 10249 SourceLocation ELoc; 10250 SourceRange ERange; 10251 Expr *SimpleRefExpr = RefExpr; 10252 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 10253 /*AllowArraySection=*/false); 10254 if (Res.second) { 10255 // It will be analyzed later. 10256 Vars.push_back(RefExpr); 10257 } 10258 ValueDecl *D = Res.first; 10259 if (!D) 10260 continue; 10261 10262 QualType QType = D->getType(); 10263 auto *VD = dyn_cast<VarDecl>(D); 10264 10265 // OpenMP [2.8.1, simd construct, Restrictions] 10266 // The type of list items appearing in the aligned clause must be 10267 // array, pointer, reference to array, or reference to pointer. 10268 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 10269 const Type *Ty = QType.getTypePtrOrNull(); 10270 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 10271 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 10272 << QType << getLangOpts().CPlusPlus << ERange; 10273 bool IsDecl = 10274 !VD || 10275 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10276 Diag(D->getLocation(), 10277 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10278 << D; 10279 continue; 10280 } 10281 10282 // OpenMP [2.8.1, simd construct, Restrictions] 10283 // A list-item cannot appear in more than one aligned clause. 10284 if (Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 10285 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 10286 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 10287 << getOpenMPClauseName(OMPC_aligned); 10288 continue; 10289 } 10290 10291 DeclRefExpr *Ref = nullptr; 10292 if (!VD && IsOpenMPCapturedDecl(D)) 10293 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 10294 Vars.push_back(DefaultFunctionArrayConversion( 10295 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 10296 .get()); 10297 } 10298 10299 // OpenMP [2.8.1, simd construct, Description] 10300 // The parameter of the aligned clause, alignment, must be a constant 10301 // positive integer expression. 10302 // If no optional parameter is specified, implementation-defined default 10303 // alignments for SIMD instructions on the target platforms are assumed. 10304 if (Alignment != nullptr) { 10305 ExprResult AlignResult = 10306 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 10307 if (AlignResult.isInvalid()) 10308 return nullptr; 10309 Alignment = AlignResult.get(); 10310 } 10311 if (Vars.empty()) 10312 return nullptr; 10313 10314 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 10315 EndLoc, Vars, Alignment); 10316 } 10317 10318 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 10319 SourceLocation StartLoc, 10320 SourceLocation LParenLoc, 10321 SourceLocation EndLoc) { 10322 SmallVector<Expr *, 8> Vars; 10323 SmallVector<Expr *, 8> SrcExprs; 10324 SmallVector<Expr *, 8> DstExprs; 10325 SmallVector<Expr *, 8> AssignmentOps; 10326 for (auto &RefExpr : VarList) { 10327 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 10328 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 10329 // It will be analyzed later. 10330 Vars.push_back(RefExpr); 10331 SrcExprs.push_back(nullptr); 10332 DstExprs.push_back(nullptr); 10333 AssignmentOps.push_back(nullptr); 10334 continue; 10335 } 10336 10337 SourceLocation ELoc = RefExpr->getExprLoc(); 10338 // OpenMP [2.1, C/C++] 10339 // A list item is a variable name. 10340 // OpenMP [2.14.4.1, Restrictions, p.1] 10341 // A list item that appears in a copyin clause must be threadprivate. 10342 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 10343 if (!DE || !isa<VarDecl>(DE->getDecl())) { 10344 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 10345 << 0 << RefExpr->getSourceRange(); 10346 continue; 10347 } 10348 10349 Decl *D = DE->getDecl(); 10350 VarDecl *VD = cast<VarDecl>(D); 10351 10352 QualType Type = VD->getType(); 10353 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 10354 // It will be analyzed later. 10355 Vars.push_back(DE); 10356 SrcExprs.push_back(nullptr); 10357 DstExprs.push_back(nullptr); 10358 AssignmentOps.push_back(nullptr); 10359 continue; 10360 } 10361 10362 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 10363 // A list item that appears in a copyin clause must be threadprivate. 10364 if (!DSAStack->isThreadPrivate(VD)) { 10365 Diag(ELoc, diag::err_omp_required_access) 10366 << getOpenMPClauseName(OMPC_copyin) 10367 << getOpenMPDirectiveName(OMPD_threadprivate); 10368 continue; 10369 } 10370 10371 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 10372 // A variable of class type (or array thereof) that appears in a 10373 // copyin clause requires an accessible, unambiguous copy assignment 10374 // operator for the class type. 10375 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 10376 auto *SrcVD = 10377 buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(), 10378 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 10379 auto *PseudoSrcExpr = buildDeclRefExpr( 10380 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 10381 auto *DstVD = 10382 buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst", 10383 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 10384 auto *PseudoDstExpr = 10385 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 10386 // For arrays generate assignment operation for single element and replace 10387 // it by the original array element in CodeGen. 10388 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 10389 PseudoDstExpr, PseudoSrcExpr); 10390 if (AssignmentOp.isInvalid()) 10391 continue; 10392 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 10393 /*DiscardedValue=*/true); 10394 if (AssignmentOp.isInvalid()) 10395 continue; 10396 10397 DSAStack->addDSA(VD, DE, OMPC_copyin); 10398 Vars.push_back(DE); 10399 SrcExprs.push_back(PseudoSrcExpr); 10400 DstExprs.push_back(PseudoDstExpr); 10401 AssignmentOps.push_back(AssignmentOp.get()); 10402 } 10403 10404 if (Vars.empty()) 10405 return nullptr; 10406 10407 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 10408 SrcExprs, DstExprs, AssignmentOps); 10409 } 10410 10411 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 10412 SourceLocation StartLoc, 10413 SourceLocation LParenLoc, 10414 SourceLocation EndLoc) { 10415 SmallVector<Expr *, 8> Vars; 10416 SmallVector<Expr *, 8> SrcExprs; 10417 SmallVector<Expr *, 8> DstExprs; 10418 SmallVector<Expr *, 8> AssignmentOps; 10419 for (auto &RefExpr : VarList) { 10420 assert(RefExpr && "NULL expr in OpenMP linear clause."); 10421 SourceLocation ELoc; 10422 SourceRange ERange; 10423 Expr *SimpleRefExpr = RefExpr; 10424 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 10425 /*AllowArraySection=*/false); 10426 if (Res.second) { 10427 // It will be analyzed later. 10428 Vars.push_back(RefExpr); 10429 SrcExprs.push_back(nullptr); 10430 DstExprs.push_back(nullptr); 10431 AssignmentOps.push_back(nullptr); 10432 } 10433 ValueDecl *D = Res.first; 10434 if (!D) 10435 continue; 10436 10437 QualType Type = D->getType(); 10438 auto *VD = dyn_cast<VarDecl>(D); 10439 10440 // OpenMP [2.14.4.2, Restrictions, p.2] 10441 // A list item that appears in a copyprivate clause may not appear in a 10442 // private or firstprivate clause on the single construct. 10443 if (!VD || !DSAStack->isThreadPrivate(VD)) { 10444 auto DVar = DSAStack->getTopDSA(D, false); 10445 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 10446 DVar.RefExpr) { 10447 Diag(ELoc, diag::err_omp_wrong_dsa) 10448 << getOpenMPClauseName(DVar.CKind) 10449 << getOpenMPClauseName(OMPC_copyprivate); 10450 ReportOriginalDSA(*this, DSAStack, D, DVar); 10451 continue; 10452 } 10453 10454 // OpenMP [2.11.4.2, Restrictions, p.1] 10455 // All list items that appear in a copyprivate clause must be either 10456 // threadprivate or private in the enclosing context. 10457 if (DVar.CKind == OMPC_unknown) { 10458 DVar = DSAStack->getImplicitDSA(D, false); 10459 if (DVar.CKind == OMPC_shared) { 10460 Diag(ELoc, diag::err_omp_required_access) 10461 << getOpenMPClauseName(OMPC_copyprivate) 10462 << "threadprivate or private in the enclosing context"; 10463 ReportOriginalDSA(*this, DSAStack, D, DVar); 10464 continue; 10465 } 10466 } 10467 } 10468 10469 // Variably modified types are not supported. 10470 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 10471 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 10472 << getOpenMPClauseName(OMPC_copyprivate) << Type 10473 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 10474 bool IsDecl = 10475 !VD || 10476 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 10477 Diag(D->getLocation(), 10478 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 10479 << D; 10480 continue; 10481 } 10482 10483 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 10484 // A variable of class type (or array thereof) that appears in a 10485 // copyin clause requires an accessible, unambiguous copy assignment 10486 // operator for the class type. 10487 Type = Context.getBaseElementType(Type.getNonReferenceType()) 10488 .getUnqualifiedType(); 10489 auto *SrcVD = 10490 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src", 10491 D->hasAttrs() ? &D->getAttrs() : nullptr); 10492 auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 10493 auto *DstVD = 10494 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst", 10495 D->hasAttrs() ? &D->getAttrs() : nullptr); 10496 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 10497 auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 10498 PseudoDstExpr, PseudoSrcExpr); 10499 if (AssignmentOp.isInvalid()) 10500 continue; 10501 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 10502 /*DiscardedValue=*/true); 10503 if (AssignmentOp.isInvalid()) 10504 continue; 10505 10506 // No need to mark vars as copyprivate, they are already threadprivate or 10507 // implicitly private. 10508 assert(VD || IsOpenMPCapturedDecl(D)); 10509 Vars.push_back( 10510 VD ? RefExpr->IgnoreParens() 10511 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 10512 SrcExprs.push_back(PseudoSrcExpr); 10513 DstExprs.push_back(PseudoDstExpr); 10514 AssignmentOps.push_back(AssignmentOp.get()); 10515 } 10516 10517 if (Vars.empty()) 10518 return nullptr; 10519 10520 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10521 Vars, SrcExprs, DstExprs, AssignmentOps); 10522 } 10523 10524 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 10525 SourceLocation StartLoc, 10526 SourceLocation LParenLoc, 10527 SourceLocation EndLoc) { 10528 if (VarList.empty()) 10529 return nullptr; 10530 10531 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 10532 } 10533 10534 OMPClause * 10535 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 10536 SourceLocation DepLoc, SourceLocation ColonLoc, 10537 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 10538 SourceLocation LParenLoc, SourceLocation EndLoc) { 10539 if (DSAStack->getCurrentDirective() == OMPD_ordered && 10540 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 10541 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 10542 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 10543 return nullptr; 10544 } 10545 if (DSAStack->getCurrentDirective() != OMPD_ordered && 10546 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 10547 DepKind == OMPC_DEPEND_sink)) { 10548 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 10549 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 10550 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 10551 /*Last=*/OMPC_DEPEND_unknown, Except) 10552 << getOpenMPClauseName(OMPC_depend); 10553 return nullptr; 10554 } 10555 SmallVector<Expr *, 8> Vars; 10556 DSAStackTy::OperatorOffsetTy OpsOffs; 10557 llvm::APSInt DepCounter(/*BitWidth=*/32); 10558 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 10559 if (DepKind == OMPC_DEPEND_sink) { 10560 if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) { 10561 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 10562 TotalDepCount.setIsUnsigned(/*Val=*/true); 10563 } 10564 } 10565 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) || 10566 DSAStack->getParentOrderedRegionParam()) { 10567 for (auto &RefExpr : VarList) { 10568 assert(RefExpr && "NULL expr in OpenMP shared clause."); 10569 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 10570 // It will be analyzed later. 10571 Vars.push_back(RefExpr); 10572 continue; 10573 } 10574 10575 SourceLocation ELoc = RefExpr->getExprLoc(); 10576 auto *SimpleExpr = RefExpr->IgnoreParenCasts(); 10577 if (DepKind == OMPC_DEPEND_sink) { 10578 if (DepCounter >= TotalDepCount) { 10579 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 10580 continue; 10581 } 10582 ++DepCounter; 10583 // OpenMP [2.13.9, Summary] 10584 // depend(dependence-type : vec), where dependence-type is: 10585 // 'sink' and where vec is the iteration vector, which has the form: 10586 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 10587 // where n is the value specified by the ordered clause in the loop 10588 // directive, xi denotes the loop iteration variable of the i-th nested 10589 // loop associated with the loop directive, and di is a constant 10590 // non-negative integer. 10591 if (CurContext->isDependentContext()) { 10592 // It will be analyzed later. 10593 Vars.push_back(RefExpr); 10594 continue; 10595 } 10596 SimpleExpr = SimpleExpr->IgnoreImplicit(); 10597 OverloadedOperatorKind OOK = OO_None; 10598 SourceLocation OOLoc; 10599 Expr *LHS = SimpleExpr; 10600 Expr *RHS = nullptr; 10601 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 10602 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 10603 OOLoc = BO->getOperatorLoc(); 10604 LHS = BO->getLHS()->IgnoreParenImpCasts(); 10605 RHS = BO->getRHS()->IgnoreParenImpCasts(); 10606 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 10607 OOK = OCE->getOperator(); 10608 OOLoc = OCE->getOperatorLoc(); 10609 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 10610 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 10611 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 10612 OOK = MCE->getMethodDecl() 10613 ->getNameInfo() 10614 .getName() 10615 .getCXXOverloadedOperator(); 10616 OOLoc = MCE->getCallee()->getExprLoc(); 10617 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 10618 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 10619 } 10620 SourceLocation ELoc; 10621 SourceRange ERange; 10622 auto Res = getPrivateItem(*this, LHS, ELoc, ERange, 10623 /*AllowArraySection=*/false); 10624 if (Res.second) { 10625 // It will be analyzed later. 10626 Vars.push_back(RefExpr); 10627 } 10628 ValueDecl *D = Res.first; 10629 if (!D) 10630 continue; 10631 10632 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 10633 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 10634 continue; 10635 } 10636 if (RHS) { 10637 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 10638 RHS, OMPC_depend, /*StrictlyPositive=*/false); 10639 if (RHSRes.isInvalid()) 10640 continue; 10641 } 10642 if (!CurContext->isDependentContext() && 10643 DSAStack->getParentOrderedRegionParam() && 10644 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 10645 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 10646 << DSAStack->getParentLoopControlVariable( 10647 DepCounter.getZExtValue()); 10648 continue; 10649 } 10650 OpsOffs.push_back({RHS, OOK}); 10651 } else { 10652 // OpenMP [2.11.1.1, Restrictions, p.3] 10653 // A variable that is part of another variable (such as a field of a 10654 // structure) but is not an array element or an array section cannot 10655 // appear in a depend clause. 10656 auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr); 10657 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 10658 auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 10659 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 10660 (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) || 10661 (ASE && 10662 !ASE->getBase() 10663 ->getType() 10664 .getNonReferenceType() 10665 ->isPointerType() && 10666 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 10667 Diag(ELoc, diag::err_omp_expected_var_name_member_expr_or_array_item) 10668 << 0 << RefExpr->getSourceRange(); 10669 continue; 10670 } 10671 } 10672 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 10673 } 10674 10675 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 10676 TotalDepCount > VarList.size() && 10677 DSAStack->getParentOrderedRegionParam()) { 10678 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 10679 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 10680 } 10681 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 10682 Vars.empty()) 10683 return nullptr; 10684 } 10685 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10686 DepKind, DepLoc, ColonLoc, Vars); 10687 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) 10688 DSAStack->addDoacrossDependClause(C, OpsOffs); 10689 return C; 10690 } 10691 10692 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 10693 SourceLocation LParenLoc, 10694 SourceLocation EndLoc) { 10695 Expr *ValExpr = Device; 10696 10697 // OpenMP [2.9.1, Restrictions] 10698 // The device expression must evaluate to a non-negative integer value. 10699 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 10700 /*StrictlyPositive=*/false)) 10701 return nullptr; 10702 10703 return new (Context) OMPDeviceClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10704 } 10705 10706 static bool IsCXXRecordForMappable(Sema &SemaRef, SourceLocation Loc, 10707 DSAStackTy *Stack, CXXRecordDecl *RD) { 10708 if (!RD || RD->isInvalidDecl()) 10709 return true; 10710 10711 auto QTy = SemaRef.Context.getRecordType(RD); 10712 if (RD->isDynamicClass()) { 10713 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 10714 SemaRef.Diag(RD->getLocation(), diag::note_omp_polymorphic_in_target); 10715 return false; 10716 } 10717 auto *DC = RD; 10718 bool IsCorrect = true; 10719 for (auto *I : DC->decls()) { 10720 if (I) { 10721 if (auto *MD = dyn_cast<CXXMethodDecl>(I)) { 10722 if (MD->isStatic()) { 10723 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 10724 SemaRef.Diag(MD->getLocation(), 10725 diag::note_omp_static_member_in_target); 10726 IsCorrect = false; 10727 } 10728 } else if (auto *VD = dyn_cast<VarDecl>(I)) { 10729 if (VD->isStaticDataMember()) { 10730 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 10731 SemaRef.Diag(VD->getLocation(), 10732 diag::note_omp_static_member_in_target); 10733 IsCorrect = false; 10734 } 10735 } 10736 } 10737 } 10738 10739 for (auto &I : RD->bases()) { 10740 if (!IsCXXRecordForMappable(SemaRef, I.getLocStart(), Stack, 10741 I.getType()->getAsCXXRecordDecl())) 10742 IsCorrect = false; 10743 } 10744 return IsCorrect; 10745 } 10746 10747 static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 10748 DSAStackTy *Stack, QualType QTy) { 10749 NamedDecl *ND; 10750 if (QTy->isIncompleteType(&ND)) { 10751 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 10752 return false; 10753 } else if (CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(ND)) { 10754 if (!RD->isInvalidDecl() && !IsCXXRecordForMappable(SemaRef, SL, Stack, RD)) 10755 return false; 10756 } 10757 return true; 10758 } 10759 10760 /// \brief Return true if it can be proven that the provided array expression 10761 /// (array section or array subscript) does NOT specify the whole size of the 10762 /// array whose base type is \a BaseQTy. 10763 static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 10764 const Expr *E, 10765 QualType BaseQTy) { 10766 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 10767 10768 // If this is an array subscript, it refers to the whole size if the size of 10769 // the dimension is constant and equals 1. Also, an array section assumes the 10770 // format of an array subscript if no colon is used. 10771 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 10772 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 10773 return ATy->getSize().getSExtValue() != 1; 10774 // Size can't be evaluated statically. 10775 return false; 10776 } 10777 10778 assert(OASE && "Expecting array section if not an array subscript."); 10779 auto *LowerBound = OASE->getLowerBound(); 10780 auto *Length = OASE->getLength(); 10781 10782 // If there is a lower bound that does not evaluates to zero, we are not 10783 // covering the whole dimension. 10784 if (LowerBound) { 10785 llvm::APSInt ConstLowerBound; 10786 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) 10787 return false; // Can't get the integer value as a constant. 10788 if (ConstLowerBound.getSExtValue()) 10789 return true; 10790 } 10791 10792 // If we don't have a length we covering the whole dimension. 10793 if (!Length) 10794 return false; 10795 10796 // If the base is a pointer, we don't have a way to get the size of the 10797 // pointee. 10798 if (BaseQTy->isPointerType()) 10799 return false; 10800 10801 // We can only check if the length is the same as the size of the dimension 10802 // if we have a constant array. 10803 auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 10804 if (!CATy) 10805 return false; 10806 10807 llvm::APSInt ConstLength; 10808 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 10809 return false; // Can't get the integer value as a constant. 10810 10811 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 10812 } 10813 10814 // Return true if it can be proven that the provided array expression (array 10815 // section or array subscript) does NOT specify a single element of the array 10816 // whose base type is \a BaseQTy. 10817 static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 10818 const Expr *E, 10819 QualType BaseQTy) { 10820 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 10821 10822 // An array subscript always refer to a single element. Also, an array section 10823 // assumes the format of an array subscript if no colon is used. 10824 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 10825 return false; 10826 10827 assert(OASE && "Expecting array section if not an array subscript."); 10828 auto *Length = OASE->getLength(); 10829 10830 // If we don't have a length we have to check if the array has unitary size 10831 // for this dimension. Also, we should always expect a length if the base type 10832 // is pointer. 10833 if (!Length) { 10834 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 10835 return ATy->getSize().getSExtValue() != 1; 10836 // We cannot assume anything. 10837 return false; 10838 } 10839 10840 // Check if the length evaluates to 1. 10841 llvm::APSInt ConstLength; 10842 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 10843 return false; // Can't get the integer value as a constant. 10844 10845 return ConstLength.getSExtValue() != 1; 10846 } 10847 10848 // Return the expression of the base of the mappable expression or null if it 10849 // cannot be determined and do all the necessary checks to see if the expression 10850 // is valid as a standalone mappable expression. In the process, record all the 10851 // components of the expression. 10852 static Expr *CheckMapClauseExpressionBase( 10853 Sema &SemaRef, Expr *E, 10854 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 10855 OpenMPClauseKind CKind) { 10856 SourceLocation ELoc = E->getExprLoc(); 10857 SourceRange ERange = E->getSourceRange(); 10858 10859 // The base of elements of list in a map clause have to be either: 10860 // - a reference to variable or field. 10861 // - a member expression. 10862 // - an array expression. 10863 // 10864 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 10865 // reference to 'r'. 10866 // 10867 // If we have: 10868 // 10869 // struct SS { 10870 // Bla S; 10871 // foo() { 10872 // #pragma omp target map (S.Arr[:12]); 10873 // } 10874 // } 10875 // 10876 // We want to retrieve the member expression 'this->S'; 10877 10878 Expr *RelevantExpr = nullptr; 10879 10880 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 10881 // If a list item is an array section, it must specify contiguous storage. 10882 // 10883 // For this restriction it is sufficient that we make sure only references 10884 // to variables or fields and array expressions, and that no array sections 10885 // exist except in the rightmost expression (unless they cover the whole 10886 // dimension of the array). E.g. these would be invalid: 10887 // 10888 // r.ArrS[3:5].Arr[6:7] 10889 // 10890 // r.ArrS[3:5].x 10891 // 10892 // but these would be valid: 10893 // r.ArrS[3].Arr[6:7] 10894 // 10895 // r.ArrS[3].x 10896 10897 bool AllowUnitySizeArraySection = true; 10898 bool AllowWholeSizeArraySection = true; 10899 10900 while (!RelevantExpr) { 10901 E = E->IgnoreParenImpCasts(); 10902 10903 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 10904 if (!isa<VarDecl>(CurE->getDecl())) 10905 break; 10906 10907 RelevantExpr = CurE; 10908 10909 // If we got a reference to a declaration, we should not expect any array 10910 // section before that. 10911 AllowUnitySizeArraySection = false; 10912 AllowWholeSizeArraySection = false; 10913 10914 // Record the component. 10915 CurComponents.push_back(OMPClauseMappableExprCommon::MappableComponent( 10916 CurE, CurE->getDecl())); 10917 continue; 10918 } 10919 10920 if (auto *CurE = dyn_cast<MemberExpr>(E)) { 10921 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 10922 10923 if (isa<CXXThisExpr>(BaseE)) 10924 // We found a base expression: this->Val. 10925 RelevantExpr = CurE; 10926 else 10927 E = BaseE; 10928 10929 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 10930 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 10931 << CurE->getSourceRange(); 10932 break; 10933 } 10934 10935 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 10936 10937 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 10938 // A bit-field cannot appear in a map clause. 10939 // 10940 if (FD->isBitField()) { 10941 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 10942 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 10943 break; 10944 } 10945 10946 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 10947 // If the type of a list item is a reference to a type T then the type 10948 // will be considered to be T for all purposes of this clause. 10949 QualType CurType = BaseE->getType().getNonReferenceType(); 10950 10951 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 10952 // A list item cannot be a variable that is a member of a structure with 10953 // a union type. 10954 // 10955 if (auto *RT = CurType->getAs<RecordType>()) 10956 if (RT->isUnionType()) { 10957 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 10958 << CurE->getSourceRange(); 10959 break; 10960 } 10961 10962 // If we got a member expression, we should not expect any array section 10963 // before that: 10964 // 10965 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 10966 // If a list item is an element of a structure, only the rightmost symbol 10967 // of the variable reference can be an array section. 10968 // 10969 AllowUnitySizeArraySection = false; 10970 AllowWholeSizeArraySection = false; 10971 10972 // Record the component. 10973 CurComponents.push_back( 10974 OMPClauseMappableExprCommon::MappableComponent(CurE, FD)); 10975 continue; 10976 } 10977 10978 if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 10979 E = CurE->getBase()->IgnoreParenImpCasts(); 10980 10981 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 10982 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 10983 << 0 << CurE->getSourceRange(); 10984 break; 10985 } 10986 10987 // If we got an array subscript that express the whole dimension we 10988 // can have any array expressions before. If it only expressing part of 10989 // the dimension, we can only have unitary-size array expressions. 10990 if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 10991 E->getType())) 10992 AllowWholeSizeArraySection = false; 10993 10994 // Record the component - we don't have any declaration associated. 10995 CurComponents.push_back( 10996 OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); 10997 continue; 10998 } 10999 11000 if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 11001 E = CurE->getBase()->IgnoreParenImpCasts(); 11002 11003 auto CurType = 11004 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 11005 11006 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 11007 // If the type of a list item is a reference to a type T then the type 11008 // will be considered to be T for all purposes of this clause. 11009 if (CurType->isReferenceType()) 11010 CurType = CurType->getPointeeType(); 11011 11012 bool IsPointer = CurType->isAnyPointerType(); 11013 11014 if (!IsPointer && !CurType->isArrayType()) { 11015 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 11016 << 0 << CurE->getSourceRange(); 11017 break; 11018 } 11019 11020 bool NotWhole = 11021 CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 11022 bool NotUnity = 11023 CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 11024 11025 if (AllowWholeSizeArraySection) { 11026 // Any array section is currently allowed. Allowing a whole size array 11027 // section implies allowing a unity array section as well. 11028 // 11029 // If this array section refers to the whole dimension we can still 11030 // accept other array sections before this one, except if the base is a 11031 // pointer. Otherwise, only unitary sections are accepted. 11032 if (NotWhole || IsPointer) 11033 AllowWholeSizeArraySection = false; 11034 } else if (AllowUnitySizeArraySection && NotUnity) { 11035 // A unity or whole array section is not allowed and that is not 11036 // compatible with the properties of the current array section. 11037 SemaRef.Diag( 11038 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 11039 << CurE->getSourceRange(); 11040 break; 11041 } 11042 11043 // Record the component - we don't have any declaration associated. 11044 CurComponents.push_back( 11045 OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); 11046 continue; 11047 } 11048 11049 // If nothing else worked, this is not a valid map clause expression. 11050 SemaRef.Diag(ELoc, 11051 diag::err_omp_expected_named_var_member_or_array_expression) 11052 << ERange; 11053 break; 11054 } 11055 11056 return RelevantExpr; 11057 } 11058 11059 // Return true if expression E associated with value VD has conflicts with other 11060 // map information. 11061 static bool CheckMapConflicts( 11062 Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E, 11063 bool CurrentRegionOnly, 11064 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 11065 OpenMPClauseKind CKind) { 11066 assert(VD && E); 11067 SourceLocation ELoc = E->getExprLoc(); 11068 SourceRange ERange = E->getSourceRange(); 11069 11070 // In order to easily check the conflicts we need to match each component of 11071 // the expression under test with the components of the expressions that are 11072 // already in the stack. 11073 11074 assert(!CurComponents.empty() && "Map clause expression with no components!"); 11075 assert(CurComponents.back().getAssociatedDeclaration() == VD && 11076 "Map clause expression with unexpected base!"); 11077 11078 // Variables to help detecting enclosing problems in data environment nests. 11079 bool IsEnclosedByDataEnvironmentExpr = false; 11080 const Expr *EnclosingExpr = nullptr; 11081 11082 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 11083 VD, CurrentRegionOnly, 11084 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef 11085 StackComponents, 11086 OpenMPClauseKind) -> bool { 11087 11088 assert(!StackComponents.empty() && 11089 "Map clause expression with no components!"); 11090 assert(StackComponents.back().getAssociatedDeclaration() == VD && 11091 "Map clause expression with unexpected base!"); 11092 11093 // The whole expression in the stack. 11094 auto *RE = StackComponents.front().getAssociatedExpression(); 11095 11096 // Expressions must start from the same base. Here we detect at which 11097 // point both expressions diverge from each other and see if we can 11098 // detect if the memory referred to both expressions is contiguous and 11099 // do not overlap. 11100 auto CI = CurComponents.rbegin(); 11101 auto CE = CurComponents.rend(); 11102 auto SI = StackComponents.rbegin(); 11103 auto SE = StackComponents.rend(); 11104 for (; CI != CE && SI != SE; ++CI, ++SI) { 11105 11106 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 11107 // At most one list item can be an array item derived from a given 11108 // variable in map clauses of the same construct. 11109 if (CurrentRegionOnly && 11110 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 11111 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 11112 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 11113 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 11114 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 11115 diag::err_omp_multiple_array_items_in_map_clause) 11116 << CI->getAssociatedExpression()->getSourceRange(); 11117 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 11118 diag::note_used_here) 11119 << SI->getAssociatedExpression()->getSourceRange(); 11120 return true; 11121 } 11122 11123 // Do both expressions have the same kind? 11124 if (CI->getAssociatedExpression()->getStmtClass() != 11125 SI->getAssociatedExpression()->getStmtClass()) 11126 break; 11127 11128 // Are we dealing with different variables/fields? 11129 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 11130 break; 11131 } 11132 // Check if the extra components of the expressions in the enclosing 11133 // data environment are redundant for the current base declaration. 11134 // If they are, the maps completely overlap, which is legal. 11135 for (; SI != SE; ++SI) { 11136 QualType Type; 11137 if (auto *ASE = 11138 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 11139 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 11140 } else if (auto *OASE = dyn_cast<OMPArraySectionExpr>( 11141 SI->getAssociatedExpression())) { 11142 auto *E = OASE->getBase()->IgnoreParenImpCasts(); 11143 Type = 11144 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 11145 } 11146 if (Type.isNull() || Type->isAnyPointerType() || 11147 CheckArrayExpressionDoesNotReferToWholeSize( 11148 SemaRef, SI->getAssociatedExpression(), Type)) 11149 break; 11150 } 11151 11152 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 11153 // List items of map clauses in the same construct must not share 11154 // original storage. 11155 // 11156 // If the expressions are exactly the same or one is a subset of the 11157 // other, it means they are sharing storage. 11158 if (CI == CE && SI == SE) { 11159 if (CurrentRegionOnly) { 11160 if (CKind == OMPC_map) 11161 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 11162 else { 11163 assert(CKind == OMPC_to || CKind == OMPC_from); 11164 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 11165 << ERange; 11166 } 11167 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 11168 << RE->getSourceRange(); 11169 return true; 11170 } else { 11171 // If we find the same expression in the enclosing data environment, 11172 // that is legal. 11173 IsEnclosedByDataEnvironmentExpr = true; 11174 return false; 11175 } 11176 } 11177 11178 QualType DerivedType = 11179 std::prev(CI)->getAssociatedDeclaration()->getType(); 11180 SourceLocation DerivedLoc = 11181 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 11182 11183 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 11184 // If the type of a list item is a reference to a type T then the type 11185 // will be considered to be T for all purposes of this clause. 11186 DerivedType = DerivedType.getNonReferenceType(); 11187 11188 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 11189 // A variable for which the type is pointer and an array section 11190 // derived from that variable must not appear as list items of map 11191 // clauses of the same construct. 11192 // 11193 // Also, cover one of the cases in: 11194 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 11195 // If any part of the original storage of a list item has corresponding 11196 // storage in the device data environment, all of the original storage 11197 // must have corresponding storage in the device data environment. 11198 // 11199 if (DerivedType->isAnyPointerType()) { 11200 if (CI == CE || SI == SE) { 11201 SemaRef.Diag( 11202 DerivedLoc, 11203 diag::err_omp_pointer_mapped_along_with_derived_section) 11204 << DerivedLoc; 11205 } else { 11206 assert(CI != CE && SI != SE); 11207 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced) 11208 << DerivedLoc; 11209 } 11210 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 11211 << RE->getSourceRange(); 11212 return true; 11213 } 11214 11215 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 11216 // List items of map clauses in the same construct must not share 11217 // original storage. 11218 // 11219 // An expression is a subset of the other. 11220 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 11221 if (CKind == OMPC_map) 11222 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 11223 else { 11224 assert(CKind == OMPC_to || CKind == OMPC_from); 11225 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 11226 << ERange; 11227 } 11228 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 11229 << RE->getSourceRange(); 11230 return true; 11231 } 11232 11233 // The current expression uses the same base as other expression in the 11234 // data environment but does not contain it completely. 11235 if (!CurrentRegionOnly && SI != SE) 11236 EnclosingExpr = RE; 11237 11238 // The current expression is a subset of the expression in the data 11239 // environment. 11240 IsEnclosedByDataEnvironmentExpr |= 11241 (!CurrentRegionOnly && CI != CE && SI == SE); 11242 11243 return false; 11244 }); 11245 11246 if (CurrentRegionOnly) 11247 return FoundError; 11248 11249 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 11250 // If any part of the original storage of a list item has corresponding 11251 // storage in the device data environment, all of the original storage must 11252 // have corresponding storage in the device data environment. 11253 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 11254 // If a list item is an element of a structure, and a different element of 11255 // the structure has a corresponding list item in the device data environment 11256 // prior to a task encountering the construct associated with the map clause, 11257 // then the list item must also have a corresponding list item in the device 11258 // data environment prior to the task encountering the construct. 11259 // 11260 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 11261 SemaRef.Diag(ELoc, 11262 diag::err_omp_original_storage_is_shared_and_does_not_contain) 11263 << ERange; 11264 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 11265 << EnclosingExpr->getSourceRange(); 11266 return true; 11267 } 11268 11269 return FoundError; 11270 } 11271 11272 namespace { 11273 // Utility struct that gathers all the related lists associated with a mappable 11274 // expression. 11275 struct MappableVarListInfo final { 11276 // The list of expressions. 11277 ArrayRef<Expr *> VarList; 11278 // The list of processed expressions. 11279 SmallVector<Expr *, 16> ProcessedVarList; 11280 // The mappble components for each expression. 11281 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 11282 // The base declaration of the variable. 11283 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 11284 11285 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 11286 // We have a list of components and base declarations for each entry in the 11287 // variable list. 11288 VarComponents.reserve(VarList.size()); 11289 VarBaseDeclarations.reserve(VarList.size()); 11290 } 11291 }; 11292 } 11293 11294 // Check the validity of the provided variable list for the provided clause kind 11295 // \a CKind. In the check process the valid expressions, and mappable expression 11296 // components and variables are extracted and used to fill \a Vars, 11297 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and 11298 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'. 11299 static void 11300 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, 11301 OpenMPClauseKind CKind, MappableVarListInfo &MVLI, 11302 SourceLocation StartLoc, 11303 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 11304 bool IsMapTypeImplicit = false) { 11305 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 11306 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 11307 "Unexpected clause kind with mappable expressions!"); 11308 11309 // Keep track of the mappable components and base declarations in this clause. 11310 // Each entry in the list is going to have a list of components associated. We 11311 // record each set of the components so that we can build the clause later on. 11312 // In the end we should have the same amount of declarations and component 11313 // lists. 11314 11315 for (auto &RE : MVLI.VarList) { 11316 assert(RE && "Null expr in omp to/from/map clause"); 11317 SourceLocation ELoc = RE->getExprLoc(); 11318 11319 auto *VE = RE->IgnoreParenLValueCasts(); 11320 11321 if (VE->isValueDependent() || VE->isTypeDependent() || 11322 VE->isInstantiationDependent() || 11323 VE->containsUnexpandedParameterPack()) { 11324 // We can only analyze this information once the missing information is 11325 // resolved. 11326 MVLI.ProcessedVarList.push_back(RE); 11327 continue; 11328 } 11329 11330 auto *SimpleExpr = RE->IgnoreParenCasts(); 11331 11332 if (!RE->IgnoreParenImpCasts()->isLValue()) { 11333 SemaRef.Diag(ELoc, 11334 diag::err_omp_expected_named_var_member_or_array_expression) 11335 << RE->getSourceRange(); 11336 continue; 11337 } 11338 11339 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 11340 ValueDecl *CurDeclaration = nullptr; 11341 11342 // Obtain the array or member expression bases if required. Also, fill the 11343 // components array with all the components identified in the process. 11344 auto *BE = 11345 CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind); 11346 if (!BE) 11347 continue; 11348 11349 assert(!CurComponents.empty() && 11350 "Invalid mappable expression information."); 11351 11352 // For the following checks, we rely on the base declaration which is 11353 // expected to be associated with the last component. The declaration is 11354 // expected to be a variable or a field (if 'this' is being mapped). 11355 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 11356 assert(CurDeclaration && "Null decl on map clause."); 11357 assert( 11358 CurDeclaration->isCanonicalDecl() && 11359 "Expecting components to have associated only canonical declarations."); 11360 11361 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 11362 auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 11363 11364 assert((VD || FD) && "Only variables or fields are expected here!"); 11365 (void)FD; 11366 11367 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 11368 // threadprivate variables cannot appear in a map clause. 11369 // OpenMP 4.5 [2.10.5, target update Construct] 11370 // threadprivate variables cannot appear in a from clause. 11371 if (VD && DSAS->isThreadPrivate(VD)) { 11372 auto DVar = DSAS->getTopDSA(VD, false); 11373 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 11374 << getOpenMPClauseName(CKind); 11375 ReportOriginalDSA(SemaRef, DSAS, VD, DVar); 11376 continue; 11377 } 11378 11379 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 11380 // A list item cannot appear in both a map clause and a data-sharing 11381 // attribute clause on the same construct. 11382 11383 // Check conflicts with other map clause expressions. We check the conflicts 11384 // with the current construct separately from the enclosing data 11385 // environment, because the restrictions are different. We only have to 11386 // check conflicts across regions for the map clauses. 11387 if (CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 11388 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 11389 break; 11390 if (CKind == OMPC_map && 11391 CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 11392 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 11393 break; 11394 11395 // OpenMP 4.5 [2.10.5, target update Construct] 11396 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 11397 // If the type of a list item is a reference to a type T then the type will 11398 // be considered to be T for all purposes of this clause. 11399 QualType Type = CurDeclaration->getType().getNonReferenceType(); 11400 11401 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 11402 // A list item in a to or from clause must have a mappable type. 11403 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 11404 // A list item must have a mappable type. 11405 if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 11406 DSAS, Type)) 11407 continue; 11408 11409 if (CKind == OMPC_map) { 11410 // target enter data 11411 // OpenMP [2.10.2, Restrictions, p. 99] 11412 // A map-type must be specified in all map clauses and must be either 11413 // to or alloc. 11414 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 11415 if (DKind == OMPD_target_enter_data && 11416 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 11417 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 11418 << (IsMapTypeImplicit ? 1 : 0) 11419 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 11420 << getOpenMPDirectiveName(DKind); 11421 continue; 11422 } 11423 11424 // target exit_data 11425 // OpenMP [2.10.3, Restrictions, p. 102] 11426 // A map-type must be specified in all map clauses and must be either 11427 // from, release, or delete. 11428 if (DKind == OMPD_target_exit_data && 11429 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 11430 MapType == OMPC_MAP_delete)) { 11431 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 11432 << (IsMapTypeImplicit ? 1 : 0) 11433 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 11434 << getOpenMPDirectiveName(DKind); 11435 continue; 11436 } 11437 11438 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 11439 // A list item cannot appear in both a map clause and a data-sharing 11440 // attribute clause on the same construct 11441 if (DKind == OMPD_target && VD) { 11442 auto DVar = DSAS->getTopDSA(VD, false); 11443 if (isOpenMPPrivate(DVar.CKind)) { 11444 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11445 << getOpenMPClauseName(DVar.CKind) 11446 << getOpenMPClauseName(OMPC_map) 11447 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 11448 ReportOriginalDSA(SemaRef, DSAS, CurDeclaration, DVar); 11449 continue; 11450 } 11451 } 11452 } 11453 11454 // Save the current expression. 11455 MVLI.ProcessedVarList.push_back(RE); 11456 11457 // Store the components in the stack so that they can be used to check 11458 // against other clauses later on. 11459 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 11460 /*WhereFoundClauseKind=*/OMPC_map); 11461 11462 // Save the components and declaration to create the clause. For purposes of 11463 // the clause creation, any component list that has has base 'this' uses 11464 // null as base declaration. 11465 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 11466 MVLI.VarComponents.back().append(CurComponents.begin(), 11467 CurComponents.end()); 11468 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 11469 : CurDeclaration); 11470 } 11471 } 11472 11473 OMPClause * 11474 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, 11475 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 11476 SourceLocation MapLoc, SourceLocation ColonLoc, 11477 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 11478 SourceLocation LParenLoc, SourceLocation EndLoc) { 11479 MappableVarListInfo MVLI(VarList); 11480 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc, 11481 MapType, IsMapTypeImplicit); 11482 11483 // We need to produce a map clause even if we don't have variables so that 11484 // other diagnostics related with non-existing map clauses are accurate. 11485 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11486 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 11487 MVLI.VarComponents, MapTypeModifier, MapType, 11488 IsMapTypeImplicit, MapLoc); 11489 } 11490 11491 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 11492 TypeResult ParsedType) { 11493 assert(ParsedType.isUsable()); 11494 11495 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 11496 if (ReductionType.isNull()) 11497 return QualType(); 11498 11499 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 11500 // A type name in a declare reduction directive cannot be a function type, an 11501 // array type, a reference type, or a type qualified with const, volatile or 11502 // restrict. 11503 if (ReductionType.hasQualifiers()) { 11504 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 11505 return QualType(); 11506 } 11507 11508 if (ReductionType->isFunctionType()) { 11509 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 11510 return QualType(); 11511 } 11512 if (ReductionType->isReferenceType()) { 11513 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 11514 return QualType(); 11515 } 11516 if (ReductionType->isArrayType()) { 11517 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 11518 return QualType(); 11519 } 11520 return ReductionType; 11521 } 11522 11523 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 11524 Scope *S, DeclContext *DC, DeclarationName Name, 11525 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 11526 AccessSpecifier AS, Decl *PrevDeclInScope) { 11527 SmallVector<Decl *, 8> Decls; 11528 Decls.reserve(ReductionTypes.size()); 11529 11530 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 11531 ForRedeclaration); 11532 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 11533 // A reduction-identifier may not be re-declared in the current scope for the 11534 // same type or for a type that is compatible according to the base language 11535 // rules. 11536 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 11537 OMPDeclareReductionDecl *PrevDRD = nullptr; 11538 bool InCompoundScope = true; 11539 if (S != nullptr) { 11540 // Find previous declaration with the same name not referenced in other 11541 // declarations. 11542 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 11543 InCompoundScope = 11544 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 11545 LookupName(Lookup, S); 11546 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 11547 /*AllowInlineNamespace=*/false); 11548 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 11549 auto Filter = Lookup.makeFilter(); 11550 while (Filter.hasNext()) { 11551 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 11552 if (InCompoundScope) { 11553 auto I = UsedAsPrevious.find(PrevDecl); 11554 if (I == UsedAsPrevious.end()) 11555 UsedAsPrevious[PrevDecl] = false; 11556 if (auto *D = PrevDecl->getPrevDeclInScope()) 11557 UsedAsPrevious[D] = true; 11558 } 11559 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 11560 PrevDecl->getLocation(); 11561 } 11562 Filter.done(); 11563 if (InCompoundScope) { 11564 for (auto &PrevData : UsedAsPrevious) { 11565 if (!PrevData.second) { 11566 PrevDRD = PrevData.first; 11567 break; 11568 } 11569 } 11570 } 11571 } else if (PrevDeclInScope != nullptr) { 11572 auto *PrevDRDInScope = PrevDRD = 11573 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 11574 do { 11575 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 11576 PrevDRDInScope->getLocation(); 11577 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 11578 } while (PrevDRDInScope != nullptr); 11579 } 11580 for (auto &TyData : ReductionTypes) { 11581 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 11582 bool Invalid = false; 11583 if (I != PreviousRedeclTypes.end()) { 11584 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 11585 << TyData.first; 11586 Diag(I->second, diag::note_previous_definition); 11587 Invalid = true; 11588 } 11589 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 11590 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 11591 Name, TyData.first, PrevDRD); 11592 DC->addDecl(DRD); 11593 DRD->setAccess(AS); 11594 Decls.push_back(DRD); 11595 if (Invalid) 11596 DRD->setInvalidDecl(); 11597 else 11598 PrevDRD = DRD; 11599 } 11600 11601 return DeclGroupPtrTy::make( 11602 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 11603 } 11604 11605 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 11606 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11607 11608 // Enter new function scope. 11609 PushFunctionScope(); 11610 getCurFunction()->setHasBranchProtectedScope(); 11611 getCurFunction()->setHasOMPDeclareReductionCombiner(); 11612 11613 if (S != nullptr) 11614 PushDeclContext(S, DRD); 11615 else 11616 CurContext = DRD; 11617 11618 PushExpressionEvaluationContext(PotentiallyEvaluated); 11619 11620 QualType ReductionType = DRD->getType(); 11621 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 11622 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 11623 // uses semantics of argument handles by value, but it should be passed by 11624 // reference. C lang does not support references, so pass all parameters as 11625 // pointers. 11626 // Create 'T omp_in;' variable. 11627 auto *OmpInParm = 11628 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 11629 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 11630 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 11631 // uses semantics of argument handles by value, but it should be passed by 11632 // reference. C lang does not support references, so pass all parameters as 11633 // pointers. 11634 // Create 'T omp_out;' variable. 11635 auto *OmpOutParm = 11636 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 11637 if (S != nullptr) { 11638 PushOnScopeChains(OmpInParm, S); 11639 PushOnScopeChains(OmpOutParm, S); 11640 } else { 11641 DRD->addDecl(OmpInParm); 11642 DRD->addDecl(OmpOutParm); 11643 } 11644 } 11645 11646 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 11647 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11648 DiscardCleanupsInEvaluationContext(); 11649 PopExpressionEvaluationContext(); 11650 11651 PopDeclContext(); 11652 PopFunctionScopeInfo(); 11653 11654 if (Combiner != nullptr) 11655 DRD->setCombiner(Combiner); 11656 else 11657 DRD->setInvalidDecl(); 11658 } 11659 11660 void Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 11661 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11662 11663 // Enter new function scope. 11664 PushFunctionScope(); 11665 getCurFunction()->setHasBranchProtectedScope(); 11666 11667 if (S != nullptr) 11668 PushDeclContext(S, DRD); 11669 else 11670 CurContext = DRD; 11671 11672 PushExpressionEvaluationContext(PotentiallyEvaluated); 11673 11674 QualType ReductionType = DRD->getType(); 11675 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 11676 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 11677 // uses semantics of argument handles by value, but it should be passed by 11678 // reference. C lang does not support references, so pass all parameters as 11679 // pointers. 11680 // Create 'T omp_priv;' variable. 11681 auto *OmpPrivParm = 11682 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 11683 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 11684 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 11685 // uses semantics of argument handles by value, but it should be passed by 11686 // reference. C lang does not support references, so pass all parameters as 11687 // pointers. 11688 // Create 'T omp_orig;' variable. 11689 auto *OmpOrigParm = 11690 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 11691 if (S != nullptr) { 11692 PushOnScopeChains(OmpPrivParm, S); 11693 PushOnScopeChains(OmpOrigParm, S); 11694 } else { 11695 DRD->addDecl(OmpPrivParm); 11696 DRD->addDecl(OmpOrigParm); 11697 } 11698 } 11699 11700 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, 11701 Expr *Initializer) { 11702 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11703 DiscardCleanupsInEvaluationContext(); 11704 PopExpressionEvaluationContext(); 11705 11706 PopDeclContext(); 11707 PopFunctionScopeInfo(); 11708 11709 if (Initializer != nullptr) 11710 DRD->setInitializer(Initializer); 11711 else 11712 DRD->setInvalidDecl(); 11713 } 11714 11715 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 11716 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 11717 for (auto *D : DeclReductions.get()) { 11718 if (IsValid) { 11719 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11720 if (S != nullptr) 11721 PushOnScopeChains(DRD, S, /*AddToContext=*/false); 11722 } else 11723 D->setInvalidDecl(); 11724 } 11725 return DeclReductions; 11726 } 11727 11728 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 11729 SourceLocation StartLoc, 11730 SourceLocation LParenLoc, 11731 SourceLocation EndLoc) { 11732 Expr *ValExpr = NumTeams; 11733 11734 // OpenMP [teams Constrcut, Restrictions] 11735 // The num_teams expression must evaluate to a positive integer value. 11736 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 11737 /*StrictlyPositive=*/true)) 11738 return nullptr; 11739 11740 return new (Context) OMPNumTeamsClause(ValExpr, StartLoc, LParenLoc, EndLoc); 11741 } 11742 11743 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 11744 SourceLocation StartLoc, 11745 SourceLocation LParenLoc, 11746 SourceLocation EndLoc) { 11747 Expr *ValExpr = ThreadLimit; 11748 11749 // OpenMP [teams Constrcut, Restrictions] 11750 // The thread_limit expression must evaluate to a positive integer value. 11751 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 11752 /*StrictlyPositive=*/true)) 11753 return nullptr; 11754 11755 return new (Context) 11756 OMPThreadLimitClause(ValExpr, StartLoc, LParenLoc, EndLoc); 11757 } 11758 11759 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 11760 SourceLocation StartLoc, 11761 SourceLocation LParenLoc, 11762 SourceLocation EndLoc) { 11763 Expr *ValExpr = Priority; 11764 11765 // OpenMP [2.9.1, task Constrcut] 11766 // The priority-value is a non-negative numerical scalar expression. 11767 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 11768 /*StrictlyPositive=*/false)) 11769 return nullptr; 11770 11771 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 11772 } 11773 11774 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 11775 SourceLocation StartLoc, 11776 SourceLocation LParenLoc, 11777 SourceLocation EndLoc) { 11778 Expr *ValExpr = Grainsize; 11779 11780 // OpenMP [2.9.2, taskloop Constrcut] 11781 // The parameter of the grainsize clause must be a positive integer 11782 // expression. 11783 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 11784 /*StrictlyPositive=*/true)) 11785 return nullptr; 11786 11787 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 11788 } 11789 11790 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 11791 SourceLocation StartLoc, 11792 SourceLocation LParenLoc, 11793 SourceLocation EndLoc) { 11794 Expr *ValExpr = NumTasks; 11795 11796 // OpenMP [2.9.2, taskloop Constrcut] 11797 // The parameter of the num_tasks clause must be a positive integer 11798 // expression. 11799 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 11800 /*StrictlyPositive=*/true)) 11801 return nullptr; 11802 11803 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 11804 } 11805 11806 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 11807 SourceLocation LParenLoc, 11808 SourceLocation EndLoc) { 11809 // OpenMP [2.13.2, critical construct, Description] 11810 // ... where hint-expression is an integer constant expression that evaluates 11811 // to a valid lock hint. 11812 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 11813 if (HintExpr.isInvalid()) 11814 return nullptr; 11815 return new (Context) 11816 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 11817 } 11818 11819 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 11820 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11821 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 11822 SourceLocation EndLoc) { 11823 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 11824 std::string Values; 11825 Values += "'"; 11826 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 11827 Values += "'"; 11828 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11829 << Values << getOpenMPClauseName(OMPC_dist_schedule); 11830 return nullptr; 11831 } 11832 Expr *ValExpr = ChunkSize; 11833 Stmt *HelperValStmt = nullptr; 11834 if (ChunkSize) { 11835 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11836 !ChunkSize->isInstantiationDependent() && 11837 !ChunkSize->containsUnexpandedParameterPack()) { 11838 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 11839 ExprResult Val = 11840 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11841 if (Val.isInvalid()) 11842 return nullptr; 11843 11844 ValExpr = Val.get(); 11845 11846 // OpenMP [2.7.1, Restrictions] 11847 // chunk_size must be a loop invariant integer expression with a positive 11848 // value. 11849 llvm::APSInt Result; 11850 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11851 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11852 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11853 << "dist_schedule" << ChunkSize->getSourceRange(); 11854 return nullptr; 11855 } 11856 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) && 11857 !CurContext->isDependentContext()) { 11858 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 11859 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11860 HelperValStmt = buildPreInits(Context, Captures); 11861 } 11862 } 11863 } 11864 11865 return new (Context) 11866 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 11867 Kind, ValExpr, HelperValStmt); 11868 } 11869 11870 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 11871 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 11872 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 11873 SourceLocation KindLoc, SourceLocation EndLoc) { 11874 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 11875 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 11876 std::string Value; 11877 SourceLocation Loc; 11878 Value += "'"; 11879 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 11880 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 11881 OMPC_DEFAULTMAP_MODIFIER_tofrom); 11882 Loc = MLoc; 11883 } else { 11884 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 11885 OMPC_DEFAULTMAP_scalar); 11886 Loc = KindLoc; 11887 } 11888 Value += "'"; 11889 Diag(Loc, diag::err_omp_unexpected_clause_value) 11890 << Value << getOpenMPClauseName(OMPC_defaultmap); 11891 return nullptr; 11892 } 11893 11894 return new (Context) 11895 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 11896 } 11897 11898 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 11899 DeclContext *CurLexicalContext = getCurLexicalContext(); 11900 if (!CurLexicalContext->isFileContext() && 11901 !CurLexicalContext->isExternCContext() && 11902 !CurLexicalContext->isExternCXXContext()) { 11903 Diag(Loc, diag::err_omp_region_not_file_context); 11904 return false; 11905 } 11906 if (IsInOpenMPDeclareTargetContext) { 11907 Diag(Loc, diag::err_omp_enclosed_declare_target); 11908 return false; 11909 } 11910 11911 IsInOpenMPDeclareTargetContext = true; 11912 return true; 11913 } 11914 11915 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 11916 assert(IsInOpenMPDeclareTargetContext && 11917 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 11918 11919 IsInOpenMPDeclareTargetContext = false; 11920 } 11921 11922 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 11923 CXXScopeSpec &ScopeSpec, 11924 const DeclarationNameInfo &Id, 11925 OMPDeclareTargetDeclAttr::MapTypeTy MT, 11926 NamedDeclSetType &SameDirectiveDecls) { 11927 LookupResult Lookup(*this, Id, LookupOrdinaryName); 11928 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 11929 11930 if (Lookup.isAmbiguous()) 11931 return; 11932 Lookup.suppressDiagnostics(); 11933 11934 if (!Lookup.isSingleResult()) { 11935 if (TypoCorrection Corrected = 11936 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, 11937 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), 11938 CTK_ErrorRecovery)) { 11939 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 11940 << Id.getName()); 11941 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 11942 return; 11943 } 11944 11945 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 11946 return; 11947 } 11948 11949 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 11950 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { 11951 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 11952 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 11953 11954 if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) { 11955 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 11956 ND->addAttr(A); 11957 if (ASTMutationListener *ML = Context.getASTMutationListener()) 11958 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 11959 checkDeclIsAllowedInOpenMPTarget(nullptr, ND); 11960 } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) { 11961 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 11962 << Id.getName(); 11963 } 11964 } else 11965 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 11966 } 11967 11968 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 11969 Sema &SemaRef, Decl *D) { 11970 if (!D) 11971 return; 11972 Decl *LD = nullptr; 11973 if (isa<TagDecl>(D)) { 11974 LD = cast<TagDecl>(D)->getDefinition(); 11975 } else if (isa<VarDecl>(D)) { 11976 LD = cast<VarDecl>(D)->getDefinition(); 11977 11978 // If this is an implicit variable that is legal and we do not need to do 11979 // anything. 11980 if (cast<VarDecl>(D)->isImplicit()) { 11981 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11982 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 11983 D->addAttr(A); 11984 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 11985 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 11986 return; 11987 } 11988 11989 } else if (isa<FunctionDecl>(D)) { 11990 const FunctionDecl *FD = nullptr; 11991 if (cast<FunctionDecl>(D)->hasBody(FD)) 11992 LD = const_cast<FunctionDecl *>(FD); 11993 11994 // If the definition is associated with the current declaration in the 11995 // target region (it can be e.g. a lambda) that is legal and we do not need 11996 // to do anything else. 11997 if (LD == D) { 11998 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11999 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 12000 D->addAttr(A); 12001 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 12002 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 12003 return; 12004 } 12005 } 12006 if (!LD) 12007 LD = D; 12008 if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() && 12009 (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) { 12010 // Outlined declaration is not declared target. 12011 if (LD->isOutOfLine()) { 12012 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 12013 SemaRef.Diag(SL, diag::note_used_here) << SR; 12014 } else { 12015 DeclContext *DC = LD->getDeclContext(); 12016 while (DC) { 12017 if (isa<FunctionDecl>(DC) && 12018 cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>()) 12019 break; 12020 DC = DC->getParent(); 12021 } 12022 if (DC) 12023 return; 12024 12025 // Is not declared in target context. 12026 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 12027 SemaRef.Diag(SL, diag::note_used_here) << SR; 12028 } 12029 // Mark decl as declared target to prevent further diagnostic. 12030 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12031 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 12032 D->addAttr(A); 12033 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 12034 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 12035 } 12036 } 12037 12038 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 12039 Sema &SemaRef, DSAStackTy *Stack, 12040 ValueDecl *VD) { 12041 if (VD->hasAttr<OMPDeclareTargetDeclAttr>()) 12042 return true; 12043 if (!CheckTypeMappable(SL, SR, SemaRef, Stack, VD->getType())) 12044 return false; 12045 return true; 12046 } 12047 12048 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D) { 12049 if (!D || D->isInvalidDecl()) 12050 return; 12051 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 12052 SourceLocation SL = E ? E->getLocStart() : D->getLocation(); 12053 // 2.10.6: threadprivate variable cannot appear in a declare target directive. 12054 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 12055 if (DSAStack->isThreadPrivate(VD)) { 12056 Diag(SL, diag::err_omp_threadprivate_in_target); 12057 ReportOriginalDSA(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 12058 return; 12059 } 12060 } 12061 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 12062 // Problem if any with var declared with incomplete type will be reported 12063 // as normal, so no need to check it here. 12064 if ((E || !VD->getType()->isIncompleteType()) && 12065 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) { 12066 // Mark decl as declared target to prevent further diagnostic. 12067 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) { 12068 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12069 Context, OMPDeclareTargetDeclAttr::MT_To); 12070 VD->addAttr(A); 12071 if (ASTMutationListener *ML = Context.getASTMutationListener()) 12072 ML->DeclarationMarkedOpenMPDeclareTarget(VD, A); 12073 } 12074 return; 12075 } 12076 } 12077 if (!E) { 12078 // Checking declaration inside declare target region. 12079 if (!D->hasAttr<OMPDeclareTargetDeclAttr>() && 12080 (isa<VarDecl>(D) || isa<FunctionDecl>(D))) { 12081 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 12082 Context, OMPDeclareTargetDeclAttr::MT_To); 12083 D->addAttr(A); 12084 if (ASTMutationListener *ML = Context.getASTMutationListener()) 12085 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 12086 } 12087 return; 12088 } 12089 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 12090 } 12091 12092 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 12093 SourceLocation StartLoc, 12094 SourceLocation LParenLoc, 12095 SourceLocation EndLoc) { 12096 MappableVarListInfo MVLI(VarList); 12097 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc); 12098 if (MVLI.ProcessedVarList.empty()) 12099 return nullptr; 12100 12101 return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12102 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 12103 MVLI.VarComponents); 12104 } 12105 12106 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 12107 SourceLocation StartLoc, 12108 SourceLocation LParenLoc, 12109 SourceLocation EndLoc) { 12110 MappableVarListInfo MVLI(VarList); 12111 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc); 12112 if (MVLI.ProcessedVarList.empty()) 12113 return nullptr; 12114 12115 return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc, 12116 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 12117 MVLI.VarComponents); 12118 } 12119 12120 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 12121 SourceLocation StartLoc, 12122 SourceLocation LParenLoc, 12123 SourceLocation EndLoc) { 12124 MappableVarListInfo MVLI(VarList); 12125 SmallVector<Expr *, 8> PrivateCopies; 12126 SmallVector<Expr *, 8> Inits; 12127 12128 for (auto &RefExpr : VarList) { 12129 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 12130 SourceLocation ELoc; 12131 SourceRange ERange; 12132 Expr *SimpleRefExpr = RefExpr; 12133 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12134 if (Res.second) { 12135 // It will be analyzed later. 12136 MVLI.ProcessedVarList.push_back(RefExpr); 12137 PrivateCopies.push_back(nullptr); 12138 Inits.push_back(nullptr); 12139 } 12140 ValueDecl *D = Res.first; 12141 if (!D) 12142 continue; 12143 12144 QualType Type = D->getType(); 12145 Type = Type.getNonReferenceType().getUnqualifiedType(); 12146 12147 auto *VD = dyn_cast<VarDecl>(D); 12148 12149 // Item should be a pointer or reference to pointer. 12150 if (!Type->isPointerType()) { 12151 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 12152 << 0 << RefExpr->getSourceRange(); 12153 continue; 12154 } 12155 12156 // Build the private variable and the expression that refers to it. 12157 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 12158 D->hasAttrs() ? &D->getAttrs() : nullptr); 12159 if (VDPrivate->isInvalidDecl()) 12160 continue; 12161 12162 CurContext->addDecl(VDPrivate); 12163 auto VDPrivateRefExpr = buildDeclRefExpr( 12164 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 12165 12166 // Add temporary variable to initialize the private copy of the pointer. 12167 auto *VDInit = 12168 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 12169 auto *VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 12170 RefExpr->getExprLoc()); 12171 AddInitializerToDecl(VDPrivate, 12172 DefaultLvalueConversion(VDInitRefExpr).get(), 12173 /*DirectInit=*/false, /*TypeMayContainAuto=*/false); 12174 12175 // If required, build a capture to implement the privatization initialized 12176 // with the current list item value. 12177 DeclRefExpr *Ref = nullptr; 12178 if (!VD) 12179 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 12180 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 12181 PrivateCopies.push_back(VDPrivateRefExpr); 12182 Inits.push_back(VDInitRefExpr); 12183 12184 // We need to add a data sharing attribute for this variable to make sure it 12185 // is correctly captured. A variable that shows up in a use_device_ptr has 12186 // similar properties of a first private variable. 12187 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 12188 12189 // Create a mappable component for the list item. List items in this clause 12190 // only need a component. 12191 MVLI.VarBaseDeclarations.push_back(D); 12192 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 12193 MVLI.VarComponents.back().push_back( 12194 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 12195 } 12196 12197 if (MVLI.ProcessedVarList.empty()) 12198 return nullptr; 12199 12200 return OMPUseDevicePtrClause::Create( 12201 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 12202 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents); 12203 } 12204 12205 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 12206 SourceLocation StartLoc, 12207 SourceLocation LParenLoc, 12208 SourceLocation EndLoc) { 12209 MappableVarListInfo MVLI(VarList); 12210 for (auto &RefExpr : VarList) { 12211 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 12212 SourceLocation ELoc; 12213 SourceRange ERange; 12214 Expr *SimpleRefExpr = RefExpr; 12215 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 12216 if (Res.second) { 12217 // It will be analyzed later. 12218 MVLI.ProcessedVarList.push_back(RefExpr); 12219 } 12220 ValueDecl *D = Res.first; 12221 if (!D) 12222 continue; 12223 12224 QualType Type = D->getType(); 12225 // item should be a pointer or array or reference to pointer or array 12226 if (!Type.getNonReferenceType()->isPointerType() && 12227 !Type.getNonReferenceType()->isArrayType()) { 12228 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 12229 << 0 << RefExpr->getSourceRange(); 12230 continue; 12231 } 12232 12233 // Check if the declaration in the clause does not show up in any data 12234 // sharing attribute. 12235 auto DVar = DSAStack->getTopDSA(D, false); 12236 if (isOpenMPPrivate(DVar.CKind)) { 12237 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 12238 << getOpenMPClauseName(DVar.CKind) 12239 << getOpenMPClauseName(OMPC_is_device_ptr) 12240 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 12241 ReportOriginalDSA(*this, DSAStack, D, DVar); 12242 continue; 12243 } 12244 12245 Expr *ConflictExpr; 12246 if (DSAStack->checkMappableExprComponentListsForDecl( 12247 D, /*CurrentRegionOnly=*/true, 12248 [&ConflictExpr]( 12249 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 12250 OpenMPClauseKind) -> bool { 12251 ConflictExpr = R.front().getAssociatedExpression(); 12252 return true; 12253 })) { 12254 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 12255 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 12256 << ConflictExpr->getSourceRange(); 12257 continue; 12258 } 12259 12260 // Store the components in the stack so that they can be used to check 12261 // against other clauses later on. 12262 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 12263 DSAStack->addMappableExpressionComponents( 12264 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 12265 12266 // Record the expression we've just processed. 12267 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 12268 12269 // Create a mappable component for the list item. List items in this clause 12270 // only need a component. We use a null declaration to signal fields in 12271 // 'this'. 12272 assert((isa<DeclRefExpr>(SimpleRefExpr) || 12273 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 12274 "Unexpected device pointer expression!"); 12275 MVLI.VarBaseDeclarations.push_back( 12276 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 12277 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 12278 MVLI.VarComponents.back().push_back(MC); 12279 } 12280 12281 if (MVLI.ProcessedVarList.empty()) 12282 return nullptr; 12283 12284 return OMPIsDevicePtrClause::Create( 12285 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 12286 MVLI.VarBaseDeclarations, MVLI.VarComponents); 12287 } 12288