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 DeclSAMapTy Threadprivates; 122 const FunctionScopeInfo *CurrentNonCapturingFunctionScope = nullptr; 123 SmallVector<std::pair<StackTy, const FunctionScopeInfo *>, 4> Stack; 124 /// \brief true, if check for DSA must be from parent directive, false, if 125 /// from current directive. 126 OpenMPClauseKind ClauseKindMode = OMPC_unknown; 127 Sema &SemaRef; 128 bool ForceCapturing = false; 129 CriticalsWithHintsTy Criticals; 130 131 typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; 132 133 DSAVarData getDSA(StackTy::reverse_iterator &Iter, ValueDecl *D); 134 135 /// \brief Checks if the variable is a local for OpenMP region. 136 bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter); 137 138 bool isStackEmpty() const { 139 return Stack.empty() || 140 Stack.back().second != CurrentNonCapturingFunctionScope || 141 Stack.back().first.empty(); 142 } 143 144 public: 145 explicit DSAStackTy(Sema &S) : SemaRef(S) {} 146 147 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 148 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 149 150 bool isForceVarCapturing() const { return ForceCapturing; } 151 void setForceVarCapturing(bool V) { ForceCapturing = V; } 152 153 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 154 Scope *CurScope, SourceLocation Loc) { 155 if (Stack.empty() || 156 Stack.back().second != CurrentNonCapturingFunctionScope) 157 Stack.emplace_back(StackTy(), CurrentNonCapturingFunctionScope); 158 Stack.back().first.emplace_back(DKind, DirName, CurScope, Loc); 159 Stack.back().first.back().DefaultAttrLoc = Loc; 160 } 161 162 void pop() { 163 assert(!Stack.back().first.empty() && 164 "Data-sharing attributes stack is empty!"); 165 Stack.back().first.pop_back(); 166 } 167 168 /// Start new OpenMP region stack in new non-capturing function. 169 void pushFunction() { 170 const FunctionScopeInfo *CurFnScope = SemaRef.getCurFunction(); 171 assert(!isa<CapturingScopeInfo>(CurFnScope)); 172 CurrentNonCapturingFunctionScope = CurFnScope; 173 } 174 /// Pop region stack for non-capturing function. 175 void popFunction(const FunctionScopeInfo *OldFSI) { 176 if (!Stack.empty() && Stack.back().second == OldFSI) { 177 assert(Stack.back().first.empty()); 178 Stack.pop_back(); 179 } 180 CurrentNonCapturingFunctionScope = nullptr; 181 for (const FunctionScopeInfo *FSI : llvm::reverse(SemaRef.FunctionScopes)) { 182 if (!isa<CapturingScopeInfo>(FSI)) { 183 CurrentNonCapturingFunctionScope = FSI; 184 break; 185 } 186 } 187 } 188 189 void addCriticalWithHint(OMPCriticalDirective *D, llvm::APSInt Hint) { 190 Criticals[D->getDirectiveName().getAsString()] = std::make_pair(D, Hint); 191 } 192 const std::pair<OMPCriticalDirective *, llvm::APSInt> 193 getCriticalWithHint(const DeclarationNameInfo &Name) const { 194 auto I = Criticals.find(Name.getAsString()); 195 if (I != Criticals.end()) 196 return I->second; 197 return std::make_pair(nullptr, llvm::APSInt()); 198 } 199 /// \brief If 'aligned' declaration for given variable \a D was not seen yet, 200 /// add it and return NULL; otherwise return previous occurrence's expression 201 /// for diagnostics. 202 Expr *addUniqueAligned(ValueDecl *D, Expr *NewDE); 203 204 /// \brief Register specified variable as loop control variable. 205 void addLoopControlVariable(ValueDecl *D, VarDecl *Capture); 206 /// \brief Check if the specified variable is a loop control variable for 207 /// current region. 208 /// \return The index of the loop control variable in the list of associated 209 /// for-loops (from outer to inner). 210 LCDeclInfo isLoopControlVariable(ValueDecl *D); 211 /// \brief Check if the specified variable is a loop control variable for 212 /// parent region. 213 /// \return The index of the loop control variable in the list of associated 214 /// for-loops (from outer to inner). 215 LCDeclInfo isParentLoopControlVariable(ValueDecl *D); 216 /// \brief Get the loop control variable for the I-th loop (or nullptr) in 217 /// parent directive. 218 ValueDecl *getParentLoopControlVariable(unsigned I); 219 220 /// \brief Adds explicit data sharing attribute to the specified declaration. 221 void addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 222 DeclRefExpr *PrivateCopy = nullptr); 223 224 /// \brief Returns data sharing attributes from top of the stack for the 225 /// specified declaration. 226 DSAVarData getTopDSA(ValueDecl *D, bool FromParent); 227 /// \brief Returns data-sharing attributes for the specified declaration. 228 DSAVarData getImplicitDSA(ValueDecl *D, bool FromParent); 229 /// \brief Checks if the specified variables has data-sharing attributes which 230 /// match specified \a CPred predicate in any directive which matches \a DPred 231 /// predicate. 232 DSAVarData hasDSA(ValueDecl *D, 233 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 234 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 235 bool FromParent); 236 /// \brief Checks if the specified variables has data-sharing attributes which 237 /// match specified \a CPred predicate in any innermost directive which 238 /// matches \a DPred predicate. 239 DSAVarData 240 hasInnermostDSA(ValueDecl *D, 241 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 242 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 243 bool FromParent); 244 /// \brief Checks if the specified variables has explicit data-sharing 245 /// attributes which match specified \a CPred predicate at the specified 246 /// OpenMP region. 247 bool hasExplicitDSA(ValueDecl *D, 248 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 249 unsigned Level, bool NotLastprivate = false); 250 251 /// \brief Returns true if the directive at level \Level matches in the 252 /// specified \a DPred predicate. 253 bool hasExplicitDirective( 254 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 255 unsigned Level); 256 257 /// \brief Finds a directive which matches specified \a DPred predicate. 258 bool hasDirective(const llvm::function_ref<bool(OpenMPDirectiveKind, 259 const DeclarationNameInfo &, 260 SourceLocation)> &DPred, 261 bool FromParent); 262 263 /// \brief Returns currently analyzed directive. 264 OpenMPDirectiveKind getCurrentDirective() const { 265 return isStackEmpty() ? OMPD_unknown : Stack.back().first.back().Directive; 266 } 267 /// \brief Returns parent directive. 268 OpenMPDirectiveKind getParentDirective() const { 269 if (isStackEmpty() || Stack.back().first.size() == 1) 270 return OMPD_unknown; 271 return std::next(Stack.back().first.rbegin())->Directive; 272 } 273 274 /// \brief Set default data sharing attribute to none. 275 void setDefaultDSANone(SourceLocation Loc) { 276 assert(!isStackEmpty()); 277 Stack.back().first.back().DefaultAttr = DSA_none; 278 Stack.back().first.back().DefaultAttrLoc = Loc; 279 } 280 /// \brief Set default data sharing attribute to shared. 281 void setDefaultDSAShared(SourceLocation Loc) { 282 assert(!isStackEmpty()); 283 Stack.back().first.back().DefaultAttr = DSA_shared; 284 Stack.back().first.back().DefaultAttrLoc = Loc; 285 } 286 287 DefaultDataSharingAttributes getDefaultDSA() const { 288 return isStackEmpty() ? DSA_unspecified 289 : Stack.back().first.back().DefaultAttr; 290 } 291 SourceLocation getDefaultDSALocation() const { 292 return isStackEmpty() ? SourceLocation() 293 : Stack.back().first.back().DefaultAttrLoc; 294 } 295 296 /// \brief Checks if the specified variable is a threadprivate. 297 bool isThreadPrivate(VarDecl *D) { 298 DSAVarData DVar = getTopDSA(D, false); 299 return isOpenMPThreadPrivate(DVar.CKind); 300 } 301 302 /// \brief Marks current region as ordered (it has an 'ordered' clause). 303 void setOrderedRegion(bool IsOrdered, Expr *Param) { 304 assert(!isStackEmpty()); 305 Stack.back().first.back().OrderedRegion.setInt(IsOrdered); 306 Stack.back().first.back().OrderedRegion.setPointer(Param); 307 } 308 /// \brief Returns true, if parent region is ordered (has associated 309 /// 'ordered' clause), false - otherwise. 310 bool isParentOrderedRegion() const { 311 if (isStackEmpty() || Stack.back().first.size() == 1) 312 return false; 313 return std::next(Stack.back().first.rbegin())->OrderedRegion.getInt(); 314 } 315 /// \brief Returns optional parameter for the ordered region. 316 Expr *getParentOrderedRegionParam() const { 317 if (isStackEmpty() || Stack.back().first.size() == 1) 318 return nullptr; 319 return std::next(Stack.back().first.rbegin())->OrderedRegion.getPointer(); 320 } 321 /// \brief Marks current region as nowait (it has a 'nowait' clause). 322 void setNowaitRegion(bool IsNowait = true) { 323 assert(!isStackEmpty()); 324 Stack.back().first.back().NowaitRegion = IsNowait; 325 } 326 /// \brief Returns true, if parent region is nowait (has associated 327 /// 'nowait' clause), false - otherwise. 328 bool isParentNowaitRegion() const { 329 if (isStackEmpty() || Stack.back().first.size() == 1) 330 return false; 331 return std::next(Stack.back().first.rbegin())->NowaitRegion; 332 } 333 /// \brief Marks parent region as cancel region. 334 void setParentCancelRegion(bool Cancel = true) { 335 if (!isStackEmpty() && Stack.back().first.size() > 1) { 336 auto &StackElemRef = *std::next(Stack.back().first.rbegin()); 337 StackElemRef.CancelRegion |= StackElemRef.CancelRegion || Cancel; 338 } 339 } 340 /// \brief Return true if current region has inner cancel construct. 341 bool isCancelRegion() const { 342 return isStackEmpty() ? false : Stack.back().first.back().CancelRegion; 343 } 344 345 /// \brief Set collapse value for the region. 346 void setAssociatedLoops(unsigned Val) { 347 assert(!isStackEmpty()); 348 Stack.back().first.back().AssociatedLoops = Val; 349 } 350 /// \brief Return collapse value for region. 351 unsigned getAssociatedLoops() const { 352 return isStackEmpty() ? 0 : Stack.back().first.back().AssociatedLoops; 353 } 354 355 /// \brief Marks current target region as one with closely nested teams 356 /// region. 357 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 358 if (!isStackEmpty() && Stack.back().first.size() > 1) { 359 std::next(Stack.back().first.rbegin())->InnerTeamsRegionLoc = 360 TeamsRegionLoc; 361 } 362 } 363 /// \brief Returns true, if current region has closely nested teams region. 364 bool hasInnerTeamsRegion() const { 365 return getInnerTeamsRegionLoc().isValid(); 366 } 367 /// \brief Returns location of the nested teams region (if any). 368 SourceLocation getInnerTeamsRegionLoc() const { 369 return isStackEmpty() ? SourceLocation() 370 : Stack.back().first.back().InnerTeamsRegionLoc; 371 } 372 373 Scope *getCurScope() const { 374 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 375 } 376 Scope *getCurScope() { 377 return isStackEmpty() ? nullptr : Stack.back().first.back().CurScope; 378 } 379 SourceLocation getConstructLoc() { 380 return isStackEmpty() ? SourceLocation() 381 : Stack.back().first.back().ConstructLoc; 382 } 383 384 /// Do the check specified in \a Check to all component lists and return true 385 /// if any issue is found. 386 bool checkMappableExprComponentListsForDecl( 387 ValueDecl *VD, bool CurrentRegionOnly, 388 const llvm::function_ref< 389 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 390 OpenMPClauseKind)> &Check) { 391 if (isStackEmpty()) 392 return false; 393 auto SI = Stack.back().first.rbegin(); 394 auto SE = Stack.back().first.rend(); 395 396 if (SI == SE) 397 return false; 398 399 if (CurrentRegionOnly) { 400 SE = std::next(SI); 401 } else { 402 ++SI; 403 } 404 405 for (; SI != SE; ++SI) { 406 auto MI = SI->MappedExprComponents.find(VD); 407 if (MI != SI->MappedExprComponents.end()) 408 for (auto &L : MI->second.Components) 409 if (Check(L, MI->second.Kind)) 410 return true; 411 } 412 return false; 413 } 414 415 /// Do the check specified in \a Check to all component lists at a given level 416 /// and return true if any issue is found. 417 bool checkMappableExprComponentListsForDeclAtLevel( 418 ValueDecl *VD, unsigned Level, 419 const llvm::function_ref< 420 bool(OMPClauseMappableExprCommon::MappableExprComponentListRef, 421 OpenMPClauseKind)> &Check) { 422 if (isStackEmpty()) 423 return false; 424 425 auto StartI = Stack.back().first.begin(); 426 auto EndI = Stack.back().first.end(); 427 if (std::distance(StartI, EndI) <= (int)Level) 428 return false; 429 std::advance(StartI, Level); 430 431 auto MI = StartI->MappedExprComponents.find(VD); 432 if (MI != StartI->MappedExprComponents.end()) 433 for (auto &L : MI->second.Components) 434 if (Check(L, MI->second.Kind)) 435 return true; 436 return false; 437 } 438 439 /// Create a new mappable expression component list associated with a given 440 /// declaration and initialize it with the provided list of components. 441 void addMappableExpressionComponents( 442 ValueDecl *VD, 443 OMPClauseMappableExprCommon::MappableExprComponentListRef Components, 444 OpenMPClauseKind WhereFoundClauseKind) { 445 assert(!isStackEmpty() && 446 "Not expecting to retrieve components from a empty stack!"); 447 auto &MEC = Stack.back().first.back().MappedExprComponents[VD]; 448 // Create new entry and append the new components there. 449 MEC.Components.resize(MEC.Components.size() + 1); 450 MEC.Components.back().append(Components.begin(), Components.end()); 451 MEC.Kind = WhereFoundClauseKind; 452 } 453 454 unsigned getNestingLevel() const { 455 assert(!isStackEmpty()); 456 return Stack.back().first.size() - 1; 457 } 458 void addDoacrossDependClause(OMPDependClause *C, OperatorOffsetTy &OpsOffs) { 459 assert(!isStackEmpty() && Stack.back().first.size() > 1); 460 auto &StackElem = *std::next(Stack.back().first.rbegin()); 461 assert(isOpenMPWorksharingDirective(StackElem.Directive)); 462 StackElem.DoacrossDepends.insert({C, OpsOffs}); 463 } 464 llvm::iterator_range<DoacrossDependMapTy::const_iterator> 465 getDoacrossDependClauses() const { 466 assert(!isStackEmpty()); 467 auto &StackElem = Stack.back().first.back(); 468 if (isOpenMPWorksharingDirective(StackElem.Directive)) { 469 auto &Ref = StackElem.DoacrossDepends; 470 return llvm::make_range(Ref.begin(), Ref.end()); 471 } 472 return llvm::make_range(StackElem.DoacrossDepends.end(), 473 StackElem.DoacrossDepends.end()); 474 } 475 }; 476 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { 477 return isOpenMPParallelDirective(DKind) || isOpenMPTaskingDirective(DKind) || 478 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; 479 } 480 } // namespace 481 482 static ValueDecl *getCanonicalDecl(ValueDecl *D) { 483 auto *VD = dyn_cast<VarDecl>(D); 484 auto *FD = dyn_cast<FieldDecl>(D); 485 if (VD != nullptr) { 486 VD = VD->getCanonicalDecl(); 487 D = VD; 488 } else { 489 assert(FD); 490 FD = FD->getCanonicalDecl(); 491 D = FD; 492 } 493 return D; 494 } 495 496 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator &Iter, 497 ValueDecl *D) { 498 D = getCanonicalDecl(D); 499 auto *VD = dyn_cast<VarDecl>(D); 500 auto *FD = dyn_cast<FieldDecl>(D); 501 DSAVarData DVar; 502 if (isStackEmpty() || Iter == Stack.back().first.rend()) { 503 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 504 // in a region but not in construct] 505 // File-scope or namespace-scope variables referenced in called routines 506 // in the region are shared unless they appear in a threadprivate 507 // directive. 508 if (VD && !VD->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D)) 509 DVar.CKind = OMPC_shared; 510 511 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 512 // in a region but not in construct] 513 // Variables with static storage duration that are declared in called 514 // routines in the region are shared. 515 if (VD && VD->hasGlobalStorage()) 516 DVar.CKind = OMPC_shared; 517 518 // Non-static data members are shared by default. 519 if (FD) 520 DVar.CKind = OMPC_shared; 521 522 return DVar; 523 } 524 525 DVar.DKind = Iter->Directive; 526 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 527 // in a Construct, C/C++, predetermined, p.1] 528 // Variables with automatic storage duration that are declared in a scope 529 // inside the construct are private. 530 if (VD && isOpenMPLocal(VD, Iter) && VD->isLocalVarDecl() && 531 (VD->getStorageClass() == SC_Auto || VD->getStorageClass() == SC_None)) { 532 DVar.CKind = OMPC_private; 533 return DVar; 534 } 535 536 // Explicitly specified attributes and local variables with predetermined 537 // attributes. 538 if (Iter->SharingMap.count(D)) { 539 DVar.RefExpr = Iter->SharingMap[D].RefExpr.getPointer(); 540 DVar.PrivateCopy = Iter->SharingMap[D].PrivateCopy; 541 DVar.CKind = Iter->SharingMap[D].Attributes; 542 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 543 return DVar; 544 } 545 546 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 547 // in a Construct, C/C++, implicitly determined, p.1] 548 // In a parallel or task construct, the data-sharing attributes of these 549 // variables are determined by the default clause, if present. 550 switch (Iter->DefaultAttr) { 551 case DSA_shared: 552 DVar.CKind = OMPC_shared; 553 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 554 return DVar; 555 case DSA_none: 556 return DVar; 557 case DSA_unspecified: 558 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 559 // in a Construct, implicitly determined, p.2] 560 // In a parallel construct, if no default clause is present, these 561 // variables are shared. 562 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 563 if (isOpenMPParallelDirective(DVar.DKind) || 564 isOpenMPTeamsDirective(DVar.DKind)) { 565 DVar.CKind = OMPC_shared; 566 return DVar; 567 } 568 569 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 570 // in a Construct, implicitly determined, p.4] 571 // In a task construct, if no default clause is present, a variable that in 572 // the enclosing context is determined to be shared by all implicit tasks 573 // bound to the current team is shared. 574 if (isOpenMPTaskingDirective(DVar.DKind)) { 575 DSAVarData DVarTemp; 576 auto I = Iter, E = Stack.back().first.rend(); 577 do { 578 ++I; 579 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 580 // Referenced in a Construct, implicitly determined, p.6] 581 // In a task construct, if no default clause is present, a variable 582 // whose data-sharing attribute is not determined by the rules above is 583 // firstprivate. 584 DVarTemp = getDSA(I, D); 585 if (DVarTemp.CKind != OMPC_shared) { 586 DVar.RefExpr = nullptr; 587 DVar.CKind = OMPC_firstprivate; 588 return DVar; 589 } 590 } while (I != E && !isParallelOrTaskRegion(I->Directive)); 591 DVar.CKind = 592 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 593 return DVar; 594 } 595 } 596 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 597 // in a Construct, implicitly determined, p.3] 598 // For constructs other than task, if no default clause is present, these 599 // variables inherit their data-sharing attributes from the enclosing 600 // context. 601 return getDSA(++Iter, D); 602 } 603 604 Expr *DSAStackTy::addUniqueAligned(ValueDecl *D, Expr *NewDE) { 605 assert(!isStackEmpty() && "Data sharing attributes stack is empty"); 606 D = getCanonicalDecl(D); 607 auto &StackElem = Stack.back().first.back(); 608 auto It = StackElem.AlignedMap.find(D); 609 if (It == StackElem.AlignedMap.end()) { 610 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 611 StackElem.AlignedMap[D] = NewDE; 612 return nullptr; 613 } else { 614 assert(It->second && "Unexpected nullptr expr in the aligned map"); 615 return It->second; 616 } 617 return nullptr; 618 } 619 620 void DSAStackTy::addLoopControlVariable(ValueDecl *D, VarDecl *Capture) { 621 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 622 D = getCanonicalDecl(D); 623 auto &StackElem = Stack.back().first.back(); 624 StackElem.LCVMap.insert( 625 {D, LCDeclInfo(StackElem.LCVMap.size() + 1, Capture)}); 626 } 627 628 DSAStackTy::LCDeclInfo DSAStackTy::isLoopControlVariable(ValueDecl *D) { 629 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 630 D = getCanonicalDecl(D); 631 auto &StackElem = Stack.back().first.back(); 632 auto It = StackElem.LCVMap.find(D); 633 if (It != StackElem.LCVMap.end()) 634 return It->second; 635 return {0, nullptr}; 636 } 637 638 DSAStackTy::LCDeclInfo DSAStackTy::isParentLoopControlVariable(ValueDecl *D) { 639 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 640 "Data-sharing attributes stack is empty"); 641 D = getCanonicalDecl(D); 642 auto &StackElem = *std::next(Stack.back().first.rbegin()); 643 auto It = StackElem.LCVMap.find(D); 644 if (It != StackElem.LCVMap.end()) 645 return It->second; 646 return {0, nullptr}; 647 } 648 649 ValueDecl *DSAStackTy::getParentLoopControlVariable(unsigned I) { 650 assert(!isStackEmpty() && Stack.back().first.size() > 1 && 651 "Data-sharing attributes stack is empty"); 652 auto &StackElem = *std::next(Stack.back().first.rbegin()); 653 if (StackElem.LCVMap.size() < I) 654 return nullptr; 655 for (auto &Pair : StackElem.LCVMap) 656 if (Pair.second.first == I) 657 return Pair.first; 658 return nullptr; 659 } 660 661 void DSAStackTy::addDSA(ValueDecl *D, Expr *E, OpenMPClauseKind A, 662 DeclRefExpr *PrivateCopy) { 663 D = getCanonicalDecl(D); 664 if (A == OMPC_threadprivate) { 665 auto &Data = Threadprivates[D]; 666 Data.Attributes = A; 667 Data.RefExpr.setPointer(E); 668 Data.PrivateCopy = nullptr; 669 } else { 670 assert(!isStackEmpty() && "Data-sharing attributes stack is empty"); 671 auto &Data = Stack.back().first.back().SharingMap[D]; 672 assert(Data.Attributes == OMPC_unknown || (A == Data.Attributes) || 673 (A == OMPC_firstprivate && Data.Attributes == OMPC_lastprivate) || 674 (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) || 675 (isLoopControlVariable(D).first && A == OMPC_private)); 676 if (A == OMPC_lastprivate && Data.Attributes == OMPC_firstprivate) { 677 Data.RefExpr.setInt(/*IntVal=*/true); 678 return; 679 } 680 const bool IsLastprivate = 681 A == OMPC_lastprivate || Data.Attributes == OMPC_lastprivate; 682 Data.Attributes = A; 683 Data.RefExpr.setPointerAndInt(E, IsLastprivate); 684 Data.PrivateCopy = PrivateCopy; 685 if (PrivateCopy) { 686 auto &Data = Stack.back().first.back().SharingMap[PrivateCopy->getDecl()]; 687 Data.Attributes = A; 688 Data.RefExpr.setPointerAndInt(PrivateCopy, IsLastprivate); 689 Data.PrivateCopy = nullptr; 690 } 691 } 692 } 693 694 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) { 695 D = D->getCanonicalDecl(); 696 if (!isStackEmpty() && Stack.back().first.size() > 1) { 697 reverse_iterator I = Iter, E = Stack.back().first.rend(); 698 Scope *TopScope = nullptr; 699 while (I != E && !isParallelOrTaskRegion(I->Directive)) 700 ++I; 701 if (I == E) 702 return false; 703 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 704 Scope *CurScope = getCurScope(); 705 while (CurScope != TopScope && !CurScope->isDeclScope(D)) 706 CurScope = CurScope->getParent(); 707 return CurScope != TopScope; 708 } 709 return false; 710 } 711 712 /// \brief Build a variable declaration for OpenMP loop iteration variable. 713 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 714 StringRef Name, const AttrVec *Attrs = nullptr) { 715 DeclContext *DC = SemaRef.CurContext; 716 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 717 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 718 VarDecl *Decl = 719 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 720 if (Attrs) { 721 for (specific_attr_iterator<AlignedAttr> I(Attrs->begin()), E(Attrs->end()); 722 I != E; ++I) 723 Decl->addAttr(*I); 724 } 725 Decl->setImplicit(); 726 return Decl; 727 } 728 729 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 730 SourceLocation Loc, 731 bool RefersToCapture = false) { 732 D->setReferenced(); 733 D->markUsed(S.Context); 734 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 735 SourceLocation(), D, RefersToCapture, Loc, Ty, 736 VK_LValue); 737 } 738 739 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(ValueDecl *D, bool FromParent) { 740 D = getCanonicalDecl(D); 741 DSAVarData DVar; 742 743 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 744 // in a Construct, C/C++, predetermined, p.1] 745 // Variables appearing in threadprivate directives are threadprivate. 746 auto *VD = dyn_cast<VarDecl>(D); 747 if ((VD && VD->getTLSKind() != VarDecl::TLS_None && 748 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 749 SemaRef.getLangOpts().OpenMPUseTLS && 750 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 751 (VD && VD->getStorageClass() == SC_Register && 752 VD->hasAttr<AsmLabelAttr>() && !VD->isLocalVarDecl())) { 753 addDSA(D, buildDeclRefExpr(SemaRef, VD, D->getType().getNonReferenceType(), 754 D->getLocation()), 755 OMPC_threadprivate); 756 } 757 auto TI = Threadprivates.find(D); 758 if (TI != Threadprivates.end()) { 759 DVar.RefExpr = TI->getSecond().RefExpr.getPointer(); 760 DVar.CKind = OMPC_threadprivate; 761 return DVar; 762 } 763 764 if (isStackEmpty()) 765 // Not in OpenMP execution region and top scope was already checked. 766 return DVar; 767 768 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 769 // in a Construct, C/C++, predetermined, p.4] 770 // Static data members are shared. 771 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 772 // in a Construct, C/C++, predetermined, p.7] 773 // Variables with static storage duration that are declared in a scope 774 // inside the construct are shared. 775 auto &&MatchesAlways = [](OpenMPDirectiveKind) -> bool { return true; }; 776 if (VD && VD->isStaticDataMember()) { 777 DSAVarData DVarTemp = hasDSA(D, isOpenMPPrivate, MatchesAlways, FromParent); 778 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 779 return DVar; 780 781 DVar.CKind = OMPC_shared; 782 return DVar; 783 } 784 785 QualType Type = D->getType().getNonReferenceType().getCanonicalType(); 786 bool IsConstant = Type.isConstant(SemaRef.getASTContext()); 787 Type = SemaRef.getASTContext().getBaseElementType(Type); 788 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 789 // in a Construct, C/C++, predetermined, p.6] 790 // Variables with const qualified type having no mutable member are 791 // shared. 792 CXXRecordDecl *RD = 793 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 794 if (auto *CTSD = dyn_cast_or_null<ClassTemplateSpecializationDecl>(RD)) 795 if (auto *CTD = CTSD->getSpecializedTemplate()) 796 RD = CTD->getTemplatedDecl(); 797 if (IsConstant && 798 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasDefinition() && 799 RD->hasMutableFields())) { 800 // Variables with const-qualified type having no mutable member may be 801 // listed in a firstprivate clause, even if they are static data members. 802 DSAVarData DVarTemp = hasDSA( 803 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_firstprivate; }, 804 MatchesAlways, FromParent); 805 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 806 return DVar; 807 808 DVar.CKind = OMPC_shared; 809 return DVar; 810 } 811 812 // Explicitly specified attributes and local variables with predetermined 813 // attributes. 814 auto StartI = std::next(Stack.back().first.rbegin()); 815 auto EndI = Stack.back().first.rend(); 816 if (FromParent && StartI != EndI) 817 StartI = std::next(StartI); 818 auto I = std::prev(StartI); 819 if (I->SharingMap.count(D)) { 820 DVar.RefExpr = I->SharingMap[D].RefExpr.getPointer(); 821 DVar.PrivateCopy = I->SharingMap[D].PrivateCopy; 822 DVar.CKind = I->SharingMap[D].Attributes; 823 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 824 } 825 826 return DVar; 827 } 828 829 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(ValueDecl *D, 830 bool FromParent) { 831 if (isStackEmpty()) { 832 StackTy::reverse_iterator I; 833 return getDSA(I, D); 834 } 835 D = getCanonicalDecl(D); 836 auto StartI = Stack.back().first.rbegin(); 837 auto EndI = Stack.back().first.rend(); 838 if (FromParent && StartI != EndI) 839 StartI = std::next(StartI); 840 return getDSA(StartI, D); 841 } 842 843 DSAStackTy::DSAVarData 844 DSAStackTy::hasDSA(ValueDecl *D, 845 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 846 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 847 bool FromParent) { 848 if (isStackEmpty()) 849 return {}; 850 D = getCanonicalDecl(D); 851 auto I = (FromParent && Stack.back().first.size() > 1) 852 ? std::next(Stack.back().first.rbegin()) 853 : Stack.back().first.rbegin(); 854 auto EndI = Stack.back().first.rend(); 855 while (std::distance(I, EndI) > 1) { 856 std::advance(I, 1); 857 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) 858 continue; 859 DSAVarData DVar = getDSA(I, D); 860 if (CPred(DVar.CKind)) 861 return DVar; 862 } 863 return {}; 864 } 865 866 DSAStackTy::DSAVarData DSAStackTy::hasInnermostDSA( 867 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 868 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 869 bool FromParent) { 870 if (isStackEmpty()) 871 return {}; 872 D = getCanonicalDecl(D); 873 auto StartI = std::next(Stack.back().first.rbegin()); 874 auto EndI = Stack.back().first.rend(); 875 if (FromParent && StartI != EndI) 876 StartI = std::next(StartI); 877 if (StartI == EndI || !DPred(StartI->Directive)) 878 return {}; 879 DSAVarData DVar = getDSA(StartI, D); 880 return CPred(DVar.CKind) ? DVar : DSAVarData(); 881 } 882 883 bool DSAStackTy::hasExplicitDSA( 884 ValueDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 885 unsigned Level, bool NotLastprivate) { 886 if (CPred(ClauseKindMode)) 887 return true; 888 if (isStackEmpty()) 889 return false; 890 D = getCanonicalDecl(D); 891 auto StartI = Stack.back().first.begin(); 892 auto EndI = Stack.back().first.end(); 893 if (std::distance(StartI, EndI) <= (int)Level) 894 return false; 895 std::advance(StartI, Level); 896 return (StartI->SharingMap.count(D) > 0) && 897 StartI->SharingMap[D].RefExpr.getPointer() && 898 CPred(StartI->SharingMap[D].Attributes) && 899 (!NotLastprivate || !StartI->SharingMap[D].RefExpr.getInt()); 900 } 901 902 bool DSAStackTy::hasExplicitDirective( 903 const llvm::function_ref<bool(OpenMPDirectiveKind)> &DPred, 904 unsigned Level) { 905 if (isStackEmpty()) 906 return false; 907 auto StartI = Stack.back().first.begin(); 908 auto EndI = Stack.back().first.end(); 909 if (std::distance(StartI, EndI) <= (int)Level) 910 return false; 911 std::advance(StartI, Level); 912 return DPred(StartI->Directive); 913 } 914 915 bool DSAStackTy::hasDirective( 916 const llvm::function_ref<bool(OpenMPDirectiveKind, 917 const DeclarationNameInfo &, SourceLocation)> 918 &DPred, 919 bool FromParent) { 920 // We look only in the enclosing region. 921 if (isStackEmpty()) 922 return false; 923 auto StartI = std::next(Stack.back().first.rbegin()); 924 auto EndI = Stack.back().first.rend(); 925 if (FromParent && StartI != EndI) 926 StartI = std::next(StartI); 927 for (auto I = StartI, EE = EndI; I != EE; ++I) { 928 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 929 return true; 930 } 931 return false; 932 } 933 934 void Sema::InitDataSharingAttributesStack() { 935 VarDataSharingAttributesStack = new DSAStackTy(*this); 936 } 937 938 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 939 940 void Sema::pushOpenMPFunctionRegion() { 941 DSAStack->pushFunction(); 942 } 943 944 void Sema::popOpenMPFunctionRegion(const FunctionScopeInfo *OldFSI) { 945 DSAStack->popFunction(OldFSI); 946 } 947 948 bool Sema::IsOpenMPCapturedByRef(ValueDecl *D, unsigned Level) { 949 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 950 951 auto &Ctx = getASTContext(); 952 bool IsByRef = true; 953 954 // Find the directive that is associated with the provided scope. 955 auto Ty = D->getType(); 956 957 if (DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, Level)) { 958 // This table summarizes how a given variable should be passed to the device 959 // given its type and the clauses where it appears. This table is based on 960 // the description in OpenMP 4.5 [2.10.4, target Construct] and 961 // OpenMP 4.5 [2.15.5, Data-mapping Attribute Rules and Clauses]. 962 // 963 // ========================================================================= 964 // | type | defaultmap | pvt | first | is_device_ptr | map | res. | 965 // | |(tofrom:scalar)| | pvt | | | | 966 // ========================================================================= 967 // | scl | | | | - | | bycopy| 968 // | scl | | - | x | - | - | bycopy| 969 // | scl | | x | - | - | - | null | 970 // | scl | x | | | - | | byref | 971 // | scl | x | - | x | - | - | bycopy| 972 // | scl | x | x | - | - | - | null | 973 // | scl | | - | - | - | x | byref | 974 // | scl | x | - | - | - | x | byref | 975 // 976 // | agg | n.a. | | | - | | byref | 977 // | agg | n.a. | - | x | - | - | byref | 978 // | agg | n.a. | x | - | - | - | null | 979 // | agg | n.a. | - | - | - | x | byref | 980 // | agg | n.a. | - | - | - | x[] | byref | 981 // 982 // | ptr | n.a. | | | - | | bycopy| 983 // | ptr | n.a. | - | x | - | - | bycopy| 984 // | ptr | n.a. | x | - | - | - | null | 985 // | ptr | n.a. | - | - | - | x | byref | 986 // | ptr | n.a. | - | - | - | x[] | bycopy| 987 // | ptr | n.a. | - | - | x | | bycopy| 988 // | ptr | n.a. | - | - | x | x | bycopy| 989 // | ptr | n.a. | - | - | x | x[] | bycopy| 990 // ========================================================================= 991 // Legend: 992 // scl - scalar 993 // ptr - pointer 994 // agg - aggregate 995 // x - applies 996 // - - invalid in this combination 997 // [] - mapped with an array section 998 // byref - should be mapped by reference 999 // byval - should be mapped by value 1000 // null - initialize a local variable to null on the device 1001 // 1002 // Observations: 1003 // - All scalar declarations that show up in a map clause have to be passed 1004 // by reference, because they may have been mapped in the enclosing data 1005 // environment. 1006 // - If the scalar value does not fit the size of uintptr, it has to be 1007 // passed by reference, regardless the result in the table above. 1008 // - For pointers mapped by value that have either an implicit map or an 1009 // array section, the runtime library may pass the NULL value to the 1010 // device instead of the value passed to it by the compiler. 1011 1012 if (Ty->isReferenceType()) 1013 Ty = Ty->castAs<ReferenceType>()->getPointeeType(); 1014 1015 // Locate map clauses and see if the variable being captured is referred to 1016 // in any of those clauses. Here we only care about variables, not fields, 1017 // because fields are part of aggregates. 1018 bool IsVariableUsedInMapClause = false; 1019 bool IsVariableAssociatedWithSection = false; 1020 1021 DSAStack->checkMappableExprComponentListsForDeclAtLevel( 1022 D, Level, [&](OMPClauseMappableExprCommon::MappableExprComponentListRef 1023 MapExprComponents, 1024 OpenMPClauseKind WhereFoundClauseKind) { 1025 // Only the map clause information influences how a variable is 1026 // captured. E.g. is_device_ptr does not require changing the default 1027 // behavior. 1028 if (WhereFoundClauseKind != OMPC_map) 1029 return false; 1030 1031 auto EI = MapExprComponents.rbegin(); 1032 auto EE = MapExprComponents.rend(); 1033 1034 assert(EI != EE && "Invalid map expression!"); 1035 1036 if (isa<DeclRefExpr>(EI->getAssociatedExpression())) 1037 IsVariableUsedInMapClause |= EI->getAssociatedDeclaration() == D; 1038 1039 ++EI; 1040 if (EI == EE) 1041 return false; 1042 1043 if (isa<ArraySubscriptExpr>(EI->getAssociatedExpression()) || 1044 isa<OMPArraySectionExpr>(EI->getAssociatedExpression()) || 1045 isa<MemberExpr>(EI->getAssociatedExpression())) { 1046 IsVariableAssociatedWithSection = true; 1047 // There is nothing more we need to know about this variable. 1048 return true; 1049 } 1050 1051 // Keep looking for more map info. 1052 return false; 1053 }); 1054 1055 if (IsVariableUsedInMapClause) { 1056 // If variable is identified in a map clause it is always captured by 1057 // reference except if it is a pointer that is dereferenced somehow. 1058 IsByRef = !(Ty->isPointerType() && IsVariableAssociatedWithSection); 1059 } else { 1060 // By default, all the data that has a scalar type is mapped by copy. 1061 IsByRef = !Ty->isScalarType(); 1062 } 1063 } 1064 1065 if (IsByRef && Ty.getNonReferenceType()->isScalarType()) { 1066 IsByRef = !DSAStack->hasExplicitDSA( 1067 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_firstprivate; }, 1068 Level, /*NotLastprivate=*/true); 1069 } 1070 1071 // When passing data by copy, we need to make sure it fits the uintptr size 1072 // and alignment, because the runtime library only deals with uintptr types. 1073 // If it does not fit the uintptr size, we need to pass the data by reference 1074 // instead. 1075 if (!IsByRef && 1076 (Ctx.getTypeSizeInChars(Ty) > 1077 Ctx.getTypeSizeInChars(Ctx.getUIntPtrType()) || 1078 Ctx.getDeclAlign(D) > Ctx.getTypeAlignInChars(Ctx.getUIntPtrType()))) { 1079 IsByRef = true; 1080 } 1081 1082 return IsByRef; 1083 } 1084 1085 unsigned Sema::getOpenMPNestingLevel() const { 1086 assert(getLangOpts().OpenMP); 1087 return DSAStack->getNestingLevel(); 1088 } 1089 1090 VarDecl *Sema::IsOpenMPCapturedDecl(ValueDecl *D) { 1091 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1092 D = getCanonicalDecl(D); 1093 1094 // If we are attempting to capture a global variable in a directive with 1095 // 'target' we return true so that this global is also mapped to the device. 1096 // 1097 // FIXME: If the declaration is enclosed in a 'declare target' directive, 1098 // then it should not be captured. Therefore, an extra check has to be 1099 // inserted here once support for 'declare target' is added. 1100 // 1101 auto *VD = dyn_cast<VarDecl>(D); 1102 if (VD && !VD->hasLocalStorage()) { 1103 if (DSAStack->getCurrentDirective() == OMPD_target && 1104 !DSAStack->isClauseParsingMode()) 1105 return VD; 1106 if (DSAStack->hasDirective( 1107 [](OpenMPDirectiveKind K, const DeclarationNameInfo &, 1108 SourceLocation) -> bool { 1109 return isOpenMPTargetExecutionDirective(K); 1110 }, 1111 false)) 1112 return VD; 1113 } 1114 1115 if (DSAStack->getCurrentDirective() != OMPD_unknown && 1116 (!DSAStack->isClauseParsingMode() || 1117 DSAStack->getParentDirective() != OMPD_unknown)) { 1118 auto &&Info = DSAStack->isLoopControlVariable(D); 1119 if (Info.first || 1120 (VD && VD->hasLocalStorage() && 1121 isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || 1122 (VD && DSAStack->isForceVarCapturing())) 1123 return VD ? VD : Info.second; 1124 auto DVarPrivate = DSAStack->getTopDSA(D, DSAStack->isClauseParsingMode()); 1125 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 1126 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1127 DVarPrivate = DSAStack->hasDSA( 1128 D, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, 1129 DSAStack->isClauseParsingMode()); 1130 if (DVarPrivate.CKind != OMPC_unknown) 1131 return VD ? VD : cast<VarDecl>(DVarPrivate.PrivateCopy->getDecl()); 1132 } 1133 return nullptr; 1134 } 1135 1136 bool Sema::isOpenMPPrivateDecl(ValueDecl *D, unsigned Level) { 1137 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1138 return DSAStack->hasExplicitDSA( 1139 D, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, Level); 1140 } 1141 1142 bool Sema::isOpenMPTargetCapturedDecl(ValueDecl *D, unsigned Level) { 1143 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 1144 // Return true if the current level is no longer enclosed in a target region. 1145 1146 auto *VD = dyn_cast<VarDecl>(D); 1147 return VD && !VD->hasLocalStorage() && 1148 DSAStack->hasExplicitDirective(isOpenMPTargetExecutionDirective, 1149 Level); 1150 } 1151 1152 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 1153 1154 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 1155 const DeclarationNameInfo &DirName, 1156 Scope *CurScope, SourceLocation Loc) { 1157 DSAStack->push(DKind, DirName, CurScope, Loc); 1158 PushExpressionEvaluationContext( 1159 ExpressionEvaluationContext::PotentiallyEvaluated); 1160 } 1161 1162 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 1163 DSAStack->setClauseParsingMode(K); 1164 } 1165 1166 void Sema::EndOpenMPClause() { 1167 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 1168 } 1169 1170 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 1171 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 1172 // A variable of class type (or array thereof) that appears in a lastprivate 1173 // clause requires an accessible, unambiguous default constructor for the 1174 // class type, unless the list item is also specified in a firstprivate 1175 // clause. 1176 if (auto *D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 1177 for (auto *C : D->clauses()) { 1178 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 1179 SmallVector<Expr *, 8> PrivateCopies; 1180 for (auto *DE : Clause->varlists()) { 1181 if (DE->isValueDependent() || DE->isTypeDependent()) { 1182 PrivateCopies.push_back(nullptr); 1183 continue; 1184 } 1185 auto *DRE = cast<DeclRefExpr>(DE->IgnoreParens()); 1186 VarDecl *VD = cast<VarDecl>(DRE->getDecl()); 1187 QualType Type = VD->getType().getNonReferenceType(); 1188 auto DVar = DSAStack->getTopDSA(VD, false); 1189 if (DVar.CKind == OMPC_lastprivate) { 1190 // Generate helper private variable and initialize it with the 1191 // default value. The address of the original variable is replaced 1192 // by the address of the new private variable in CodeGen. This new 1193 // variable is not added to IdResolver, so the code in the OpenMP 1194 // region uses original variable for proper diagnostics. 1195 auto *VDPrivate = buildVarDecl( 1196 *this, DE->getExprLoc(), Type.getUnqualifiedType(), 1197 VD->getName(), VD->hasAttrs() ? &VD->getAttrs() : nullptr); 1198 ActOnUninitializedDecl(VDPrivate); 1199 if (VDPrivate->isInvalidDecl()) 1200 continue; 1201 PrivateCopies.push_back(buildDeclRefExpr( 1202 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 1203 } else { 1204 // The variable is also a firstprivate, so initialization sequence 1205 // for private copy is generated already. 1206 PrivateCopies.push_back(nullptr); 1207 } 1208 } 1209 // Set initializers to private copies if no errors were found. 1210 if (PrivateCopies.size() == Clause->varlist_size()) 1211 Clause->setPrivateCopies(PrivateCopies); 1212 } 1213 } 1214 } 1215 1216 DSAStack->pop(); 1217 DiscardCleanupsInEvaluationContext(); 1218 PopExpressionEvaluationContext(); 1219 } 1220 1221 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 1222 Expr *NumIterations, Sema &SemaRef, 1223 Scope *S, DSAStackTy *Stack); 1224 1225 namespace { 1226 1227 class VarDeclFilterCCC : public CorrectionCandidateCallback { 1228 private: 1229 Sema &SemaRef; 1230 1231 public: 1232 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 1233 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1234 NamedDecl *ND = Candidate.getCorrectionDecl(); 1235 if (auto *VD = dyn_cast_or_null<VarDecl>(ND)) { 1236 return VD->hasGlobalStorage() && 1237 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1238 SemaRef.getCurScope()); 1239 } 1240 return false; 1241 } 1242 }; 1243 1244 class VarOrFuncDeclFilterCCC : public CorrectionCandidateCallback { 1245 private: 1246 Sema &SemaRef; 1247 1248 public: 1249 explicit VarOrFuncDeclFilterCCC(Sema &S) : SemaRef(S) {} 1250 bool ValidateCandidate(const TypoCorrection &Candidate) override { 1251 NamedDecl *ND = Candidate.getCorrectionDecl(); 1252 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { 1253 return SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 1254 SemaRef.getCurScope()); 1255 } 1256 return false; 1257 } 1258 }; 1259 1260 } // namespace 1261 1262 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 1263 CXXScopeSpec &ScopeSpec, 1264 const DeclarationNameInfo &Id) { 1265 LookupResult Lookup(*this, Id, LookupOrdinaryName); 1266 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 1267 1268 if (Lookup.isAmbiguous()) 1269 return ExprError(); 1270 1271 VarDecl *VD; 1272 if (!Lookup.isSingleResult()) { 1273 if (TypoCorrection Corrected = CorrectTypo( 1274 Id, LookupOrdinaryName, CurScope, nullptr, 1275 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 1276 diagnoseTypo(Corrected, 1277 PDiag(Lookup.empty() 1278 ? diag::err_undeclared_var_use_suggest 1279 : diag::err_omp_expected_var_arg_suggest) 1280 << Id.getName()); 1281 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 1282 } else { 1283 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 1284 : diag::err_omp_expected_var_arg) 1285 << Id.getName(); 1286 return ExprError(); 1287 } 1288 } else { 1289 if (!(VD = Lookup.getAsSingle<VarDecl>())) { 1290 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 1291 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 1292 return ExprError(); 1293 } 1294 } 1295 Lookup.suppressDiagnostics(); 1296 1297 // OpenMP [2.9.2, Syntax, C/C++] 1298 // Variables must be file-scope, namespace-scope, or static block-scope. 1299 if (!VD->hasGlobalStorage()) { 1300 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 1301 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); 1302 bool IsDecl = 1303 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1304 Diag(VD->getLocation(), 1305 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1306 << VD; 1307 return ExprError(); 1308 } 1309 1310 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 1311 NamedDecl *ND = cast<NamedDecl>(CanonicalVD); 1312 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 1313 // A threadprivate directive for file-scope variables must appear outside 1314 // any definition or declaration. 1315 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 1316 !getCurLexicalContext()->isTranslationUnit()) { 1317 Diag(Id.getLoc(), diag::err_omp_var_scope) 1318 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1319 bool IsDecl = 1320 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1321 Diag(VD->getLocation(), 1322 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1323 << VD; 1324 return ExprError(); 1325 } 1326 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 1327 // A threadprivate directive for static class member variables must appear 1328 // in the class definition, in the same scope in which the member 1329 // variables are declared. 1330 if (CanonicalVD->isStaticDataMember() && 1331 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 1332 Diag(Id.getLoc(), diag::err_omp_var_scope) 1333 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1334 bool IsDecl = 1335 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1336 Diag(VD->getLocation(), 1337 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1338 << VD; 1339 return ExprError(); 1340 } 1341 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 1342 // A threadprivate directive for namespace-scope variables must appear 1343 // outside any definition or declaration other than the namespace 1344 // definition itself. 1345 if (CanonicalVD->getDeclContext()->isNamespace() && 1346 (!getCurLexicalContext()->isFileContext() || 1347 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 1348 Diag(Id.getLoc(), diag::err_omp_var_scope) 1349 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1350 bool IsDecl = 1351 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1352 Diag(VD->getLocation(), 1353 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1354 << VD; 1355 return ExprError(); 1356 } 1357 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 1358 // A threadprivate directive for static block-scope variables must appear 1359 // in the scope of the variable and not in a nested scope. 1360 if (CanonicalVD->isStaticLocal() && CurScope && 1361 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 1362 Diag(Id.getLoc(), diag::err_omp_var_scope) 1363 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1364 bool IsDecl = 1365 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1366 Diag(VD->getLocation(), 1367 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1368 << VD; 1369 return ExprError(); 1370 } 1371 1372 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 1373 // A threadprivate directive must lexically precede all references to any 1374 // of the variables in its list. 1375 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { 1376 Diag(Id.getLoc(), diag::err_omp_var_used) 1377 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 1378 return ExprError(); 1379 } 1380 1381 QualType ExprType = VD->getType().getNonReferenceType(); 1382 return DeclRefExpr::Create(Context, NestedNameSpecifierLoc(), 1383 SourceLocation(), VD, 1384 /*RefersToEnclosingVariableOrCapture=*/false, 1385 Id.getLoc(), ExprType, VK_LValue); 1386 } 1387 1388 Sema::DeclGroupPtrTy 1389 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 1390 ArrayRef<Expr *> VarList) { 1391 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 1392 CurContext->addDecl(D); 1393 return DeclGroupPtrTy::make(DeclGroupRef(D)); 1394 } 1395 return nullptr; 1396 } 1397 1398 namespace { 1399 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> { 1400 Sema &SemaRef; 1401 1402 public: 1403 bool VisitDeclRefExpr(const DeclRefExpr *E) { 1404 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1405 if (VD->hasLocalStorage()) { 1406 SemaRef.Diag(E->getLocStart(), 1407 diag::err_omp_local_var_in_threadprivate_init) 1408 << E->getSourceRange(); 1409 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 1410 << VD << VD->getSourceRange(); 1411 return true; 1412 } 1413 } 1414 return false; 1415 } 1416 bool VisitStmt(const Stmt *S) { 1417 for (auto Child : S->children()) { 1418 if (Child && Visit(Child)) 1419 return true; 1420 } 1421 return false; 1422 } 1423 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 1424 }; 1425 } // namespace 1426 1427 OMPThreadPrivateDecl * 1428 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 1429 SmallVector<Expr *, 8> Vars; 1430 for (auto &RefExpr : VarList) { 1431 DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr); 1432 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 1433 SourceLocation ILoc = DE->getExprLoc(); 1434 1435 // Mark variable as used. 1436 VD->setReferenced(); 1437 VD->markUsed(Context); 1438 1439 QualType QType = VD->getType(); 1440 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 1441 // It will be analyzed later. 1442 Vars.push_back(DE); 1443 continue; 1444 } 1445 1446 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1447 // A threadprivate variable must not have an incomplete type. 1448 if (RequireCompleteType(ILoc, VD->getType(), 1449 diag::err_omp_threadprivate_incomplete_type)) { 1450 continue; 1451 } 1452 1453 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 1454 // A threadprivate variable must not have a reference type. 1455 if (VD->getType()->isReferenceType()) { 1456 Diag(ILoc, diag::err_omp_ref_type_arg) 1457 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 1458 bool IsDecl = 1459 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1460 Diag(VD->getLocation(), 1461 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1462 << VD; 1463 continue; 1464 } 1465 1466 // Check if this is a TLS variable. If TLS is not being supported, produce 1467 // the corresponding diagnostic. 1468 if ((VD->getTLSKind() != VarDecl::TLS_None && 1469 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 1470 getLangOpts().OpenMPUseTLS && 1471 getASTContext().getTargetInfo().isTLSSupported())) || 1472 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 1473 !VD->isLocalVarDecl())) { 1474 Diag(ILoc, diag::err_omp_var_thread_local) 1475 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 1476 bool IsDecl = 1477 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 1478 Diag(VD->getLocation(), 1479 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 1480 << VD; 1481 continue; 1482 } 1483 1484 // Check if initial value of threadprivate variable reference variable with 1485 // local storage (it is not supported by runtime). 1486 if (auto Init = VD->getAnyInitializer()) { 1487 LocalVarRefChecker Checker(*this); 1488 if (Checker.Visit(Init)) 1489 continue; 1490 } 1491 1492 Vars.push_back(RefExpr); 1493 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 1494 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 1495 Context, SourceRange(Loc, Loc))); 1496 if (auto *ML = Context.getASTMutationListener()) 1497 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 1498 } 1499 OMPThreadPrivateDecl *D = nullptr; 1500 if (!Vars.empty()) { 1501 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 1502 Vars); 1503 D->setAccess(AS_public); 1504 } 1505 return D; 1506 } 1507 1508 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, 1509 const ValueDecl *D, DSAStackTy::DSAVarData DVar, 1510 bool IsLoopIterVar = false) { 1511 if (DVar.RefExpr) { 1512 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 1513 << getOpenMPClauseName(DVar.CKind); 1514 return; 1515 } 1516 enum { 1517 PDSA_StaticMemberShared, 1518 PDSA_StaticLocalVarShared, 1519 PDSA_LoopIterVarPrivate, 1520 PDSA_LoopIterVarLinear, 1521 PDSA_LoopIterVarLastprivate, 1522 PDSA_ConstVarShared, 1523 PDSA_GlobalVarShared, 1524 PDSA_TaskVarFirstprivate, 1525 PDSA_LocalVarPrivate, 1526 PDSA_Implicit 1527 } Reason = PDSA_Implicit; 1528 bool ReportHint = false; 1529 auto ReportLoc = D->getLocation(); 1530 auto *VD = dyn_cast<VarDecl>(D); 1531 if (IsLoopIterVar) { 1532 if (DVar.CKind == OMPC_private) 1533 Reason = PDSA_LoopIterVarPrivate; 1534 else if (DVar.CKind == OMPC_lastprivate) 1535 Reason = PDSA_LoopIterVarLastprivate; 1536 else 1537 Reason = PDSA_LoopIterVarLinear; 1538 } else if (isOpenMPTaskingDirective(DVar.DKind) && 1539 DVar.CKind == OMPC_firstprivate) { 1540 Reason = PDSA_TaskVarFirstprivate; 1541 ReportLoc = DVar.ImplicitDSALoc; 1542 } else if (VD && VD->isStaticLocal()) 1543 Reason = PDSA_StaticLocalVarShared; 1544 else if (VD && VD->isStaticDataMember()) 1545 Reason = PDSA_StaticMemberShared; 1546 else if (VD && VD->isFileVarDecl()) 1547 Reason = PDSA_GlobalVarShared; 1548 else if (D->getType().isConstant(SemaRef.getASTContext())) 1549 Reason = PDSA_ConstVarShared; 1550 else if (VD && VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 1551 ReportHint = true; 1552 Reason = PDSA_LocalVarPrivate; 1553 } 1554 if (Reason != PDSA_Implicit) { 1555 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 1556 << Reason << ReportHint 1557 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 1558 } else if (DVar.ImplicitDSALoc.isValid()) { 1559 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 1560 << getOpenMPClauseName(DVar.CKind); 1561 } 1562 } 1563 1564 namespace { 1565 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> { 1566 DSAStackTy *Stack; 1567 Sema &SemaRef; 1568 bool ErrorFound; 1569 CapturedStmt *CS; 1570 llvm::SmallVector<Expr *, 8> ImplicitFirstprivate; 1571 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 1572 1573 public: 1574 void VisitDeclRefExpr(DeclRefExpr *E) { 1575 if (E->isTypeDependent() || E->isValueDependent() || 1576 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 1577 return; 1578 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1579 // Skip internally declared variables. 1580 if (VD->isLocalVarDecl() && !CS->capturesVariable(VD)) 1581 return; 1582 1583 auto DVar = Stack->getTopDSA(VD, false); 1584 // Check if the variable has explicit DSA set and stop analysis if it so. 1585 if (DVar.RefExpr) 1586 return; 1587 1588 auto ELoc = E->getExprLoc(); 1589 auto DKind = Stack->getCurrentDirective(); 1590 // The default(none) clause requires that each variable that is referenced 1591 // in the construct, and does not have a predetermined data-sharing 1592 // attribute, must have its data-sharing attribute explicitly determined 1593 // by being listed in a data-sharing attribute clause. 1594 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 1595 isParallelOrTaskRegion(DKind) && 1596 VarsWithInheritedDSA.count(VD) == 0) { 1597 VarsWithInheritedDSA[VD] = E; 1598 return; 1599 } 1600 1601 // OpenMP [2.9.3.6, Restrictions, p.2] 1602 // A list item that appears in a reduction clause of the innermost 1603 // enclosing worksharing or parallel construct may not be accessed in an 1604 // explicit task. 1605 DVar = Stack->hasInnermostDSA( 1606 VD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 1607 [](OpenMPDirectiveKind K) -> bool { 1608 return isOpenMPParallelDirective(K) || 1609 isOpenMPWorksharingDirective(K) || isOpenMPTeamsDirective(K); 1610 }, 1611 false); 1612 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 1613 ErrorFound = true; 1614 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1615 ReportOriginalDSA(SemaRef, Stack, VD, DVar); 1616 return; 1617 } 1618 1619 // Define implicit data-sharing attributes for task. 1620 DVar = Stack->getImplicitDSA(VD, false); 1621 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 1622 !Stack->isLoopControlVariable(VD).first) 1623 ImplicitFirstprivate.push_back(E); 1624 } 1625 } 1626 void VisitMemberExpr(MemberExpr *E) { 1627 if (E->isTypeDependent() || E->isValueDependent() || 1628 E->containsUnexpandedParameterPack() || E->isInstantiationDependent()) 1629 return; 1630 if (isa<CXXThisExpr>(E->getBase()->IgnoreParens())) { 1631 if (auto *FD = dyn_cast<FieldDecl>(E->getMemberDecl())) { 1632 auto DVar = Stack->getTopDSA(FD, false); 1633 // Check if the variable has explicit DSA set and stop analysis if it 1634 // so. 1635 if (DVar.RefExpr) 1636 return; 1637 1638 auto ELoc = E->getExprLoc(); 1639 auto DKind = Stack->getCurrentDirective(); 1640 // OpenMP [2.9.3.6, Restrictions, p.2] 1641 // A list item that appears in a reduction clause of the innermost 1642 // enclosing worksharing or parallel construct may not be accessed in 1643 // an explicit task. 1644 DVar = Stack->hasInnermostDSA( 1645 FD, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 1646 [](OpenMPDirectiveKind K) -> bool { 1647 return isOpenMPParallelDirective(K) || 1648 isOpenMPWorksharingDirective(K) || 1649 isOpenMPTeamsDirective(K); 1650 }, 1651 false); 1652 if (isOpenMPTaskingDirective(DKind) && DVar.CKind == OMPC_reduction) { 1653 ErrorFound = true; 1654 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1655 ReportOriginalDSA(SemaRef, Stack, FD, DVar); 1656 return; 1657 } 1658 1659 // Define implicit data-sharing attributes for task. 1660 DVar = Stack->getImplicitDSA(FD, false); 1661 if (isOpenMPTaskingDirective(DKind) && DVar.CKind != OMPC_shared && 1662 !Stack->isLoopControlVariable(FD).first) 1663 ImplicitFirstprivate.push_back(E); 1664 } 1665 } else 1666 Visit(E->getBase()); 1667 } 1668 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 1669 for (auto *C : S->clauses()) { 1670 // Skip analysis of arguments of implicitly defined firstprivate clause 1671 // for task directives. 1672 if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid())) 1673 for (auto *CC : C->children()) { 1674 if (CC) 1675 Visit(CC); 1676 } 1677 } 1678 } 1679 void VisitStmt(Stmt *S) { 1680 for (auto *C : S->children()) { 1681 if (C && !isa<OMPExecutableDirective>(C)) 1682 Visit(C); 1683 } 1684 } 1685 1686 bool isErrorFound() { return ErrorFound; } 1687 ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; } 1688 llvm::DenseMap<ValueDecl *, Expr *> &getVarsWithInheritedDSA() { 1689 return VarsWithInheritedDSA; 1690 } 1691 1692 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 1693 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} 1694 }; 1695 } // namespace 1696 1697 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 1698 switch (DKind) { 1699 case OMPD_parallel: 1700 case OMPD_parallel_for: 1701 case OMPD_parallel_for_simd: 1702 case OMPD_parallel_sections: 1703 case OMPD_teams: { 1704 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1705 QualType KmpInt32PtrTy = 1706 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1707 Sema::CapturedParamNameType Params[] = { 1708 std::make_pair(".global_tid.", KmpInt32PtrTy), 1709 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1710 std::make_pair(StringRef(), QualType()) // __context with shared vars 1711 }; 1712 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1713 Params); 1714 break; 1715 } 1716 case OMPD_target_teams: 1717 case OMPD_target_parallel: { 1718 Sema::CapturedParamNameType ParamsTarget[] = { 1719 std::make_pair(StringRef(), QualType()) // __context with shared vars 1720 }; 1721 // Start a captured region for 'target' with no implicit parameters. 1722 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1723 ParamsTarget); 1724 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1725 QualType KmpInt32PtrTy = 1726 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1727 Sema::CapturedParamNameType ParamsTeamsOrParallel[] = { 1728 std::make_pair(".global_tid.", KmpInt32PtrTy), 1729 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1730 std::make_pair(StringRef(), QualType()) // __context with shared vars 1731 }; 1732 // Start a captured region for 'teams' or 'parallel'. Both regions have 1733 // the same implicit parameters. 1734 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1735 ParamsTeamsOrParallel); 1736 break; 1737 } 1738 case OMPD_simd: 1739 case OMPD_for: 1740 case OMPD_for_simd: 1741 case OMPD_sections: 1742 case OMPD_section: 1743 case OMPD_single: 1744 case OMPD_master: 1745 case OMPD_critical: 1746 case OMPD_taskgroup: 1747 case OMPD_distribute: 1748 case OMPD_ordered: 1749 case OMPD_atomic: 1750 case OMPD_target_data: 1751 case OMPD_target: 1752 case OMPD_target_parallel_for: 1753 case OMPD_target_parallel_for_simd: 1754 case OMPD_target_simd: { 1755 Sema::CapturedParamNameType Params[] = { 1756 std::make_pair(StringRef(), QualType()) // __context with shared vars 1757 }; 1758 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1759 Params); 1760 break; 1761 } 1762 case OMPD_task: { 1763 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1764 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 1765 FunctionProtoType::ExtProtoInfo EPI; 1766 EPI.Variadic = true; 1767 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 1768 Sema::CapturedParamNameType Params[] = { 1769 std::make_pair(".global_tid.", KmpInt32Ty), 1770 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), 1771 std::make_pair(".privates.", Context.VoidPtrTy.withConst()), 1772 std::make_pair(".copy_fn.", 1773 Context.getPointerType(CopyFnType).withConst()), 1774 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 1775 std::make_pair(StringRef(), QualType()) // __context with shared vars 1776 }; 1777 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1778 Params); 1779 // Mark this captured region as inlined, because we don't use outlined 1780 // function directly. 1781 getCurCapturedRegion()->TheCapturedDecl->addAttr( 1782 AlwaysInlineAttr::CreateImplicit( 1783 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 1784 break; 1785 } 1786 case OMPD_taskloop: 1787 case OMPD_taskloop_simd: { 1788 QualType KmpInt32Ty = 1789 Context.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/1); 1790 QualType KmpUInt64Ty = 1791 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 1792 QualType KmpInt64Ty = 1793 Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 1794 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 1795 FunctionProtoType::ExtProtoInfo EPI; 1796 EPI.Variadic = true; 1797 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 1798 Sema::CapturedParamNameType Params[] = { 1799 std::make_pair(".global_tid.", KmpInt32Ty), 1800 std::make_pair(".part_id.", Context.getPointerType(KmpInt32Ty)), 1801 std::make_pair(".privates.", 1802 Context.VoidPtrTy.withConst().withRestrict()), 1803 std::make_pair( 1804 ".copy_fn.", 1805 Context.getPointerType(CopyFnType).withConst().withRestrict()), 1806 std::make_pair(".task_t.", Context.VoidPtrTy.withConst()), 1807 std::make_pair(".lb.", KmpUInt64Ty), 1808 std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty), 1809 std::make_pair(".liter.", KmpInt32Ty), 1810 std::make_pair(StringRef(), QualType()) // __context with shared vars 1811 }; 1812 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1813 Params); 1814 // Mark this captured region as inlined, because we don't use outlined 1815 // function directly. 1816 getCurCapturedRegion()->TheCapturedDecl->addAttr( 1817 AlwaysInlineAttr::CreateImplicit( 1818 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 1819 break; 1820 } 1821 case OMPD_distribute_parallel_for_simd: 1822 case OMPD_distribute_simd: 1823 case OMPD_distribute_parallel_for: 1824 case OMPD_teams_distribute: 1825 case OMPD_teams_distribute_simd: 1826 case OMPD_teams_distribute_parallel_for_simd: 1827 case OMPD_teams_distribute_parallel_for: 1828 case OMPD_target_teams_distribute: 1829 case OMPD_target_teams_distribute_parallel_for: 1830 case OMPD_target_teams_distribute_parallel_for_simd: 1831 case OMPD_target_teams_distribute_simd: { 1832 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1833 QualType KmpInt32PtrTy = 1834 Context.getPointerType(KmpInt32Ty).withConst().withRestrict(); 1835 Sema::CapturedParamNameType Params[] = { 1836 std::make_pair(".global_tid.", KmpInt32PtrTy), 1837 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1838 std::make_pair(".previous.lb.", Context.getSizeType()), 1839 std::make_pair(".previous.ub.", Context.getSizeType()), 1840 std::make_pair(StringRef(), QualType()) // __context with shared vars 1841 }; 1842 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1843 Params); 1844 break; 1845 } 1846 case OMPD_threadprivate: 1847 case OMPD_taskyield: 1848 case OMPD_barrier: 1849 case OMPD_taskwait: 1850 case OMPD_cancellation_point: 1851 case OMPD_cancel: 1852 case OMPD_flush: 1853 case OMPD_target_enter_data: 1854 case OMPD_target_exit_data: 1855 case OMPD_declare_reduction: 1856 case OMPD_declare_simd: 1857 case OMPD_declare_target: 1858 case OMPD_end_declare_target: 1859 case OMPD_target_update: 1860 llvm_unreachable("OpenMP Directive is not allowed"); 1861 case OMPD_unknown: 1862 llvm_unreachable("Unknown OpenMP directive"); 1863 } 1864 } 1865 1866 int Sema::getOpenMPCaptureLevels(OpenMPDirectiveKind DKind) { 1867 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 1868 getOpenMPCaptureRegions(CaptureRegions, DKind); 1869 return CaptureRegions.size(); 1870 } 1871 1872 static OMPCapturedExprDecl *buildCaptureDecl(Sema &S, IdentifierInfo *Id, 1873 Expr *CaptureExpr, bool WithInit, 1874 bool AsExpression) { 1875 assert(CaptureExpr); 1876 ASTContext &C = S.getASTContext(); 1877 Expr *Init = AsExpression ? CaptureExpr : CaptureExpr->IgnoreImpCasts(); 1878 QualType Ty = Init->getType(); 1879 if (CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue()) { 1880 if (S.getLangOpts().CPlusPlus) 1881 Ty = C.getLValueReferenceType(Ty); 1882 else { 1883 Ty = C.getPointerType(Ty); 1884 ExprResult Res = 1885 S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_AddrOf, Init); 1886 if (!Res.isUsable()) 1887 return nullptr; 1888 Init = Res.get(); 1889 } 1890 WithInit = true; 1891 } 1892 auto *CED = OMPCapturedExprDecl::Create(C, S.CurContext, Id, Ty, 1893 CaptureExpr->getLocStart()); 1894 if (!WithInit) 1895 CED->addAttr(OMPCaptureNoInitAttr::CreateImplicit(C, SourceRange())); 1896 S.CurContext->addHiddenDecl(CED); 1897 S.AddInitializerToDecl(CED, Init, /*DirectInit=*/false); 1898 return CED; 1899 } 1900 1901 static DeclRefExpr *buildCapture(Sema &S, ValueDecl *D, Expr *CaptureExpr, 1902 bool WithInit) { 1903 OMPCapturedExprDecl *CD; 1904 if (auto *VD = S.IsOpenMPCapturedDecl(D)) 1905 CD = cast<OMPCapturedExprDecl>(VD); 1906 else 1907 CD = buildCaptureDecl(S, D->getIdentifier(), CaptureExpr, WithInit, 1908 /*AsExpression=*/false); 1909 return buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 1910 CaptureExpr->getExprLoc()); 1911 } 1912 1913 static ExprResult buildCapture(Sema &S, Expr *CaptureExpr, DeclRefExpr *&Ref) { 1914 if (!Ref) { 1915 auto *CD = 1916 buildCaptureDecl(S, &S.getASTContext().Idents.get(".capture_expr."), 1917 CaptureExpr, /*WithInit=*/true, /*AsExpression=*/true); 1918 Ref = buildDeclRefExpr(S, CD, CD->getType().getNonReferenceType(), 1919 CaptureExpr->getExprLoc()); 1920 } 1921 ExprResult Res = Ref; 1922 if (!S.getLangOpts().CPlusPlus && 1923 CaptureExpr->getObjectKind() == OK_Ordinary && CaptureExpr->isGLValue() && 1924 Ref->getType()->isPointerType()) 1925 Res = S.CreateBuiltinUnaryOp(CaptureExpr->getExprLoc(), UO_Deref, Ref); 1926 if (!Res.isUsable()) 1927 return ExprError(); 1928 return CaptureExpr->isGLValue() ? Res : S.DefaultLvalueConversion(Res.get()); 1929 } 1930 1931 namespace { 1932 // OpenMP directives parsed in this section are represented as a 1933 // CapturedStatement with an associated statement. If a syntax error 1934 // is detected during the parsing of the associated statement, the 1935 // compiler must abort processing and close the CapturedStatement. 1936 // 1937 // Combined directives such as 'target parallel' have more than one 1938 // nested CapturedStatements. This RAII ensures that we unwind out 1939 // of all the nested CapturedStatements when an error is found. 1940 class CaptureRegionUnwinderRAII { 1941 private: 1942 Sema &S; 1943 bool &ErrorFound; 1944 OpenMPDirectiveKind DKind; 1945 1946 public: 1947 CaptureRegionUnwinderRAII(Sema &S, bool &ErrorFound, 1948 OpenMPDirectiveKind DKind) 1949 : S(S), ErrorFound(ErrorFound), DKind(DKind) {} 1950 ~CaptureRegionUnwinderRAII() { 1951 if (ErrorFound) { 1952 int ThisCaptureLevel = S.getOpenMPCaptureLevels(DKind); 1953 while (--ThisCaptureLevel >= 0) 1954 S.ActOnCapturedRegionError(); 1955 } 1956 } 1957 }; 1958 } // namespace 1959 1960 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 1961 ArrayRef<OMPClause *> Clauses) { 1962 bool ErrorFound = false; 1963 CaptureRegionUnwinderRAII CaptureRegionUnwinder( 1964 *this, ErrorFound, DSAStack->getCurrentDirective()); 1965 if (!S.isUsable()) { 1966 ErrorFound = true; 1967 return StmtError(); 1968 } 1969 1970 OMPOrderedClause *OC = nullptr; 1971 OMPScheduleClause *SC = nullptr; 1972 SmallVector<OMPLinearClause *, 4> LCs; 1973 SmallVector<OMPClauseWithPreInit *, 8> PICs; 1974 // This is required for proper codegen. 1975 for (auto *Clause : Clauses) { 1976 if (isOpenMPPrivate(Clause->getClauseKind()) || 1977 Clause->getClauseKind() == OMPC_copyprivate || 1978 (getLangOpts().OpenMPUseTLS && 1979 getASTContext().getTargetInfo().isTLSSupported() && 1980 Clause->getClauseKind() == OMPC_copyin)) { 1981 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 1982 // Mark all variables in private list clauses as used in inner region. 1983 for (auto *VarRef : Clause->children()) { 1984 if (auto *E = cast_or_null<Expr>(VarRef)) { 1985 MarkDeclarationsReferencedInExpr(E); 1986 } 1987 } 1988 DSAStack->setForceVarCapturing(/*V=*/false); 1989 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 1990 if (auto *C = OMPClauseWithPreInit::get(Clause)) 1991 PICs.push_back(C); 1992 if (auto *C = OMPClauseWithPostUpdate::get(Clause)) { 1993 if (auto *E = C->getPostUpdateExpr()) 1994 MarkDeclarationsReferencedInExpr(E); 1995 } 1996 } 1997 if (Clause->getClauseKind() == OMPC_schedule) 1998 SC = cast<OMPScheduleClause>(Clause); 1999 else if (Clause->getClauseKind() == OMPC_ordered) 2000 OC = cast<OMPOrderedClause>(Clause); 2001 else if (Clause->getClauseKind() == OMPC_linear) 2002 LCs.push_back(cast<OMPLinearClause>(Clause)); 2003 } 2004 // OpenMP, 2.7.1 Loop Construct, Restrictions 2005 // The nonmonotonic modifier cannot be specified if an ordered clause is 2006 // specified. 2007 if (SC && 2008 (SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 2009 SC->getSecondScheduleModifier() == 2010 OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 2011 OC) { 2012 Diag(SC->getFirstScheduleModifier() == OMPC_SCHEDULE_MODIFIER_nonmonotonic 2013 ? SC->getFirstScheduleModifierLoc() 2014 : SC->getSecondScheduleModifierLoc(), 2015 diag::err_omp_schedule_nonmonotonic_ordered) 2016 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 2017 ErrorFound = true; 2018 } 2019 if (!LCs.empty() && OC && OC->getNumForLoops()) { 2020 for (auto *C : LCs) { 2021 Diag(C->getLocStart(), diag::err_omp_linear_ordered) 2022 << SourceRange(OC->getLocStart(), OC->getLocEnd()); 2023 } 2024 ErrorFound = true; 2025 } 2026 if (isOpenMPWorksharingDirective(DSAStack->getCurrentDirective()) && 2027 isOpenMPSimdDirective(DSAStack->getCurrentDirective()) && OC && 2028 OC->getNumForLoops()) { 2029 Diag(OC->getLocStart(), diag::err_omp_ordered_simd) 2030 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 2031 ErrorFound = true; 2032 } 2033 if (ErrorFound) { 2034 return StmtError(); 2035 } 2036 StmtResult SR = S; 2037 SmallVector<OpenMPDirectiveKind, 4> CaptureRegions; 2038 getOpenMPCaptureRegions(CaptureRegions, DSAStack->getCurrentDirective()); 2039 for (auto ThisCaptureRegion : llvm::reverse(CaptureRegions)) { 2040 // Mark all variables in private list clauses as used in inner region. 2041 // Required for proper codegen of combined directives. 2042 // TODO: add processing for other clauses. 2043 if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 2044 for (auto *C : PICs) { 2045 OpenMPDirectiveKind CaptureRegion = C->getCaptureRegion(); 2046 // Find the particular capture region for the clause if the 2047 // directive is a combined one with multiple capture regions. 2048 // If the directive is not a combined one, the capture region 2049 // associated with the clause is OMPD_unknown and is generated 2050 // only once. 2051 if (CaptureRegion == ThisCaptureRegion || 2052 CaptureRegion == OMPD_unknown) { 2053 if (auto *DS = cast_or_null<DeclStmt>(C->getPreInitStmt())) { 2054 for (auto *D : DS->decls()) 2055 MarkVariableReferenced(D->getLocation(), cast<VarDecl>(D)); 2056 } 2057 } 2058 } 2059 } 2060 SR = ActOnCapturedRegionEnd(SR.get()); 2061 } 2062 return SR; 2063 } 2064 2065 static bool checkCancelRegion(Sema &SemaRef, OpenMPDirectiveKind CurrentRegion, 2066 OpenMPDirectiveKind CancelRegion, 2067 SourceLocation StartLoc) { 2068 // CancelRegion is only needed for cancel and cancellation_point. 2069 if (CurrentRegion != OMPD_cancel && CurrentRegion != OMPD_cancellation_point) 2070 return false; 2071 2072 if (CancelRegion == OMPD_parallel || CancelRegion == OMPD_for || 2073 CancelRegion == OMPD_sections || CancelRegion == OMPD_taskgroup) 2074 return false; 2075 2076 SemaRef.Diag(StartLoc, diag::err_omp_wrong_cancel_region) 2077 << getOpenMPDirectiveName(CancelRegion); 2078 return true; 2079 } 2080 2081 static bool checkNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, 2082 OpenMPDirectiveKind CurrentRegion, 2083 const DeclarationNameInfo &CurrentName, 2084 OpenMPDirectiveKind CancelRegion, 2085 SourceLocation StartLoc) { 2086 if (Stack->getCurScope()) { 2087 auto ParentRegion = Stack->getParentDirective(); 2088 auto OffendingRegion = ParentRegion; 2089 bool NestingProhibited = false; 2090 bool CloseNesting = true; 2091 bool OrphanSeen = false; 2092 enum { 2093 NoRecommend, 2094 ShouldBeInParallelRegion, 2095 ShouldBeInOrderedRegion, 2096 ShouldBeInTargetRegion, 2097 ShouldBeInTeamsRegion 2098 } Recommend = NoRecommend; 2099 if (isOpenMPSimdDirective(ParentRegion) && CurrentRegion != OMPD_ordered) { 2100 // OpenMP [2.16, Nesting of Regions] 2101 // OpenMP constructs may not be nested inside a simd region. 2102 // OpenMP [2.8.1,simd Construct, Restrictions] 2103 // An ordered construct with the simd clause is the only OpenMP 2104 // construct that can appear in the simd region. 2105 // Allowing a SIMD construct nested in another SIMD construct is an 2106 // extension. The OpenMP 4.5 spec does not allow it. Issue a warning 2107 // message. 2108 SemaRef.Diag(StartLoc, (CurrentRegion != OMPD_simd) 2109 ? diag::err_omp_prohibited_region_simd 2110 : diag::warn_omp_nesting_simd); 2111 return CurrentRegion != OMPD_simd; 2112 } 2113 if (ParentRegion == OMPD_atomic) { 2114 // OpenMP [2.16, Nesting of Regions] 2115 // OpenMP constructs may not be nested inside an atomic region. 2116 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 2117 return true; 2118 } 2119 if (CurrentRegion == OMPD_section) { 2120 // OpenMP [2.7.2, sections Construct, Restrictions] 2121 // Orphaned section directives are prohibited. That is, the section 2122 // directives must appear within the sections construct and must not be 2123 // encountered elsewhere in the sections region. 2124 if (ParentRegion != OMPD_sections && 2125 ParentRegion != OMPD_parallel_sections) { 2126 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 2127 << (ParentRegion != OMPD_unknown) 2128 << getOpenMPDirectiveName(ParentRegion); 2129 return true; 2130 } 2131 return false; 2132 } 2133 // Allow some constructs (except teams) to be orphaned (they could be 2134 // used in functions, called from OpenMP regions with the required 2135 // preconditions). 2136 if (ParentRegion == OMPD_unknown && 2137 !isOpenMPNestingTeamsDirective(CurrentRegion)) 2138 return false; 2139 if (CurrentRegion == OMPD_cancellation_point || 2140 CurrentRegion == OMPD_cancel) { 2141 // OpenMP [2.16, Nesting of Regions] 2142 // A cancellation point construct for which construct-type-clause is 2143 // taskgroup must be nested inside a task construct. A cancellation 2144 // point construct for which construct-type-clause is not taskgroup must 2145 // be closely nested inside an OpenMP construct that matches the type 2146 // specified in construct-type-clause. 2147 // A cancel construct for which construct-type-clause is taskgroup must be 2148 // nested inside a task construct. A cancel construct for which 2149 // construct-type-clause is not taskgroup must be closely nested inside an 2150 // OpenMP construct that matches the type specified in 2151 // construct-type-clause. 2152 NestingProhibited = 2153 !((CancelRegion == OMPD_parallel && 2154 (ParentRegion == OMPD_parallel || 2155 ParentRegion == OMPD_target_parallel)) || 2156 (CancelRegion == OMPD_for && 2157 (ParentRegion == OMPD_for || ParentRegion == OMPD_parallel_for || 2158 ParentRegion == OMPD_target_parallel_for)) || 2159 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 2160 (CancelRegion == OMPD_sections && 2161 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections || 2162 ParentRegion == OMPD_parallel_sections))); 2163 } else if (CurrentRegion == OMPD_master) { 2164 // OpenMP [2.16, Nesting of Regions] 2165 // A master region may not be closely nested inside a worksharing, 2166 // atomic, or explicit task region. 2167 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2168 isOpenMPTaskingDirective(ParentRegion); 2169 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 2170 // OpenMP [2.16, Nesting of Regions] 2171 // A critical region may not be nested (closely or otherwise) inside a 2172 // critical region with the same name. Note that this restriction is not 2173 // sufficient to prevent deadlock. 2174 SourceLocation PreviousCriticalLoc; 2175 bool DeadLock = Stack->hasDirective( 2176 [CurrentName, &PreviousCriticalLoc](OpenMPDirectiveKind K, 2177 const DeclarationNameInfo &DNI, 2178 SourceLocation Loc) -> bool { 2179 if (K == OMPD_critical && DNI.getName() == CurrentName.getName()) { 2180 PreviousCriticalLoc = Loc; 2181 return true; 2182 } else 2183 return false; 2184 }, 2185 false /* skip top directive */); 2186 if (DeadLock) { 2187 SemaRef.Diag(StartLoc, 2188 diag::err_omp_prohibited_region_critical_same_name) 2189 << CurrentName.getName(); 2190 if (PreviousCriticalLoc.isValid()) 2191 SemaRef.Diag(PreviousCriticalLoc, 2192 diag::note_omp_previous_critical_region); 2193 return true; 2194 } 2195 } else if (CurrentRegion == OMPD_barrier) { 2196 // OpenMP [2.16, Nesting of Regions] 2197 // A barrier region may not be closely nested inside a worksharing, 2198 // explicit task, critical, ordered, atomic, or master region. 2199 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2200 isOpenMPTaskingDirective(ParentRegion) || 2201 ParentRegion == OMPD_master || 2202 ParentRegion == OMPD_critical || 2203 ParentRegion == OMPD_ordered; 2204 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 2205 !isOpenMPParallelDirective(CurrentRegion) && 2206 !isOpenMPTeamsDirective(CurrentRegion)) { 2207 // OpenMP [2.16, Nesting of Regions] 2208 // A worksharing region may not be closely nested inside a worksharing, 2209 // explicit task, critical, ordered, atomic, or master region. 2210 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 2211 isOpenMPTaskingDirective(ParentRegion) || 2212 ParentRegion == OMPD_master || 2213 ParentRegion == OMPD_critical || 2214 ParentRegion == OMPD_ordered; 2215 Recommend = ShouldBeInParallelRegion; 2216 } else if (CurrentRegion == OMPD_ordered) { 2217 // OpenMP [2.16, Nesting of Regions] 2218 // An ordered region may not be closely nested inside a critical, 2219 // atomic, or explicit task region. 2220 // An ordered region must be closely nested inside a loop region (or 2221 // parallel loop region) with an ordered clause. 2222 // OpenMP [2.8.1,simd Construct, Restrictions] 2223 // An ordered construct with the simd clause is the only OpenMP construct 2224 // that can appear in the simd region. 2225 NestingProhibited = ParentRegion == OMPD_critical || 2226 isOpenMPTaskingDirective(ParentRegion) || 2227 !(isOpenMPSimdDirective(ParentRegion) || 2228 Stack->isParentOrderedRegion()); 2229 Recommend = ShouldBeInOrderedRegion; 2230 } else if (isOpenMPNestingTeamsDirective(CurrentRegion)) { 2231 // OpenMP [2.16, Nesting of Regions] 2232 // If specified, a teams construct must be contained within a target 2233 // construct. 2234 NestingProhibited = ParentRegion != OMPD_target; 2235 OrphanSeen = ParentRegion == OMPD_unknown; 2236 Recommend = ShouldBeInTargetRegion; 2237 Stack->setParentTeamsRegionLoc(Stack->getConstructLoc()); 2238 } 2239 if (!NestingProhibited && 2240 !isOpenMPTargetExecutionDirective(CurrentRegion) && 2241 !isOpenMPTargetDataManagementDirective(CurrentRegion) && 2242 (ParentRegion == OMPD_teams || ParentRegion == OMPD_target_teams)) { 2243 // OpenMP [2.16, Nesting of Regions] 2244 // distribute, parallel, parallel sections, parallel workshare, and the 2245 // parallel loop and parallel loop SIMD constructs are the only OpenMP 2246 // constructs that can be closely nested in the teams region. 2247 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion) && 2248 !isOpenMPDistributeDirective(CurrentRegion); 2249 Recommend = ShouldBeInParallelRegion; 2250 } 2251 if (!NestingProhibited && 2252 isOpenMPNestingDistributeDirective(CurrentRegion)) { 2253 // OpenMP 4.5 [2.17 Nesting of Regions] 2254 // The region associated with the distribute construct must be strictly 2255 // nested inside a teams region 2256 NestingProhibited = 2257 (ParentRegion != OMPD_teams && ParentRegion != OMPD_target_teams); 2258 Recommend = ShouldBeInTeamsRegion; 2259 } 2260 if (!NestingProhibited && 2261 (isOpenMPTargetExecutionDirective(CurrentRegion) || 2262 isOpenMPTargetDataManagementDirective(CurrentRegion))) { 2263 // OpenMP 4.5 [2.17 Nesting of Regions] 2264 // If a target, target update, target data, target enter data, or 2265 // target exit data construct is encountered during execution of a 2266 // target region, the behavior is unspecified. 2267 NestingProhibited = Stack->hasDirective( 2268 [&OffendingRegion](OpenMPDirectiveKind K, const DeclarationNameInfo &, 2269 SourceLocation) -> bool { 2270 if (isOpenMPTargetExecutionDirective(K)) { 2271 OffendingRegion = K; 2272 return true; 2273 } else 2274 return false; 2275 }, 2276 false /* don't skip top directive */); 2277 CloseNesting = false; 2278 } 2279 if (NestingProhibited) { 2280 if (OrphanSeen) { 2281 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_device_directive) 2282 << getOpenMPDirectiveName(CurrentRegion) << Recommend; 2283 } else { 2284 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 2285 << CloseNesting << getOpenMPDirectiveName(OffendingRegion) 2286 << Recommend << getOpenMPDirectiveName(CurrentRegion); 2287 } 2288 return true; 2289 } 2290 } 2291 return false; 2292 } 2293 2294 static bool checkIfClauses(Sema &S, OpenMPDirectiveKind Kind, 2295 ArrayRef<OMPClause *> Clauses, 2296 ArrayRef<OpenMPDirectiveKind> AllowedNameModifiers) { 2297 bool ErrorFound = false; 2298 unsigned NamedModifiersNumber = 0; 2299 SmallVector<const OMPIfClause *, OMPC_unknown + 1> FoundNameModifiers( 2300 OMPD_unknown + 1); 2301 SmallVector<SourceLocation, 4> NameModifierLoc; 2302 for (const auto *C : Clauses) { 2303 if (const auto *IC = dyn_cast_or_null<OMPIfClause>(C)) { 2304 // At most one if clause without a directive-name-modifier can appear on 2305 // the directive. 2306 OpenMPDirectiveKind CurNM = IC->getNameModifier(); 2307 if (FoundNameModifiers[CurNM]) { 2308 S.Diag(C->getLocStart(), diag::err_omp_more_one_clause) 2309 << getOpenMPDirectiveName(Kind) << getOpenMPClauseName(OMPC_if) 2310 << (CurNM != OMPD_unknown) << getOpenMPDirectiveName(CurNM); 2311 ErrorFound = true; 2312 } else if (CurNM != OMPD_unknown) { 2313 NameModifierLoc.push_back(IC->getNameModifierLoc()); 2314 ++NamedModifiersNumber; 2315 } 2316 FoundNameModifiers[CurNM] = IC; 2317 if (CurNM == OMPD_unknown) 2318 continue; 2319 // Check if the specified name modifier is allowed for the current 2320 // directive. 2321 // At most one if clause with the particular directive-name-modifier can 2322 // appear on the directive. 2323 bool MatchFound = false; 2324 for (auto NM : AllowedNameModifiers) { 2325 if (CurNM == NM) { 2326 MatchFound = true; 2327 break; 2328 } 2329 } 2330 if (!MatchFound) { 2331 S.Diag(IC->getNameModifierLoc(), 2332 diag::err_omp_wrong_if_directive_name_modifier) 2333 << getOpenMPDirectiveName(CurNM) << getOpenMPDirectiveName(Kind); 2334 ErrorFound = true; 2335 } 2336 } 2337 } 2338 // If any if clause on the directive includes a directive-name-modifier then 2339 // all if clauses on the directive must include a directive-name-modifier. 2340 if (FoundNameModifiers[OMPD_unknown] && NamedModifiersNumber > 0) { 2341 if (NamedModifiersNumber == AllowedNameModifiers.size()) { 2342 S.Diag(FoundNameModifiers[OMPD_unknown]->getLocStart(), 2343 diag::err_omp_no_more_if_clause); 2344 } else { 2345 std::string Values; 2346 std::string Sep(", "); 2347 unsigned AllowedCnt = 0; 2348 unsigned TotalAllowedNum = 2349 AllowedNameModifiers.size() - NamedModifiersNumber; 2350 for (unsigned Cnt = 0, End = AllowedNameModifiers.size(); Cnt < End; 2351 ++Cnt) { 2352 OpenMPDirectiveKind NM = AllowedNameModifiers[Cnt]; 2353 if (!FoundNameModifiers[NM]) { 2354 Values += "'"; 2355 Values += getOpenMPDirectiveName(NM); 2356 Values += "'"; 2357 if (AllowedCnt + 2 == TotalAllowedNum) 2358 Values += " or "; 2359 else if (AllowedCnt + 1 != TotalAllowedNum) 2360 Values += Sep; 2361 ++AllowedCnt; 2362 } 2363 } 2364 S.Diag(FoundNameModifiers[OMPD_unknown]->getCondition()->getLocStart(), 2365 diag::err_omp_unnamed_if_clause) 2366 << (TotalAllowedNum > 1) << Values; 2367 } 2368 for (auto Loc : NameModifierLoc) { 2369 S.Diag(Loc, diag::note_omp_previous_named_if_clause); 2370 } 2371 ErrorFound = true; 2372 } 2373 return ErrorFound; 2374 } 2375 2376 StmtResult Sema::ActOnOpenMPExecutableDirective( 2377 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 2378 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 2379 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 2380 StmtResult Res = StmtError(); 2381 // First check CancelRegion which is then used in checkNestingOfRegions. 2382 if (checkCancelRegion(*this, Kind, CancelRegion, StartLoc) || 2383 checkNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 2384 StartLoc)) 2385 return StmtError(); 2386 2387 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 2388 llvm::DenseMap<ValueDecl *, Expr *> VarsWithInheritedDSA; 2389 bool ErrorFound = false; 2390 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 2391 if (AStmt) { 2392 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 2393 2394 // Check default data sharing attributes for referenced variables. 2395 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 2396 int ThisCaptureLevel = getOpenMPCaptureLevels(Kind); 2397 Stmt *S = AStmt; 2398 while (--ThisCaptureLevel >= 0) 2399 S = cast<CapturedStmt>(S)->getCapturedStmt(); 2400 DSAChecker.Visit(S); 2401 if (DSAChecker.isErrorFound()) 2402 return StmtError(); 2403 // Generate list of implicitly defined firstprivate variables. 2404 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 2405 2406 if (!DSAChecker.getImplicitFirstprivate().empty()) { 2407 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 2408 DSAChecker.getImplicitFirstprivate(), SourceLocation(), 2409 SourceLocation(), SourceLocation())) { 2410 ClausesWithImplicit.push_back(Implicit); 2411 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 2412 DSAChecker.getImplicitFirstprivate().size(); 2413 } else 2414 ErrorFound = true; 2415 } 2416 } 2417 2418 llvm::SmallVector<OpenMPDirectiveKind, 4> AllowedNameModifiers; 2419 switch (Kind) { 2420 case OMPD_parallel: 2421 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 2422 EndLoc); 2423 AllowedNameModifiers.push_back(OMPD_parallel); 2424 break; 2425 case OMPD_simd: 2426 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 2427 VarsWithInheritedDSA); 2428 break; 2429 case OMPD_for: 2430 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 2431 VarsWithInheritedDSA); 2432 break; 2433 case OMPD_for_simd: 2434 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 2435 EndLoc, VarsWithInheritedDSA); 2436 break; 2437 case OMPD_sections: 2438 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 2439 EndLoc); 2440 break; 2441 case OMPD_section: 2442 assert(ClausesWithImplicit.empty() && 2443 "No clauses are allowed for 'omp section' directive"); 2444 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 2445 break; 2446 case OMPD_single: 2447 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 2448 EndLoc); 2449 break; 2450 case OMPD_master: 2451 assert(ClausesWithImplicit.empty() && 2452 "No clauses are allowed for 'omp master' directive"); 2453 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 2454 break; 2455 case OMPD_critical: 2456 Res = ActOnOpenMPCriticalDirective(DirName, ClausesWithImplicit, AStmt, 2457 StartLoc, EndLoc); 2458 break; 2459 case OMPD_parallel_for: 2460 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 2461 EndLoc, VarsWithInheritedDSA); 2462 AllowedNameModifiers.push_back(OMPD_parallel); 2463 break; 2464 case OMPD_parallel_for_simd: 2465 Res = ActOnOpenMPParallelForSimdDirective( 2466 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2467 AllowedNameModifiers.push_back(OMPD_parallel); 2468 break; 2469 case OMPD_parallel_sections: 2470 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 2471 StartLoc, EndLoc); 2472 AllowedNameModifiers.push_back(OMPD_parallel); 2473 break; 2474 case OMPD_task: 2475 Res = 2476 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 2477 AllowedNameModifiers.push_back(OMPD_task); 2478 break; 2479 case OMPD_taskyield: 2480 assert(ClausesWithImplicit.empty() && 2481 "No clauses are allowed for 'omp taskyield' directive"); 2482 assert(AStmt == nullptr && 2483 "No associated statement allowed for 'omp taskyield' directive"); 2484 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 2485 break; 2486 case OMPD_barrier: 2487 assert(ClausesWithImplicit.empty() && 2488 "No clauses are allowed for 'omp barrier' directive"); 2489 assert(AStmt == nullptr && 2490 "No associated statement allowed for 'omp barrier' directive"); 2491 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 2492 break; 2493 case OMPD_taskwait: 2494 assert(ClausesWithImplicit.empty() && 2495 "No clauses are allowed for 'omp taskwait' directive"); 2496 assert(AStmt == nullptr && 2497 "No associated statement allowed for 'omp taskwait' directive"); 2498 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 2499 break; 2500 case OMPD_taskgroup: 2501 assert(ClausesWithImplicit.empty() && 2502 "No clauses are allowed for 'omp taskgroup' directive"); 2503 Res = ActOnOpenMPTaskgroupDirective(AStmt, StartLoc, EndLoc); 2504 break; 2505 case OMPD_flush: 2506 assert(AStmt == nullptr && 2507 "No associated statement allowed for 'omp flush' directive"); 2508 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 2509 break; 2510 case OMPD_ordered: 2511 Res = ActOnOpenMPOrderedDirective(ClausesWithImplicit, AStmt, StartLoc, 2512 EndLoc); 2513 break; 2514 case OMPD_atomic: 2515 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 2516 EndLoc); 2517 break; 2518 case OMPD_teams: 2519 Res = 2520 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 2521 break; 2522 case OMPD_target: 2523 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 2524 EndLoc); 2525 AllowedNameModifiers.push_back(OMPD_target); 2526 break; 2527 case OMPD_target_parallel: 2528 Res = ActOnOpenMPTargetParallelDirective(ClausesWithImplicit, AStmt, 2529 StartLoc, EndLoc); 2530 AllowedNameModifiers.push_back(OMPD_target); 2531 AllowedNameModifiers.push_back(OMPD_parallel); 2532 break; 2533 case OMPD_target_parallel_for: 2534 Res = ActOnOpenMPTargetParallelForDirective( 2535 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2536 AllowedNameModifiers.push_back(OMPD_target); 2537 AllowedNameModifiers.push_back(OMPD_parallel); 2538 break; 2539 case OMPD_cancellation_point: 2540 assert(ClausesWithImplicit.empty() && 2541 "No clauses are allowed for 'omp cancellation point' directive"); 2542 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 2543 "cancellation point' directive"); 2544 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 2545 break; 2546 case OMPD_cancel: 2547 assert(AStmt == nullptr && 2548 "No associated statement allowed for 'omp cancel' directive"); 2549 Res = ActOnOpenMPCancelDirective(ClausesWithImplicit, StartLoc, EndLoc, 2550 CancelRegion); 2551 AllowedNameModifiers.push_back(OMPD_cancel); 2552 break; 2553 case OMPD_target_data: 2554 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 2555 EndLoc); 2556 AllowedNameModifiers.push_back(OMPD_target_data); 2557 break; 2558 case OMPD_target_enter_data: 2559 Res = ActOnOpenMPTargetEnterDataDirective(ClausesWithImplicit, StartLoc, 2560 EndLoc); 2561 AllowedNameModifiers.push_back(OMPD_target_enter_data); 2562 break; 2563 case OMPD_target_exit_data: 2564 Res = ActOnOpenMPTargetExitDataDirective(ClausesWithImplicit, StartLoc, 2565 EndLoc); 2566 AllowedNameModifiers.push_back(OMPD_target_exit_data); 2567 break; 2568 case OMPD_taskloop: 2569 Res = ActOnOpenMPTaskLoopDirective(ClausesWithImplicit, AStmt, StartLoc, 2570 EndLoc, VarsWithInheritedDSA); 2571 AllowedNameModifiers.push_back(OMPD_taskloop); 2572 break; 2573 case OMPD_taskloop_simd: 2574 Res = ActOnOpenMPTaskLoopSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 2575 EndLoc, VarsWithInheritedDSA); 2576 AllowedNameModifiers.push_back(OMPD_taskloop); 2577 break; 2578 case OMPD_distribute: 2579 Res = ActOnOpenMPDistributeDirective(ClausesWithImplicit, AStmt, StartLoc, 2580 EndLoc, VarsWithInheritedDSA); 2581 break; 2582 case OMPD_target_update: 2583 assert(!AStmt && "Statement is not allowed for target update"); 2584 Res = 2585 ActOnOpenMPTargetUpdateDirective(ClausesWithImplicit, StartLoc, EndLoc); 2586 AllowedNameModifiers.push_back(OMPD_target_update); 2587 break; 2588 case OMPD_distribute_parallel_for: 2589 Res = ActOnOpenMPDistributeParallelForDirective( 2590 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2591 AllowedNameModifiers.push_back(OMPD_parallel); 2592 break; 2593 case OMPD_distribute_parallel_for_simd: 2594 Res = ActOnOpenMPDistributeParallelForSimdDirective( 2595 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2596 AllowedNameModifiers.push_back(OMPD_parallel); 2597 break; 2598 case OMPD_distribute_simd: 2599 Res = ActOnOpenMPDistributeSimdDirective( 2600 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2601 break; 2602 case OMPD_target_parallel_for_simd: 2603 Res = ActOnOpenMPTargetParallelForSimdDirective( 2604 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2605 AllowedNameModifiers.push_back(OMPD_target); 2606 AllowedNameModifiers.push_back(OMPD_parallel); 2607 break; 2608 case OMPD_target_simd: 2609 Res = ActOnOpenMPTargetSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 2610 EndLoc, VarsWithInheritedDSA); 2611 AllowedNameModifiers.push_back(OMPD_target); 2612 break; 2613 case OMPD_teams_distribute: 2614 Res = ActOnOpenMPTeamsDistributeDirective( 2615 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2616 break; 2617 case OMPD_teams_distribute_simd: 2618 Res = ActOnOpenMPTeamsDistributeSimdDirective( 2619 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2620 break; 2621 case OMPD_teams_distribute_parallel_for_simd: 2622 Res = ActOnOpenMPTeamsDistributeParallelForSimdDirective( 2623 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2624 AllowedNameModifiers.push_back(OMPD_parallel); 2625 break; 2626 case OMPD_teams_distribute_parallel_for: 2627 Res = ActOnOpenMPTeamsDistributeParallelForDirective( 2628 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2629 AllowedNameModifiers.push_back(OMPD_parallel); 2630 break; 2631 case OMPD_target_teams: 2632 Res = ActOnOpenMPTargetTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, 2633 EndLoc); 2634 AllowedNameModifiers.push_back(OMPD_target); 2635 break; 2636 case OMPD_target_teams_distribute: 2637 Res = ActOnOpenMPTargetTeamsDistributeDirective( 2638 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2639 AllowedNameModifiers.push_back(OMPD_target); 2640 break; 2641 case OMPD_target_teams_distribute_parallel_for: 2642 Res = ActOnOpenMPTargetTeamsDistributeParallelForDirective( 2643 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2644 AllowedNameModifiers.push_back(OMPD_target); 2645 AllowedNameModifiers.push_back(OMPD_parallel); 2646 break; 2647 case OMPD_target_teams_distribute_parallel_for_simd: 2648 Res = ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 2649 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2650 AllowedNameModifiers.push_back(OMPD_target); 2651 AllowedNameModifiers.push_back(OMPD_parallel); 2652 break; 2653 case OMPD_target_teams_distribute_simd: 2654 Res = ActOnOpenMPTargetTeamsDistributeSimdDirective( 2655 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2656 AllowedNameModifiers.push_back(OMPD_target); 2657 break; 2658 case OMPD_declare_target: 2659 case OMPD_end_declare_target: 2660 case OMPD_threadprivate: 2661 case OMPD_declare_reduction: 2662 case OMPD_declare_simd: 2663 llvm_unreachable("OpenMP Directive is not allowed"); 2664 case OMPD_unknown: 2665 llvm_unreachable("Unknown OpenMP directive"); 2666 } 2667 2668 for (auto P : VarsWithInheritedDSA) { 2669 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 2670 << P.first << P.second->getSourceRange(); 2671 } 2672 ErrorFound = !VarsWithInheritedDSA.empty() || ErrorFound; 2673 2674 if (!AllowedNameModifiers.empty()) 2675 ErrorFound = checkIfClauses(*this, Kind, Clauses, AllowedNameModifiers) || 2676 ErrorFound; 2677 2678 if (ErrorFound) 2679 return StmtError(); 2680 return Res; 2681 } 2682 2683 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareSimdDirective( 2684 DeclGroupPtrTy DG, OMPDeclareSimdDeclAttr::BranchStateTy BS, Expr *Simdlen, 2685 ArrayRef<Expr *> Uniforms, ArrayRef<Expr *> Aligneds, 2686 ArrayRef<Expr *> Alignments, ArrayRef<Expr *> Linears, 2687 ArrayRef<unsigned> LinModifiers, ArrayRef<Expr *> Steps, SourceRange SR) { 2688 assert(Aligneds.size() == Alignments.size()); 2689 assert(Linears.size() == LinModifiers.size()); 2690 assert(Linears.size() == Steps.size()); 2691 if (!DG || DG.get().isNull()) 2692 return DeclGroupPtrTy(); 2693 2694 if (!DG.get().isSingleDecl()) { 2695 Diag(SR.getBegin(), diag::err_omp_single_decl_in_declare_simd); 2696 return DG; 2697 } 2698 auto *ADecl = DG.get().getSingleDecl(); 2699 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(ADecl)) 2700 ADecl = FTD->getTemplatedDecl(); 2701 2702 auto *FD = dyn_cast<FunctionDecl>(ADecl); 2703 if (!FD) { 2704 Diag(ADecl->getLocation(), diag::err_omp_function_expected); 2705 return DeclGroupPtrTy(); 2706 } 2707 2708 // OpenMP [2.8.2, declare simd construct, Description] 2709 // The parameter of the simdlen clause must be a constant positive integer 2710 // expression. 2711 ExprResult SL; 2712 if (Simdlen) 2713 SL = VerifyPositiveIntegerConstantInClause(Simdlen, OMPC_simdlen); 2714 // OpenMP [2.8.2, declare simd construct, Description] 2715 // The special this pointer can be used as if was one of the arguments to the 2716 // function in any of the linear, aligned, or uniform clauses. 2717 // The uniform clause declares one or more arguments to have an invariant 2718 // value for all concurrent invocations of the function in the execution of a 2719 // single SIMD loop. 2720 llvm::DenseMap<Decl *, Expr *> UniformedArgs; 2721 Expr *UniformedLinearThis = nullptr; 2722 for (auto *E : Uniforms) { 2723 E = E->IgnoreParenImpCasts(); 2724 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 2725 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) 2726 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 2727 FD->getParamDecl(PVD->getFunctionScopeIndex()) 2728 ->getCanonicalDecl() == PVD->getCanonicalDecl()) { 2729 UniformedArgs.insert(std::make_pair(PVD->getCanonicalDecl(), E)); 2730 continue; 2731 } 2732 if (isa<CXXThisExpr>(E)) { 2733 UniformedLinearThis = E; 2734 continue; 2735 } 2736 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 2737 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 2738 } 2739 // OpenMP [2.8.2, declare simd construct, Description] 2740 // The aligned clause declares that the object to which each list item points 2741 // is aligned to the number of bytes expressed in the optional parameter of 2742 // the aligned clause. 2743 // The special this pointer can be used as if was one of the arguments to the 2744 // function in any of the linear, aligned, or uniform clauses. 2745 // The type of list items appearing in the aligned clause must be array, 2746 // pointer, reference to array, or reference to pointer. 2747 llvm::DenseMap<Decl *, Expr *> AlignedArgs; 2748 Expr *AlignedThis = nullptr; 2749 for (auto *E : Aligneds) { 2750 E = E->IgnoreParenImpCasts(); 2751 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 2752 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 2753 auto *CanonPVD = PVD->getCanonicalDecl(); 2754 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 2755 FD->getParamDecl(PVD->getFunctionScopeIndex()) 2756 ->getCanonicalDecl() == CanonPVD) { 2757 // OpenMP [2.8.1, simd construct, Restrictions] 2758 // A list-item cannot appear in more than one aligned clause. 2759 if (AlignedArgs.count(CanonPVD) > 0) { 2760 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 2761 << 1 << E->getSourceRange(); 2762 Diag(AlignedArgs[CanonPVD]->getExprLoc(), 2763 diag::note_omp_explicit_dsa) 2764 << getOpenMPClauseName(OMPC_aligned); 2765 continue; 2766 } 2767 AlignedArgs[CanonPVD] = E; 2768 QualType QTy = PVD->getType() 2769 .getNonReferenceType() 2770 .getUnqualifiedType() 2771 .getCanonicalType(); 2772 const Type *Ty = QTy.getTypePtrOrNull(); 2773 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 2774 Diag(E->getExprLoc(), diag::err_omp_aligned_expected_array_or_ptr) 2775 << QTy << getLangOpts().CPlusPlus << E->getSourceRange(); 2776 Diag(PVD->getLocation(), diag::note_previous_decl) << PVD; 2777 } 2778 continue; 2779 } 2780 } 2781 if (isa<CXXThisExpr>(E)) { 2782 if (AlignedThis) { 2783 Diag(E->getExprLoc(), diag::err_omp_aligned_twice) 2784 << 2 << E->getSourceRange(); 2785 Diag(AlignedThis->getExprLoc(), diag::note_omp_explicit_dsa) 2786 << getOpenMPClauseName(OMPC_aligned); 2787 } 2788 AlignedThis = E; 2789 continue; 2790 } 2791 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 2792 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 2793 } 2794 // The optional parameter of the aligned clause, alignment, must be a constant 2795 // positive integer expression. If no optional parameter is specified, 2796 // implementation-defined default alignments for SIMD instructions on the 2797 // target platforms are assumed. 2798 SmallVector<Expr *, 4> NewAligns; 2799 for (auto *E : Alignments) { 2800 ExprResult Align; 2801 if (E) 2802 Align = VerifyPositiveIntegerConstantInClause(E, OMPC_aligned); 2803 NewAligns.push_back(Align.get()); 2804 } 2805 // OpenMP [2.8.2, declare simd construct, Description] 2806 // The linear clause declares one or more list items to be private to a SIMD 2807 // lane and to have a linear relationship with respect to the iteration space 2808 // of a loop. 2809 // The special this pointer can be used as if was one of the arguments to the 2810 // function in any of the linear, aligned, or uniform clauses. 2811 // When a linear-step expression is specified in a linear clause it must be 2812 // either a constant integer expression or an integer-typed parameter that is 2813 // specified in a uniform clause on the directive. 2814 llvm::DenseMap<Decl *, Expr *> LinearArgs; 2815 const bool IsUniformedThis = UniformedLinearThis != nullptr; 2816 auto MI = LinModifiers.begin(); 2817 for (auto *E : Linears) { 2818 auto LinKind = static_cast<OpenMPLinearClauseKind>(*MI); 2819 ++MI; 2820 E = E->IgnoreParenImpCasts(); 2821 if (auto *DRE = dyn_cast<DeclRefExpr>(E)) 2822 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 2823 auto *CanonPVD = PVD->getCanonicalDecl(); 2824 if (FD->getNumParams() > PVD->getFunctionScopeIndex() && 2825 FD->getParamDecl(PVD->getFunctionScopeIndex()) 2826 ->getCanonicalDecl() == CanonPVD) { 2827 // OpenMP [2.15.3.7, linear Clause, Restrictions] 2828 // A list-item cannot appear in more than one linear clause. 2829 if (LinearArgs.count(CanonPVD) > 0) { 2830 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 2831 << getOpenMPClauseName(OMPC_linear) 2832 << getOpenMPClauseName(OMPC_linear) << E->getSourceRange(); 2833 Diag(LinearArgs[CanonPVD]->getExprLoc(), 2834 diag::note_omp_explicit_dsa) 2835 << getOpenMPClauseName(OMPC_linear); 2836 continue; 2837 } 2838 // Each argument can appear in at most one uniform or linear clause. 2839 if (UniformedArgs.count(CanonPVD) > 0) { 2840 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 2841 << getOpenMPClauseName(OMPC_linear) 2842 << getOpenMPClauseName(OMPC_uniform) << E->getSourceRange(); 2843 Diag(UniformedArgs[CanonPVD]->getExprLoc(), 2844 diag::note_omp_explicit_dsa) 2845 << getOpenMPClauseName(OMPC_uniform); 2846 continue; 2847 } 2848 LinearArgs[CanonPVD] = E; 2849 if (E->isValueDependent() || E->isTypeDependent() || 2850 E->isInstantiationDependent() || 2851 E->containsUnexpandedParameterPack()) 2852 continue; 2853 (void)CheckOpenMPLinearDecl(CanonPVD, E->getExprLoc(), LinKind, 2854 PVD->getOriginalType()); 2855 continue; 2856 } 2857 } 2858 if (isa<CXXThisExpr>(E)) { 2859 if (UniformedLinearThis) { 2860 Diag(E->getExprLoc(), diag::err_omp_wrong_dsa) 2861 << getOpenMPClauseName(OMPC_linear) 2862 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform : OMPC_linear) 2863 << E->getSourceRange(); 2864 Diag(UniformedLinearThis->getExprLoc(), diag::note_omp_explicit_dsa) 2865 << getOpenMPClauseName(IsUniformedThis ? OMPC_uniform 2866 : OMPC_linear); 2867 continue; 2868 } 2869 UniformedLinearThis = E; 2870 if (E->isValueDependent() || E->isTypeDependent() || 2871 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 2872 continue; 2873 (void)CheckOpenMPLinearDecl(/*D=*/nullptr, E->getExprLoc(), LinKind, 2874 E->getType()); 2875 continue; 2876 } 2877 Diag(E->getExprLoc(), diag::err_omp_param_or_this_in_clause) 2878 << FD->getDeclName() << (isa<CXXMethodDecl>(ADecl) ? 1 : 0); 2879 } 2880 Expr *Step = nullptr; 2881 Expr *NewStep = nullptr; 2882 SmallVector<Expr *, 4> NewSteps; 2883 for (auto *E : Steps) { 2884 // Skip the same step expression, it was checked already. 2885 if (Step == E || !E) { 2886 NewSteps.push_back(E ? NewStep : nullptr); 2887 continue; 2888 } 2889 Step = E; 2890 if (auto *DRE = dyn_cast<DeclRefExpr>(Step)) 2891 if (auto *PVD = dyn_cast<ParmVarDecl>(DRE->getDecl())) { 2892 auto *CanonPVD = PVD->getCanonicalDecl(); 2893 if (UniformedArgs.count(CanonPVD) == 0) { 2894 Diag(Step->getExprLoc(), diag::err_omp_expected_uniform_param) 2895 << Step->getSourceRange(); 2896 } else if (E->isValueDependent() || E->isTypeDependent() || 2897 E->isInstantiationDependent() || 2898 E->containsUnexpandedParameterPack() || 2899 CanonPVD->getType()->hasIntegerRepresentation()) 2900 NewSteps.push_back(Step); 2901 else { 2902 Diag(Step->getExprLoc(), diag::err_omp_expected_int_param) 2903 << Step->getSourceRange(); 2904 } 2905 continue; 2906 } 2907 NewStep = Step; 2908 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 2909 !Step->isInstantiationDependent() && 2910 !Step->containsUnexpandedParameterPack()) { 2911 NewStep = PerformOpenMPImplicitIntegerConversion(Step->getExprLoc(), Step) 2912 .get(); 2913 if (NewStep) 2914 NewStep = VerifyIntegerConstantExpression(NewStep).get(); 2915 } 2916 NewSteps.push_back(NewStep); 2917 } 2918 auto *NewAttr = OMPDeclareSimdDeclAttr::CreateImplicit( 2919 Context, BS, SL.get(), const_cast<Expr **>(Uniforms.data()), 2920 Uniforms.size(), const_cast<Expr **>(Aligneds.data()), Aligneds.size(), 2921 const_cast<Expr **>(NewAligns.data()), NewAligns.size(), 2922 const_cast<Expr **>(Linears.data()), Linears.size(), 2923 const_cast<unsigned *>(LinModifiers.data()), LinModifiers.size(), 2924 NewSteps.data(), NewSteps.size(), SR); 2925 ADecl->addAttr(NewAttr); 2926 return ConvertDeclToDeclGroup(ADecl); 2927 } 2928 2929 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 2930 Stmt *AStmt, 2931 SourceLocation StartLoc, 2932 SourceLocation EndLoc) { 2933 if (!AStmt) 2934 return StmtError(); 2935 2936 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 2937 // 1.2.2 OpenMP Language Terminology 2938 // Structured block - An executable statement with a single entry at the 2939 // top and a single exit at the bottom. 2940 // The point of exit cannot be a branch out of the structured block. 2941 // longjmp() and throw() must not violate the entry/exit criteria. 2942 CS->getCapturedDecl()->setNothrow(); 2943 2944 getCurFunction()->setHasBranchProtectedScope(); 2945 2946 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 2947 DSAStack->isCancelRegion()); 2948 } 2949 2950 namespace { 2951 /// \brief Helper class for checking canonical form of the OpenMP loops and 2952 /// extracting iteration space of each loop in the loop nest, that will be used 2953 /// for IR generation. 2954 class OpenMPIterationSpaceChecker { 2955 /// \brief Reference to Sema. 2956 Sema &SemaRef; 2957 /// \brief A location for diagnostics (when there is no some better location). 2958 SourceLocation DefaultLoc; 2959 /// \brief A location for diagnostics (when increment is not compatible). 2960 SourceLocation ConditionLoc; 2961 /// \brief A source location for referring to loop init later. 2962 SourceRange InitSrcRange; 2963 /// \brief A source location for referring to condition later. 2964 SourceRange ConditionSrcRange; 2965 /// \brief A source location for referring to increment later. 2966 SourceRange IncrementSrcRange; 2967 /// \brief Loop variable. 2968 ValueDecl *LCDecl = nullptr; 2969 /// \brief Reference to loop variable. 2970 Expr *LCRef = nullptr; 2971 /// \brief Lower bound (initializer for the var). 2972 Expr *LB = nullptr; 2973 /// \brief Upper bound. 2974 Expr *UB = nullptr; 2975 /// \brief Loop step (increment). 2976 Expr *Step = nullptr; 2977 /// \brief This flag is true when condition is one of: 2978 /// Var < UB 2979 /// Var <= UB 2980 /// UB > Var 2981 /// UB >= Var 2982 bool TestIsLessOp = false; 2983 /// \brief This flag is true when condition is strict ( < or > ). 2984 bool TestIsStrictOp = false; 2985 /// \brief This flag is true when step is subtracted on each iteration. 2986 bool SubtractStep = false; 2987 2988 public: 2989 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 2990 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc) {} 2991 /// \brief Check init-expr for canonical loop form and save loop counter 2992 /// variable - #Var and its initialization value - #LB. 2993 bool CheckInit(Stmt *S, bool EmitDiags = true); 2994 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags 2995 /// for less/greater and for strict/non-strict comparison. 2996 bool CheckCond(Expr *S); 2997 /// \brief Check incr-expr for canonical loop form and return true if it 2998 /// does not conform, otherwise save loop step (#Step). 2999 bool CheckInc(Expr *S); 3000 /// \brief Return the loop counter variable. 3001 ValueDecl *GetLoopDecl() const { return LCDecl; } 3002 /// \brief Return the reference expression to loop counter variable. 3003 Expr *GetLoopDeclRefExpr() const { return LCRef; } 3004 /// \brief Source range of the loop init. 3005 SourceRange GetInitSrcRange() const { return InitSrcRange; } 3006 /// \brief Source range of the loop condition. 3007 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; } 3008 /// \brief Source range of the loop increment. 3009 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; } 3010 /// \brief True if the step should be subtracted. 3011 bool ShouldSubtractStep() const { return SubtractStep; } 3012 /// \brief Build the expression to calculate the number of iterations. 3013 Expr * 3014 BuildNumIterations(Scope *S, const bool LimitedType, 3015 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3016 /// \brief Build the precondition expression for the loops. 3017 Expr *BuildPreCond(Scope *S, Expr *Cond, 3018 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const; 3019 /// \brief Build reference expression to the counter be used for codegen. 3020 DeclRefExpr *BuildCounterVar(llvm::MapVector<Expr *, DeclRefExpr *> &Captures, 3021 DSAStackTy &DSA) const; 3022 /// \brief Build reference expression to the private counter be used for 3023 /// codegen. 3024 Expr *BuildPrivateCounterVar() const; 3025 /// \brief Build initialization of the counter be used for codegen. 3026 Expr *BuildCounterInit() const; 3027 /// \brief Build step of the counter be used for codegen. 3028 Expr *BuildCounterStep() const; 3029 /// \brief Return true if any expression is dependent. 3030 bool Dependent() const; 3031 3032 private: 3033 /// \brief Check the right-hand side of an assignment in the increment 3034 /// expression. 3035 bool CheckIncRHS(Expr *RHS); 3036 /// \brief Helper to set loop counter variable and its initializer. 3037 bool SetLCDeclAndLB(ValueDecl *NewLCDecl, Expr *NewDeclRefExpr, Expr *NewLB); 3038 /// \brief Helper to set upper bound. 3039 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, SourceRange SR, 3040 SourceLocation SL); 3041 /// \brief Helper to set loop increment. 3042 bool SetStep(Expr *NewStep, bool Subtract); 3043 }; 3044 3045 bool OpenMPIterationSpaceChecker::Dependent() const { 3046 if (!LCDecl) { 3047 assert(!LB && !UB && !Step); 3048 return false; 3049 } 3050 return LCDecl->getType()->isDependentType() || 3051 (LB && LB->isValueDependent()) || (UB && UB->isValueDependent()) || 3052 (Step && Step->isValueDependent()); 3053 } 3054 3055 static Expr *getExprAsWritten(Expr *E) { 3056 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) 3057 E = ExprTemp->getSubExpr(); 3058 3059 if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 3060 E = MTE->GetTemporaryExpr(); 3061 3062 while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 3063 E = Binder->getSubExpr(); 3064 3065 if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 3066 E = ICE->getSubExprAsWritten(); 3067 return E->IgnoreParens(); 3068 } 3069 3070 bool OpenMPIterationSpaceChecker::SetLCDeclAndLB(ValueDecl *NewLCDecl, 3071 Expr *NewLCRefExpr, 3072 Expr *NewLB) { 3073 // State consistency checking to ensure correct usage. 3074 assert(LCDecl == nullptr && LB == nullptr && LCRef == nullptr && 3075 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3076 if (!NewLCDecl || !NewLB) 3077 return true; 3078 LCDecl = getCanonicalDecl(NewLCDecl); 3079 LCRef = NewLCRefExpr; 3080 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 3081 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3082 if ((Ctor->isCopyOrMoveConstructor() || 3083 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3084 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3085 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 3086 LB = NewLB; 3087 return false; 3088 } 3089 3090 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp, 3091 SourceRange SR, SourceLocation SL) { 3092 // State consistency checking to ensure correct usage. 3093 assert(LCDecl != nullptr && LB != nullptr && UB == nullptr && 3094 Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 3095 if (!NewUB) 3096 return true; 3097 UB = NewUB; 3098 TestIsLessOp = LessOp; 3099 TestIsStrictOp = StrictOp; 3100 ConditionSrcRange = SR; 3101 ConditionLoc = SL; 3102 return false; 3103 } 3104 3105 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) { 3106 // State consistency checking to ensure correct usage. 3107 assert(LCDecl != nullptr && LB != nullptr && Step == nullptr); 3108 if (!NewStep) 3109 return true; 3110 if (!NewStep->isValueDependent()) { 3111 // Check that the step is integer expression. 3112 SourceLocation StepLoc = NewStep->getLocStart(); 3113 ExprResult Val = 3114 SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep); 3115 if (Val.isInvalid()) 3116 return true; 3117 NewStep = Val.get(); 3118 3119 // OpenMP [2.6, Canonical Loop Form, Restrictions] 3120 // If test-expr is of form var relational-op b and relational-op is < or 3121 // <= then incr-expr must cause var to increase on each iteration of the 3122 // loop. If test-expr is of form var relational-op b and relational-op is 3123 // > or >= then incr-expr must cause var to decrease on each iteration of 3124 // the loop. 3125 // If test-expr is of form b relational-op var and relational-op is < or 3126 // <= then incr-expr must cause var to decrease on each iteration of the 3127 // loop. If test-expr is of form b relational-op var and relational-op is 3128 // > or >= then incr-expr must cause var to increase on each iteration of 3129 // the loop. 3130 llvm::APSInt Result; 3131 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 3132 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 3133 bool IsConstNeg = 3134 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 3135 bool IsConstPos = 3136 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 3137 bool IsConstZero = IsConstant && !Result.getBoolValue(); 3138 if (UB && (IsConstZero || 3139 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 3140 : (IsConstPos || (IsUnsigned && !Subtract))))) { 3141 SemaRef.Diag(NewStep->getExprLoc(), 3142 diag::err_omp_loop_incr_not_compatible) 3143 << LCDecl << TestIsLessOp << NewStep->getSourceRange(); 3144 SemaRef.Diag(ConditionLoc, 3145 diag::note_omp_loop_cond_requres_compatible_incr) 3146 << TestIsLessOp << ConditionSrcRange; 3147 return true; 3148 } 3149 if (TestIsLessOp == Subtract) { 3150 NewStep = 3151 SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, NewStep) 3152 .get(); 3153 Subtract = !Subtract; 3154 } 3155 } 3156 3157 Step = NewStep; 3158 SubtractStep = Subtract; 3159 return false; 3160 } 3161 3162 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { 3163 // Check init-expr for canonical loop form and save loop counter 3164 // variable - #Var and its initialization value - #LB. 3165 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 3166 // var = lb 3167 // integer-type var = lb 3168 // random-access-iterator-type var = lb 3169 // pointer-type var = lb 3170 // 3171 if (!S) { 3172 if (EmitDiags) { 3173 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 3174 } 3175 return true; 3176 } 3177 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 3178 if (!ExprTemp->cleanupsHaveSideEffects()) 3179 S = ExprTemp->getSubExpr(); 3180 3181 InitSrcRange = S->getSourceRange(); 3182 if (Expr *E = dyn_cast<Expr>(S)) 3183 S = E->IgnoreParens(); 3184 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 3185 if (BO->getOpcode() == BO_Assign) { 3186 auto *LHS = BO->getLHS()->IgnoreParens(); 3187 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 3188 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3189 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3190 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3191 return SetLCDeclAndLB(DRE->getDecl(), DRE, BO->getRHS()); 3192 } 3193 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3194 if (ME->isArrow() && 3195 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3196 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3197 } 3198 } 3199 } else if (auto *DS = dyn_cast<DeclStmt>(S)) { 3200 if (DS->isSingleDecl()) { 3201 if (auto *Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 3202 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 3203 // Accept non-canonical init form here but emit ext. warning. 3204 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 3205 SemaRef.Diag(S->getLocStart(), 3206 diag::ext_omp_loop_not_canonical_init) 3207 << S->getSourceRange(); 3208 return SetLCDeclAndLB(Var, nullptr, Var->getInit()); 3209 } 3210 } 3211 } 3212 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3213 if (CE->getOperator() == OO_Equal) { 3214 auto *LHS = CE->getArg(0); 3215 if (auto *DRE = dyn_cast<DeclRefExpr>(LHS)) { 3216 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(DRE->getDecl())) 3217 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3218 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3219 return SetLCDeclAndLB(DRE->getDecl(), DRE, CE->getArg(1)); 3220 } 3221 if (auto *ME = dyn_cast<MemberExpr>(LHS)) { 3222 if (ME->isArrow() && 3223 isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3224 return SetLCDeclAndLB(ME->getMemberDecl(), ME, BO->getRHS()); 3225 } 3226 } 3227 } 3228 3229 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3230 return false; 3231 if (EmitDiags) { 3232 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init) 3233 << S->getSourceRange(); 3234 } 3235 return true; 3236 } 3237 3238 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the 3239 /// variable (which may be the loop variable) if possible. 3240 static const ValueDecl *GetInitLCDecl(Expr *E) { 3241 if (!E) 3242 return nullptr; 3243 E = getExprAsWritten(E); 3244 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 3245 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 3246 if ((Ctor->isCopyOrMoveConstructor() || 3247 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 3248 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 3249 E = CE->getArg(0)->IgnoreParenImpCasts(); 3250 if (auto *DRE = dyn_cast_or_null<DeclRefExpr>(E)) { 3251 if (auto *VD = dyn_cast<VarDecl>(DRE->getDecl())) { 3252 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(VD)) 3253 if (auto *ME = dyn_cast<MemberExpr>(getExprAsWritten(CED->getInit()))) 3254 return getCanonicalDecl(ME->getMemberDecl()); 3255 return getCanonicalDecl(VD); 3256 } 3257 } 3258 if (auto *ME = dyn_cast_or_null<MemberExpr>(E)) 3259 if (ME->isArrow() && isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts())) 3260 return getCanonicalDecl(ME->getMemberDecl()); 3261 return nullptr; 3262 } 3263 3264 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { 3265 // Check test-expr for canonical form, save upper-bound UB, flags for 3266 // less/greater and for strict/non-strict comparison. 3267 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3268 // var relational-op b 3269 // b relational-op var 3270 // 3271 if (!S) { 3272 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << LCDecl; 3273 return true; 3274 } 3275 S = getExprAsWritten(S); 3276 SourceLocation CondLoc = S->getLocStart(); 3277 if (auto *BO = dyn_cast<BinaryOperator>(S)) { 3278 if (BO->isRelationalOp()) { 3279 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3280 return SetUB(BO->getRHS(), 3281 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 3282 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3283 BO->getSourceRange(), BO->getOperatorLoc()); 3284 if (GetInitLCDecl(BO->getRHS()) == LCDecl) 3285 return SetUB(BO->getLHS(), 3286 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 3287 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 3288 BO->getSourceRange(), BO->getOperatorLoc()); 3289 } 3290 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3291 if (CE->getNumArgs() == 2) { 3292 auto Op = CE->getOperator(); 3293 switch (Op) { 3294 case OO_Greater: 3295 case OO_GreaterEqual: 3296 case OO_Less: 3297 case OO_LessEqual: 3298 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3299 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 3300 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3301 CE->getOperatorLoc()); 3302 if (GetInitLCDecl(CE->getArg(1)) == LCDecl) 3303 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 3304 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 3305 CE->getOperatorLoc()); 3306 break; 3307 default: 3308 break; 3309 } 3310 } 3311 } 3312 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3313 return false; 3314 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 3315 << S->getSourceRange() << LCDecl; 3316 return true; 3317 } 3318 3319 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) { 3320 // RHS of canonical loop form increment can be: 3321 // var + incr 3322 // incr + var 3323 // var - incr 3324 // 3325 RHS = RHS->IgnoreParenImpCasts(); 3326 if (auto *BO = dyn_cast<BinaryOperator>(RHS)) { 3327 if (BO->isAdditiveOp()) { 3328 bool IsAdd = BO->getOpcode() == BO_Add; 3329 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3330 return SetStep(BO->getRHS(), !IsAdd); 3331 if (IsAdd && GetInitLCDecl(BO->getRHS()) == LCDecl) 3332 return SetStep(BO->getLHS(), false); 3333 } 3334 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 3335 bool IsAdd = CE->getOperator() == OO_Plus; 3336 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 3337 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3338 return SetStep(CE->getArg(1), !IsAdd); 3339 if (IsAdd && GetInitLCDecl(CE->getArg(1)) == LCDecl) 3340 return SetStep(CE->getArg(0), false); 3341 } 3342 } 3343 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3344 return false; 3345 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr) 3346 << RHS->getSourceRange() << LCDecl; 3347 return true; 3348 } 3349 3350 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { 3351 // Check incr-expr for canonical loop form and return true if it 3352 // does not conform. 3353 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 3354 // ++var 3355 // var++ 3356 // --var 3357 // var-- 3358 // var += incr 3359 // var -= incr 3360 // var = var + incr 3361 // var = incr + var 3362 // var = var - incr 3363 // 3364 if (!S) { 3365 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << LCDecl; 3366 return true; 3367 } 3368 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(S)) 3369 if (!ExprTemp->cleanupsHaveSideEffects()) 3370 S = ExprTemp->getSubExpr(); 3371 3372 IncrementSrcRange = S->getSourceRange(); 3373 S = S->IgnoreParens(); 3374 if (auto *UO = dyn_cast<UnaryOperator>(S)) { 3375 if (UO->isIncrementDecrementOp() && 3376 GetInitLCDecl(UO->getSubExpr()) == LCDecl) 3377 return SetStep(SemaRef 3378 .ActOnIntegerConstant(UO->getLocStart(), 3379 (UO->isDecrementOp() ? -1 : 1)) 3380 .get(), 3381 false); 3382 } else if (auto *BO = dyn_cast<BinaryOperator>(S)) { 3383 switch (BO->getOpcode()) { 3384 case BO_AddAssign: 3385 case BO_SubAssign: 3386 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3387 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 3388 break; 3389 case BO_Assign: 3390 if (GetInitLCDecl(BO->getLHS()) == LCDecl) 3391 return CheckIncRHS(BO->getRHS()); 3392 break; 3393 default: 3394 break; 3395 } 3396 } else if (auto *CE = dyn_cast<CXXOperatorCallExpr>(S)) { 3397 switch (CE->getOperator()) { 3398 case OO_PlusPlus: 3399 case OO_MinusMinus: 3400 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3401 return SetStep(SemaRef 3402 .ActOnIntegerConstant( 3403 CE->getLocStart(), 3404 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)) 3405 .get(), 3406 false); 3407 break; 3408 case OO_PlusEqual: 3409 case OO_MinusEqual: 3410 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3411 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 3412 break; 3413 case OO_Equal: 3414 if (GetInitLCDecl(CE->getArg(0)) == LCDecl) 3415 return CheckIncRHS(CE->getArg(1)); 3416 break; 3417 default: 3418 break; 3419 } 3420 } 3421 if (Dependent() || SemaRef.CurContext->isDependentContext()) 3422 return false; 3423 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr) 3424 << S->getSourceRange() << LCDecl; 3425 return true; 3426 } 3427 3428 static ExprResult 3429 tryBuildCapture(Sema &SemaRef, Expr *Capture, 3430 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 3431 if (SemaRef.CurContext->isDependentContext()) 3432 return ExprResult(Capture); 3433 if (Capture->isEvaluatable(SemaRef.Context, Expr::SE_AllowSideEffects)) 3434 return SemaRef.PerformImplicitConversion( 3435 Capture->IgnoreImpCasts(), Capture->getType(), Sema::AA_Converting, 3436 /*AllowExplicit=*/true); 3437 auto I = Captures.find(Capture); 3438 if (I != Captures.end()) 3439 return buildCapture(SemaRef, Capture, I->second); 3440 DeclRefExpr *Ref = nullptr; 3441 ExprResult Res = buildCapture(SemaRef, Capture, Ref); 3442 Captures[Capture] = Ref; 3443 return Res; 3444 } 3445 3446 /// \brief Build the expression to calculate the number of iterations. 3447 Expr *OpenMPIterationSpaceChecker::BuildNumIterations( 3448 Scope *S, const bool LimitedType, 3449 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 3450 ExprResult Diff; 3451 auto VarType = LCDecl->getType().getNonReferenceType(); 3452 if (VarType->isIntegerType() || VarType->isPointerType() || 3453 SemaRef.getLangOpts().CPlusPlus) { 3454 // Upper - Lower 3455 auto *UBExpr = TestIsLessOp ? UB : LB; 3456 auto *LBExpr = TestIsLessOp ? LB : UB; 3457 Expr *Upper = tryBuildCapture(SemaRef, UBExpr, Captures).get(); 3458 Expr *Lower = tryBuildCapture(SemaRef, LBExpr, Captures).get(); 3459 if (!Upper || !Lower) 3460 return nullptr; 3461 3462 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 3463 3464 if (!Diff.isUsable() && VarType->getAsCXXRecordDecl()) { 3465 // BuildBinOp already emitted error, this one is to point user to upper 3466 // and lower bound, and to tell what is passed to 'operator-'. 3467 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) 3468 << Upper->getSourceRange() << Lower->getSourceRange(); 3469 return nullptr; 3470 } 3471 } 3472 3473 if (!Diff.isUsable()) 3474 return nullptr; 3475 3476 // Upper - Lower [- 1] 3477 if (TestIsStrictOp) 3478 Diff = SemaRef.BuildBinOp( 3479 S, DefaultLoc, BO_Sub, Diff.get(), 3480 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 3481 if (!Diff.isUsable()) 3482 return nullptr; 3483 3484 // Upper - Lower [- 1] + Step 3485 auto NewStep = tryBuildCapture(SemaRef, Step, Captures); 3486 if (!NewStep.isUsable()) 3487 return nullptr; 3488 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), NewStep.get()); 3489 if (!Diff.isUsable()) 3490 return nullptr; 3491 3492 // Parentheses (for dumping/debugging purposes only). 3493 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 3494 if (!Diff.isUsable()) 3495 return nullptr; 3496 3497 // (Upper - Lower [- 1] + Step) / Step 3498 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), NewStep.get()); 3499 if (!Diff.isUsable()) 3500 return nullptr; 3501 3502 // OpenMP runtime requires 32-bit or 64-bit loop variables. 3503 QualType Type = Diff.get()->getType(); 3504 auto &C = SemaRef.Context; 3505 bool UseVarType = VarType->hasIntegerRepresentation() && 3506 C.getTypeSize(Type) > C.getTypeSize(VarType); 3507 if (!Type->isIntegerType() || UseVarType) { 3508 unsigned NewSize = 3509 UseVarType ? C.getTypeSize(VarType) : C.getTypeSize(Type); 3510 bool IsSigned = UseVarType ? VarType->hasSignedIntegerRepresentation() 3511 : Type->hasSignedIntegerRepresentation(); 3512 Type = C.getIntTypeForBitwidth(NewSize, IsSigned); 3513 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), Type)) { 3514 Diff = SemaRef.PerformImplicitConversion( 3515 Diff.get(), Type, Sema::AA_Converting, /*AllowExplicit=*/true); 3516 if (!Diff.isUsable()) 3517 return nullptr; 3518 } 3519 } 3520 if (LimitedType) { 3521 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 3522 if (NewSize != C.getTypeSize(Type)) { 3523 if (NewSize < C.getTypeSize(Type)) { 3524 assert(NewSize == 64 && "incorrect loop var size"); 3525 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 3526 << InitSrcRange << ConditionSrcRange; 3527 } 3528 QualType NewType = C.getIntTypeForBitwidth( 3529 NewSize, Type->hasSignedIntegerRepresentation() || 3530 C.getTypeSize(Type) < NewSize); 3531 if (!SemaRef.Context.hasSameType(Diff.get()->getType(), NewType)) { 3532 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 3533 Sema::AA_Converting, true); 3534 if (!Diff.isUsable()) 3535 return nullptr; 3536 } 3537 } 3538 } 3539 3540 return Diff.get(); 3541 } 3542 3543 Expr *OpenMPIterationSpaceChecker::BuildPreCond( 3544 Scope *S, Expr *Cond, 3545 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) const { 3546 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 3547 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 3548 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 3549 3550 auto NewLB = tryBuildCapture(SemaRef, LB, Captures); 3551 auto NewUB = tryBuildCapture(SemaRef, UB, Captures); 3552 if (!NewLB.isUsable() || !NewUB.isUsable()) 3553 return nullptr; 3554 3555 auto CondExpr = SemaRef.BuildBinOp( 3556 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) 3557 : (TestIsStrictOp ? BO_GT : BO_GE), 3558 NewLB.get(), NewUB.get()); 3559 if (CondExpr.isUsable()) { 3560 if (!SemaRef.Context.hasSameUnqualifiedType(CondExpr.get()->getType(), 3561 SemaRef.Context.BoolTy)) 3562 CondExpr = SemaRef.PerformImplicitConversion( 3563 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 3564 /*AllowExplicit=*/true); 3565 } 3566 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 3567 // Otherwise use original loop conditon and evaluate it in runtime. 3568 return CondExpr.isUsable() ? CondExpr.get() : Cond; 3569 } 3570 3571 /// \brief Build reference expression to the counter be used for codegen. 3572 DeclRefExpr *OpenMPIterationSpaceChecker::BuildCounterVar( 3573 llvm::MapVector<Expr *, DeclRefExpr *> &Captures, DSAStackTy &DSA) const { 3574 auto *VD = dyn_cast<VarDecl>(LCDecl); 3575 if (!VD) { 3576 VD = SemaRef.IsOpenMPCapturedDecl(LCDecl); 3577 auto *Ref = buildDeclRefExpr( 3578 SemaRef, VD, VD->getType().getNonReferenceType(), DefaultLoc); 3579 DSAStackTy::DSAVarData Data = DSA.getTopDSA(LCDecl, /*FromParent=*/false); 3580 // If the loop control decl is explicitly marked as private, do not mark it 3581 // as captured again. 3582 if (!isOpenMPPrivate(Data.CKind) || !Data.RefExpr) 3583 Captures.insert(std::make_pair(LCRef, Ref)); 3584 return Ref; 3585 } 3586 return buildDeclRefExpr(SemaRef, VD, VD->getType().getNonReferenceType(), 3587 DefaultLoc); 3588 } 3589 3590 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const { 3591 if (LCDecl && !LCDecl->isInvalidDecl()) { 3592 auto Type = LCDecl->getType().getNonReferenceType(); 3593 auto *PrivateVar = 3594 buildVarDecl(SemaRef, DefaultLoc, Type, LCDecl->getName(), 3595 LCDecl->hasAttrs() ? &LCDecl->getAttrs() : nullptr); 3596 if (PrivateVar->isInvalidDecl()) 3597 return nullptr; 3598 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 3599 } 3600 return nullptr; 3601 } 3602 3603 /// \brief Build initialization of the counter to be used for codegen. 3604 Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; } 3605 3606 /// \brief Build step of the counter be used for codegen. 3607 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; } 3608 3609 /// \brief Iteration space of a single for loop. 3610 struct LoopIterationSpace final { 3611 /// \brief Condition of the loop. 3612 Expr *PreCond = nullptr; 3613 /// \brief This expression calculates the number of iterations in the loop. 3614 /// It is always possible to calculate it before starting the loop. 3615 Expr *NumIterations = nullptr; 3616 /// \brief The loop counter variable. 3617 Expr *CounterVar = nullptr; 3618 /// \brief Private loop counter variable. 3619 Expr *PrivateCounterVar = nullptr; 3620 /// \brief This is initializer for the initial value of #CounterVar. 3621 Expr *CounterInit = nullptr; 3622 /// \brief This is step for the #CounterVar used to generate its update: 3623 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 3624 Expr *CounterStep = nullptr; 3625 /// \brief Should step be subtracted? 3626 bool Subtract = false; 3627 /// \brief Source range of the loop init. 3628 SourceRange InitSrcRange; 3629 /// \brief Source range of the loop condition. 3630 SourceRange CondSrcRange; 3631 /// \brief Source range of the loop increment. 3632 SourceRange IncSrcRange; 3633 }; 3634 3635 } // namespace 3636 3637 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 3638 assert(getLangOpts().OpenMP && "OpenMP is not active."); 3639 assert(Init && "Expected loop in canonical form."); 3640 unsigned AssociatedLoops = DSAStack->getAssociatedLoops(); 3641 if (AssociatedLoops > 0 && 3642 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 3643 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 3644 if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) { 3645 if (auto *D = ISC.GetLoopDecl()) { 3646 auto *VD = dyn_cast<VarDecl>(D); 3647 if (!VD) { 3648 if (auto *Private = IsOpenMPCapturedDecl(D)) 3649 VD = Private; 3650 else { 3651 auto *Ref = buildCapture(*this, D, ISC.GetLoopDeclRefExpr(), 3652 /*WithInit=*/false); 3653 VD = cast<VarDecl>(Ref->getDecl()); 3654 } 3655 } 3656 DSAStack->addLoopControlVariable(D, VD); 3657 } 3658 } 3659 DSAStack->setAssociatedLoops(AssociatedLoops - 1); 3660 } 3661 } 3662 3663 /// \brief Called on a for stmt to check and extract its iteration space 3664 /// for further processing (such as collapsing). 3665 static bool CheckOpenMPIterationSpace( 3666 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 3667 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 3668 Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, 3669 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 3670 LoopIterationSpace &ResultIterSpace, 3671 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 3672 // OpenMP [2.6, Canonical Loop Form] 3673 // for (init-expr; test-expr; incr-expr) structured-block 3674 auto *For = dyn_cast_or_null<ForStmt>(S); 3675 if (!For) { 3676 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for) 3677 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 3678 << getOpenMPDirectiveName(DKind) << NestedLoopCount 3679 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 3680 if (NestedLoopCount > 1) { 3681 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 3682 SemaRef.Diag(DSA.getConstructLoc(), 3683 diag::note_omp_collapse_ordered_expr) 3684 << 2 << CollapseLoopCountExpr->getSourceRange() 3685 << OrderedLoopCountExpr->getSourceRange(); 3686 else if (CollapseLoopCountExpr) 3687 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 3688 diag::note_omp_collapse_ordered_expr) 3689 << 0 << CollapseLoopCountExpr->getSourceRange(); 3690 else 3691 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 3692 diag::note_omp_collapse_ordered_expr) 3693 << 1 << OrderedLoopCountExpr->getSourceRange(); 3694 } 3695 return true; 3696 } 3697 assert(For->getBody()); 3698 3699 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 3700 3701 // Check init. 3702 auto Init = For->getInit(); 3703 if (ISC.CheckInit(Init)) 3704 return true; 3705 3706 bool HasErrors = false; 3707 3708 // Check loop variable's type. 3709 if (auto *LCDecl = ISC.GetLoopDecl()) { 3710 auto *LoopDeclRefExpr = ISC.GetLoopDeclRefExpr(); 3711 3712 // OpenMP [2.6, Canonical Loop Form] 3713 // Var is one of the following: 3714 // A variable of signed or unsigned integer type. 3715 // For C++, a variable of a random access iterator type. 3716 // For C, a variable of a pointer type. 3717 auto VarType = LCDecl->getType().getNonReferenceType(); 3718 if (!VarType->isDependentType() && !VarType->isIntegerType() && 3719 !VarType->isPointerType() && 3720 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 3721 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type) 3722 << SemaRef.getLangOpts().CPlusPlus; 3723 HasErrors = true; 3724 } 3725 3726 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in 3727 // a Construct 3728 // The loop iteration variable(s) in the associated for-loop(s) of a for or 3729 // parallel for construct is (are) private. 3730 // The loop iteration variable in the associated for-loop of a simd 3731 // construct with just one associated for-loop is linear with a 3732 // constant-linear-step that is the increment of the associated for-loop. 3733 // Exclude loop var from the list of variables with implicitly defined data 3734 // sharing attributes. 3735 VarsWithImplicitDSA.erase(LCDecl); 3736 3737 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 3738 // in a Construct, C/C++]. 3739 // The loop iteration variable in the associated for-loop of a simd 3740 // construct with just one associated for-loop may be listed in a linear 3741 // clause with a constant-linear-step that is the increment of the 3742 // associated for-loop. 3743 // The loop iteration variable(s) in the associated for-loop(s) of a for or 3744 // parallel for construct may be listed in a private or lastprivate clause. 3745 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(LCDecl, false); 3746 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 3747 // declared in the loop and it is predetermined as a private. 3748 auto PredeterminedCKind = 3749 isOpenMPSimdDirective(DKind) 3750 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 3751 : OMPC_private; 3752 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 3753 DVar.CKind != PredeterminedCKind) || 3754 ((isOpenMPWorksharingDirective(DKind) || DKind == OMPD_taskloop || 3755 isOpenMPDistributeDirective(DKind)) && 3756 !isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 3757 DVar.CKind != OMPC_private && DVar.CKind != OMPC_lastprivate)) && 3758 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 3759 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa) 3760 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 3761 << getOpenMPClauseName(PredeterminedCKind); 3762 if (DVar.RefExpr == nullptr) 3763 DVar.CKind = PredeterminedCKind; 3764 ReportOriginalDSA(SemaRef, &DSA, LCDecl, DVar, /*IsLoopIterVar=*/true); 3765 HasErrors = true; 3766 } else if (LoopDeclRefExpr != nullptr) { 3767 // Make the loop iteration variable private (for worksharing constructs), 3768 // linear (for simd directives with the only one associated loop) or 3769 // lastprivate (for simd directives with several collapsed or ordered 3770 // loops). 3771 if (DVar.CKind == OMPC_unknown) 3772 DVar = DSA.hasDSA(LCDecl, isOpenMPPrivate, 3773 [](OpenMPDirectiveKind) -> bool { return true; }, 3774 /*FromParent=*/false); 3775 DSA.addDSA(LCDecl, LoopDeclRefExpr, PredeterminedCKind); 3776 } 3777 3778 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 3779 3780 // Check test-expr. 3781 HasErrors |= ISC.CheckCond(For->getCond()); 3782 3783 // Check incr-expr. 3784 HasErrors |= ISC.CheckInc(For->getInc()); 3785 } 3786 3787 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 3788 return HasErrors; 3789 3790 // Build the loop's iteration space representation. 3791 ResultIterSpace.PreCond = 3792 ISC.BuildPreCond(DSA.getCurScope(), For->getCond(), Captures); 3793 ResultIterSpace.NumIterations = ISC.BuildNumIterations( 3794 DSA.getCurScope(), 3795 (isOpenMPWorksharingDirective(DKind) || 3796 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)), 3797 Captures); 3798 ResultIterSpace.CounterVar = ISC.BuildCounterVar(Captures, DSA); 3799 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); 3800 ResultIterSpace.CounterInit = ISC.BuildCounterInit(); 3801 ResultIterSpace.CounterStep = ISC.BuildCounterStep(); 3802 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); 3803 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange(); 3804 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange(); 3805 ResultIterSpace.Subtract = ISC.ShouldSubtractStep(); 3806 3807 HasErrors |= (ResultIterSpace.PreCond == nullptr || 3808 ResultIterSpace.NumIterations == nullptr || 3809 ResultIterSpace.CounterVar == nullptr || 3810 ResultIterSpace.PrivateCounterVar == nullptr || 3811 ResultIterSpace.CounterInit == nullptr || 3812 ResultIterSpace.CounterStep == nullptr); 3813 3814 return HasErrors; 3815 } 3816 3817 /// \brief Build 'VarRef = Start. 3818 static ExprResult 3819 BuildCounterInit(Sema &SemaRef, Scope *S, SourceLocation Loc, ExprResult VarRef, 3820 ExprResult Start, 3821 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 3822 // Build 'VarRef = Start. 3823 auto NewStart = tryBuildCapture(SemaRef, Start.get(), Captures); 3824 if (!NewStart.isUsable()) 3825 return ExprError(); 3826 if (!SemaRef.Context.hasSameType(NewStart.get()->getType(), 3827 VarRef.get()->getType())) { 3828 NewStart = SemaRef.PerformImplicitConversion( 3829 NewStart.get(), VarRef.get()->getType(), Sema::AA_Converting, 3830 /*AllowExplicit=*/true); 3831 if (!NewStart.isUsable()) 3832 return ExprError(); 3833 } 3834 3835 auto Init = 3836 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 3837 return Init; 3838 } 3839 3840 /// \brief Build 'VarRef = Start + Iter * Step'. 3841 static ExprResult 3842 BuildCounterUpdate(Sema &SemaRef, Scope *S, SourceLocation Loc, 3843 ExprResult VarRef, ExprResult Start, ExprResult Iter, 3844 ExprResult Step, bool Subtract, 3845 llvm::MapVector<Expr *, DeclRefExpr *> *Captures = nullptr) { 3846 // Add parentheses (for debugging purposes only). 3847 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 3848 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 3849 !Step.isUsable()) 3850 return ExprError(); 3851 3852 ExprResult NewStep = Step; 3853 if (Captures) 3854 NewStep = tryBuildCapture(SemaRef, Step.get(), *Captures); 3855 if (NewStep.isInvalid()) 3856 return ExprError(); 3857 ExprResult Update = 3858 SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), NewStep.get()); 3859 if (!Update.isUsable()) 3860 return ExprError(); 3861 3862 // Try to build 'VarRef = Start, VarRef (+|-)= Iter * Step' or 3863 // 'VarRef = Start (+|-) Iter * Step'. 3864 ExprResult NewStart = Start; 3865 if (Captures) 3866 NewStart = tryBuildCapture(SemaRef, Start.get(), *Captures); 3867 if (NewStart.isInvalid()) 3868 return ExprError(); 3869 3870 // First attempt: try to build 'VarRef = Start, VarRef += Iter * Step'. 3871 ExprResult SavedUpdate = Update; 3872 ExprResult UpdateVal; 3873 if (VarRef.get()->getType()->isOverloadableType() || 3874 NewStart.get()->getType()->isOverloadableType() || 3875 Update.get()->getType()->isOverloadableType()) { 3876 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 3877 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 3878 Update = 3879 SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), NewStart.get()); 3880 if (Update.isUsable()) { 3881 UpdateVal = 3882 SemaRef.BuildBinOp(S, Loc, Subtract ? BO_SubAssign : BO_AddAssign, 3883 VarRef.get(), SavedUpdate.get()); 3884 if (UpdateVal.isUsable()) { 3885 Update = SemaRef.CreateBuiltinBinOp(Loc, BO_Comma, Update.get(), 3886 UpdateVal.get()); 3887 } 3888 } 3889 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 3890 } 3891 3892 // Second attempt: try to build 'VarRef = Start (+|-) Iter * Step'. 3893 if (!Update.isUsable() || !UpdateVal.isUsable()) { 3894 Update = SemaRef.BuildBinOp(S, Loc, Subtract ? BO_Sub : BO_Add, 3895 NewStart.get(), SavedUpdate.get()); 3896 if (!Update.isUsable()) 3897 return ExprError(); 3898 3899 if (!SemaRef.Context.hasSameType(Update.get()->getType(), 3900 VarRef.get()->getType())) { 3901 Update = SemaRef.PerformImplicitConversion( 3902 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 3903 if (!Update.isUsable()) 3904 return ExprError(); 3905 } 3906 3907 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 3908 } 3909 return Update; 3910 } 3911 3912 /// \brief Convert integer expression \a E to make it have at least \a Bits 3913 /// bits. 3914 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, Sema &SemaRef) { 3915 if (E == nullptr) 3916 return ExprError(); 3917 auto &C = SemaRef.Context; 3918 QualType OldType = E->getType(); 3919 unsigned HasBits = C.getTypeSize(OldType); 3920 if (HasBits >= Bits) 3921 return ExprResult(E); 3922 // OK to convert to signed, because new type has more bits than old. 3923 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 3924 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 3925 true); 3926 } 3927 3928 /// \brief Check if the given expression \a E is a constant integer that fits 3929 /// into \a Bits bits. 3930 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { 3931 if (E == nullptr) 3932 return false; 3933 llvm::APSInt Result; 3934 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 3935 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 3936 return false; 3937 } 3938 3939 /// Build preinits statement for the given declarations. 3940 static Stmt *buildPreInits(ASTContext &Context, 3941 SmallVectorImpl<Decl *> &PreInits) { 3942 if (!PreInits.empty()) { 3943 return new (Context) DeclStmt( 3944 DeclGroupRef::Create(Context, PreInits.begin(), PreInits.size()), 3945 SourceLocation(), SourceLocation()); 3946 } 3947 return nullptr; 3948 } 3949 3950 /// Build preinits statement for the given declarations. 3951 static Stmt *buildPreInits(ASTContext &Context, 3952 llvm::MapVector<Expr *, DeclRefExpr *> &Captures) { 3953 if (!Captures.empty()) { 3954 SmallVector<Decl *, 16> PreInits; 3955 for (auto &Pair : Captures) 3956 PreInits.push_back(Pair.second->getDecl()); 3957 return buildPreInits(Context, PreInits); 3958 } 3959 return nullptr; 3960 } 3961 3962 /// Build postupdate expression for the given list of postupdates expressions. 3963 static Expr *buildPostUpdate(Sema &S, ArrayRef<Expr *> PostUpdates) { 3964 Expr *PostUpdate = nullptr; 3965 if (!PostUpdates.empty()) { 3966 for (auto *E : PostUpdates) { 3967 Expr *ConvE = S.BuildCStyleCastExpr( 3968 E->getExprLoc(), 3969 S.Context.getTrivialTypeSourceInfo(S.Context.VoidTy), 3970 E->getExprLoc(), E) 3971 .get(); 3972 PostUpdate = PostUpdate 3973 ? S.CreateBuiltinBinOp(ConvE->getExprLoc(), BO_Comma, 3974 PostUpdate, ConvE) 3975 .get() 3976 : ConvE; 3977 } 3978 } 3979 return PostUpdate; 3980 } 3981 3982 /// \brief Called on a for stmt to check itself and nested loops (if any). 3983 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 3984 /// number of collapsed loops otherwise. 3985 static unsigned 3986 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 3987 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 3988 DSAStackTy &DSA, 3989 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA, 3990 OMPLoopDirective::HelperExprs &Built) { 3991 unsigned NestedLoopCount = 1; 3992 if (CollapseLoopCountExpr) { 3993 // Found 'collapse' clause - calculate collapse number. 3994 llvm::APSInt Result; 3995 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 3996 NestedLoopCount = Result.getLimitedValue(); 3997 } 3998 if (OrderedLoopCountExpr) { 3999 // Found 'ordered' clause - calculate collapse number. 4000 llvm::APSInt Result; 4001 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) { 4002 if (Result.getLimitedValue() < NestedLoopCount) { 4003 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 4004 diag::err_omp_wrong_ordered_loop_count) 4005 << OrderedLoopCountExpr->getSourceRange(); 4006 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 4007 diag::note_collapse_loop_count) 4008 << CollapseLoopCountExpr->getSourceRange(); 4009 } 4010 NestedLoopCount = Result.getLimitedValue(); 4011 } 4012 } 4013 // This is helper routine for loop directives (e.g., 'for', 'simd', 4014 // 'for simd', etc.). 4015 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 4016 SmallVector<LoopIterationSpace, 4> IterSpaces; 4017 IterSpaces.resize(NestedLoopCount); 4018 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 4019 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 4020 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, 4021 NestedLoopCount, CollapseLoopCountExpr, 4022 OrderedLoopCountExpr, VarsWithImplicitDSA, 4023 IterSpaces[Cnt], Captures)) 4024 return 0; 4025 // Move on to the next nested for loop, or to the loop body. 4026 // OpenMP [2.8.1, simd construct, Restrictions] 4027 // All loops associated with the construct must be perfectly nested; that 4028 // is, there must be no intervening code nor any OpenMP directive between 4029 // any two loops. 4030 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 4031 } 4032 4033 Built.clear(/* size */ NestedLoopCount); 4034 4035 if (SemaRef.CurContext->isDependentContext()) 4036 return NestedLoopCount; 4037 4038 // An example of what is generated for the following code: 4039 // 4040 // #pragma omp simd collapse(2) ordered(2) 4041 // for (i = 0; i < NI; ++i) 4042 // for (k = 0; k < NK; ++k) 4043 // for (j = J0; j < NJ; j+=2) { 4044 // <loop body> 4045 // } 4046 // 4047 // We generate the code below. 4048 // Note: the loop body may be outlined in CodeGen. 4049 // Note: some counters may be C++ classes, operator- is used to find number of 4050 // iterations and operator+= to calculate counter value. 4051 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 4052 // or i64 is currently supported). 4053 // 4054 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 4055 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 4056 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 4057 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 4058 // // similar updates for vars in clauses (e.g. 'linear') 4059 // <loop body (using local i and j)> 4060 // } 4061 // i = NI; // assign final values of counters 4062 // j = NJ; 4063 // 4064 4065 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 4066 // the iteration counts of the collapsed for loops. 4067 // Precondition tests if there is at least one iteration (all conditions are 4068 // true). 4069 auto PreCond = ExprResult(IterSpaces[0].PreCond); 4070 auto N0 = IterSpaces[0].NumIterations; 4071 ExprResult LastIteration32 = WidenIterationCount( 4072 32 /* Bits */, SemaRef 4073 .PerformImplicitConversion( 4074 N0->IgnoreImpCasts(), N0->getType(), 4075 Sema::AA_Converting, /*AllowExplicit=*/true) 4076 .get(), 4077 SemaRef); 4078 ExprResult LastIteration64 = WidenIterationCount( 4079 64 /* Bits */, SemaRef 4080 .PerformImplicitConversion( 4081 N0->IgnoreImpCasts(), N0->getType(), 4082 Sema::AA_Converting, /*AllowExplicit=*/true) 4083 .get(), 4084 SemaRef); 4085 4086 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 4087 return NestedLoopCount; 4088 4089 auto &C = SemaRef.Context; 4090 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 4091 4092 Scope *CurScope = DSA.getCurScope(); 4093 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 4094 if (PreCond.isUsable()) { 4095 PreCond = 4096 SemaRef.BuildBinOp(CurScope, PreCond.get()->getExprLoc(), BO_LAnd, 4097 PreCond.get(), IterSpaces[Cnt].PreCond); 4098 } 4099 auto N = IterSpaces[Cnt].NumIterations; 4100 SourceLocation Loc = N->getExprLoc(); 4101 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 4102 if (LastIteration32.isUsable()) 4103 LastIteration32 = SemaRef.BuildBinOp( 4104 CurScope, Loc, BO_Mul, LastIteration32.get(), 4105 SemaRef 4106 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4107 Sema::AA_Converting, 4108 /*AllowExplicit=*/true) 4109 .get()); 4110 if (LastIteration64.isUsable()) 4111 LastIteration64 = SemaRef.BuildBinOp( 4112 CurScope, Loc, BO_Mul, LastIteration64.get(), 4113 SemaRef 4114 .PerformImplicitConversion(N->IgnoreImpCasts(), N->getType(), 4115 Sema::AA_Converting, 4116 /*AllowExplicit=*/true) 4117 .get()); 4118 } 4119 4120 // Choose either the 32-bit or 64-bit version. 4121 ExprResult LastIteration = LastIteration64; 4122 if (LastIteration32.isUsable() && 4123 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 4124 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 4125 FitsInto( 4126 32 /* Bits */, 4127 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 4128 LastIteration64.get(), SemaRef))) 4129 LastIteration = LastIteration32; 4130 QualType VType = LastIteration.get()->getType(); 4131 QualType RealVType = VType; 4132 QualType StrideVType = VType; 4133 if (isOpenMPTaskLoopDirective(DKind)) { 4134 VType = 4135 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/0); 4136 StrideVType = 4137 SemaRef.Context.getIntTypeForBitwidth(/*DestWidth=*/64, /*Signed=*/1); 4138 } 4139 4140 if (!LastIteration.isUsable()) 4141 return 0; 4142 4143 // Save the number of iterations. 4144 ExprResult NumIterations = LastIteration; 4145 { 4146 LastIteration = SemaRef.BuildBinOp( 4147 CurScope, LastIteration.get()->getExprLoc(), BO_Sub, 4148 LastIteration.get(), 4149 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4150 if (!LastIteration.isUsable()) 4151 return 0; 4152 } 4153 4154 // Calculate the last iteration number beforehand instead of doing this on 4155 // each iteration. Do not do this if the number of iterations may be kfold-ed. 4156 llvm::APSInt Result; 4157 bool IsConstant = 4158 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 4159 ExprResult CalcLastIteration; 4160 if (!IsConstant) { 4161 ExprResult SaveRef = 4162 tryBuildCapture(SemaRef, LastIteration.get(), Captures); 4163 LastIteration = SaveRef; 4164 4165 // Prepare SaveRef + 1. 4166 NumIterations = SemaRef.BuildBinOp( 4167 CurScope, SaveRef.get()->getExprLoc(), BO_Add, SaveRef.get(), 4168 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 4169 if (!NumIterations.isUsable()) 4170 return 0; 4171 } 4172 4173 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 4174 4175 // Build variables passed into runtime, necessary for worksharing directives. 4176 ExprResult LB, UB, IL, ST, EUB, CombLB, CombUB, PrevLB, PrevUB, CombEUB; 4177 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4178 isOpenMPDistributeDirective(DKind)) { 4179 // Lower bound variable, initialized with zero. 4180 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 4181 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 4182 SemaRef.AddInitializerToDecl(LBDecl, 4183 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4184 /*DirectInit*/ false); 4185 4186 // Upper bound variable, initialized with last iteration number. 4187 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 4188 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 4189 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 4190 /*DirectInit*/ false); 4191 4192 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 4193 // This will be used to implement clause 'lastprivate'. 4194 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 4195 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 4196 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 4197 SemaRef.AddInitializerToDecl(ILDecl, 4198 SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4199 /*DirectInit*/ false); 4200 4201 // Stride variable returned by runtime (we initialize it to 1 by default). 4202 VarDecl *STDecl = 4203 buildVarDecl(SemaRef, InitLoc, StrideVType, ".omp.stride"); 4204 ST = buildDeclRefExpr(SemaRef, STDecl, StrideVType, InitLoc); 4205 SemaRef.AddInitializerToDecl(STDecl, 4206 SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 4207 /*DirectInit*/ false); 4208 4209 // Build expression: UB = min(UB, LastIteration) 4210 // It is necessary for CodeGen of directives with static scheduling. 4211 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 4212 UB.get(), LastIteration.get()); 4213 ExprResult CondOp = SemaRef.ActOnConditionalOp( 4214 InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get()); 4215 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 4216 CondOp.get()); 4217 EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); 4218 4219 // If we have a combined directive that combines 'distribute', 'for' or 4220 // 'simd' we need to be able to access the bounds of the schedule of the 4221 // enclosing region. E.g. in 'distribute parallel for' the bounds obtained 4222 // by scheduling 'distribute' have to be passed to the schedule of 'for'. 4223 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4224 4225 // Lower bound variable, initialized with zero. 4226 VarDecl *CombLBDecl = 4227 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.lb"); 4228 CombLB = buildDeclRefExpr(SemaRef, CombLBDecl, VType, InitLoc); 4229 SemaRef.AddInitializerToDecl( 4230 CombLBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 4231 /*DirectInit*/ false); 4232 4233 // Upper bound variable, initialized with last iteration number. 4234 VarDecl *CombUBDecl = 4235 buildVarDecl(SemaRef, InitLoc, VType, ".omp.comb.ub"); 4236 CombUB = buildDeclRefExpr(SemaRef, CombUBDecl, VType, InitLoc); 4237 SemaRef.AddInitializerToDecl(CombUBDecl, LastIteration.get(), 4238 /*DirectInit*/ false); 4239 4240 ExprResult CombIsUBGreater = SemaRef.BuildBinOp( 4241 CurScope, InitLoc, BO_GT, CombUB.get(), LastIteration.get()); 4242 ExprResult CombCondOp = 4243 SemaRef.ActOnConditionalOp(InitLoc, InitLoc, CombIsUBGreater.get(), 4244 LastIteration.get(), CombUB.get()); 4245 CombEUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, CombUB.get(), 4246 CombCondOp.get()); 4247 CombEUB = SemaRef.ActOnFinishFullExpr(CombEUB.get()); 4248 4249 auto *CD = cast<CapturedStmt>(AStmt)->getCapturedDecl(); 4250 // We expect to have at least 2 more parameters than the 'parallel' 4251 // directive does - the lower and upper bounds of the previous schedule. 4252 assert(CD->getNumParams() >= 4 && 4253 "Unexpected number of parameters in loop combined directive"); 4254 4255 // Set the proper type for the bounds given what we learned from the 4256 // enclosed loops. 4257 auto *PrevLBDecl = CD->getParam(/*PrevLB=*/2); 4258 auto *PrevUBDecl = CD->getParam(/*PrevUB=*/3); 4259 4260 // Previous lower and upper bounds are obtained from the region 4261 // parameters. 4262 PrevLB = 4263 buildDeclRefExpr(SemaRef, PrevLBDecl, PrevLBDecl->getType(), InitLoc); 4264 PrevUB = 4265 buildDeclRefExpr(SemaRef, PrevUBDecl, PrevUBDecl->getType(), InitLoc); 4266 } 4267 } 4268 4269 // Build the iteration variable and its initialization before loop. 4270 ExprResult IV; 4271 ExprResult Init, CombInit; 4272 { 4273 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, RealVType, ".omp.iv"); 4274 IV = buildDeclRefExpr(SemaRef, IVDecl, RealVType, InitLoc); 4275 Expr *RHS = 4276 (isOpenMPWorksharingDirective(DKind) || 4277 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 4278 ? LB.get() 4279 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 4280 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 4281 Init = SemaRef.ActOnFinishFullExpr(Init.get()); 4282 4283 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4284 Expr *CombRHS = 4285 (isOpenMPWorksharingDirective(DKind) || 4286 isOpenMPTaskLoopDirective(DKind) || 4287 isOpenMPDistributeDirective(DKind)) 4288 ? CombLB.get() 4289 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 4290 CombInit = 4291 SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), CombRHS); 4292 CombInit = SemaRef.ActOnFinishFullExpr(CombInit.get()); 4293 } 4294 } 4295 4296 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. 4297 SourceLocation CondLoc; 4298 ExprResult Cond = 4299 (isOpenMPWorksharingDirective(DKind) || 4300 isOpenMPTaskLoopDirective(DKind) || isOpenMPDistributeDirective(DKind)) 4301 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) 4302 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 4303 NumIterations.get()); 4304 ExprResult CombCond; 4305 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4306 CombCond = 4307 SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), CombUB.get()); 4308 } 4309 // Loop increment (IV = IV + 1) 4310 SourceLocation IncLoc; 4311 ExprResult Inc = 4312 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 4313 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 4314 if (!Inc.isUsable()) 4315 return 0; 4316 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 4317 Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); 4318 if (!Inc.isUsable()) 4319 return 0; 4320 4321 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 4322 // Used for directives with static scheduling. 4323 // In combined construct, add combined version that use CombLB and CombUB 4324 // base variables for the update 4325 ExprResult NextLB, NextUB, CombNextLB, CombNextUB; 4326 if (isOpenMPWorksharingDirective(DKind) || isOpenMPTaskLoopDirective(DKind) || 4327 isOpenMPDistributeDirective(DKind)) { 4328 // LB + ST 4329 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 4330 if (!NextLB.isUsable()) 4331 return 0; 4332 // LB = LB + ST 4333 NextLB = 4334 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 4335 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); 4336 if (!NextLB.isUsable()) 4337 return 0; 4338 // UB + ST 4339 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 4340 if (!NextUB.isUsable()) 4341 return 0; 4342 // UB = UB + ST 4343 NextUB = 4344 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 4345 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); 4346 if (!NextUB.isUsable()) 4347 return 0; 4348 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4349 CombNextLB = 4350 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombLB.get(), ST.get()); 4351 if (!NextLB.isUsable()) 4352 return 0; 4353 // LB = LB + ST 4354 CombNextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombLB.get(), 4355 CombNextLB.get()); 4356 CombNextLB = SemaRef.ActOnFinishFullExpr(CombNextLB.get()); 4357 if (!CombNextLB.isUsable()) 4358 return 0; 4359 // UB + ST 4360 CombNextUB = 4361 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, CombUB.get(), ST.get()); 4362 if (!CombNextUB.isUsable()) 4363 return 0; 4364 // UB = UB + ST 4365 CombNextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, CombUB.get(), 4366 CombNextUB.get()); 4367 CombNextUB = SemaRef.ActOnFinishFullExpr(CombNextUB.get()); 4368 if (!CombNextUB.isUsable()) 4369 return 0; 4370 } 4371 } 4372 4373 // Create increment expression for distribute loop when combined in a same 4374 // directive with for as IV = IV + ST; ensure upper bound expression based 4375 // on PrevUB instead of NumIterations - used to implement 'for' when found 4376 // in combination with 'distribute', like in 'distribute parallel for' 4377 SourceLocation DistIncLoc; 4378 ExprResult DistCond, DistInc, PrevEUB; 4379 if (isOpenMPLoopBoundSharingDirective(DKind)) { 4380 DistCond = SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()); 4381 assert(DistCond.isUsable() && "distribute cond expr was not built"); 4382 4383 DistInc = 4384 SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Add, IV.get(), ST.get()); 4385 assert(DistInc.isUsable() && "distribute inc expr was not built"); 4386 DistInc = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, IV.get(), 4387 DistInc.get()); 4388 DistInc = SemaRef.ActOnFinishFullExpr(DistInc.get()); 4389 assert(DistInc.isUsable() && "distribute inc expr was not built"); 4390 4391 // Build expression: UB = min(UB, prevUB) for #for in composite or combined 4392 // construct 4393 SourceLocation DistEUBLoc; 4394 ExprResult IsUBGreater = 4395 SemaRef.BuildBinOp(CurScope, DistEUBLoc, BO_GT, UB.get(), PrevUB.get()); 4396 ExprResult CondOp = SemaRef.ActOnConditionalOp( 4397 DistEUBLoc, DistEUBLoc, IsUBGreater.get(), PrevUB.get(), UB.get()); 4398 PrevEUB = SemaRef.BuildBinOp(CurScope, DistIncLoc, BO_Assign, UB.get(), 4399 CondOp.get()); 4400 PrevEUB = SemaRef.ActOnFinishFullExpr(PrevEUB.get()); 4401 } 4402 4403 // Build updates and final values of the loop counters. 4404 bool HasErrors = false; 4405 Built.Counters.resize(NestedLoopCount); 4406 Built.Inits.resize(NestedLoopCount); 4407 Built.Updates.resize(NestedLoopCount); 4408 Built.Finals.resize(NestedLoopCount); 4409 SmallVector<Expr *, 4> LoopMultipliers; 4410 { 4411 ExprResult Div; 4412 // Go from inner nested loop to outer. 4413 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 4414 LoopIterationSpace &IS = IterSpaces[Cnt]; 4415 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 4416 // Build: Iter = (IV / Div) % IS.NumIters 4417 // where Div is product of previous iterations' IS.NumIters. 4418 ExprResult Iter; 4419 if (Div.isUsable()) { 4420 Iter = 4421 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); 4422 } else { 4423 Iter = IV; 4424 assert((Cnt == (int)NestedLoopCount - 1) && 4425 "unusable div expected on first iteration only"); 4426 } 4427 4428 if (Cnt != 0 && Iter.isUsable()) 4429 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), 4430 IS.NumIterations); 4431 if (!Iter.isUsable()) { 4432 HasErrors = true; 4433 break; 4434 } 4435 4436 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 4437 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()); 4438 auto *CounterVar = buildDeclRefExpr(SemaRef, VD, IS.CounterVar->getType(), 4439 IS.CounterVar->getExprLoc(), 4440 /*RefersToCapture=*/true); 4441 ExprResult Init = BuildCounterInit(SemaRef, CurScope, UpdLoc, CounterVar, 4442 IS.CounterInit, Captures); 4443 if (!Init.isUsable()) { 4444 HasErrors = true; 4445 break; 4446 } 4447 ExprResult Update = BuildCounterUpdate( 4448 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, Iter, 4449 IS.CounterStep, IS.Subtract, &Captures); 4450 if (!Update.isUsable()) { 4451 HasErrors = true; 4452 break; 4453 } 4454 4455 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 4456 ExprResult Final = BuildCounterUpdate( 4457 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 4458 IS.NumIterations, IS.CounterStep, IS.Subtract, &Captures); 4459 if (!Final.isUsable()) { 4460 HasErrors = true; 4461 break; 4462 } 4463 4464 // Build Div for the next iteration: Div <- Div * IS.NumIters 4465 if (Cnt != 0) { 4466 if (Div.isUnset()) 4467 Div = IS.NumIterations; 4468 else 4469 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), 4470 IS.NumIterations); 4471 4472 // Add parentheses (for debugging purposes only). 4473 if (Div.isUsable()) 4474 Div = tryBuildCapture(SemaRef, Div.get(), Captures); 4475 if (!Div.isUsable()) { 4476 HasErrors = true; 4477 break; 4478 } 4479 LoopMultipliers.push_back(Div.get()); 4480 } 4481 if (!Update.isUsable() || !Final.isUsable()) { 4482 HasErrors = true; 4483 break; 4484 } 4485 // Save results 4486 Built.Counters[Cnt] = IS.CounterVar; 4487 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 4488 Built.Inits[Cnt] = Init.get(); 4489 Built.Updates[Cnt] = Update.get(); 4490 Built.Finals[Cnt] = Final.get(); 4491 } 4492 } 4493 4494 if (HasErrors) 4495 return 0; 4496 4497 // Save results 4498 Built.IterationVarRef = IV.get(); 4499 Built.LastIteration = LastIteration.get(); 4500 Built.NumIterations = NumIterations.get(); 4501 Built.CalcLastIteration = 4502 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); 4503 Built.PreCond = PreCond.get(); 4504 Built.PreInits = buildPreInits(C, Captures); 4505 Built.Cond = Cond.get(); 4506 Built.Init = Init.get(); 4507 Built.Inc = Inc.get(); 4508 Built.LB = LB.get(); 4509 Built.UB = UB.get(); 4510 Built.IL = IL.get(); 4511 Built.ST = ST.get(); 4512 Built.EUB = EUB.get(); 4513 Built.NLB = NextLB.get(); 4514 Built.NUB = NextUB.get(); 4515 Built.PrevLB = PrevLB.get(); 4516 Built.PrevUB = PrevUB.get(); 4517 Built.DistInc = DistInc.get(); 4518 Built.PrevEUB = PrevEUB.get(); 4519 Built.DistCombinedFields.LB = CombLB.get(); 4520 Built.DistCombinedFields.UB = CombUB.get(); 4521 Built.DistCombinedFields.EUB = CombEUB.get(); 4522 Built.DistCombinedFields.Init = CombInit.get(); 4523 Built.DistCombinedFields.Cond = CombCond.get(); 4524 Built.DistCombinedFields.NLB = CombNextLB.get(); 4525 Built.DistCombinedFields.NUB = CombNextUB.get(); 4526 4527 Expr *CounterVal = SemaRef.DefaultLvalueConversion(IV.get()).get(); 4528 // Fill data for doacross depend clauses. 4529 for (auto Pair : DSA.getDoacrossDependClauses()) { 4530 if (Pair.first->getDependencyKind() == OMPC_DEPEND_source) 4531 Pair.first->setCounterValue(CounterVal); 4532 else { 4533 if (NestedLoopCount != Pair.second.size() || 4534 NestedLoopCount != LoopMultipliers.size() + 1) { 4535 // Erroneous case - clause has some problems. 4536 Pair.first->setCounterValue(CounterVal); 4537 continue; 4538 } 4539 assert(Pair.first->getDependencyKind() == OMPC_DEPEND_sink); 4540 auto I = Pair.second.rbegin(); 4541 auto IS = IterSpaces.rbegin(); 4542 auto ILM = LoopMultipliers.rbegin(); 4543 Expr *UpCounterVal = CounterVal; 4544 Expr *Multiplier = nullptr; 4545 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 4546 if (I->first) { 4547 assert(IS->CounterStep); 4548 Expr *NormalizedOffset = 4549 SemaRef 4550 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Div, 4551 I->first, IS->CounterStep) 4552 .get(); 4553 if (Multiplier) { 4554 NormalizedOffset = 4555 SemaRef 4556 .BuildBinOp(CurScope, I->first->getExprLoc(), BO_Mul, 4557 NormalizedOffset, Multiplier) 4558 .get(); 4559 } 4560 assert(I->second == OO_Plus || I->second == OO_Minus); 4561 BinaryOperatorKind BOK = (I->second == OO_Plus) ? BO_Add : BO_Sub; 4562 UpCounterVal = SemaRef 4563 .BuildBinOp(CurScope, I->first->getExprLoc(), BOK, 4564 UpCounterVal, NormalizedOffset) 4565 .get(); 4566 } 4567 Multiplier = *ILM; 4568 ++I; 4569 ++IS; 4570 ++ILM; 4571 } 4572 Pair.first->setCounterValue(UpCounterVal); 4573 } 4574 } 4575 4576 return NestedLoopCount; 4577 } 4578 4579 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 4580 auto CollapseClauses = 4581 OMPExecutableDirective::getClausesOfKind<OMPCollapseClause>(Clauses); 4582 if (CollapseClauses.begin() != CollapseClauses.end()) 4583 return (*CollapseClauses.begin())->getNumForLoops(); 4584 return nullptr; 4585 } 4586 4587 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 4588 auto OrderedClauses = 4589 OMPExecutableDirective::getClausesOfKind<OMPOrderedClause>(Clauses); 4590 if (OrderedClauses.begin() != OrderedClauses.end()) 4591 return (*OrderedClauses.begin())->getNumForLoops(); 4592 return nullptr; 4593 } 4594 4595 static bool checkSimdlenSafelenSpecified(Sema &S, 4596 const ArrayRef<OMPClause *> Clauses) { 4597 OMPSafelenClause *Safelen = nullptr; 4598 OMPSimdlenClause *Simdlen = nullptr; 4599 4600 for (auto *Clause : Clauses) { 4601 if (Clause->getClauseKind() == OMPC_safelen) 4602 Safelen = cast<OMPSafelenClause>(Clause); 4603 else if (Clause->getClauseKind() == OMPC_simdlen) 4604 Simdlen = cast<OMPSimdlenClause>(Clause); 4605 if (Safelen && Simdlen) 4606 break; 4607 } 4608 4609 if (Simdlen && Safelen) { 4610 llvm::APSInt SimdlenRes, SafelenRes; 4611 auto SimdlenLength = Simdlen->getSimdlen(); 4612 auto SafelenLength = Safelen->getSafelen(); 4613 if (SimdlenLength->isValueDependent() || SimdlenLength->isTypeDependent() || 4614 SimdlenLength->isInstantiationDependent() || 4615 SimdlenLength->containsUnexpandedParameterPack()) 4616 return false; 4617 if (SafelenLength->isValueDependent() || SafelenLength->isTypeDependent() || 4618 SafelenLength->isInstantiationDependent() || 4619 SafelenLength->containsUnexpandedParameterPack()) 4620 return false; 4621 SimdlenLength->EvaluateAsInt(SimdlenRes, S.Context); 4622 SafelenLength->EvaluateAsInt(SafelenRes, S.Context); 4623 // OpenMP 4.5 [2.8.1, simd Construct, Restrictions] 4624 // If both simdlen and safelen clauses are specified, the value of the 4625 // simdlen parameter must be less than or equal to the value of the safelen 4626 // parameter. 4627 if (SimdlenRes > SafelenRes) { 4628 S.Diag(SimdlenLength->getExprLoc(), 4629 diag::err_omp_wrong_simdlen_safelen_values) 4630 << SimdlenLength->getSourceRange() << SafelenLength->getSourceRange(); 4631 return true; 4632 } 4633 } 4634 return false; 4635 } 4636 4637 StmtResult Sema::ActOnOpenMPSimdDirective( 4638 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4639 SourceLocation EndLoc, 4640 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4641 if (!AStmt) 4642 return StmtError(); 4643 4644 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4645 OMPLoopDirective::HelperExprs B; 4646 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 4647 // define the nested loops number. 4648 unsigned NestedLoopCount = CheckOpenMPLoop( 4649 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 4650 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 4651 if (NestedLoopCount == 0) 4652 return StmtError(); 4653 4654 assert((CurContext->isDependentContext() || B.builtAll()) && 4655 "omp simd loop exprs were not built"); 4656 4657 if (!CurContext->isDependentContext()) { 4658 // Finalize the clauses that need pre-built expressions for CodeGen. 4659 for (auto C : Clauses) { 4660 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 4661 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 4662 B.NumIterations, *this, CurScope, 4663 DSAStack)) 4664 return StmtError(); 4665 } 4666 } 4667 4668 if (checkSimdlenSafelenSpecified(*this, Clauses)) 4669 return StmtError(); 4670 4671 getCurFunction()->setHasBranchProtectedScope(); 4672 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 4673 Clauses, AStmt, B); 4674 } 4675 4676 StmtResult Sema::ActOnOpenMPForDirective( 4677 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4678 SourceLocation EndLoc, 4679 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4680 if (!AStmt) 4681 return StmtError(); 4682 4683 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4684 OMPLoopDirective::HelperExprs B; 4685 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 4686 // define the nested loops number. 4687 unsigned NestedLoopCount = CheckOpenMPLoop( 4688 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 4689 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 4690 if (NestedLoopCount == 0) 4691 return StmtError(); 4692 4693 assert((CurContext->isDependentContext() || B.builtAll()) && 4694 "omp for loop exprs were not built"); 4695 4696 if (!CurContext->isDependentContext()) { 4697 // Finalize the clauses that need pre-built expressions for CodeGen. 4698 for (auto C : Clauses) { 4699 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 4700 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 4701 B.NumIterations, *this, CurScope, 4702 DSAStack)) 4703 return StmtError(); 4704 } 4705 } 4706 4707 getCurFunction()->setHasBranchProtectedScope(); 4708 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 4709 Clauses, AStmt, B, DSAStack->isCancelRegion()); 4710 } 4711 4712 StmtResult Sema::ActOnOpenMPForSimdDirective( 4713 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4714 SourceLocation EndLoc, 4715 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4716 if (!AStmt) 4717 return StmtError(); 4718 4719 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4720 OMPLoopDirective::HelperExprs B; 4721 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 4722 // define the nested loops number. 4723 unsigned NestedLoopCount = 4724 CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 4725 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 4726 VarsWithImplicitDSA, B); 4727 if (NestedLoopCount == 0) 4728 return StmtError(); 4729 4730 assert((CurContext->isDependentContext() || B.builtAll()) && 4731 "omp for simd loop exprs were not built"); 4732 4733 if (!CurContext->isDependentContext()) { 4734 // Finalize the clauses that need pre-built expressions for CodeGen. 4735 for (auto C : Clauses) { 4736 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 4737 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 4738 B.NumIterations, *this, CurScope, 4739 DSAStack)) 4740 return StmtError(); 4741 } 4742 } 4743 4744 if (checkSimdlenSafelenSpecified(*this, Clauses)) 4745 return StmtError(); 4746 4747 getCurFunction()->setHasBranchProtectedScope(); 4748 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 4749 Clauses, AStmt, B); 4750 } 4751 4752 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 4753 Stmt *AStmt, 4754 SourceLocation StartLoc, 4755 SourceLocation EndLoc) { 4756 if (!AStmt) 4757 return StmtError(); 4758 4759 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4760 auto BaseStmt = AStmt; 4761 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 4762 BaseStmt = CS->getCapturedStmt(); 4763 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 4764 auto S = C->children(); 4765 if (S.begin() == S.end()) 4766 return StmtError(); 4767 // All associated statements must be '#pragma omp section' except for 4768 // the first one. 4769 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 4770 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 4771 if (SectionStmt) 4772 Diag(SectionStmt->getLocStart(), 4773 diag::err_omp_sections_substmt_not_section); 4774 return StmtError(); 4775 } 4776 cast<OMPSectionDirective>(SectionStmt) 4777 ->setHasCancel(DSAStack->isCancelRegion()); 4778 } 4779 } else { 4780 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt); 4781 return StmtError(); 4782 } 4783 4784 getCurFunction()->setHasBranchProtectedScope(); 4785 4786 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4787 DSAStack->isCancelRegion()); 4788 } 4789 4790 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 4791 SourceLocation StartLoc, 4792 SourceLocation EndLoc) { 4793 if (!AStmt) 4794 return StmtError(); 4795 4796 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4797 4798 getCurFunction()->setHasBranchProtectedScope(); 4799 DSAStack->setParentCancelRegion(DSAStack->isCancelRegion()); 4800 4801 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt, 4802 DSAStack->isCancelRegion()); 4803 } 4804 4805 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 4806 Stmt *AStmt, 4807 SourceLocation StartLoc, 4808 SourceLocation EndLoc) { 4809 if (!AStmt) 4810 return StmtError(); 4811 4812 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4813 4814 getCurFunction()->setHasBranchProtectedScope(); 4815 4816 // OpenMP [2.7.3, single Construct, Restrictions] 4817 // The copyprivate clause must not be used with the nowait clause. 4818 OMPClause *Nowait = nullptr; 4819 OMPClause *Copyprivate = nullptr; 4820 for (auto *Clause : Clauses) { 4821 if (Clause->getClauseKind() == OMPC_nowait) 4822 Nowait = Clause; 4823 else if (Clause->getClauseKind() == OMPC_copyprivate) 4824 Copyprivate = Clause; 4825 if (Copyprivate && Nowait) { 4826 Diag(Copyprivate->getLocStart(), 4827 diag::err_omp_single_copyprivate_with_nowait); 4828 Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here); 4829 return StmtError(); 4830 } 4831 } 4832 4833 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 4834 } 4835 4836 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 4837 SourceLocation StartLoc, 4838 SourceLocation EndLoc) { 4839 if (!AStmt) 4840 return StmtError(); 4841 4842 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4843 4844 getCurFunction()->setHasBranchProtectedScope(); 4845 4846 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 4847 } 4848 4849 StmtResult Sema::ActOnOpenMPCriticalDirective( 4850 const DeclarationNameInfo &DirName, ArrayRef<OMPClause *> Clauses, 4851 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 4852 if (!AStmt) 4853 return StmtError(); 4854 4855 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4856 4857 bool ErrorFound = false; 4858 llvm::APSInt Hint; 4859 SourceLocation HintLoc; 4860 bool DependentHint = false; 4861 for (auto *C : Clauses) { 4862 if (C->getClauseKind() == OMPC_hint) { 4863 if (!DirName.getName()) { 4864 Diag(C->getLocStart(), diag::err_omp_hint_clause_no_name); 4865 ErrorFound = true; 4866 } 4867 Expr *E = cast<OMPHintClause>(C)->getHint(); 4868 if (E->isTypeDependent() || E->isValueDependent() || 4869 E->isInstantiationDependent()) 4870 DependentHint = true; 4871 else { 4872 Hint = E->EvaluateKnownConstInt(Context); 4873 HintLoc = C->getLocStart(); 4874 } 4875 } 4876 } 4877 if (ErrorFound) 4878 return StmtError(); 4879 auto Pair = DSAStack->getCriticalWithHint(DirName); 4880 if (Pair.first && DirName.getName() && !DependentHint) { 4881 if (llvm::APSInt::compareValues(Hint, Pair.second) != 0) { 4882 Diag(StartLoc, diag::err_omp_critical_with_hint); 4883 if (HintLoc.isValid()) { 4884 Diag(HintLoc, diag::note_omp_critical_hint_here) 4885 << 0 << Hint.toString(/*Radix=*/10, /*Signed=*/false); 4886 } else 4887 Diag(StartLoc, diag::note_omp_critical_no_hint) << 0; 4888 if (auto *C = Pair.first->getSingleClause<OMPHintClause>()) { 4889 Diag(C->getLocStart(), diag::note_omp_critical_hint_here) 4890 << 1 4891 << C->getHint()->EvaluateKnownConstInt(Context).toString( 4892 /*Radix=*/10, /*Signed=*/false); 4893 } else 4894 Diag(Pair.first->getLocStart(), diag::note_omp_critical_no_hint) << 1; 4895 } 4896 } 4897 4898 getCurFunction()->setHasBranchProtectedScope(); 4899 4900 auto *Dir = OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 4901 Clauses, AStmt); 4902 if (!Pair.first && DirName.getName() && !DependentHint) 4903 DSAStack->addCriticalWithHint(Dir, Hint); 4904 return Dir; 4905 } 4906 4907 StmtResult Sema::ActOnOpenMPParallelForDirective( 4908 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4909 SourceLocation EndLoc, 4910 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4911 if (!AStmt) 4912 return StmtError(); 4913 4914 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 4915 // 1.2.2 OpenMP Language Terminology 4916 // Structured block - An executable statement with a single entry at the 4917 // top and a single exit at the bottom. 4918 // The point of exit cannot be a branch out of the structured block. 4919 // longjmp() and throw() must not violate the entry/exit criteria. 4920 CS->getCapturedDecl()->setNothrow(); 4921 4922 OMPLoopDirective::HelperExprs B; 4923 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 4924 // define the nested loops number. 4925 unsigned NestedLoopCount = 4926 CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 4927 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 4928 VarsWithImplicitDSA, B); 4929 if (NestedLoopCount == 0) 4930 return StmtError(); 4931 4932 assert((CurContext->isDependentContext() || B.builtAll()) && 4933 "omp parallel for loop exprs were not built"); 4934 4935 if (!CurContext->isDependentContext()) { 4936 // Finalize the clauses that need pre-built expressions for CodeGen. 4937 for (auto C : Clauses) { 4938 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 4939 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 4940 B.NumIterations, *this, CurScope, 4941 DSAStack)) 4942 return StmtError(); 4943 } 4944 } 4945 4946 getCurFunction()->setHasBranchProtectedScope(); 4947 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 4948 NestedLoopCount, Clauses, AStmt, B, 4949 DSAStack->isCancelRegion()); 4950 } 4951 4952 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 4953 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 4954 SourceLocation EndLoc, 4955 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 4956 if (!AStmt) 4957 return StmtError(); 4958 4959 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 4960 // 1.2.2 OpenMP Language Terminology 4961 // Structured block - An executable statement with a single entry at the 4962 // top and a single exit at the bottom. 4963 // The point of exit cannot be a branch out of the structured block. 4964 // longjmp() and throw() must not violate the entry/exit criteria. 4965 CS->getCapturedDecl()->setNothrow(); 4966 4967 OMPLoopDirective::HelperExprs B; 4968 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 4969 // define the nested loops number. 4970 unsigned NestedLoopCount = 4971 CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 4972 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 4973 VarsWithImplicitDSA, B); 4974 if (NestedLoopCount == 0) 4975 return StmtError(); 4976 4977 if (!CurContext->isDependentContext()) { 4978 // Finalize the clauses that need pre-built expressions for CodeGen. 4979 for (auto C : Clauses) { 4980 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 4981 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 4982 B.NumIterations, *this, CurScope, 4983 DSAStack)) 4984 return StmtError(); 4985 } 4986 } 4987 4988 if (checkSimdlenSafelenSpecified(*this, Clauses)) 4989 return StmtError(); 4990 4991 getCurFunction()->setHasBranchProtectedScope(); 4992 return OMPParallelForSimdDirective::Create( 4993 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 4994 } 4995 4996 StmtResult 4997 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 4998 Stmt *AStmt, SourceLocation StartLoc, 4999 SourceLocation EndLoc) { 5000 if (!AStmt) 5001 return StmtError(); 5002 5003 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5004 auto BaseStmt = AStmt; 5005 while (auto *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 5006 BaseStmt = CS->getCapturedStmt(); 5007 if (auto *C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 5008 auto S = C->children(); 5009 if (S.begin() == S.end()) 5010 return StmtError(); 5011 // All associated statements must be '#pragma omp section' except for 5012 // the first one. 5013 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 5014 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 5015 if (SectionStmt) 5016 Diag(SectionStmt->getLocStart(), 5017 diag::err_omp_parallel_sections_substmt_not_section); 5018 return StmtError(); 5019 } 5020 cast<OMPSectionDirective>(SectionStmt) 5021 ->setHasCancel(DSAStack->isCancelRegion()); 5022 } 5023 } else { 5024 Diag(AStmt->getLocStart(), 5025 diag::err_omp_parallel_sections_not_compound_stmt); 5026 return StmtError(); 5027 } 5028 5029 getCurFunction()->setHasBranchProtectedScope(); 5030 5031 return OMPParallelSectionsDirective::Create( 5032 Context, StartLoc, EndLoc, Clauses, AStmt, DSAStack->isCancelRegion()); 5033 } 5034 5035 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 5036 Stmt *AStmt, SourceLocation StartLoc, 5037 SourceLocation EndLoc) { 5038 if (!AStmt) 5039 return StmtError(); 5040 5041 auto *CS = cast<CapturedStmt>(AStmt); 5042 // 1.2.2 OpenMP Language Terminology 5043 // Structured block - An executable statement with a single entry at the 5044 // top and a single exit at the bottom. 5045 // The point of exit cannot be a branch out of the structured block. 5046 // longjmp() and throw() must not violate the entry/exit criteria. 5047 CS->getCapturedDecl()->setNothrow(); 5048 5049 getCurFunction()->setHasBranchProtectedScope(); 5050 5051 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5052 DSAStack->isCancelRegion()); 5053 } 5054 5055 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 5056 SourceLocation EndLoc) { 5057 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 5058 } 5059 5060 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 5061 SourceLocation EndLoc) { 5062 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 5063 } 5064 5065 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 5066 SourceLocation EndLoc) { 5067 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 5068 } 5069 5070 StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt, 5071 SourceLocation StartLoc, 5072 SourceLocation EndLoc) { 5073 if (!AStmt) 5074 return StmtError(); 5075 5076 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5077 5078 getCurFunction()->setHasBranchProtectedScope(); 5079 5080 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, AStmt); 5081 } 5082 5083 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 5084 SourceLocation StartLoc, 5085 SourceLocation EndLoc) { 5086 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 5087 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 5088 } 5089 5090 StmtResult Sema::ActOnOpenMPOrderedDirective(ArrayRef<OMPClause *> Clauses, 5091 Stmt *AStmt, 5092 SourceLocation StartLoc, 5093 SourceLocation EndLoc) { 5094 OMPClause *DependFound = nullptr; 5095 OMPClause *DependSourceClause = nullptr; 5096 OMPClause *DependSinkClause = nullptr; 5097 bool ErrorFound = false; 5098 OMPThreadsClause *TC = nullptr; 5099 OMPSIMDClause *SC = nullptr; 5100 for (auto *C : Clauses) { 5101 if (auto *DC = dyn_cast<OMPDependClause>(C)) { 5102 DependFound = C; 5103 if (DC->getDependencyKind() == OMPC_DEPEND_source) { 5104 if (DependSourceClause) { 5105 Diag(C->getLocStart(), diag::err_omp_more_one_clause) 5106 << getOpenMPDirectiveName(OMPD_ordered) 5107 << getOpenMPClauseName(OMPC_depend) << 2; 5108 ErrorFound = true; 5109 } else 5110 DependSourceClause = C; 5111 if (DependSinkClause) { 5112 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5113 << 0; 5114 ErrorFound = true; 5115 } 5116 } else if (DC->getDependencyKind() == OMPC_DEPEND_sink) { 5117 if (DependSourceClause) { 5118 Diag(C->getLocStart(), diag::err_omp_depend_sink_source_not_allowed) 5119 << 1; 5120 ErrorFound = true; 5121 } 5122 DependSinkClause = C; 5123 } 5124 } else if (C->getClauseKind() == OMPC_threads) 5125 TC = cast<OMPThreadsClause>(C); 5126 else if (C->getClauseKind() == OMPC_simd) 5127 SC = cast<OMPSIMDClause>(C); 5128 } 5129 if (!ErrorFound && !SC && 5130 isOpenMPSimdDirective(DSAStack->getParentDirective())) { 5131 // OpenMP [2.8.1,simd Construct, Restrictions] 5132 // An ordered construct with the simd clause is the only OpenMP construct 5133 // that can appear in the simd region. 5134 Diag(StartLoc, diag::err_omp_prohibited_region_simd); 5135 ErrorFound = true; 5136 } else if (DependFound && (TC || SC)) { 5137 Diag(DependFound->getLocStart(), diag::err_omp_depend_clause_thread_simd) 5138 << getOpenMPClauseName(TC ? TC->getClauseKind() : SC->getClauseKind()); 5139 ErrorFound = true; 5140 } else if (DependFound && !DSAStack->getParentOrderedRegionParam()) { 5141 Diag(DependFound->getLocStart(), 5142 diag::err_omp_ordered_directive_without_param); 5143 ErrorFound = true; 5144 } else if (TC || Clauses.empty()) { 5145 if (auto *Param = DSAStack->getParentOrderedRegionParam()) { 5146 SourceLocation ErrLoc = TC ? TC->getLocStart() : StartLoc; 5147 Diag(ErrLoc, diag::err_omp_ordered_directive_with_param) 5148 << (TC != nullptr); 5149 Diag(Param->getLocStart(), diag::note_omp_ordered_param); 5150 ErrorFound = true; 5151 } 5152 } 5153 if ((!AStmt && !DependFound) || ErrorFound) 5154 return StmtError(); 5155 5156 if (AStmt) { 5157 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5158 5159 getCurFunction()->setHasBranchProtectedScope(); 5160 } 5161 5162 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5163 } 5164 5165 namespace { 5166 /// \brief Helper class for checking expression in 'omp atomic [update]' 5167 /// construct. 5168 class OpenMPAtomicUpdateChecker { 5169 /// \brief Error results for atomic update expressions. 5170 enum ExprAnalysisErrorCode { 5171 /// \brief A statement is not an expression statement. 5172 NotAnExpression, 5173 /// \brief Expression is not builtin binary or unary operation. 5174 NotABinaryOrUnaryExpression, 5175 /// \brief Unary operation is not post-/pre- increment/decrement operation. 5176 NotAnUnaryIncDecExpression, 5177 /// \brief An expression is not of scalar type. 5178 NotAScalarType, 5179 /// \brief A binary operation is not an assignment operation. 5180 NotAnAssignmentOp, 5181 /// \brief RHS part of the binary operation is not a binary expression. 5182 NotABinaryExpression, 5183 /// \brief RHS part is not additive/multiplicative/shift/biwise binary 5184 /// expression. 5185 NotABinaryOperator, 5186 /// \brief RHS binary operation does not have reference to the updated LHS 5187 /// part. 5188 NotAnUpdateExpression, 5189 /// \brief No errors is found. 5190 NoError 5191 }; 5192 /// \brief Reference to Sema. 5193 Sema &SemaRef; 5194 /// \brief A location for note diagnostics (when error is found). 5195 SourceLocation NoteLoc; 5196 /// \brief 'x' lvalue part of the source atomic expression. 5197 Expr *X; 5198 /// \brief 'expr' rvalue part of the source atomic expression. 5199 Expr *E; 5200 /// \brief Helper expression of the form 5201 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5202 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5203 Expr *UpdateExpr; 5204 /// \brief Is 'x' a LHS in a RHS part of full update expression. It is 5205 /// important for non-associative operations. 5206 bool IsXLHSInRHSPart; 5207 BinaryOperatorKind Op; 5208 SourceLocation OpLoc; 5209 /// \brief true if the source expression is a postfix unary operation, false 5210 /// if it is a prefix unary operation. 5211 bool IsPostfixUpdate; 5212 5213 public: 5214 OpenMPAtomicUpdateChecker(Sema &SemaRef) 5215 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 5216 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 5217 /// \brief Check specified statement that it is suitable for 'atomic update' 5218 /// constructs and extract 'x', 'expr' and Operation from the original 5219 /// expression. If DiagId and NoteId == 0, then only check is performed 5220 /// without error notification. 5221 /// \param DiagId Diagnostic which should be emitted if error is found. 5222 /// \param NoteId Diagnostic note for the main error message. 5223 /// \return true if statement is not an update expression, false otherwise. 5224 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 5225 /// \brief Return the 'x' lvalue part of the source atomic expression. 5226 Expr *getX() const { return X; } 5227 /// \brief Return the 'expr' rvalue part of the source atomic expression. 5228 Expr *getExpr() const { return E; } 5229 /// \brief Return the update expression used in calculation of the updated 5230 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 5231 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 5232 Expr *getUpdateExpr() const { return UpdateExpr; } 5233 /// \brief Return true if 'x' is LHS in RHS part of full update expression, 5234 /// false otherwise. 5235 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 5236 5237 /// \brief true if the source expression is a postfix unary operation, false 5238 /// if it is a prefix unary operation. 5239 bool isPostfixUpdate() const { return IsPostfixUpdate; } 5240 5241 private: 5242 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 5243 unsigned NoteId = 0); 5244 }; 5245 } // namespace 5246 5247 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 5248 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 5249 ExprAnalysisErrorCode ErrorFound = NoError; 5250 SourceLocation ErrorLoc, NoteLoc; 5251 SourceRange ErrorRange, NoteRange; 5252 // Allowed constructs are: 5253 // x = x binop expr; 5254 // x = expr binop x; 5255 if (AtomicBinOp->getOpcode() == BO_Assign) { 5256 X = AtomicBinOp->getLHS(); 5257 if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 5258 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 5259 if (AtomicInnerBinOp->isMultiplicativeOp() || 5260 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 5261 AtomicInnerBinOp->isBitwiseOp()) { 5262 Op = AtomicInnerBinOp->getOpcode(); 5263 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 5264 auto *LHS = AtomicInnerBinOp->getLHS(); 5265 auto *RHS = AtomicInnerBinOp->getRHS(); 5266 llvm::FoldingSetNodeID XId, LHSId, RHSId; 5267 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 5268 /*Canonical=*/true); 5269 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 5270 /*Canonical=*/true); 5271 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 5272 /*Canonical=*/true); 5273 if (XId == LHSId) { 5274 E = RHS; 5275 IsXLHSInRHSPart = true; 5276 } else if (XId == RHSId) { 5277 E = LHS; 5278 IsXLHSInRHSPart = false; 5279 } else { 5280 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5281 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5282 NoteLoc = X->getExprLoc(); 5283 NoteRange = X->getSourceRange(); 5284 ErrorFound = NotAnUpdateExpression; 5285 } 5286 } else { 5287 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 5288 ErrorRange = AtomicInnerBinOp->getSourceRange(); 5289 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 5290 NoteRange = SourceRange(NoteLoc, NoteLoc); 5291 ErrorFound = NotABinaryOperator; 5292 } 5293 } else { 5294 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 5295 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 5296 ErrorFound = NotABinaryExpression; 5297 } 5298 } else { 5299 ErrorLoc = AtomicBinOp->getExprLoc(); 5300 ErrorRange = AtomicBinOp->getSourceRange(); 5301 NoteLoc = AtomicBinOp->getOperatorLoc(); 5302 NoteRange = SourceRange(NoteLoc, NoteLoc); 5303 ErrorFound = NotAnAssignmentOp; 5304 } 5305 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5306 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5307 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5308 return true; 5309 } else if (SemaRef.CurContext->isDependentContext()) 5310 E = X = UpdateExpr = nullptr; 5311 return ErrorFound != NoError; 5312 } 5313 5314 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 5315 unsigned NoteId) { 5316 ExprAnalysisErrorCode ErrorFound = NoError; 5317 SourceLocation ErrorLoc, NoteLoc; 5318 SourceRange ErrorRange, NoteRange; 5319 // Allowed constructs are: 5320 // x++; 5321 // x--; 5322 // ++x; 5323 // --x; 5324 // x binop= expr; 5325 // x = x binop expr; 5326 // x = expr binop x; 5327 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 5328 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 5329 if (AtomicBody->getType()->isScalarType() || 5330 AtomicBody->isInstantiationDependent()) { 5331 if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 5332 AtomicBody->IgnoreParenImpCasts())) { 5333 // Check for Compound Assignment Operation 5334 Op = BinaryOperator::getOpForCompoundAssignment( 5335 AtomicCompAssignOp->getOpcode()); 5336 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 5337 E = AtomicCompAssignOp->getRHS(); 5338 X = AtomicCompAssignOp->getLHS()->IgnoreParens(); 5339 IsXLHSInRHSPart = true; 5340 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 5341 AtomicBody->IgnoreParenImpCasts())) { 5342 // Check for Binary Operation 5343 if (checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 5344 return true; 5345 } else if (auto *AtomicUnaryOp = dyn_cast<UnaryOperator>( 5346 AtomicBody->IgnoreParenImpCasts())) { 5347 // Check for Unary Operation 5348 if (AtomicUnaryOp->isIncrementDecrementOp()) { 5349 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 5350 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 5351 OpLoc = AtomicUnaryOp->getOperatorLoc(); 5352 X = AtomicUnaryOp->getSubExpr()->IgnoreParens(); 5353 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 5354 IsXLHSInRHSPart = true; 5355 } else { 5356 ErrorFound = NotAnUnaryIncDecExpression; 5357 ErrorLoc = AtomicUnaryOp->getExprLoc(); 5358 ErrorRange = AtomicUnaryOp->getSourceRange(); 5359 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 5360 NoteRange = SourceRange(NoteLoc, NoteLoc); 5361 } 5362 } else if (!AtomicBody->isInstantiationDependent()) { 5363 ErrorFound = NotABinaryOrUnaryExpression; 5364 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 5365 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 5366 } 5367 } else { 5368 ErrorFound = NotAScalarType; 5369 NoteLoc = ErrorLoc = AtomicBody->getLocStart(); 5370 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5371 } 5372 } else { 5373 ErrorFound = NotAnExpression; 5374 NoteLoc = ErrorLoc = S->getLocStart(); 5375 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5376 } 5377 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 5378 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 5379 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 5380 return true; 5381 } else if (SemaRef.CurContext->isDependentContext()) 5382 E = X = UpdateExpr = nullptr; 5383 if (ErrorFound == NoError && E && X) { 5384 // Build an update expression of form 'OpaqueValueExpr(x) binop 5385 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 5386 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 5387 auto *OVEX = new (SemaRef.getASTContext()) 5388 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 5389 auto *OVEExpr = new (SemaRef.getASTContext()) 5390 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 5391 auto Update = 5392 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 5393 IsXLHSInRHSPart ? OVEExpr : OVEX); 5394 if (Update.isInvalid()) 5395 return true; 5396 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 5397 Sema::AA_Casting); 5398 if (Update.isInvalid()) 5399 return true; 5400 UpdateExpr = Update.get(); 5401 } 5402 return ErrorFound != NoError; 5403 } 5404 5405 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 5406 Stmt *AStmt, 5407 SourceLocation StartLoc, 5408 SourceLocation EndLoc) { 5409 if (!AStmt) 5410 return StmtError(); 5411 5412 auto *CS = cast<CapturedStmt>(AStmt); 5413 // 1.2.2 OpenMP Language Terminology 5414 // Structured block - An executable statement with a single entry at the 5415 // top and a single exit at the bottom. 5416 // The point of exit cannot be a branch out of the structured block. 5417 // longjmp() and throw() must not violate the entry/exit criteria. 5418 OpenMPClauseKind AtomicKind = OMPC_unknown; 5419 SourceLocation AtomicKindLoc; 5420 for (auto *C : Clauses) { 5421 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 5422 C->getClauseKind() == OMPC_update || 5423 C->getClauseKind() == OMPC_capture) { 5424 if (AtomicKind != OMPC_unknown) { 5425 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) 5426 << SourceRange(C->getLocStart(), C->getLocEnd()); 5427 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 5428 << getOpenMPClauseName(AtomicKind); 5429 } else { 5430 AtomicKind = C->getClauseKind(); 5431 AtomicKindLoc = C->getLocStart(); 5432 } 5433 } 5434 } 5435 5436 auto Body = CS->getCapturedStmt(); 5437 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 5438 Body = EWC->getSubExpr(); 5439 5440 Expr *X = nullptr; 5441 Expr *V = nullptr; 5442 Expr *E = nullptr; 5443 Expr *UE = nullptr; 5444 bool IsXLHSInRHSPart = false; 5445 bool IsPostfixUpdate = false; 5446 // OpenMP [2.12.6, atomic Construct] 5447 // In the next expressions: 5448 // * x and v (as applicable) are both l-value expressions with scalar type. 5449 // * During the execution of an atomic region, multiple syntactic 5450 // occurrences of x must designate the same storage location. 5451 // * Neither of v and expr (as applicable) may access the storage location 5452 // designated by x. 5453 // * Neither of x and expr (as applicable) may access the storage location 5454 // designated by v. 5455 // * expr is an expression with scalar type. 5456 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 5457 // * binop, binop=, ++, and -- are not overloaded operators. 5458 // * The expression x binop expr must be numerically equivalent to x binop 5459 // (expr). This requirement is satisfied if the operators in expr have 5460 // precedence greater than binop, or by using parentheses around expr or 5461 // subexpressions of expr. 5462 // * The expression expr binop x must be numerically equivalent to (expr) 5463 // binop x. This requirement is satisfied if the operators in expr have 5464 // precedence equal to or greater than binop, or by using parentheses around 5465 // expr or subexpressions of expr. 5466 // * For forms that allow multiple occurrences of x, the number of times 5467 // that x is evaluated is unspecified. 5468 if (AtomicKind == OMPC_read) { 5469 enum { 5470 NotAnExpression, 5471 NotAnAssignmentOp, 5472 NotAScalarType, 5473 NotAnLValue, 5474 NoError 5475 } ErrorFound = NoError; 5476 SourceLocation ErrorLoc, NoteLoc; 5477 SourceRange ErrorRange, NoteRange; 5478 // If clause is read: 5479 // v = x; 5480 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 5481 auto *AtomicBinOp = 5482 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5483 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5484 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 5485 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 5486 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 5487 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 5488 if (!X->isLValue() || !V->isLValue()) { 5489 auto NotLValueExpr = X->isLValue() ? V : X; 5490 ErrorFound = NotAnLValue; 5491 ErrorLoc = AtomicBinOp->getExprLoc(); 5492 ErrorRange = AtomicBinOp->getSourceRange(); 5493 NoteLoc = NotLValueExpr->getExprLoc(); 5494 NoteRange = NotLValueExpr->getSourceRange(); 5495 } 5496 } else if (!X->isInstantiationDependent() || 5497 !V->isInstantiationDependent()) { 5498 auto NotScalarExpr = 5499 (X->isInstantiationDependent() || X->getType()->isScalarType()) 5500 ? V 5501 : X; 5502 ErrorFound = NotAScalarType; 5503 ErrorLoc = AtomicBinOp->getExprLoc(); 5504 ErrorRange = AtomicBinOp->getSourceRange(); 5505 NoteLoc = NotScalarExpr->getExprLoc(); 5506 NoteRange = NotScalarExpr->getSourceRange(); 5507 } 5508 } else if (!AtomicBody->isInstantiationDependent()) { 5509 ErrorFound = NotAnAssignmentOp; 5510 ErrorLoc = AtomicBody->getExprLoc(); 5511 ErrorRange = AtomicBody->getSourceRange(); 5512 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5513 : AtomicBody->getExprLoc(); 5514 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5515 : AtomicBody->getSourceRange(); 5516 } 5517 } else { 5518 ErrorFound = NotAnExpression; 5519 NoteLoc = ErrorLoc = Body->getLocStart(); 5520 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5521 } 5522 if (ErrorFound != NoError) { 5523 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 5524 << ErrorRange; 5525 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 5526 << NoteRange; 5527 return StmtError(); 5528 } else if (CurContext->isDependentContext()) 5529 V = X = nullptr; 5530 } else if (AtomicKind == OMPC_write) { 5531 enum { 5532 NotAnExpression, 5533 NotAnAssignmentOp, 5534 NotAScalarType, 5535 NotAnLValue, 5536 NoError 5537 } ErrorFound = NoError; 5538 SourceLocation ErrorLoc, NoteLoc; 5539 SourceRange ErrorRange, NoteRange; 5540 // If clause is write: 5541 // x = expr; 5542 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 5543 auto *AtomicBinOp = 5544 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5545 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5546 X = AtomicBinOp->getLHS(); 5547 E = AtomicBinOp->getRHS(); 5548 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 5549 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 5550 if (!X->isLValue()) { 5551 ErrorFound = NotAnLValue; 5552 ErrorLoc = AtomicBinOp->getExprLoc(); 5553 ErrorRange = AtomicBinOp->getSourceRange(); 5554 NoteLoc = X->getExprLoc(); 5555 NoteRange = X->getSourceRange(); 5556 } 5557 } else if (!X->isInstantiationDependent() || 5558 !E->isInstantiationDependent()) { 5559 auto NotScalarExpr = 5560 (X->isInstantiationDependent() || X->getType()->isScalarType()) 5561 ? E 5562 : X; 5563 ErrorFound = NotAScalarType; 5564 ErrorLoc = AtomicBinOp->getExprLoc(); 5565 ErrorRange = AtomicBinOp->getSourceRange(); 5566 NoteLoc = NotScalarExpr->getExprLoc(); 5567 NoteRange = NotScalarExpr->getSourceRange(); 5568 } 5569 } else if (!AtomicBody->isInstantiationDependent()) { 5570 ErrorFound = NotAnAssignmentOp; 5571 ErrorLoc = AtomicBody->getExprLoc(); 5572 ErrorRange = AtomicBody->getSourceRange(); 5573 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5574 : AtomicBody->getExprLoc(); 5575 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5576 : AtomicBody->getSourceRange(); 5577 } 5578 } else { 5579 ErrorFound = NotAnExpression; 5580 NoteLoc = ErrorLoc = Body->getLocStart(); 5581 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 5582 } 5583 if (ErrorFound != NoError) { 5584 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 5585 << ErrorRange; 5586 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 5587 << NoteRange; 5588 return StmtError(); 5589 } else if (CurContext->isDependentContext()) 5590 E = X = nullptr; 5591 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 5592 // If clause is update: 5593 // x++; 5594 // x--; 5595 // ++x; 5596 // --x; 5597 // x binop= expr; 5598 // x = x binop expr; 5599 // x = expr binop x; 5600 OpenMPAtomicUpdateChecker Checker(*this); 5601 if (Checker.checkStatement( 5602 Body, (AtomicKind == OMPC_update) 5603 ? diag::err_omp_atomic_update_not_expression_statement 5604 : diag::err_omp_atomic_not_expression_statement, 5605 diag::note_omp_atomic_update)) 5606 return StmtError(); 5607 if (!CurContext->isDependentContext()) { 5608 E = Checker.getExpr(); 5609 X = Checker.getX(); 5610 UE = Checker.getUpdateExpr(); 5611 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5612 } 5613 } else if (AtomicKind == OMPC_capture) { 5614 enum { 5615 NotAnAssignmentOp, 5616 NotACompoundStatement, 5617 NotTwoSubstatements, 5618 NotASpecificExpression, 5619 NoError 5620 } ErrorFound = NoError; 5621 SourceLocation ErrorLoc, NoteLoc; 5622 SourceRange ErrorRange, NoteRange; 5623 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 5624 // If clause is a capture: 5625 // v = x++; 5626 // v = x--; 5627 // v = ++x; 5628 // v = --x; 5629 // v = x binop= expr; 5630 // v = x = x binop expr; 5631 // v = x = expr binop x; 5632 auto *AtomicBinOp = 5633 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 5634 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 5635 V = AtomicBinOp->getLHS(); 5636 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 5637 OpenMPAtomicUpdateChecker Checker(*this); 5638 if (Checker.checkStatement( 5639 Body, diag::err_omp_atomic_capture_not_expression_statement, 5640 diag::note_omp_atomic_update)) 5641 return StmtError(); 5642 E = Checker.getExpr(); 5643 X = Checker.getX(); 5644 UE = Checker.getUpdateExpr(); 5645 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5646 IsPostfixUpdate = Checker.isPostfixUpdate(); 5647 } else if (!AtomicBody->isInstantiationDependent()) { 5648 ErrorLoc = AtomicBody->getExprLoc(); 5649 ErrorRange = AtomicBody->getSourceRange(); 5650 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 5651 : AtomicBody->getExprLoc(); 5652 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 5653 : AtomicBody->getSourceRange(); 5654 ErrorFound = NotAnAssignmentOp; 5655 } 5656 if (ErrorFound != NoError) { 5657 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 5658 << ErrorRange; 5659 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 5660 return StmtError(); 5661 } else if (CurContext->isDependentContext()) { 5662 UE = V = E = X = nullptr; 5663 } 5664 } else { 5665 // If clause is a capture: 5666 // { v = x; x = expr; } 5667 // { v = x; x++; } 5668 // { v = x; x--; } 5669 // { v = x; ++x; } 5670 // { v = x; --x; } 5671 // { v = x; x binop= expr; } 5672 // { v = x; x = x binop expr; } 5673 // { v = x; x = expr binop x; } 5674 // { x++; v = x; } 5675 // { x--; v = x; } 5676 // { ++x; v = x; } 5677 // { --x; v = x; } 5678 // { x binop= expr; v = x; } 5679 // { x = x binop expr; v = x; } 5680 // { x = expr binop x; v = x; } 5681 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 5682 // Check that this is { expr1; expr2; } 5683 if (CS->size() == 2) { 5684 auto *First = CS->body_front(); 5685 auto *Second = CS->body_back(); 5686 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 5687 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 5688 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 5689 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 5690 // Need to find what subexpression is 'v' and what is 'x'. 5691 OpenMPAtomicUpdateChecker Checker(*this); 5692 bool IsUpdateExprFound = !Checker.checkStatement(Second); 5693 BinaryOperator *BinOp = nullptr; 5694 if (IsUpdateExprFound) { 5695 BinOp = dyn_cast<BinaryOperator>(First); 5696 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 5697 } 5698 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 5699 // { v = x; x++; } 5700 // { v = x; x--; } 5701 // { v = x; ++x; } 5702 // { v = x; --x; } 5703 // { v = x; x binop= expr; } 5704 // { v = x; x = x binop expr; } 5705 // { v = x; x = expr binop x; } 5706 // Check that the first expression has form v = x. 5707 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 5708 llvm::FoldingSetNodeID XId, PossibleXId; 5709 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 5710 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 5711 IsUpdateExprFound = XId == PossibleXId; 5712 if (IsUpdateExprFound) { 5713 V = BinOp->getLHS(); 5714 X = Checker.getX(); 5715 E = Checker.getExpr(); 5716 UE = Checker.getUpdateExpr(); 5717 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5718 IsPostfixUpdate = true; 5719 } 5720 } 5721 if (!IsUpdateExprFound) { 5722 IsUpdateExprFound = !Checker.checkStatement(First); 5723 BinOp = nullptr; 5724 if (IsUpdateExprFound) { 5725 BinOp = dyn_cast<BinaryOperator>(Second); 5726 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 5727 } 5728 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 5729 // { x++; v = x; } 5730 // { x--; v = x; } 5731 // { ++x; v = x; } 5732 // { --x; v = x; } 5733 // { x binop= expr; v = x; } 5734 // { x = x binop expr; v = x; } 5735 // { x = expr binop x; v = x; } 5736 // Check that the second expression has form v = x. 5737 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 5738 llvm::FoldingSetNodeID XId, PossibleXId; 5739 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 5740 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 5741 IsUpdateExprFound = XId == PossibleXId; 5742 if (IsUpdateExprFound) { 5743 V = BinOp->getLHS(); 5744 X = Checker.getX(); 5745 E = Checker.getExpr(); 5746 UE = Checker.getUpdateExpr(); 5747 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 5748 IsPostfixUpdate = false; 5749 } 5750 } 5751 } 5752 if (!IsUpdateExprFound) { 5753 // { v = x; x = expr; } 5754 auto *FirstExpr = dyn_cast<Expr>(First); 5755 auto *SecondExpr = dyn_cast<Expr>(Second); 5756 if (!FirstExpr || !SecondExpr || 5757 !(FirstExpr->isInstantiationDependent() || 5758 SecondExpr->isInstantiationDependent())) { 5759 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 5760 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 5761 ErrorFound = NotAnAssignmentOp; 5762 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 5763 : First->getLocStart(); 5764 NoteRange = ErrorRange = FirstBinOp 5765 ? FirstBinOp->getSourceRange() 5766 : SourceRange(ErrorLoc, ErrorLoc); 5767 } else { 5768 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 5769 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 5770 ErrorFound = NotAnAssignmentOp; 5771 NoteLoc = ErrorLoc = SecondBinOp 5772 ? SecondBinOp->getOperatorLoc() 5773 : Second->getLocStart(); 5774 NoteRange = ErrorRange = 5775 SecondBinOp ? SecondBinOp->getSourceRange() 5776 : SourceRange(ErrorLoc, ErrorLoc); 5777 } else { 5778 auto *PossibleXRHSInFirst = 5779 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 5780 auto *PossibleXLHSInSecond = 5781 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 5782 llvm::FoldingSetNodeID X1Id, X2Id; 5783 PossibleXRHSInFirst->Profile(X1Id, Context, 5784 /*Canonical=*/true); 5785 PossibleXLHSInSecond->Profile(X2Id, Context, 5786 /*Canonical=*/true); 5787 IsUpdateExprFound = X1Id == X2Id; 5788 if (IsUpdateExprFound) { 5789 V = FirstBinOp->getLHS(); 5790 X = SecondBinOp->getLHS(); 5791 E = SecondBinOp->getRHS(); 5792 UE = nullptr; 5793 IsXLHSInRHSPart = false; 5794 IsPostfixUpdate = true; 5795 } else { 5796 ErrorFound = NotASpecificExpression; 5797 ErrorLoc = FirstBinOp->getExprLoc(); 5798 ErrorRange = FirstBinOp->getSourceRange(); 5799 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 5800 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 5801 } 5802 } 5803 } 5804 } 5805 } 5806 } else { 5807 NoteLoc = ErrorLoc = Body->getLocStart(); 5808 NoteRange = ErrorRange = 5809 SourceRange(Body->getLocStart(), Body->getLocStart()); 5810 ErrorFound = NotTwoSubstatements; 5811 } 5812 } else { 5813 NoteLoc = ErrorLoc = Body->getLocStart(); 5814 NoteRange = ErrorRange = 5815 SourceRange(Body->getLocStart(), Body->getLocStart()); 5816 ErrorFound = NotACompoundStatement; 5817 } 5818 if (ErrorFound != NoError) { 5819 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 5820 << ErrorRange; 5821 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 5822 return StmtError(); 5823 } else if (CurContext->isDependentContext()) { 5824 UE = V = E = X = nullptr; 5825 } 5826 } 5827 } 5828 5829 getCurFunction()->setHasBranchProtectedScope(); 5830 5831 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 5832 X, V, E, UE, IsXLHSInRHSPart, 5833 IsPostfixUpdate); 5834 } 5835 5836 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 5837 Stmt *AStmt, 5838 SourceLocation StartLoc, 5839 SourceLocation EndLoc) { 5840 if (!AStmt) 5841 return StmtError(); 5842 5843 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5844 // 1.2.2 OpenMP Language Terminology 5845 // Structured block - An executable statement with a single entry at the 5846 // top and a single exit at the bottom. 5847 // The point of exit cannot be a branch out of the structured block. 5848 // longjmp() and throw() must not violate the entry/exit criteria. 5849 CS->getCapturedDecl()->setNothrow(); 5850 5851 // OpenMP [2.16, Nesting of Regions] 5852 // If specified, a teams construct must be contained within a target 5853 // construct. That target construct must contain no statements or directives 5854 // outside of the teams construct. 5855 if (DSAStack->hasInnerTeamsRegion()) { 5856 auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true); 5857 bool OMPTeamsFound = true; 5858 if (auto *CS = dyn_cast<CompoundStmt>(S)) { 5859 auto I = CS->body_begin(); 5860 while (I != CS->body_end()) { 5861 auto *OED = dyn_cast<OMPExecutableDirective>(*I); 5862 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { 5863 OMPTeamsFound = false; 5864 break; 5865 } 5866 ++I; 5867 } 5868 assert(I != CS->body_end() && "Not found statement"); 5869 S = *I; 5870 } else { 5871 auto *OED = dyn_cast<OMPExecutableDirective>(S); 5872 OMPTeamsFound = OED && isOpenMPTeamsDirective(OED->getDirectiveKind()); 5873 } 5874 if (!OMPTeamsFound) { 5875 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 5876 Diag(DSAStack->getInnerTeamsRegionLoc(), 5877 diag::note_omp_nested_teams_construct_here); 5878 Diag(S->getLocStart(), diag::note_omp_nested_statement_here) 5879 << isa<OMPExecutableDirective>(S); 5880 return StmtError(); 5881 } 5882 } 5883 5884 getCurFunction()->setHasBranchProtectedScope(); 5885 5886 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 5887 } 5888 5889 StmtResult 5890 Sema::ActOnOpenMPTargetParallelDirective(ArrayRef<OMPClause *> Clauses, 5891 Stmt *AStmt, SourceLocation StartLoc, 5892 SourceLocation EndLoc) { 5893 if (!AStmt) 5894 return StmtError(); 5895 5896 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5897 // 1.2.2 OpenMP Language Terminology 5898 // Structured block - An executable statement with a single entry at the 5899 // top and a single exit at the bottom. 5900 // The point of exit cannot be a branch out of the structured block. 5901 // longjmp() and throw() must not violate the entry/exit criteria. 5902 CS->getCapturedDecl()->setNothrow(); 5903 5904 getCurFunction()->setHasBranchProtectedScope(); 5905 5906 return OMPTargetParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 5907 AStmt); 5908 } 5909 5910 StmtResult Sema::ActOnOpenMPTargetParallelForDirective( 5911 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 5912 SourceLocation EndLoc, 5913 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 5914 if (!AStmt) 5915 return StmtError(); 5916 5917 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 5918 // 1.2.2 OpenMP Language Terminology 5919 // Structured block - An executable statement with a single entry at the 5920 // top and a single exit at the bottom. 5921 // The point of exit cannot be a branch out of the structured block. 5922 // longjmp() and throw() must not violate the entry/exit criteria. 5923 CS->getCapturedDecl()->setNothrow(); 5924 5925 OMPLoopDirective::HelperExprs B; 5926 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 5927 // define the nested loops number. 5928 unsigned NestedLoopCount = 5929 CheckOpenMPLoop(OMPD_target_parallel_for, getCollapseNumberExpr(Clauses), 5930 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 5931 VarsWithImplicitDSA, B); 5932 if (NestedLoopCount == 0) 5933 return StmtError(); 5934 5935 assert((CurContext->isDependentContext() || B.builtAll()) && 5936 "omp target parallel for loop exprs were not built"); 5937 5938 if (!CurContext->isDependentContext()) { 5939 // Finalize the clauses that need pre-built expressions for CodeGen. 5940 for (auto C : Clauses) { 5941 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 5942 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 5943 B.NumIterations, *this, CurScope, 5944 DSAStack)) 5945 return StmtError(); 5946 } 5947 } 5948 5949 getCurFunction()->setHasBranchProtectedScope(); 5950 return OMPTargetParallelForDirective::Create(Context, StartLoc, EndLoc, 5951 NestedLoopCount, Clauses, AStmt, 5952 B, DSAStack->isCancelRegion()); 5953 } 5954 5955 /// Check for existence of a map clause in the list of clauses. 5956 static bool hasClauses(ArrayRef<OMPClause *> Clauses, 5957 const OpenMPClauseKind K) { 5958 return llvm::any_of( 5959 Clauses, [K](const OMPClause *C) { return C->getClauseKind() == K; }); 5960 } 5961 5962 template <typename... Params> 5963 static bool hasClauses(ArrayRef<OMPClause *> Clauses, const OpenMPClauseKind K, 5964 const Params... ClauseTypes) { 5965 return hasClauses(Clauses, K) || hasClauses(Clauses, ClauseTypes...); 5966 } 5967 5968 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 5969 Stmt *AStmt, 5970 SourceLocation StartLoc, 5971 SourceLocation EndLoc) { 5972 if (!AStmt) 5973 return StmtError(); 5974 5975 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 5976 5977 // OpenMP [2.10.1, Restrictions, p. 97] 5978 // At least one map clause must appear on the directive. 5979 if (!hasClauses(Clauses, OMPC_map, OMPC_use_device_ptr)) { 5980 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 5981 << "'map' or 'use_device_ptr'" 5982 << getOpenMPDirectiveName(OMPD_target_data); 5983 return StmtError(); 5984 } 5985 5986 getCurFunction()->setHasBranchProtectedScope(); 5987 5988 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 5989 AStmt); 5990 } 5991 5992 StmtResult 5993 Sema::ActOnOpenMPTargetEnterDataDirective(ArrayRef<OMPClause *> Clauses, 5994 SourceLocation StartLoc, 5995 SourceLocation EndLoc) { 5996 // OpenMP [2.10.2, Restrictions, p. 99] 5997 // At least one map clause must appear on the directive. 5998 if (!hasClauses(Clauses, OMPC_map)) { 5999 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6000 << "'map'" << getOpenMPDirectiveName(OMPD_target_enter_data); 6001 return StmtError(); 6002 } 6003 6004 return OMPTargetEnterDataDirective::Create(Context, StartLoc, EndLoc, 6005 Clauses); 6006 } 6007 6008 StmtResult 6009 Sema::ActOnOpenMPTargetExitDataDirective(ArrayRef<OMPClause *> Clauses, 6010 SourceLocation StartLoc, 6011 SourceLocation EndLoc) { 6012 // OpenMP [2.10.3, Restrictions, p. 102] 6013 // At least one map clause must appear on the directive. 6014 if (!hasClauses(Clauses, OMPC_map)) { 6015 Diag(StartLoc, diag::err_omp_no_clause_for_directive) 6016 << "'map'" << getOpenMPDirectiveName(OMPD_target_exit_data); 6017 return StmtError(); 6018 } 6019 6020 return OMPTargetExitDataDirective::Create(Context, StartLoc, EndLoc, Clauses); 6021 } 6022 6023 StmtResult Sema::ActOnOpenMPTargetUpdateDirective(ArrayRef<OMPClause *> Clauses, 6024 SourceLocation StartLoc, 6025 SourceLocation EndLoc) { 6026 if (!hasClauses(Clauses, OMPC_to, OMPC_from)) { 6027 Diag(StartLoc, diag::err_omp_at_least_one_motion_clause_required); 6028 return StmtError(); 6029 } 6030 return OMPTargetUpdateDirective::Create(Context, StartLoc, EndLoc, Clauses); 6031 } 6032 6033 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 6034 Stmt *AStmt, SourceLocation StartLoc, 6035 SourceLocation EndLoc) { 6036 if (!AStmt) 6037 return StmtError(); 6038 6039 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6040 // 1.2.2 OpenMP Language Terminology 6041 // Structured block - An executable statement with a single entry at the 6042 // top and a single exit at the bottom. 6043 // The point of exit cannot be a branch out of the structured block. 6044 // longjmp() and throw() must not violate the entry/exit criteria. 6045 CS->getCapturedDecl()->setNothrow(); 6046 6047 getCurFunction()->setHasBranchProtectedScope(); 6048 6049 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 6050 } 6051 6052 StmtResult 6053 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 6054 SourceLocation EndLoc, 6055 OpenMPDirectiveKind CancelRegion) { 6056 if (DSAStack->isParentNowaitRegion()) { 6057 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 6058 return StmtError(); 6059 } 6060 if (DSAStack->isParentOrderedRegion()) { 6061 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 6062 return StmtError(); 6063 } 6064 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 6065 CancelRegion); 6066 } 6067 6068 StmtResult Sema::ActOnOpenMPCancelDirective(ArrayRef<OMPClause *> Clauses, 6069 SourceLocation StartLoc, 6070 SourceLocation EndLoc, 6071 OpenMPDirectiveKind CancelRegion) { 6072 if (DSAStack->isParentNowaitRegion()) { 6073 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 6074 return StmtError(); 6075 } 6076 if (DSAStack->isParentOrderedRegion()) { 6077 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 6078 return StmtError(); 6079 } 6080 DSAStack->setParentCancelRegion(/*Cancel=*/true); 6081 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, Clauses, 6082 CancelRegion); 6083 } 6084 6085 static bool checkGrainsizeNumTasksClauses(Sema &S, 6086 ArrayRef<OMPClause *> Clauses) { 6087 OMPClause *PrevClause = nullptr; 6088 bool ErrorFound = false; 6089 for (auto *C : Clauses) { 6090 if (C->getClauseKind() == OMPC_grainsize || 6091 C->getClauseKind() == OMPC_num_tasks) { 6092 if (!PrevClause) 6093 PrevClause = C; 6094 else if (PrevClause->getClauseKind() != C->getClauseKind()) { 6095 S.Diag(C->getLocStart(), 6096 diag::err_omp_grainsize_num_tasks_mutually_exclusive) 6097 << getOpenMPClauseName(C->getClauseKind()) 6098 << getOpenMPClauseName(PrevClause->getClauseKind()); 6099 S.Diag(PrevClause->getLocStart(), 6100 diag::note_omp_previous_grainsize_num_tasks) 6101 << getOpenMPClauseName(PrevClause->getClauseKind()); 6102 ErrorFound = true; 6103 } 6104 } 6105 } 6106 return ErrorFound; 6107 } 6108 6109 StmtResult Sema::ActOnOpenMPTaskLoopDirective( 6110 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6111 SourceLocation EndLoc, 6112 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6113 if (!AStmt) 6114 return StmtError(); 6115 6116 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6117 OMPLoopDirective::HelperExprs B; 6118 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6119 // define the nested loops number. 6120 unsigned NestedLoopCount = 6121 CheckOpenMPLoop(OMPD_taskloop, getCollapseNumberExpr(Clauses), 6122 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6123 VarsWithImplicitDSA, B); 6124 if (NestedLoopCount == 0) 6125 return StmtError(); 6126 6127 assert((CurContext->isDependentContext() || B.builtAll()) && 6128 "omp for loop exprs were not built"); 6129 6130 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6131 // The grainsize clause and num_tasks clause are mutually exclusive and may 6132 // not appear on the same taskloop directive. 6133 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6134 return StmtError(); 6135 6136 getCurFunction()->setHasBranchProtectedScope(); 6137 return OMPTaskLoopDirective::Create(Context, StartLoc, EndLoc, 6138 NestedLoopCount, Clauses, AStmt, B); 6139 } 6140 6141 StmtResult Sema::ActOnOpenMPTaskLoopSimdDirective( 6142 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6143 SourceLocation EndLoc, 6144 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6145 if (!AStmt) 6146 return StmtError(); 6147 6148 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6149 OMPLoopDirective::HelperExprs B; 6150 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6151 // define the nested loops number. 6152 unsigned NestedLoopCount = 6153 CheckOpenMPLoop(OMPD_taskloop_simd, getCollapseNumberExpr(Clauses), 6154 /*OrderedLoopCountExpr=*/nullptr, AStmt, *this, *DSAStack, 6155 VarsWithImplicitDSA, B); 6156 if (NestedLoopCount == 0) 6157 return StmtError(); 6158 6159 assert((CurContext->isDependentContext() || B.builtAll()) && 6160 "omp for loop exprs were not built"); 6161 6162 if (!CurContext->isDependentContext()) { 6163 // Finalize the clauses that need pre-built expressions for CodeGen. 6164 for (auto C : Clauses) { 6165 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6166 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6167 B.NumIterations, *this, CurScope, 6168 DSAStack)) 6169 return StmtError(); 6170 } 6171 } 6172 6173 // OpenMP, [2.9.2 taskloop Construct, Restrictions] 6174 // The grainsize clause and num_tasks clause are mutually exclusive and may 6175 // not appear on the same taskloop directive. 6176 if (checkGrainsizeNumTasksClauses(*this, Clauses)) 6177 return StmtError(); 6178 6179 getCurFunction()->setHasBranchProtectedScope(); 6180 return OMPTaskLoopSimdDirective::Create(Context, StartLoc, EndLoc, 6181 NestedLoopCount, Clauses, AStmt, B); 6182 } 6183 6184 StmtResult Sema::ActOnOpenMPDistributeDirective( 6185 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6186 SourceLocation EndLoc, 6187 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6188 if (!AStmt) 6189 return StmtError(); 6190 6191 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 6192 OMPLoopDirective::HelperExprs B; 6193 // In presence of clause 'collapse' with number of loops, it will 6194 // define the nested loops number. 6195 unsigned NestedLoopCount = 6196 CheckOpenMPLoop(OMPD_distribute, getCollapseNumberExpr(Clauses), 6197 nullptr /*ordered not a clause on distribute*/, AStmt, 6198 *this, *DSAStack, VarsWithImplicitDSA, B); 6199 if (NestedLoopCount == 0) 6200 return StmtError(); 6201 6202 assert((CurContext->isDependentContext() || B.builtAll()) && 6203 "omp for loop exprs were not built"); 6204 6205 getCurFunction()->setHasBranchProtectedScope(); 6206 return OMPDistributeDirective::Create(Context, StartLoc, EndLoc, 6207 NestedLoopCount, Clauses, AStmt, B); 6208 } 6209 6210 StmtResult Sema::ActOnOpenMPDistributeParallelForDirective( 6211 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6212 SourceLocation EndLoc, 6213 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6214 if (!AStmt) 6215 return StmtError(); 6216 6217 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6218 // 1.2.2 OpenMP Language Terminology 6219 // Structured block - An executable statement with a single entry at the 6220 // top and a single exit at the bottom. 6221 // The point of exit cannot be a branch out of the structured block. 6222 // longjmp() and throw() must not violate the entry/exit criteria. 6223 CS->getCapturedDecl()->setNothrow(); 6224 6225 OMPLoopDirective::HelperExprs B; 6226 // In presence of clause 'collapse' with number of loops, it will 6227 // define the nested loops number. 6228 unsigned NestedLoopCount = CheckOpenMPLoop( 6229 OMPD_distribute_parallel_for, getCollapseNumberExpr(Clauses), 6230 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6231 VarsWithImplicitDSA, B); 6232 if (NestedLoopCount == 0) 6233 return StmtError(); 6234 6235 assert((CurContext->isDependentContext() || B.builtAll()) && 6236 "omp for loop exprs were not built"); 6237 6238 getCurFunction()->setHasBranchProtectedScope(); 6239 return OMPDistributeParallelForDirective::Create( 6240 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6241 } 6242 6243 StmtResult Sema::ActOnOpenMPDistributeParallelForSimdDirective( 6244 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6245 SourceLocation EndLoc, 6246 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6247 if (!AStmt) 6248 return StmtError(); 6249 6250 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6251 // 1.2.2 OpenMP Language Terminology 6252 // Structured block - An executable statement with a single entry at the 6253 // top and a single exit at the bottom. 6254 // The point of exit cannot be a branch out of the structured block. 6255 // longjmp() and throw() must not violate the entry/exit criteria. 6256 CS->getCapturedDecl()->setNothrow(); 6257 6258 OMPLoopDirective::HelperExprs B; 6259 // In presence of clause 'collapse' with number of loops, it will 6260 // define the nested loops number. 6261 unsigned NestedLoopCount = CheckOpenMPLoop( 6262 OMPD_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 6263 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6264 VarsWithImplicitDSA, B); 6265 if (NestedLoopCount == 0) 6266 return StmtError(); 6267 6268 assert((CurContext->isDependentContext() || B.builtAll()) && 6269 "omp for loop exprs were not built"); 6270 6271 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6272 return StmtError(); 6273 6274 getCurFunction()->setHasBranchProtectedScope(); 6275 return OMPDistributeParallelForSimdDirective::Create( 6276 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6277 } 6278 6279 StmtResult Sema::ActOnOpenMPDistributeSimdDirective( 6280 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6281 SourceLocation EndLoc, 6282 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6283 if (!AStmt) 6284 return StmtError(); 6285 6286 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6287 // 1.2.2 OpenMP Language Terminology 6288 // Structured block - An executable statement with a single entry at the 6289 // top and a single exit at the bottom. 6290 // The point of exit cannot be a branch out of the structured block. 6291 // longjmp() and throw() must not violate the entry/exit criteria. 6292 CS->getCapturedDecl()->setNothrow(); 6293 6294 OMPLoopDirective::HelperExprs B; 6295 // In presence of clause 'collapse' with number of loops, it will 6296 // define the nested loops number. 6297 unsigned NestedLoopCount = 6298 CheckOpenMPLoop(OMPD_distribute_simd, getCollapseNumberExpr(Clauses), 6299 nullptr /*ordered not a clause on distribute*/, AStmt, 6300 *this, *DSAStack, VarsWithImplicitDSA, B); 6301 if (NestedLoopCount == 0) 6302 return StmtError(); 6303 6304 assert((CurContext->isDependentContext() || B.builtAll()) && 6305 "omp for loop exprs were not built"); 6306 6307 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6308 return StmtError(); 6309 6310 getCurFunction()->setHasBranchProtectedScope(); 6311 return OMPDistributeSimdDirective::Create(Context, StartLoc, EndLoc, 6312 NestedLoopCount, Clauses, AStmt, B); 6313 } 6314 6315 StmtResult Sema::ActOnOpenMPTargetParallelForSimdDirective( 6316 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6317 SourceLocation EndLoc, 6318 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6319 if (!AStmt) 6320 return StmtError(); 6321 6322 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6323 // 1.2.2 OpenMP Language Terminology 6324 // Structured block - An executable statement with a single entry at the 6325 // top and a single exit at the bottom. 6326 // The point of exit cannot be a branch out of the structured block. 6327 // longjmp() and throw() must not violate the entry/exit criteria. 6328 CS->getCapturedDecl()->setNothrow(); 6329 6330 OMPLoopDirective::HelperExprs B; 6331 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 6332 // define the nested loops number. 6333 unsigned NestedLoopCount = CheckOpenMPLoop( 6334 OMPD_target_parallel_for_simd, getCollapseNumberExpr(Clauses), 6335 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6336 VarsWithImplicitDSA, B); 6337 if (NestedLoopCount == 0) 6338 return StmtError(); 6339 6340 assert((CurContext->isDependentContext() || B.builtAll()) && 6341 "omp target parallel for simd loop exprs were not built"); 6342 6343 if (!CurContext->isDependentContext()) { 6344 // Finalize the clauses that need pre-built expressions for CodeGen. 6345 for (auto C : Clauses) { 6346 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6347 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6348 B.NumIterations, *this, CurScope, 6349 DSAStack)) 6350 return StmtError(); 6351 } 6352 } 6353 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6354 return StmtError(); 6355 6356 getCurFunction()->setHasBranchProtectedScope(); 6357 return OMPTargetParallelForSimdDirective::Create( 6358 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6359 } 6360 6361 StmtResult Sema::ActOnOpenMPTargetSimdDirective( 6362 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6363 SourceLocation EndLoc, 6364 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6365 if (!AStmt) 6366 return StmtError(); 6367 6368 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6369 // 1.2.2 OpenMP Language Terminology 6370 // Structured block - An executable statement with a single entry at the 6371 // top and a single exit at the bottom. 6372 // The point of exit cannot be a branch out of the structured block. 6373 // longjmp() and throw() must not violate the entry/exit criteria. 6374 CS->getCapturedDecl()->setNothrow(); 6375 6376 OMPLoopDirective::HelperExprs B; 6377 // In presence of clause 'collapse' with number of loops, it will define the 6378 // nested loops number. 6379 unsigned NestedLoopCount = 6380 CheckOpenMPLoop(OMPD_target_simd, getCollapseNumberExpr(Clauses), 6381 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 6382 VarsWithImplicitDSA, B); 6383 if (NestedLoopCount == 0) 6384 return StmtError(); 6385 6386 assert((CurContext->isDependentContext() || B.builtAll()) && 6387 "omp target simd loop exprs were not built"); 6388 6389 if (!CurContext->isDependentContext()) { 6390 // Finalize the clauses that need pre-built expressions for CodeGen. 6391 for (auto C : Clauses) { 6392 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6393 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6394 B.NumIterations, *this, CurScope, 6395 DSAStack)) 6396 return StmtError(); 6397 } 6398 } 6399 6400 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6401 return StmtError(); 6402 6403 getCurFunction()->setHasBranchProtectedScope(); 6404 return OMPTargetSimdDirective::Create(Context, StartLoc, EndLoc, 6405 NestedLoopCount, Clauses, AStmt, B); 6406 } 6407 6408 StmtResult Sema::ActOnOpenMPTeamsDistributeDirective( 6409 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6410 SourceLocation EndLoc, 6411 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6412 if (!AStmt) 6413 return StmtError(); 6414 6415 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6416 // 1.2.2 OpenMP Language Terminology 6417 // Structured block - An executable statement with a single entry at the 6418 // top and a single exit at the bottom. 6419 // The point of exit cannot be a branch out of the structured block. 6420 // longjmp() and throw() must not violate the entry/exit criteria. 6421 CS->getCapturedDecl()->setNothrow(); 6422 6423 OMPLoopDirective::HelperExprs B; 6424 // In presence of clause 'collapse' with number of loops, it will 6425 // define the nested loops number. 6426 unsigned NestedLoopCount = 6427 CheckOpenMPLoop(OMPD_teams_distribute, getCollapseNumberExpr(Clauses), 6428 nullptr /*ordered not a clause on distribute*/, AStmt, 6429 *this, *DSAStack, VarsWithImplicitDSA, B); 6430 if (NestedLoopCount == 0) 6431 return StmtError(); 6432 6433 assert((CurContext->isDependentContext() || B.builtAll()) && 6434 "omp teams distribute loop exprs were not built"); 6435 6436 getCurFunction()->setHasBranchProtectedScope(); 6437 return OMPTeamsDistributeDirective::Create( 6438 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6439 } 6440 6441 StmtResult Sema::ActOnOpenMPTeamsDistributeSimdDirective( 6442 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6443 SourceLocation EndLoc, 6444 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6445 if (!AStmt) 6446 return StmtError(); 6447 6448 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6449 // 1.2.2 OpenMP Language Terminology 6450 // Structured block - An executable statement with a single entry at the 6451 // top and a single exit at the bottom. 6452 // The point of exit cannot be a branch out of the structured block. 6453 // longjmp() and throw() must not violate the entry/exit criteria. 6454 CS->getCapturedDecl()->setNothrow(); 6455 6456 OMPLoopDirective::HelperExprs B; 6457 // In presence of clause 'collapse' with number of loops, it will 6458 // define the nested loops number. 6459 unsigned NestedLoopCount = CheckOpenMPLoop( 6460 OMPD_teams_distribute_simd, getCollapseNumberExpr(Clauses), 6461 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6462 VarsWithImplicitDSA, B); 6463 6464 if (NestedLoopCount == 0) 6465 return StmtError(); 6466 6467 assert((CurContext->isDependentContext() || B.builtAll()) && 6468 "omp teams distribute simd loop exprs were not built"); 6469 6470 if (!CurContext->isDependentContext()) { 6471 // Finalize the clauses that need pre-built expressions for CodeGen. 6472 for (auto C : Clauses) { 6473 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6474 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6475 B.NumIterations, *this, CurScope, 6476 DSAStack)) 6477 return StmtError(); 6478 } 6479 } 6480 6481 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6482 return StmtError(); 6483 6484 getCurFunction()->setHasBranchProtectedScope(); 6485 return OMPTeamsDistributeSimdDirective::Create( 6486 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6487 } 6488 6489 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForSimdDirective( 6490 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6491 SourceLocation EndLoc, 6492 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6493 if (!AStmt) 6494 return StmtError(); 6495 6496 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6497 // 1.2.2 OpenMP Language Terminology 6498 // Structured block - An executable statement with a single entry at the 6499 // top and a single exit at the bottom. 6500 // The point of exit cannot be a branch out of the structured block. 6501 // longjmp() and throw() must not violate the entry/exit criteria. 6502 CS->getCapturedDecl()->setNothrow(); 6503 6504 OMPLoopDirective::HelperExprs B; 6505 // In presence of clause 'collapse' with number of loops, it will 6506 // define the nested loops number. 6507 auto NestedLoopCount = CheckOpenMPLoop( 6508 OMPD_teams_distribute_parallel_for_simd, getCollapseNumberExpr(Clauses), 6509 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6510 VarsWithImplicitDSA, B); 6511 6512 if (NestedLoopCount == 0) 6513 return StmtError(); 6514 6515 assert((CurContext->isDependentContext() || B.builtAll()) && 6516 "omp for loop exprs were not built"); 6517 6518 if (!CurContext->isDependentContext()) { 6519 // Finalize the clauses that need pre-built expressions for CodeGen. 6520 for (auto C : Clauses) { 6521 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6522 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6523 B.NumIterations, *this, CurScope, 6524 DSAStack)) 6525 return StmtError(); 6526 } 6527 } 6528 6529 if (checkSimdlenSafelenSpecified(*this, Clauses)) 6530 return StmtError(); 6531 6532 getCurFunction()->setHasBranchProtectedScope(); 6533 return OMPTeamsDistributeParallelForSimdDirective::Create( 6534 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6535 } 6536 6537 StmtResult Sema::ActOnOpenMPTeamsDistributeParallelForDirective( 6538 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6539 SourceLocation EndLoc, 6540 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6541 if (!AStmt) 6542 return StmtError(); 6543 6544 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6545 // 1.2.2 OpenMP Language Terminology 6546 // Structured block - An executable statement with a single entry at the 6547 // top and a single exit at the bottom. 6548 // The point of exit cannot be a branch out of the structured block. 6549 // longjmp() and throw() must not violate the entry/exit criteria. 6550 CS->getCapturedDecl()->setNothrow(); 6551 6552 OMPLoopDirective::HelperExprs B; 6553 // In presence of clause 'collapse' with number of loops, it will 6554 // define the nested loops number. 6555 unsigned NestedLoopCount = CheckOpenMPLoop( 6556 OMPD_teams_distribute_parallel_for, getCollapseNumberExpr(Clauses), 6557 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6558 VarsWithImplicitDSA, B); 6559 6560 if (NestedLoopCount == 0) 6561 return StmtError(); 6562 6563 assert((CurContext->isDependentContext() || B.builtAll()) && 6564 "omp for loop exprs were not built"); 6565 6566 if (!CurContext->isDependentContext()) { 6567 // Finalize the clauses that need pre-built expressions for CodeGen. 6568 for (auto C : Clauses) { 6569 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6570 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6571 B.NumIterations, *this, CurScope, 6572 DSAStack)) 6573 return StmtError(); 6574 } 6575 } 6576 6577 getCurFunction()->setHasBranchProtectedScope(); 6578 return OMPTeamsDistributeParallelForDirective::Create( 6579 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6580 } 6581 6582 StmtResult Sema::ActOnOpenMPTargetTeamsDirective(ArrayRef<OMPClause *> Clauses, 6583 Stmt *AStmt, 6584 SourceLocation StartLoc, 6585 SourceLocation EndLoc) { 6586 if (!AStmt) 6587 return StmtError(); 6588 6589 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6590 // 1.2.2 OpenMP Language Terminology 6591 // Structured block - An executable statement with a single entry at the 6592 // top and a single exit at the bottom. 6593 // The point of exit cannot be a branch out of the structured block. 6594 // longjmp() and throw() must not violate the entry/exit criteria. 6595 CS->getCapturedDecl()->setNothrow(); 6596 6597 getCurFunction()->setHasBranchProtectedScope(); 6598 6599 return OMPTargetTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, 6600 AStmt); 6601 } 6602 6603 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeDirective( 6604 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6605 SourceLocation EndLoc, 6606 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6607 if (!AStmt) 6608 return StmtError(); 6609 6610 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6611 // 1.2.2 OpenMP Language Terminology 6612 // Structured block - An executable statement with a single entry at the 6613 // top and a single exit at the bottom. 6614 // The point of exit cannot be a branch out of the structured block. 6615 // longjmp() and throw() must not violate the entry/exit criteria. 6616 CS->getCapturedDecl()->setNothrow(); 6617 6618 OMPLoopDirective::HelperExprs B; 6619 // In presence of clause 'collapse' with number of loops, it will 6620 // define the nested loops number. 6621 auto NestedLoopCount = CheckOpenMPLoop( 6622 OMPD_target_teams_distribute, 6623 getCollapseNumberExpr(Clauses), 6624 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6625 VarsWithImplicitDSA, B); 6626 if (NestedLoopCount == 0) 6627 return StmtError(); 6628 6629 assert((CurContext->isDependentContext() || B.builtAll()) && 6630 "omp target teams distribute loop exprs were not built"); 6631 6632 getCurFunction()->setHasBranchProtectedScope(); 6633 return OMPTargetTeamsDistributeDirective::Create( 6634 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6635 } 6636 6637 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForDirective( 6638 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6639 SourceLocation EndLoc, 6640 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6641 if (!AStmt) 6642 return StmtError(); 6643 6644 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6645 // 1.2.2 OpenMP Language Terminology 6646 // Structured block - An executable statement with a single entry at the 6647 // top and a single exit at the bottom. 6648 // The point of exit cannot be a branch out of the structured block. 6649 // longjmp() and throw() must not violate the entry/exit criteria. 6650 CS->getCapturedDecl()->setNothrow(); 6651 6652 OMPLoopDirective::HelperExprs B; 6653 // In presence of clause 'collapse' with number of loops, it will 6654 // define the nested loops number. 6655 auto NestedLoopCount = CheckOpenMPLoop( 6656 OMPD_target_teams_distribute_parallel_for, 6657 getCollapseNumberExpr(Clauses), 6658 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6659 VarsWithImplicitDSA, B); 6660 if (NestedLoopCount == 0) 6661 return StmtError(); 6662 6663 assert((CurContext->isDependentContext() || B.builtAll()) && 6664 "omp target teams distribute parallel for loop exprs were not built"); 6665 6666 if (!CurContext->isDependentContext()) { 6667 // Finalize the clauses that need pre-built expressions for CodeGen. 6668 for (auto C : Clauses) { 6669 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6670 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6671 B.NumIterations, *this, CurScope, 6672 DSAStack)) 6673 return StmtError(); 6674 } 6675 } 6676 6677 getCurFunction()->setHasBranchProtectedScope(); 6678 return OMPTargetTeamsDistributeParallelForDirective::Create( 6679 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6680 } 6681 6682 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeParallelForSimdDirective( 6683 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6684 SourceLocation EndLoc, 6685 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6686 if (!AStmt) 6687 return StmtError(); 6688 6689 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 6690 // 1.2.2 OpenMP Language Terminology 6691 // Structured block - An executable statement with a single entry at the 6692 // top and a single exit at the bottom. 6693 // The point of exit cannot be a branch out of the structured block. 6694 // longjmp() and throw() must not violate the entry/exit criteria. 6695 CS->getCapturedDecl()->setNothrow(); 6696 6697 OMPLoopDirective::HelperExprs B; 6698 // In presence of clause 'collapse' with number of loops, it will 6699 // define the nested loops number. 6700 auto NestedLoopCount = CheckOpenMPLoop( 6701 OMPD_target_teams_distribute_parallel_for_simd, 6702 getCollapseNumberExpr(Clauses), 6703 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6704 VarsWithImplicitDSA, B); 6705 if (NestedLoopCount == 0) 6706 return StmtError(); 6707 6708 assert((CurContext->isDependentContext() || B.builtAll()) && 6709 "omp target teams distribute parallel for simd loop exprs were not " 6710 "built"); 6711 6712 if (!CurContext->isDependentContext()) { 6713 // Finalize the clauses that need pre-built expressions for CodeGen. 6714 for (auto C : Clauses) { 6715 if (auto *LC = dyn_cast<OMPLinearClause>(C)) 6716 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 6717 B.NumIterations, *this, CurScope, 6718 DSAStack)) 6719 return StmtError(); 6720 } 6721 } 6722 6723 getCurFunction()->setHasBranchProtectedScope(); 6724 return OMPTargetTeamsDistributeParallelForSimdDirective::Create( 6725 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6726 } 6727 6728 StmtResult Sema::ActOnOpenMPTargetTeamsDistributeSimdDirective( 6729 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 6730 SourceLocation EndLoc, 6731 llvm::DenseMap<ValueDecl *, Expr *> &VarsWithImplicitDSA) { 6732 if (!AStmt) 6733 return StmtError(); 6734 6735 auto *CS = cast<CapturedStmt>(AStmt); 6736 // 1.2.2 OpenMP Language Terminology 6737 // Structured block - An executable statement with a single entry at the 6738 // top and a single exit at the bottom. 6739 // The point of exit cannot be a branch out of the structured block. 6740 // longjmp() and throw() must not violate the entry/exit criteria. 6741 CS->getCapturedDecl()->setNothrow(); 6742 6743 OMPLoopDirective::HelperExprs B; 6744 // In presence of clause 'collapse' with number of loops, it will 6745 // define the nested loops number. 6746 auto NestedLoopCount = CheckOpenMPLoop( 6747 OMPD_target_teams_distribute_simd, getCollapseNumberExpr(Clauses), 6748 nullptr /*ordered not a clause on distribute*/, AStmt, *this, *DSAStack, 6749 VarsWithImplicitDSA, B); 6750 if (NestedLoopCount == 0) 6751 return StmtError(); 6752 6753 assert((CurContext->isDependentContext() || B.builtAll()) && 6754 "omp target teams distribute simd loop exprs were not built"); 6755 6756 getCurFunction()->setHasBranchProtectedScope(); 6757 return OMPTargetTeamsDistributeSimdDirective::Create( 6758 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 6759 } 6760 6761 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 6762 SourceLocation StartLoc, 6763 SourceLocation LParenLoc, 6764 SourceLocation EndLoc) { 6765 OMPClause *Res = nullptr; 6766 switch (Kind) { 6767 case OMPC_final: 6768 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 6769 break; 6770 case OMPC_num_threads: 6771 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 6772 break; 6773 case OMPC_safelen: 6774 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 6775 break; 6776 case OMPC_simdlen: 6777 Res = ActOnOpenMPSimdlenClause(Expr, StartLoc, LParenLoc, EndLoc); 6778 break; 6779 case OMPC_collapse: 6780 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 6781 break; 6782 case OMPC_ordered: 6783 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 6784 break; 6785 case OMPC_device: 6786 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 6787 break; 6788 case OMPC_num_teams: 6789 Res = ActOnOpenMPNumTeamsClause(Expr, StartLoc, LParenLoc, EndLoc); 6790 break; 6791 case OMPC_thread_limit: 6792 Res = ActOnOpenMPThreadLimitClause(Expr, StartLoc, LParenLoc, EndLoc); 6793 break; 6794 case OMPC_priority: 6795 Res = ActOnOpenMPPriorityClause(Expr, StartLoc, LParenLoc, EndLoc); 6796 break; 6797 case OMPC_grainsize: 6798 Res = ActOnOpenMPGrainsizeClause(Expr, StartLoc, LParenLoc, EndLoc); 6799 break; 6800 case OMPC_num_tasks: 6801 Res = ActOnOpenMPNumTasksClause(Expr, StartLoc, LParenLoc, EndLoc); 6802 break; 6803 case OMPC_hint: 6804 Res = ActOnOpenMPHintClause(Expr, StartLoc, LParenLoc, EndLoc); 6805 break; 6806 case OMPC_if: 6807 case OMPC_default: 6808 case OMPC_proc_bind: 6809 case OMPC_schedule: 6810 case OMPC_private: 6811 case OMPC_firstprivate: 6812 case OMPC_lastprivate: 6813 case OMPC_shared: 6814 case OMPC_reduction: 6815 case OMPC_linear: 6816 case OMPC_aligned: 6817 case OMPC_copyin: 6818 case OMPC_copyprivate: 6819 case OMPC_nowait: 6820 case OMPC_untied: 6821 case OMPC_mergeable: 6822 case OMPC_threadprivate: 6823 case OMPC_flush: 6824 case OMPC_read: 6825 case OMPC_write: 6826 case OMPC_update: 6827 case OMPC_capture: 6828 case OMPC_seq_cst: 6829 case OMPC_depend: 6830 case OMPC_threads: 6831 case OMPC_simd: 6832 case OMPC_map: 6833 case OMPC_nogroup: 6834 case OMPC_dist_schedule: 6835 case OMPC_defaultmap: 6836 case OMPC_unknown: 6837 case OMPC_uniform: 6838 case OMPC_to: 6839 case OMPC_from: 6840 case OMPC_use_device_ptr: 6841 case OMPC_is_device_ptr: 6842 llvm_unreachable("Clause is not allowed."); 6843 } 6844 return Res; 6845 } 6846 6847 // An OpenMP directive such as 'target parallel' has two captured regions: 6848 // for the 'target' and 'parallel' respectively. This function returns 6849 // the region in which to capture expressions associated with a clause. 6850 // A return value of OMPD_unknown signifies that the expression should not 6851 // be captured. 6852 static OpenMPDirectiveKind getOpenMPCaptureRegionForClause( 6853 OpenMPDirectiveKind DKind, OpenMPClauseKind CKind, 6854 OpenMPDirectiveKind NameModifier = OMPD_unknown) { 6855 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 6856 6857 switch (CKind) { 6858 case OMPC_if: 6859 switch (DKind) { 6860 case OMPD_target_parallel: 6861 // If this clause applies to the nested 'parallel' region, capture within 6862 // the 'target' region, otherwise do not capture. 6863 if (NameModifier == OMPD_unknown || NameModifier == OMPD_parallel) 6864 CaptureRegion = OMPD_target; 6865 break; 6866 case OMPD_cancel: 6867 case OMPD_parallel: 6868 case OMPD_parallel_sections: 6869 case OMPD_parallel_for: 6870 case OMPD_parallel_for_simd: 6871 case OMPD_target: 6872 case OMPD_target_simd: 6873 case OMPD_target_parallel_for: 6874 case OMPD_target_parallel_for_simd: 6875 case OMPD_target_teams: 6876 case OMPD_target_teams_distribute: 6877 case OMPD_target_teams_distribute_simd: 6878 case OMPD_target_teams_distribute_parallel_for: 6879 case OMPD_target_teams_distribute_parallel_for_simd: 6880 case OMPD_teams_distribute_parallel_for: 6881 case OMPD_teams_distribute_parallel_for_simd: 6882 case OMPD_distribute_parallel_for: 6883 case OMPD_distribute_parallel_for_simd: 6884 case OMPD_task: 6885 case OMPD_taskloop: 6886 case OMPD_taskloop_simd: 6887 case OMPD_target_data: 6888 case OMPD_target_enter_data: 6889 case OMPD_target_exit_data: 6890 case OMPD_target_update: 6891 // Do not capture if-clause expressions. 6892 break; 6893 case OMPD_threadprivate: 6894 case OMPD_taskyield: 6895 case OMPD_barrier: 6896 case OMPD_taskwait: 6897 case OMPD_cancellation_point: 6898 case OMPD_flush: 6899 case OMPD_declare_reduction: 6900 case OMPD_declare_simd: 6901 case OMPD_declare_target: 6902 case OMPD_end_declare_target: 6903 case OMPD_teams: 6904 case OMPD_simd: 6905 case OMPD_for: 6906 case OMPD_for_simd: 6907 case OMPD_sections: 6908 case OMPD_section: 6909 case OMPD_single: 6910 case OMPD_master: 6911 case OMPD_critical: 6912 case OMPD_taskgroup: 6913 case OMPD_distribute: 6914 case OMPD_ordered: 6915 case OMPD_atomic: 6916 case OMPD_distribute_simd: 6917 case OMPD_teams_distribute: 6918 case OMPD_teams_distribute_simd: 6919 llvm_unreachable("Unexpected OpenMP directive with if-clause"); 6920 case OMPD_unknown: 6921 llvm_unreachable("Unknown OpenMP directive"); 6922 } 6923 break; 6924 case OMPC_num_threads: 6925 switch (DKind) { 6926 case OMPD_target_parallel: 6927 CaptureRegion = OMPD_target; 6928 break; 6929 case OMPD_cancel: 6930 case OMPD_parallel: 6931 case OMPD_parallel_sections: 6932 case OMPD_parallel_for: 6933 case OMPD_parallel_for_simd: 6934 case OMPD_target: 6935 case OMPD_target_simd: 6936 case OMPD_target_parallel_for: 6937 case OMPD_target_parallel_for_simd: 6938 case OMPD_target_teams: 6939 case OMPD_target_teams_distribute: 6940 case OMPD_target_teams_distribute_simd: 6941 case OMPD_target_teams_distribute_parallel_for: 6942 case OMPD_target_teams_distribute_parallel_for_simd: 6943 case OMPD_teams_distribute_parallel_for: 6944 case OMPD_teams_distribute_parallel_for_simd: 6945 case OMPD_distribute_parallel_for: 6946 case OMPD_distribute_parallel_for_simd: 6947 case OMPD_task: 6948 case OMPD_taskloop: 6949 case OMPD_taskloop_simd: 6950 case OMPD_target_data: 6951 case OMPD_target_enter_data: 6952 case OMPD_target_exit_data: 6953 case OMPD_target_update: 6954 // Do not capture num_threads-clause expressions. 6955 break; 6956 case OMPD_threadprivate: 6957 case OMPD_taskyield: 6958 case OMPD_barrier: 6959 case OMPD_taskwait: 6960 case OMPD_cancellation_point: 6961 case OMPD_flush: 6962 case OMPD_declare_reduction: 6963 case OMPD_declare_simd: 6964 case OMPD_declare_target: 6965 case OMPD_end_declare_target: 6966 case OMPD_teams: 6967 case OMPD_simd: 6968 case OMPD_for: 6969 case OMPD_for_simd: 6970 case OMPD_sections: 6971 case OMPD_section: 6972 case OMPD_single: 6973 case OMPD_master: 6974 case OMPD_critical: 6975 case OMPD_taskgroup: 6976 case OMPD_distribute: 6977 case OMPD_ordered: 6978 case OMPD_atomic: 6979 case OMPD_distribute_simd: 6980 case OMPD_teams_distribute: 6981 case OMPD_teams_distribute_simd: 6982 llvm_unreachable("Unexpected OpenMP directive with num_threads-clause"); 6983 case OMPD_unknown: 6984 llvm_unreachable("Unknown OpenMP directive"); 6985 } 6986 break; 6987 case OMPC_num_teams: 6988 switch (DKind) { 6989 case OMPD_target_teams: 6990 CaptureRegion = OMPD_target; 6991 break; 6992 case OMPD_cancel: 6993 case OMPD_parallel: 6994 case OMPD_parallel_sections: 6995 case OMPD_parallel_for: 6996 case OMPD_parallel_for_simd: 6997 case OMPD_target: 6998 case OMPD_target_simd: 6999 case OMPD_target_parallel: 7000 case OMPD_target_parallel_for: 7001 case OMPD_target_parallel_for_simd: 7002 case OMPD_target_teams_distribute: 7003 case OMPD_target_teams_distribute_simd: 7004 case OMPD_target_teams_distribute_parallel_for: 7005 case OMPD_target_teams_distribute_parallel_for_simd: 7006 case OMPD_teams_distribute_parallel_for: 7007 case OMPD_teams_distribute_parallel_for_simd: 7008 case OMPD_distribute_parallel_for: 7009 case OMPD_distribute_parallel_for_simd: 7010 case OMPD_task: 7011 case OMPD_taskloop: 7012 case OMPD_taskloop_simd: 7013 case OMPD_target_data: 7014 case OMPD_target_enter_data: 7015 case OMPD_target_exit_data: 7016 case OMPD_target_update: 7017 case OMPD_teams: 7018 case OMPD_teams_distribute: 7019 case OMPD_teams_distribute_simd: 7020 // Do not capture num_teams-clause expressions. 7021 break; 7022 case OMPD_threadprivate: 7023 case OMPD_taskyield: 7024 case OMPD_barrier: 7025 case OMPD_taskwait: 7026 case OMPD_cancellation_point: 7027 case OMPD_flush: 7028 case OMPD_declare_reduction: 7029 case OMPD_declare_simd: 7030 case OMPD_declare_target: 7031 case OMPD_end_declare_target: 7032 case OMPD_simd: 7033 case OMPD_for: 7034 case OMPD_for_simd: 7035 case OMPD_sections: 7036 case OMPD_section: 7037 case OMPD_single: 7038 case OMPD_master: 7039 case OMPD_critical: 7040 case OMPD_taskgroup: 7041 case OMPD_distribute: 7042 case OMPD_ordered: 7043 case OMPD_atomic: 7044 case OMPD_distribute_simd: 7045 llvm_unreachable("Unexpected OpenMP directive with num_teams-clause"); 7046 case OMPD_unknown: 7047 llvm_unreachable("Unknown OpenMP directive"); 7048 } 7049 break; 7050 case OMPC_thread_limit: 7051 switch (DKind) { 7052 case OMPD_target_teams: 7053 CaptureRegion = OMPD_target; 7054 break; 7055 case OMPD_cancel: 7056 case OMPD_parallel: 7057 case OMPD_parallel_sections: 7058 case OMPD_parallel_for: 7059 case OMPD_parallel_for_simd: 7060 case OMPD_target: 7061 case OMPD_target_simd: 7062 case OMPD_target_parallel: 7063 case OMPD_target_parallel_for: 7064 case OMPD_target_parallel_for_simd: 7065 case OMPD_target_teams_distribute: 7066 case OMPD_target_teams_distribute_simd: 7067 case OMPD_target_teams_distribute_parallel_for: 7068 case OMPD_target_teams_distribute_parallel_for_simd: 7069 case OMPD_teams_distribute_parallel_for: 7070 case OMPD_teams_distribute_parallel_for_simd: 7071 case OMPD_distribute_parallel_for: 7072 case OMPD_distribute_parallel_for_simd: 7073 case OMPD_task: 7074 case OMPD_taskloop: 7075 case OMPD_taskloop_simd: 7076 case OMPD_target_data: 7077 case OMPD_target_enter_data: 7078 case OMPD_target_exit_data: 7079 case OMPD_target_update: 7080 case OMPD_teams: 7081 case OMPD_teams_distribute: 7082 case OMPD_teams_distribute_simd: 7083 // Do not capture thread_limit-clause expressions. 7084 break; 7085 case OMPD_threadprivate: 7086 case OMPD_taskyield: 7087 case OMPD_barrier: 7088 case OMPD_taskwait: 7089 case OMPD_cancellation_point: 7090 case OMPD_flush: 7091 case OMPD_declare_reduction: 7092 case OMPD_declare_simd: 7093 case OMPD_declare_target: 7094 case OMPD_end_declare_target: 7095 case OMPD_simd: 7096 case OMPD_for: 7097 case OMPD_for_simd: 7098 case OMPD_sections: 7099 case OMPD_section: 7100 case OMPD_single: 7101 case OMPD_master: 7102 case OMPD_critical: 7103 case OMPD_taskgroup: 7104 case OMPD_distribute: 7105 case OMPD_ordered: 7106 case OMPD_atomic: 7107 case OMPD_distribute_simd: 7108 llvm_unreachable("Unexpected OpenMP directive with thread_limit-clause"); 7109 case OMPD_unknown: 7110 llvm_unreachable("Unknown OpenMP directive"); 7111 } 7112 break; 7113 case OMPC_schedule: 7114 case OMPC_dist_schedule: 7115 case OMPC_firstprivate: 7116 case OMPC_lastprivate: 7117 case OMPC_reduction: 7118 case OMPC_linear: 7119 case OMPC_default: 7120 case OMPC_proc_bind: 7121 case OMPC_final: 7122 case OMPC_safelen: 7123 case OMPC_simdlen: 7124 case OMPC_collapse: 7125 case OMPC_private: 7126 case OMPC_shared: 7127 case OMPC_aligned: 7128 case OMPC_copyin: 7129 case OMPC_copyprivate: 7130 case OMPC_ordered: 7131 case OMPC_nowait: 7132 case OMPC_untied: 7133 case OMPC_mergeable: 7134 case OMPC_threadprivate: 7135 case OMPC_flush: 7136 case OMPC_read: 7137 case OMPC_write: 7138 case OMPC_update: 7139 case OMPC_capture: 7140 case OMPC_seq_cst: 7141 case OMPC_depend: 7142 case OMPC_device: 7143 case OMPC_threads: 7144 case OMPC_simd: 7145 case OMPC_map: 7146 case OMPC_priority: 7147 case OMPC_grainsize: 7148 case OMPC_nogroup: 7149 case OMPC_num_tasks: 7150 case OMPC_hint: 7151 case OMPC_defaultmap: 7152 case OMPC_unknown: 7153 case OMPC_uniform: 7154 case OMPC_to: 7155 case OMPC_from: 7156 case OMPC_use_device_ptr: 7157 case OMPC_is_device_ptr: 7158 llvm_unreachable("Unexpected OpenMP clause."); 7159 } 7160 return CaptureRegion; 7161 } 7162 7163 OMPClause *Sema::ActOnOpenMPIfClause(OpenMPDirectiveKind NameModifier, 7164 Expr *Condition, SourceLocation StartLoc, 7165 SourceLocation LParenLoc, 7166 SourceLocation NameModifierLoc, 7167 SourceLocation ColonLoc, 7168 SourceLocation EndLoc) { 7169 Expr *ValExpr = Condition; 7170 Stmt *HelperValStmt = nullptr; 7171 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 7172 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 7173 !Condition->isInstantiationDependent() && 7174 !Condition->containsUnexpandedParameterPack()) { 7175 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 7176 if (Val.isInvalid()) 7177 return nullptr; 7178 7179 ValExpr = MakeFullExpr(Val.get()).get(); 7180 7181 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7182 CaptureRegion = 7183 getOpenMPCaptureRegionForClause(DKind, OMPC_if, NameModifier); 7184 if (CaptureRegion != OMPD_unknown) { 7185 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 7186 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 7187 HelperValStmt = buildPreInits(Context, Captures); 7188 } 7189 } 7190 7191 return new (Context) 7192 OMPIfClause(NameModifier, ValExpr, HelperValStmt, CaptureRegion, StartLoc, 7193 LParenLoc, NameModifierLoc, ColonLoc, EndLoc); 7194 } 7195 7196 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 7197 SourceLocation StartLoc, 7198 SourceLocation LParenLoc, 7199 SourceLocation EndLoc) { 7200 Expr *ValExpr = Condition; 7201 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 7202 !Condition->isInstantiationDependent() && 7203 !Condition->containsUnexpandedParameterPack()) { 7204 ExprResult Val = CheckBooleanCondition(StartLoc, Condition); 7205 if (Val.isInvalid()) 7206 return nullptr; 7207 7208 ValExpr = MakeFullExpr(Val.get()).get(); 7209 } 7210 7211 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 7212 } 7213 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 7214 Expr *Op) { 7215 if (!Op) 7216 return ExprError(); 7217 7218 class IntConvertDiagnoser : public ICEConvertDiagnoser { 7219 public: 7220 IntConvertDiagnoser() 7221 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 7222 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 7223 QualType T) override { 7224 return S.Diag(Loc, diag::err_omp_not_integral) << T; 7225 } 7226 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 7227 QualType T) override { 7228 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 7229 } 7230 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 7231 QualType T, 7232 QualType ConvTy) override { 7233 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 7234 } 7235 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 7236 QualType ConvTy) override { 7237 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 7238 << ConvTy->isEnumeralType() << ConvTy; 7239 } 7240 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 7241 QualType T) override { 7242 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 7243 } 7244 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 7245 QualType ConvTy) override { 7246 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 7247 << ConvTy->isEnumeralType() << ConvTy; 7248 } 7249 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 7250 QualType) override { 7251 llvm_unreachable("conversion functions are permitted"); 7252 } 7253 } ConvertDiagnoser; 7254 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 7255 } 7256 7257 static bool IsNonNegativeIntegerValue(Expr *&ValExpr, Sema &SemaRef, 7258 OpenMPClauseKind CKind, 7259 bool StrictlyPositive) { 7260 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 7261 !ValExpr->isInstantiationDependent()) { 7262 SourceLocation Loc = ValExpr->getExprLoc(); 7263 ExprResult Value = 7264 SemaRef.PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 7265 if (Value.isInvalid()) 7266 return false; 7267 7268 ValExpr = Value.get(); 7269 // The expression must evaluate to a non-negative integer value. 7270 llvm::APSInt Result; 7271 if (ValExpr->isIntegerConstantExpr(Result, SemaRef.Context) && 7272 Result.isSigned() && 7273 !((!StrictlyPositive && Result.isNonNegative()) || 7274 (StrictlyPositive && Result.isStrictlyPositive()))) { 7275 SemaRef.Diag(Loc, diag::err_omp_negative_expression_in_clause) 7276 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 7277 << ValExpr->getSourceRange(); 7278 return false; 7279 } 7280 } 7281 return true; 7282 } 7283 7284 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 7285 SourceLocation StartLoc, 7286 SourceLocation LParenLoc, 7287 SourceLocation EndLoc) { 7288 Expr *ValExpr = NumThreads; 7289 Stmt *HelperValStmt = nullptr; 7290 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 7291 7292 // OpenMP [2.5, Restrictions] 7293 // The num_threads expression must evaluate to a positive integer value. 7294 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_threads, 7295 /*StrictlyPositive=*/true)) 7296 return nullptr; 7297 7298 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 7299 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_num_threads); 7300 if (CaptureRegion != OMPD_unknown) { 7301 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 7302 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 7303 HelperValStmt = buildPreInits(Context, Captures); 7304 } 7305 7306 return new (Context) OMPNumThreadsClause( 7307 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 7308 } 7309 7310 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 7311 OpenMPClauseKind CKind, 7312 bool StrictlyPositive) { 7313 if (!E) 7314 return ExprError(); 7315 if (E->isValueDependent() || E->isTypeDependent() || 7316 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 7317 return E; 7318 llvm::APSInt Result; 7319 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 7320 if (ICE.isInvalid()) 7321 return ExprError(); 7322 if ((StrictlyPositive && !Result.isStrictlyPositive()) || 7323 (!StrictlyPositive && !Result.isNonNegative())) { 7324 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 7325 << getOpenMPClauseName(CKind) << (StrictlyPositive ? 1 : 0) 7326 << E->getSourceRange(); 7327 return ExprError(); 7328 } 7329 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 7330 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 7331 << E->getSourceRange(); 7332 return ExprError(); 7333 } 7334 if (CKind == OMPC_collapse && DSAStack->getAssociatedLoops() == 1) 7335 DSAStack->setAssociatedLoops(Result.getExtValue()); 7336 else if (CKind == OMPC_ordered) 7337 DSAStack->setAssociatedLoops(Result.getExtValue()); 7338 return ICE; 7339 } 7340 7341 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 7342 SourceLocation LParenLoc, 7343 SourceLocation EndLoc) { 7344 // OpenMP [2.8.1, simd construct, Description] 7345 // The parameter of the safelen clause must be a constant 7346 // positive integer expression. 7347 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 7348 if (Safelen.isInvalid()) 7349 return nullptr; 7350 return new (Context) 7351 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 7352 } 7353 7354 OMPClause *Sema::ActOnOpenMPSimdlenClause(Expr *Len, SourceLocation StartLoc, 7355 SourceLocation LParenLoc, 7356 SourceLocation EndLoc) { 7357 // OpenMP [2.8.1, simd construct, Description] 7358 // The parameter of the simdlen clause must be a constant 7359 // positive integer expression. 7360 ExprResult Simdlen = VerifyPositiveIntegerConstantInClause(Len, OMPC_simdlen); 7361 if (Simdlen.isInvalid()) 7362 return nullptr; 7363 return new (Context) 7364 OMPSimdlenClause(Simdlen.get(), StartLoc, LParenLoc, EndLoc); 7365 } 7366 7367 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 7368 SourceLocation StartLoc, 7369 SourceLocation LParenLoc, 7370 SourceLocation EndLoc) { 7371 // OpenMP [2.7.1, loop construct, Description] 7372 // OpenMP [2.8.1, simd construct, Description] 7373 // OpenMP [2.9.6, distribute construct, Description] 7374 // The parameter of the collapse clause must be a constant 7375 // positive integer expression. 7376 ExprResult NumForLoopsResult = 7377 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 7378 if (NumForLoopsResult.isInvalid()) 7379 return nullptr; 7380 return new (Context) 7381 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 7382 } 7383 7384 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 7385 SourceLocation EndLoc, 7386 SourceLocation LParenLoc, 7387 Expr *NumForLoops) { 7388 // OpenMP [2.7.1, loop construct, Description] 7389 // OpenMP [2.8.1, simd construct, Description] 7390 // OpenMP [2.9.6, distribute construct, Description] 7391 // The parameter of the ordered clause must be a constant 7392 // positive integer expression if any. 7393 if (NumForLoops && LParenLoc.isValid()) { 7394 ExprResult NumForLoopsResult = 7395 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 7396 if (NumForLoopsResult.isInvalid()) 7397 return nullptr; 7398 NumForLoops = NumForLoopsResult.get(); 7399 } else 7400 NumForLoops = nullptr; 7401 DSAStack->setOrderedRegion(/*IsOrdered=*/true, NumForLoops); 7402 return new (Context) 7403 OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc); 7404 } 7405 7406 OMPClause *Sema::ActOnOpenMPSimpleClause( 7407 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 7408 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 7409 OMPClause *Res = nullptr; 7410 switch (Kind) { 7411 case OMPC_default: 7412 Res = 7413 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 7414 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 7415 break; 7416 case OMPC_proc_bind: 7417 Res = ActOnOpenMPProcBindClause( 7418 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 7419 LParenLoc, EndLoc); 7420 break; 7421 case OMPC_if: 7422 case OMPC_final: 7423 case OMPC_num_threads: 7424 case OMPC_safelen: 7425 case OMPC_simdlen: 7426 case OMPC_collapse: 7427 case OMPC_schedule: 7428 case OMPC_private: 7429 case OMPC_firstprivate: 7430 case OMPC_lastprivate: 7431 case OMPC_shared: 7432 case OMPC_reduction: 7433 case OMPC_linear: 7434 case OMPC_aligned: 7435 case OMPC_copyin: 7436 case OMPC_copyprivate: 7437 case OMPC_ordered: 7438 case OMPC_nowait: 7439 case OMPC_untied: 7440 case OMPC_mergeable: 7441 case OMPC_threadprivate: 7442 case OMPC_flush: 7443 case OMPC_read: 7444 case OMPC_write: 7445 case OMPC_update: 7446 case OMPC_capture: 7447 case OMPC_seq_cst: 7448 case OMPC_depend: 7449 case OMPC_device: 7450 case OMPC_threads: 7451 case OMPC_simd: 7452 case OMPC_map: 7453 case OMPC_num_teams: 7454 case OMPC_thread_limit: 7455 case OMPC_priority: 7456 case OMPC_grainsize: 7457 case OMPC_nogroup: 7458 case OMPC_num_tasks: 7459 case OMPC_hint: 7460 case OMPC_dist_schedule: 7461 case OMPC_defaultmap: 7462 case OMPC_unknown: 7463 case OMPC_uniform: 7464 case OMPC_to: 7465 case OMPC_from: 7466 case OMPC_use_device_ptr: 7467 case OMPC_is_device_ptr: 7468 llvm_unreachable("Clause is not allowed."); 7469 } 7470 return Res; 7471 } 7472 7473 static std::string 7474 getListOfPossibleValues(OpenMPClauseKind K, unsigned First, unsigned Last, 7475 ArrayRef<unsigned> Exclude = llvm::None) { 7476 std::string Values; 7477 unsigned Bound = Last >= 2 ? Last - 2 : 0; 7478 unsigned Skipped = Exclude.size(); 7479 auto S = Exclude.begin(), E = Exclude.end(); 7480 for (unsigned i = First; i < Last; ++i) { 7481 if (std::find(S, E, i) != E) { 7482 --Skipped; 7483 continue; 7484 } 7485 Values += "'"; 7486 Values += getOpenMPSimpleClauseTypeName(K, i); 7487 Values += "'"; 7488 if (i == Bound - Skipped) 7489 Values += " or "; 7490 else if (i != Bound + 1 - Skipped) 7491 Values += ", "; 7492 } 7493 return Values; 7494 } 7495 7496 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 7497 SourceLocation KindKwLoc, 7498 SourceLocation StartLoc, 7499 SourceLocation LParenLoc, 7500 SourceLocation EndLoc) { 7501 if (Kind == OMPC_DEFAULT_unknown) { 7502 static_assert(OMPC_DEFAULT_unknown > 0, 7503 "OMPC_DEFAULT_unknown not greater than 0"); 7504 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 7505 << getListOfPossibleValues(OMPC_default, /*First=*/0, 7506 /*Last=*/OMPC_DEFAULT_unknown) 7507 << getOpenMPClauseName(OMPC_default); 7508 return nullptr; 7509 } 7510 switch (Kind) { 7511 case OMPC_DEFAULT_none: 7512 DSAStack->setDefaultDSANone(KindKwLoc); 7513 break; 7514 case OMPC_DEFAULT_shared: 7515 DSAStack->setDefaultDSAShared(KindKwLoc); 7516 break; 7517 case OMPC_DEFAULT_unknown: 7518 llvm_unreachable("Clause kind is not allowed."); 7519 break; 7520 } 7521 return new (Context) 7522 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 7523 } 7524 7525 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 7526 SourceLocation KindKwLoc, 7527 SourceLocation StartLoc, 7528 SourceLocation LParenLoc, 7529 SourceLocation EndLoc) { 7530 if (Kind == OMPC_PROC_BIND_unknown) { 7531 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 7532 << getListOfPossibleValues(OMPC_proc_bind, /*First=*/0, 7533 /*Last=*/OMPC_PROC_BIND_unknown) 7534 << getOpenMPClauseName(OMPC_proc_bind); 7535 return nullptr; 7536 } 7537 return new (Context) 7538 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 7539 } 7540 7541 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 7542 OpenMPClauseKind Kind, ArrayRef<unsigned> Argument, Expr *Expr, 7543 SourceLocation StartLoc, SourceLocation LParenLoc, 7544 ArrayRef<SourceLocation> ArgumentLoc, SourceLocation DelimLoc, 7545 SourceLocation EndLoc) { 7546 OMPClause *Res = nullptr; 7547 switch (Kind) { 7548 case OMPC_schedule: 7549 enum { Modifier1, Modifier2, ScheduleKind, NumberOfElements }; 7550 assert(Argument.size() == NumberOfElements && 7551 ArgumentLoc.size() == NumberOfElements); 7552 Res = ActOnOpenMPScheduleClause( 7553 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier1]), 7554 static_cast<OpenMPScheduleClauseModifier>(Argument[Modifier2]), 7555 static_cast<OpenMPScheduleClauseKind>(Argument[ScheduleKind]), Expr, 7556 StartLoc, LParenLoc, ArgumentLoc[Modifier1], ArgumentLoc[Modifier2], 7557 ArgumentLoc[ScheduleKind], DelimLoc, EndLoc); 7558 break; 7559 case OMPC_if: 7560 assert(Argument.size() == 1 && ArgumentLoc.size() == 1); 7561 Res = ActOnOpenMPIfClause(static_cast<OpenMPDirectiveKind>(Argument.back()), 7562 Expr, StartLoc, LParenLoc, ArgumentLoc.back(), 7563 DelimLoc, EndLoc); 7564 break; 7565 case OMPC_dist_schedule: 7566 Res = ActOnOpenMPDistScheduleClause( 7567 static_cast<OpenMPDistScheduleClauseKind>(Argument.back()), Expr, 7568 StartLoc, LParenLoc, ArgumentLoc.back(), DelimLoc, EndLoc); 7569 break; 7570 case OMPC_defaultmap: 7571 enum { Modifier, DefaultmapKind }; 7572 Res = ActOnOpenMPDefaultmapClause( 7573 static_cast<OpenMPDefaultmapClauseModifier>(Argument[Modifier]), 7574 static_cast<OpenMPDefaultmapClauseKind>(Argument[DefaultmapKind]), 7575 StartLoc, LParenLoc, ArgumentLoc[Modifier], ArgumentLoc[DefaultmapKind], 7576 EndLoc); 7577 break; 7578 case OMPC_final: 7579 case OMPC_num_threads: 7580 case OMPC_safelen: 7581 case OMPC_simdlen: 7582 case OMPC_collapse: 7583 case OMPC_default: 7584 case OMPC_proc_bind: 7585 case OMPC_private: 7586 case OMPC_firstprivate: 7587 case OMPC_lastprivate: 7588 case OMPC_shared: 7589 case OMPC_reduction: 7590 case OMPC_linear: 7591 case OMPC_aligned: 7592 case OMPC_copyin: 7593 case OMPC_copyprivate: 7594 case OMPC_ordered: 7595 case OMPC_nowait: 7596 case OMPC_untied: 7597 case OMPC_mergeable: 7598 case OMPC_threadprivate: 7599 case OMPC_flush: 7600 case OMPC_read: 7601 case OMPC_write: 7602 case OMPC_update: 7603 case OMPC_capture: 7604 case OMPC_seq_cst: 7605 case OMPC_depend: 7606 case OMPC_device: 7607 case OMPC_threads: 7608 case OMPC_simd: 7609 case OMPC_map: 7610 case OMPC_num_teams: 7611 case OMPC_thread_limit: 7612 case OMPC_priority: 7613 case OMPC_grainsize: 7614 case OMPC_nogroup: 7615 case OMPC_num_tasks: 7616 case OMPC_hint: 7617 case OMPC_unknown: 7618 case OMPC_uniform: 7619 case OMPC_to: 7620 case OMPC_from: 7621 case OMPC_use_device_ptr: 7622 case OMPC_is_device_ptr: 7623 llvm_unreachable("Clause is not allowed."); 7624 } 7625 return Res; 7626 } 7627 7628 static bool checkScheduleModifiers(Sema &S, OpenMPScheduleClauseModifier M1, 7629 OpenMPScheduleClauseModifier M2, 7630 SourceLocation M1Loc, SourceLocation M2Loc) { 7631 if (M1 == OMPC_SCHEDULE_MODIFIER_unknown && M1Loc.isValid()) { 7632 SmallVector<unsigned, 2> Excluded; 7633 if (M2 != OMPC_SCHEDULE_MODIFIER_unknown) 7634 Excluded.push_back(M2); 7635 if (M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) 7636 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_monotonic); 7637 if (M2 == OMPC_SCHEDULE_MODIFIER_monotonic) 7638 Excluded.push_back(OMPC_SCHEDULE_MODIFIER_nonmonotonic); 7639 S.Diag(M1Loc, diag::err_omp_unexpected_clause_value) 7640 << getListOfPossibleValues(OMPC_schedule, 7641 /*First=*/OMPC_SCHEDULE_MODIFIER_unknown + 1, 7642 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 7643 Excluded) 7644 << getOpenMPClauseName(OMPC_schedule); 7645 return true; 7646 } 7647 return false; 7648 } 7649 7650 OMPClause *Sema::ActOnOpenMPScheduleClause( 7651 OpenMPScheduleClauseModifier M1, OpenMPScheduleClauseModifier M2, 7652 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 7653 SourceLocation LParenLoc, SourceLocation M1Loc, SourceLocation M2Loc, 7654 SourceLocation KindLoc, SourceLocation CommaLoc, SourceLocation EndLoc) { 7655 if (checkScheduleModifiers(*this, M1, M2, M1Loc, M2Loc) || 7656 checkScheduleModifiers(*this, M2, M1, M2Loc, M1Loc)) 7657 return nullptr; 7658 // OpenMP, 2.7.1, Loop Construct, Restrictions 7659 // Either the monotonic modifier or the nonmonotonic modifier can be specified 7660 // but not both. 7661 if ((M1 == M2 && M1 != OMPC_SCHEDULE_MODIFIER_unknown) || 7662 (M1 == OMPC_SCHEDULE_MODIFIER_monotonic && 7663 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) || 7664 (M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic && 7665 M2 == OMPC_SCHEDULE_MODIFIER_monotonic)) { 7666 Diag(M2Loc, diag::err_omp_unexpected_schedule_modifier) 7667 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M2) 7668 << getOpenMPSimpleClauseTypeName(OMPC_schedule, M1); 7669 return nullptr; 7670 } 7671 if (Kind == OMPC_SCHEDULE_unknown) { 7672 std::string Values; 7673 if (M1Loc.isInvalid() && M2Loc.isInvalid()) { 7674 unsigned Exclude[] = {OMPC_SCHEDULE_unknown}; 7675 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 7676 /*Last=*/OMPC_SCHEDULE_MODIFIER_last, 7677 Exclude); 7678 } else { 7679 Values = getListOfPossibleValues(OMPC_schedule, /*First=*/0, 7680 /*Last=*/OMPC_SCHEDULE_unknown); 7681 } 7682 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 7683 << Values << getOpenMPClauseName(OMPC_schedule); 7684 return nullptr; 7685 } 7686 // OpenMP, 2.7.1, Loop Construct, Restrictions 7687 // The nonmonotonic modifier can only be specified with schedule(dynamic) or 7688 // schedule(guided). 7689 if ((M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic || 7690 M2 == OMPC_SCHEDULE_MODIFIER_nonmonotonic) && 7691 Kind != OMPC_SCHEDULE_dynamic && Kind != OMPC_SCHEDULE_guided) { 7692 Diag(M1 == OMPC_SCHEDULE_MODIFIER_nonmonotonic ? M1Loc : M2Loc, 7693 diag::err_omp_schedule_nonmonotonic_static); 7694 return nullptr; 7695 } 7696 Expr *ValExpr = ChunkSize; 7697 Stmt *HelperValStmt = nullptr; 7698 if (ChunkSize) { 7699 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 7700 !ChunkSize->isInstantiationDependent() && 7701 !ChunkSize->containsUnexpandedParameterPack()) { 7702 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 7703 ExprResult Val = 7704 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 7705 if (Val.isInvalid()) 7706 return nullptr; 7707 7708 ValExpr = Val.get(); 7709 7710 // OpenMP [2.7.1, Restrictions] 7711 // chunk_size must be a loop invariant integer expression with a positive 7712 // value. 7713 llvm::APSInt Result; 7714 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 7715 if (Result.isSigned() && !Result.isStrictlyPositive()) { 7716 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 7717 << "schedule" << 1 << ChunkSize->getSourceRange(); 7718 return nullptr; 7719 } 7720 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) && 7721 !CurContext->isDependentContext()) { 7722 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 7723 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 7724 HelperValStmt = buildPreInits(Context, Captures); 7725 } 7726 } 7727 } 7728 7729 return new (Context) 7730 OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, Kind, 7731 ValExpr, HelperValStmt, M1, M1Loc, M2, M2Loc); 7732 } 7733 7734 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 7735 SourceLocation StartLoc, 7736 SourceLocation EndLoc) { 7737 OMPClause *Res = nullptr; 7738 switch (Kind) { 7739 case OMPC_ordered: 7740 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 7741 break; 7742 case OMPC_nowait: 7743 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 7744 break; 7745 case OMPC_untied: 7746 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 7747 break; 7748 case OMPC_mergeable: 7749 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 7750 break; 7751 case OMPC_read: 7752 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 7753 break; 7754 case OMPC_write: 7755 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 7756 break; 7757 case OMPC_update: 7758 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 7759 break; 7760 case OMPC_capture: 7761 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 7762 break; 7763 case OMPC_seq_cst: 7764 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 7765 break; 7766 case OMPC_threads: 7767 Res = ActOnOpenMPThreadsClause(StartLoc, EndLoc); 7768 break; 7769 case OMPC_simd: 7770 Res = ActOnOpenMPSIMDClause(StartLoc, EndLoc); 7771 break; 7772 case OMPC_nogroup: 7773 Res = ActOnOpenMPNogroupClause(StartLoc, EndLoc); 7774 break; 7775 case OMPC_if: 7776 case OMPC_final: 7777 case OMPC_num_threads: 7778 case OMPC_safelen: 7779 case OMPC_simdlen: 7780 case OMPC_collapse: 7781 case OMPC_schedule: 7782 case OMPC_private: 7783 case OMPC_firstprivate: 7784 case OMPC_lastprivate: 7785 case OMPC_shared: 7786 case OMPC_reduction: 7787 case OMPC_linear: 7788 case OMPC_aligned: 7789 case OMPC_copyin: 7790 case OMPC_copyprivate: 7791 case OMPC_default: 7792 case OMPC_proc_bind: 7793 case OMPC_threadprivate: 7794 case OMPC_flush: 7795 case OMPC_depend: 7796 case OMPC_device: 7797 case OMPC_map: 7798 case OMPC_num_teams: 7799 case OMPC_thread_limit: 7800 case OMPC_priority: 7801 case OMPC_grainsize: 7802 case OMPC_num_tasks: 7803 case OMPC_hint: 7804 case OMPC_dist_schedule: 7805 case OMPC_defaultmap: 7806 case OMPC_unknown: 7807 case OMPC_uniform: 7808 case OMPC_to: 7809 case OMPC_from: 7810 case OMPC_use_device_ptr: 7811 case OMPC_is_device_ptr: 7812 llvm_unreachable("Clause is not allowed."); 7813 } 7814 return Res; 7815 } 7816 7817 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 7818 SourceLocation EndLoc) { 7819 DSAStack->setNowaitRegion(); 7820 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 7821 } 7822 7823 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 7824 SourceLocation EndLoc) { 7825 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 7826 } 7827 7828 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 7829 SourceLocation EndLoc) { 7830 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 7831 } 7832 7833 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 7834 SourceLocation EndLoc) { 7835 return new (Context) OMPReadClause(StartLoc, EndLoc); 7836 } 7837 7838 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 7839 SourceLocation EndLoc) { 7840 return new (Context) OMPWriteClause(StartLoc, EndLoc); 7841 } 7842 7843 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 7844 SourceLocation EndLoc) { 7845 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 7846 } 7847 7848 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 7849 SourceLocation EndLoc) { 7850 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 7851 } 7852 7853 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 7854 SourceLocation EndLoc) { 7855 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 7856 } 7857 7858 OMPClause *Sema::ActOnOpenMPThreadsClause(SourceLocation StartLoc, 7859 SourceLocation EndLoc) { 7860 return new (Context) OMPThreadsClause(StartLoc, EndLoc); 7861 } 7862 7863 OMPClause *Sema::ActOnOpenMPSIMDClause(SourceLocation StartLoc, 7864 SourceLocation EndLoc) { 7865 return new (Context) OMPSIMDClause(StartLoc, EndLoc); 7866 } 7867 7868 OMPClause *Sema::ActOnOpenMPNogroupClause(SourceLocation StartLoc, 7869 SourceLocation EndLoc) { 7870 return new (Context) OMPNogroupClause(StartLoc, EndLoc); 7871 } 7872 7873 OMPClause *Sema::ActOnOpenMPVarListClause( 7874 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 7875 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 7876 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 7877 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, 7878 OpenMPLinearClauseKind LinKind, OpenMPMapClauseKind MapTypeModifier, 7879 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 7880 SourceLocation DepLinMapLoc) { 7881 OMPClause *Res = nullptr; 7882 switch (Kind) { 7883 case OMPC_private: 7884 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7885 break; 7886 case OMPC_firstprivate: 7887 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7888 break; 7889 case OMPC_lastprivate: 7890 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7891 break; 7892 case OMPC_shared: 7893 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 7894 break; 7895 case OMPC_reduction: 7896 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 7897 EndLoc, ReductionIdScopeSpec, ReductionId); 7898 break; 7899 case OMPC_linear: 7900 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 7901 LinKind, DepLinMapLoc, ColonLoc, EndLoc); 7902 break; 7903 case OMPC_aligned: 7904 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 7905 ColonLoc, EndLoc); 7906 break; 7907 case OMPC_copyin: 7908 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 7909 break; 7910 case OMPC_copyprivate: 7911 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 7912 break; 7913 case OMPC_flush: 7914 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 7915 break; 7916 case OMPC_depend: 7917 Res = ActOnOpenMPDependClause(DepKind, DepLinMapLoc, ColonLoc, VarList, 7918 StartLoc, LParenLoc, EndLoc); 7919 break; 7920 case OMPC_map: 7921 Res = ActOnOpenMPMapClause(MapTypeModifier, MapType, IsMapTypeImplicit, 7922 DepLinMapLoc, ColonLoc, VarList, StartLoc, 7923 LParenLoc, EndLoc); 7924 break; 7925 case OMPC_to: 7926 Res = ActOnOpenMPToClause(VarList, StartLoc, LParenLoc, EndLoc); 7927 break; 7928 case OMPC_from: 7929 Res = ActOnOpenMPFromClause(VarList, StartLoc, LParenLoc, EndLoc); 7930 break; 7931 case OMPC_use_device_ptr: 7932 Res = ActOnOpenMPUseDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); 7933 break; 7934 case OMPC_is_device_ptr: 7935 Res = ActOnOpenMPIsDevicePtrClause(VarList, StartLoc, LParenLoc, EndLoc); 7936 break; 7937 case OMPC_if: 7938 case OMPC_final: 7939 case OMPC_num_threads: 7940 case OMPC_safelen: 7941 case OMPC_simdlen: 7942 case OMPC_collapse: 7943 case OMPC_default: 7944 case OMPC_proc_bind: 7945 case OMPC_schedule: 7946 case OMPC_ordered: 7947 case OMPC_nowait: 7948 case OMPC_untied: 7949 case OMPC_mergeable: 7950 case OMPC_threadprivate: 7951 case OMPC_read: 7952 case OMPC_write: 7953 case OMPC_update: 7954 case OMPC_capture: 7955 case OMPC_seq_cst: 7956 case OMPC_device: 7957 case OMPC_threads: 7958 case OMPC_simd: 7959 case OMPC_num_teams: 7960 case OMPC_thread_limit: 7961 case OMPC_priority: 7962 case OMPC_grainsize: 7963 case OMPC_nogroup: 7964 case OMPC_num_tasks: 7965 case OMPC_hint: 7966 case OMPC_dist_schedule: 7967 case OMPC_defaultmap: 7968 case OMPC_unknown: 7969 case OMPC_uniform: 7970 llvm_unreachable("Clause is not allowed."); 7971 } 7972 return Res; 7973 } 7974 7975 ExprResult Sema::getOpenMPCapturedExpr(VarDecl *Capture, ExprValueKind VK, 7976 ExprObjectKind OK, SourceLocation Loc) { 7977 ExprResult Res = BuildDeclRefExpr( 7978 Capture, Capture->getType().getNonReferenceType(), VK_LValue, Loc); 7979 if (!Res.isUsable()) 7980 return ExprError(); 7981 if (OK == OK_Ordinary && !getLangOpts().CPlusPlus) { 7982 Res = CreateBuiltinUnaryOp(Loc, UO_Deref, Res.get()); 7983 if (!Res.isUsable()) 7984 return ExprError(); 7985 } 7986 if (VK != VK_LValue && Res.get()->isGLValue()) { 7987 Res = DefaultLvalueConversion(Res.get()); 7988 if (!Res.isUsable()) 7989 return ExprError(); 7990 } 7991 return Res; 7992 } 7993 7994 static std::pair<ValueDecl *, bool> 7995 getPrivateItem(Sema &S, Expr *&RefExpr, SourceLocation &ELoc, 7996 SourceRange &ERange, bool AllowArraySection = false) { 7997 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 7998 RefExpr->containsUnexpandedParameterPack()) 7999 return std::make_pair(nullptr, true); 8000 8001 // OpenMP [3.1, C/C++] 8002 // A list item is a variable name. 8003 // OpenMP [2.9.3.3, Restrictions, p.1] 8004 // A variable that is part of another variable (as an array or 8005 // structure element) cannot appear in a private clause. 8006 RefExpr = RefExpr->IgnoreParens(); 8007 enum { 8008 NoArrayExpr = -1, 8009 ArraySubscript = 0, 8010 OMPArraySection = 1 8011 } IsArrayExpr = NoArrayExpr; 8012 if (AllowArraySection) { 8013 if (auto *ASE = dyn_cast_or_null<ArraySubscriptExpr>(RefExpr)) { 8014 auto *Base = ASE->getBase()->IgnoreParenImpCasts(); 8015 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 8016 Base = TempASE->getBase()->IgnoreParenImpCasts(); 8017 RefExpr = Base; 8018 IsArrayExpr = ArraySubscript; 8019 } else if (auto *OASE = dyn_cast_or_null<OMPArraySectionExpr>(RefExpr)) { 8020 auto *Base = OASE->getBase()->IgnoreParenImpCasts(); 8021 while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base)) 8022 Base = TempOASE->getBase()->IgnoreParenImpCasts(); 8023 while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base)) 8024 Base = TempASE->getBase()->IgnoreParenImpCasts(); 8025 RefExpr = Base; 8026 IsArrayExpr = OMPArraySection; 8027 } 8028 } 8029 ELoc = RefExpr->getExprLoc(); 8030 ERange = RefExpr->getSourceRange(); 8031 RefExpr = RefExpr->IgnoreParenImpCasts(); 8032 auto *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 8033 auto *ME = dyn_cast_or_null<MemberExpr>(RefExpr); 8034 if ((!DE || !isa<VarDecl>(DE->getDecl())) && 8035 (S.getCurrentThisType().isNull() || !ME || 8036 !isa<CXXThisExpr>(ME->getBase()->IgnoreParenImpCasts()) || 8037 !isa<FieldDecl>(ME->getMemberDecl()))) { 8038 if (IsArrayExpr != NoArrayExpr) 8039 S.Diag(ELoc, diag::err_omp_expected_base_var_name) << IsArrayExpr 8040 << ERange; 8041 else { 8042 S.Diag(ELoc, 8043 AllowArraySection 8044 ? diag::err_omp_expected_var_name_member_expr_or_array_item 8045 : diag::err_omp_expected_var_name_member_expr) 8046 << (S.getCurrentThisType().isNull() ? 0 : 1) << ERange; 8047 } 8048 return std::make_pair(nullptr, false); 8049 } 8050 return std::make_pair(DE ? DE->getDecl() : ME->getMemberDecl(), false); 8051 } 8052 8053 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 8054 SourceLocation StartLoc, 8055 SourceLocation LParenLoc, 8056 SourceLocation EndLoc) { 8057 SmallVector<Expr *, 8> Vars; 8058 SmallVector<Expr *, 8> PrivateCopies; 8059 for (auto &RefExpr : VarList) { 8060 assert(RefExpr && "NULL expr in OpenMP private clause."); 8061 SourceLocation ELoc; 8062 SourceRange ERange; 8063 Expr *SimpleRefExpr = RefExpr; 8064 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8065 if (Res.second) { 8066 // It will be analyzed later. 8067 Vars.push_back(RefExpr); 8068 PrivateCopies.push_back(nullptr); 8069 } 8070 ValueDecl *D = Res.first; 8071 if (!D) 8072 continue; 8073 8074 QualType Type = D->getType(); 8075 auto *VD = dyn_cast<VarDecl>(D); 8076 8077 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 8078 // A variable that appears in a private clause must not have an incomplete 8079 // type or a reference type. 8080 if (RequireCompleteType(ELoc, Type, diag::err_omp_private_incomplete_type)) 8081 continue; 8082 Type = Type.getNonReferenceType(); 8083 8084 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8085 // in a Construct] 8086 // Variables with the predetermined data-sharing attributes may not be 8087 // listed in data-sharing attributes clauses, except for the cases 8088 // listed below. For these exceptions only, listing a predetermined 8089 // variable in a data-sharing attribute clause is allowed and overrides 8090 // the variable's predetermined data-sharing attributes. 8091 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8092 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 8093 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 8094 << getOpenMPClauseName(OMPC_private); 8095 ReportOriginalDSA(*this, DSAStack, D, DVar); 8096 continue; 8097 } 8098 8099 auto CurrDir = DSAStack->getCurrentDirective(); 8100 // Variably modified types are not supported for tasks. 8101 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 8102 isOpenMPTaskingDirective(CurrDir)) { 8103 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 8104 << getOpenMPClauseName(OMPC_private) << Type 8105 << getOpenMPDirectiveName(CurrDir); 8106 bool IsDecl = 8107 !VD || 8108 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8109 Diag(D->getLocation(), 8110 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8111 << D; 8112 continue; 8113 } 8114 8115 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 8116 // A list item cannot appear in both a map clause and a data-sharing 8117 // attribute clause on the same construct 8118 if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel || 8119 CurrDir == OMPD_target_teams || 8120 CurrDir == OMPD_target_teams_distribute || 8121 CurrDir == OMPD_target_teams_distribute_parallel_for || 8122 CurrDir == OMPD_target_teams_distribute_parallel_for_simd || 8123 CurrDir == OMPD_target_teams_distribute_simd || 8124 CurrDir == OMPD_target_parallel_for_simd || 8125 CurrDir == OMPD_target_parallel_for) { 8126 OpenMPClauseKind ConflictKind; 8127 if (DSAStack->checkMappableExprComponentListsForDecl( 8128 VD, /*CurrentRegionOnly=*/true, 8129 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 8130 OpenMPClauseKind WhereFoundClauseKind) -> bool { 8131 ConflictKind = WhereFoundClauseKind; 8132 return true; 8133 })) { 8134 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 8135 << getOpenMPClauseName(OMPC_private) 8136 << getOpenMPClauseName(ConflictKind) 8137 << getOpenMPDirectiveName(CurrDir); 8138 ReportOriginalDSA(*this, DSAStack, D, DVar); 8139 continue; 8140 } 8141 } 8142 8143 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 8144 // A variable of class type (or array thereof) that appears in a private 8145 // clause requires an accessible, unambiguous default constructor for the 8146 // class type. 8147 // Generate helper private variable and initialize it with the default 8148 // value. The address of the original variable is replaced by the address of 8149 // the new private variable in CodeGen. This new variable is not added to 8150 // IdResolver, so the code in the OpenMP region uses original variable for 8151 // proper diagnostics. 8152 Type = Type.getUnqualifiedType(); 8153 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 8154 D->hasAttrs() ? &D->getAttrs() : nullptr); 8155 ActOnUninitializedDecl(VDPrivate); 8156 if (VDPrivate->isInvalidDecl()) 8157 continue; 8158 auto VDPrivateRefExpr = buildDeclRefExpr( 8159 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 8160 8161 DeclRefExpr *Ref = nullptr; 8162 if (!VD && !CurContext->isDependentContext()) 8163 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 8164 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_private, Ref); 8165 Vars.push_back((VD || CurContext->isDependentContext()) 8166 ? RefExpr->IgnoreParens() 8167 : Ref); 8168 PrivateCopies.push_back(VDPrivateRefExpr); 8169 } 8170 8171 if (Vars.empty()) 8172 return nullptr; 8173 8174 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 8175 PrivateCopies); 8176 } 8177 8178 namespace { 8179 class DiagsUninitializedSeveretyRAII { 8180 private: 8181 DiagnosticsEngine &Diags; 8182 SourceLocation SavedLoc; 8183 bool IsIgnored; 8184 8185 public: 8186 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 8187 bool IsIgnored) 8188 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 8189 if (!IsIgnored) { 8190 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 8191 /*Map*/ diag::Severity::Ignored, Loc); 8192 } 8193 } 8194 ~DiagsUninitializedSeveretyRAII() { 8195 if (!IsIgnored) 8196 Diags.popMappings(SavedLoc); 8197 } 8198 }; 8199 } 8200 8201 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 8202 SourceLocation StartLoc, 8203 SourceLocation LParenLoc, 8204 SourceLocation EndLoc) { 8205 SmallVector<Expr *, 8> Vars; 8206 SmallVector<Expr *, 8> PrivateCopies; 8207 SmallVector<Expr *, 8> Inits; 8208 SmallVector<Decl *, 4> ExprCaptures; 8209 bool IsImplicitClause = 8210 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 8211 auto ImplicitClauseLoc = DSAStack->getConstructLoc(); 8212 8213 for (auto &RefExpr : VarList) { 8214 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 8215 SourceLocation ELoc; 8216 SourceRange ERange; 8217 Expr *SimpleRefExpr = RefExpr; 8218 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8219 if (Res.second) { 8220 // It will be analyzed later. 8221 Vars.push_back(RefExpr); 8222 PrivateCopies.push_back(nullptr); 8223 Inits.push_back(nullptr); 8224 } 8225 ValueDecl *D = Res.first; 8226 if (!D) 8227 continue; 8228 8229 ELoc = IsImplicitClause ? ImplicitClauseLoc : ELoc; 8230 QualType Type = D->getType(); 8231 auto *VD = dyn_cast<VarDecl>(D); 8232 8233 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 8234 // A variable that appears in a private clause must not have an incomplete 8235 // type or a reference type. 8236 if (RequireCompleteType(ELoc, Type, 8237 diag::err_omp_firstprivate_incomplete_type)) 8238 continue; 8239 Type = Type.getNonReferenceType(); 8240 8241 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 8242 // A variable of class type (or array thereof) that appears in a private 8243 // clause requires an accessible, unambiguous copy constructor for the 8244 // class type. 8245 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 8246 8247 // If an implicit firstprivate variable found it was checked already. 8248 DSAStackTy::DSAVarData TopDVar; 8249 if (!IsImplicitClause) { 8250 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8251 TopDVar = DVar; 8252 bool IsConstant = ElemType.isConstant(Context); 8253 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 8254 // A list item that specifies a given variable may not appear in more 8255 // than one clause on the same directive, except that a variable may be 8256 // specified in both firstprivate and lastprivate clauses. 8257 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 8258 DVar.CKind != OMPC_lastprivate && DVar.RefExpr) { 8259 Diag(ELoc, diag::err_omp_wrong_dsa) 8260 << getOpenMPClauseName(DVar.CKind) 8261 << getOpenMPClauseName(OMPC_firstprivate); 8262 ReportOriginalDSA(*this, DSAStack, D, DVar); 8263 continue; 8264 } 8265 8266 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8267 // in a Construct] 8268 // Variables with the predetermined data-sharing attributes may not be 8269 // listed in data-sharing attributes clauses, except for the cases 8270 // listed below. For these exceptions only, listing a predetermined 8271 // variable in a data-sharing attribute clause is allowed and overrides 8272 // the variable's predetermined data-sharing attributes. 8273 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8274 // in a Construct, C/C++, p.2] 8275 // Variables with const-qualified type having no mutable member may be 8276 // listed in a firstprivate clause, even if they are static data members. 8277 if (!(IsConstant || (VD && VD->isStaticDataMember())) && !DVar.RefExpr && 8278 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 8279 Diag(ELoc, diag::err_omp_wrong_dsa) 8280 << getOpenMPClauseName(DVar.CKind) 8281 << getOpenMPClauseName(OMPC_firstprivate); 8282 ReportOriginalDSA(*this, DSAStack, D, DVar); 8283 continue; 8284 } 8285 8286 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 8287 // OpenMP [2.9.3.4, Restrictions, p.2] 8288 // A list item that is private within a parallel region must not appear 8289 // in a firstprivate clause on a worksharing construct if any of the 8290 // worksharing regions arising from the worksharing construct ever bind 8291 // to any of the parallel regions arising from the parallel construct. 8292 if (isOpenMPWorksharingDirective(CurrDir) && 8293 !isOpenMPParallelDirective(CurrDir) && 8294 !isOpenMPTeamsDirective(CurrDir)) { 8295 DVar = DSAStack->getImplicitDSA(D, true); 8296 if (DVar.CKind != OMPC_shared && 8297 (isOpenMPParallelDirective(DVar.DKind) || 8298 DVar.DKind == OMPD_unknown)) { 8299 Diag(ELoc, diag::err_omp_required_access) 8300 << getOpenMPClauseName(OMPC_firstprivate) 8301 << getOpenMPClauseName(OMPC_shared); 8302 ReportOriginalDSA(*this, DSAStack, D, DVar); 8303 continue; 8304 } 8305 } 8306 // OpenMP [2.9.3.4, Restrictions, p.3] 8307 // A list item that appears in a reduction clause of a parallel construct 8308 // must not appear in a firstprivate clause on a worksharing or task 8309 // construct if any of the worksharing or task regions arising from the 8310 // worksharing or task construct ever bind to any of the parallel regions 8311 // arising from the parallel construct. 8312 // OpenMP [2.9.3.4, Restrictions, p.4] 8313 // A list item that appears in a reduction clause in worksharing 8314 // construct must not appear in a firstprivate clause in a task construct 8315 // encountered during execution of any of the worksharing regions arising 8316 // from the worksharing construct. 8317 if (isOpenMPTaskingDirective(CurrDir)) { 8318 DVar = DSAStack->hasInnermostDSA( 8319 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 8320 [](OpenMPDirectiveKind K) -> bool { 8321 return isOpenMPParallelDirective(K) || 8322 isOpenMPWorksharingDirective(K); 8323 }, 8324 false); 8325 if (DVar.CKind == OMPC_reduction && 8326 (isOpenMPParallelDirective(DVar.DKind) || 8327 isOpenMPWorksharingDirective(DVar.DKind))) { 8328 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 8329 << getOpenMPDirectiveName(DVar.DKind); 8330 ReportOriginalDSA(*this, DSAStack, D, DVar); 8331 continue; 8332 } 8333 } 8334 8335 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 8336 // A list item that is private within a teams region must not appear in a 8337 // firstprivate clause on a distribute construct if any of the distribute 8338 // regions arising from the distribute construct ever bind to any of the 8339 // teams regions arising from the teams construct. 8340 // OpenMP 4.5 [2.15.3.4, Restrictions, p.3] 8341 // A list item that appears in a reduction clause of a teams construct 8342 // must not appear in a firstprivate clause on a distribute construct if 8343 // any of the distribute regions arising from the distribute construct 8344 // ever bind to any of the teams regions arising from the teams construct. 8345 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 8346 // A list item may appear in a firstprivate or lastprivate clause but not 8347 // both. 8348 if (CurrDir == OMPD_distribute) { 8349 DVar = DSAStack->hasInnermostDSA( 8350 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_private; }, 8351 [](OpenMPDirectiveKind K) -> bool { 8352 return isOpenMPTeamsDirective(K); 8353 }, 8354 false); 8355 if (DVar.CKind == OMPC_private && isOpenMPTeamsDirective(DVar.DKind)) { 8356 Diag(ELoc, diag::err_omp_firstprivate_distribute_private_teams); 8357 ReportOriginalDSA(*this, DSAStack, D, DVar); 8358 continue; 8359 } 8360 DVar = DSAStack->hasInnermostDSA( 8361 D, [](OpenMPClauseKind C) -> bool { return C == OMPC_reduction; }, 8362 [](OpenMPDirectiveKind K) -> bool { 8363 return isOpenMPTeamsDirective(K); 8364 }, 8365 false); 8366 if (DVar.CKind == OMPC_reduction && 8367 isOpenMPTeamsDirective(DVar.DKind)) { 8368 Diag(ELoc, diag::err_omp_firstprivate_distribute_in_teams_reduction); 8369 ReportOriginalDSA(*this, DSAStack, D, DVar); 8370 continue; 8371 } 8372 DVar = DSAStack->getTopDSA(D, false); 8373 if (DVar.CKind == OMPC_lastprivate) { 8374 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); 8375 ReportOriginalDSA(*this, DSAStack, D, DVar); 8376 continue; 8377 } 8378 } 8379 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 8380 // A list item cannot appear in both a map clause and a data-sharing 8381 // attribute clause on the same construct 8382 if (CurrDir == OMPD_target || CurrDir == OMPD_target_parallel || 8383 CurrDir == OMPD_target_teams || 8384 CurrDir == OMPD_target_teams_distribute || 8385 CurrDir == OMPD_target_teams_distribute_parallel_for || 8386 CurrDir == OMPD_target_teams_distribute_parallel_for_simd || 8387 CurrDir == OMPD_target_teams_distribute_simd || 8388 CurrDir == OMPD_target_parallel_for_simd || 8389 CurrDir == OMPD_target_parallel_for) { 8390 OpenMPClauseKind ConflictKind; 8391 if (DSAStack->checkMappableExprComponentListsForDecl( 8392 VD, /*CurrentRegionOnly=*/true, 8393 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef, 8394 OpenMPClauseKind WhereFoundClauseKind) -> bool { 8395 ConflictKind = WhereFoundClauseKind; 8396 return true; 8397 })) { 8398 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 8399 << getOpenMPClauseName(OMPC_firstprivate) 8400 << getOpenMPClauseName(ConflictKind) 8401 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 8402 ReportOriginalDSA(*this, DSAStack, D, DVar); 8403 continue; 8404 } 8405 } 8406 } 8407 8408 // Variably modified types are not supported for tasks. 8409 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 8410 isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) { 8411 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 8412 << getOpenMPClauseName(OMPC_firstprivate) << Type 8413 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 8414 bool IsDecl = 8415 !VD || 8416 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 8417 Diag(D->getLocation(), 8418 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 8419 << D; 8420 continue; 8421 } 8422 8423 Type = Type.getUnqualifiedType(); 8424 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 8425 D->hasAttrs() ? &D->getAttrs() : nullptr); 8426 // Generate helper private variable and initialize it with the value of the 8427 // original variable. The address of the original variable is replaced by 8428 // the address of the new private variable in the CodeGen. This new variable 8429 // is not added to IdResolver, so the code in the OpenMP region uses 8430 // original variable for proper diagnostics and variable capturing. 8431 Expr *VDInitRefExpr = nullptr; 8432 // For arrays generate initializer for single element and replace it by the 8433 // original array element in CodeGen. 8434 if (Type->isArrayType()) { 8435 auto VDInit = 8436 buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, D->getName()); 8437 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 8438 auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); 8439 ElemType = ElemType.getUnqualifiedType(); 8440 auto *VDInitTemp = buildVarDecl(*this, RefExpr->getExprLoc(), ElemType, 8441 ".firstprivate.temp"); 8442 InitializedEntity Entity = 8443 InitializedEntity::InitializeVariable(VDInitTemp); 8444 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 8445 8446 InitializationSequence InitSeq(*this, Entity, Kind, Init); 8447 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 8448 if (Result.isInvalid()) 8449 VDPrivate->setInvalidDecl(); 8450 else 8451 VDPrivate->setInit(Result.getAs<Expr>()); 8452 // Remove temp variable declaration. 8453 Context.Deallocate(VDInitTemp); 8454 } else { 8455 auto *VDInit = buildVarDecl(*this, RefExpr->getExprLoc(), Type, 8456 ".firstprivate.temp"); 8457 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 8458 RefExpr->getExprLoc()); 8459 AddInitializerToDecl(VDPrivate, 8460 DefaultLvalueConversion(VDInitRefExpr).get(), 8461 /*DirectInit=*/false); 8462 } 8463 if (VDPrivate->isInvalidDecl()) { 8464 if (IsImplicitClause) { 8465 Diag(RefExpr->getExprLoc(), 8466 diag::note_omp_task_predetermined_firstprivate_here); 8467 } 8468 continue; 8469 } 8470 CurContext->addDecl(VDPrivate); 8471 auto VDPrivateRefExpr = buildDeclRefExpr( 8472 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), 8473 RefExpr->getExprLoc()); 8474 DeclRefExpr *Ref = nullptr; 8475 if (!VD && !CurContext->isDependentContext()) { 8476 if (TopDVar.CKind == OMPC_lastprivate) 8477 Ref = TopDVar.PrivateCopy; 8478 else { 8479 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 8480 if (!IsOpenMPCapturedDecl(D)) 8481 ExprCaptures.push_back(Ref->getDecl()); 8482 } 8483 } 8484 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 8485 Vars.push_back((VD || CurContext->isDependentContext()) 8486 ? RefExpr->IgnoreParens() 8487 : Ref); 8488 PrivateCopies.push_back(VDPrivateRefExpr); 8489 Inits.push_back(VDInitRefExpr); 8490 } 8491 8492 if (Vars.empty()) 8493 return nullptr; 8494 8495 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 8496 Vars, PrivateCopies, Inits, 8497 buildPreInits(Context, ExprCaptures)); 8498 } 8499 8500 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 8501 SourceLocation StartLoc, 8502 SourceLocation LParenLoc, 8503 SourceLocation EndLoc) { 8504 SmallVector<Expr *, 8> Vars; 8505 SmallVector<Expr *, 8> SrcExprs; 8506 SmallVector<Expr *, 8> DstExprs; 8507 SmallVector<Expr *, 8> AssignmentOps; 8508 SmallVector<Decl *, 4> ExprCaptures; 8509 SmallVector<Expr *, 4> ExprPostUpdates; 8510 for (auto &RefExpr : VarList) { 8511 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 8512 SourceLocation ELoc; 8513 SourceRange ERange; 8514 Expr *SimpleRefExpr = RefExpr; 8515 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8516 if (Res.second) { 8517 // It will be analyzed later. 8518 Vars.push_back(RefExpr); 8519 SrcExprs.push_back(nullptr); 8520 DstExprs.push_back(nullptr); 8521 AssignmentOps.push_back(nullptr); 8522 } 8523 ValueDecl *D = Res.first; 8524 if (!D) 8525 continue; 8526 8527 QualType Type = D->getType(); 8528 auto *VD = dyn_cast<VarDecl>(D); 8529 8530 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 8531 // A variable that appears in a lastprivate clause must not have an 8532 // incomplete type or a reference type. 8533 if (RequireCompleteType(ELoc, Type, 8534 diag::err_omp_lastprivate_incomplete_type)) 8535 continue; 8536 Type = Type.getNonReferenceType(); 8537 8538 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 8539 // in a Construct] 8540 // Variables with the predetermined data-sharing attributes may not be 8541 // listed in data-sharing attributes clauses, except for the cases 8542 // listed below. 8543 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8544 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 8545 DVar.CKind != OMPC_firstprivate && 8546 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 8547 Diag(ELoc, diag::err_omp_wrong_dsa) 8548 << getOpenMPClauseName(DVar.CKind) 8549 << getOpenMPClauseName(OMPC_lastprivate); 8550 ReportOriginalDSA(*this, DSAStack, D, DVar); 8551 continue; 8552 } 8553 8554 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 8555 // OpenMP [2.14.3.5, Restrictions, p.2] 8556 // A list item that is private within a parallel region, or that appears in 8557 // the reduction clause of a parallel construct, must not appear in a 8558 // lastprivate clause on a worksharing construct if any of the corresponding 8559 // worksharing regions ever binds to any of the corresponding parallel 8560 // regions. 8561 DSAStackTy::DSAVarData TopDVar = DVar; 8562 if (isOpenMPWorksharingDirective(CurrDir) && 8563 !isOpenMPParallelDirective(CurrDir) && 8564 !isOpenMPTeamsDirective(CurrDir)) { 8565 DVar = DSAStack->getImplicitDSA(D, true); 8566 if (DVar.CKind != OMPC_shared) { 8567 Diag(ELoc, diag::err_omp_required_access) 8568 << getOpenMPClauseName(OMPC_lastprivate) 8569 << getOpenMPClauseName(OMPC_shared); 8570 ReportOriginalDSA(*this, DSAStack, D, DVar); 8571 continue; 8572 } 8573 } 8574 8575 // OpenMP 4.5 [2.10.8, Distribute Construct, p.3] 8576 // A list item may appear in a firstprivate or lastprivate clause but not 8577 // both. 8578 if (CurrDir == OMPD_distribute) { 8579 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8580 if (DVar.CKind == OMPC_firstprivate) { 8581 Diag(ELoc, diag::err_omp_firstprivate_and_lastprivate_in_distribute); 8582 ReportOriginalDSA(*this, DSAStack, D, DVar); 8583 continue; 8584 } 8585 } 8586 8587 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 8588 // A variable of class type (or array thereof) that appears in a 8589 // lastprivate clause requires an accessible, unambiguous default 8590 // constructor for the class type, unless the list item is also specified 8591 // in a firstprivate clause. 8592 // A variable of class type (or array thereof) that appears in a 8593 // lastprivate clause requires an accessible, unambiguous copy assignment 8594 // operator for the class type. 8595 Type = Context.getBaseElementType(Type).getNonReferenceType(); 8596 auto *SrcVD = buildVarDecl(*this, ERange.getBegin(), 8597 Type.getUnqualifiedType(), ".lastprivate.src", 8598 D->hasAttrs() ? &D->getAttrs() : nullptr); 8599 auto *PseudoSrcExpr = 8600 buildDeclRefExpr(*this, SrcVD, Type.getUnqualifiedType(), ELoc); 8601 auto *DstVD = 8602 buildVarDecl(*this, ERange.getBegin(), Type, ".lastprivate.dst", 8603 D->hasAttrs() ? &D->getAttrs() : nullptr); 8604 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 8605 // For arrays generate assignment operation for single element and replace 8606 // it by the original array element in CodeGen. 8607 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, ELoc, BO_Assign, 8608 PseudoDstExpr, PseudoSrcExpr); 8609 if (AssignmentOp.isInvalid()) 8610 continue; 8611 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 8612 /*DiscardedValue=*/true); 8613 if (AssignmentOp.isInvalid()) 8614 continue; 8615 8616 DeclRefExpr *Ref = nullptr; 8617 if (!VD && !CurContext->isDependentContext()) { 8618 if (TopDVar.CKind == OMPC_firstprivate) 8619 Ref = TopDVar.PrivateCopy; 8620 else { 8621 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 8622 if (!IsOpenMPCapturedDecl(D)) 8623 ExprCaptures.push_back(Ref->getDecl()); 8624 } 8625 if (TopDVar.CKind == OMPC_firstprivate || 8626 (!IsOpenMPCapturedDecl(D) && 8627 Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>())) { 8628 ExprResult RefRes = DefaultLvalueConversion(Ref); 8629 if (!RefRes.isUsable()) 8630 continue; 8631 ExprResult PostUpdateRes = 8632 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr, 8633 RefRes.get()); 8634 if (!PostUpdateRes.isUsable()) 8635 continue; 8636 ExprPostUpdates.push_back( 8637 IgnoredValueConversions(PostUpdateRes.get()).get()); 8638 } 8639 } 8640 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_lastprivate, Ref); 8641 Vars.push_back((VD || CurContext->isDependentContext()) 8642 ? RefExpr->IgnoreParens() 8643 : Ref); 8644 SrcExprs.push_back(PseudoSrcExpr); 8645 DstExprs.push_back(PseudoDstExpr); 8646 AssignmentOps.push_back(AssignmentOp.get()); 8647 } 8648 8649 if (Vars.empty()) 8650 return nullptr; 8651 8652 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 8653 Vars, SrcExprs, DstExprs, AssignmentOps, 8654 buildPreInits(Context, ExprCaptures), 8655 buildPostUpdate(*this, ExprPostUpdates)); 8656 } 8657 8658 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 8659 SourceLocation StartLoc, 8660 SourceLocation LParenLoc, 8661 SourceLocation EndLoc) { 8662 SmallVector<Expr *, 8> Vars; 8663 for (auto &RefExpr : VarList) { 8664 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 8665 SourceLocation ELoc; 8666 SourceRange ERange; 8667 Expr *SimpleRefExpr = RefExpr; 8668 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 8669 if (Res.second) { 8670 // It will be analyzed later. 8671 Vars.push_back(RefExpr); 8672 } 8673 ValueDecl *D = Res.first; 8674 if (!D) 8675 continue; 8676 8677 auto *VD = dyn_cast<VarDecl>(D); 8678 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 8679 // in a Construct] 8680 // Variables with the predetermined data-sharing attributes may not be 8681 // listed in data-sharing attributes clauses, except for the cases 8682 // listed below. For these exceptions only, listing a predetermined 8683 // variable in a data-sharing attribute clause is allowed and overrides 8684 // the variable's predetermined data-sharing attributes. 8685 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 8686 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 8687 DVar.RefExpr) { 8688 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 8689 << getOpenMPClauseName(OMPC_shared); 8690 ReportOriginalDSA(*this, DSAStack, D, DVar); 8691 continue; 8692 } 8693 8694 DeclRefExpr *Ref = nullptr; 8695 if (!VD && IsOpenMPCapturedDecl(D) && !CurContext->isDependentContext()) 8696 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 8697 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_shared, Ref); 8698 Vars.push_back((VD || !Ref || CurContext->isDependentContext()) 8699 ? RefExpr->IgnoreParens() 8700 : Ref); 8701 } 8702 8703 if (Vars.empty()) 8704 return nullptr; 8705 8706 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 8707 } 8708 8709 namespace { 8710 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 8711 DSAStackTy *Stack; 8712 8713 public: 8714 bool VisitDeclRefExpr(DeclRefExpr *E) { 8715 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { 8716 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false); 8717 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 8718 return false; 8719 if (DVar.CKind != OMPC_unknown) 8720 return true; 8721 DSAStackTy::DSAVarData DVarPrivate = Stack->hasDSA( 8722 VD, isOpenMPPrivate, [](OpenMPDirectiveKind) -> bool { return true; }, 8723 false); 8724 if (DVarPrivate.CKind != OMPC_unknown) 8725 return true; 8726 return false; 8727 } 8728 return false; 8729 } 8730 bool VisitStmt(Stmt *S) { 8731 for (auto Child : S->children()) { 8732 if (Child && Visit(Child)) 8733 return true; 8734 } 8735 return false; 8736 } 8737 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 8738 }; 8739 } // namespace 8740 8741 namespace { 8742 // Transform MemberExpression for specified FieldDecl of current class to 8743 // DeclRefExpr to specified OMPCapturedExprDecl. 8744 class TransformExprToCaptures : public TreeTransform<TransformExprToCaptures> { 8745 typedef TreeTransform<TransformExprToCaptures> BaseTransform; 8746 ValueDecl *Field; 8747 DeclRefExpr *CapturedExpr; 8748 8749 public: 8750 TransformExprToCaptures(Sema &SemaRef, ValueDecl *FieldDecl) 8751 : BaseTransform(SemaRef), Field(FieldDecl), CapturedExpr(nullptr) {} 8752 8753 ExprResult TransformMemberExpr(MemberExpr *E) { 8754 if (isa<CXXThisExpr>(E->getBase()->IgnoreParenImpCasts()) && 8755 E->getMemberDecl() == Field) { 8756 CapturedExpr = buildCapture(SemaRef, Field, E, /*WithInit=*/false); 8757 return CapturedExpr; 8758 } 8759 return BaseTransform::TransformMemberExpr(E); 8760 } 8761 DeclRefExpr *getCapturedExpr() { return CapturedExpr; } 8762 }; 8763 } // namespace 8764 8765 template <typename T> 8766 static T filterLookupForUDR(SmallVectorImpl<UnresolvedSet<8>> &Lookups, 8767 const llvm::function_ref<T(ValueDecl *)> &Gen) { 8768 for (auto &Set : Lookups) { 8769 for (auto *D : Set) { 8770 if (auto Res = Gen(cast<ValueDecl>(D))) 8771 return Res; 8772 } 8773 } 8774 return T(); 8775 } 8776 8777 static ExprResult 8778 buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range, 8779 Scope *S, CXXScopeSpec &ReductionIdScopeSpec, 8780 const DeclarationNameInfo &ReductionId, QualType Ty, 8781 CXXCastPath &BasePath, Expr *UnresolvedReduction) { 8782 if (ReductionIdScopeSpec.isInvalid()) 8783 return ExprError(); 8784 SmallVector<UnresolvedSet<8>, 4> Lookups; 8785 if (S) { 8786 LookupResult Lookup(SemaRef, ReductionId, Sema::LookupOMPReductionName); 8787 Lookup.suppressDiagnostics(); 8788 while (S && SemaRef.LookupParsedName(Lookup, S, &ReductionIdScopeSpec)) { 8789 auto *D = Lookup.getRepresentativeDecl(); 8790 do { 8791 S = S->getParent(); 8792 } while (S && !S->isDeclScope(D)); 8793 if (S) 8794 S = S->getParent(); 8795 Lookups.push_back(UnresolvedSet<8>()); 8796 Lookups.back().append(Lookup.begin(), Lookup.end()); 8797 Lookup.clear(); 8798 } 8799 } else if (auto *ULE = 8800 cast_or_null<UnresolvedLookupExpr>(UnresolvedReduction)) { 8801 Lookups.push_back(UnresolvedSet<8>()); 8802 Decl *PrevD = nullptr; 8803 for (auto *D : ULE->decls()) { 8804 if (D == PrevD) 8805 Lookups.push_back(UnresolvedSet<8>()); 8806 else if (auto *DRD = cast<OMPDeclareReductionDecl>(D)) 8807 Lookups.back().addDecl(DRD); 8808 PrevD = D; 8809 } 8810 } 8811 if (Ty->isDependentType() || Ty->isInstantiationDependentType() || 8812 Ty->containsUnexpandedParameterPack() || 8813 filterLookupForUDR<bool>(Lookups, [](ValueDecl *D) -> bool { 8814 return !D->isInvalidDecl() && 8815 (D->getType()->isDependentType() || 8816 D->getType()->isInstantiationDependentType() || 8817 D->getType()->containsUnexpandedParameterPack()); 8818 })) { 8819 UnresolvedSet<8> ResSet; 8820 for (auto &Set : Lookups) { 8821 ResSet.append(Set.begin(), Set.end()); 8822 // The last item marks the end of all declarations at the specified scope. 8823 ResSet.addDecl(Set[Set.size() - 1]); 8824 } 8825 return UnresolvedLookupExpr::Create( 8826 SemaRef.Context, /*NamingClass=*/nullptr, 8827 ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), ReductionId, 8828 /*ADL=*/true, /*Overloaded=*/true, ResSet.begin(), ResSet.end()); 8829 } 8830 if (auto *VD = filterLookupForUDR<ValueDecl *>( 8831 Lookups, [&SemaRef, Ty](ValueDecl *D) -> ValueDecl * { 8832 if (!D->isInvalidDecl() && 8833 SemaRef.Context.hasSameType(D->getType(), Ty)) 8834 return D; 8835 return nullptr; 8836 })) 8837 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 8838 if (auto *VD = filterLookupForUDR<ValueDecl *>( 8839 Lookups, [&SemaRef, Ty, Loc](ValueDecl *D) -> ValueDecl * { 8840 if (!D->isInvalidDecl() && 8841 SemaRef.IsDerivedFrom(Loc, Ty, D->getType()) && 8842 !Ty.isMoreQualifiedThan(D->getType())) 8843 return D; 8844 return nullptr; 8845 })) { 8846 CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true, 8847 /*DetectVirtual=*/false); 8848 if (SemaRef.IsDerivedFrom(Loc, Ty, VD->getType(), Paths)) { 8849 if (!Paths.isAmbiguous(SemaRef.Context.getCanonicalType( 8850 VD->getType().getUnqualifiedType()))) { 8851 if (SemaRef.CheckBaseClassAccess(Loc, VD->getType(), Ty, Paths.front(), 8852 /*DiagID=*/0) != 8853 Sema::AR_inaccessible) { 8854 SemaRef.BuildBasePathArray(Paths, BasePath); 8855 return SemaRef.BuildDeclRefExpr(VD, Ty, VK_LValue, Loc); 8856 } 8857 } 8858 } 8859 } 8860 if (ReductionIdScopeSpec.isSet()) { 8861 SemaRef.Diag(Loc, diag::err_omp_not_resolved_reduction_identifier) << Range; 8862 return ExprError(); 8863 } 8864 return ExprEmpty(); 8865 } 8866 8867 OMPClause *Sema::ActOnOpenMPReductionClause( 8868 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 8869 SourceLocation ColonLoc, SourceLocation EndLoc, 8870 CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId, 8871 ArrayRef<Expr *> UnresolvedReductions) { 8872 auto DN = ReductionId.getName(); 8873 auto OOK = DN.getCXXOverloadedOperator(); 8874 BinaryOperatorKind BOK = BO_Comma; 8875 8876 // OpenMP [2.14.3.6, reduction clause] 8877 // C 8878 // reduction-identifier is either an identifier or one of the following 8879 // operators: +, -, *, &, |, ^, && and || 8880 // C++ 8881 // reduction-identifier is either an id-expression or one of the following 8882 // operators: +, -, *, &, |, ^, && and || 8883 // FIXME: Only 'min' and 'max' identifiers are supported for now. 8884 switch (OOK) { 8885 case OO_Plus: 8886 case OO_Minus: 8887 BOK = BO_Add; 8888 break; 8889 case OO_Star: 8890 BOK = BO_Mul; 8891 break; 8892 case OO_Amp: 8893 BOK = BO_And; 8894 break; 8895 case OO_Pipe: 8896 BOK = BO_Or; 8897 break; 8898 case OO_Caret: 8899 BOK = BO_Xor; 8900 break; 8901 case OO_AmpAmp: 8902 BOK = BO_LAnd; 8903 break; 8904 case OO_PipePipe: 8905 BOK = BO_LOr; 8906 break; 8907 case OO_New: 8908 case OO_Delete: 8909 case OO_Array_New: 8910 case OO_Array_Delete: 8911 case OO_Slash: 8912 case OO_Percent: 8913 case OO_Tilde: 8914 case OO_Exclaim: 8915 case OO_Equal: 8916 case OO_Less: 8917 case OO_Greater: 8918 case OO_LessEqual: 8919 case OO_GreaterEqual: 8920 case OO_PlusEqual: 8921 case OO_MinusEqual: 8922 case OO_StarEqual: 8923 case OO_SlashEqual: 8924 case OO_PercentEqual: 8925 case OO_CaretEqual: 8926 case OO_AmpEqual: 8927 case OO_PipeEqual: 8928 case OO_LessLess: 8929 case OO_GreaterGreater: 8930 case OO_LessLessEqual: 8931 case OO_GreaterGreaterEqual: 8932 case OO_EqualEqual: 8933 case OO_ExclaimEqual: 8934 case OO_PlusPlus: 8935 case OO_MinusMinus: 8936 case OO_Comma: 8937 case OO_ArrowStar: 8938 case OO_Arrow: 8939 case OO_Call: 8940 case OO_Subscript: 8941 case OO_Conditional: 8942 case OO_Coawait: 8943 case NUM_OVERLOADED_OPERATORS: 8944 llvm_unreachable("Unexpected reduction identifier"); 8945 case OO_None: 8946 if (auto II = DN.getAsIdentifierInfo()) { 8947 if (II->isStr("max")) 8948 BOK = BO_GT; 8949 else if (II->isStr("min")) 8950 BOK = BO_LT; 8951 } 8952 break; 8953 } 8954 SourceRange ReductionIdRange; 8955 if (ReductionIdScopeSpec.isValid()) 8956 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 8957 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 8958 8959 SmallVector<Expr *, 8> Vars; 8960 SmallVector<Expr *, 8> Privates; 8961 SmallVector<Expr *, 8> LHSs; 8962 SmallVector<Expr *, 8> RHSs; 8963 SmallVector<Expr *, 8> ReductionOps; 8964 SmallVector<Decl *, 4> ExprCaptures; 8965 SmallVector<Expr *, 4> ExprPostUpdates; 8966 auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end(); 8967 bool FirstIter = true; 8968 for (auto RefExpr : VarList) { 8969 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 8970 // OpenMP [2.1, C/C++] 8971 // A list item is a variable or array section, subject to the restrictions 8972 // specified in Section 2.4 on page 42 and in each of the sections 8973 // describing clauses and directives for which a list appears. 8974 // OpenMP [2.14.3.3, Restrictions, p.1] 8975 // A variable that is part of another variable (as an array or 8976 // structure element) cannot appear in a private clause. 8977 if (!FirstIter && IR != ER) 8978 ++IR; 8979 FirstIter = false; 8980 SourceLocation ELoc; 8981 SourceRange ERange; 8982 Expr *SimpleRefExpr = RefExpr; 8983 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 8984 /*AllowArraySection=*/true); 8985 if (Res.second) { 8986 // It will be analyzed later. 8987 Vars.push_back(RefExpr); 8988 Privates.push_back(nullptr); 8989 LHSs.push_back(nullptr); 8990 RHSs.push_back(nullptr); 8991 // Try to find 'declare reduction' corresponding construct before using 8992 // builtin/overloaded operators. 8993 QualType Type = Context.DependentTy; 8994 CXXCastPath BasePath; 8995 ExprResult DeclareReductionRef = buildDeclareReductionRef( 8996 *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, 8997 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 8998 if (CurContext->isDependentContext() && 8999 (DeclareReductionRef.isUnset() || 9000 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) 9001 ReductionOps.push_back(DeclareReductionRef.get()); 9002 else 9003 ReductionOps.push_back(nullptr); 9004 } 9005 ValueDecl *D = Res.first; 9006 if (!D) 9007 continue; 9008 9009 QualType Type; 9010 auto *ASE = dyn_cast<ArraySubscriptExpr>(RefExpr->IgnoreParens()); 9011 auto *OASE = dyn_cast<OMPArraySectionExpr>(RefExpr->IgnoreParens()); 9012 if (ASE) 9013 Type = ASE->getType().getNonReferenceType(); 9014 else if (OASE) { 9015 auto BaseType = OMPArraySectionExpr::getBaseOriginalType(OASE->getBase()); 9016 if (auto *ATy = BaseType->getAsArrayTypeUnsafe()) 9017 Type = ATy->getElementType(); 9018 else 9019 Type = BaseType->getPointeeType(); 9020 Type = Type.getNonReferenceType(); 9021 } else 9022 Type = Context.getBaseElementType(D->getType().getNonReferenceType()); 9023 auto *VD = dyn_cast<VarDecl>(D); 9024 9025 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 9026 // A variable that appears in a private clause must not have an incomplete 9027 // type or a reference type. 9028 if (RequireCompleteType(ELoc, Type, 9029 diag::err_omp_reduction_incomplete_type)) 9030 continue; 9031 // OpenMP [2.14.3.6, reduction clause, Restrictions] 9032 // A list item that appears in a reduction clause must not be 9033 // const-qualified. 9034 if (Type.getNonReferenceType().isConstant(Context)) { 9035 Diag(ELoc, diag::err_omp_const_reduction_list_item) 9036 << getOpenMPClauseName(OMPC_reduction) << Type << ERange; 9037 if (!ASE && !OASE) { 9038 bool IsDecl = !VD || 9039 VD->isThisDeclarationADefinition(Context) == 9040 VarDecl::DeclarationOnly; 9041 Diag(D->getLocation(), 9042 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9043 << D; 9044 } 9045 continue; 9046 } 9047 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 9048 // If a list-item is a reference type then it must bind to the same object 9049 // for all threads of the team. 9050 if (!ASE && !OASE && VD) { 9051 VarDecl *VDDef = VD->getDefinition(); 9052 if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) { 9053 DSARefChecker Check(DSAStack); 9054 if (Check.Visit(VDDef->getInit())) { 9055 Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; 9056 Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 9057 continue; 9058 } 9059 } 9060 } 9061 9062 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 9063 // in a Construct] 9064 // Variables with the predetermined data-sharing attributes may not be 9065 // listed in data-sharing attributes clauses, except for the cases 9066 // listed below. For these exceptions only, listing a predetermined 9067 // variable in a data-sharing attribute clause is allowed and overrides 9068 // the variable's predetermined data-sharing attributes. 9069 // OpenMP [2.14.3.6, Restrictions, p.3] 9070 // Any number of reduction clauses can be specified on the directive, 9071 // but a list item can appear only once in the reduction clauses for that 9072 // directive. 9073 DSAStackTy::DSAVarData DVar; 9074 DVar = DSAStack->getTopDSA(D, false); 9075 if (DVar.CKind == OMPC_reduction) { 9076 Diag(ELoc, diag::err_omp_once_referenced) 9077 << getOpenMPClauseName(OMPC_reduction); 9078 if (DVar.RefExpr) 9079 Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 9080 } else if (DVar.CKind != OMPC_unknown) { 9081 Diag(ELoc, diag::err_omp_wrong_dsa) 9082 << getOpenMPClauseName(DVar.CKind) 9083 << getOpenMPClauseName(OMPC_reduction); 9084 ReportOriginalDSA(*this, DSAStack, D, DVar); 9085 continue; 9086 } 9087 9088 // OpenMP [2.14.3.6, Restrictions, p.1] 9089 // A list item that appears in a reduction clause of a worksharing 9090 // construct must be shared in the parallel regions to which any of the 9091 // worksharing regions arising from the worksharing construct bind. 9092 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 9093 if (isOpenMPWorksharingDirective(CurrDir) && 9094 !isOpenMPParallelDirective(CurrDir) && 9095 !isOpenMPTeamsDirective(CurrDir)) { 9096 DVar = DSAStack->getImplicitDSA(D, true); 9097 if (DVar.CKind != OMPC_shared) { 9098 Diag(ELoc, diag::err_omp_required_access) 9099 << getOpenMPClauseName(OMPC_reduction) 9100 << getOpenMPClauseName(OMPC_shared); 9101 ReportOriginalDSA(*this, DSAStack, D, DVar); 9102 continue; 9103 } 9104 } 9105 9106 // Try to find 'declare reduction' corresponding construct before using 9107 // builtin/overloaded operators. 9108 CXXCastPath BasePath; 9109 ExprResult DeclareReductionRef = buildDeclareReductionRef( 9110 *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec, 9111 ReductionId, Type, BasePath, IR == ER ? nullptr : *IR); 9112 if (DeclareReductionRef.isInvalid()) 9113 continue; 9114 if (CurContext->isDependentContext() && 9115 (DeclareReductionRef.isUnset() || 9116 isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) { 9117 Vars.push_back(RefExpr); 9118 Privates.push_back(nullptr); 9119 LHSs.push_back(nullptr); 9120 RHSs.push_back(nullptr); 9121 ReductionOps.push_back(DeclareReductionRef.get()); 9122 continue; 9123 } 9124 if (BOK == BO_Comma && DeclareReductionRef.isUnset()) { 9125 // Not allowed reduction identifier is found. 9126 Diag(ReductionId.getLocStart(), 9127 diag::err_omp_unknown_reduction_identifier) 9128 << Type << ReductionIdRange; 9129 continue; 9130 } 9131 9132 // OpenMP [2.14.3.6, reduction clause, Restrictions] 9133 // The type of a list item that appears in a reduction clause must be valid 9134 // for the reduction-identifier. For a max or min reduction in C, the type 9135 // of the list item must be an allowed arithmetic data type: char, int, 9136 // float, double, or _Bool, possibly modified with long, short, signed, or 9137 // unsigned. For a max or min reduction in C++, the type of the list item 9138 // must be an allowed arithmetic data type: char, wchar_t, int, float, 9139 // double, or bool, possibly modified with long, short, signed, or unsigned. 9140 if (DeclareReductionRef.isUnset()) { 9141 if ((BOK == BO_GT || BOK == BO_LT) && 9142 !(Type->isScalarType() || 9143 (getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 9144 Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 9145 << getLangOpts().CPlusPlus; 9146 if (!ASE && !OASE) { 9147 bool IsDecl = !VD || 9148 VD->isThisDeclarationADefinition(Context) == 9149 VarDecl::DeclarationOnly; 9150 Diag(D->getLocation(), 9151 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9152 << D; 9153 } 9154 continue; 9155 } 9156 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 9157 !getLangOpts().CPlusPlus && Type->isFloatingType()) { 9158 Diag(ELoc, diag::err_omp_clause_floating_type_arg); 9159 if (!ASE && !OASE) { 9160 bool IsDecl = !VD || 9161 VD->isThisDeclarationADefinition(Context) == 9162 VarDecl::DeclarationOnly; 9163 Diag(D->getLocation(), 9164 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9165 << D; 9166 } 9167 continue; 9168 } 9169 } 9170 9171 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 9172 auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs", 9173 D->hasAttrs() ? &D->getAttrs() : nullptr); 9174 auto *RHSVD = buildVarDecl(*this, ELoc, Type, D->getName(), 9175 D->hasAttrs() ? &D->getAttrs() : nullptr); 9176 auto PrivateTy = Type; 9177 if (OASE || 9178 (!ASE && 9179 D->getType().getNonReferenceType()->isVariablyModifiedType())) { 9180 // For arrays/array sections only: 9181 // Create pseudo array type for private copy. The size for this array will 9182 // be generated during codegen. 9183 // For array subscripts or single variables Private Ty is the same as Type 9184 // (type of the variable or single array element). 9185 PrivateTy = Context.getVariableArrayType( 9186 Type, new (Context) OpaqueValueExpr(SourceLocation(), 9187 Context.getSizeType(), VK_RValue), 9188 ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange()); 9189 } else if (!ASE && !OASE && 9190 Context.getAsArrayType(D->getType().getNonReferenceType())) 9191 PrivateTy = D->getType().getNonReferenceType(); 9192 // Private copy. 9193 auto *PrivateVD = buildVarDecl(*this, ELoc, PrivateTy, D->getName(), 9194 D->hasAttrs() ? &D->getAttrs() : nullptr); 9195 // Add initializer for private variable. 9196 Expr *Init = nullptr; 9197 auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc); 9198 auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc); 9199 if (DeclareReductionRef.isUsable()) { 9200 auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>(); 9201 auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl()); 9202 if (DRD->getInitializer()) { 9203 Init = DRDRef; 9204 RHSVD->setInit(DRDRef); 9205 RHSVD->setInitStyle(VarDecl::CallInit); 9206 } 9207 } else { 9208 switch (BOK) { 9209 case BO_Add: 9210 case BO_Xor: 9211 case BO_Or: 9212 case BO_LOr: 9213 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 9214 if (Type->isScalarType() || Type->isAnyComplexType()) 9215 Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 9216 break; 9217 case BO_Mul: 9218 case BO_LAnd: 9219 if (Type->isScalarType() || Type->isAnyComplexType()) { 9220 // '*' and '&&' reduction ops - initializer is '1'. 9221 Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 9222 } 9223 break; 9224 case BO_And: { 9225 // '&' reduction op - initializer is '~0'. 9226 QualType OrigType = Type; 9227 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) 9228 Type = ComplexTy->getElementType(); 9229 if (Type->isRealFloatingType()) { 9230 llvm::APFloat InitValue = 9231 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 9232 /*isIEEE=*/true); 9233 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 9234 Type, ELoc); 9235 } else if (Type->isScalarType()) { 9236 auto Size = Context.getTypeSize(Type); 9237 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 9238 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 9239 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 9240 } 9241 if (Init && OrigType->isAnyComplexType()) { 9242 // Init = 0xFFFF + 0xFFFFi; 9243 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 9244 Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 9245 } 9246 Type = OrigType; 9247 break; 9248 } 9249 case BO_LT: 9250 case BO_GT: { 9251 // 'min' reduction op - initializer is 'Largest representable number in 9252 // the reduction list item type'. 9253 // 'max' reduction op - initializer is 'Least representable number in 9254 // the reduction list item type'. 9255 if (Type->isIntegerType() || Type->isPointerType()) { 9256 bool IsSigned = Type->hasSignedIntegerRepresentation(); 9257 auto Size = Context.getTypeSize(Type); 9258 QualType IntTy = 9259 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 9260 llvm::APInt InitValue = 9261 (BOK != BO_LT) 9262 ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 9263 : llvm::APInt::getMinValue(Size) 9264 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 9265 : llvm::APInt::getMaxValue(Size); 9266 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 9267 if (Type->isPointerType()) { 9268 // Cast to pointer type. 9269 auto CastExpr = BuildCStyleCastExpr( 9270 SourceLocation(), Context.getTrivialTypeSourceInfo(Type, ELoc), 9271 SourceLocation(), Init); 9272 if (CastExpr.isInvalid()) 9273 continue; 9274 Init = CastExpr.get(); 9275 } 9276 } else if (Type->isRealFloatingType()) { 9277 llvm::APFloat InitValue = llvm::APFloat::getLargest( 9278 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 9279 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 9280 Type, ELoc); 9281 } 9282 break; 9283 } 9284 case BO_PtrMemD: 9285 case BO_PtrMemI: 9286 case BO_MulAssign: 9287 case BO_Div: 9288 case BO_Rem: 9289 case BO_Sub: 9290 case BO_Shl: 9291 case BO_Shr: 9292 case BO_LE: 9293 case BO_GE: 9294 case BO_EQ: 9295 case BO_NE: 9296 case BO_AndAssign: 9297 case BO_XorAssign: 9298 case BO_OrAssign: 9299 case BO_Assign: 9300 case BO_AddAssign: 9301 case BO_SubAssign: 9302 case BO_DivAssign: 9303 case BO_RemAssign: 9304 case BO_ShlAssign: 9305 case BO_ShrAssign: 9306 case BO_Comma: 9307 llvm_unreachable("Unexpected reduction operation"); 9308 } 9309 } 9310 if (Init && DeclareReductionRef.isUnset()) { 9311 AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false); 9312 } else if (!Init) 9313 ActOnUninitializedDecl(RHSVD); 9314 if (RHSVD->isInvalidDecl()) 9315 continue; 9316 if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) { 9317 Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type 9318 << ReductionIdRange; 9319 bool IsDecl = 9320 !VD || 9321 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9322 Diag(D->getLocation(), 9323 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9324 << D; 9325 continue; 9326 } 9327 // Store initializer for single element in private copy. Will be used during 9328 // codegen. 9329 PrivateVD->setInit(RHSVD->getInit()); 9330 PrivateVD->setInitStyle(RHSVD->getInitStyle()); 9331 auto *PrivateDRE = buildDeclRefExpr(*this, PrivateVD, PrivateTy, ELoc); 9332 ExprResult ReductionOp; 9333 if (DeclareReductionRef.isUsable()) { 9334 QualType RedTy = DeclareReductionRef.get()->getType(); 9335 QualType PtrRedTy = Context.getPointerType(RedTy); 9336 ExprResult LHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE); 9337 ExprResult RHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE); 9338 if (!BasePath.empty()) { 9339 LHS = DefaultLvalueConversion(LHS.get()); 9340 RHS = DefaultLvalueConversion(RHS.get()); 9341 LHS = ImplicitCastExpr::Create(Context, PtrRedTy, 9342 CK_UncheckedDerivedToBase, LHS.get(), 9343 &BasePath, LHS.get()->getValueKind()); 9344 RHS = ImplicitCastExpr::Create(Context, PtrRedTy, 9345 CK_UncheckedDerivedToBase, RHS.get(), 9346 &BasePath, RHS.get()->getValueKind()); 9347 } 9348 FunctionProtoType::ExtProtoInfo EPI; 9349 QualType Params[] = {PtrRedTy, PtrRedTy}; 9350 QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI); 9351 auto *OVE = new (Context) OpaqueValueExpr( 9352 ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary, 9353 DefaultLvalueConversion(DeclareReductionRef.get()).get()); 9354 Expr *Args[] = {LHS.get(), RHS.get()}; 9355 ReductionOp = new (Context) 9356 CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc); 9357 } else { 9358 ReductionOp = BuildBinOp(DSAStack->getCurScope(), 9359 ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE); 9360 if (ReductionOp.isUsable()) { 9361 if (BOK != BO_LT && BOK != BO_GT) { 9362 ReductionOp = 9363 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 9364 BO_Assign, LHSDRE, ReductionOp.get()); 9365 } else { 9366 auto *ConditionalOp = new (Context) ConditionalOperator( 9367 ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(), 9368 RHSDRE, Type, VK_LValue, OK_Ordinary); 9369 ReductionOp = 9370 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 9371 BO_Assign, LHSDRE, ConditionalOp); 9372 } 9373 ReductionOp = ActOnFinishFullExpr(ReductionOp.get()); 9374 } 9375 if (ReductionOp.isInvalid()) 9376 continue; 9377 } 9378 9379 DeclRefExpr *Ref = nullptr; 9380 Expr *VarsExpr = RefExpr->IgnoreParens(); 9381 if (!VD && !CurContext->isDependentContext()) { 9382 if (ASE || OASE) { 9383 TransformExprToCaptures RebuildToCapture(*this, D); 9384 VarsExpr = 9385 RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get(); 9386 Ref = RebuildToCapture.getCapturedExpr(); 9387 } else { 9388 VarsExpr = Ref = 9389 buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 9390 } 9391 if (!IsOpenMPCapturedDecl(D)) { 9392 ExprCaptures.push_back(Ref->getDecl()); 9393 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 9394 ExprResult RefRes = DefaultLvalueConversion(Ref); 9395 if (!RefRes.isUsable()) 9396 continue; 9397 ExprResult PostUpdateRes = 9398 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 9399 SimpleRefExpr, RefRes.get()); 9400 if (!PostUpdateRes.isUsable()) 9401 continue; 9402 ExprPostUpdates.push_back( 9403 IgnoredValueConversions(PostUpdateRes.get()).get()); 9404 } 9405 } 9406 } 9407 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref); 9408 Vars.push_back(VarsExpr); 9409 Privates.push_back(PrivateDRE); 9410 LHSs.push_back(LHSDRE); 9411 RHSs.push_back(RHSDRE); 9412 ReductionOps.push_back(ReductionOp.get()); 9413 } 9414 9415 if (Vars.empty()) 9416 return nullptr; 9417 9418 return OMPReductionClause::Create( 9419 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars, 9420 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates, 9421 LHSs, RHSs, ReductionOps, buildPreInits(Context, ExprCaptures), 9422 buildPostUpdate(*this, ExprPostUpdates)); 9423 } 9424 9425 bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind, 9426 SourceLocation LinLoc) { 9427 if ((!LangOpts.CPlusPlus && LinKind != OMPC_LINEAR_val) || 9428 LinKind == OMPC_LINEAR_unknown) { 9429 Diag(LinLoc, diag::err_omp_wrong_linear_modifier) << LangOpts.CPlusPlus; 9430 return true; 9431 } 9432 return false; 9433 } 9434 9435 bool Sema::CheckOpenMPLinearDecl(ValueDecl *D, SourceLocation ELoc, 9436 OpenMPLinearClauseKind LinKind, 9437 QualType Type) { 9438 auto *VD = dyn_cast_or_null<VarDecl>(D); 9439 // A variable must not have an incomplete type or a reference type. 9440 if (RequireCompleteType(ELoc, Type, diag::err_omp_linear_incomplete_type)) 9441 return true; 9442 if ((LinKind == OMPC_LINEAR_uval || LinKind == OMPC_LINEAR_ref) && 9443 !Type->isReferenceType()) { 9444 Diag(ELoc, diag::err_omp_wrong_linear_modifier_non_reference) 9445 << Type << getOpenMPSimpleClauseTypeName(OMPC_linear, LinKind); 9446 return true; 9447 } 9448 Type = Type.getNonReferenceType(); 9449 9450 // A list item must not be const-qualified. 9451 if (Type.isConstant(Context)) { 9452 Diag(ELoc, diag::err_omp_const_variable) 9453 << getOpenMPClauseName(OMPC_linear); 9454 if (D) { 9455 bool IsDecl = 9456 !VD || 9457 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9458 Diag(D->getLocation(), 9459 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9460 << D; 9461 } 9462 return true; 9463 } 9464 9465 // A list item must be of integral or pointer type. 9466 Type = Type.getUnqualifiedType().getCanonicalType(); 9467 const auto *Ty = Type.getTypePtrOrNull(); 9468 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 9469 !Ty->isPointerType())) { 9470 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << Type; 9471 if (D) { 9472 bool IsDecl = 9473 !VD || 9474 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9475 Diag(D->getLocation(), 9476 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9477 << D; 9478 } 9479 return true; 9480 } 9481 return false; 9482 } 9483 9484 OMPClause *Sema::ActOnOpenMPLinearClause( 9485 ArrayRef<Expr *> VarList, Expr *Step, SourceLocation StartLoc, 9486 SourceLocation LParenLoc, OpenMPLinearClauseKind LinKind, 9487 SourceLocation LinLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 9488 SmallVector<Expr *, 8> Vars; 9489 SmallVector<Expr *, 8> Privates; 9490 SmallVector<Expr *, 8> Inits; 9491 SmallVector<Decl *, 4> ExprCaptures; 9492 SmallVector<Expr *, 4> ExprPostUpdates; 9493 if (CheckOpenMPLinearModifier(LinKind, LinLoc)) 9494 LinKind = OMPC_LINEAR_val; 9495 for (auto &RefExpr : VarList) { 9496 assert(RefExpr && "NULL expr in OpenMP linear clause."); 9497 SourceLocation ELoc; 9498 SourceRange ERange; 9499 Expr *SimpleRefExpr = RefExpr; 9500 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 9501 /*AllowArraySection=*/false); 9502 if (Res.second) { 9503 // It will be analyzed later. 9504 Vars.push_back(RefExpr); 9505 Privates.push_back(nullptr); 9506 Inits.push_back(nullptr); 9507 } 9508 ValueDecl *D = Res.first; 9509 if (!D) 9510 continue; 9511 9512 QualType Type = D->getType(); 9513 auto *VD = dyn_cast<VarDecl>(D); 9514 9515 // OpenMP [2.14.3.7, linear clause] 9516 // A list-item cannot appear in more than one linear clause. 9517 // A list-item that appears in a linear clause cannot appear in any 9518 // other data-sharing attribute clause. 9519 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(D, false); 9520 if (DVar.RefExpr) { 9521 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 9522 << getOpenMPClauseName(OMPC_linear); 9523 ReportOriginalDSA(*this, DSAStack, D, DVar); 9524 continue; 9525 } 9526 9527 if (CheckOpenMPLinearDecl(D, ELoc, LinKind, Type)) 9528 continue; 9529 Type = Type.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 9530 9531 // Build private copy of original var. 9532 auto *Private = buildVarDecl(*this, ELoc, Type, D->getName(), 9533 D->hasAttrs() ? &D->getAttrs() : nullptr); 9534 auto *PrivateRef = buildDeclRefExpr(*this, Private, Type, ELoc); 9535 // Build var to save initial value. 9536 VarDecl *Init = buildVarDecl(*this, ELoc, Type, ".linear.start"); 9537 Expr *InitExpr; 9538 DeclRefExpr *Ref = nullptr; 9539 if (!VD && !CurContext->isDependentContext()) { 9540 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false); 9541 if (!IsOpenMPCapturedDecl(D)) { 9542 ExprCaptures.push_back(Ref->getDecl()); 9543 if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) { 9544 ExprResult RefRes = DefaultLvalueConversion(Ref); 9545 if (!RefRes.isUsable()) 9546 continue; 9547 ExprResult PostUpdateRes = 9548 BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 9549 SimpleRefExpr, RefRes.get()); 9550 if (!PostUpdateRes.isUsable()) 9551 continue; 9552 ExprPostUpdates.push_back( 9553 IgnoredValueConversions(PostUpdateRes.get()).get()); 9554 } 9555 } 9556 } 9557 if (LinKind == OMPC_LINEAR_uval) 9558 InitExpr = VD ? VD->getInit() : SimpleRefExpr; 9559 else 9560 InitExpr = VD ? SimpleRefExpr : Ref; 9561 AddInitializerToDecl(Init, DefaultLvalueConversion(InitExpr).get(), 9562 /*DirectInit=*/false); 9563 auto InitRef = buildDeclRefExpr(*this, Init, Type, ELoc); 9564 9565 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_linear, Ref); 9566 Vars.push_back((VD || CurContext->isDependentContext()) 9567 ? RefExpr->IgnoreParens() 9568 : Ref); 9569 Privates.push_back(PrivateRef); 9570 Inits.push_back(InitRef); 9571 } 9572 9573 if (Vars.empty()) 9574 return nullptr; 9575 9576 Expr *StepExpr = Step; 9577 Expr *CalcStepExpr = nullptr; 9578 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 9579 !Step->isInstantiationDependent() && 9580 !Step->containsUnexpandedParameterPack()) { 9581 SourceLocation StepLoc = Step->getLocStart(); 9582 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 9583 if (Val.isInvalid()) 9584 return nullptr; 9585 StepExpr = Val.get(); 9586 9587 // Build var to save the step value. 9588 VarDecl *SaveVar = 9589 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 9590 ExprResult SaveRef = 9591 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 9592 ExprResult CalcStep = 9593 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 9594 CalcStep = ActOnFinishFullExpr(CalcStep.get()); 9595 9596 // Warn about zero linear step (it would be probably better specified as 9597 // making corresponding variables 'const'). 9598 llvm::APSInt Result; 9599 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 9600 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 9601 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 9602 << (Vars.size() > 1); 9603 if (!IsConstant && CalcStep.isUsable()) { 9604 // Calculate the step beforehand instead of doing this on each iteration. 9605 // (This is not used if the number of iterations may be kfold-ed). 9606 CalcStepExpr = CalcStep.get(); 9607 } 9608 } 9609 9610 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, LinKind, LinLoc, 9611 ColonLoc, EndLoc, Vars, Privates, Inits, 9612 StepExpr, CalcStepExpr, 9613 buildPreInits(Context, ExprCaptures), 9614 buildPostUpdate(*this, ExprPostUpdates)); 9615 } 9616 9617 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 9618 Expr *NumIterations, Sema &SemaRef, 9619 Scope *S, DSAStackTy *Stack) { 9620 // Walk the vars and build update/final expressions for the CodeGen. 9621 SmallVector<Expr *, 8> Updates; 9622 SmallVector<Expr *, 8> Finals; 9623 Expr *Step = Clause.getStep(); 9624 Expr *CalcStep = Clause.getCalcStep(); 9625 // OpenMP [2.14.3.7, linear clause] 9626 // If linear-step is not specified it is assumed to be 1. 9627 if (Step == nullptr) 9628 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 9629 else if (CalcStep) { 9630 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 9631 } 9632 bool HasErrors = false; 9633 auto CurInit = Clause.inits().begin(); 9634 auto CurPrivate = Clause.privates().begin(); 9635 auto LinKind = Clause.getModifier(); 9636 for (auto &RefExpr : Clause.varlists()) { 9637 SourceLocation ELoc; 9638 SourceRange ERange; 9639 Expr *SimpleRefExpr = RefExpr; 9640 auto Res = getPrivateItem(SemaRef, SimpleRefExpr, ELoc, ERange, 9641 /*AllowArraySection=*/false); 9642 ValueDecl *D = Res.first; 9643 if (Res.second || !D) { 9644 Updates.push_back(nullptr); 9645 Finals.push_back(nullptr); 9646 HasErrors = true; 9647 continue; 9648 } 9649 if (auto *CED = dyn_cast<OMPCapturedExprDecl>(D)) { 9650 D = cast<MemberExpr>(CED->getInit()->IgnoreParenImpCasts()) 9651 ->getMemberDecl(); 9652 } 9653 auto &&Info = Stack->isLoopControlVariable(D); 9654 Expr *InitExpr = *CurInit; 9655 9656 // Build privatized reference to the current linear var. 9657 auto *DE = cast<DeclRefExpr>(SimpleRefExpr); 9658 Expr *CapturedRef; 9659 if (LinKind == OMPC_LINEAR_uval) 9660 CapturedRef = cast<VarDecl>(DE->getDecl())->getInit(); 9661 else 9662 CapturedRef = 9663 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 9664 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 9665 /*RefersToCapture=*/true); 9666 9667 // Build update: Var = InitExpr + IV * Step 9668 ExprResult Update; 9669 if (!Info.first) { 9670 Update = 9671 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), *CurPrivate, 9672 InitExpr, IV, Step, /* Subtract */ false); 9673 } else 9674 Update = *CurPrivate; 9675 Update = SemaRef.ActOnFinishFullExpr(Update.get(), DE->getLocStart(), 9676 /*DiscardedValue=*/true); 9677 9678 // Build final: Var = InitExpr + NumIterations * Step 9679 ExprResult Final; 9680 if (!Info.first) { 9681 Final = BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), CapturedRef, 9682 InitExpr, NumIterations, Step, 9683 /* Subtract */ false); 9684 } else 9685 Final = *CurPrivate; 9686 Final = SemaRef.ActOnFinishFullExpr(Final.get(), DE->getLocStart(), 9687 /*DiscardedValue=*/true); 9688 9689 if (!Update.isUsable() || !Final.isUsable()) { 9690 Updates.push_back(nullptr); 9691 Finals.push_back(nullptr); 9692 HasErrors = true; 9693 } else { 9694 Updates.push_back(Update.get()); 9695 Finals.push_back(Final.get()); 9696 } 9697 ++CurInit; 9698 ++CurPrivate; 9699 } 9700 Clause.setUpdates(Updates); 9701 Clause.setFinals(Finals); 9702 return HasErrors; 9703 } 9704 9705 OMPClause *Sema::ActOnOpenMPAlignedClause( 9706 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 9707 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 9708 9709 SmallVector<Expr *, 8> Vars; 9710 for (auto &RefExpr : VarList) { 9711 assert(RefExpr && "NULL expr in OpenMP linear clause."); 9712 SourceLocation ELoc; 9713 SourceRange ERange; 9714 Expr *SimpleRefExpr = RefExpr; 9715 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 9716 /*AllowArraySection=*/false); 9717 if (Res.second) { 9718 // It will be analyzed later. 9719 Vars.push_back(RefExpr); 9720 } 9721 ValueDecl *D = Res.first; 9722 if (!D) 9723 continue; 9724 9725 QualType QType = D->getType(); 9726 auto *VD = dyn_cast<VarDecl>(D); 9727 9728 // OpenMP [2.8.1, simd construct, Restrictions] 9729 // The type of list items appearing in the aligned clause must be 9730 // array, pointer, reference to array, or reference to pointer. 9731 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 9732 const Type *Ty = QType.getTypePtrOrNull(); 9733 if (!Ty || (!Ty->isArrayType() && !Ty->isPointerType())) { 9734 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 9735 << QType << getLangOpts().CPlusPlus << ERange; 9736 bool IsDecl = 9737 !VD || 9738 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9739 Diag(D->getLocation(), 9740 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9741 << D; 9742 continue; 9743 } 9744 9745 // OpenMP [2.8.1, simd construct, Restrictions] 9746 // A list-item cannot appear in more than one aligned clause. 9747 if (Expr *PrevRef = DSAStack->addUniqueAligned(D, SimpleRefExpr)) { 9748 Diag(ELoc, diag::err_omp_aligned_twice) << 0 << ERange; 9749 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 9750 << getOpenMPClauseName(OMPC_aligned); 9751 continue; 9752 } 9753 9754 DeclRefExpr *Ref = nullptr; 9755 if (!VD && IsOpenMPCapturedDecl(D)) 9756 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 9757 Vars.push_back(DefaultFunctionArrayConversion( 9758 (VD || !Ref) ? RefExpr->IgnoreParens() : Ref) 9759 .get()); 9760 } 9761 9762 // OpenMP [2.8.1, simd construct, Description] 9763 // The parameter of the aligned clause, alignment, must be a constant 9764 // positive integer expression. 9765 // If no optional parameter is specified, implementation-defined default 9766 // alignments for SIMD instructions on the target platforms are assumed. 9767 if (Alignment != nullptr) { 9768 ExprResult AlignResult = 9769 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 9770 if (AlignResult.isInvalid()) 9771 return nullptr; 9772 Alignment = AlignResult.get(); 9773 } 9774 if (Vars.empty()) 9775 return nullptr; 9776 9777 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 9778 EndLoc, Vars, Alignment); 9779 } 9780 9781 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 9782 SourceLocation StartLoc, 9783 SourceLocation LParenLoc, 9784 SourceLocation EndLoc) { 9785 SmallVector<Expr *, 8> Vars; 9786 SmallVector<Expr *, 8> SrcExprs; 9787 SmallVector<Expr *, 8> DstExprs; 9788 SmallVector<Expr *, 8> AssignmentOps; 9789 for (auto &RefExpr : VarList) { 9790 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 9791 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 9792 // It will be analyzed later. 9793 Vars.push_back(RefExpr); 9794 SrcExprs.push_back(nullptr); 9795 DstExprs.push_back(nullptr); 9796 AssignmentOps.push_back(nullptr); 9797 continue; 9798 } 9799 9800 SourceLocation ELoc = RefExpr->getExprLoc(); 9801 // OpenMP [2.1, C/C++] 9802 // A list item is a variable name. 9803 // OpenMP [2.14.4.1, Restrictions, p.1] 9804 // A list item that appears in a copyin clause must be threadprivate. 9805 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 9806 if (!DE || !isa<VarDecl>(DE->getDecl())) { 9807 Diag(ELoc, diag::err_omp_expected_var_name_member_expr) 9808 << 0 << RefExpr->getSourceRange(); 9809 continue; 9810 } 9811 9812 Decl *D = DE->getDecl(); 9813 VarDecl *VD = cast<VarDecl>(D); 9814 9815 QualType Type = VD->getType(); 9816 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 9817 // It will be analyzed later. 9818 Vars.push_back(DE); 9819 SrcExprs.push_back(nullptr); 9820 DstExprs.push_back(nullptr); 9821 AssignmentOps.push_back(nullptr); 9822 continue; 9823 } 9824 9825 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 9826 // A list item that appears in a copyin clause must be threadprivate. 9827 if (!DSAStack->isThreadPrivate(VD)) { 9828 Diag(ELoc, diag::err_omp_required_access) 9829 << getOpenMPClauseName(OMPC_copyin) 9830 << getOpenMPDirectiveName(OMPD_threadprivate); 9831 continue; 9832 } 9833 9834 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 9835 // A variable of class type (or array thereof) that appears in a 9836 // copyin clause requires an accessible, unambiguous copy assignment 9837 // operator for the class type. 9838 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 9839 auto *SrcVD = 9840 buildVarDecl(*this, DE->getLocStart(), ElemType.getUnqualifiedType(), 9841 ".copyin.src", VD->hasAttrs() ? &VD->getAttrs() : nullptr); 9842 auto *PseudoSrcExpr = buildDeclRefExpr( 9843 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 9844 auto *DstVD = 9845 buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst", 9846 VD->hasAttrs() ? &VD->getAttrs() : nullptr); 9847 auto *PseudoDstExpr = 9848 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 9849 // For arrays generate assignment operation for single element and replace 9850 // it by the original array element in CodeGen. 9851 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 9852 PseudoDstExpr, PseudoSrcExpr); 9853 if (AssignmentOp.isInvalid()) 9854 continue; 9855 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 9856 /*DiscardedValue=*/true); 9857 if (AssignmentOp.isInvalid()) 9858 continue; 9859 9860 DSAStack->addDSA(VD, DE, OMPC_copyin); 9861 Vars.push_back(DE); 9862 SrcExprs.push_back(PseudoSrcExpr); 9863 DstExprs.push_back(PseudoDstExpr); 9864 AssignmentOps.push_back(AssignmentOp.get()); 9865 } 9866 9867 if (Vars.empty()) 9868 return nullptr; 9869 9870 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 9871 SrcExprs, DstExprs, AssignmentOps); 9872 } 9873 9874 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 9875 SourceLocation StartLoc, 9876 SourceLocation LParenLoc, 9877 SourceLocation EndLoc) { 9878 SmallVector<Expr *, 8> Vars; 9879 SmallVector<Expr *, 8> SrcExprs; 9880 SmallVector<Expr *, 8> DstExprs; 9881 SmallVector<Expr *, 8> AssignmentOps; 9882 for (auto &RefExpr : VarList) { 9883 assert(RefExpr && "NULL expr in OpenMP linear clause."); 9884 SourceLocation ELoc; 9885 SourceRange ERange; 9886 Expr *SimpleRefExpr = RefExpr; 9887 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange, 9888 /*AllowArraySection=*/false); 9889 if (Res.second) { 9890 // It will be analyzed later. 9891 Vars.push_back(RefExpr); 9892 SrcExprs.push_back(nullptr); 9893 DstExprs.push_back(nullptr); 9894 AssignmentOps.push_back(nullptr); 9895 } 9896 ValueDecl *D = Res.first; 9897 if (!D) 9898 continue; 9899 9900 QualType Type = D->getType(); 9901 auto *VD = dyn_cast<VarDecl>(D); 9902 9903 // OpenMP [2.14.4.2, Restrictions, p.2] 9904 // A list item that appears in a copyprivate clause may not appear in a 9905 // private or firstprivate clause on the single construct. 9906 if (!VD || !DSAStack->isThreadPrivate(VD)) { 9907 auto DVar = DSAStack->getTopDSA(D, false); 9908 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 9909 DVar.RefExpr) { 9910 Diag(ELoc, diag::err_omp_wrong_dsa) 9911 << getOpenMPClauseName(DVar.CKind) 9912 << getOpenMPClauseName(OMPC_copyprivate); 9913 ReportOriginalDSA(*this, DSAStack, D, DVar); 9914 continue; 9915 } 9916 9917 // OpenMP [2.11.4.2, Restrictions, p.1] 9918 // All list items that appear in a copyprivate clause must be either 9919 // threadprivate or private in the enclosing context. 9920 if (DVar.CKind == OMPC_unknown) { 9921 DVar = DSAStack->getImplicitDSA(D, false); 9922 if (DVar.CKind == OMPC_shared) { 9923 Diag(ELoc, diag::err_omp_required_access) 9924 << getOpenMPClauseName(OMPC_copyprivate) 9925 << "threadprivate or private in the enclosing context"; 9926 ReportOriginalDSA(*this, DSAStack, D, DVar); 9927 continue; 9928 } 9929 } 9930 } 9931 9932 // Variably modified types are not supported. 9933 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 9934 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 9935 << getOpenMPClauseName(OMPC_copyprivate) << Type 9936 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 9937 bool IsDecl = 9938 !VD || 9939 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 9940 Diag(D->getLocation(), 9941 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 9942 << D; 9943 continue; 9944 } 9945 9946 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 9947 // A variable of class type (or array thereof) that appears in a 9948 // copyin clause requires an accessible, unambiguous copy assignment 9949 // operator for the class type. 9950 Type = Context.getBaseElementType(Type.getNonReferenceType()) 9951 .getUnqualifiedType(); 9952 auto *SrcVD = 9953 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.src", 9954 D->hasAttrs() ? &D->getAttrs() : nullptr); 9955 auto *PseudoSrcExpr = buildDeclRefExpr(*this, SrcVD, Type, ELoc); 9956 auto *DstVD = 9957 buildVarDecl(*this, RefExpr->getLocStart(), Type, ".copyprivate.dst", 9958 D->hasAttrs() ? &D->getAttrs() : nullptr); 9959 auto *PseudoDstExpr = buildDeclRefExpr(*this, DstVD, Type, ELoc); 9960 auto AssignmentOp = BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign, 9961 PseudoDstExpr, PseudoSrcExpr); 9962 if (AssignmentOp.isInvalid()) 9963 continue; 9964 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), ELoc, 9965 /*DiscardedValue=*/true); 9966 if (AssignmentOp.isInvalid()) 9967 continue; 9968 9969 // No need to mark vars as copyprivate, they are already threadprivate or 9970 // implicitly private. 9971 assert(VD || IsOpenMPCapturedDecl(D)); 9972 Vars.push_back( 9973 VD ? RefExpr->IgnoreParens() 9974 : buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false)); 9975 SrcExprs.push_back(PseudoSrcExpr); 9976 DstExprs.push_back(PseudoDstExpr); 9977 AssignmentOps.push_back(AssignmentOp.get()); 9978 } 9979 9980 if (Vars.empty()) 9981 return nullptr; 9982 9983 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 9984 Vars, SrcExprs, DstExprs, AssignmentOps); 9985 } 9986 9987 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 9988 SourceLocation StartLoc, 9989 SourceLocation LParenLoc, 9990 SourceLocation EndLoc) { 9991 if (VarList.empty()) 9992 return nullptr; 9993 9994 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 9995 } 9996 9997 OMPClause * 9998 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 9999 SourceLocation DepLoc, SourceLocation ColonLoc, 10000 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 10001 SourceLocation LParenLoc, SourceLocation EndLoc) { 10002 if (DSAStack->getCurrentDirective() == OMPD_ordered && 10003 DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink) { 10004 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 10005 << "'source' or 'sink'" << getOpenMPClauseName(OMPC_depend); 10006 return nullptr; 10007 } 10008 if (DSAStack->getCurrentDirective() != OMPD_ordered && 10009 (DepKind == OMPC_DEPEND_unknown || DepKind == OMPC_DEPEND_source || 10010 DepKind == OMPC_DEPEND_sink)) { 10011 unsigned Except[] = {OMPC_DEPEND_source, OMPC_DEPEND_sink}; 10012 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 10013 << getListOfPossibleValues(OMPC_depend, /*First=*/0, 10014 /*Last=*/OMPC_DEPEND_unknown, Except) 10015 << getOpenMPClauseName(OMPC_depend); 10016 return nullptr; 10017 } 10018 SmallVector<Expr *, 8> Vars; 10019 DSAStackTy::OperatorOffsetTy OpsOffs; 10020 llvm::APSInt DepCounter(/*BitWidth=*/32); 10021 llvm::APSInt TotalDepCount(/*BitWidth=*/32); 10022 if (DepKind == OMPC_DEPEND_sink) { 10023 if (auto *OrderedCountExpr = DSAStack->getParentOrderedRegionParam()) { 10024 TotalDepCount = OrderedCountExpr->EvaluateKnownConstInt(Context); 10025 TotalDepCount.setIsUnsigned(/*Val=*/true); 10026 } 10027 } 10028 if ((DepKind != OMPC_DEPEND_sink && DepKind != OMPC_DEPEND_source) || 10029 DSAStack->getParentOrderedRegionParam()) { 10030 for (auto &RefExpr : VarList) { 10031 assert(RefExpr && "NULL expr in OpenMP shared clause."); 10032 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 10033 // It will be analyzed later. 10034 Vars.push_back(RefExpr); 10035 continue; 10036 } 10037 10038 SourceLocation ELoc = RefExpr->getExprLoc(); 10039 auto *SimpleExpr = RefExpr->IgnoreParenCasts(); 10040 if (DepKind == OMPC_DEPEND_sink) { 10041 if (DepCounter >= TotalDepCount) { 10042 Diag(ELoc, diag::err_omp_depend_sink_unexpected_expr); 10043 continue; 10044 } 10045 ++DepCounter; 10046 // OpenMP [2.13.9, Summary] 10047 // depend(dependence-type : vec), where dependence-type is: 10048 // 'sink' and where vec is the iteration vector, which has the form: 10049 // x1 [+- d1], x2 [+- d2 ], . . . , xn [+- dn] 10050 // where n is the value specified by the ordered clause in the loop 10051 // directive, xi denotes the loop iteration variable of the i-th nested 10052 // loop associated with the loop directive, and di is a constant 10053 // non-negative integer. 10054 if (CurContext->isDependentContext()) { 10055 // It will be analyzed later. 10056 Vars.push_back(RefExpr); 10057 continue; 10058 } 10059 SimpleExpr = SimpleExpr->IgnoreImplicit(); 10060 OverloadedOperatorKind OOK = OO_None; 10061 SourceLocation OOLoc; 10062 Expr *LHS = SimpleExpr; 10063 Expr *RHS = nullptr; 10064 if (auto *BO = dyn_cast<BinaryOperator>(SimpleExpr)) { 10065 OOK = BinaryOperator::getOverloadedOperator(BO->getOpcode()); 10066 OOLoc = BO->getOperatorLoc(); 10067 LHS = BO->getLHS()->IgnoreParenImpCasts(); 10068 RHS = BO->getRHS()->IgnoreParenImpCasts(); 10069 } else if (auto *OCE = dyn_cast<CXXOperatorCallExpr>(SimpleExpr)) { 10070 OOK = OCE->getOperator(); 10071 OOLoc = OCE->getOperatorLoc(); 10072 LHS = OCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 10073 RHS = OCE->getArg(/*Arg=*/1)->IgnoreParenImpCasts(); 10074 } else if (auto *MCE = dyn_cast<CXXMemberCallExpr>(SimpleExpr)) { 10075 OOK = MCE->getMethodDecl() 10076 ->getNameInfo() 10077 .getName() 10078 .getCXXOverloadedOperator(); 10079 OOLoc = MCE->getCallee()->getExprLoc(); 10080 LHS = MCE->getImplicitObjectArgument()->IgnoreParenImpCasts(); 10081 RHS = MCE->getArg(/*Arg=*/0)->IgnoreParenImpCasts(); 10082 } 10083 SourceLocation ELoc; 10084 SourceRange ERange; 10085 auto Res = getPrivateItem(*this, LHS, ELoc, ERange, 10086 /*AllowArraySection=*/false); 10087 if (Res.second) { 10088 // It will be analyzed later. 10089 Vars.push_back(RefExpr); 10090 } 10091 ValueDecl *D = Res.first; 10092 if (!D) 10093 continue; 10094 10095 if (OOK != OO_Plus && OOK != OO_Minus && (RHS || OOK != OO_None)) { 10096 Diag(OOLoc, diag::err_omp_depend_sink_expected_plus_minus); 10097 continue; 10098 } 10099 if (RHS) { 10100 ExprResult RHSRes = VerifyPositiveIntegerConstantInClause( 10101 RHS, OMPC_depend, /*StrictlyPositive=*/false); 10102 if (RHSRes.isInvalid()) 10103 continue; 10104 } 10105 if (!CurContext->isDependentContext() && 10106 DSAStack->getParentOrderedRegionParam() && 10107 DepCounter != DSAStack->isParentLoopControlVariable(D).first) { 10108 Diag(ELoc, diag::err_omp_depend_sink_expected_loop_iteration) 10109 << DSAStack->getParentLoopControlVariable( 10110 DepCounter.getZExtValue()); 10111 continue; 10112 } 10113 OpsOffs.push_back({RHS, OOK}); 10114 } else { 10115 // OpenMP [2.11.1.1, Restrictions, p.3] 10116 // A variable that is part of another variable (such as a field of a 10117 // structure) but is not an array element or an array section cannot 10118 // appear in a depend clause. 10119 auto *DE = dyn_cast<DeclRefExpr>(SimpleExpr); 10120 auto *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 10121 auto *OASE = dyn_cast<OMPArraySectionExpr>(SimpleExpr); 10122 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || 10123 (!ASE && !DE && !OASE) || (DE && !isa<VarDecl>(DE->getDecl())) || 10124 (ASE && 10125 !ASE->getBase() 10126 ->getType() 10127 .getNonReferenceType() 10128 ->isPointerType() && 10129 !ASE->getBase()->getType().getNonReferenceType()->isArrayType())) { 10130 Diag(ELoc, diag::err_omp_expected_var_name_member_expr_or_array_item) 10131 << 0 << RefExpr->getSourceRange(); 10132 continue; 10133 } 10134 } 10135 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 10136 } 10137 10138 if (!CurContext->isDependentContext() && DepKind == OMPC_DEPEND_sink && 10139 TotalDepCount > VarList.size() && 10140 DSAStack->getParentOrderedRegionParam()) { 10141 Diag(EndLoc, diag::err_omp_depend_sink_expected_loop_iteration) 10142 << DSAStack->getParentLoopControlVariable(VarList.size() + 1); 10143 } 10144 if (DepKind != OMPC_DEPEND_source && DepKind != OMPC_DEPEND_sink && 10145 Vars.empty()) 10146 return nullptr; 10147 } 10148 auto *C = OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10149 DepKind, DepLoc, ColonLoc, Vars); 10150 if (DepKind == OMPC_DEPEND_sink || DepKind == OMPC_DEPEND_source) 10151 DSAStack->addDoacrossDependClause(C, OpsOffs); 10152 return C; 10153 } 10154 10155 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 10156 SourceLocation LParenLoc, 10157 SourceLocation EndLoc) { 10158 Expr *ValExpr = Device; 10159 10160 // OpenMP [2.9.1, Restrictions] 10161 // The device expression must evaluate to a non-negative integer value. 10162 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_device, 10163 /*StrictlyPositive=*/false)) 10164 return nullptr; 10165 10166 return new (Context) OMPDeviceClause(ValExpr, StartLoc, LParenLoc, EndLoc); 10167 } 10168 10169 static bool IsCXXRecordForMappable(Sema &SemaRef, SourceLocation Loc, 10170 DSAStackTy *Stack, CXXRecordDecl *RD) { 10171 if (!RD || RD->isInvalidDecl()) 10172 return true; 10173 10174 auto QTy = SemaRef.Context.getRecordType(RD); 10175 if (RD->isDynamicClass()) { 10176 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 10177 SemaRef.Diag(RD->getLocation(), diag::note_omp_polymorphic_in_target); 10178 return false; 10179 } 10180 auto *DC = RD; 10181 bool IsCorrect = true; 10182 for (auto *I : DC->decls()) { 10183 if (I) { 10184 if (auto *MD = dyn_cast<CXXMethodDecl>(I)) { 10185 if (MD->isStatic()) { 10186 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 10187 SemaRef.Diag(MD->getLocation(), 10188 diag::note_omp_static_member_in_target); 10189 IsCorrect = false; 10190 } 10191 } else if (auto *VD = dyn_cast<VarDecl>(I)) { 10192 if (VD->isStaticDataMember()) { 10193 SemaRef.Diag(Loc, diag::err_omp_not_mappable_type) << QTy; 10194 SemaRef.Diag(VD->getLocation(), 10195 diag::note_omp_static_member_in_target); 10196 IsCorrect = false; 10197 } 10198 } 10199 } 10200 } 10201 10202 for (auto &I : RD->bases()) { 10203 if (!IsCXXRecordForMappable(SemaRef, I.getLocStart(), Stack, 10204 I.getType()->getAsCXXRecordDecl())) 10205 IsCorrect = false; 10206 } 10207 return IsCorrect; 10208 } 10209 10210 static bool CheckTypeMappable(SourceLocation SL, SourceRange SR, Sema &SemaRef, 10211 DSAStackTy *Stack, QualType QTy) { 10212 NamedDecl *ND; 10213 if (QTy->isIncompleteType(&ND)) { 10214 SemaRef.Diag(SL, diag::err_incomplete_type) << QTy << SR; 10215 return false; 10216 } else if (CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(ND)) { 10217 if (!RD->isInvalidDecl() && !IsCXXRecordForMappable(SemaRef, SL, Stack, RD)) 10218 return false; 10219 } 10220 return true; 10221 } 10222 10223 /// \brief Return true if it can be proven that the provided array expression 10224 /// (array section or array subscript) does NOT specify the whole size of the 10225 /// array whose base type is \a BaseQTy. 10226 static bool CheckArrayExpressionDoesNotReferToWholeSize(Sema &SemaRef, 10227 const Expr *E, 10228 QualType BaseQTy) { 10229 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 10230 10231 // If this is an array subscript, it refers to the whole size if the size of 10232 // the dimension is constant and equals 1. Also, an array section assumes the 10233 // format of an array subscript if no colon is used. 10234 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) { 10235 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 10236 return ATy->getSize().getSExtValue() != 1; 10237 // Size can't be evaluated statically. 10238 return false; 10239 } 10240 10241 assert(OASE && "Expecting array section if not an array subscript."); 10242 auto *LowerBound = OASE->getLowerBound(); 10243 auto *Length = OASE->getLength(); 10244 10245 // If there is a lower bound that does not evaluates to zero, we are not 10246 // covering the whole dimension. 10247 if (LowerBound) { 10248 llvm::APSInt ConstLowerBound; 10249 if (!LowerBound->EvaluateAsInt(ConstLowerBound, SemaRef.getASTContext())) 10250 return false; // Can't get the integer value as a constant. 10251 if (ConstLowerBound.getSExtValue()) 10252 return true; 10253 } 10254 10255 // If we don't have a length we covering the whole dimension. 10256 if (!Length) 10257 return false; 10258 10259 // If the base is a pointer, we don't have a way to get the size of the 10260 // pointee. 10261 if (BaseQTy->isPointerType()) 10262 return false; 10263 10264 // We can only check if the length is the same as the size of the dimension 10265 // if we have a constant array. 10266 auto *CATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr()); 10267 if (!CATy) 10268 return false; 10269 10270 llvm::APSInt ConstLength; 10271 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 10272 return false; // Can't get the integer value as a constant. 10273 10274 return CATy->getSize().getSExtValue() != ConstLength.getSExtValue(); 10275 } 10276 10277 // Return true if it can be proven that the provided array expression (array 10278 // section or array subscript) does NOT specify a single element of the array 10279 // whose base type is \a BaseQTy. 10280 static bool CheckArrayExpressionDoesNotReferToUnitySize(Sema &SemaRef, 10281 const Expr *E, 10282 QualType BaseQTy) { 10283 auto *OASE = dyn_cast<OMPArraySectionExpr>(E); 10284 10285 // An array subscript always refer to a single element. Also, an array section 10286 // assumes the format of an array subscript if no colon is used. 10287 if (isa<ArraySubscriptExpr>(E) || (OASE && OASE->getColonLoc().isInvalid())) 10288 return false; 10289 10290 assert(OASE && "Expecting array section if not an array subscript."); 10291 auto *Length = OASE->getLength(); 10292 10293 // If we don't have a length we have to check if the array has unitary size 10294 // for this dimension. Also, we should always expect a length if the base type 10295 // is pointer. 10296 if (!Length) { 10297 if (auto *ATy = dyn_cast<ConstantArrayType>(BaseQTy.getTypePtr())) 10298 return ATy->getSize().getSExtValue() != 1; 10299 // We cannot assume anything. 10300 return false; 10301 } 10302 10303 // Check if the length evaluates to 1. 10304 llvm::APSInt ConstLength; 10305 if (!Length->EvaluateAsInt(ConstLength, SemaRef.getASTContext())) 10306 return false; // Can't get the integer value as a constant. 10307 10308 return ConstLength.getSExtValue() != 1; 10309 } 10310 10311 // Return the expression of the base of the mappable expression or null if it 10312 // cannot be determined and do all the necessary checks to see if the expression 10313 // is valid as a standalone mappable expression. In the process, record all the 10314 // components of the expression. 10315 static Expr *CheckMapClauseExpressionBase( 10316 Sema &SemaRef, Expr *E, 10317 OMPClauseMappableExprCommon::MappableExprComponentList &CurComponents, 10318 OpenMPClauseKind CKind) { 10319 SourceLocation ELoc = E->getExprLoc(); 10320 SourceRange ERange = E->getSourceRange(); 10321 10322 // The base of elements of list in a map clause have to be either: 10323 // - a reference to variable or field. 10324 // - a member expression. 10325 // - an array expression. 10326 // 10327 // E.g. if we have the expression 'r.S.Arr[:12]', we want to retrieve the 10328 // reference to 'r'. 10329 // 10330 // If we have: 10331 // 10332 // struct SS { 10333 // Bla S; 10334 // foo() { 10335 // #pragma omp target map (S.Arr[:12]); 10336 // } 10337 // } 10338 // 10339 // We want to retrieve the member expression 'this->S'; 10340 10341 Expr *RelevantExpr = nullptr; 10342 10343 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.2] 10344 // If a list item is an array section, it must specify contiguous storage. 10345 // 10346 // For this restriction it is sufficient that we make sure only references 10347 // to variables or fields and array expressions, and that no array sections 10348 // exist except in the rightmost expression (unless they cover the whole 10349 // dimension of the array). E.g. these would be invalid: 10350 // 10351 // r.ArrS[3:5].Arr[6:7] 10352 // 10353 // r.ArrS[3:5].x 10354 // 10355 // but these would be valid: 10356 // r.ArrS[3].Arr[6:7] 10357 // 10358 // r.ArrS[3].x 10359 10360 bool AllowUnitySizeArraySection = true; 10361 bool AllowWholeSizeArraySection = true; 10362 10363 while (!RelevantExpr) { 10364 E = E->IgnoreParenImpCasts(); 10365 10366 if (auto *CurE = dyn_cast<DeclRefExpr>(E)) { 10367 if (!isa<VarDecl>(CurE->getDecl())) 10368 break; 10369 10370 RelevantExpr = CurE; 10371 10372 // If we got a reference to a declaration, we should not expect any array 10373 // section before that. 10374 AllowUnitySizeArraySection = false; 10375 AllowWholeSizeArraySection = false; 10376 10377 // Record the component. 10378 CurComponents.push_back(OMPClauseMappableExprCommon::MappableComponent( 10379 CurE, CurE->getDecl())); 10380 continue; 10381 } 10382 10383 if (auto *CurE = dyn_cast<MemberExpr>(E)) { 10384 auto *BaseE = CurE->getBase()->IgnoreParenImpCasts(); 10385 10386 if (isa<CXXThisExpr>(BaseE)) 10387 // We found a base expression: this->Val. 10388 RelevantExpr = CurE; 10389 else 10390 E = BaseE; 10391 10392 if (!isa<FieldDecl>(CurE->getMemberDecl())) { 10393 SemaRef.Diag(ELoc, diag::err_omp_expected_access_to_data_field) 10394 << CurE->getSourceRange(); 10395 break; 10396 } 10397 10398 auto *FD = cast<FieldDecl>(CurE->getMemberDecl()); 10399 10400 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.3] 10401 // A bit-field cannot appear in a map clause. 10402 // 10403 if (FD->isBitField()) { 10404 SemaRef.Diag(ELoc, diag::err_omp_bit_fields_forbidden_in_clause) 10405 << CurE->getSourceRange() << getOpenMPClauseName(CKind); 10406 break; 10407 } 10408 10409 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 10410 // If the type of a list item is a reference to a type T then the type 10411 // will be considered to be T for all purposes of this clause. 10412 QualType CurType = BaseE->getType().getNonReferenceType(); 10413 10414 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.2] 10415 // A list item cannot be a variable that is a member of a structure with 10416 // a union type. 10417 // 10418 if (auto *RT = CurType->getAs<RecordType>()) 10419 if (RT->isUnionType()) { 10420 SemaRef.Diag(ELoc, diag::err_omp_union_type_not_allowed) 10421 << CurE->getSourceRange(); 10422 break; 10423 } 10424 10425 // If we got a member expression, we should not expect any array section 10426 // before that: 10427 // 10428 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.7] 10429 // If a list item is an element of a structure, only the rightmost symbol 10430 // of the variable reference can be an array section. 10431 // 10432 AllowUnitySizeArraySection = false; 10433 AllowWholeSizeArraySection = false; 10434 10435 // Record the component. 10436 CurComponents.push_back( 10437 OMPClauseMappableExprCommon::MappableComponent(CurE, FD)); 10438 continue; 10439 } 10440 10441 if (auto *CurE = dyn_cast<ArraySubscriptExpr>(E)) { 10442 E = CurE->getBase()->IgnoreParenImpCasts(); 10443 10444 if (!E->getType()->isAnyPointerType() && !E->getType()->isArrayType()) { 10445 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 10446 << 0 << CurE->getSourceRange(); 10447 break; 10448 } 10449 10450 // If we got an array subscript that express the whole dimension we 10451 // can have any array expressions before. If it only expressing part of 10452 // the dimension, we can only have unitary-size array expressions. 10453 if (CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, 10454 E->getType())) 10455 AllowWholeSizeArraySection = false; 10456 10457 // Record the component - we don't have any declaration associated. 10458 CurComponents.push_back( 10459 OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); 10460 continue; 10461 } 10462 10463 if (auto *CurE = dyn_cast<OMPArraySectionExpr>(E)) { 10464 E = CurE->getBase()->IgnoreParenImpCasts(); 10465 10466 auto CurType = 10467 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 10468 10469 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 10470 // If the type of a list item is a reference to a type T then the type 10471 // will be considered to be T for all purposes of this clause. 10472 if (CurType->isReferenceType()) 10473 CurType = CurType->getPointeeType(); 10474 10475 bool IsPointer = CurType->isAnyPointerType(); 10476 10477 if (!IsPointer && !CurType->isArrayType()) { 10478 SemaRef.Diag(ELoc, diag::err_omp_expected_base_var_name) 10479 << 0 << CurE->getSourceRange(); 10480 break; 10481 } 10482 10483 bool NotWhole = 10484 CheckArrayExpressionDoesNotReferToWholeSize(SemaRef, CurE, CurType); 10485 bool NotUnity = 10486 CheckArrayExpressionDoesNotReferToUnitySize(SemaRef, CurE, CurType); 10487 10488 if (AllowWholeSizeArraySection) { 10489 // Any array section is currently allowed. Allowing a whole size array 10490 // section implies allowing a unity array section as well. 10491 // 10492 // If this array section refers to the whole dimension we can still 10493 // accept other array sections before this one, except if the base is a 10494 // pointer. Otherwise, only unitary sections are accepted. 10495 if (NotWhole || IsPointer) 10496 AllowWholeSizeArraySection = false; 10497 } else if (AllowUnitySizeArraySection && NotUnity) { 10498 // A unity or whole array section is not allowed and that is not 10499 // compatible with the properties of the current array section. 10500 SemaRef.Diag( 10501 ELoc, diag::err_array_section_does_not_specify_contiguous_storage) 10502 << CurE->getSourceRange(); 10503 break; 10504 } 10505 10506 // Record the component - we don't have any declaration associated. 10507 CurComponents.push_back( 10508 OMPClauseMappableExprCommon::MappableComponent(CurE, nullptr)); 10509 continue; 10510 } 10511 10512 // If nothing else worked, this is not a valid map clause expression. 10513 SemaRef.Diag(ELoc, 10514 diag::err_omp_expected_named_var_member_or_array_expression) 10515 << ERange; 10516 break; 10517 } 10518 10519 return RelevantExpr; 10520 } 10521 10522 // Return true if expression E associated with value VD has conflicts with other 10523 // map information. 10524 static bool CheckMapConflicts( 10525 Sema &SemaRef, DSAStackTy *DSAS, ValueDecl *VD, Expr *E, 10526 bool CurrentRegionOnly, 10527 OMPClauseMappableExprCommon::MappableExprComponentListRef CurComponents, 10528 OpenMPClauseKind CKind) { 10529 assert(VD && E); 10530 SourceLocation ELoc = E->getExprLoc(); 10531 SourceRange ERange = E->getSourceRange(); 10532 10533 // In order to easily check the conflicts we need to match each component of 10534 // the expression under test with the components of the expressions that are 10535 // already in the stack. 10536 10537 assert(!CurComponents.empty() && "Map clause expression with no components!"); 10538 assert(CurComponents.back().getAssociatedDeclaration() == VD && 10539 "Map clause expression with unexpected base!"); 10540 10541 // Variables to help detecting enclosing problems in data environment nests. 10542 bool IsEnclosedByDataEnvironmentExpr = false; 10543 const Expr *EnclosingExpr = nullptr; 10544 10545 bool FoundError = DSAS->checkMappableExprComponentListsForDecl( 10546 VD, CurrentRegionOnly, 10547 [&](OMPClauseMappableExprCommon::MappableExprComponentListRef 10548 StackComponents, 10549 OpenMPClauseKind) -> bool { 10550 10551 assert(!StackComponents.empty() && 10552 "Map clause expression with no components!"); 10553 assert(StackComponents.back().getAssociatedDeclaration() == VD && 10554 "Map clause expression with unexpected base!"); 10555 10556 // The whole expression in the stack. 10557 auto *RE = StackComponents.front().getAssociatedExpression(); 10558 10559 // Expressions must start from the same base. Here we detect at which 10560 // point both expressions diverge from each other and see if we can 10561 // detect if the memory referred to both expressions is contiguous and 10562 // do not overlap. 10563 auto CI = CurComponents.rbegin(); 10564 auto CE = CurComponents.rend(); 10565 auto SI = StackComponents.rbegin(); 10566 auto SE = StackComponents.rend(); 10567 for (; CI != CE && SI != SE; ++CI, ++SI) { 10568 10569 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.3] 10570 // At most one list item can be an array item derived from a given 10571 // variable in map clauses of the same construct. 10572 if (CurrentRegionOnly && 10573 (isa<ArraySubscriptExpr>(CI->getAssociatedExpression()) || 10574 isa<OMPArraySectionExpr>(CI->getAssociatedExpression())) && 10575 (isa<ArraySubscriptExpr>(SI->getAssociatedExpression()) || 10576 isa<OMPArraySectionExpr>(SI->getAssociatedExpression()))) { 10577 SemaRef.Diag(CI->getAssociatedExpression()->getExprLoc(), 10578 diag::err_omp_multiple_array_items_in_map_clause) 10579 << CI->getAssociatedExpression()->getSourceRange(); 10580 SemaRef.Diag(SI->getAssociatedExpression()->getExprLoc(), 10581 diag::note_used_here) 10582 << SI->getAssociatedExpression()->getSourceRange(); 10583 return true; 10584 } 10585 10586 // Do both expressions have the same kind? 10587 if (CI->getAssociatedExpression()->getStmtClass() != 10588 SI->getAssociatedExpression()->getStmtClass()) 10589 break; 10590 10591 // Are we dealing with different variables/fields? 10592 if (CI->getAssociatedDeclaration() != SI->getAssociatedDeclaration()) 10593 break; 10594 } 10595 // Check if the extra components of the expressions in the enclosing 10596 // data environment are redundant for the current base declaration. 10597 // If they are, the maps completely overlap, which is legal. 10598 for (; SI != SE; ++SI) { 10599 QualType Type; 10600 if (auto *ASE = 10601 dyn_cast<ArraySubscriptExpr>(SI->getAssociatedExpression())) { 10602 Type = ASE->getBase()->IgnoreParenImpCasts()->getType(); 10603 } else if (auto *OASE = dyn_cast<OMPArraySectionExpr>( 10604 SI->getAssociatedExpression())) { 10605 auto *E = OASE->getBase()->IgnoreParenImpCasts(); 10606 Type = 10607 OMPArraySectionExpr::getBaseOriginalType(E).getCanonicalType(); 10608 } 10609 if (Type.isNull() || Type->isAnyPointerType() || 10610 CheckArrayExpressionDoesNotReferToWholeSize( 10611 SemaRef, SI->getAssociatedExpression(), Type)) 10612 break; 10613 } 10614 10615 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 10616 // List items of map clauses in the same construct must not share 10617 // original storage. 10618 // 10619 // If the expressions are exactly the same or one is a subset of the 10620 // other, it means they are sharing storage. 10621 if (CI == CE && SI == SE) { 10622 if (CurrentRegionOnly) { 10623 if (CKind == OMPC_map) 10624 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 10625 else { 10626 assert(CKind == OMPC_to || CKind == OMPC_from); 10627 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 10628 << ERange; 10629 } 10630 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 10631 << RE->getSourceRange(); 10632 return true; 10633 } else { 10634 // If we find the same expression in the enclosing data environment, 10635 // that is legal. 10636 IsEnclosedByDataEnvironmentExpr = true; 10637 return false; 10638 } 10639 } 10640 10641 QualType DerivedType = 10642 std::prev(CI)->getAssociatedDeclaration()->getType(); 10643 SourceLocation DerivedLoc = 10644 std::prev(CI)->getAssociatedExpression()->getExprLoc(); 10645 10646 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 10647 // If the type of a list item is a reference to a type T then the type 10648 // will be considered to be T for all purposes of this clause. 10649 DerivedType = DerivedType.getNonReferenceType(); 10650 10651 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C/C++, p.1] 10652 // A variable for which the type is pointer and an array section 10653 // derived from that variable must not appear as list items of map 10654 // clauses of the same construct. 10655 // 10656 // Also, cover one of the cases in: 10657 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 10658 // If any part of the original storage of a list item has corresponding 10659 // storage in the device data environment, all of the original storage 10660 // must have corresponding storage in the device data environment. 10661 // 10662 if (DerivedType->isAnyPointerType()) { 10663 if (CI == CE || SI == SE) { 10664 SemaRef.Diag( 10665 DerivedLoc, 10666 diag::err_omp_pointer_mapped_along_with_derived_section) 10667 << DerivedLoc; 10668 } else { 10669 assert(CI != CE && SI != SE); 10670 SemaRef.Diag(DerivedLoc, diag::err_omp_same_pointer_derreferenced) 10671 << DerivedLoc; 10672 } 10673 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 10674 << RE->getSourceRange(); 10675 return true; 10676 } 10677 10678 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.4] 10679 // List items of map clauses in the same construct must not share 10680 // original storage. 10681 // 10682 // An expression is a subset of the other. 10683 if (CurrentRegionOnly && (CI == CE || SI == SE)) { 10684 if (CKind == OMPC_map) 10685 SemaRef.Diag(ELoc, diag::err_omp_map_shared_storage) << ERange; 10686 else { 10687 assert(CKind == OMPC_to || CKind == OMPC_from); 10688 SemaRef.Diag(ELoc, diag::err_omp_once_referenced_in_target_update) 10689 << ERange; 10690 } 10691 SemaRef.Diag(RE->getExprLoc(), diag::note_used_here) 10692 << RE->getSourceRange(); 10693 return true; 10694 } 10695 10696 // The current expression uses the same base as other expression in the 10697 // data environment but does not contain it completely. 10698 if (!CurrentRegionOnly && SI != SE) 10699 EnclosingExpr = RE; 10700 10701 // The current expression is a subset of the expression in the data 10702 // environment. 10703 IsEnclosedByDataEnvironmentExpr |= 10704 (!CurrentRegionOnly && CI != CE && SI == SE); 10705 10706 return false; 10707 }); 10708 10709 if (CurrentRegionOnly) 10710 return FoundError; 10711 10712 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.5] 10713 // If any part of the original storage of a list item has corresponding 10714 // storage in the device data environment, all of the original storage must 10715 // have corresponding storage in the device data environment. 10716 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.6] 10717 // If a list item is an element of a structure, and a different element of 10718 // the structure has a corresponding list item in the device data environment 10719 // prior to a task encountering the construct associated with the map clause, 10720 // then the list item must also have a corresponding list item in the device 10721 // data environment prior to the task encountering the construct. 10722 // 10723 if (EnclosingExpr && !IsEnclosedByDataEnvironmentExpr) { 10724 SemaRef.Diag(ELoc, 10725 diag::err_omp_original_storage_is_shared_and_does_not_contain) 10726 << ERange; 10727 SemaRef.Diag(EnclosingExpr->getExprLoc(), diag::note_used_here) 10728 << EnclosingExpr->getSourceRange(); 10729 return true; 10730 } 10731 10732 return FoundError; 10733 } 10734 10735 namespace { 10736 // Utility struct that gathers all the related lists associated with a mappable 10737 // expression. 10738 struct MappableVarListInfo final { 10739 // The list of expressions. 10740 ArrayRef<Expr *> VarList; 10741 // The list of processed expressions. 10742 SmallVector<Expr *, 16> ProcessedVarList; 10743 // The mappble components for each expression. 10744 OMPClauseMappableExprCommon::MappableExprComponentLists VarComponents; 10745 // The base declaration of the variable. 10746 SmallVector<ValueDecl *, 16> VarBaseDeclarations; 10747 10748 MappableVarListInfo(ArrayRef<Expr *> VarList) : VarList(VarList) { 10749 // We have a list of components and base declarations for each entry in the 10750 // variable list. 10751 VarComponents.reserve(VarList.size()); 10752 VarBaseDeclarations.reserve(VarList.size()); 10753 } 10754 }; 10755 } 10756 10757 // Check the validity of the provided variable list for the provided clause kind 10758 // \a CKind. In the check process the valid expressions, and mappable expression 10759 // components and variables are extracted and used to fill \a Vars, 10760 // \a ClauseComponents, and \a ClauseBaseDeclarations. \a MapType and 10761 // \a IsMapTypeImplicit are expected to be valid if the clause kind is 'map'. 10762 static void 10763 checkMappableExpressionList(Sema &SemaRef, DSAStackTy *DSAS, 10764 OpenMPClauseKind CKind, MappableVarListInfo &MVLI, 10765 SourceLocation StartLoc, 10766 OpenMPMapClauseKind MapType = OMPC_MAP_unknown, 10767 bool IsMapTypeImplicit = false) { 10768 // We only expect mappable expressions in 'to', 'from', and 'map' clauses. 10769 assert((CKind == OMPC_map || CKind == OMPC_to || CKind == OMPC_from) && 10770 "Unexpected clause kind with mappable expressions!"); 10771 10772 // Keep track of the mappable components and base declarations in this clause. 10773 // Each entry in the list is going to have a list of components associated. We 10774 // record each set of the components so that we can build the clause later on. 10775 // In the end we should have the same amount of declarations and component 10776 // lists. 10777 10778 for (auto &RE : MVLI.VarList) { 10779 assert(RE && "Null expr in omp to/from/map clause"); 10780 SourceLocation ELoc = RE->getExprLoc(); 10781 10782 auto *VE = RE->IgnoreParenLValueCasts(); 10783 10784 if (VE->isValueDependent() || VE->isTypeDependent() || 10785 VE->isInstantiationDependent() || 10786 VE->containsUnexpandedParameterPack()) { 10787 // We can only analyze this information once the missing information is 10788 // resolved. 10789 MVLI.ProcessedVarList.push_back(RE); 10790 continue; 10791 } 10792 10793 auto *SimpleExpr = RE->IgnoreParenCasts(); 10794 10795 if (!RE->IgnoreParenImpCasts()->isLValue()) { 10796 SemaRef.Diag(ELoc, 10797 diag::err_omp_expected_named_var_member_or_array_expression) 10798 << RE->getSourceRange(); 10799 continue; 10800 } 10801 10802 OMPClauseMappableExprCommon::MappableExprComponentList CurComponents; 10803 ValueDecl *CurDeclaration = nullptr; 10804 10805 // Obtain the array or member expression bases if required. Also, fill the 10806 // components array with all the components identified in the process. 10807 auto *BE = 10808 CheckMapClauseExpressionBase(SemaRef, SimpleExpr, CurComponents, CKind); 10809 if (!BE) 10810 continue; 10811 10812 assert(!CurComponents.empty() && 10813 "Invalid mappable expression information."); 10814 10815 // For the following checks, we rely on the base declaration which is 10816 // expected to be associated with the last component. The declaration is 10817 // expected to be a variable or a field (if 'this' is being mapped). 10818 CurDeclaration = CurComponents.back().getAssociatedDeclaration(); 10819 assert(CurDeclaration && "Null decl on map clause."); 10820 assert( 10821 CurDeclaration->isCanonicalDecl() && 10822 "Expecting components to have associated only canonical declarations."); 10823 10824 auto *VD = dyn_cast<VarDecl>(CurDeclaration); 10825 auto *FD = dyn_cast<FieldDecl>(CurDeclaration); 10826 10827 assert((VD || FD) && "Only variables or fields are expected here!"); 10828 (void)FD; 10829 10830 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.10] 10831 // threadprivate variables cannot appear in a map clause. 10832 // OpenMP 4.5 [2.10.5, target update Construct] 10833 // threadprivate variables cannot appear in a from clause. 10834 if (VD && DSAS->isThreadPrivate(VD)) { 10835 auto DVar = DSAS->getTopDSA(VD, false); 10836 SemaRef.Diag(ELoc, diag::err_omp_threadprivate_in_clause) 10837 << getOpenMPClauseName(CKind); 10838 ReportOriginalDSA(SemaRef, DSAS, VD, DVar); 10839 continue; 10840 } 10841 10842 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 10843 // A list item cannot appear in both a map clause and a data-sharing 10844 // attribute clause on the same construct. 10845 10846 // Check conflicts with other map clause expressions. We check the conflicts 10847 // with the current construct separately from the enclosing data 10848 // environment, because the restrictions are different. We only have to 10849 // check conflicts across regions for the map clauses. 10850 if (CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 10851 /*CurrentRegionOnly=*/true, CurComponents, CKind)) 10852 break; 10853 if (CKind == OMPC_map && 10854 CheckMapConflicts(SemaRef, DSAS, CurDeclaration, SimpleExpr, 10855 /*CurrentRegionOnly=*/false, CurComponents, CKind)) 10856 break; 10857 10858 // OpenMP 4.5 [2.10.5, target update Construct] 10859 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, C++, p.1] 10860 // If the type of a list item is a reference to a type T then the type will 10861 // be considered to be T for all purposes of this clause. 10862 QualType Type = CurDeclaration->getType().getNonReferenceType(); 10863 10864 // OpenMP 4.5 [2.10.5, target update Construct, Restrictions, p.4] 10865 // A list item in a to or from clause must have a mappable type. 10866 // OpenMP 4.5 [2.15.5.1, map Clause, Restrictions, p.9] 10867 // A list item must have a mappable type. 10868 if (!CheckTypeMappable(VE->getExprLoc(), VE->getSourceRange(), SemaRef, 10869 DSAS, Type)) 10870 continue; 10871 10872 if (CKind == OMPC_map) { 10873 // target enter data 10874 // OpenMP [2.10.2, Restrictions, p. 99] 10875 // A map-type must be specified in all map clauses and must be either 10876 // to or alloc. 10877 OpenMPDirectiveKind DKind = DSAS->getCurrentDirective(); 10878 if (DKind == OMPD_target_enter_data && 10879 !(MapType == OMPC_MAP_to || MapType == OMPC_MAP_alloc)) { 10880 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 10881 << (IsMapTypeImplicit ? 1 : 0) 10882 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 10883 << getOpenMPDirectiveName(DKind); 10884 continue; 10885 } 10886 10887 // target exit_data 10888 // OpenMP [2.10.3, Restrictions, p. 102] 10889 // A map-type must be specified in all map clauses and must be either 10890 // from, release, or delete. 10891 if (DKind == OMPD_target_exit_data && 10892 !(MapType == OMPC_MAP_from || MapType == OMPC_MAP_release || 10893 MapType == OMPC_MAP_delete)) { 10894 SemaRef.Diag(StartLoc, diag::err_omp_invalid_map_type_for_directive) 10895 << (IsMapTypeImplicit ? 1 : 0) 10896 << getOpenMPSimpleClauseTypeName(OMPC_map, MapType) 10897 << getOpenMPDirectiveName(DKind); 10898 continue; 10899 } 10900 10901 // OpenMP 4.5 [2.15.5.1, Restrictions, p.3] 10902 // A list item cannot appear in both a map clause and a data-sharing 10903 // attribute clause on the same construct 10904 if ((DKind == OMPD_target || DKind == OMPD_target_teams || 10905 DKind == OMPD_target_teams_distribute || 10906 DKind == OMPD_target_teams_distribute_parallel_for || 10907 DKind == OMPD_target_teams_distribute_parallel_for_simd || 10908 DKind == OMPD_target_teams_distribute_simd) && VD) { 10909 auto DVar = DSAS->getTopDSA(VD, false); 10910 if (isOpenMPPrivate(DVar.CKind)) { 10911 SemaRef.Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 10912 << getOpenMPClauseName(DVar.CKind) 10913 << getOpenMPClauseName(OMPC_map) 10914 << getOpenMPDirectiveName(DSAS->getCurrentDirective()); 10915 ReportOriginalDSA(SemaRef, DSAS, CurDeclaration, DVar); 10916 continue; 10917 } 10918 } 10919 } 10920 10921 // Save the current expression. 10922 MVLI.ProcessedVarList.push_back(RE); 10923 10924 // Store the components in the stack so that they can be used to check 10925 // against other clauses later on. 10926 DSAS->addMappableExpressionComponents(CurDeclaration, CurComponents, 10927 /*WhereFoundClauseKind=*/OMPC_map); 10928 10929 // Save the components and declaration to create the clause. For purposes of 10930 // the clause creation, any component list that has has base 'this' uses 10931 // null as base declaration. 10932 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 10933 MVLI.VarComponents.back().append(CurComponents.begin(), 10934 CurComponents.end()); 10935 MVLI.VarBaseDeclarations.push_back(isa<MemberExpr>(BE) ? nullptr 10936 : CurDeclaration); 10937 } 10938 } 10939 10940 OMPClause * 10941 Sema::ActOnOpenMPMapClause(OpenMPMapClauseKind MapTypeModifier, 10942 OpenMPMapClauseKind MapType, bool IsMapTypeImplicit, 10943 SourceLocation MapLoc, SourceLocation ColonLoc, 10944 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 10945 SourceLocation LParenLoc, SourceLocation EndLoc) { 10946 MappableVarListInfo MVLI(VarList); 10947 checkMappableExpressionList(*this, DSAStack, OMPC_map, MVLI, StartLoc, 10948 MapType, IsMapTypeImplicit); 10949 10950 // We need to produce a map clause even if we don't have variables so that 10951 // other diagnostics related with non-existing map clauses are accurate. 10952 return OMPMapClause::Create(Context, StartLoc, LParenLoc, EndLoc, 10953 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 10954 MVLI.VarComponents, MapTypeModifier, MapType, 10955 IsMapTypeImplicit, MapLoc); 10956 } 10957 10958 QualType Sema::ActOnOpenMPDeclareReductionType(SourceLocation TyLoc, 10959 TypeResult ParsedType) { 10960 assert(ParsedType.isUsable()); 10961 10962 QualType ReductionType = GetTypeFromParser(ParsedType.get()); 10963 if (ReductionType.isNull()) 10964 return QualType(); 10965 10966 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions, C\C++ 10967 // A type name in a declare reduction directive cannot be a function type, an 10968 // array type, a reference type, or a type qualified with const, volatile or 10969 // restrict. 10970 if (ReductionType.hasQualifiers()) { 10971 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 0; 10972 return QualType(); 10973 } 10974 10975 if (ReductionType->isFunctionType()) { 10976 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 1; 10977 return QualType(); 10978 } 10979 if (ReductionType->isReferenceType()) { 10980 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 2; 10981 return QualType(); 10982 } 10983 if (ReductionType->isArrayType()) { 10984 Diag(TyLoc, diag::err_omp_reduction_wrong_type) << 3; 10985 return QualType(); 10986 } 10987 return ReductionType; 10988 } 10989 10990 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveStart( 10991 Scope *S, DeclContext *DC, DeclarationName Name, 10992 ArrayRef<std::pair<QualType, SourceLocation>> ReductionTypes, 10993 AccessSpecifier AS, Decl *PrevDeclInScope) { 10994 SmallVector<Decl *, 8> Decls; 10995 Decls.reserve(ReductionTypes.size()); 10996 10997 LookupResult Lookup(*this, Name, SourceLocation(), LookupOMPReductionName, 10998 ForRedeclaration); 10999 // [OpenMP 4.0], 2.15 declare reduction Directive, Restrictions 11000 // A reduction-identifier may not be re-declared in the current scope for the 11001 // same type or for a type that is compatible according to the base language 11002 // rules. 11003 llvm::DenseMap<QualType, SourceLocation> PreviousRedeclTypes; 11004 OMPDeclareReductionDecl *PrevDRD = nullptr; 11005 bool InCompoundScope = true; 11006 if (S != nullptr) { 11007 // Find previous declaration with the same name not referenced in other 11008 // declarations. 11009 FunctionScopeInfo *ParentFn = getEnclosingFunction(); 11010 InCompoundScope = 11011 (ParentFn != nullptr) && !ParentFn->CompoundScopes.empty(); 11012 LookupName(Lookup, S); 11013 FilterLookupForScope(Lookup, DC, S, /*ConsiderLinkage=*/false, 11014 /*AllowInlineNamespace=*/false); 11015 llvm::DenseMap<OMPDeclareReductionDecl *, bool> UsedAsPrevious; 11016 auto Filter = Lookup.makeFilter(); 11017 while (Filter.hasNext()) { 11018 auto *PrevDecl = cast<OMPDeclareReductionDecl>(Filter.next()); 11019 if (InCompoundScope) { 11020 auto I = UsedAsPrevious.find(PrevDecl); 11021 if (I == UsedAsPrevious.end()) 11022 UsedAsPrevious[PrevDecl] = false; 11023 if (auto *D = PrevDecl->getPrevDeclInScope()) 11024 UsedAsPrevious[D] = true; 11025 } 11026 PreviousRedeclTypes[PrevDecl->getType().getCanonicalType()] = 11027 PrevDecl->getLocation(); 11028 } 11029 Filter.done(); 11030 if (InCompoundScope) { 11031 for (auto &PrevData : UsedAsPrevious) { 11032 if (!PrevData.second) { 11033 PrevDRD = PrevData.first; 11034 break; 11035 } 11036 } 11037 } 11038 } else if (PrevDeclInScope != nullptr) { 11039 auto *PrevDRDInScope = PrevDRD = 11040 cast<OMPDeclareReductionDecl>(PrevDeclInScope); 11041 do { 11042 PreviousRedeclTypes[PrevDRDInScope->getType().getCanonicalType()] = 11043 PrevDRDInScope->getLocation(); 11044 PrevDRDInScope = PrevDRDInScope->getPrevDeclInScope(); 11045 } while (PrevDRDInScope != nullptr); 11046 } 11047 for (auto &TyData : ReductionTypes) { 11048 auto I = PreviousRedeclTypes.find(TyData.first.getCanonicalType()); 11049 bool Invalid = false; 11050 if (I != PreviousRedeclTypes.end()) { 11051 Diag(TyData.second, diag::err_omp_declare_reduction_redefinition) 11052 << TyData.first; 11053 Diag(I->second, diag::note_previous_definition); 11054 Invalid = true; 11055 } 11056 PreviousRedeclTypes[TyData.first.getCanonicalType()] = TyData.second; 11057 auto *DRD = OMPDeclareReductionDecl::Create(Context, DC, TyData.second, 11058 Name, TyData.first, PrevDRD); 11059 DC->addDecl(DRD); 11060 DRD->setAccess(AS); 11061 Decls.push_back(DRD); 11062 if (Invalid) 11063 DRD->setInvalidDecl(); 11064 else 11065 PrevDRD = DRD; 11066 } 11067 11068 return DeclGroupPtrTy::make( 11069 DeclGroupRef::Create(Context, Decls.begin(), Decls.size())); 11070 } 11071 11072 void Sema::ActOnOpenMPDeclareReductionCombinerStart(Scope *S, Decl *D) { 11073 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11074 11075 // Enter new function scope. 11076 PushFunctionScope(); 11077 getCurFunction()->setHasBranchProtectedScope(); 11078 getCurFunction()->setHasOMPDeclareReductionCombiner(); 11079 11080 if (S != nullptr) 11081 PushDeclContext(S, DRD); 11082 else 11083 CurContext = DRD; 11084 11085 PushExpressionEvaluationContext( 11086 ExpressionEvaluationContext::PotentiallyEvaluated); 11087 11088 QualType ReductionType = DRD->getType(); 11089 // Create 'T* omp_parm;T omp_in;'. All references to 'omp_in' will 11090 // be replaced by '*omp_parm' during codegen. This required because 'omp_in' 11091 // uses semantics of argument handles by value, but it should be passed by 11092 // reference. C lang does not support references, so pass all parameters as 11093 // pointers. 11094 // Create 'T omp_in;' variable. 11095 auto *OmpInParm = 11096 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_in"); 11097 // Create 'T* omp_parm;T omp_out;'. All references to 'omp_out' will 11098 // be replaced by '*omp_parm' during codegen. This required because 'omp_out' 11099 // uses semantics of argument handles by value, but it should be passed by 11100 // reference. C lang does not support references, so pass all parameters as 11101 // pointers. 11102 // Create 'T omp_out;' variable. 11103 auto *OmpOutParm = 11104 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_out"); 11105 if (S != nullptr) { 11106 PushOnScopeChains(OmpInParm, S); 11107 PushOnScopeChains(OmpOutParm, S); 11108 } else { 11109 DRD->addDecl(OmpInParm); 11110 DRD->addDecl(OmpOutParm); 11111 } 11112 } 11113 11114 void Sema::ActOnOpenMPDeclareReductionCombinerEnd(Decl *D, Expr *Combiner) { 11115 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11116 DiscardCleanupsInEvaluationContext(); 11117 PopExpressionEvaluationContext(); 11118 11119 PopDeclContext(); 11120 PopFunctionScopeInfo(); 11121 11122 if (Combiner != nullptr) 11123 DRD->setCombiner(Combiner); 11124 else 11125 DRD->setInvalidDecl(); 11126 } 11127 11128 void Sema::ActOnOpenMPDeclareReductionInitializerStart(Scope *S, Decl *D) { 11129 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11130 11131 // Enter new function scope. 11132 PushFunctionScope(); 11133 getCurFunction()->setHasBranchProtectedScope(); 11134 11135 if (S != nullptr) 11136 PushDeclContext(S, DRD); 11137 else 11138 CurContext = DRD; 11139 11140 PushExpressionEvaluationContext( 11141 ExpressionEvaluationContext::PotentiallyEvaluated); 11142 11143 QualType ReductionType = DRD->getType(); 11144 // Create 'T* omp_parm;T omp_priv;'. All references to 'omp_priv' will 11145 // be replaced by '*omp_parm' during codegen. This required because 'omp_priv' 11146 // uses semantics of argument handles by value, but it should be passed by 11147 // reference. C lang does not support references, so pass all parameters as 11148 // pointers. 11149 // Create 'T omp_priv;' variable. 11150 auto *OmpPrivParm = 11151 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_priv"); 11152 // Create 'T* omp_parm;T omp_orig;'. All references to 'omp_orig' will 11153 // be replaced by '*omp_parm' during codegen. This required because 'omp_orig' 11154 // uses semantics of argument handles by value, but it should be passed by 11155 // reference. C lang does not support references, so pass all parameters as 11156 // pointers. 11157 // Create 'T omp_orig;' variable. 11158 auto *OmpOrigParm = 11159 buildVarDecl(*this, D->getLocation(), ReductionType, "omp_orig"); 11160 if (S != nullptr) { 11161 PushOnScopeChains(OmpPrivParm, S); 11162 PushOnScopeChains(OmpOrigParm, S); 11163 } else { 11164 DRD->addDecl(OmpPrivParm); 11165 DRD->addDecl(OmpOrigParm); 11166 } 11167 } 11168 11169 void Sema::ActOnOpenMPDeclareReductionInitializerEnd(Decl *D, 11170 Expr *Initializer) { 11171 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11172 DiscardCleanupsInEvaluationContext(); 11173 PopExpressionEvaluationContext(); 11174 11175 PopDeclContext(); 11176 PopFunctionScopeInfo(); 11177 11178 if (Initializer != nullptr) 11179 DRD->setInitializer(Initializer); 11180 else 11181 DRD->setInvalidDecl(); 11182 } 11183 11184 Sema::DeclGroupPtrTy Sema::ActOnOpenMPDeclareReductionDirectiveEnd( 11185 Scope *S, DeclGroupPtrTy DeclReductions, bool IsValid) { 11186 for (auto *D : DeclReductions.get()) { 11187 if (IsValid) { 11188 auto *DRD = cast<OMPDeclareReductionDecl>(D); 11189 if (S != nullptr) 11190 PushOnScopeChains(DRD, S, /*AddToContext=*/false); 11191 } else 11192 D->setInvalidDecl(); 11193 } 11194 return DeclReductions; 11195 } 11196 11197 OMPClause *Sema::ActOnOpenMPNumTeamsClause(Expr *NumTeams, 11198 SourceLocation StartLoc, 11199 SourceLocation LParenLoc, 11200 SourceLocation EndLoc) { 11201 Expr *ValExpr = NumTeams; 11202 Stmt *HelperValStmt = nullptr; 11203 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11204 11205 // OpenMP [teams Constrcut, Restrictions] 11206 // The num_teams expression must evaluate to a positive integer value. 11207 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_teams, 11208 /*StrictlyPositive=*/true)) 11209 return nullptr; 11210 11211 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11212 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_num_teams); 11213 if (CaptureRegion != OMPD_unknown) { 11214 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 11215 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11216 HelperValStmt = buildPreInits(Context, Captures); 11217 } 11218 11219 return new (Context) OMPNumTeamsClause(ValExpr, HelperValStmt, CaptureRegion, 11220 StartLoc, LParenLoc, EndLoc); 11221 } 11222 11223 OMPClause *Sema::ActOnOpenMPThreadLimitClause(Expr *ThreadLimit, 11224 SourceLocation StartLoc, 11225 SourceLocation LParenLoc, 11226 SourceLocation EndLoc) { 11227 Expr *ValExpr = ThreadLimit; 11228 Stmt *HelperValStmt = nullptr; 11229 OpenMPDirectiveKind CaptureRegion = OMPD_unknown; 11230 11231 // OpenMP [teams Constrcut, Restrictions] 11232 // The thread_limit expression must evaluate to a positive integer value. 11233 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_thread_limit, 11234 /*StrictlyPositive=*/true)) 11235 return nullptr; 11236 11237 OpenMPDirectiveKind DKind = DSAStack->getCurrentDirective(); 11238 CaptureRegion = getOpenMPCaptureRegionForClause(DKind, OMPC_thread_limit); 11239 if (CaptureRegion != OMPD_unknown) { 11240 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 11241 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11242 HelperValStmt = buildPreInits(Context, Captures); 11243 } 11244 11245 return new (Context) OMPThreadLimitClause( 11246 ValExpr, HelperValStmt, CaptureRegion, StartLoc, LParenLoc, EndLoc); 11247 } 11248 11249 OMPClause *Sema::ActOnOpenMPPriorityClause(Expr *Priority, 11250 SourceLocation StartLoc, 11251 SourceLocation LParenLoc, 11252 SourceLocation EndLoc) { 11253 Expr *ValExpr = Priority; 11254 11255 // OpenMP [2.9.1, task Constrcut] 11256 // The priority-value is a non-negative numerical scalar expression. 11257 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_priority, 11258 /*StrictlyPositive=*/false)) 11259 return nullptr; 11260 11261 return new (Context) OMPPriorityClause(ValExpr, StartLoc, LParenLoc, EndLoc); 11262 } 11263 11264 OMPClause *Sema::ActOnOpenMPGrainsizeClause(Expr *Grainsize, 11265 SourceLocation StartLoc, 11266 SourceLocation LParenLoc, 11267 SourceLocation EndLoc) { 11268 Expr *ValExpr = Grainsize; 11269 11270 // OpenMP [2.9.2, taskloop Constrcut] 11271 // The parameter of the grainsize clause must be a positive integer 11272 // expression. 11273 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_grainsize, 11274 /*StrictlyPositive=*/true)) 11275 return nullptr; 11276 11277 return new (Context) OMPGrainsizeClause(ValExpr, StartLoc, LParenLoc, EndLoc); 11278 } 11279 11280 OMPClause *Sema::ActOnOpenMPNumTasksClause(Expr *NumTasks, 11281 SourceLocation StartLoc, 11282 SourceLocation LParenLoc, 11283 SourceLocation EndLoc) { 11284 Expr *ValExpr = NumTasks; 11285 11286 // OpenMP [2.9.2, taskloop Constrcut] 11287 // The parameter of the num_tasks clause must be a positive integer 11288 // expression. 11289 if (!IsNonNegativeIntegerValue(ValExpr, *this, OMPC_num_tasks, 11290 /*StrictlyPositive=*/true)) 11291 return nullptr; 11292 11293 return new (Context) OMPNumTasksClause(ValExpr, StartLoc, LParenLoc, EndLoc); 11294 } 11295 11296 OMPClause *Sema::ActOnOpenMPHintClause(Expr *Hint, SourceLocation StartLoc, 11297 SourceLocation LParenLoc, 11298 SourceLocation EndLoc) { 11299 // OpenMP [2.13.2, critical construct, Description] 11300 // ... where hint-expression is an integer constant expression that evaluates 11301 // to a valid lock hint. 11302 ExprResult HintExpr = VerifyPositiveIntegerConstantInClause(Hint, OMPC_hint); 11303 if (HintExpr.isInvalid()) 11304 return nullptr; 11305 return new (Context) 11306 OMPHintClause(HintExpr.get(), StartLoc, LParenLoc, EndLoc); 11307 } 11308 11309 OMPClause *Sema::ActOnOpenMPDistScheduleClause( 11310 OpenMPDistScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 11311 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 11312 SourceLocation EndLoc) { 11313 if (Kind == OMPC_DIST_SCHEDULE_unknown) { 11314 std::string Values; 11315 Values += "'"; 11316 Values += getOpenMPSimpleClauseTypeName(OMPC_dist_schedule, 0); 11317 Values += "'"; 11318 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 11319 << Values << getOpenMPClauseName(OMPC_dist_schedule); 11320 return nullptr; 11321 } 11322 Expr *ValExpr = ChunkSize; 11323 Stmt *HelperValStmt = nullptr; 11324 if (ChunkSize) { 11325 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 11326 !ChunkSize->isInstantiationDependent() && 11327 !ChunkSize->containsUnexpandedParameterPack()) { 11328 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 11329 ExprResult Val = 11330 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 11331 if (Val.isInvalid()) 11332 return nullptr; 11333 11334 ValExpr = Val.get(); 11335 11336 // OpenMP [2.7.1, Restrictions] 11337 // chunk_size must be a loop invariant integer expression with a positive 11338 // value. 11339 llvm::APSInt Result; 11340 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 11341 if (Result.isSigned() && !Result.isStrictlyPositive()) { 11342 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 11343 << "dist_schedule" << ChunkSize->getSourceRange(); 11344 return nullptr; 11345 } 11346 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) && 11347 !CurContext->isDependentContext()) { 11348 llvm::MapVector<Expr *, DeclRefExpr *> Captures; 11349 ValExpr = tryBuildCapture(*this, ValExpr, Captures).get(); 11350 HelperValStmt = buildPreInits(Context, Captures); 11351 } 11352 } 11353 } 11354 11355 return new (Context) 11356 OMPDistScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, EndLoc, 11357 Kind, ValExpr, HelperValStmt); 11358 } 11359 11360 OMPClause *Sema::ActOnOpenMPDefaultmapClause( 11361 OpenMPDefaultmapClauseModifier M, OpenMPDefaultmapClauseKind Kind, 11362 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation MLoc, 11363 SourceLocation KindLoc, SourceLocation EndLoc) { 11364 // OpenMP 4.5 only supports 'defaultmap(tofrom: scalar)' 11365 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom || Kind != OMPC_DEFAULTMAP_scalar) { 11366 std::string Value; 11367 SourceLocation Loc; 11368 Value += "'"; 11369 if (M != OMPC_DEFAULTMAP_MODIFIER_tofrom) { 11370 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 11371 OMPC_DEFAULTMAP_MODIFIER_tofrom); 11372 Loc = MLoc; 11373 } else { 11374 Value += getOpenMPSimpleClauseTypeName(OMPC_defaultmap, 11375 OMPC_DEFAULTMAP_scalar); 11376 Loc = KindLoc; 11377 } 11378 Value += "'"; 11379 Diag(Loc, diag::err_omp_unexpected_clause_value) 11380 << Value << getOpenMPClauseName(OMPC_defaultmap); 11381 return nullptr; 11382 } 11383 11384 return new (Context) 11385 OMPDefaultmapClause(StartLoc, LParenLoc, MLoc, KindLoc, EndLoc, Kind, M); 11386 } 11387 11388 bool Sema::ActOnStartOpenMPDeclareTargetDirective(SourceLocation Loc) { 11389 DeclContext *CurLexicalContext = getCurLexicalContext(); 11390 if (!CurLexicalContext->isFileContext() && 11391 !CurLexicalContext->isExternCContext() && 11392 !CurLexicalContext->isExternCXXContext()) { 11393 Diag(Loc, diag::err_omp_region_not_file_context); 11394 return false; 11395 } 11396 if (IsInOpenMPDeclareTargetContext) { 11397 Diag(Loc, diag::err_omp_enclosed_declare_target); 11398 return false; 11399 } 11400 11401 IsInOpenMPDeclareTargetContext = true; 11402 return true; 11403 } 11404 11405 void Sema::ActOnFinishOpenMPDeclareTargetDirective() { 11406 assert(IsInOpenMPDeclareTargetContext && 11407 "Unexpected ActOnFinishOpenMPDeclareTargetDirective"); 11408 11409 IsInOpenMPDeclareTargetContext = false; 11410 } 11411 11412 void Sema::ActOnOpenMPDeclareTargetName(Scope *CurScope, 11413 CXXScopeSpec &ScopeSpec, 11414 const DeclarationNameInfo &Id, 11415 OMPDeclareTargetDeclAttr::MapTypeTy MT, 11416 NamedDeclSetType &SameDirectiveDecls) { 11417 LookupResult Lookup(*this, Id, LookupOrdinaryName); 11418 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 11419 11420 if (Lookup.isAmbiguous()) 11421 return; 11422 Lookup.suppressDiagnostics(); 11423 11424 if (!Lookup.isSingleResult()) { 11425 if (TypoCorrection Corrected = 11426 CorrectTypo(Id, LookupOrdinaryName, CurScope, nullptr, 11427 llvm::make_unique<VarOrFuncDeclFilterCCC>(*this), 11428 CTK_ErrorRecovery)) { 11429 diagnoseTypo(Corrected, PDiag(diag::err_undeclared_var_use_suggest) 11430 << Id.getName()); 11431 checkDeclIsAllowedInOpenMPTarget(nullptr, Corrected.getCorrectionDecl()); 11432 return; 11433 } 11434 11435 Diag(Id.getLoc(), diag::err_undeclared_var_use) << Id.getName(); 11436 return; 11437 } 11438 11439 NamedDecl *ND = Lookup.getAsSingle<NamedDecl>(); 11440 if (isa<VarDecl>(ND) || isa<FunctionDecl>(ND)) { 11441 if (!SameDirectiveDecls.insert(cast<NamedDecl>(ND->getCanonicalDecl()))) 11442 Diag(Id.getLoc(), diag::err_omp_declare_target_multiple) << Id.getName(); 11443 11444 if (!ND->hasAttr<OMPDeclareTargetDeclAttr>()) { 11445 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit(Context, MT); 11446 ND->addAttr(A); 11447 if (ASTMutationListener *ML = Context.getASTMutationListener()) 11448 ML->DeclarationMarkedOpenMPDeclareTarget(ND, A); 11449 checkDeclIsAllowedInOpenMPTarget(nullptr, ND); 11450 } else if (ND->getAttr<OMPDeclareTargetDeclAttr>()->getMapType() != MT) { 11451 Diag(Id.getLoc(), diag::err_omp_declare_target_to_and_link) 11452 << Id.getName(); 11453 } 11454 } else 11455 Diag(Id.getLoc(), diag::err_omp_invalid_target_decl) << Id.getName(); 11456 } 11457 11458 static void checkDeclInTargetContext(SourceLocation SL, SourceRange SR, 11459 Sema &SemaRef, Decl *D) { 11460 if (!D) 11461 return; 11462 Decl *LD = nullptr; 11463 if (isa<TagDecl>(D)) { 11464 LD = cast<TagDecl>(D)->getDefinition(); 11465 } else if (isa<VarDecl>(D)) { 11466 LD = cast<VarDecl>(D)->getDefinition(); 11467 11468 // If this is an implicit variable that is legal and we do not need to do 11469 // anything. 11470 if (cast<VarDecl>(D)->isImplicit()) { 11471 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11472 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 11473 D->addAttr(A); 11474 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 11475 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 11476 return; 11477 } 11478 11479 } else if (isa<FunctionDecl>(D)) { 11480 const FunctionDecl *FD = nullptr; 11481 if (cast<FunctionDecl>(D)->hasBody(FD)) 11482 LD = const_cast<FunctionDecl *>(FD); 11483 11484 // If the definition is associated with the current declaration in the 11485 // target region (it can be e.g. a lambda) that is legal and we do not need 11486 // to do anything else. 11487 if (LD == D) { 11488 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11489 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 11490 D->addAttr(A); 11491 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 11492 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 11493 return; 11494 } 11495 } 11496 if (!LD) 11497 LD = D; 11498 if (LD && !LD->hasAttr<OMPDeclareTargetDeclAttr>() && 11499 (isa<VarDecl>(LD) || isa<FunctionDecl>(LD))) { 11500 // Outlined declaration is not declared target. 11501 if (LD->isOutOfLine()) { 11502 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 11503 SemaRef.Diag(SL, diag::note_used_here) << SR; 11504 } else { 11505 DeclContext *DC = LD->getDeclContext(); 11506 while (DC) { 11507 if (isa<FunctionDecl>(DC) && 11508 cast<FunctionDecl>(DC)->hasAttr<OMPDeclareTargetDeclAttr>()) 11509 break; 11510 DC = DC->getParent(); 11511 } 11512 if (DC) 11513 return; 11514 11515 // Is not declared in target context. 11516 SemaRef.Diag(LD->getLocation(), diag::warn_omp_not_in_target_context); 11517 SemaRef.Diag(SL, diag::note_used_here) << SR; 11518 } 11519 // Mark decl as declared target to prevent further diagnostic. 11520 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11521 SemaRef.Context, OMPDeclareTargetDeclAttr::MT_To); 11522 D->addAttr(A); 11523 if (ASTMutationListener *ML = SemaRef.Context.getASTMutationListener()) 11524 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 11525 } 11526 } 11527 11528 static bool checkValueDeclInTarget(SourceLocation SL, SourceRange SR, 11529 Sema &SemaRef, DSAStackTy *Stack, 11530 ValueDecl *VD) { 11531 if (VD->hasAttr<OMPDeclareTargetDeclAttr>()) 11532 return true; 11533 if (!CheckTypeMappable(SL, SR, SemaRef, Stack, VD->getType())) 11534 return false; 11535 return true; 11536 } 11537 11538 void Sema::checkDeclIsAllowedInOpenMPTarget(Expr *E, Decl *D) { 11539 if (!D || D->isInvalidDecl()) 11540 return; 11541 SourceRange SR = E ? E->getSourceRange() : D->getSourceRange(); 11542 SourceLocation SL = E ? E->getLocStart() : D->getLocation(); 11543 // 2.10.6: threadprivate variable cannot appear in a declare target directive. 11544 if (VarDecl *VD = dyn_cast<VarDecl>(D)) { 11545 if (DSAStack->isThreadPrivate(VD)) { 11546 Diag(SL, diag::err_omp_threadprivate_in_target); 11547 ReportOriginalDSA(*this, DSAStack, VD, DSAStack->getTopDSA(VD, false)); 11548 return; 11549 } 11550 } 11551 if (ValueDecl *VD = dyn_cast<ValueDecl>(D)) { 11552 // Problem if any with var declared with incomplete type will be reported 11553 // as normal, so no need to check it here. 11554 if ((E || !VD->getType()->isIncompleteType()) && 11555 !checkValueDeclInTarget(SL, SR, *this, DSAStack, VD)) { 11556 // Mark decl as declared target to prevent further diagnostic. 11557 if (isa<VarDecl>(VD) || isa<FunctionDecl>(VD)) { 11558 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11559 Context, OMPDeclareTargetDeclAttr::MT_To); 11560 VD->addAttr(A); 11561 if (ASTMutationListener *ML = Context.getASTMutationListener()) 11562 ML->DeclarationMarkedOpenMPDeclareTarget(VD, A); 11563 } 11564 return; 11565 } 11566 } 11567 if (!E) { 11568 // Checking declaration inside declare target region. 11569 if (!D->hasAttr<OMPDeclareTargetDeclAttr>() && 11570 (isa<VarDecl>(D) || isa<FunctionDecl>(D))) { 11571 Attr *A = OMPDeclareTargetDeclAttr::CreateImplicit( 11572 Context, OMPDeclareTargetDeclAttr::MT_To); 11573 D->addAttr(A); 11574 if (ASTMutationListener *ML = Context.getASTMutationListener()) 11575 ML->DeclarationMarkedOpenMPDeclareTarget(D, A); 11576 } 11577 return; 11578 } 11579 checkDeclInTargetContext(E->getExprLoc(), E->getSourceRange(), *this, D); 11580 } 11581 11582 OMPClause *Sema::ActOnOpenMPToClause(ArrayRef<Expr *> VarList, 11583 SourceLocation StartLoc, 11584 SourceLocation LParenLoc, 11585 SourceLocation EndLoc) { 11586 MappableVarListInfo MVLI(VarList); 11587 checkMappableExpressionList(*this, DSAStack, OMPC_to, MVLI, StartLoc); 11588 if (MVLI.ProcessedVarList.empty()) 11589 return nullptr; 11590 11591 return OMPToClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11592 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 11593 MVLI.VarComponents); 11594 } 11595 11596 OMPClause *Sema::ActOnOpenMPFromClause(ArrayRef<Expr *> VarList, 11597 SourceLocation StartLoc, 11598 SourceLocation LParenLoc, 11599 SourceLocation EndLoc) { 11600 MappableVarListInfo MVLI(VarList); 11601 checkMappableExpressionList(*this, DSAStack, OMPC_from, MVLI, StartLoc); 11602 if (MVLI.ProcessedVarList.empty()) 11603 return nullptr; 11604 11605 return OMPFromClause::Create(Context, StartLoc, LParenLoc, EndLoc, 11606 MVLI.ProcessedVarList, MVLI.VarBaseDeclarations, 11607 MVLI.VarComponents); 11608 } 11609 11610 OMPClause *Sema::ActOnOpenMPUseDevicePtrClause(ArrayRef<Expr *> VarList, 11611 SourceLocation StartLoc, 11612 SourceLocation LParenLoc, 11613 SourceLocation EndLoc) { 11614 MappableVarListInfo MVLI(VarList); 11615 SmallVector<Expr *, 8> PrivateCopies; 11616 SmallVector<Expr *, 8> Inits; 11617 11618 for (auto &RefExpr : VarList) { 11619 assert(RefExpr && "NULL expr in OpenMP use_device_ptr clause."); 11620 SourceLocation ELoc; 11621 SourceRange ERange; 11622 Expr *SimpleRefExpr = RefExpr; 11623 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11624 if (Res.second) { 11625 // It will be analyzed later. 11626 MVLI.ProcessedVarList.push_back(RefExpr); 11627 PrivateCopies.push_back(nullptr); 11628 Inits.push_back(nullptr); 11629 } 11630 ValueDecl *D = Res.first; 11631 if (!D) 11632 continue; 11633 11634 QualType Type = D->getType(); 11635 Type = Type.getNonReferenceType().getUnqualifiedType(); 11636 11637 auto *VD = dyn_cast<VarDecl>(D); 11638 11639 // Item should be a pointer or reference to pointer. 11640 if (!Type->isPointerType()) { 11641 Diag(ELoc, diag::err_omp_usedeviceptr_not_a_pointer) 11642 << 0 << RefExpr->getSourceRange(); 11643 continue; 11644 } 11645 11646 // Build the private variable and the expression that refers to it. 11647 auto VDPrivate = buildVarDecl(*this, ELoc, Type, D->getName(), 11648 D->hasAttrs() ? &D->getAttrs() : nullptr); 11649 if (VDPrivate->isInvalidDecl()) 11650 continue; 11651 11652 CurContext->addDecl(VDPrivate); 11653 auto VDPrivateRefExpr = buildDeclRefExpr( 11654 *this, VDPrivate, RefExpr->getType().getUnqualifiedType(), ELoc); 11655 11656 // Add temporary variable to initialize the private copy of the pointer. 11657 auto *VDInit = 11658 buildVarDecl(*this, RefExpr->getExprLoc(), Type, ".devptr.temp"); 11659 auto *VDInitRefExpr = buildDeclRefExpr(*this, VDInit, RefExpr->getType(), 11660 RefExpr->getExprLoc()); 11661 AddInitializerToDecl(VDPrivate, 11662 DefaultLvalueConversion(VDInitRefExpr).get(), 11663 /*DirectInit=*/false); 11664 11665 // If required, build a capture to implement the privatization initialized 11666 // with the current list item value. 11667 DeclRefExpr *Ref = nullptr; 11668 if (!VD) 11669 Ref = buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/true); 11670 MVLI.ProcessedVarList.push_back(VD ? RefExpr->IgnoreParens() : Ref); 11671 PrivateCopies.push_back(VDPrivateRefExpr); 11672 Inits.push_back(VDInitRefExpr); 11673 11674 // We need to add a data sharing attribute for this variable to make sure it 11675 // is correctly captured. A variable that shows up in a use_device_ptr has 11676 // similar properties of a first private variable. 11677 DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_firstprivate, Ref); 11678 11679 // Create a mappable component for the list item. List items in this clause 11680 // only need a component. 11681 MVLI.VarBaseDeclarations.push_back(D); 11682 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 11683 MVLI.VarComponents.back().push_back( 11684 OMPClauseMappableExprCommon::MappableComponent(SimpleRefExpr, D)); 11685 } 11686 11687 if (MVLI.ProcessedVarList.empty()) 11688 return nullptr; 11689 11690 return OMPUseDevicePtrClause::Create( 11691 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 11692 PrivateCopies, Inits, MVLI.VarBaseDeclarations, MVLI.VarComponents); 11693 } 11694 11695 OMPClause *Sema::ActOnOpenMPIsDevicePtrClause(ArrayRef<Expr *> VarList, 11696 SourceLocation StartLoc, 11697 SourceLocation LParenLoc, 11698 SourceLocation EndLoc) { 11699 MappableVarListInfo MVLI(VarList); 11700 for (auto &RefExpr : VarList) { 11701 assert(RefExpr && "NULL expr in OpenMP is_device_ptr clause."); 11702 SourceLocation ELoc; 11703 SourceRange ERange; 11704 Expr *SimpleRefExpr = RefExpr; 11705 auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange); 11706 if (Res.second) { 11707 // It will be analyzed later. 11708 MVLI.ProcessedVarList.push_back(RefExpr); 11709 } 11710 ValueDecl *D = Res.first; 11711 if (!D) 11712 continue; 11713 11714 QualType Type = D->getType(); 11715 // item should be a pointer or array or reference to pointer or array 11716 if (!Type.getNonReferenceType()->isPointerType() && 11717 !Type.getNonReferenceType()->isArrayType()) { 11718 Diag(ELoc, diag::err_omp_argument_type_isdeviceptr) 11719 << 0 << RefExpr->getSourceRange(); 11720 continue; 11721 } 11722 11723 // Check if the declaration in the clause does not show up in any data 11724 // sharing attribute. 11725 auto DVar = DSAStack->getTopDSA(D, false); 11726 if (isOpenMPPrivate(DVar.CKind)) { 11727 Diag(ELoc, diag::err_omp_variable_in_given_clause_and_dsa) 11728 << getOpenMPClauseName(DVar.CKind) 11729 << getOpenMPClauseName(OMPC_is_device_ptr) 11730 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 11731 ReportOriginalDSA(*this, DSAStack, D, DVar); 11732 continue; 11733 } 11734 11735 Expr *ConflictExpr; 11736 if (DSAStack->checkMappableExprComponentListsForDecl( 11737 D, /*CurrentRegionOnly=*/true, 11738 [&ConflictExpr]( 11739 OMPClauseMappableExprCommon::MappableExprComponentListRef R, 11740 OpenMPClauseKind) -> bool { 11741 ConflictExpr = R.front().getAssociatedExpression(); 11742 return true; 11743 })) { 11744 Diag(ELoc, diag::err_omp_map_shared_storage) << RefExpr->getSourceRange(); 11745 Diag(ConflictExpr->getExprLoc(), diag::note_used_here) 11746 << ConflictExpr->getSourceRange(); 11747 continue; 11748 } 11749 11750 // Store the components in the stack so that they can be used to check 11751 // against other clauses later on. 11752 OMPClauseMappableExprCommon::MappableComponent MC(SimpleRefExpr, D); 11753 DSAStack->addMappableExpressionComponents( 11754 D, MC, /*WhereFoundClauseKind=*/OMPC_is_device_ptr); 11755 11756 // Record the expression we've just processed. 11757 MVLI.ProcessedVarList.push_back(SimpleRefExpr); 11758 11759 // Create a mappable component for the list item. List items in this clause 11760 // only need a component. We use a null declaration to signal fields in 11761 // 'this'. 11762 assert((isa<DeclRefExpr>(SimpleRefExpr) || 11763 isa<CXXThisExpr>(cast<MemberExpr>(SimpleRefExpr)->getBase())) && 11764 "Unexpected device pointer expression!"); 11765 MVLI.VarBaseDeclarations.push_back( 11766 isa<DeclRefExpr>(SimpleRefExpr) ? D : nullptr); 11767 MVLI.VarComponents.resize(MVLI.VarComponents.size() + 1); 11768 MVLI.VarComponents.back().push_back(MC); 11769 } 11770 11771 if (MVLI.ProcessedVarList.empty()) 11772 return nullptr; 11773 11774 return OMPIsDevicePtrClause::Create( 11775 Context, StartLoc, LParenLoc, EndLoc, MVLI.ProcessedVarList, 11776 MVLI.VarBaseDeclarations, MVLI.VarComponents); 11777 } 11778