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 "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTMutationListener.h" 17 #include "clang/AST/Decl.h" 18 #include "clang/AST/DeclCXX.h" 19 #include "clang/AST/DeclOpenMP.h" 20 #include "clang/AST/StmtCXX.h" 21 #include "clang/AST/StmtOpenMP.h" 22 #include "clang/AST/StmtVisitor.h" 23 #include "clang/Basic/OpenMPKinds.h" 24 #include "clang/Basic/TargetInfo.h" 25 #include "clang/Lex/Preprocessor.h" 26 #include "clang/Sema/Initialization.h" 27 #include "clang/Sema/Lookup.h" 28 #include "clang/Sema/Scope.h" 29 #include "clang/Sema/ScopeInfo.h" 30 #include "clang/Sema/SemaInternal.h" 31 using namespace clang; 32 33 //===----------------------------------------------------------------------===// 34 // Stack of data-sharing attributes for variables 35 //===----------------------------------------------------------------------===// 36 37 namespace { 38 /// \brief Default data sharing attributes, which can be applied to directive. 39 enum DefaultDataSharingAttributes { 40 DSA_unspecified = 0, /// \brief Data sharing attribute not specified. 41 DSA_none = 1 << 0, /// \brief Default data sharing attribute 'none'. 42 DSA_shared = 1 << 1 /// \brief Default data sharing attribute 'shared'. 43 }; 44 45 template <class T> struct MatchesAny { 46 explicit MatchesAny(ArrayRef<T> Arr) : Arr(std::move(Arr)) {} 47 bool operator()(T Kind) { 48 for (auto KindEl : Arr) 49 if (KindEl == Kind) 50 return true; 51 return false; 52 } 53 54 private: 55 ArrayRef<T> Arr; 56 }; 57 struct MatchesAlways { 58 MatchesAlways() {} 59 template <class T> bool operator()(T) { return true; } 60 }; 61 62 typedef MatchesAny<OpenMPClauseKind> MatchesAnyClause; 63 typedef MatchesAny<OpenMPDirectiveKind> MatchesAnyDirective; 64 65 /// \brief Stack for tracking declarations used in OpenMP directives and 66 /// clauses and their data-sharing attributes. 67 class DSAStackTy { 68 public: 69 struct DSAVarData { 70 OpenMPDirectiveKind DKind; 71 OpenMPClauseKind CKind; 72 DeclRefExpr *RefExpr; 73 SourceLocation ImplicitDSALoc; 74 DSAVarData() 75 : DKind(OMPD_unknown), CKind(OMPC_unknown), RefExpr(nullptr), 76 ImplicitDSALoc() {} 77 }; 78 79 private: 80 struct DSAInfo { 81 OpenMPClauseKind Attributes; 82 DeclRefExpr *RefExpr; 83 }; 84 typedef llvm::SmallDenseMap<VarDecl *, DSAInfo, 64> DeclSAMapTy; 85 typedef llvm::SmallDenseMap<VarDecl *, DeclRefExpr *, 64> AlignedMapTy; 86 typedef llvm::DenseSet<VarDecl *> LoopControlVariablesSetTy; 87 88 struct SharingMapTy { 89 DeclSAMapTy SharingMap; 90 AlignedMapTy AlignedMap; 91 LoopControlVariablesSetTy LCVSet; 92 DefaultDataSharingAttributes DefaultAttr; 93 SourceLocation DefaultAttrLoc; 94 OpenMPDirectiveKind Directive; 95 DeclarationNameInfo DirectiveName; 96 Scope *CurScope; 97 SourceLocation ConstructLoc; 98 bool OrderedRegion; 99 bool NowaitRegion; 100 unsigned CollapseNumber; 101 SourceLocation InnerTeamsRegionLoc; 102 SharingMapTy(OpenMPDirectiveKind DKind, DeclarationNameInfo Name, 103 Scope *CurScope, SourceLocation Loc) 104 : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified), 105 Directive(DKind), DirectiveName(std::move(Name)), CurScope(CurScope), 106 ConstructLoc(Loc), OrderedRegion(false), NowaitRegion(false), 107 CollapseNumber(1), InnerTeamsRegionLoc() {} 108 SharingMapTy() 109 : SharingMap(), AlignedMap(), LCVSet(), DefaultAttr(DSA_unspecified), 110 Directive(OMPD_unknown), DirectiveName(), CurScope(nullptr), 111 ConstructLoc(), OrderedRegion(false), NowaitRegion(false), 112 CollapseNumber(1), InnerTeamsRegionLoc() {} 113 }; 114 115 typedef SmallVector<SharingMapTy, 64> StackTy; 116 117 /// \brief Stack of used declaration and their data-sharing attributes. 118 StackTy Stack; 119 /// \brief true, if check for DSA must be from parent directive, false, if 120 /// from current directive. 121 OpenMPClauseKind ClauseKindMode; 122 Sema &SemaRef; 123 bool ForceCapturing; 124 125 typedef SmallVector<SharingMapTy, 8>::reverse_iterator reverse_iterator; 126 127 DSAVarData getDSA(StackTy::reverse_iterator Iter, VarDecl *D); 128 129 /// \brief Checks if the variable is a local for OpenMP region. 130 bool isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter); 131 132 public: 133 explicit DSAStackTy(Sema &S) 134 : Stack(1), ClauseKindMode(OMPC_unknown), SemaRef(S), 135 ForceCapturing(false) {} 136 137 bool isClauseParsingMode() const { return ClauseKindMode != OMPC_unknown; } 138 void setClauseParsingMode(OpenMPClauseKind K) { ClauseKindMode = K; } 139 140 bool isForceVarCapturing() const { return ForceCapturing; } 141 void setForceVarCapturing(bool V) { ForceCapturing = V; } 142 143 void push(OpenMPDirectiveKind DKind, const DeclarationNameInfo &DirName, 144 Scope *CurScope, SourceLocation Loc) { 145 Stack.push_back(SharingMapTy(DKind, DirName, CurScope, Loc)); 146 Stack.back().DefaultAttrLoc = Loc; 147 } 148 149 void pop() { 150 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty!"); 151 Stack.pop_back(); 152 } 153 154 /// \brief If 'aligned' declaration for given variable \a D was not seen yet, 155 /// add it and return NULL; otherwise return previous occurrence's expression 156 /// for diagnostics. 157 DeclRefExpr *addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE); 158 159 /// \brief Register specified variable as loop control variable. 160 void addLoopControlVariable(VarDecl *D); 161 /// \brief Check if the specified variable is a loop control variable for 162 /// current region. 163 bool isLoopControlVariable(VarDecl *D); 164 165 /// \brief Adds explicit data sharing attribute to the specified declaration. 166 void addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A); 167 168 /// \brief Returns data sharing attributes from top of the stack for the 169 /// specified declaration. 170 DSAVarData getTopDSA(VarDecl *D, bool FromParent); 171 /// \brief Returns data-sharing attributes for the specified declaration. 172 DSAVarData getImplicitDSA(VarDecl *D, bool FromParent); 173 /// \brief Checks if the specified variables has data-sharing attributes which 174 /// match specified \a CPred predicate in any directive which matches \a DPred 175 /// predicate. 176 template <class ClausesPredicate, class DirectivesPredicate> 177 DSAVarData hasDSA(VarDecl *D, ClausesPredicate CPred, 178 DirectivesPredicate DPred, bool FromParent); 179 /// \brief Checks if the specified variables has data-sharing attributes which 180 /// match specified \a CPred predicate in any innermost directive which 181 /// matches \a DPred predicate. 182 template <class ClausesPredicate, class DirectivesPredicate> 183 DSAVarData hasInnermostDSA(VarDecl *D, ClausesPredicate CPred, 184 DirectivesPredicate DPred, 185 bool FromParent); 186 /// \brief Checks if the specified variables has explicit data-sharing 187 /// attributes which match specified \a CPred predicate at the specified 188 /// OpenMP region. 189 bool hasExplicitDSA(VarDecl *D, 190 const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 191 unsigned Level); 192 /// \brief Finds a directive which matches specified \a DPred predicate. 193 template <class NamedDirectivesPredicate> 194 bool hasDirective(NamedDirectivesPredicate DPred, bool FromParent); 195 196 /// \brief Returns currently analyzed directive. 197 OpenMPDirectiveKind getCurrentDirective() const { 198 return Stack.back().Directive; 199 } 200 /// \brief Returns parent directive. 201 OpenMPDirectiveKind getParentDirective() const { 202 if (Stack.size() > 2) 203 return Stack[Stack.size() - 2].Directive; 204 return OMPD_unknown; 205 } 206 207 /// \brief Set default data sharing attribute to none. 208 void setDefaultDSANone(SourceLocation Loc) { 209 Stack.back().DefaultAttr = DSA_none; 210 Stack.back().DefaultAttrLoc = Loc; 211 } 212 /// \brief Set default data sharing attribute to shared. 213 void setDefaultDSAShared(SourceLocation Loc) { 214 Stack.back().DefaultAttr = DSA_shared; 215 Stack.back().DefaultAttrLoc = Loc; 216 } 217 218 DefaultDataSharingAttributes getDefaultDSA() const { 219 return Stack.back().DefaultAttr; 220 } 221 SourceLocation getDefaultDSALocation() const { 222 return Stack.back().DefaultAttrLoc; 223 } 224 225 /// \brief Checks if the specified variable is a threadprivate. 226 bool isThreadPrivate(VarDecl *D) { 227 DSAVarData DVar = getTopDSA(D, false); 228 return isOpenMPThreadPrivate(DVar.CKind); 229 } 230 231 /// \brief Marks current region as ordered (it has an 'ordered' clause). 232 void setOrderedRegion(bool IsOrdered = true) { 233 Stack.back().OrderedRegion = IsOrdered; 234 } 235 /// \brief Returns true, if parent region is ordered (has associated 236 /// 'ordered' clause), false - otherwise. 237 bool isParentOrderedRegion() const { 238 if (Stack.size() > 2) 239 return Stack[Stack.size() - 2].OrderedRegion; 240 return false; 241 } 242 /// \brief Marks current region as nowait (it has a 'nowait' clause). 243 void setNowaitRegion(bool IsNowait = true) { 244 Stack.back().NowaitRegion = IsNowait; 245 } 246 /// \brief Returns true, if parent region is nowait (has associated 247 /// 'nowait' clause), false - otherwise. 248 bool isParentNowaitRegion() const { 249 if (Stack.size() > 2) 250 return Stack[Stack.size() - 2].NowaitRegion; 251 return false; 252 } 253 254 /// \brief Set collapse value for the region. 255 void setCollapseNumber(unsigned Val) { Stack.back().CollapseNumber = Val; } 256 /// \brief Return collapse value for region. 257 unsigned getCollapseNumber() const { 258 return Stack.back().CollapseNumber; 259 } 260 261 /// \brief Marks current target region as one with closely nested teams 262 /// region. 263 void setParentTeamsRegionLoc(SourceLocation TeamsRegionLoc) { 264 if (Stack.size() > 2) 265 Stack[Stack.size() - 2].InnerTeamsRegionLoc = TeamsRegionLoc; 266 } 267 /// \brief Returns true, if current region has closely nested teams region. 268 bool hasInnerTeamsRegion() const { 269 return getInnerTeamsRegionLoc().isValid(); 270 } 271 /// \brief Returns location of the nested teams region (if any). 272 SourceLocation getInnerTeamsRegionLoc() const { 273 if (Stack.size() > 1) 274 return Stack.back().InnerTeamsRegionLoc; 275 return SourceLocation(); 276 } 277 278 Scope *getCurScope() const { return Stack.back().CurScope; } 279 Scope *getCurScope() { return Stack.back().CurScope; } 280 SourceLocation getConstructLoc() { return Stack.back().ConstructLoc; } 281 }; 282 bool isParallelOrTaskRegion(OpenMPDirectiveKind DKind) { 283 return isOpenMPParallelDirective(DKind) || DKind == OMPD_task || 284 isOpenMPTeamsDirective(DKind) || DKind == OMPD_unknown; 285 } 286 } // namespace 287 288 DSAStackTy::DSAVarData DSAStackTy::getDSA(StackTy::reverse_iterator Iter, 289 VarDecl *D) { 290 D = D->getCanonicalDecl(); 291 DSAVarData DVar; 292 if (Iter == std::prev(Stack.rend())) { 293 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 294 // in a region but not in construct] 295 // File-scope or namespace-scope variables referenced in called routines 296 // in the region are shared unless they appear in a threadprivate 297 // directive. 298 if (!D->isFunctionOrMethodVarDecl() && !isa<ParmVarDecl>(D)) 299 DVar.CKind = OMPC_shared; 300 301 // OpenMP [2.9.1.2, Data-sharing Attribute Rules for Variables Referenced 302 // in a region but not in construct] 303 // Variables with static storage duration that are declared in called 304 // routines in the region are shared. 305 if (D->hasGlobalStorage()) 306 DVar.CKind = OMPC_shared; 307 308 return DVar; 309 } 310 311 DVar.DKind = Iter->Directive; 312 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 313 // in a Construct, C/C++, predetermined, p.1] 314 // Variables with automatic storage duration that are declared in a scope 315 // inside the construct are private. 316 if (isOpenMPLocal(D, Iter) && D->isLocalVarDecl() && 317 (D->getStorageClass() == SC_Auto || D->getStorageClass() == SC_None)) { 318 DVar.CKind = OMPC_private; 319 return DVar; 320 } 321 322 // Explicitly specified attributes and local variables with predetermined 323 // attributes. 324 if (Iter->SharingMap.count(D)) { 325 DVar.RefExpr = Iter->SharingMap[D].RefExpr; 326 DVar.CKind = Iter->SharingMap[D].Attributes; 327 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 328 return DVar; 329 } 330 331 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 332 // in a Construct, C/C++, implicitly determined, p.1] 333 // In a parallel or task construct, the data-sharing attributes of these 334 // variables are determined by the default clause, if present. 335 switch (Iter->DefaultAttr) { 336 case DSA_shared: 337 DVar.CKind = OMPC_shared; 338 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 339 return DVar; 340 case DSA_none: 341 return DVar; 342 case DSA_unspecified: 343 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 344 // in a Construct, implicitly determined, p.2] 345 // In a parallel construct, if no default clause is present, these 346 // variables are shared. 347 DVar.ImplicitDSALoc = Iter->DefaultAttrLoc; 348 if (isOpenMPParallelDirective(DVar.DKind) || 349 isOpenMPTeamsDirective(DVar.DKind)) { 350 DVar.CKind = OMPC_shared; 351 return DVar; 352 } 353 354 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 355 // in a Construct, implicitly determined, p.4] 356 // In a task construct, if no default clause is present, a variable that in 357 // the enclosing context is determined to be shared by all implicit tasks 358 // bound to the current team is shared. 359 if (DVar.DKind == OMPD_task) { 360 DSAVarData DVarTemp; 361 for (StackTy::reverse_iterator I = std::next(Iter), EE = Stack.rend(); 362 I != EE; ++I) { 363 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables 364 // Referenced 365 // in a Construct, implicitly determined, p.6] 366 // In a task construct, if no default clause is present, a variable 367 // whose data-sharing attribute is not determined by the rules above is 368 // firstprivate. 369 DVarTemp = getDSA(I, D); 370 if (DVarTemp.CKind != OMPC_shared) { 371 DVar.RefExpr = nullptr; 372 DVar.DKind = OMPD_task; 373 DVar.CKind = OMPC_firstprivate; 374 return DVar; 375 } 376 if (isParallelOrTaskRegion(I->Directive)) 377 break; 378 } 379 DVar.DKind = OMPD_task; 380 DVar.CKind = 381 (DVarTemp.CKind == OMPC_unknown) ? OMPC_firstprivate : OMPC_shared; 382 return DVar; 383 } 384 } 385 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 386 // in a Construct, implicitly determined, p.3] 387 // For constructs other than task, if no default clause is present, these 388 // variables inherit their data-sharing attributes from the enclosing 389 // context. 390 return getDSA(std::next(Iter), D); 391 } 392 393 DeclRefExpr *DSAStackTy::addUniqueAligned(VarDecl *D, DeclRefExpr *NewDE) { 394 assert(Stack.size() > 1 && "Data sharing attributes stack is empty"); 395 D = D->getCanonicalDecl(); 396 auto It = Stack.back().AlignedMap.find(D); 397 if (It == Stack.back().AlignedMap.end()) { 398 assert(NewDE && "Unexpected nullptr expr to be added into aligned map"); 399 Stack.back().AlignedMap[D] = NewDE; 400 return nullptr; 401 } else { 402 assert(It->second && "Unexpected nullptr expr in the aligned map"); 403 return It->second; 404 } 405 return nullptr; 406 } 407 408 void DSAStackTy::addLoopControlVariable(VarDecl *D) { 409 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 410 D = D->getCanonicalDecl(); 411 Stack.back().LCVSet.insert(D); 412 } 413 414 bool DSAStackTy::isLoopControlVariable(VarDecl *D) { 415 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 416 D = D->getCanonicalDecl(); 417 return Stack.back().LCVSet.count(D) > 0; 418 } 419 420 void DSAStackTy::addDSA(VarDecl *D, DeclRefExpr *E, OpenMPClauseKind A) { 421 D = D->getCanonicalDecl(); 422 if (A == OMPC_threadprivate) { 423 Stack[0].SharingMap[D].Attributes = A; 424 Stack[0].SharingMap[D].RefExpr = E; 425 } else { 426 assert(Stack.size() > 1 && "Data-sharing attributes stack is empty"); 427 Stack.back().SharingMap[D].Attributes = A; 428 Stack.back().SharingMap[D].RefExpr = E; 429 } 430 } 431 432 bool DSAStackTy::isOpenMPLocal(VarDecl *D, StackTy::reverse_iterator Iter) { 433 D = D->getCanonicalDecl(); 434 if (Stack.size() > 2) { 435 reverse_iterator I = Iter, E = std::prev(Stack.rend()); 436 Scope *TopScope = nullptr; 437 while (I != E && !isParallelOrTaskRegion(I->Directive)) { 438 ++I; 439 } 440 if (I == E) 441 return false; 442 TopScope = I->CurScope ? I->CurScope->getParent() : nullptr; 443 Scope *CurScope = getCurScope(); 444 while (CurScope != TopScope && !CurScope->isDeclScope(D)) { 445 CurScope = CurScope->getParent(); 446 } 447 return CurScope != TopScope; 448 } 449 return false; 450 } 451 452 /// \brief Build a variable declaration for OpenMP loop iteration variable. 453 static VarDecl *buildVarDecl(Sema &SemaRef, SourceLocation Loc, QualType Type, 454 StringRef Name) { 455 DeclContext *DC = SemaRef.CurContext; 456 IdentifierInfo *II = &SemaRef.PP.getIdentifierTable().get(Name); 457 TypeSourceInfo *TInfo = SemaRef.Context.getTrivialTypeSourceInfo(Type, Loc); 458 VarDecl *Decl = 459 VarDecl::Create(SemaRef.Context, DC, Loc, Loc, II, Type, TInfo, SC_None); 460 Decl->setImplicit(); 461 return Decl; 462 } 463 464 static DeclRefExpr *buildDeclRefExpr(Sema &S, VarDecl *D, QualType Ty, 465 SourceLocation Loc, 466 bool RefersToCapture = false) { 467 D->setReferenced(); 468 D->markUsed(S.Context); 469 return DeclRefExpr::Create(S.getASTContext(), NestedNameSpecifierLoc(), 470 SourceLocation(), D, RefersToCapture, Loc, Ty, 471 VK_LValue); 472 } 473 474 DSAStackTy::DSAVarData DSAStackTy::getTopDSA(VarDecl *D, bool FromParent) { 475 D = D->getCanonicalDecl(); 476 DSAVarData DVar; 477 478 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 479 // in a Construct, C/C++, predetermined, p.1] 480 // Variables appearing in threadprivate directives are threadprivate. 481 if ((D->getTLSKind() != VarDecl::TLS_None && 482 !(D->hasAttr<OMPThreadPrivateDeclAttr>() && 483 SemaRef.getLangOpts().OpenMPUseTLS && 484 SemaRef.getASTContext().getTargetInfo().isTLSSupported())) || 485 (D->getStorageClass() == SC_Register && D->hasAttr<AsmLabelAttr>() && 486 !D->isLocalVarDecl())) { 487 addDSA(D, buildDeclRefExpr(SemaRef, D, D->getType().getNonReferenceType(), 488 D->getLocation()), 489 OMPC_threadprivate); 490 } 491 if (Stack[0].SharingMap.count(D)) { 492 DVar.RefExpr = Stack[0].SharingMap[D].RefExpr; 493 DVar.CKind = OMPC_threadprivate; 494 return DVar; 495 } 496 497 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 498 // in a Construct, C/C++, predetermined, p.1] 499 // Variables with automatic storage duration that are declared in a scope 500 // inside the construct are private. 501 OpenMPDirectiveKind Kind = 502 FromParent ? getParentDirective() : getCurrentDirective(); 503 auto StartI = std::next(Stack.rbegin()); 504 auto EndI = std::prev(Stack.rend()); 505 if (FromParent && StartI != EndI) { 506 StartI = std::next(StartI); 507 } 508 if (!isParallelOrTaskRegion(Kind)) { 509 if (isOpenMPLocal(D, StartI) && 510 ((D->isLocalVarDecl() && (D->getStorageClass() == SC_Auto || 511 D->getStorageClass() == SC_None)) || 512 isa<ParmVarDecl>(D))) { 513 DVar.CKind = OMPC_private; 514 return DVar; 515 } 516 517 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 518 // in a Construct, C/C++, predetermined, p.4] 519 // Static data members are shared. 520 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 521 // in a Construct, C/C++, predetermined, p.7] 522 // Variables with static storage duration that are declared in a scope 523 // inside the construct are shared. 524 if (D->isStaticDataMember() || D->isStaticLocal()) { 525 DSAVarData DVarTemp = 526 hasDSA(D, isOpenMPPrivate, MatchesAlways(), FromParent); 527 if (DVarTemp.CKind != OMPC_unknown && DVarTemp.RefExpr) 528 return DVar; 529 530 DVar.CKind = OMPC_shared; 531 return DVar; 532 } 533 } 534 535 QualType Type = D->getType().getNonReferenceType().getCanonicalType(); 536 bool IsConstant = Type.isConstant(SemaRef.getASTContext()); 537 Type = SemaRef.getASTContext().getBaseElementType(Type); 538 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 539 // in a Construct, C/C++, predetermined, p.6] 540 // Variables with const qualified type having no mutable member are 541 // shared. 542 CXXRecordDecl *RD = 543 SemaRef.getLangOpts().CPlusPlus ? Type->getAsCXXRecordDecl() : nullptr; 544 if (IsConstant && 545 !(SemaRef.getLangOpts().CPlusPlus && RD && RD->hasMutableFields())) { 546 // Variables with const-qualified type having no mutable member may be 547 // listed in a firstprivate clause, even if they are static data members. 548 DSAVarData DVarTemp = hasDSA(D, MatchesAnyClause(OMPC_firstprivate), 549 MatchesAlways(), FromParent); 550 if (DVarTemp.CKind == OMPC_firstprivate && DVarTemp.RefExpr) 551 return DVar; 552 553 DVar.CKind = OMPC_shared; 554 return DVar; 555 } 556 557 // Explicitly specified attributes and local variables with predetermined 558 // attributes. 559 auto I = std::prev(StartI); 560 if (I->SharingMap.count(D)) { 561 DVar.RefExpr = I->SharingMap[D].RefExpr; 562 DVar.CKind = I->SharingMap[D].Attributes; 563 DVar.ImplicitDSALoc = I->DefaultAttrLoc; 564 } 565 566 return DVar; 567 } 568 569 DSAStackTy::DSAVarData DSAStackTy::getImplicitDSA(VarDecl *D, bool FromParent) { 570 D = D->getCanonicalDecl(); 571 auto StartI = Stack.rbegin(); 572 auto EndI = std::prev(Stack.rend()); 573 if (FromParent && StartI != EndI) { 574 StartI = std::next(StartI); 575 } 576 return getDSA(StartI, D); 577 } 578 579 template <class ClausesPredicate, class DirectivesPredicate> 580 DSAStackTy::DSAVarData DSAStackTy::hasDSA(VarDecl *D, ClausesPredicate CPred, 581 DirectivesPredicate DPred, 582 bool FromParent) { 583 D = D->getCanonicalDecl(); 584 auto StartI = std::next(Stack.rbegin()); 585 auto EndI = std::prev(Stack.rend()); 586 if (FromParent && StartI != EndI) { 587 StartI = std::next(StartI); 588 } 589 for (auto I = StartI, EE = EndI; I != EE; ++I) { 590 if (!DPred(I->Directive) && !isParallelOrTaskRegion(I->Directive)) 591 continue; 592 DSAVarData DVar = getDSA(I, D); 593 if (CPred(DVar.CKind)) 594 return DVar; 595 } 596 return DSAVarData(); 597 } 598 599 template <class ClausesPredicate, class DirectivesPredicate> 600 DSAStackTy::DSAVarData 601 DSAStackTy::hasInnermostDSA(VarDecl *D, ClausesPredicate CPred, 602 DirectivesPredicate DPred, bool FromParent) { 603 D = D->getCanonicalDecl(); 604 auto StartI = std::next(Stack.rbegin()); 605 auto EndI = std::prev(Stack.rend()); 606 if (FromParent && StartI != EndI) { 607 StartI = std::next(StartI); 608 } 609 for (auto I = StartI, EE = EndI; I != EE; ++I) { 610 if (!DPred(I->Directive)) 611 break; 612 DSAVarData DVar = getDSA(I, D); 613 if (CPred(DVar.CKind)) 614 return DVar; 615 return DSAVarData(); 616 } 617 return DSAVarData(); 618 } 619 620 bool DSAStackTy::hasExplicitDSA( 621 VarDecl *D, const llvm::function_ref<bool(OpenMPClauseKind)> &CPred, 622 unsigned Level) { 623 if (CPred(ClauseKindMode)) 624 return true; 625 if (isClauseParsingMode()) 626 ++Level; 627 D = D->getCanonicalDecl(); 628 auto StartI = Stack.rbegin(); 629 auto EndI = std::prev(Stack.rend()); 630 if (std::distance(StartI, EndI) <= (int)Level) 631 return false; 632 std::advance(StartI, Level); 633 return (StartI->SharingMap.count(D) > 0) && StartI->SharingMap[D].RefExpr && 634 CPred(StartI->SharingMap[D].Attributes); 635 } 636 637 template <class NamedDirectivesPredicate> 638 bool DSAStackTy::hasDirective(NamedDirectivesPredicate DPred, bool FromParent) { 639 auto StartI = std::next(Stack.rbegin()); 640 auto EndI = std::prev(Stack.rend()); 641 if (FromParent && StartI != EndI) { 642 StartI = std::next(StartI); 643 } 644 for (auto I = StartI, EE = EndI; I != EE; ++I) { 645 if (DPred(I->Directive, I->DirectiveName, I->ConstructLoc)) 646 return true; 647 } 648 return false; 649 } 650 651 void Sema::InitDataSharingAttributesStack() { 652 VarDataSharingAttributesStack = new DSAStackTy(*this); 653 } 654 655 #define DSAStack static_cast<DSAStackTy *>(VarDataSharingAttributesStack) 656 657 bool Sema::IsOpenMPCapturedVar(VarDecl *VD) { 658 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 659 VD = VD->getCanonicalDecl(); 660 if (DSAStack->getCurrentDirective() != OMPD_unknown && 661 (!DSAStack->isClauseParsingMode() || 662 DSAStack->getParentDirective() != OMPD_unknown)) { 663 if (DSAStack->isLoopControlVariable(VD) || 664 (VD->hasLocalStorage() && 665 isParallelOrTaskRegion(DSAStack->getCurrentDirective())) || 666 DSAStack->isForceVarCapturing()) 667 return true; 668 auto DVarPrivate = DSAStack->getTopDSA(VD, DSAStack->isClauseParsingMode()); 669 if (DVarPrivate.CKind != OMPC_unknown && isOpenMPPrivate(DVarPrivate.CKind)) 670 return true; 671 DVarPrivate = DSAStack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), 672 DSAStack->isClauseParsingMode()); 673 return DVarPrivate.CKind != OMPC_unknown; 674 } 675 return false; 676 } 677 678 bool Sema::isOpenMPPrivateVar(VarDecl *VD, unsigned Level) { 679 assert(LangOpts.OpenMP && "OpenMP is not allowed"); 680 return DSAStack->hasExplicitDSA( 681 VD, [](OpenMPClauseKind K) -> bool { return K == OMPC_private; }, Level); 682 } 683 684 void Sema::DestroyDataSharingAttributesStack() { delete DSAStack; } 685 686 void Sema::StartOpenMPDSABlock(OpenMPDirectiveKind DKind, 687 const DeclarationNameInfo &DirName, 688 Scope *CurScope, SourceLocation Loc) { 689 DSAStack->push(DKind, DirName, CurScope, Loc); 690 PushExpressionEvaluationContext(PotentiallyEvaluated); 691 } 692 693 void Sema::StartOpenMPClause(OpenMPClauseKind K) { 694 DSAStack->setClauseParsingMode(K); 695 } 696 697 void Sema::EndOpenMPClause() { 698 DSAStack->setClauseParsingMode(/*K=*/OMPC_unknown); 699 } 700 701 void Sema::EndOpenMPDSABlock(Stmt *CurDirective) { 702 // OpenMP [2.14.3.5, Restrictions, C/C++, p.1] 703 // A variable of class type (or array thereof) that appears in a lastprivate 704 // clause requires an accessible, unambiguous default constructor for the 705 // class type, unless the list item is also specified in a firstprivate 706 // clause. 707 if (auto D = dyn_cast_or_null<OMPExecutableDirective>(CurDirective)) { 708 for (auto *C : D->clauses()) { 709 if (auto *Clause = dyn_cast<OMPLastprivateClause>(C)) { 710 SmallVector<Expr *, 8> PrivateCopies; 711 for (auto *DE : Clause->varlists()) { 712 if (DE->isValueDependent() || DE->isTypeDependent()) { 713 PrivateCopies.push_back(nullptr); 714 continue; 715 } 716 auto *VD = cast<VarDecl>(cast<DeclRefExpr>(DE)->getDecl()); 717 QualType Type = VD->getType(); 718 auto DVar = DSAStack->getTopDSA(VD, false); 719 if (DVar.CKind == OMPC_lastprivate) { 720 // Generate helper private variable and initialize it with the 721 // default value. The address of the original variable is replaced 722 // by the address of the new private variable in CodeGen. This new 723 // variable is not added to IdResolver, so the code in the OpenMP 724 // region uses original variable for proper diagnostics. 725 auto *VDPrivate = 726 buildVarDecl(*this, DE->getExprLoc(), Type.getUnqualifiedType(), 727 VD->getName()); 728 ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); 729 if (VDPrivate->isInvalidDecl()) 730 continue; 731 PrivateCopies.push_back(buildDeclRefExpr( 732 *this, VDPrivate, DE->getType(), DE->getExprLoc())); 733 } else { 734 // The variable is also a firstprivate, so initialization sequence 735 // for private copy is generated already. 736 PrivateCopies.push_back(nullptr); 737 } 738 } 739 // Set initializers to private copies if no errors were found. 740 if (PrivateCopies.size() == Clause->varlist_size()) { 741 Clause->setPrivateCopies(PrivateCopies); 742 } 743 } 744 } 745 } 746 747 DSAStack->pop(); 748 DiscardCleanupsInEvaluationContext(); 749 PopExpressionEvaluationContext(); 750 } 751 752 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 753 Expr *NumIterations, Sema &SemaRef, 754 Scope *S); 755 756 namespace { 757 758 class VarDeclFilterCCC : public CorrectionCandidateCallback { 759 private: 760 Sema &SemaRef; 761 762 public: 763 explicit VarDeclFilterCCC(Sema &S) : SemaRef(S) {} 764 bool ValidateCandidate(const TypoCorrection &Candidate) override { 765 NamedDecl *ND = Candidate.getCorrectionDecl(); 766 if (VarDecl *VD = dyn_cast_or_null<VarDecl>(ND)) { 767 return VD->hasGlobalStorage() && 768 SemaRef.isDeclInScope(ND, SemaRef.getCurLexicalContext(), 769 SemaRef.getCurScope()); 770 } 771 return false; 772 } 773 }; 774 } // namespace 775 776 ExprResult Sema::ActOnOpenMPIdExpression(Scope *CurScope, 777 CXXScopeSpec &ScopeSpec, 778 const DeclarationNameInfo &Id) { 779 LookupResult Lookup(*this, Id, LookupOrdinaryName); 780 LookupParsedName(Lookup, CurScope, &ScopeSpec, true); 781 782 if (Lookup.isAmbiguous()) 783 return ExprError(); 784 785 VarDecl *VD; 786 if (!Lookup.isSingleResult()) { 787 if (TypoCorrection Corrected = CorrectTypo( 788 Id, LookupOrdinaryName, CurScope, nullptr, 789 llvm::make_unique<VarDeclFilterCCC>(*this), CTK_ErrorRecovery)) { 790 diagnoseTypo(Corrected, 791 PDiag(Lookup.empty() 792 ? diag::err_undeclared_var_use_suggest 793 : diag::err_omp_expected_var_arg_suggest) 794 << Id.getName()); 795 VD = Corrected.getCorrectionDeclAs<VarDecl>(); 796 } else { 797 Diag(Id.getLoc(), Lookup.empty() ? diag::err_undeclared_var_use 798 : diag::err_omp_expected_var_arg) 799 << Id.getName(); 800 return ExprError(); 801 } 802 } else { 803 if (!(VD = Lookup.getAsSingle<VarDecl>())) { 804 Diag(Id.getLoc(), diag::err_omp_expected_var_arg) << Id.getName(); 805 Diag(Lookup.getFoundDecl()->getLocation(), diag::note_declared_at); 806 return ExprError(); 807 } 808 } 809 Lookup.suppressDiagnostics(); 810 811 // OpenMP [2.9.2, Syntax, C/C++] 812 // Variables must be file-scope, namespace-scope, or static block-scope. 813 if (!VD->hasGlobalStorage()) { 814 Diag(Id.getLoc(), diag::err_omp_global_var_arg) 815 << getOpenMPDirectiveName(OMPD_threadprivate) << !VD->isStaticLocal(); 816 bool IsDecl = 817 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 818 Diag(VD->getLocation(), 819 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 820 << VD; 821 return ExprError(); 822 } 823 824 VarDecl *CanonicalVD = VD->getCanonicalDecl(); 825 NamedDecl *ND = cast<NamedDecl>(CanonicalVD); 826 // OpenMP [2.9.2, Restrictions, C/C++, p.2] 827 // A threadprivate directive for file-scope variables must appear outside 828 // any definition or declaration. 829 if (CanonicalVD->getDeclContext()->isTranslationUnit() && 830 !getCurLexicalContext()->isTranslationUnit()) { 831 Diag(Id.getLoc(), diag::err_omp_var_scope) 832 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 833 bool IsDecl = 834 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 835 Diag(VD->getLocation(), 836 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 837 << VD; 838 return ExprError(); 839 } 840 // OpenMP [2.9.2, Restrictions, C/C++, p.3] 841 // A threadprivate directive for static class member variables must appear 842 // in the class definition, in the same scope in which the member 843 // variables are declared. 844 if (CanonicalVD->isStaticDataMember() && 845 !CanonicalVD->getDeclContext()->Equals(getCurLexicalContext())) { 846 Diag(Id.getLoc(), diag::err_omp_var_scope) 847 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 848 bool IsDecl = 849 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 850 Diag(VD->getLocation(), 851 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 852 << VD; 853 return ExprError(); 854 } 855 // OpenMP [2.9.2, Restrictions, C/C++, p.4] 856 // A threadprivate directive for namespace-scope variables must appear 857 // outside any definition or declaration other than the namespace 858 // definition itself. 859 if (CanonicalVD->getDeclContext()->isNamespace() && 860 (!getCurLexicalContext()->isFileContext() || 861 !getCurLexicalContext()->Encloses(CanonicalVD->getDeclContext()))) { 862 Diag(Id.getLoc(), diag::err_omp_var_scope) 863 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 864 bool IsDecl = 865 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 866 Diag(VD->getLocation(), 867 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 868 << VD; 869 return ExprError(); 870 } 871 // OpenMP [2.9.2, Restrictions, C/C++, p.6] 872 // A threadprivate directive for static block-scope variables must appear 873 // in the scope of the variable and not in a nested scope. 874 if (CanonicalVD->isStaticLocal() && CurScope && 875 !isDeclInScope(ND, getCurLexicalContext(), CurScope)) { 876 Diag(Id.getLoc(), diag::err_omp_var_scope) 877 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 878 bool IsDecl = 879 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 880 Diag(VD->getLocation(), 881 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 882 << VD; 883 return ExprError(); 884 } 885 886 // OpenMP [2.9.2, Restrictions, C/C++, p.2-6] 887 // A threadprivate directive must lexically precede all references to any 888 // of the variables in its list. 889 if (VD->isUsed() && !DSAStack->isThreadPrivate(VD)) { 890 Diag(Id.getLoc(), diag::err_omp_var_used) 891 << getOpenMPDirectiveName(OMPD_threadprivate) << VD; 892 return ExprError(); 893 } 894 895 QualType ExprType = VD->getType().getNonReferenceType(); 896 ExprResult DE = buildDeclRefExpr(*this, VD, ExprType, Id.getLoc()); 897 return DE; 898 } 899 900 Sema::DeclGroupPtrTy 901 Sema::ActOnOpenMPThreadprivateDirective(SourceLocation Loc, 902 ArrayRef<Expr *> VarList) { 903 if (OMPThreadPrivateDecl *D = CheckOMPThreadPrivateDecl(Loc, VarList)) { 904 CurContext->addDecl(D); 905 return DeclGroupPtrTy::make(DeclGroupRef(D)); 906 } 907 return DeclGroupPtrTy(); 908 } 909 910 namespace { 911 class LocalVarRefChecker : public ConstStmtVisitor<LocalVarRefChecker, bool> { 912 Sema &SemaRef; 913 914 public: 915 bool VisitDeclRefExpr(const DeclRefExpr *E) { 916 if (auto VD = dyn_cast<VarDecl>(E->getDecl())) { 917 if (VD->hasLocalStorage()) { 918 SemaRef.Diag(E->getLocStart(), 919 diag::err_omp_local_var_in_threadprivate_init) 920 << E->getSourceRange(); 921 SemaRef.Diag(VD->getLocation(), diag::note_defined_here) 922 << VD << VD->getSourceRange(); 923 return true; 924 } 925 } 926 return false; 927 } 928 bool VisitStmt(const Stmt *S) { 929 for (auto Child : S->children()) { 930 if (Child && Visit(Child)) 931 return true; 932 } 933 return false; 934 } 935 explicit LocalVarRefChecker(Sema &SemaRef) : SemaRef(SemaRef) {} 936 }; 937 } // namespace 938 939 OMPThreadPrivateDecl * 940 Sema::CheckOMPThreadPrivateDecl(SourceLocation Loc, ArrayRef<Expr *> VarList) { 941 SmallVector<Expr *, 8> Vars; 942 for (auto &RefExpr : VarList) { 943 DeclRefExpr *DE = cast<DeclRefExpr>(RefExpr); 944 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 945 SourceLocation ILoc = DE->getExprLoc(); 946 947 QualType QType = VD->getType(); 948 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 949 // It will be analyzed later. 950 Vars.push_back(DE); 951 continue; 952 } 953 954 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 955 // A threadprivate variable must not have an incomplete type. 956 if (RequireCompleteType(ILoc, VD->getType(), 957 diag::err_omp_threadprivate_incomplete_type)) { 958 continue; 959 } 960 961 // OpenMP [2.9.2, Restrictions, C/C++, p.10] 962 // A threadprivate variable must not have a reference type. 963 if (VD->getType()->isReferenceType()) { 964 Diag(ILoc, diag::err_omp_ref_type_arg) 965 << getOpenMPDirectiveName(OMPD_threadprivate) << VD->getType(); 966 bool IsDecl = 967 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 968 Diag(VD->getLocation(), 969 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 970 << VD; 971 continue; 972 } 973 974 // Check if this is a TLS variable. If TLS is not being supported, produce 975 // the corresponding diagnostic. 976 if ((VD->getTLSKind() != VarDecl::TLS_None && 977 !(VD->hasAttr<OMPThreadPrivateDeclAttr>() && 978 getLangOpts().OpenMPUseTLS && 979 getASTContext().getTargetInfo().isTLSSupported())) || 980 (VD->getStorageClass() == SC_Register && VD->hasAttr<AsmLabelAttr>() && 981 !VD->isLocalVarDecl())) { 982 Diag(ILoc, diag::err_omp_var_thread_local) 983 << VD << ((VD->getTLSKind() != VarDecl::TLS_None) ? 0 : 1); 984 bool IsDecl = 985 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 986 Diag(VD->getLocation(), 987 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 988 << VD; 989 continue; 990 } 991 992 // Check if initial value of threadprivate variable reference variable with 993 // local storage (it is not supported by runtime). 994 if (auto Init = VD->getAnyInitializer()) { 995 LocalVarRefChecker Checker(*this); 996 if (Checker.Visit(Init)) 997 continue; 998 } 999 1000 Vars.push_back(RefExpr); 1001 DSAStack->addDSA(VD, DE, OMPC_threadprivate); 1002 VD->addAttr(OMPThreadPrivateDeclAttr::CreateImplicit( 1003 Context, SourceRange(Loc, Loc))); 1004 if (auto *ML = Context.getASTMutationListener()) 1005 ML->DeclarationMarkedOpenMPThreadPrivate(VD); 1006 } 1007 OMPThreadPrivateDecl *D = nullptr; 1008 if (!Vars.empty()) { 1009 D = OMPThreadPrivateDecl::Create(Context, getCurLexicalContext(), Loc, 1010 Vars); 1011 D->setAccess(AS_public); 1012 } 1013 return D; 1014 } 1015 1016 static void ReportOriginalDSA(Sema &SemaRef, DSAStackTy *Stack, 1017 const VarDecl *VD, DSAStackTy::DSAVarData DVar, 1018 bool IsLoopIterVar = false) { 1019 if (DVar.RefExpr) { 1020 SemaRef.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_explicit_dsa) 1021 << getOpenMPClauseName(DVar.CKind); 1022 return; 1023 } 1024 enum { 1025 PDSA_StaticMemberShared, 1026 PDSA_StaticLocalVarShared, 1027 PDSA_LoopIterVarPrivate, 1028 PDSA_LoopIterVarLinear, 1029 PDSA_LoopIterVarLastprivate, 1030 PDSA_ConstVarShared, 1031 PDSA_GlobalVarShared, 1032 PDSA_TaskVarFirstprivate, 1033 PDSA_LocalVarPrivate, 1034 PDSA_Implicit 1035 } Reason = PDSA_Implicit; 1036 bool ReportHint = false; 1037 auto ReportLoc = VD->getLocation(); 1038 if (IsLoopIterVar) { 1039 if (DVar.CKind == OMPC_private) 1040 Reason = PDSA_LoopIterVarPrivate; 1041 else if (DVar.CKind == OMPC_lastprivate) 1042 Reason = PDSA_LoopIterVarLastprivate; 1043 else 1044 Reason = PDSA_LoopIterVarLinear; 1045 } else if (DVar.DKind == OMPD_task && DVar.CKind == OMPC_firstprivate) { 1046 Reason = PDSA_TaskVarFirstprivate; 1047 ReportLoc = DVar.ImplicitDSALoc; 1048 } else if (VD->isStaticLocal()) 1049 Reason = PDSA_StaticLocalVarShared; 1050 else if (VD->isStaticDataMember()) 1051 Reason = PDSA_StaticMemberShared; 1052 else if (VD->isFileVarDecl()) 1053 Reason = PDSA_GlobalVarShared; 1054 else if (VD->getType().isConstant(SemaRef.getASTContext())) 1055 Reason = PDSA_ConstVarShared; 1056 else if (VD->isLocalVarDecl() && DVar.CKind == OMPC_private) { 1057 ReportHint = true; 1058 Reason = PDSA_LocalVarPrivate; 1059 } 1060 if (Reason != PDSA_Implicit) { 1061 SemaRef.Diag(ReportLoc, diag::note_omp_predetermined_dsa) 1062 << Reason << ReportHint 1063 << getOpenMPDirectiveName(Stack->getCurrentDirective()); 1064 } else if (DVar.ImplicitDSALoc.isValid()) { 1065 SemaRef.Diag(DVar.ImplicitDSALoc, diag::note_omp_implicit_dsa) 1066 << getOpenMPClauseName(DVar.CKind); 1067 } 1068 } 1069 1070 namespace { 1071 class DSAAttrChecker : public StmtVisitor<DSAAttrChecker, void> { 1072 DSAStackTy *Stack; 1073 Sema &SemaRef; 1074 bool ErrorFound; 1075 CapturedStmt *CS; 1076 llvm::SmallVector<Expr *, 8> ImplicitFirstprivate; 1077 llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA; 1078 1079 public: 1080 void VisitDeclRefExpr(DeclRefExpr *E) { 1081 if (auto *VD = dyn_cast<VarDecl>(E->getDecl())) { 1082 // Skip internally declared variables. 1083 if (VD->isLocalVarDecl() && !CS->capturesVariable(VD)) 1084 return; 1085 1086 auto DVar = Stack->getTopDSA(VD, false); 1087 // Check if the variable has explicit DSA set and stop analysis if it so. 1088 if (DVar.RefExpr) return; 1089 1090 auto ELoc = E->getExprLoc(); 1091 auto DKind = Stack->getCurrentDirective(); 1092 // The default(none) clause requires that each variable that is referenced 1093 // in the construct, and does not have a predetermined data-sharing 1094 // attribute, must have its data-sharing attribute explicitly determined 1095 // by being listed in a data-sharing attribute clause. 1096 if (DVar.CKind == OMPC_unknown && Stack->getDefaultDSA() == DSA_none && 1097 isParallelOrTaskRegion(DKind) && 1098 VarsWithInheritedDSA.count(VD) == 0) { 1099 VarsWithInheritedDSA[VD] = E; 1100 return; 1101 } 1102 1103 // OpenMP [2.9.3.6, Restrictions, p.2] 1104 // A list item that appears in a reduction clause of the innermost 1105 // enclosing worksharing or parallel construct may not be accessed in an 1106 // explicit task. 1107 DVar = Stack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction), 1108 [](OpenMPDirectiveKind K) -> bool { 1109 return isOpenMPParallelDirective(K) || 1110 isOpenMPWorksharingDirective(K) || 1111 isOpenMPTeamsDirective(K); 1112 }, 1113 false); 1114 if (DKind == OMPD_task && DVar.CKind == OMPC_reduction) { 1115 ErrorFound = true; 1116 SemaRef.Diag(ELoc, diag::err_omp_reduction_in_task); 1117 ReportOriginalDSA(SemaRef, Stack, VD, DVar); 1118 return; 1119 } 1120 1121 // Define implicit data-sharing attributes for task. 1122 DVar = Stack->getImplicitDSA(VD, false); 1123 if (DKind == OMPD_task && DVar.CKind != OMPC_shared) 1124 ImplicitFirstprivate.push_back(E); 1125 } 1126 } 1127 void VisitOMPExecutableDirective(OMPExecutableDirective *S) { 1128 for (auto *C : S->clauses()) { 1129 // Skip analysis of arguments of implicitly defined firstprivate clause 1130 // for task directives. 1131 if (C && (!isa<OMPFirstprivateClause>(C) || C->getLocStart().isValid())) 1132 for (auto *CC : C->children()) { 1133 if (CC) 1134 Visit(CC); 1135 } 1136 } 1137 } 1138 void VisitStmt(Stmt *S) { 1139 for (auto *C : S->children()) { 1140 if (C && !isa<OMPExecutableDirective>(C)) 1141 Visit(C); 1142 } 1143 } 1144 1145 bool isErrorFound() { return ErrorFound; } 1146 ArrayRef<Expr *> getImplicitFirstprivate() { return ImplicitFirstprivate; } 1147 llvm::DenseMap<VarDecl *, Expr *> &getVarsWithInheritedDSA() { 1148 return VarsWithInheritedDSA; 1149 } 1150 1151 DSAAttrChecker(DSAStackTy *S, Sema &SemaRef, CapturedStmt *CS) 1152 : Stack(S), SemaRef(SemaRef), ErrorFound(false), CS(CS) {} 1153 }; 1154 } // namespace 1155 1156 void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) { 1157 switch (DKind) { 1158 case OMPD_parallel: { 1159 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1160 QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); 1161 Sema::CapturedParamNameType Params[] = { 1162 std::make_pair(".global_tid.", KmpInt32PtrTy), 1163 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1164 std::make_pair(StringRef(), QualType()) // __context with shared vars 1165 }; 1166 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1167 Params); 1168 break; 1169 } 1170 case OMPD_simd: { 1171 Sema::CapturedParamNameType Params[] = { 1172 std::make_pair(StringRef(), QualType()) // __context with shared vars 1173 }; 1174 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1175 Params); 1176 break; 1177 } 1178 case OMPD_for: { 1179 Sema::CapturedParamNameType Params[] = { 1180 std::make_pair(StringRef(), QualType()) // __context with shared vars 1181 }; 1182 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1183 Params); 1184 break; 1185 } 1186 case OMPD_for_simd: { 1187 Sema::CapturedParamNameType Params[] = { 1188 std::make_pair(StringRef(), QualType()) // __context with shared vars 1189 }; 1190 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1191 Params); 1192 break; 1193 } 1194 case OMPD_sections: { 1195 Sema::CapturedParamNameType Params[] = { 1196 std::make_pair(StringRef(), QualType()) // __context with shared vars 1197 }; 1198 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1199 Params); 1200 break; 1201 } 1202 case OMPD_section: { 1203 Sema::CapturedParamNameType Params[] = { 1204 std::make_pair(StringRef(), QualType()) // __context with shared vars 1205 }; 1206 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1207 Params); 1208 break; 1209 } 1210 case OMPD_single: { 1211 Sema::CapturedParamNameType Params[] = { 1212 std::make_pair(StringRef(), QualType()) // __context with shared vars 1213 }; 1214 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1215 Params); 1216 break; 1217 } 1218 case OMPD_master: { 1219 Sema::CapturedParamNameType Params[] = { 1220 std::make_pair(StringRef(), QualType()) // __context with shared vars 1221 }; 1222 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1223 Params); 1224 break; 1225 } 1226 case OMPD_critical: { 1227 Sema::CapturedParamNameType Params[] = { 1228 std::make_pair(StringRef(), QualType()) // __context with shared vars 1229 }; 1230 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1231 Params); 1232 break; 1233 } 1234 case OMPD_parallel_for: { 1235 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1236 QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); 1237 Sema::CapturedParamNameType Params[] = { 1238 std::make_pair(".global_tid.", KmpInt32PtrTy), 1239 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1240 std::make_pair(StringRef(), QualType()) // __context with shared vars 1241 }; 1242 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1243 Params); 1244 break; 1245 } 1246 case OMPD_parallel_for_simd: { 1247 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1248 QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); 1249 Sema::CapturedParamNameType Params[] = { 1250 std::make_pair(".global_tid.", KmpInt32PtrTy), 1251 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1252 std::make_pair(StringRef(), QualType()) // __context with shared vars 1253 }; 1254 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1255 Params); 1256 break; 1257 } 1258 case OMPD_parallel_sections: { 1259 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1260 QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); 1261 Sema::CapturedParamNameType Params[] = { 1262 std::make_pair(".global_tid.", KmpInt32PtrTy), 1263 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1264 std::make_pair(StringRef(), QualType()) // __context with shared vars 1265 }; 1266 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1267 Params); 1268 break; 1269 } 1270 case OMPD_task: { 1271 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1272 QualType Args[] = {Context.VoidPtrTy.withConst().withRestrict()}; 1273 FunctionProtoType::ExtProtoInfo EPI; 1274 EPI.Variadic = true; 1275 QualType CopyFnType = Context.getFunctionType(Context.VoidTy, Args, EPI); 1276 Sema::CapturedParamNameType Params[] = { 1277 std::make_pair(".global_tid.", KmpInt32Ty), 1278 std::make_pair(".part_id.", KmpInt32Ty), 1279 std::make_pair(".privates.", 1280 Context.VoidPtrTy.withConst().withRestrict()), 1281 std::make_pair( 1282 ".copy_fn.", 1283 Context.getPointerType(CopyFnType).withConst().withRestrict()), 1284 std::make_pair(StringRef(), QualType()) // __context with shared vars 1285 }; 1286 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1287 Params); 1288 // Mark this captured region as inlined, because we don't use outlined 1289 // function directly. 1290 getCurCapturedRegion()->TheCapturedDecl->addAttr( 1291 AlwaysInlineAttr::CreateImplicit( 1292 Context, AlwaysInlineAttr::Keyword_forceinline, SourceRange())); 1293 break; 1294 } 1295 case OMPD_ordered: { 1296 Sema::CapturedParamNameType Params[] = { 1297 std::make_pair(StringRef(), QualType()) // __context with shared vars 1298 }; 1299 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1300 Params); 1301 break; 1302 } 1303 case OMPD_atomic: { 1304 Sema::CapturedParamNameType Params[] = { 1305 std::make_pair(StringRef(), QualType()) // __context with shared vars 1306 }; 1307 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1308 Params); 1309 break; 1310 } 1311 case OMPD_target_data: 1312 case OMPD_target: { 1313 Sema::CapturedParamNameType Params[] = { 1314 std::make_pair(StringRef(), QualType()) // __context with shared vars 1315 }; 1316 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1317 Params); 1318 break; 1319 } 1320 case OMPD_teams: { 1321 QualType KmpInt32Ty = Context.getIntTypeForBitwidth(32, 1); 1322 QualType KmpInt32PtrTy = Context.getPointerType(KmpInt32Ty); 1323 Sema::CapturedParamNameType Params[] = { 1324 std::make_pair(".global_tid.", KmpInt32PtrTy), 1325 std::make_pair(".bound_tid.", KmpInt32PtrTy), 1326 std::make_pair(StringRef(), QualType()) // __context with shared vars 1327 }; 1328 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1329 Params); 1330 break; 1331 } 1332 case OMPD_taskgroup: { 1333 Sema::CapturedParamNameType Params[] = { 1334 std::make_pair(StringRef(), QualType()) // __context with shared vars 1335 }; 1336 ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP, 1337 Params); 1338 break; 1339 } 1340 case OMPD_threadprivate: 1341 case OMPD_taskyield: 1342 case OMPD_barrier: 1343 case OMPD_taskwait: 1344 case OMPD_cancellation_point: 1345 case OMPD_cancel: 1346 case OMPD_flush: 1347 llvm_unreachable("OpenMP Directive is not allowed"); 1348 case OMPD_unknown: 1349 llvm_unreachable("Unknown OpenMP directive"); 1350 } 1351 } 1352 1353 StmtResult Sema::ActOnOpenMPRegionEnd(StmtResult S, 1354 ArrayRef<OMPClause *> Clauses) { 1355 if (!S.isUsable()) { 1356 ActOnCapturedRegionError(); 1357 return StmtError(); 1358 } 1359 // This is required for proper codegen. 1360 for (auto *Clause : Clauses) { 1361 if (isOpenMPPrivate(Clause->getClauseKind()) || 1362 Clause->getClauseKind() == OMPC_copyprivate || 1363 (getLangOpts().OpenMPUseTLS && 1364 getASTContext().getTargetInfo().isTLSSupported() && 1365 Clause->getClauseKind() == OMPC_copyin)) { 1366 DSAStack->setForceVarCapturing(Clause->getClauseKind() == OMPC_copyin); 1367 // Mark all variables in private list clauses as used in inner region. 1368 for (auto *VarRef : Clause->children()) { 1369 if (auto *E = cast_or_null<Expr>(VarRef)) { 1370 MarkDeclarationsReferencedInExpr(E); 1371 } 1372 } 1373 DSAStack->setForceVarCapturing(/*V=*/false); 1374 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective()) && 1375 Clause->getClauseKind() == OMPC_schedule) { 1376 // Mark all variables in private list clauses as used in inner region. 1377 // Required for proper codegen of combined directives. 1378 // TODO: add processing for other clauses. 1379 if (auto *E = cast_or_null<Expr>( 1380 cast<OMPScheduleClause>(Clause)->getHelperChunkSize())) { 1381 MarkDeclarationsReferencedInExpr(E); 1382 } 1383 } 1384 } 1385 return ActOnCapturedRegionEnd(S.get()); 1386 } 1387 1388 static bool CheckNestingOfRegions(Sema &SemaRef, DSAStackTy *Stack, 1389 OpenMPDirectiveKind CurrentRegion, 1390 const DeclarationNameInfo &CurrentName, 1391 OpenMPDirectiveKind CancelRegion, 1392 SourceLocation StartLoc) { 1393 // Allowed nesting of constructs 1394 // +------------------+-----------------+------------------------------------+ 1395 // | Parent directive | Child directive | Closely (!), No-Closely(+), Both(*)| 1396 // +------------------+-----------------+------------------------------------+ 1397 // | parallel | parallel | * | 1398 // | parallel | for | * | 1399 // | parallel | for simd | * | 1400 // | parallel | master | * | 1401 // | parallel | critical | * | 1402 // | parallel | simd | * | 1403 // | parallel | sections | * | 1404 // | parallel | section | + | 1405 // | parallel | single | * | 1406 // | parallel | parallel for | * | 1407 // | parallel |parallel for simd| * | 1408 // | parallel |parallel sections| * | 1409 // | parallel | task | * | 1410 // | parallel | taskyield | * | 1411 // | parallel | barrier | * | 1412 // | parallel | taskwait | * | 1413 // | parallel | taskgroup | * | 1414 // | parallel | flush | * | 1415 // | parallel | ordered | + | 1416 // | parallel | atomic | * | 1417 // | parallel | target | * | 1418 // | parallel | teams | + | 1419 // | parallel | cancellation | | 1420 // | | point | ! | 1421 // | parallel | cancel | ! | 1422 // +------------------+-----------------+------------------------------------+ 1423 // | for | parallel | * | 1424 // | for | for | + | 1425 // | for | for simd | + | 1426 // | for | master | + | 1427 // | for | critical | * | 1428 // | for | simd | * | 1429 // | for | sections | + | 1430 // | for | section | + | 1431 // | for | single | + | 1432 // | for | parallel for | * | 1433 // | for |parallel for simd| * | 1434 // | for |parallel sections| * | 1435 // | for | task | * | 1436 // | for | taskyield | * | 1437 // | for | barrier | + | 1438 // | for | taskwait | * | 1439 // | for | taskgroup | * | 1440 // | for | flush | * | 1441 // | for | ordered | * (if construct is ordered) | 1442 // | for | atomic | * | 1443 // | for | target | * | 1444 // | for | teams | + | 1445 // | for | cancellation | | 1446 // | | point | ! | 1447 // | for | cancel | ! | 1448 // +------------------+-----------------+------------------------------------+ 1449 // | master | parallel | * | 1450 // | master | for | + | 1451 // | master | for simd | + | 1452 // | master | master | * | 1453 // | master | critical | * | 1454 // | master | simd | * | 1455 // | master | sections | + | 1456 // | master | section | + | 1457 // | master | single | + | 1458 // | master | parallel for | * | 1459 // | master |parallel for simd| * | 1460 // | master |parallel sections| * | 1461 // | master | task | * | 1462 // | master | taskyield | * | 1463 // | master | barrier | + | 1464 // | master | taskwait | * | 1465 // | master | taskgroup | * | 1466 // | master | flush | * | 1467 // | master | ordered | + | 1468 // | master | atomic | * | 1469 // | master | target | * | 1470 // | master | teams | + | 1471 // | master | cancellation | | 1472 // | | point | | 1473 // | master | cancel | | 1474 // +------------------+-----------------+------------------------------------+ 1475 // | critical | parallel | * | 1476 // | critical | for | + | 1477 // | critical | for simd | + | 1478 // | critical | master | * | 1479 // | critical | critical | * (should have different names) | 1480 // | critical | simd | * | 1481 // | critical | sections | + | 1482 // | critical | section | + | 1483 // | critical | single | + | 1484 // | critical | parallel for | * | 1485 // | critical |parallel for simd| * | 1486 // | critical |parallel sections| * | 1487 // | critical | task | * | 1488 // | critical | taskyield | * | 1489 // | critical | barrier | + | 1490 // | critical | taskwait | * | 1491 // | critical | taskgroup | * | 1492 // | critical | ordered | + | 1493 // | critical | atomic | * | 1494 // | critical | target | * | 1495 // | critical | teams | + | 1496 // | critical | cancellation | | 1497 // | | point | | 1498 // | critical | cancel | | 1499 // +------------------+-----------------+------------------------------------+ 1500 // | simd | parallel | | 1501 // | simd | for | | 1502 // | simd | for simd | | 1503 // | simd | master | | 1504 // | simd | critical | | 1505 // | simd | simd | | 1506 // | simd | sections | | 1507 // | simd | section | | 1508 // | simd | single | | 1509 // | simd | parallel for | | 1510 // | simd |parallel for simd| | 1511 // | simd |parallel sections| | 1512 // | simd | task | | 1513 // | simd | taskyield | | 1514 // | simd | barrier | | 1515 // | simd | taskwait | | 1516 // | simd | taskgroup | | 1517 // | simd | flush | | 1518 // | simd | ordered | | 1519 // | simd | atomic | | 1520 // | simd | target | | 1521 // | simd | teams | | 1522 // | simd | cancellation | | 1523 // | | point | | 1524 // | simd | cancel | | 1525 // +------------------+-----------------+------------------------------------+ 1526 // | for simd | parallel | | 1527 // | for simd | for | | 1528 // | for simd | for simd | | 1529 // | for simd | master | | 1530 // | for simd | critical | | 1531 // | for simd | simd | | 1532 // | for simd | sections | | 1533 // | for simd | section | | 1534 // | for simd | single | | 1535 // | for simd | parallel for | | 1536 // | for simd |parallel for simd| | 1537 // | for simd |parallel sections| | 1538 // | for simd | task | | 1539 // | for simd | taskyield | | 1540 // | for simd | barrier | | 1541 // | for simd | taskwait | | 1542 // | for simd | taskgroup | | 1543 // | for simd | flush | | 1544 // | for simd | ordered | | 1545 // | for simd | atomic | | 1546 // | for simd | target | | 1547 // | for simd | teams | | 1548 // | for simd | cancellation | | 1549 // | | point | | 1550 // | for simd | cancel | | 1551 // +------------------+-----------------+------------------------------------+ 1552 // | parallel for simd| parallel | | 1553 // | parallel for simd| for | | 1554 // | parallel for simd| for simd | | 1555 // | parallel for simd| master | | 1556 // | parallel for simd| critical | | 1557 // | parallel for simd| simd | | 1558 // | parallel for simd| sections | | 1559 // | parallel for simd| section | | 1560 // | parallel for simd| single | | 1561 // | parallel for simd| parallel for | | 1562 // | parallel for simd|parallel for simd| | 1563 // | parallel for simd|parallel sections| | 1564 // | parallel for simd| task | | 1565 // | parallel for simd| taskyield | | 1566 // | parallel for simd| barrier | | 1567 // | parallel for simd| taskwait | | 1568 // | parallel for simd| taskgroup | | 1569 // | parallel for simd| flush | | 1570 // | parallel for simd| ordered | | 1571 // | parallel for simd| atomic | | 1572 // | parallel for simd| target | | 1573 // | parallel for simd| teams | | 1574 // | parallel for simd| cancellation | | 1575 // | | point | | 1576 // | parallel for simd| cancel | | 1577 // +------------------+-----------------+------------------------------------+ 1578 // | sections | parallel | * | 1579 // | sections | for | + | 1580 // | sections | for simd | + | 1581 // | sections | master | + | 1582 // | sections | critical | * | 1583 // | sections | simd | * | 1584 // | sections | sections | + | 1585 // | sections | section | * | 1586 // | sections | single | + | 1587 // | sections | parallel for | * | 1588 // | sections |parallel for simd| * | 1589 // | sections |parallel sections| * | 1590 // | sections | task | * | 1591 // | sections | taskyield | * | 1592 // | sections | barrier | + | 1593 // | sections | taskwait | * | 1594 // | sections | taskgroup | * | 1595 // | sections | flush | * | 1596 // | sections | ordered | + | 1597 // | sections | atomic | * | 1598 // | sections | target | * | 1599 // | sections | teams | + | 1600 // | sections | cancellation | | 1601 // | | point | ! | 1602 // | sections | cancel | ! | 1603 // +------------------+-----------------+------------------------------------+ 1604 // | section | parallel | * | 1605 // | section | for | + | 1606 // | section | for simd | + | 1607 // | section | master | + | 1608 // | section | critical | * | 1609 // | section | simd | * | 1610 // | section | sections | + | 1611 // | section | section | + | 1612 // | section | single | + | 1613 // | section | parallel for | * | 1614 // | section |parallel for simd| * | 1615 // | section |parallel sections| * | 1616 // | section | task | * | 1617 // | section | taskyield | * | 1618 // | section | barrier | + | 1619 // | section | taskwait | * | 1620 // | section | taskgroup | * | 1621 // | section | flush | * | 1622 // | section | ordered | + | 1623 // | section | atomic | * | 1624 // | section | target | * | 1625 // | section | teams | + | 1626 // | section | cancellation | | 1627 // | | point | ! | 1628 // | section | cancel | ! | 1629 // +------------------+-----------------+------------------------------------+ 1630 // | single | parallel | * | 1631 // | single | for | + | 1632 // | single | for simd | + | 1633 // | single | master | + | 1634 // | single | critical | * | 1635 // | single | simd | * | 1636 // | single | sections | + | 1637 // | single | section | + | 1638 // | single | single | + | 1639 // | single | parallel for | * | 1640 // | single |parallel for simd| * | 1641 // | single |parallel sections| * | 1642 // | single | task | * | 1643 // | single | taskyield | * | 1644 // | single | barrier | + | 1645 // | single | taskwait | * | 1646 // | single | taskgroup | * | 1647 // | single | flush | * | 1648 // | single | ordered | + | 1649 // | single | atomic | * | 1650 // | single | target | * | 1651 // | single | teams | + | 1652 // | single | cancellation | | 1653 // | | point | | 1654 // | single | cancel | | 1655 // +------------------+-----------------+------------------------------------+ 1656 // | parallel for | parallel | * | 1657 // | parallel for | for | + | 1658 // | parallel for | for simd | + | 1659 // | parallel for | master | + | 1660 // | parallel for | critical | * | 1661 // | parallel for | simd | * | 1662 // | parallel for | sections | + | 1663 // | parallel for | section | + | 1664 // | parallel for | single | + | 1665 // | parallel for | parallel for | * | 1666 // | parallel for |parallel for simd| * | 1667 // | parallel for |parallel sections| * | 1668 // | parallel for | task | * | 1669 // | parallel for | taskyield | * | 1670 // | parallel for | barrier | + | 1671 // | parallel for | taskwait | * | 1672 // | parallel for | taskgroup | * | 1673 // | parallel for | flush | * | 1674 // | parallel for | ordered | * (if construct is ordered) | 1675 // | parallel for | atomic | * | 1676 // | parallel for | target | * | 1677 // | parallel for | teams | + | 1678 // | parallel for | cancellation | | 1679 // | | point | ! | 1680 // | parallel for | cancel | ! | 1681 // +------------------+-----------------+------------------------------------+ 1682 // | parallel sections| parallel | * | 1683 // | parallel sections| for | + | 1684 // | parallel sections| for simd | + | 1685 // | parallel sections| master | + | 1686 // | parallel sections| critical | + | 1687 // | parallel sections| simd | * | 1688 // | parallel sections| sections | + | 1689 // | parallel sections| section | * | 1690 // | parallel sections| single | + | 1691 // | parallel sections| parallel for | * | 1692 // | parallel sections|parallel for simd| * | 1693 // | parallel sections|parallel sections| * | 1694 // | parallel sections| task | * | 1695 // | parallel sections| taskyield | * | 1696 // | parallel sections| barrier | + | 1697 // | parallel sections| taskwait | * | 1698 // | parallel sections| taskgroup | * | 1699 // | parallel sections| flush | * | 1700 // | parallel sections| ordered | + | 1701 // | parallel sections| atomic | * | 1702 // | parallel sections| target | * | 1703 // | parallel sections| teams | + | 1704 // | parallel sections| cancellation | | 1705 // | | point | ! | 1706 // | parallel sections| cancel | ! | 1707 // +------------------+-----------------+------------------------------------+ 1708 // | task | parallel | * | 1709 // | task | for | + | 1710 // | task | for simd | + | 1711 // | task | master | + | 1712 // | task | critical | * | 1713 // | task | simd | * | 1714 // | task | sections | + | 1715 // | task | section | + | 1716 // | task | single | + | 1717 // | task | parallel for | * | 1718 // | task |parallel for simd| * | 1719 // | task |parallel sections| * | 1720 // | task | task | * | 1721 // | task | taskyield | * | 1722 // | task | barrier | + | 1723 // | task | taskwait | * | 1724 // | task | taskgroup | * | 1725 // | task | flush | * | 1726 // | task | ordered | + | 1727 // | task | atomic | * | 1728 // | task | target | * | 1729 // | task | teams | + | 1730 // | task | cancellation | | 1731 // | | point | ! | 1732 // | task | cancel | ! | 1733 // +------------------+-----------------+------------------------------------+ 1734 // | ordered | parallel | * | 1735 // | ordered | for | + | 1736 // | ordered | for simd | + | 1737 // | ordered | master | * | 1738 // | ordered | critical | * | 1739 // | ordered | simd | * | 1740 // | ordered | sections | + | 1741 // | ordered | section | + | 1742 // | ordered | single | + | 1743 // | ordered | parallel for | * | 1744 // | ordered |parallel for simd| * | 1745 // | ordered |parallel sections| * | 1746 // | ordered | task | * | 1747 // | ordered | taskyield | * | 1748 // | ordered | barrier | + | 1749 // | ordered | taskwait | * | 1750 // | ordered | taskgroup | * | 1751 // | ordered | flush | * | 1752 // | ordered | ordered | + | 1753 // | ordered | atomic | * | 1754 // | ordered | target | * | 1755 // | ordered | teams | + | 1756 // | ordered | cancellation | | 1757 // | | point | | 1758 // | ordered | cancel | | 1759 // +------------------+-----------------+------------------------------------+ 1760 // | atomic | parallel | | 1761 // | atomic | for | | 1762 // | atomic | for simd | | 1763 // | atomic | master | | 1764 // | atomic | critical | | 1765 // | atomic | simd | | 1766 // | atomic | sections | | 1767 // | atomic | section | | 1768 // | atomic | single | | 1769 // | atomic | parallel for | | 1770 // | atomic |parallel for simd| | 1771 // | atomic |parallel sections| | 1772 // | atomic | task | | 1773 // | atomic | taskyield | | 1774 // | atomic | barrier | | 1775 // | atomic | taskwait | | 1776 // | atomic | taskgroup | | 1777 // | atomic | flush | | 1778 // | atomic | ordered | | 1779 // | atomic | atomic | | 1780 // | atomic | target | | 1781 // | atomic | teams | | 1782 // | atomic | cancellation | | 1783 // | | point | | 1784 // | atomic | cancel | | 1785 // +------------------+-----------------+------------------------------------+ 1786 // | target | parallel | * | 1787 // | target | for | * | 1788 // | target | for simd | * | 1789 // | target | master | * | 1790 // | target | critical | * | 1791 // | target | simd | * | 1792 // | target | sections | * | 1793 // | target | section | * | 1794 // | target | single | * | 1795 // | target | parallel for | * | 1796 // | target |parallel for simd| * | 1797 // | target |parallel sections| * | 1798 // | target | task | * | 1799 // | target | taskyield | * | 1800 // | target | barrier | * | 1801 // | target | taskwait | * | 1802 // | target | taskgroup | * | 1803 // | target | flush | * | 1804 // | target | ordered | * | 1805 // | target | atomic | * | 1806 // | target | target | * | 1807 // | target | teams | * | 1808 // | target | cancellation | | 1809 // | | point | | 1810 // | target | cancel | | 1811 // +------------------+-----------------+------------------------------------+ 1812 // | teams | parallel | * | 1813 // | teams | for | + | 1814 // | teams | for simd | + | 1815 // | teams | master | + | 1816 // | teams | critical | + | 1817 // | teams | simd | + | 1818 // | teams | sections | + | 1819 // | teams | section | + | 1820 // | teams | single | + | 1821 // | teams | parallel for | * | 1822 // | teams |parallel for simd| * | 1823 // | teams |parallel sections| * | 1824 // | teams | task | + | 1825 // | teams | taskyield | + | 1826 // | teams | barrier | + | 1827 // | teams | taskwait | + | 1828 // | teams | taskgroup | + | 1829 // | teams | flush | + | 1830 // | teams | ordered | + | 1831 // | teams | atomic | + | 1832 // | teams | target | + | 1833 // | teams | teams | + | 1834 // | teams | cancellation | | 1835 // | | point | | 1836 // | teams | cancel | | 1837 // +------------------+-----------------+------------------------------------+ 1838 if (Stack->getCurScope()) { 1839 auto ParentRegion = Stack->getParentDirective(); 1840 bool NestingProhibited = false; 1841 bool CloseNesting = true; 1842 enum { 1843 NoRecommend, 1844 ShouldBeInParallelRegion, 1845 ShouldBeInOrderedRegion, 1846 ShouldBeInTargetRegion 1847 } Recommend = NoRecommend; 1848 if (isOpenMPSimdDirective(ParentRegion)) { 1849 // OpenMP [2.16, Nesting of Regions] 1850 // OpenMP constructs may not be nested inside a simd region. 1851 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_simd); 1852 return true; 1853 } 1854 if (ParentRegion == OMPD_atomic) { 1855 // OpenMP [2.16, Nesting of Regions] 1856 // OpenMP constructs may not be nested inside an atomic region. 1857 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region_atomic); 1858 return true; 1859 } 1860 if (CurrentRegion == OMPD_section) { 1861 // OpenMP [2.7.2, sections Construct, Restrictions] 1862 // Orphaned section directives are prohibited. That is, the section 1863 // directives must appear within the sections construct and must not be 1864 // encountered elsewhere in the sections region. 1865 if (ParentRegion != OMPD_sections && 1866 ParentRegion != OMPD_parallel_sections) { 1867 SemaRef.Diag(StartLoc, diag::err_omp_orphaned_section_directive) 1868 << (ParentRegion != OMPD_unknown) 1869 << getOpenMPDirectiveName(ParentRegion); 1870 return true; 1871 } 1872 return false; 1873 } 1874 // Allow some constructs to be orphaned (they could be used in functions, 1875 // called from OpenMP regions with the required preconditions). 1876 if (ParentRegion == OMPD_unknown) 1877 return false; 1878 if (CurrentRegion == OMPD_cancellation_point || 1879 CurrentRegion == OMPD_cancel) { 1880 // OpenMP [2.16, Nesting of Regions] 1881 // A cancellation point construct for which construct-type-clause is 1882 // taskgroup must be nested inside a task construct. A cancellation 1883 // point construct for which construct-type-clause is not taskgroup must 1884 // be closely nested inside an OpenMP construct that matches the type 1885 // specified in construct-type-clause. 1886 // A cancel construct for which construct-type-clause is taskgroup must be 1887 // nested inside a task construct. A cancel construct for which 1888 // construct-type-clause is not taskgroup must be closely nested inside an 1889 // OpenMP construct that matches the type specified in 1890 // construct-type-clause. 1891 NestingProhibited = 1892 !((CancelRegion == OMPD_parallel && ParentRegion == OMPD_parallel) || 1893 (CancelRegion == OMPD_for && ParentRegion == OMPD_for) || 1894 (CancelRegion == OMPD_taskgroup && ParentRegion == OMPD_task) || 1895 (CancelRegion == OMPD_sections && 1896 (ParentRegion == OMPD_section || ParentRegion == OMPD_sections))); 1897 } else if (CurrentRegion == OMPD_master) { 1898 // OpenMP [2.16, Nesting of Regions] 1899 // A master region may not be closely nested inside a worksharing, 1900 // atomic, or explicit task region. 1901 NestingProhibited = isOpenMPWorksharingDirective(ParentRegion) || 1902 ParentRegion == OMPD_task; 1903 } else if (CurrentRegion == OMPD_critical && CurrentName.getName()) { 1904 // OpenMP [2.16, Nesting of Regions] 1905 // A critical region may not be nested (closely or otherwise) inside a 1906 // critical region with the same name. Note that this restriction is not 1907 // sufficient to prevent deadlock. 1908 SourceLocation PreviousCriticalLoc; 1909 bool DeadLock = 1910 Stack->hasDirective([CurrentName, &PreviousCriticalLoc]( 1911 OpenMPDirectiveKind K, 1912 const DeclarationNameInfo &DNI, 1913 SourceLocation Loc) 1914 ->bool { 1915 if (K == OMPD_critical && 1916 DNI.getName() == CurrentName.getName()) { 1917 PreviousCriticalLoc = Loc; 1918 return true; 1919 } else 1920 return false; 1921 }, 1922 false /* skip top directive */); 1923 if (DeadLock) { 1924 SemaRef.Diag(StartLoc, 1925 diag::err_omp_prohibited_region_critical_same_name) 1926 << CurrentName.getName(); 1927 if (PreviousCriticalLoc.isValid()) 1928 SemaRef.Diag(PreviousCriticalLoc, 1929 diag::note_omp_previous_critical_region); 1930 return true; 1931 } 1932 } else if (CurrentRegion == OMPD_barrier) { 1933 // OpenMP [2.16, Nesting of Regions] 1934 // A barrier region may not be closely nested inside a worksharing, 1935 // explicit task, critical, ordered, atomic, or master region. 1936 NestingProhibited = 1937 isOpenMPWorksharingDirective(ParentRegion) || 1938 ParentRegion == OMPD_task || ParentRegion == OMPD_master || 1939 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 1940 } else if (isOpenMPWorksharingDirective(CurrentRegion) && 1941 !isOpenMPParallelDirective(CurrentRegion)) { 1942 // OpenMP [2.16, Nesting of Regions] 1943 // A worksharing region may not be closely nested inside a worksharing, 1944 // explicit task, critical, ordered, atomic, or master region. 1945 NestingProhibited = 1946 isOpenMPWorksharingDirective(ParentRegion) || 1947 ParentRegion == OMPD_task || ParentRegion == OMPD_master || 1948 ParentRegion == OMPD_critical || ParentRegion == OMPD_ordered; 1949 Recommend = ShouldBeInParallelRegion; 1950 } else if (CurrentRegion == OMPD_ordered) { 1951 // OpenMP [2.16, Nesting of Regions] 1952 // An ordered region may not be closely nested inside a critical, 1953 // atomic, or explicit task region. 1954 // An ordered region must be closely nested inside a loop region (or 1955 // parallel loop region) with an ordered clause. 1956 NestingProhibited = ParentRegion == OMPD_critical || 1957 ParentRegion == OMPD_task || 1958 !Stack->isParentOrderedRegion(); 1959 Recommend = ShouldBeInOrderedRegion; 1960 } else if (isOpenMPTeamsDirective(CurrentRegion)) { 1961 // OpenMP [2.16, Nesting of Regions] 1962 // If specified, a teams construct must be contained within a target 1963 // construct. 1964 NestingProhibited = ParentRegion != OMPD_target; 1965 Recommend = ShouldBeInTargetRegion; 1966 Stack->setParentTeamsRegionLoc(Stack->getConstructLoc()); 1967 } 1968 if (!NestingProhibited && isOpenMPTeamsDirective(ParentRegion)) { 1969 // OpenMP [2.16, Nesting of Regions] 1970 // distribute, parallel, parallel sections, parallel workshare, and the 1971 // parallel loop and parallel loop SIMD constructs are the only OpenMP 1972 // constructs that can be closely nested in the teams region. 1973 // TODO: add distribute directive. 1974 NestingProhibited = !isOpenMPParallelDirective(CurrentRegion); 1975 Recommend = ShouldBeInParallelRegion; 1976 } 1977 if (NestingProhibited) { 1978 SemaRef.Diag(StartLoc, diag::err_omp_prohibited_region) 1979 << CloseNesting << getOpenMPDirectiveName(ParentRegion) << Recommend 1980 << getOpenMPDirectiveName(CurrentRegion); 1981 return true; 1982 } 1983 } 1984 return false; 1985 } 1986 1987 StmtResult Sema::ActOnOpenMPExecutableDirective( 1988 OpenMPDirectiveKind Kind, const DeclarationNameInfo &DirName, 1989 OpenMPDirectiveKind CancelRegion, ArrayRef<OMPClause *> Clauses, 1990 Stmt *AStmt, SourceLocation StartLoc, SourceLocation EndLoc) { 1991 StmtResult Res = StmtError(); 1992 if (CheckNestingOfRegions(*this, DSAStack, Kind, DirName, CancelRegion, 1993 StartLoc)) 1994 return StmtError(); 1995 1996 llvm::SmallVector<OMPClause *, 8> ClausesWithImplicit; 1997 llvm::DenseMap<VarDecl *, Expr *> VarsWithInheritedDSA; 1998 bool ErrorFound = false; 1999 ClausesWithImplicit.append(Clauses.begin(), Clauses.end()); 2000 if (AStmt) { 2001 assert(isa<CapturedStmt>(AStmt) && "Captured statement expected"); 2002 2003 // Check default data sharing attributes for referenced variables. 2004 DSAAttrChecker DSAChecker(DSAStack, *this, cast<CapturedStmt>(AStmt)); 2005 DSAChecker.Visit(cast<CapturedStmt>(AStmt)->getCapturedStmt()); 2006 if (DSAChecker.isErrorFound()) 2007 return StmtError(); 2008 // Generate list of implicitly defined firstprivate variables. 2009 VarsWithInheritedDSA = DSAChecker.getVarsWithInheritedDSA(); 2010 2011 if (!DSAChecker.getImplicitFirstprivate().empty()) { 2012 if (OMPClause *Implicit = ActOnOpenMPFirstprivateClause( 2013 DSAChecker.getImplicitFirstprivate(), SourceLocation(), 2014 SourceLocation(), SourceLocation())) { 2015 ClausesWithImplicit.push_back(Implicit); 2016 ErrorFound = cast<OMPFirstprivateClause>(Implicit)->varlist_size() != 2017 DSAChecker.getImplicitFirstprivate().size(); 2018 } else 2019 ErrorFound = true; 2020 } 2021 } 2022 2023 switch (Kind) { 2024 case OMPD_parallel: 2025 Res = ActOnOpenMPParallelDirective(ClausesWithImplicit, AStmt, StartLoc, 2026 EndLoc); 2027 break; 2028 case OMPD_simd: 2029 Res = ActOnOpenMPSimdDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 2030 VarsWithInheritedDSA); 2031 break; 2032 case OMPD_for: 2033 Res = ActOnOpenMPForDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc, 2034 VarsWithInheritedDSA); 2035 break; 2036 case OMPD_for_simd: 2037 Res = ActOnOpenMPForSimdDirective(ClausesWithImplicit, AStmt, StartLoc, 2038 EndLoc, VarsWithInheritedDSA); 2039 break; 2040 case OMPD_sections: 2041 Res = ActOnOpenMPSectionsDirective(ClausesWithImplicit, AStmt, StartLoc, 2042 EndLoc); 2043 break; 2044 case OMPD_section: 2045 assert(ClausesWithImplicit.empty() && 2046 "No clauses are allowed for 'omp section' directive"); 2047 Res = ActOnOpenMPSectionDirective(AStmt, StartLoc, EndLoc); 2048 break; 2049 case OMPD_single: 2050 Res = ActOnOpenMPSingleDirective(ClausesWithImplicit, AStmt, StartLoc, 2051 EndLoc); 2052 break; 2053 case OMPD_master: 2054 assert(ClausesWithImplicit.empty() && 2055 "No clauses are allowed for 'omp master' directive"); 2056 Res = ActOnOpenMPMasterDirective(AStmt, StartLoc, EndLoc); 2057 break; 2058 case OMPD_critical: 2059 assert(ClausesWithImplicit.empty() && 2060 "No clauses are allowed for 'omp critical' directive"); 2061 Res = ActOnOpenMPCriticalDirective(DirName, AStmt, StartLoc, EndLoc); 2062 break; 2063 case OMPD_parallel_for: 2064 Res = ActOnOpenMPParallelForDirective(ClausesWithImplicit, AStmt, StartLoc, 2065 EndLoc, VarsWithInheritedDSA); 2066 break; 2067 case OMPD_parallel_for_simd: 2068 Res = ActOnOpenMPParallelForSimdDirective( 2069 ClausesWithImplicit, AStmt, StartLoc, EndLoc, VarsWithInheritedDSA); 2070 break; 2071 case OMPD_parallel_sections: 2072 Res = ActOnOpenMPParallelSectionsDirective(ClausesWithImplicit, AStmt, 2073 StartLoc, EndLoc); 2074 break; 2075 case OMPD_task: 2076 Res = 2077 ActOnOpenMPTaskDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 2078 break; 2079 case OMPD_taskyield: 2080 assert(ClausesWithImplicit.empty() && 2081 "No clauses are allowed for 'omp taskyield' directive"); 2082 assert(AStmt == nullptr && 2083 "No associated statement allowed for 'omp taskyield' directive"); 2084 Res = ActOnOpenMPTaskyieldDirective(StartLoc, EndLoc); 2085 break; 2086 case OMPD_barrier: 2087 assert(ClausesWithImplicit.empty() && 2088 "No clauses are allowed for 'omp barrier' directive"); 2089 assert(AStmt == nullptr && 2090 "No associated statement allowed for 'omp barrier' directive"); 2091 Res = ActOnOpenMPBarrierDirective(StartLoc, EndLoc); 2092 break; 2093 case OMPD_taskwait: 2094 assert(ClausesWithImplicit.empty() && 2095 "No clauses are allowed for 'omp taskwait' directive"); 2096 assert(AStmt == nullptr && 2097 "No associated statement allowed for 'omp taskwait' directive"); 2098 Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc); 2099 break; 2100 case OMPD_taskgroup: 2101 assert(ClausesWithImplicit.empty() && 2102 "No clauses are allowed for 'omp taskgroup' directive"); 2103 Res = ActOnOpenMPTaskgroupDirective(AStmt, StartLoc, EndLoc); 2104 break; 2105 case OMPD_flush: 2106 assert(AStmt == nullptr && 2107 "No associated statement allowed for 'omp flush' directive"); 2108 Res = ActOnOpenMPFlushDirective(ClausesWithImplicit, StartLoc, EndLoc); 2109 break; 2110 case OMPD_ordered: 2111 assert(ClausesWithImplicit.empty() && 2112 "No clauses are allowed for 'omp ordered' directive"); 2113 Res = ActOnOpenMPOrderedDirective(AStmt, StartLoc, EndLoc); 2114 break; 2115 case OMPD_atomic: 2116 Res = ActOnOpenMPAtomicDirective(ClausesWithImplicit, AStmt, StartLoc, 2117 EndLoc); 2118 break; 2119 case OMPD_teams: 2120 Res = 2121 ActOnOpenMPTeamsDirective(ClausesWithImplicit, AStmt, StartLoc, EndLoc); 2122 break; 2123 case OMPD_target: 2124 Res = ActOnOpenMPTargetDirective(ClausesWithImplicit, AStmt, StartLoc, 2125 EndLoc); 2126 break; 2127 case OMPD_cancellation_point: 2128 assert(ClausesWithImplicit.empty() && 2129 "No clauses are allowed for 'omp cancellation point' directive"); 2130 assert(AStmt == nullptr && "No associated statement allowed for 'omp " 2131 "cancellation point' directive"); 2132 Res = ActOnOpenMPCancellationPointDirective(StartLoc, EndLoc, CancelRegion); 2133 break; 2134 case OMPD_cancel: 2135 assert(ClausesWithImplicit.empty() && 2136 "No clauses are allowed for 'omp cancel' directive"); 2137 assert(AStmt == nullptr && 2138 "No associated statement allowed for 'omp cancel' directive"); 2139 Res = ActOnOpenMPCancelDirective(StartLoc, EndLoc, CancelRegion); 2140 break; 2141 case OMPD_target_data: 2142 Res = ActOnOpenMPTargetDataDirective(ClausesWithImplicit, AStmt, StartLoc, 2143 EndLoc); 2144 break; 2145 case OMPD_threadprivate: 2146 llvm_unreachable("OpenMP Directive is not allowed"); 2147 case OMPD_unknown: 2148 llvm_unreachable("Unknown OpenMP directive"); 2149 } 2150 2151 for (auto P : VarsWithInheritedDSA) { 2152 Diag(P.second->getExprLoc(), diag::err_omp_no_dsa_for_variable) 2153 << P.first << P.second->getSourceRange(); 2154 } 2155 if (!VarsWithInheritedDSA.empty()) 2156 return StmtError(); 2157 2158 if (ErrorFound) 2159 return StmtError(); 2160 return Res; 2161 } 2162 2163 StmtResult Sema::ActOnOpenMPParallelDirective(ArrayRef<OMPClause *> Clauses, 2164 Stmt *AStmt, 2165 SourceLocation StartLoc, 2166 SourceLocation EndLoc) { 2167 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 2168 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 2169 // 1.2.2 OpenMP Language Terminology 2170 // Structured block - An executable statement with a single entry at the 2171 // top and a single exit at the bottom. 2172 // The point of exit cannot be a branch out of the structured block. 2173 // longjmp() and throw() must not violate the entry/exit criteria. 2174 CS->getCapturedDecl()->setNothrow(); 2175 2176 getCurFunction()->setHasBranchProtectedScope(); 2177 2178 return OMPParallelDirective::Create(Context, StartLoc, EndLoc, Clauses, 2179 AStmt); 2180 } 2181 2182 namespace { 2183 /// \brief Helper class for checking canonical form of the OpenMP loops and 2184 /// extracting iteration space of each loop in the loop nest, that will be used 2185 /// for IR generation. 2186 class OpenMPIterationSpaceChecker { 2187 /// \brief Reference to Sema. 2188 Sema &SemaRef; 2189 /// \brief A location for diagnostics (when there is no some better location). 2190 SourceLocation DefaultLoc; 2191 /// \brief A location for diagnostics (when increment is not compatible). 2192 SourceLocation ConditionLoc; 2193 /// \brief A source location for referring to loop init later. 2194 SourceRange InitSrcRange; 2195 /// \brief A source location for referring to condition later. 2196 SourceRange ConditionSrcRange; 2197 /// \brief A source location for referring to increment later. 2198 SourceRange IncrementSrcRange; 2199 /// \brief Loop variable. 2200 VarDecl *Var; 2201 /// \brief Reference to loop variable. 2202 DeclRefExpr *VarRef; 2203 /// \brief Lower bound (initializer for the var). 2204 Expr *LB; 2205 /// \brief Upper bound. 2206 Expr *UB; 2207 /// \brief Loop step (increment). 2208 Expr *Step; 2209 /// \brief This flag is true when condition is one of: 2210 /// Var < UB 2211 /// Var <= UB 2212 /// UB > Var 2213 /// UB >= Var 2214 bool TestIsLessOp; 2215 /// \brief This flag is true when condition is strict ( < or > ). 2216 bool TestIsStrictOp; 2217 /// \brief This flag is true when step is subtracted on each iteration. 2218 bool SubtractStep; 2219 2220 public: 2221 OpenMPIterationSpaceChecker(Sema &SemaRef, SourceLocation DefaultLoc) 2222 : SemaRef(SemaRef), DefaultLoc(DefaultLoc), ConditionLoc(DefaultLoc), 2223 InitSrcRange(SourceRange()), ConditionSrcRange(SourceRange()), 2224 IncrementSrcRange(SourceRange()), Var(nullptr), VarRef(nullptr), 2225 LB(nullptr), UB(nullptr), Step(nullptr), TestIsLessOp(false), 2226 TestIsStrictOp(false), SubtractStep(false) {} 2227 /// \brief Check init-expr for canonical loop form and save loop counter 2228 /// variable - #Var and its initialization value - #LB. 2229 bool CheckInit(Stmt *S, bool EmitDiags = true); 2230 /// \brief Check test-expr for canonical form, save upper-bound (#UB), flags 2231 /// for less/greater and for strict/non-strict comparison. 2232 bool CheckCond(Expr *S); 2233 /// \brief Check incr-expr for canonical loop form and return true if it 2234 /// does not conform, otherwise save loop step (#Step). 2235 bool CheckInc(Expr *S); 2236 /// \brief Return the loop counter variable. 2237 VarDecl *GetLoopVar() const { return Var; } 2238 /// \brief Return the reference expression to loop counter variable. 2239 DeclRefExpr *GetLoopVarRefExpr() const { return VarRef; } 2240 /// \brief Source range of the loop init. 2241 SourceRange GetInitSrcRange() const { return InitSrcRange; } 2242 /// \brief Source range of the loop condition. 2243 SourceRange GetConditionSrcRange() const { return ConditionSrcRange; } 2244 /// \brief Source range of the loop increment. 2245 SourceRange GetIncrementSrcRange() const { return IncrementSrcRange; } 2246 /// \brief True if the step should be subtracted. 2247 bool ShouldSubtractStep() const { return SubtractStep; } 2248 /// \brief Build the expression to calculate the number of iterations. 2249 Expr *BuildNumIterations(Scope *S, const bool LimitedType) const; 2250 /// \brief Build the precondition expression for the loops. 2251 Expr *BuildPreCond(Scope *S, Expr *Cond) const; 2252 /// \brief Build reference expression to the counter be used for codegen. 2253 Expr *BuildCounterVar() const; 2254 /// \brief Build reference expression to the private counter be used for 2255 /// codegen. 2256 Expr *BuildPrivateCounterVar() const; 2257 /// \brief Build initization of the counter be used for codegen. 2258 Expr *BuildCounterInit() const; 2259 /// \brief Build step of the counter be used for codegen. 2260 Expr *BuildCounterStep() const; 2261 /// \brief Return true if any expression is dependent. 2262 bool Dependent() const; 2263 2264 private: 2265 /// \brief Check the right-hand side of an assignment in the increment 2266 /// expression. 2267 bool CheckIncRHS(Expr *RHS); 2268 /// \brief Helper to set loop counter variable and its initializer. 2269 bool SetVarAndLB(VarDecl *NewVar, DeclRefExpr *NewVarRefExpr, Expr *NewLB); 2270 /// \brief Helper to set upper bound. 2271 bool SetUB(Expr *NewUB, bool LessOp, bool StrictOp, const SourceRange &SR, 2272 const SourceLocation &SL); 2273 /// \brief Helper to set loop increment. 2274 bool SetStep(Expr *NewStep, bool Subtract); 2275 }; 2276 2277 bool OpenMPIterationSpaceChecker::Dependent() const { 2278 if (!Var) { 2279 assert(!LB && !UB && !Step); 2280 return false; 2281 } 2282 return Var->getType()->isDependentType() || (LB && LB->isValueDependent()) || 2283 (UB && UB->isValueDependent()) || (Step && Step->isValueDependent()); 2284 } 2285 2286 template <typename T> 2287 static T *getExprAsWritten(T *E) { 2288 if (auto *ExprTemp = dyn_cast<ExprWithCleanups>(E)) 2289 E = ExprTemp->getSubExpr(); 2290 2291 if (auto *MTE = dyn_cast<MaterializeTemporaryExpr>(E)) 2292 E = MTE->GetTemporaryExpr(); 2293 2294 while (auto *Binder = dyn_cast<CXXBindTemporaryExpr>(E)) 2295 E = Binder->getSubExpr(); 2296 2297 if (auto *ICE = dyn_cast<ImplicitCastExpr>(E)) 2298 E = ICE->getSubExprAsWritten(); 2299 return E->IgnoreParens(); 2300 } 2301 2302 bool OpenMPIterationSpaceChecker::SetVarAndLB(VarDecl *NewVar, 2303 DeclRefExpr *NewVarRefExpr, 2304 Expr *NewLB) { 2305 // State consistency checking to ensure correct usage. 2306 assert(Var == nullptr && LB == nullptr && VarRef == nullptr && 2307 UB == nullptr && Step == nullptr && !TestIsLessOp && !TestIsStrictOp); 2308 if (!NewVar || !NewLB) 2309 return true; 2310 Var = NewVar; 2311 VarRef = NewVarRefExpr; 2312 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(NewLB)) 2313 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 2314 if ((Ctor->isCopyOrMoveConstructor() || 2315 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 2316 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 2317 NewLB = CE->getArg(0)->IgnoreParenImpCasts(); 2318 LB = NewLB; 2319 return false; 2320 } 2321 2322 bool OpenMPIterationSpaceChecker::SetUB(Expr *NewUB, bool LessOp, bool StrictOp, 2323 const SourceRange &SR, 2324 const SourceLocation &SL) { 2325 // State consistency checking to ensure correct usage. 2326 assert(Var != nullptr && LB != nullptr && UB == nullptr && Step == nullptr && 2327 !TestIsLessOp && !TestIsStrictOp); 2328 if (!NewUB) 2329 return true; 2330 UB = NewUB; 2331 TestIsLessOp = LessOp; 2332 TestIsStrictOp = StrictOp; 2333 ConditionSrcRange = SR; 2334 ConditionLoc = SL; 2335 return false; 2336 } 2337 2338 bool OpenMPIterationSpaceChecker::SetStep(Expr *NewStep, bool Subtract) { 2339 // State consistency checking to ensure correct usage. 2340 assert(Var != nullptr && LB != nullptr && Step == nullptr); 2341 if (!NewStep) 2342 return true; 2343 if (!NewStep->isValueDependent()) { 2344 // Check that the step is integer expression. 2345 SourceLocation StepLoc = NewStep->getLocStart(); 2346 ExprResult Val = 2347 SemaRef.PerformOpenMPImplicitIntegerConversion(StepLoc, NewStep); 2348 if (Val.isInvalid()) 2349 return true; 2350 NewStep = Val.get(); 2351 2352 // OpenMP [2.6, Canonical Loop Form, Restrictions] 2353 // If test-expr is of form var relational-op b and relational-op is < or 2354 // <= then incr-expr must cause var to increase on each iteration of the 2355 // loop. If test-expr is of form var relational-op b and relational-op is 2356 // > or >= then incr-expr must cause var to decrease on each iteration of 2357 // the loop. 2358 // If test-expr is of form b relational-op var and relational-op is < or 2359 // <= then incr-expr must cause var to decrease on each iteration of the 2360 // loop. If test-expr is of form b relational-op var and relational-op is 2361 // > or >= then incr-expr must cause var to increase on each iteration of 2362 // the loop. 2363 llvm::APSInt Result; 2364 bool IsConstant = NewStep->isIntegerConstantExpr(Result, SemaRef.Context); 2365 bool IsUnsigned = !NewStep->getType()->hasSignedIntegerRepresentation(); 2366 bool IsConstNeg = 2367 IsConstant && Result.isSigned() && (Subtract != Result.isNegative()); 2368 bool IsConstPos = 2369 IsConstant && Result.isSigned() && (Subtract == Result.isNegative()); 2370 bool IsConstZero = IsConstant && !Result.getBoolValue(); 2371 if (UB && (IsConstZero || 2372 (TestIsLessOp ? (IsConstNeg || (IsUnsigned && Subtract)) 2373 : (IsConstPos || (IsUnsigned && !Subtract))))) { 2374 SemaRef.Diag(NewStep->getExprLoc(), 2375 diag::err_omp_loop_incr_not_compatible) 2376 << Var << TestIsLessOp << NewStep->getSourceRange(); 2377 SemaRef.Diag(ConditionLoc, 2378 diag::note_omp_loop_cond_requres_compatible_incr) 2379 << TestIsLessOp << ConditionSrcRange; 2380 return true; 2381 } 2382 if (TestIsLessOp == Subtract) { 2383 NewStep = SemaRef.CreateBuiltinUnaryOp(NewStep->getExprLoc(), UO_Minus, 2384 NewStep).get(); 2385 Subtract = !Subtract; 2386 } 2387 } 2388 2389 Step = NewStep; 2390 SubtractStep = Subtract; 2391 return false; 2392 } 2393 2394 bool OpenMPIterationSpaceChecker::CheckInit(Stmt *S, bool EmitDiags) { 2395 // Check init-expr for canonical loop form and save loop counter 2396 // variable - #Var and its initialization value - #LB. 2397 // OpenMP [2.6] Canonical loop form. init-expr may be one of the following: 2398 // var = lb 2399 // integer-type var = lb 2400 // random-access-iterator-type var = lb 2401 // pointer-type var = lb 2402 // 2403 if (!S) { 2404 if (EmitDiags) { 2405 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_init); 2406 } 2407 return true; 2408 } 2409 InitSrcRange = S->getSourceRange(); 2410 if (Expr *E = dyn_cast<Expr>(S)) 2411 S = E->IgnoreParens(); 2412 if (auto BO = dyn_cast<BinaryOperator>(S)) { 2413 if (BO->getOpcode() == BO_Assign) 2414 if (auto DRE = dyn_cast<DeclRefExpr>(BO->getLHS()->IgnoreParens())) 2415 return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE, 2416 BO->getRHS()); 2417 } else if (auto DS = dyn_cast<DeclStmt>(S)) { 2418 if (DS->isSingleDecl()) { 2419 if (auto Var = dyn_cast_or_null<VarDecl>(DS->getSingleDecl())) { 2420 if (Var->hasInit() && !Var->getType()->isReferenceType()) { 2421 // Accept non-canonical init form here but emit ext. warning. 2422 if (Var->getInitStyle() != VarDecl::CInit && EmitDiags) 2423 SemaRef.Diag(S->getLocStart(), 2424 diag::ext_omp_loop_not_canonical_init) 2425 << S->getSourceRange(); 2426 return SetVarAndLB(Var, nullptr, Var->getInit()); 2427 } 2428 } 2429 } 2430 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) 2431 if (CE->getOperator() == OO_Equal) 2432 if (auto DRE = dyn_cast<DeclRefExpr>(CE->getArg(0))) 2433 return SetVarAndLB(dyn_cast<VarDecl>(DRE->getDecl()), DRE, 2434 CE->getArg(1)); 2435 2436 if (EmitDiags) { 2437 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_init) 2438 << S->getSourceRange(); 2439 } 2440 return true; 2441 } 2442 2443 /// \brief Ignore parenthesizes, implicit casts, copy constructor and return the 2444 /// variable (which may be the loop variable) if possible. 2445 static const VarDecl *GetInitVarDecl(const Expr *E) { 2446 if (!E) 2447 return nullptr; 2448 E = getExprAsWritten(E); 2449 if (auto *CE = dyn_cast_or_null<CXXConstructExpr>(E)) 2450 if (const CXXConstructorDecl *Ctor = CE->getConstructor()) 2451 if ((Ctor->isCopyOrMoveConstructor() || 2452 Ctor->isConvertingConstructor(/*AllowExplicit=*/false)) && 2453 CE->getNumArgs() > 0 && CE->getArg(0) != nullptr) 2454 E = CE->getArg(0)->IgnoreParenImpCasts(); 2455 auto DRE = dyn_cast_or_null<DeclRefExpr>(E); 2456 if (!DRE) 2457 return nullptr; 2458 return dyn_cast<VarDecl>(DRE->getDecl()); 2459 } 2460 2461 bool OpenMPIterationSpaceChecker::CheckCond(Expr *S) { 2462 // Check test-expr for canonical form, save upper-bound UB, flags for 2463 // less/greater and for strict/non-strict comparison. 2464 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 2465 // var relational-op b 2466 // b relational-op var 2467 // 2468 if (!S) { 2469 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_cond) << Var; 2470 return true; 2471 } 2472 S = getExprAsWritten(S); 2473 SourceLocation CondLoc = S->getLocStart(); 2474 if (auto BO = dyn_cast<BinaryOperator>(S)) { 2475 if (BO->isRelationalOp()) { 2476 if (GetInitVarDecl(BO->getLHS()) == Var) 2477 return SetUB(BO->getRHS(), 2478 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_LE), 2479 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 2480 BO->getSourceRange(), BO->getOperatorLoc()); 2481 if (GetInitVarDecl(BO->getRHS()) == Var) 2482 return SetUB(BO->getLHS(), 2483 (BO->getOpcode() == BO_GT || BO->getOpcode() == BO_GE), 2484 (BO->getOpcode() == BO_LT || BO->getOpcode() == BO_GT), 2485 BO->getSourceRange(), BO->getOperatorLoc()); 2486 } 2487 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 2488 if (CE->getNumArgs() == 2) { 2489 auto Op = CE->getOperator(); 2490 switch (Op) { 2491 case OO_Greater: 2492 case OO_GreaterEqual: 2493 case OO_Less: 2494 case OO_LessEqual: 2495 if (GetInitVarDecl(CE->getArg(0)) == Var) 2496 return SetUB(CE->getArg(1), Op == OO_Less || Op == OO_LessEqual, 2497 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 2498 CE->getOperatorLoc()); 2499 if (GetInitVarDecl(CE->getArg(1)) == Var) 2500 return SetUB(CE->getArg(0), Op == OO_Greater || Op == OO_GreaterEqual, 2501 Op == OO_Less || Op == OO_Greater, CE->getSourceRange(), 2502 CE->getOperatorLoc()); 2503 break; 2504 default: 2505 break; 2506 } 2507 } 2508 } 2509 SemaRef.Diag(CondLoc, diag::err_omp_loop_not_canonical_cond) 2510 << S->getSourceRange() << Var; 2511 return true; 2512 } 2513 2514 bool OpenMPIterationSpaceChecker::CheckIncRHS(Expr *RHS) { 2515 // RHS of canonical loop form increment can be: 2516 // var + incr 2517 // incr + var 2518 // var - incr 2519 // 2520 RHS = RHS->IgnoreParenImpCasts(); 2521 if (auto BO = dyn_cast<BinaryOperator>(RHS)) { 2522 if (BO->isAdditiveOp()) { 2523 bool IsAdd = BO->getOpcode() == BO_Add; 2524 if (GetInitVarDecl(BO->getLHS()) == Var) 2525 return SetStep(BO->getRHS(), !IsAdd); 2526 if (IsAdd && GetInitVarDecl(BO->getRHS()) == Var) 2527 return SetStep(BO->getLHS(), false); 2528 } 2529 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(RHS)) { 2530 bool IsAdd = CE->getOperator() == OO_Plus; 2531 if ((IsAdd || CE->getOperator() == OO_Minus) && CE->getNumArgs() == 2) { 2532 if (GetInitVarDecl(CE->getArg(0)) == Var) 2533 return SetStep(CE->getArg(1), !IsAdd); 2534 if (IsAdd && GetInitVarDecl(CE->getArg(1)) == Var) 2535 return SetStep(CE->getArg(0), false); 2536 } 2537 } 2538 SemaRef.Diag(RHS->getLocStart(), diag::err_omp_loop_not_canonical_incr) 2539 << RHS->getSourceRange() << Var; 2540 return true; 2541 } 2542 2543 bool OpenMPIterationSpaceChecker::CheckInc(Expr *S) { 2544 // Check incr-expr for canonical loop form and return true if it 2545 // does not conform. 2546 // OpenMP [2.6] Canonical loop form. Test-expr may be one of the following: 2547 // ++var 2548 // var++ 2549 // --var 2550 // var-- 2551 // var += incr 2552 // var -= incr 2553 // var = var + incr 2554 // var = incr + var 2555 // var = var - incr 2556 // 2557 if (!S) { 2558 SemaRef.Diag(DefaultLoc, diag::err_omp_loop_not_canonical_incr) << Var; 2559 return true; 2560 } 2561 IncrementSrcRange = S->getSourceRange(); 2562 S = S->IgnoreParens(); 2563 if (auto UO = dyn_cast<UnaryOperator>(S)) { 2564 if (UO->isIncrementDecrementOp() && GetInitVarDecl(UO->getSubExpr()) == Var) 2565 return SetStep( 2566 SemaRef.ActOnIntegerConstant(UO->getLocStart(), 2567 (UO->isDecrementOp() ? -1 : 1)).get(), 2568 false); 2569 } else if (auto BO = dyn_cast<BinaryOperator>(S)) { 2570 switch (BO->getOpcode()) { 2571 case BO_AddAssign: 2572 case BO_SubAssign: 2573 if (GetInitVarDecl(BO->getLHS()) == Var) 2574 return SetStep(BO->getRHS(), BO->getOpcode() == BO_SubAssign); 2575 break; 2576 case BO_Assign: 2577 if (GetInitVarDecl(BO->getLHS()) == Var) 2578 return CheckIncRHS(BO->getRHS()); 2579 break; 2580 default: 2581 break; 2582 } 2583 } else if (auto CE = dyn_cast<CXXOperatorCallExpr>(S)) { 2584 switch (CE->getOperator()) { 2585 case OO_PlusPlus: 2586 case OO_MinusMinus: 2587 if (GetInitVarDecl(CE->getArg(0)) == Var) 2588 return SetStep( 2589 SemaRef.ActOnIntegerConstant( 2590 CE->getLocStart(), 2591 ((CE->getOperator() == OO_MinusMinus) ? -1 : 1)).get(), 2592 false); 2593 break; 2594 case OO_PlusEqual: 2595 case OO_MinusEqual: 2596 if (GetInitVarDecl(CE->getArg(0)) == Var) 2597 return SetStep(CE->getArg(1), CE->getOperator() == OO_MinusEqual); 2598 break; 2599 case OO_Equal: 2600 if (GetInitVarDecl(CE->getArg(0)) == Var) 2601 return CheckIncRHS(CE->getArg(1)); 2602 break; 2603 default: 2604 break; 2605 } 2606 } 2607 SemaRef.Diag(S->getLocStart(), diag::err_omp_loop_not_canonical_incr) 2608 << S->getSourceRange() << Var; 2609 return true; 2610 } 2611 2612 /// \brief Build the expression to calculate the number of iterations. 2613 Expr * 2614 OpenMPIterationSpaceChecker::BuildNumIterations(Scope *S, 2615 const bool LimitedType) const { 2616 ExprResult Diff; 2617 if (Var->getType()->isIntegerType() || Var->getType()->isPointerType() || 2618 SemaRef.getLangOpts().CPlusPlus) { 2619 // Upper - Lower 2620 Expr *Upper = TestIsLessOp ? UB : LB; 2621 Expr *Lower = TestIsLessOp ? LB : UB; 2622 2623 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Sub, Upper, Lower); 2624 2625 if (!Diff.isUsable() && Var->getType()->getAsCXXRecordDecl()) { 2626 // BuildBinOp already emitted error, this one is to point user to upper 2627 // and lower bound, and to tell what is passed to 'operator-'. 2628 SemaRef.Diag(Upper->getLocStart(), diag::err_omp_loop_diff_cxx) 2629 << Upper->getSourceRange() << Lower->getSourceRange(); 2630 return nullptr; 2631 } 2632 } 2633 2634 if (!Diff.isUsable()) 2635 return nullptr; 2636 2637 // Upper - Lower [- 1] 2638 if (TestIsStrictOp) 2639 Diff = SemaRef.BuildBinOp( 2640 S, DefaultLoc, BO_Sub, Diff.get(), 2641 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 2642 if (!Diff.isUsable()) 2643 return nullptr; 2644 2645 // Upper - Lower [- 1] + Step 2646 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Add, Diff.get(), 2647 Step->IgnoreImplicit()); 2648 if (!Diff.isUsable()) 2649 return nullptr; 2650 2651 // Parentheses (for dumping/debugging purposes only). 2652 Diff = SemaRef.ActOnParenExpr(DefaultLoc, DefaultLoc, Diff.get()); 2653 if (!Diff.isUsable()) 2654 return nullptr; 2655 2656 // (Upper - Lower [- 1] + Step) / Step 2657 Diff = SemaRef.BuildBinOp(S, DefaultLoc, BO_Div, Diff.get(), 2658 Step->IgnoreImplicit()); 2659 if (!Diff.isUsable()) 2660 return nullptr; 2661 2662 // OpenMP runtime requires 32-bit or 64-bit loop variables. 2663 if (LimitedType) { 2664 auto &C = SemaRef.Context; 2665 QualType Type = Diff.get()->getType(); 2666 unsigned NewSize = (C.getTypeSize(Type) > 32) ? 64 : 32; 2667 if (NewSize != C.getTypeSize(Type)) { 2668 if (NewSize < C.getTypeSize(Type)) { 2669 assert(NewSize == 64 && "incorrect loop var size"); 2670 SemaRef.Diag(DefaultLoc, diag::warn_omp_loop_64_bit_var) 2671 << InitSrcRange << ConditionSrcRange; 2672 } 2673 QualType NewType = C.getIntTypeForBitwidth( 2674 NewSize, Type->hasSignedIntegerRepresentation()); 2675 Diff = SemaRef.PerformImplicitConversion(Diff.get(), NewType, 2676 Sema::AA_Converting, true); 2677 if (!Diff.isUsable()) 2678 return nullptr; 2679 } 2680 } 2681 2682 return Diff.get(); 2683 } 2684 2685 Expr *OpenMPIterationSpaceChecker::BuildPreCond(Scope *S, Expr *Cond) const { 2686 // Try to build LB <op> UB, where <op> is <, >, <=, or >=. 2687 bool Suppress = SemaRef.getDiagnostics().getSuppressAllDiagnostics(); 2688 SemaRef.getDiagnostics().setSuppressAllDiagnostics(/*Val=*/true); 2689 auto CondExpr = SemaRef.BuildBinOp( 2690 S, DefaultLoc, TestIsLessOp ? (TestIsStrictOp ? BO_LT : BO_LE) 2691 : (TestIsStrictOp ? BO_GT : BO_GE), 2692 LB, UB); 2693 if (CondExpr.isUsable()) { 2694 CondExpr = SemaRef.PerformImplicitConversion( 2695 CondExpr.get(), SemaRef.Context.BoolTy, /*Action=*/Sema::AA_Casting, 2696 /*AllowExplicit=*/true); 2697 } 2698 SemaRef.getDiagnostics().setSuppressAllDiagnostics(Suppress); 2699 // Otherwise use original loop conditon and evaluate it in runtime. 2700 return CondExpr.isUsable() ? CondExpr.get() : Cond; 2701 } 2702 2703 /// \brief Build reference expression to the counter be used for codegen. 2704 Expr *OpenMPIterationSpaceChecker::BuildCounterVar() const { 2705 return buildDeclRefExpr(SemaRef, Var, Var->getType().getNonReferenceType(), 2706 DefaultLoc); 2707 } 2708 2709 Expr *OpenMPIterationSpaceChecker::BuildPrivateCounterVar() const { 2710 if (Var && !Var->isInvalidDecl()) { 2711 auto Type = Var->getType().getNonReferenceType(); 2712 auto *PrivateVar = buildVarDecl(SemaRef, DefaultLoc, Type, Var->getName()); 2713 if (PrivateVar->isInvalidDecl()) 2714 return nullptr; 2715 return buildDeclRefExpr(SemaRef, PrivateVar, Type, DefaultLoc); 2716 } 2717 return nullptr; 2718 } 2719 2720 /// \brief Build initization of the counter be used for codegen. 2721 Expr *OpenMPIterationSpaceChecker::BuildCounterInit() const { return LB; } 2722 2723 /// \brief Build step of the counter be used for codegen. 2724 Expr *OpenMPIterationSpaceChecker::BuildCounterStep() const { return Step; } 2725 2726 /// \brief Iteration space of a single for loop. 2727 struct LoopIterationSpace { 2728 /// \brief Condition of the loop. 2729 Expr *PreCond; 2730 /// \brief This expression calculates the number of iterations in the loop. 2731 /// It is always possible to calculate it before starting the loop. 2732 Expr *NumIterations; 2733 /// \brief The loop counter variable. 2734 Expr *CounterVar; 2735 /// \brief Private loop counter variable. 2736 Expr *PrivateCounterVar; 2737 /// \brief This is initializer for the initial value of #CounterVar. 2738 Expr *CounterInit; 2739 /// \brief This is step for the #CounterVar used to generate its update: 2740 /// #CounterVar = #CounterInit + #CounterStep * CurrentIteration. 2741 Expr *CounterStep; 2742 /// \brief Should step be subtracted? 2743 bool Subtract; 2744 /// \brief Source range of the loop init. 2745 SourceRange InitSrcRange; 2746 /// \brief Source range of the loop condition. 2747 SourceRange CondSrcRange; 2748 /// \brief Source range of the loop increment. 2749 SourceRange IncSrcRange; 2750 }; 2751 2752 } // namespace 2753 2754 void Sema::ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init) { 2755 assert(getLangOpts().OpenMP && "OpenMP is not active."); 2756 assert(Init && "Expected loop in canonical form."); 2757 unsigned CollapseIteration = DSAStack->getCollapseNumber(); 2758 if (CollapseIteration > 0 && 2759 isOpenMPLoopDirective(DSAStack->getCurrentDirective())) { 2760 OpenMPIterationSpaceChecker ISC(*this, ForLoc); 2761 if (!ISC.CheckInit(Init, /*EmitDiags=*/false)) { 2762 DSAStack->addLoopControlVariable(ISC.GetLoopVar()); 2763 } 2764 DSAStack->setCollapseNumber(CollapseIteration - 1); 2765 } 2766 } 2767 2768 /// \brief Called on a for stmt to check and extract its iteration space 2769 /// for further processing (such as collapsing). 2770 static bool CheckOpenMPIterationSpace( 2771 OpenMPDirectiveKind DKind, Stmt *S, Sema &SemaRef, DSAStackTy &DSA, 2772 unsigned CurrentNestedLoopCount, unsigned NestedLoopCount, 2773 Expr *CollapseLoopCountExpr, Expr *OrderedLoopCountExpr, 2774 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA, 2775 LoopIterationSpace &ResultIterSpace) { 2776 // OpenMP [2.6, Canonical Loop Form] 2777 // for (init-expr; test-expr; incr-expr) structured-block 2778 auto For = dyn_cast_or_null<ForStmt>(S); 2779 if (!For) { 2780 SemaRef.Diag(S->getLocStart(), diag::err_omp_not_for) 2781 << (CollapseLoopCountExpr != nullptr || OrderedLoopCountExpr != nullptr) 2782 << getOpenMPDirectiveName(DKind) << NestedLoopCount 2783 << (CurrentNestedLoopCount > 0) << CurrentNestedLoopCount; 2784 if (NestedLoopCount > 1) { 2785 if (CollapseLoopCountExpr && OrderedLoopCountExpr) 2786 SemaRef.Diag(DSA.getConstructLoc(), 2787 diag::note_omp_collapse_ordered_expr) 2788 << 2 << CollapseLoopCountExpr->getSourceRange() 2789 << OrderedLoopCountExpr->getSourceRange(); 2790 else if (CollapseLoopCountExpr) 2791 SemaRef.Diag(CollapseLoopCountExpr->getExprLoc(), 2792 diag::note_omp_collapse_ordered_expr) 2793 << 0 << CollapseLoopCountExpr->getSourceRange(); 2794 else 2795 SemaRef.Diag(OrderedLoopCountExpr->getExprLoc(), 2796 diag::note_omp_collapse_ordered_expr) 2797 << 1 << OrderedLoopCountExpr->getSourceRange(); 2798 } 2799 return true; 2800 } 2801 assert(For->getBody()); 2802 2803 OpenMPIterationSpaceChecker ISC(SemaRef, For->getForLoc()); 2804 2805 // Check init. 2806 auto Init = For->getInit(); 2807 if (ISC.CheckInit(Init)) { 2808 return true; 2809 } 2810 2811 bool HasErrors = false; 2812 2813 // Check loop variable's type. 2814 auto Var = ISC.GetLoopVar(); 2815 2816 // OpenMP [2.6, Canonical Loop Form] 2817 // Var is one of the following: 2818 // A variable of signed or unsigned integer type. 2819 // For C++, a variable of a random access iterator type. 2820 // For C, a variable of a pointer type. 2821 auto VarType = Var->getType().getNonReferenceType(); 2822 if (!VarType->isDependentType() && !VarType->isIntegerType() && 2823 !VarType->isPointerType() && 2824 !(SemaRef.getLangOpts().CPlusPlus && VarType->isOverloadableType())) { 2825 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_variable_type) 2826 << SemaRef.getLangOpts().CPlusPlus; 2827 HasErrors = true; 2828 } 2829 2830 // OpenMP, 2.14.1.1 Data-sharing Attribute Rules for Variables Referenced in a 2831 // Construct 2832 // The loop iteration variable(s) in the associated for-loop(s) of a for or 2833 // parallel for construct is (are) private. 2834 // The loop iteration variable in the associated for-loop of a simd construct 2835 // with just one associated for-loop is linear with a constant-linear-step 2836 // that is the increment of the associated for-loop. 2837 // Exclude loop var from the list of variables with implicitly defined data 2838 // sharing attributes. 2839 VarsWithImplicitDSA.erase(Var); 2840 2841 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced in 2842 // a Construct, C/C++]. 2843 // The loop iteration variable in the associated for-loop of a simd construct 2844 // with just one associated for-loop may be listed in a linear clause with a 2845 // constant-linear-step that is the increment of the associated for-loop. 2846 // The loop iteration variable(s) in the associated for-loop(s) of a for or 2847 // parallel for construct may be listed in a private or lastprivate clause. 2848 DSAStackTy::DSAVarData DVar = DSA.getTopDSA(Var, false); 2849 auto LoopVarRefExpr = ISC.GetLoopVarRefExpr(); 2850 // If LoopVarRefExpr is nullptr it means the corresponding loop variable is 2851 // declared in the loop and it is predetermined as a private. 2852 auto PredeterminedCKind = 2853 isOpenMPSimdDirective(DKind) 2854 ? ((NestedLoopCount == 1) ? OMPC_linear : OMPC_lastprivate) 2855 : OMPC_private; 2856 if (((isOpenMPSimdDirective(DKind) && DVar.CKind != OMPC_unknown && 2857 DVar.CKind != OMPC_threadprivate && DVar.CKind != PredeterminedCKind) || 2858 (isOpenMPWorksharingDirective(DKind) && !isOpenMPSimdDirective(DKind) && 2859 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private && 2860 DVar.CKind != OMPC_lastprivate && DVar.CKind != OMPC_threadprivate)) && 2861 ((DVar.CKind != OMPC_private && DVar.CKind != OMPC_threadprivate) || 2862 DVar.RefExpr != nullptr)) { 2863 SemaRef.Diag(Init->getLocStart(), diag::err_omp_loop_var_dsa) 2864 << getOpenMPClauseName(DVar.CKind) << getOpenMPDirectiveName(DKind) 2865 << getOpenMPClauseName(PredeterminedCKind); 2866 if (DVar.RefExpr == nullptr) 2867 DVar.CKind = PredeterminedCKind; 2868 ReportOriginalDSA(SemaRef, &DSA, Var, DVar, /*IsLoopIterVar=*/true); 2869 HasErrors = true; 2870 } else if (LoopVarRefExpr != nullptr) { 2871 // Make the loop iteration variable private (for worksharing constructs), 2872 // linear (for simd directives with the only one associated loop) or 2873 // lastprivate (for simd directives with several collapsed or ordered 2874 // loops). 2875 if (DVar.CKind == OMPC_unknown) 2876 DVar = DSA.hasDSA(Var, isOpenMPPrivate, MatchesAlways(), 2877 /*FromParent=*/false); 2878 DSA.addDSA(Var, LoopVarRefExpr, PredeterminedCKind); 2879 } 2880 2881 assert(isOpenMPLoopDirective(DKind) && "DSA for non-loop vars"); 2882 2883 // Check test-expr. 2884 HasErrors |= ISC.CheckCond(For->getCond()); 2885 2886 // Check incr-expr. 2887 HasErrors |= ISC.CheckInc(For->getInc()); 2888 2889 if (ISC.Dependent() || SemaRef.CurContext->isDependentContext() || HasErrors) 2890 return HasErrors; 2891 2892 // Build the loop's iteration space representation. 2893 ResultIterSpace.PreCond = ISC.BuildPreCond(DSA.getCurScope(), For->getCond()); 2894 ResultIterSpace.NumIterations = ISC.BuildNumIterations( 2895 DSA.getCurScope(), /* LimitedType */ isOpenMPWorksharingDirective(DKind)); 2896 ResultIterSpace.CounterVar = ISC.BuildCounterVar(); 2897 ResultIterSpace.PrivateCounterVar = ISC.BuildPrivateCounterVar(); 2898 ResultIterSpace.CounterInit = ISC.BuildCounterInit(); 2899 ResultIterSpace.CounterStep = ISC.BuildCounterStep(); 2900 ResultIterSpace.InitSrcRange = ISC.GetInitSrcRange(); 2901 ResultIterSpace.CondSrcRange = ISC.GetConditionSrcRange(); 2902 ResultIterSpace.IncSrcRange = ISC.GetIncrementSrcRange(); 2903 ResultIterSpace.Subtract = ISC.ShouldSubtractStep(); 2904 2905 HasErrors |= (ResultIterSpace.PreCond == nullptr || 2906 ResultIterSpace.NumIterations == nullptr || 2907 ResultIterSpace.CounterVar == nullptr || 2908 ResultIterSpace.PrivateCounterVar == nullptr || 2909 ResultIterSpace.CounterInit == nullptr || 2910 ResultIterSpace.CounterStep == nullptr); 2911 2912 return HasErrors; 2913 } 2914 2915 /// \brief Build 'VarRef = Start + Iter * Step'. 2916 static ExprResult BuildCounterUpdate(Sema &SemaRef, Scope *S, 2917 SourceLocation Loc, ExprResult VarRef, 2918 ExprResult Start, ExprResult Iter, 2919 ExprResult Step, bool Subtract) { 2920 // Add parentheses (for debugging purposes only). 2921 Iter = SemaRef.ActOnParenExpr(Loc, Loc, Iter.get()); 2922 if (!VarRef.isUsable() || !Start.isUsable() || !Iter.isUsable() || 2923 !Step.isUsable()) 2924 return ExprError(); 2925 2926 ExprResult Update = SemaRef.BuildBinOp(S, Loc, BO_Mul, Iter.get(), 2927 Step.get()->IgnoreImplicit()); 2928 if (!Update.isUsable()) 2929 return ExprError(); 2930 2931 // Build 'VarRef = Start + Iter * Step'. 2932 Update = SemaRef.BuildBinOp(S, Loc, (Subtract ? BO_Sub : BO_Add), 2933 Start.get()->IgnoreImplicit(), Update.get()); 2934 if (!Update.isUsable()) 2935 return ExprError(); 2936 2937 Update = SemaRef.PerformImplicitConversion( 2938 Update.get(), VarRef.get()->getType(), Sema::AA_Converting, true); 2939 if (!Update.isUsable()) 2940 return ExprError(); 2941 2942 Update = SemaRef.BuildBinOp(S, Loc, BO_Assign, VarRef.get(), Update.get()); 2943 return Update; 2944 } 2945 2946 /// \brief Convert integer expression \a E to make it have at least \a Bits 2947 /// bits. 2948 static ExprResult WidenIterationCount(unsigned Bits, Expr *E, 2949 Sema &SemaRef) { 2950 if (E == nullptr) 2951 return ExprError(); 2952 auto &C = SemaRef.Context; 2953 QualType OldType = E->getType(); 2954 unsigned HasBits = C.getTypeSize(OldType); 2955 if (HasBits >= Bits) 2956 return ExprResult(E); 2957 // OK to convert to signed, because new type has more bits than old. 2958 QualType NewType = C.getIntTypeForBitwidth(Bits, /* Signed */ true); 2959 return SemaRef.PerformImplicitConversion(E, NewType, Sema::AA_Converting, 2960 true); 2961 } 2962 2963 /// \brief Check if the given expression \a E is a constant integer that fits 2964 /// into \a Bits bits. 2965 static bool FitsInto(unsigned Bits, bool Signed, Expr *E, Sema &SemaRef) { 2966 if (E == nullptr) 2967 return false; 2968 llvm::APSInt Result; 2969 if (E->isIntegerConstantExpr(Result, SemaRef.Context)) 2970 return Signed ? Result.isSignedIntN(Bits) : Result.isIntN(Bits); 2971 return false; 2972 } 2973 2974 /// \brief Called on a for stmt to check itself and nested loops (if any). 2975 /// \return Returns 0 if one of the collapsed stmts is not canonical for loop, 2976 /// number of collapsed loops otherwise. 2977 static unsigned 2978 CheckOpenMPLoop(OpenMPDirectiveKind DKind, Expr *CollapseLoopCountExpr, 2979 Expr *OrderedLoopCountExpr, Stmt *AStmt, Sema &SemaRef, 2980 DSAStackTy &DSA, 2981 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA, 2982 OMPLoopDirective::HelperExprs &Built) { 2983 unsigned NestedLoopCount = 1; 2984 if (CollapseLoopCountExpr) { 2985 // Found 'collapse' clause - calculate collapse number. 2986 llvm::APSInt Result; 2987 if (CollapseLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 2988 NestedLoopCount += Result.getLimitedValue() - 1; 2989 } 2990 if (OrderedLoopCountExpr) { 2991 // Found 'ordered' clause - calculate collapse number. 2992 llvm::APSInt Result; 2993 if (OrderedLoopCountExpr->EvaluateAsInt(Result, SemaRef.getASTContext())) 2994 NestedLoopCount += Result.getLimitedValue() - 1; 2995 } 2996 // This is helper routine for loop directives (e.g., 'for', 'simd', 2997 // 'for simd', etc.). 2998 SmallVector<LoopIterationSpace, 4> IterSpaces; 2999 IterSpaces.resize(NestedLoopCount); 3000 Stmt *CurStmt = AStmt->IgnoreContainers(/* IgnoreCaptured */ true); 3001 for (unsigned Cnt = 0; Cnt < NestedLoopCount; ++Cnt) { 3002 if (CheckOpenMPIterationSpace(DKind, CurStmt, SemaRef, DSA, Cnt, 3003 NestedLoopCount, CollapseLoopCountExpr, 3004 OrderedLoopCountExpr, VarsWithImplicitDSA, 3005 IterSpaces[Cnt])) 3006 return 0; 3007 // Move on to the next nested for loop, or to the loop body. 3008 // OpenMP [2.8.1, simd construct, Restrictions] 3009 // All loops associated with the construct must be perfectly nested; that 3010 // is, there must be no intervening code nor any OpenMP directive between 3011 // any two loops. 3012 CurStmt = cast<ForStmt>(CurStmt)->getBody()->IgnoreContainers(); 3013 } 3014 3015 Built.clear(/* size */ NestedLoopCount); 3016 3017 if (SemaRef.CurContext->isDependentContext()) 3018 return NestedLoopCount; 3019 3020 // An example of what is generated for the following code: 3021 // 3022 // #pragma omp simd collapse(2) ordered(2) 3023 // for (i = 0; i < NI; ++i) 3024 // for (k = 0; k < NK; ++k) 3025 // for (j = J0; j < NJ; j+=2) { 3026 // <loop body> 3027 // } 3028 // 3029 // We generate the code below. 3030 // Note: the loop body may be outlined in CodeGen. 3031 // Note: some counters may be C++ classes, operator- is used to find number of 3032 // iterations and operator+= to calculate counter value. 3033 // Note: decltype(NumIterations) must be integer type (in 'omp for', only i32 3034 // or i64 is currently supported). 3035 // 3036 // #define NumIterations (NI * ((NJ - J0 - 1 + 2) / 2)) 3037 // for (int[32|64]_t IV = 0; IV < NumIterations; ++IV ) { 3038 // .local.i = IV / ((NJ - J0 - 1 + 2) / 2); 3039 // .local.j = J0 + (IV % ((NJ - J0 - 1 + 2) / 2)) * 2; 3040 // // similar updates for vars in clauses (e.g. 'linear') 3041 // <loop body (using local i and j)> 3042 // } 3043 // i = NI; // assign final values of counters 3044 // j = NJ; 3045 // 3046 3047 // Last iteration number is (I1 * I2 * ... In) - 1, where I1, I2 ... In are 3048 // the iteration counts of the collapsed for loops. 3049 // Precondition tests if there is at least one iteration (all conditions are 3050 // true). 3051 auto PreCond = ExprResult(IterSpaces[0].PreCond); 3052 auto N0 = IterSpaces[0].NumIterations; 3053 ExprResult LastIteration32 = WidenIterationCount(32 /* Bits */, N0, SemaRef); 3054 ExprResult LastIteration64 = WidenIterationCount(64 /* Bits */, N0, SemaRef); 3055 3056 if (!LastIteration32.isUsable() || !LastIteration64.isUsable()) 3057 return NestedLoopCount; 3058 3059 auto &C = SemaRef.Context; 3060 bool AllCountsNeedLessThan32Bits = C.getTypeSize(N0->getType()) < 32; 3061 3062 Scope *CurScope = DSA.getCurScope(); 3063 for (unsigned Cnt = 1; Cnt < NestedLoopCount; ++Cnt) { 3064 if (PreCond.isUsable()) { 3065 PreCond = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_LAnd, 3066 PreCond.get(), IterSpaces[Cnt].PreCond); 3067 } 3068 auto N = IterSpaces[Cnt].NumIterations; 3069 AllCountsNeedLessThan32Bits &= C.getTypeSize(N->getType()) < 32; 3070 if (LastIteration32.isUsable()) 3071 LastIteration32 = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_Mul, 3072 LastIteration32.get(), N); 3073 if (LastIteration64.isUsable()) 3074 LastIteration64 = SemaRef.BuildBinOp(CurScope, SourceLocation(), BO_Mul, 3075 LastIteration64.get(), N); 3076 } 3077 3078 // Choose either the 32-bit or 64-bit version. 3079 ExprResult LastIteration = LastIteration64; 3080 if (LastIteration32.isUsable() && 3081 C.getTypeSize(LastIteration32.get()->getType()) == 32 && 3082 (AllCountsNeedLessThan32Bits || NestedLoopCount == 1 || 3083 FitsInto( 3084 32 /* Bits */, 3085 LastIteration32.get()->getType()->hasSignedIntegerRepresentation(), 3086 LastIteration64.get(), SemaRef))) 3087 LastIteration = LastIteration32; 3088 3089 if (!LastIteration.isUsable()) 3090 return 0; 3091 3092 // Save the number of iterations. 3093 ExprResult NumIterations = LastIteration; 3094 { 3095 LastIteration = SemaRef.BuildBinOp( 3096 CurScope, SourceLocation(), BO_Sub, LastIteration.get(), 3097 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 3098 if (!LastIteration.isUsable()) 3099 return 0; 3100 } 3101 3102 // Calculate the last iteration number beforehand instead of doing this on 3103 // each iteration. Do not do this if the number of iterations may be kfold-ed. 3104 llvm::APSInt Result; 3105 bool IsConstant = 3106 LastIteration.get()->isIntegerConstantExpr(Result, SemaRef.Context); 3107 ExprResult CalcLastIteration; 3108 if (!IsConstant) { 3109 SourceLocation SaveLoc; 3110 VarDecl *SaveVar = 3111 buildVarDecl(SemaRef, SaveLoc, LastIteration.get()->getType(), 3112 ".omp.last.iteration"); 3113 ExprResult SaveRef = buildDeclRefExpr( 3114 SemaRef, SaveVar, LastIteration.get()->getType(), SaveLoc); 3115 CalcLastIteration = SemaRef.BuildBinOp(CurScope, SaveLoc, BO_Assign, 3116 SaveRef.get(), LastIteration.get()); 3117 LastIteration = SaveRef; 3118 3119 // Prepare SaveRef + 1. 3120 NumIterations = SemaRef.BuildBinOp( 3121 CurScope, SaveLoc, BO_Add, SaveRef.get(), 3122 SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get()); 3123 if (!NumIterations.isUsable()) 3124 return 0; 3125 } 3126 3127 SourceLocation InitLoc = IterSpaces[0].InitSrcRange.getBegin(); 3128 3129 QualType VType = LastIteration.get()->getType(); 3130 // Build variables passed into runtime, nesessary for worksharing directives. 3131 ExprResult LB, UB, IL, ST, EUB; 3132 if (isOpenMPWorksharingDirective(DKind)) { 3133 // Lower bound variable, initialized with zero. 3134 VarDecl *LBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.lb"); 3135 LB = buildDeclRefExpr(SemaRef, LBDecl, VType, InitLoc); 3136 SemaRef.AddInitializerToDecl( 3137 LBDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 3138 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 3139 3140 // Upper bound variable, initialized with last iteration number. 3141 VarDecl *UBDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.ub"); 3142 UB = buildDeclRefExpr(SemaRef, UBDecl, VType, InitLoc); 3143 SemaRef.AddInitializerToDecl(UBDecl, LastIteration.get(), 3144 /*DirectInit*/ false, 3145 /*TypeMayContainAuto*/ false); 3146 3147 // A 32-bit variable-flag where runtime returns 1 for the last iteration. 3148 // This will be used to implement clause 'lastprivate'. 3149 QualType Int32Ty = SemaRef.Context.getIntTypeForBitwidth(32, true); 3150 VarDecl *ILDecl = buildVarDecl(SemaRef, InitLoc, Int32Ty, ".omp.is_last"); 3151 IL = buildDeclRefExpr(SemaRef, ILDecl, Int32Ty, InitLoc); 3152 SemaRef.AddInitializerToDecl( 3153 ILDecl, SemaRef.ActOnIntegerConstant(InitLoc, 0).get(), 3154 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 3155 3156 // Stride variable returned by runtime (we initialize it to 1 by default). 3157 VarDecl *STDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.stride"); 3158 ST = buildDeclRefExpr(SemaRef, STDecl, VType, InitLoc); 3159 SemaRef.AddInitializerToDecl( 3160 STDecl, SemaRef.ActOnIntegerConstant(InitLoc, 1).get(), 3161 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 3162 3163 // Build expression: UB = min(UB, LastIteration) 3164 // It is nesessary for CodeGen of directives with static scheduling. 3165 ExprResult IsUBGreater = SemaRef.BuildBinOp(CurScope, InitLoc, BO_GT, 3166 UB.get(), LastIteration.get()); 3167 ExprResult CondOp = SemaRef.ActOnConditionalOp( 3168 InitLoc, InitLoc, IsUBGreater.get(), LastIteration.get(), UB.get()); 3169 EUB = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, UB.get(), 3170 CondOp.get()); 3171 EUB = SemaRef.ActOnFinishFullExpr(EUB.get()); 3172 } 3173 3174 // Build the iteration variable and its initialization before loop. 3175 ExprResult IV; 3176 ExprResult Init; 3177 { 3178 VarDecl *IVDecl = buildVarDecl(SemaRef, InitLoc, VType, ".omp.iv"); 3179 IV = buildDeclRefExpr(SemaRef, IVDecl, VType, InitLoc); 3180 Expr *RHS = isOpenMPWorksharingDirective(DKind) 3181 ? LB.get() 3182 : SemaRef.ActOnIntegerConstant(SourceLocation(), 0).get(); 3183 Init = SemaRef.BuildBinOp(CurScope, InitLoc, BO_Assign, IV.get(), RHS); 3184 Init = SemaRef.ActOnFinishFullExpr(Init.get()); 3185 } 3186 3187 // Loop condition (IV < NumIterations) or (IV <= UB) for worksharing loops. 3188 SourceLocation CondLoc; 3189 ExprResult Cond = 3190 isOpenMPWorksharingDirective(DKind) 3191 ? SemaRef.BuildBinOp(CurScope, CondLoc, BO_LE, IV.get(), UB.get()) 3192 : SemaRef.BuildBinOp(CurScope, CondLoc, BO_LT, IV.get(), 3193 NumIterations.get()); 3194 3195 // Loop increment (IV = IV + 1) 3196 SourceLocation IncLoc; 3197 ExprResult Inc = 3198 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, IV.get(), 3199 SemaRef.ActOnIntegerConstant(IncLoc, 1).get()); 3200 if (!Inc.isUsable()) 3201 return 0; 3202 Inc = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, IV.get(), Inc.get()); 3203 Inc = SemaRef.ActOnFinishFullExpr(Inc.get()); 3204 if (!Inc.isUsable()) 3205 return 0; 3206 3207 // Increments for worksharing loops (LB = LB + ST; UB = UB + ST). 3208 // Used for directives with static scheduling. 3209 ExprResult NextLB, NextUB; 3210 if (isOpenMPWorksharingDirective(DKind)) { 3211 // LB + ST 3212 NextLB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, LB.get(), ST.get()); 3213 if (!NextLB.isUsable()) 3214 return 0; 3215 // LB = LB + ST 3216 NextLB = 3217 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, LB.get(), NextLB.get()); 3218 NextLB = SemaRef.ActOnFinishFullExpr(NextLB.get()); 3219 if (!NextLB.isUsable()) 3220 return 0; 3221 // UB + ST 3222 NextUB = SemaRef.BuildBinOp(CurScope, IncLoc, BO_Add, UB.get(), ST.get()); 3223 if (!NextUB.isUsable()) 3224 return 0; 3225 // UB = UB + ST 3226 NextUB = 3227 SemaRef.BuildBinOp(CurScope, IncLoc, BO_Assign, UB.get(), NextUB.get()); 3228 NextUB = SemaRef.ActOnFinishFullExpr(NextUB.get()); 3229 if (!NextUB.isUsable()) 3230 return 0; 3231 } 3232 3233 // Build updates and final values of the loop counters. 3234 bool HasErrors = false; 3235 Built.Counters.resize(NestedLoopCount); 3236 Built.Updates.resize(NestedLoopCount); 3237 Built.Finals.resize(NestedLoopCount); 3238 { 3239 ExprResult Div; 3240 // Go from inner nested loop to outer. 3241 for (int Cnt = NestedLoopCount - 1; Cnt >= 0; --Cnt) { 3242 LoopIterationSpace &IS = IterSpaces[Cnt]; 3243 SourceLocation UpdLoc = IS.IncSrcRange.getBegin(); 3244 // Build: Iter = (IV / Div) % IS.NumIters 3245 // where Div is product of previous iterations' IS.NumIters. 3246 ExprResult Iter; 3247 if (Div.isUsable()) { 3248 Iter = 3249 SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Div, IV.get(), Div.get()); 3250 } else { 3251 Iter = IV; 3252 assert((Cnt == (int)NestedLoopCount - 1) && 3253 "unusable div expected on first iteration only"); 3254 } 3255 3256 if (Cnt != 0 && Iter.isUsable()) 3257 Iter = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Rem, Iter.get(), 3258 IS.NumIterations); 3259 if (!Iter.isUsable()) { 3260 HasErrors = true; 3261 break; 3262 } 3263 3264 // Build update: IS.CounterVar(Private) = IS.Start + Iter * IS.Step 3265 auto *CounterVar = buildDeclRefExpr( 3266 SemaRef, cast<VarDecl>(cast<DeclRefExpr>(IS.CounterVar)->getDecl()), 3267 IS.CounterVar->getType(), IS.CounterVar->getExprLoc(), 3268 /*RefersToCapture=*/true); 3269 ExprResult Update = 3270 BuildCounterUpdate(SemaRef, CurScope, UpdLoc, CounterVar, 3271 IS.CounterInit, Iter, IS.CounterStep, IS.Subtract); 3272 if (!Update.isUsable()) { 3273 HasErrors = true; 3274 break; 3275 } 3276 3277 // Build final: IS.CounterVar = IS.Start + IS.NumIters * IS.Step 3278 ExprResult Final = BuildCounterUpdate( 3279 SemaRef, CurScope, UpdLoc, CounterVar, IS.CounterInit, 3280 IS.NumIterations, IS.CounterStep, IS.Subtract); 3281 if (!Final.isUsable()) { 3282 HasErrors = true; 3283 break; 3284 } 3285 3286 // Build Div for the next iteration: Div <- Div * IS.NumIters 3287 if (Cnt != 0) { 3288 if (Div.isUnset()) 3289 Div = IS.NumIterations; 3290 else 3291 Div = SemaRef.BuildBinOp(CurScope, UpdLoc, BO_Mul, Div.get(), 3292 IS.NumIterations); 3293 3294 // Add parentheses (for debugging purposes only). 3295 if (Div.isUsable()) 3296 Div = SemaRef.ActOnParenExpr(UpdLoc, UpdLoc, Div.get()); 3297 if (!Div.isUsable()) { 3298 HasErrors = true; 3299 break; 3300 } 3301 } 3302 if (!Update.isUsable() || !Final.isUsable()) { 3303 HasErrors = true; 3304 break; 3305 } 3306 // Save results 3307 Built.Counters[Cnt] = IS.CounterVar; 3308 Built.PrivateCounters[Cnt] = IS.PrivateCounterVar; 3309 Built.Updates[Cnt] = Update.get(); 3310 Built.Finals[Cnt] = Final.get(); 3311 } 3312 } 3313 3314 if (HasErrors) 3315 return 0; 3316 3317 // Save results 3318 Built.IterationVarRef = IV.get(); 3319 Built.LastIteration = LastIteration.get(); 3320 Built.NumIterations = NumIterations.get(); 3321 Built.CalcLastIteration = 3322 SemaRef.ActOnFinishFullExpr(CalcLastIteration.get()).get(); 3323 Built.PreCond = PreCond.get(); 3324 Built.Cond = Cond.get(); 3325 Built.Init = Init.get(); 3326 Built.Inc = Inc.get(); 3327 Built.LB = LB.get(); 3328 Built.UB = UB.get(); 3329 Built.IL = IL.get(); 3330 Built.ST = ST.get(); 3331 Built.EUB = EUB.get(); 3332 Built.NLB = NextLB.get(); 3333 Built.NUB = NextUB.get(); 3334 3335 return NestedLoopCount; 3336 } 3337 3338 static Expr *getCollapseNumberExpr(ArrayRef<OMPClause *> Clauses) { 3339 auto &&CollapseFilter = [](const OMPClause *C) -> bool { 3340 return C->getClauseKind() == OMPC_collapse; 3341 }; 3342 OMPExecutableDirective::filtered_clause_iterator<decltype(CollapseFilter)> I( 3343 Clauses, std::move(CollapseFilter)); 3344 if (I) 3345 return cast<OMPCollapseClause>(*I)->getNumForLoops(); 3346 return nullptr; 3347 } 3348 3349 static Expr *getOrderedNumberExpr(ArrayRef<OMPClause *> Clauses) { 3350 auto &&OrderedFilter = [](const OMPClause *C) -> bool { 3351 return C->getClauseKind() == OMPC_ordered; 3352 }; 3353 OMPExecutableDirective::filtered_clause_iterator<decltype(OrderedFilter)> I( 3354 Clauses, std::move(OrderedFilter)); 3355 if (I) 3356 return cast<OMPOrderedClause>(*I)->getNumForLoops(); 3357 return nullptr; 3358 } 3359 3360 StmtResult Sema::ActOnOpenMPSimdDirective( 3361 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 3362 SourceLocation EndLoc, 3363 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { 3364 OMPLoopDirective::HelperExprs B; 3365 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 3366 // define the nested loops number. 3367 unsigned NestedLoopCount = CheckOpenMPLoop( 3368 OMPD_simd, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 3369 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 3370 if (NestedLoopCount == 0) 3371 return StmtError(); 3372 3373 assert((CurContext->isDependentContext() || B.builtAll()) && 3374 "omp simd loop exprs were not built"); 3375 3376 if (!CurContext->isDependentContext()) { 3377 // Finalize the clauses that need pre-built expressions for CodeGen. 3378 for (auto C : Clauses) { 3379 if (auto LC = dyn_cast<OMPLinearClause>(C)) 3380 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 3381 B.NumIterations, *this, CurScope)) 3382 return StmtError(); 3383 } 3384 } 3385 3386 getCurFunction()->setHasBranchProtectedScope(); 3387 return OMPSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 3388 Clauses, AStmt, B); 3389 } 3390 3391 StmtResult Sema::ActOnOpenMPForDirective( 3392 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 3393 SourceLocation EndLoc, 3394 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { 3395 OMPLoopDirective::HelperExprs B; 3396 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 3397 // define the nested loops number. 3398 unsigned NestedLoopCount = CheckOpenMPLoop( 3399 OMPD_for, getCollapseNumberExpr(Clauses), getOrderedNumberExpr(Clauses), 3400 AStmt, *this, *DSAStack, VarsWithImplicitDSA, B); 3401 if (NestedLoopCount == 0) 3402 return StmtError(); 3403 3404 assert((CurContext->isDependentContext() || B.builtAll()) && 3405 "omp for loop exprs were not built"); 3406 3407 if (!CurContext->isDependentContext()) { 3408 // Finalize the clauses that need pre-built expressions for CodeGen. 3409 for (auto C : Clauses) { 3410 if (auto LC = dyn_cast<OMPLinearClause>(C)) 3411 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 3412 B.NumIterations, *this, CurScope)) 3413 return StmtError(); 3414 } 3415 } 3416 3417 getCurFunction()->setHasBranchProtectedScope(); 3418 return OMPForDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 3419 Clauses, AStmt, B); 3420 } 3421 3422 StmtResult Sema::ActOnOpenMPForSimdDirective( 3423 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 3424 SourceLocation EndLoc, 3425 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { 3426 OMPLoopDirective::HelperExprs B; 3427 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 3428 // define the nested loops number. 3429 unsigned NestedLoopCount = 3430 CheckOpenMPLoop(OMPD_for_simd, getCollapseNumberExpr(Clauses), 3431 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 3432 VarsWithImplicitDSA, B); 3433 if (NestedLoopCount == 0) 3434 return StmtError(); 3435 3436 assert((CurContext->isDependentContext() || B.builtAll()) && 3437 "omp for simd loop exprs were not built"); 3438 3439 if (!CurContext->isDependentContext()) { 3440 // Finalize the clauses that need pre-built expressions for CodeGen. 3441 for (auto C : Clauses) { 3442 if (auto LC = dyn_cast<OMPLinearClause>(C)) 3443 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 3444 B.NumIterations, *this, CurScope)) 3445 return StmtError(); 3446 } 3447 } 3448 3449 getCurFunction()->setHasBranchProtectedScope(); 3450 return OMPForSimdDirective::Create(Context, StartLoc, EndLoc, NestedLoopCount, 3451 Clauses, AStmt, B); 3452 } 3453 3454 StmtResult Sema::ActOnOpenMPSectionsDirective(ArrayRef<OMPClause *> Clauses, 3455 Stmt *AStmt, 3456 SourceLocation StartLoc, 3457 SourceLocation EndLoc) { 3458 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3459 auto BaseStmt = AStmt; 3460 while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 3461 BaseStmt = CS->getCapturedStmt(); 3462 if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 3463 auto S = C->children(); 3464 if (S.begin() == S.end()) 3465 return StmtError(); 3466 // All associated statements must be '#pragma omp section' except for 3467 // the first one. 3468 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 3469 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 3470 if (SectionStmt) 3471 Diag(SectionStmt->getLocStart(), 3472 diag::err_omp_sections_substmt_not_section); 3473 return StmtError(); 3474 } 3475 } 3476 } else { 3477 Diag(AStmt->getLocStart(), diag::err_omp_sections_not_compound_stmt); 3478 return StmtError(); 3479 } 3480 3481 getCurFunction()->setHasBranchProtectedScope(); 3482 3483 return OMPSectionsDirective::Create(Context, StartLoc, EndLoc, Clauses, 3484 AStmt); 3485 } 3486 3487 StmtResult Sema::ActOnOpenMPSectionDirective(Stmt *AStmt, 3488 SourceLocation StartLoc, 3489 SourceLocation EndLoc) { 3490 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3491 3492 getCurFunction()->setHasBranchProtectedScope(); 3493 3494 return OMPSectionDirective::Create(Context, StartLoc, EndLoc, AStmt); 3495 } 3496 3497 StmtResult Sema::ActOnOpenMPSingleDirective(ArrayRef<OMPClause *> Clauses, 3498 Stmt *AStmt, 3499 SourceLocation StartLoc, 3500 SourceLocation EndLoc) { 3501 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3502 3503 getCurFunction()->setHasBranchProtectedScope(); 3504 3505 // OpenMP [2.7.3, single Construct, Restrictions] 3506 // The copyprivate clause must not be used with the nowait clause. 3507 OMPClause *Nowait = nullptr; 3508 OMPClause *Copyprivate = nullptr; 3509 for (auto *Clause : Clauses) { 3510 if (Clause->getClauseKind() == OMPC_nowait) 3511 Nowait = Clause; 3512 else if (Clause->getClauseKind() == OMPC_copyprivate) 3513 Copyprivate = Clause; 3514 if (Copyprivate && Nowait) { 3515 Diag(Copyprivate->getLocStart(), 3516 diag::err_omp_single_copyprivate_with_nowait); 3517 Diag(Nowait->getLocStart(), diag::note_omp_nowait_clause_here); 3518 return StmtError(); 3519 } 3520 } 3521 3522 return OMPSingleDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 3523 } 3524 3525 StmtResult Sema::ActOnOpenMPMasterDirective(Stmt *AStmt, 3526 SourceLocation StartLoc, 3527 SourceLocation EndLoc) { 3528 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3529 3530 getCurFunction()->setHasBranchProtectedScope(); 3531 3532 return OMPMasterDirective::Create(Context, StartLoc, EndLoc, AStmt); 3533 } 3534 3535 StmtResult 3536 Sema::ActOnOpenMPCriticalDirective(const DeclarationNameInfo &DirName, 3537 Stmt *AStmt, SourceLocation StartLoc, 3538 SourceLocation EndLoc) { 3539 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3540 3541 getCurFunction()->setHasBranchProtectedScope(); 3542 3543 return OMPCriticalDirective::Create(Context, DirName, StartLoc, EndLoc, 3544 AStmt); 3545 } 3546 3547 StmtResult Sema::ActOnOpenMPParallelForDirective( 3548 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 3549 SourceLocation EndLoc, 3550 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { 3551 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3552 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 3553 // 1.2.2 OpenMP Language Terminology 3554 // Structured block - An executable statement with a single entry at the 3555 // top and a single exit at the bottom. 3556 // The point of exit cannot be a branch out of the structured block. 3557 // longjmp() and throw() must not violate the entry/exit criteria. 3558 CS->getCapturedDecl()->setNothrow(); 3559 3560 OMPLoopDirective::HelperExprs B; 3561 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 3562 // define the nested loops number. 3563 unsigned NestedLoopCount = 3564 CheckOpenMPLoop(OMPD_parallel_for, getCollapseNumberExpr(Clauses), 3565 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 3566 VarsWithImplicitDSA, B); 3567 if (NestedLoopCount == 0) 3568 return StmtError(); 3569 3570 assert((CurContext->isDependentContext() || B.builtAll()) && 3571 "omp parallel for loop exprs were not built"); 3572 3573 if (!CurContext->isDependentContext()) { 3574 // Finalize the clauses that need pre-built expressions for CodeGen. 3575 for (auto C : Clauses) { 3576 if (auto LC = dyn_cast<OMPLinearClause>(C)) 3577 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 3578 B.NumIterations, *this, CurScope)) 3579 return StmtError(); 3580 } 3581 } 3582 3583 getCurFunction()->setHasBranchProtectedScope(); 3584 return OMPParallelForDirective::Create(Context, StartLoc, EndLoc, 3585 NestedLoopCount, Clauses, AStmt, B); 3586 } 3587 3588 StmtResult Sema::ActOnOpenMPParallelForSimdDirective( 3589 ArrayRef<OMPClause *> Clauses, Stmt *AStmt, SourceLocation StartLoc, 3590 SourceLocation EndLoc, 3591 llvm::DenseMap<VarDecl *, Expr *> &VarsWithImplicitDSA) { 3592 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3593 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 3594 // 1.2.2 OpenMP Language Terminology 3595 // Structured block - An executable statement with a single entry at the 3596 // top and a single exit at the bottom. 3597 // The point of exit cannot be a branch out of the structured block. 3598 // longjmp() and throw() must not violate the entry/exit criteria. 3599 CS->getCapturedDecl()->setNothrow(); 3600 3601 OMPLoopDirective::HelperExprs B; 3602 // In presence of clause 'collapse' or 'ordered' with number of loops, it will 3603 // define the nested loops number. 3604 unsigned NestedLoopCount = 3605 CheckOpenMPLoop(OMPD_parallel_for_simd, getCollapseNumberExpr(Clauses), 3606 getOrderedNumberExpr(Clauses), AStmt, *this, *DSAStack, 3607 VarsWithImplicitDSA, B); 3608 if (NestedLoopCount == 0) 3609 return StmtError(); 3610 3611 if (!CurContext->isDependentContext()) { 3612 // Finalize the clauses that need pre-built expressions for CodeGen. 3613 for (auto C : Clauses) { 3614 if (auto LC = dyn_cast<OMPLinearClause>(C)) 3615 if (FinishOpenMPLinearClause(*LC, cast<DeclRefExpr>(B.IterationVarRef), 3616 B.NumIterations, *this, CurScope)) 3617 return StmtError(); 3618 } 3619 } 3620 3621 getCurFunction()->setHasBranchProtectedScope(); 3622 return OMPParallelForSimdDirective::Create( 3623 Context, StartLoc, EndLoc, NestedLoopCount, Clauses, AStmt, B); 3624 } 3625 3626 StmtResult 3627 Sema::ActOnOpenMPParallelSectionsDirective(ArrayRef<OMPClause *> Clauses, 3628 Stmt *AStmt, SourceLocation StartLoc, 3629 SourceLocation EndLoc) { 3630 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3631 auto BaseStmt = AStmt; 3632 while (CapturedStmt *CS = dyn_cast_or_null<CapturedStmt>(BaseStmt)) 3633 BaseStmt = CS->getCapturedStmt(); 3634 if (auto C = dyn_cast_or_null<CompoundStmt>(BaseStmt)) { 3635 auto S = C->children(); 3636 if (S.begin() == S.end()) 3637 return StmtError(); 3638 // All associated statements must be '#pragma omp section' except for 3639 // the first one. 3640 for (Stmt *SectionStmt : llvm::make_range(std::next(S.begin()), S.end())) { 3641 if (!SectionStmt || !isa<OMPSectionDirective>(SectionStmt)) { 3642 if (SectionStmt) 3643 Diag(SectionStmt->getLocStart(), 3644 diag::err_omp_parallel_sections_substmt_not_section); 3645 return StmtError(); 3646 } 3647 } 3648 } else { 3649 Diag(AStmt->getLocStart(), 3650 diag::err_omp_parallel_sections_not_compound_stmt); 3651 return StmtError(); 3652 } 3653 3654 getCurFunction()->setHasBranchProtectedScope(); 3655 3656 return OMPParallelSectionsDirective::Create(Context, StartLoc, EndLoc, 3657 Clauses, AStmt); 3658 } 3659 3660 StmtResult Sema::ActOnOpenMPTaskDirective(ArrayRef<OMPClause *> Clauses, 3661 Stmt *AStmt, SourceLocation StartLoc, 3662 SourceLocation EndLoc) { 3663 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3664 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 3665 // 1.2.2 OpenMP Language Terminology 3666 // Structured block - An executable statement with a single entry at the 3667 // top and a single exit at the bottom. 3668 // The point of exit cannot be a branch out of the structured block. 3669 // longjmp() and throw() must not violate the entry/exit criteria. 3670 CS->getCapturedDecl()->setNothrow(); 3671 3672 getCurFunction()->setHasBranchProtectedScope(); 3673 3674 return OMPTaskDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 3675 } 3676 3677 StmtResult Sema::ActOnOpenMPTaskyieldDirective(SourceLocation StartLoc, 3678 SourceLocation EndLoc) { 3679 return OMPTaskyieldDirective::Create(Context, StartLoc, EndLoc); 3680 } 3681 3682 StmtResult Sema::ActOnOpenMPBarrierDirective(SourceLocation StartLoc, 3683 SourceLocation EndLoc) { 3684 return OMPBarrierDirective::Create(Context, StartLoc, EndLoc); 3685 } 3686 3687 StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc, 3688 SourceLocation EndLoc) { 3689 return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc); 3690 } 3691 3692 StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt, 3693 SourceLocation StartLoc, 3694 SourceLocation EndLoc) { 3695 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3696 3697 getCurFunction()->setHasBranchProtectedScope(); 3698 3699 return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, AStmt); 3700 } 3701 3702 StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses, 3703 SourceLocation StartLoc, 3704 SourceLocation EndLoc) { 3705 assert(Clauses.size() <= 1 && "Extra clauses in flush directive"); 3706 return OMPFlushDirective::Create(Context, StartLoc, EndLoc, Clauses); 3707 } 3708 3709 StmtResult Sema::ActOnOpenMPOrderedDirective(Stmt *AStmt, 3710 SourceLocation StartLoc, 3711 SourceLocation EndLoc) { 3712 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3713 3714 getCurFunction()->setHasBranchProtectedScope(); 3715 3716 return OMPOrderedDirective::Create(Context, StartLoc, EndLoc, AStmt); 3717 } 3718 3719 namespace { 3720 /// \brief Helper class for checking expression in 'omp atomic [update]' 3721 /// construct. 3722 class OpenMPAtomicUpdateChecker { 3723 /// \brief Error results for atomic update expressions. 3724 enum ExprAnalysisErrorCode { 3725 /// \brief A statement is not an expression statement. 3726 NotAnExpression, 3727 /// \brief Expression is not builtin binary or unary operation. 3728 NotABinaryOrUnaryExpression, 3729 /// \brief Unary operation is not post-/pre- increment/decrement operation. 3730 NotAnUnaryIncDecExpression, 3731 /// \brief An expression is not of scalar type. 3732 NotAScalarType, 3733 /// \brief A binary operation is not an assignment operation. 3734 NotAnAssignmentOp, 3735 /// \brief RHS part of the binary operation is not a binary expression. 3736 NotABinaryExpression, 3737 /// \brief RHS part is not additive/multiplicative/shift/biwise binary 3738 /// expression. 3739 NotABinaryOperator, 3740 /// \brief RHS binary operation does not have reference to the updated LHS 3741 /// part. 3742 NotAnUpdateExpression, 3743 /// \brief No errors is found. 3744 NoError 3745 }; 3746 /// \brief Reference to Sema. 3747 Sema &SemaRef; 3748 /// \brief A location for note diagnostics (when error is found). 3749 SourceLocation NoteLoc; 3750 /// \brief 'x' lvalue part of the source atomic expression. 3751 Expr *X; 3752 /// \brief 'expr' rvalue part of the source atomic expression. 3753 Expr *E; 3754 /// \brief Helper expression of the form 3755 /// 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 3756 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 3757 Expr *UpdateExpr; 3758 /// \brief Is 'x' a LHS in a RHS part of full update expression. It is 3759 /// important for non-associative operations. 3760 bool IsXLHSInRHSPart; 3761 BinaryOperatorKind Op; 3762 SourceLocation OpLoc; 3763 /// \brief true if the source expression is a postfix unary operation, false 3764 /// if it is a prefix unary operation. 3765 bool IsPostfixUpdate; 3766 3767 public: 3768 OpenMPAtomicUpdateChecker(Sema &SemaRef) 3769 : SemaRef(SemaRef), X(nullptr), E(nullptr), UpdateExpr(nullptr), 3770 IsXLHSInRHSPart(false), Op(BO_PtrMemD), IsPostfixUpdate(false) {} 3771 /// \brief Check specified statement that it is suitable for 'atomic update' 3772 /// constructs and extract 'x', 'expr' and Operation from the original 3773 /// expression. If DiagId and NoteId == 0, then only check is performed 3774 /// without error notification. 3775 /// \param DiagId Diagnostic which should be emitted if error is found. 3776 /// \param NoteId Diagnostic note for the main error message. 3777 /// \return true if statement is not an update expression, false otherwise. 3778 bool checkStatement(Stmt *S, unsigned DiagId = 0, unsigned NoteId = 0); 3779 /// \brief Return the 'x' lvalue part of the source atomic expression. 3780 Expr *getX() const { return X; } 3781 /// \brief Return the 'expr' rvalue part of the source atomic expression. 3782 Expr *getExpr() const { return E; } 3783 /// \brief Return the update expression used in calculation of the updated 3784 /// value. Always has form 'OpaqueValueExpr(x) binop OpaqueValueExpr(expr)' or 3785 /// 'OpaqueValueExpr(expr) binop OpaqueValueExpr(x)'. 3786 Expr *getUpdateExpr() const { return UpdateExpr; } 3787 /// \brief Return true if 'x' is LHS in RHS part of full update expression, 3788 /// false otherwise. 3789 bool isXLHSInRHSPart() const { return IsXLHSInRHSPart; } 3790 3791 /// \brief true if the source expression is a postfix unary operation, false 3792 /// if it is a prefix unary operation. 3793 bool isPostfixUpdate() const { return IsPostfixUpdate; } 3794 3795 private: 3796 bool checkBinaryOperation(BinaryOperator *AtomicBinOp, unsigned DiagId = 0, 3797 unsigned NoteId = 0); 3798 }; 3799 } // namespace 3800 3801 bool OpenMPAtomicUpdateChecker::checkBinaryOperation( 3802 BinaryOperator *AtomicBinOp, unsigned DiagId, unsigned NoteId) { 3803 ExprAnalysisErrorCode ErrorFound = NoError; 3804 SourceLocation ErrorLoc, NoteLoc; 3805 SourceRange ErrorRange, NoteRange; 3806 // Allowed constructs are: 3807 // x = x binop expr; 3808 // x = expr binop x; 3809 if (AtomicBinOp->getOpcode() == BO_Assign) { 3810 X = AtomicBinOp->getLHS(); 3811 if (auto *AtomicInnerBinOp = dyn_cast<BinaryOperator>( 3812 AtomicBinOp->getRHS()->IgnoreParenImpCasts())) { 3813 if (AtomicInnerBinOp->isMultiplicativeOp() || 3814 AtomicInnerBinOp->isAdditiveOp() || AtomicInnerBinOp->isShiftOp() || 3815 AtomicInnerBinOp->isBitwiseOp()) { 3816 Op = AtomicInnerBinOp->getOpcode(); 3817 OpLoc = AtomicInnerBinOp->getOperatorLoc(); 3818 auto *LHS = AtomicInnerBinOp->getLHS(); 3819 auto *RHS = AtomicInnerBinOp->getRHS(); 3820 llvm::FoldingSetNodeID XId, LHSId, RHSId; 3821 X->IgnoreParenImpCasts()->Profile(XId, SemaRef.getASTContext(), 3822 /*Canonical=*/true); 3823 LHS->IgnoreParenImpCasts()->Profile(LHSId, SemaRef.getASTContext(), 3824 /*Canonical=*/true); 3825 RHS->IgnoreParenImpCasts()->Profile(RHSId, SemaRef.getASTContext(), 3826 /*Canonical=*/true); 3827 if (XId == LHSId) { 3828 E = RHS; 3829 IsXLHSInRHSPart = true; 3830 } else if (XId == RHSId) { 3831 E = LHS; 3832 IsXLHSInRHSPart = false; 3833 } else { 3834 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 3835 ErrorRange = AtomicInnerBinOp->getSourceRange(); 3836 NoteLoc = X->getExprLoc(); 3837 NoteRange = X->getSourceRange(); 3838 ErrorFound = NotAnUpdateExpression; 3839 } 3840 } else { 3841 ErrorLoc = AtomicInnerBinOp->getExprLoc(); 3842 ErrorRange = AtomicInnerBinOp->getSourceRange(); 3843 NoteLoc = AtomicInnerBinOp->getOperatorLoc(); 3844 NoteRange = SourceRange(NoteLoc, NoteLoc); 3845 ErrorFound = NotABinaryOperator; 3846 } 3847 } else { 3848 NoteLoc = ErrorLoc = AtomicBinOp->getRHS()->getExprLoc(); 3849 NoteRange = ErrorRange = AtomicBinOp->getRHS()->getSourceRange(); 3850 ErrorFound = NotABinaryExpression; 3851 } 3852 } else { 3853 ErrorLoc = AtomicBinOp->getExprLoc(); 3854 ErrorRange = AtomicBinOp->getSourceRange(); 3855 NoteLoc = AtomicBinOp->getOperatorLoc(); 3856 NoteRange = SourceRange(NoteLoc, NoteLoc); 3857 ErrorFound = NotAnAssignmentOp; 3858 } 3859 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 3860 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 3861 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 3862 return true; 3863 } else if (SemaRef.CurContext->isDependentContext()) 3864 E = X = UpdateExpr = nullptr; 3865 return ErrorFound != NoError; 3866 } 3867 3868 bool OpenMPAtomicUpdateChecker::checkStatement(Stmt *S, unsigned DiagId, 3869 unsigned NoteId) { 3870 ExprAnalysisErrorCode ErrorFound = NoError; 3871 SourceLocation ErrorLoc, NoteLoc; 3872 SourceRange ErrorRange, NoteRange; 3873 // Allowed constructs are: 3874 // x++; 3875 // x--; 3876 // ++x; 3877 // --x; 3878 // x binop= expr; 3879 // x = x binop expr; 3880 // x = expr binop x; 3881 if (auto *AtomicBody = dyn_cast<Expr>(S)) { 3882 AtomicBody = AtomicBody->IgnoreParenImpCasts(); 3883 if (AtomicBody->getType()->isScalarType() || 3884 AtomicBody->isInstantiationDependent()) { 3885 if (auto *AtomicCompAssignOp = dyn_cast<CompoundAssignOperator>( 3886 AtomicBody->IgnoreParenImpCasts())) { 3887 // Check for Compound Assignment Operation 3888 Op = BinaryOperator::getOpForCompoundAssignment( 3889 AtomicCompAssignOp->getOpcode()); 3890 OpLoc = AtomicCompAssignOp->getOperatorLoc(); 3891 E = AtomicCompAssignOp->getRHS(); 3892 X = AtomicCompAssignOp->getLHS(); 3893 IsXLHSInRHSPart = true; 3894 } else if (auto *AtomicBinOp = dyn_cast<BinaryOperator>( 3895 AtomicBody->IgnoreParenImpCasts())) { 3896 // Check for Binary Operation 3897 if(checkBinaryOperation(AtomicBinOp, DiagId, NoteId)) 3898 return true; 3899 } else if (auto *AtomicUnaryOp = 3900 dyn_cast<UnaryOperator>(AtomicBody->IgnoreParenImpCasts())) { 3901 // Check for Unary Operation 3902 if (AtomicUnaryOp->isIncrementDecrementOp()) { 3903 IsPostfixUpdate = AtomicUnaryOp->isPostfix(); 3904 Op = AtomicUnaryOp->isIncrementOp() ? BO_Add : BO_Sub; 3905 OpLoc = AtomicUnaryOp->getOperatorLoc(); 3906 X = AtomicUnaryOp->getSubExpr(); 3907 E = SemaRef.ActOnIntegerConstant(OpLoc, /*uint64_t Val=*/1).get(); 3908 IsXLHSInRHSPart = true; 3909 } else { 3910 ErrorFound = NotAnUnaryIncDecExpression; 3911 ErrorLoc = AtomicUnaryOp->getExprLoc(); 3912 ErrorRange = AtomicUnaryOp->getSourceRange(); 3913 NoteLoc = AtomicUnaryOp->getOperatorLoc(); 3914 NoteRange = SourceRange(NoteLoc, NoteLoc); 3915 } 3916 } else { 3917 ErrorFound = NotABinaryOrUnaryExpression; 3918 NoteLoc = ErrorLoc = AtomicBody->getExprLoc(); 3919 NoteRange = ErrorRange = AtomicBody->getSourceRange(); 3920 } 3921 } else { 3922 ErrorFound = NotAScalarType; 3923 NoteLoc = ErrorLoc = AtomicBody->getLocStart(); 3924 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 3925 } 3926 } else { 3927 ErrorFound = NotAnExpression; 3928 NoteLoc = ErrorLoc = S->getLocStart(); 3929 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 3930 } 3931 if (ErrorFound != NoError && DiagId != 0 && NoteId != 0) { 3932 SemaRef.Diag(ErrorLoc, DiagId) << ErrorRange; 3933 SemaRef.Diag(NoteLoc, NoteId) << ErrorFound << NoteRange; 3934 return true; 3935 } else if (SemaRef.CurContext->isDependentContext()) 3936 E = X = UpdateExpr = nullptr; 3937 if (ErrorFound == NoError && E && X) { 3938 // Build an update expression of form 'OpaqueValueExpr(x) binop 3939 // OpaqueValueExpr(expr)' or 'OpaqueValueExpr(expr) binop 3940 // OpaqueValueExpr(x)' and then cast it to the type of the 'x' expression. 3941 auto *OVEX = new (SemaRef.getASTContext()) 3942 OpaqueValueExpr(X->getExprLoc(), X->getType(), VK_RValue); 3943 auto *OVEExpr = new (SemaRef.getASTContext()) 3944 OpaqueValueExpr(E->getExprLoc(), E->getType(), VK_RValue); 3945 auto Update = 3946 SemaRef.CreateBuiltinBinOp(OpLoc, Op, IsXLHSInRHSPart ? OVEX : OVEExpr, 3947 IsXLHSInRHSPart ? OVEExpr : OVEX); 3948 if (Update.isInvalid()) 3949 return true; 3950 Update = SemaRef.PerformImplicitConversion(Update.get(), X->getType(), 3951 Sema::AA_Casting); 3952 if (Update.isInvalid()) 3953 return true; 3954 UpdateExpr = Update.get(); 3955 } 3956 return ErrorFound != NoError; 3957 } 3958 3959 StmtResult Sema::ActOnOpenMPAtomicDirective(ArrayRef<OMPClause *> Clauses, 3960 Stmt *AStmt, 3961 SourceLocation StartLoc, 3962 SourceLocation EndLoc) { 3963 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 3964 auto CS = cast<CapturedStmt>(AStmt); 3965 // 1.2.2 OpenMP Language Terminology 3966 // Structured block - An executable statement with a single entry at the 3967 // top and a single exit at the bottom. 3968 // The point of exit cannot be a branch out of the structured block. 3969 // longjmp() and throw() must not violate the entry/exit criteria. 3970 OpenMPClauseKind AtomicKind = OMPC_unknown; 3971 SourceLocation AtomicKindLoc; 3972 for (auto *C : Clauses) { 3973 if (C->getClauseKind() == OMPC_read || C->getClauseKind() == OMPC_write || 3974 C->getClauseKind() == OMPC_update || 3975 C->getClauseKind() == OMPC_capture) { 3976 if (AtomicKind != OMPC_unknown) { 3977 Diag(C->getLocStart(), diag::err_omp_atomic_several_clauses) 3978 << SourceRange(C->getLocStart(), C->getLocEnd()); 3979 Diag(AtomicKindLoc, diag::note_omp_atomic_previous_clause) 3980 << getOpenMPClauseName(AtomicKind); 3981 } else { 3982 AtomicKind = C->getClauseKind(); 3983 AtomicKindLoc = C->getLocStart(); 3984 } 3985 } 3986 } 3987 3988 auto Body = CS->getCapturedStmt(); 3989 if (auto *EWC = dyn_cast<ExprWithCleanups>(Body)) 3990 Body = EWC->getSubExpr(); 3991 3992 Expr *X = nullptr; 3993 Expr *V = nullptr; 3994 Expr *E = nullptr; 3995 Expr *UE = nullptr; 3996 bool IsXLHSInRHSPart = false; 3997 bool IsPostfixUpdate = false; 3998 // OpenMP [2.12.6, atomic Construct] 3999 // In the next expressions: 4000 // * x and v (as applicable) are both l-value expressions with scalar type. 4001 // * During the execution of an atomic region, multiple syntactic 4002 // occurrences of x must designate the same storage location. 4003 // * Neither of v and expr (as applicable) may access the storage location 4004 // designated by x. 4005 // * Neither of x and expr (as applicable) may access the storage location 4006 // designated by v. 4007 // * expr is an expression with scalar type. 4008 // * binop is one of +, *, -, /, &, ^, |, <<, or >>. 4009 // * binop, binop=, ++, and -- are not overloaded operators. 4010 // * The expression x binop expr must be numerically equivalent to x binop 4011 // (expr). This requirement is satisfied if the operators in expr have 4012 // precedence greater than binop, or by using parentheses around expr or 4013 // subexpressions of expr. 4014 // * The expression expr binop x must be numerically equivalent to (expr) 4015 // binop x. This requirement is satisfied if the operators in expr have 4016 // precedence equal to or greater than binop, or by using parentheses around 4017 // expr or subexpressions of expr. 4018 // * For forms that allow multiple occurrences of x, the number of times 4019 // that x is evaluated is unspecified. 4020 if (AtomicKind == OMPC_read) { 4021 enum { 4022 NotAnExpression, 4023 NotAnAssignmentOp, 4024 NotAScalarType, 4025 NotAnLValue, 4026 NoError 4027 } ErrorFound = NoError; 4028 SourceLocation ErrorLoc, NoteLoc; 4029 SourceRange ErrorRange, NoteRange; 4030 // If clause is read: 4031 // v = x; 4032 if (auto AtomicBody = dyn_cast<Expr>(Body)) { 4033 auto AtomicBinOp = 4034 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 4035 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 4036 X = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 4037 V = AtomicBinOp->getLHS()->IgnoreParenImpCasts(); 4038 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 4039 (V->isInstantiationDependent() || V->getType()->isScalarType())) { 4040 if (!X->isLValue() || !V->isLValue()) { 4041 auto NotLValueExpr = X->isLValue() ? V : X; 4042 ErrorFound = NotAnLValue; 4043 ErrorLoc = AtomicBinOp->getExprLoc(); 4044 ErrorRange = AtomicBinOp->getSourceRange(); 4045 NoteLoc = NotLValueExpr->getExprLoc(); 4046 NoteRange = NotLValueExpr->getSourceRange(); 4047 } 4048 } else if (!X->isInstantiationDependent() || 4049 !V->isInstantiationDependent()) { 4050 auto NotScalarExpr = 4051 (X->isInstantiationDependent() || X->getType()->isScalarType()) 4052 ? V 4053 : X; 4054 ErrorFound = NotAScalarType; 4055 ErrorLoc = AtomicBinOp->getExprLoc(); 4056 ErrorRange = AtomicBinOp->getSourceRange(); 4057 NoteLoc = NotScalarExpr->getExprLoc(); 4058 NoteRange = NotScalarExpr->getSourceRange(); 4059 } 4060 } else { 4061 ErrorFound = NotAnAssignmentOp; 4062 ErrorLoc = AtomicBody->getExprLoc(); 4063 ErrorRange = AtomicBody->getSourceRange(); 4064 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 4065 : AtomicBody->getExprLoc(); 4066 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 4067 : AtomicBody->getSourceRange(); 4068 } 4069 } else { 4070 ErrorFound = NotAnExpression; 4071 NoteLoc = ErrorLoc = Body->getLocStart(); 4072 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 4073 } 4074 if (ErrorFound != NoError) { 4075 Diag(ErrorLoc, diag::err_omp_atomic_read_not_expression_statement) 4076 << ErrorRange; 4077 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 4078 << NoteRange; 4079 return StmtError(); 4080 } else if (CurContext->isDependentContext()) 4081 V = X = nullptr; 4082 } else if (AtomicKind == OMPC_write) { 4083 enum { 4084 NotAnExpression, 4085 NotAnAssignmentOp, 4086 NotAScalarType, 4087 NotAnLValue, 4088 NoError 4089 } ErrorFound = NoError; 4090 SourceLocation ErrorLoc, NoteLoc; 4091 SourceRange ErrorRange, NoteRange; 4092 // If clause is write: 4093 // x = expr; 4094 if (auto AtomicBody = dyn_cast<Expr>(Body)) { 4095 auto AtomicBinOp = 4096 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 4097 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 4098 X = AtomicBinOp->getLHS(); 4099 E = AtomicBinOp->getRHS(); 4100 if ((X->isInstantiationDependent() || X->getType()->isScalarType()) && 4101 (E->isInstantiationDependent() || E->getType()->isScalarType())) { 4102 if (!X->isLValue()) { 4103 ErrorFound = NotAnLValue; 4104 ErrorLoc = AtomicBinOp->getExprLoc(); 4105 ErrorRange = AtomicBinOp->getSourceRange(); 4106 NoteLoc = X->getExprLoc(); 4107 NoteRange = X->getSourceRange(); 4108 } 4109 } else if (!X->isInstantiationDependent() || 4110 !E->isInstantiationDependent()) { 4111 auto NotScalarExpr = 4112 (X->isInstantiationDependent() || X->getType()->isScalarType()) 4113 ? E 4114 : X; 4115 ErrorFound = NotAScalarType; 4116 ErrorLoc = AtomicBinOp->getExprLoc(); 4117 ErrorRange = AtomicBinOp->getSourceRange(); 4118 NoteLoc = NotScalarExpr->getExprLoc(); 4119 NoteRange = NotScalarExpr->getSourceRange(); 4120 } 4121 } else { 4122 ErrorFound = NotAnAssignmentOp; 4123 ErrorLoc = AtomicBody->getExprLoc(); 4124 ErrorRange = AtomicBody->getSourceRange(); 4125 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 4126 : AtomicBody->getExprLoc(); 4127 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 4128 : AtomicBody->getSourceRange(); 4129 } 4130 } else { 4131 ErrorFound = NotAnExpression; 4132 NoteLoc = ErrorLoc = Body->getLocStart(); 4133 NoteRange = ErrorRange = SourceRange(NoteLoc, NoteLoc); 4134 } 4135 if (ErrorFound != NoError) { 4136 Diag(ErrorLoc, diag::err_omp_atomic_write_not_expression_statement) 4137 << ErrorRange; 4138 Diag(NoteLoc, diag::note_omp_atomic_read_write) << ErrorFound 4139 << NoteRange; 4140 return StmtError(); 4141 } else if (CurContext->isDependentContext()) 4142 E = X = nullptr; 4143 } else if (AtomicKind == OMPC_update || AtomicKind == OMPC_unknown) { 4144 // If clause is update: 4145 // x++; 4146 // x--; 4147 // ++x; 4148 // --x; 4149 // x binop= expr; 4150 // x = x binop expr; 4151 // x = expr binop x; 4152 OpenMPAtomicUpdateChecker Checker(*this); 4153 if (Checker.checkStatement( 4154 Body, (AtomicKind == OMPC_update) 4155 ? diag::err_omp_atomic_update_not_expression_statement 4156 : diag::err_omp_atomic_not_expression_statement, 4157 diag::note_omp_atomic_update)) 4158 return StmtError(); 4159 if (!CurContext->isDependentContext()) { 4160 E = Checker.getExpr(); 4161 X = Checker.getX(); 4162 UE = Checker.getUpdateExpr(); 4163 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 4164 } 4165 } else if (AtomicKind == OMPC_capture) { 4166 enum { 4167 NotAnAssignmentOp, 4168 NotACompoundStatement, 4169 NotTwoSubstatements, 4170 NotASpecificExpression, 4171 NoError 4172 } ErrorFound = NoError; 4173 SourceLocation ErrorLoc, NoteLoc; 4174 SourceRange ErrorRange, NoteRange; 4175 if (auto *AtomicBody = dyn_cast<Expr>(Body)) { 4176 // If clause is a capture: 4177 // v = x++; 4178 // v = x--; 4179 // v = ++x; 4180 // v = --x; 4181 // v = x binop= expr; 4182 // v = x = x binop expr; 4183 // v = x = expr binop x; 4184 auto *AtomicBinOp = 4185 dyn_cast<BinaryOperator>(AtomicBody->IgnoreParenImpCasts()); 4186 if (AtomicBinOp && AtomicBinOp->getOpcode() == BO_Assign) { 4187 V = AtomicBinOp->getLHS(); 4188 Body = AtomicBinOp->getRHS()->IgnoreParenImpCasts(); 4189 OpenMPAtomicUpdateChecker Checker(*this); 4190 if (Checker.checkStatement( 4191 Body, diag::err_omp_atomic_capture_not_expression_statement, 4192 diag::note_omp_atomic_update)) 4193 return StmtError(); 4194 E = Checker.getExpr(); 4195 X = Checker.getX(); 4196 UE = Checker.getUpdateExpr(); 4197 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 4198 IsPostfixUpdate = Checker.isPostfixUpdate(); 4199 } else { 4200 ErrorLoc = AtomicBody->getExprLoc(); 4201 ErrorRange = AtomicBody->getSourceRange(); 4202 NoteLoc = AtomicBinOp ? AtomicBinOp->getOperatorLoc() 4203 : AtomicBody->getExprLoc(); 4204 NoteRange = AtomicBinOp ? AtomicBinOp->getSourceRange() 4205 : AtomicBody->getSourceRange(); 4206 ErrorFound = NotAnAssignmentOp; 4207 } 4208 if (ErrorFound != NoError) { 4209 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_expression_statement) 4210 << ErrorRange; 4211 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 4212 return StmtError(); 4213 } else if (CurContext->isDependentContext()) { 4214 UE = V = E = X = nullptr; 4215 } 4216 } else { 4217 // If clause is a capture: 4218 // { v = x; x = expr; } 4219 // { v = x; x++; } 4220 // { v = x; x--; } 4221 // { v = x; ++x; } 4222 // { v = x; --x; } 4223 // { v = x; x binop= expr; } 4224 // { v = x; x = x binop expr; } 4225 // { v = x; x = expr binop x; } 4226 // { x++; v = x; } 4227 // { x--; v = x; } 4228 // { ++x; v = x; } 4229 // { --x; v = x; } 4230 // { x binop= expr; v = x; } 4231 // { x = x binop expr; v = x; } 4232 // { x = expr binop x; v = x; } 4233 if (auto *CS = dyn_cast<CompoundStmt>(Body)) { 4234 // Check that this is { expr1; expr2; } 4235 if (CS->size() == 2) { 4236 auto *First = CS->body_front(); 4237 auto *Second = CS->body_back(); 4238 if (auto *EWC = dyn_cast<ExprWithCleanups>(First)) 4239 First = EWC->getSubExpr()->IgnoreParenImpCasts(); 4240 if (auto *EWC = dyn_cast<ExprWithCleanups>(Second)) 4241 Second = EWC->getSubExpr()->IgnoreParenImpCasts(); 4242 // Need to find what subexpression is 'v' and what is 'x'. 4243 OpenMPAtomicUpdateChecker Checker(*this); 4244 bool IsUpdateExprFound = !Checker.checkStatement(Second); 4245 BinaryOperator *BinOp = nullptr; 4246 if (IsUpdateExprFound) { 4247 BinOp = dyn_cast<BinaryOperator>(First); 4248 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 4249 } 4250 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 4251 // { v = x; x++; } 4252 // { v = x; x--; } 4253 // { v = x; ++x; } 4254 // { v = x; --x; } 4255 // { v = x; x binop= expr; } 4256 // { v = x; x = x binop expr; } 4257 // { v = x; x = expr binop x; } 4258 // Check that the first expression has form v = x. 4259 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 4260 llvm::FoldingSetNodeID XId, PossibleXId; 4261 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 4262 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 4263 IsUpdateExprFound = XId == PossibleXId; 4264 if (IsUpdateExprFound) { 4265 V = BinOp->getLHS(); 4266 X = Checker.getX(); 4267 E = Checker.getExpr(); 4268 UE = Checker.getUpdateExpr(); 4269 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 4270 IsPostfixUpdate = true; 4271 } 4272 } 4273 if (!IsUpdateExprFound) { 4274 IsUpdateExprFound = !Checker.checkStatement(First); 4275 BinOp = nullptr; 4276 if (IsUpdateExprFound) { 4277 BinOp = dyn_cast<BinaryOperator>(Second); 4278 IsUpdateExprFound = BinOp && BinOp->getOpcode() == BO_Assign; 4279 } 4280 if (IsUpdateExprFound && !CurContext->isDependentContext()) { 4281 // { x++; v = x; } 4282 // { x--; v = x; } 4283 // { ++x; v = x; } 4284 // { --x; v = x; } 4285 // { x binop= expr; v = x; } 4286 // { x = x binop expr; v = x; } 4287 // { x = expr binop x; v = x; } 4288 // Check that the second expression has form v = x. 4289 auto *PossibleX = BinOp->getRHS()->IgnoreParenImpCasts(); 4290 llvm::FoldingSetNodeID XId, PossibleXId; 4291 Checker.getX()->Profile(XId, Context, /*Canonical=*/true); 4292 PossibleX->Profile(PossibleXId, Context, /*Canonical=*/true); 4293 IsUpdateExprFound = XId == PossibleXId; 4294 if (IsUpdateExprFound) { 4295 V = BinOp->getLHS(); 4296 X = Checker.getX(); 4297 E = Checker.getExpr(); 4298 UE = Checker.getUpdateExpr(); 4299 IsXLHSInRHSPart = Checker.isXLHSInRHSPart(); 4300 IsPostfixUpdate = false; 4301 } 4302 } 4303 } 4304 if (!IsUpdateExprFound) { 4305 // { v = x; x = expr; } 4306 auto *FirstBinOp = dyn_cast<BinaryOperator>(First); 4307 if (!FirstBinOp || FirstBinOp->getOpcode() != BO_Assign) { 4308 ErrorFound = NotAnAssignmentOp; 4309 NoteLoc = ErrorLoc = FirstBinOp ? FirstBinOp->getOperatorLoc() 4310 : First->getLocStart(); 4311 NoteRange = ErrorRange = FirstBinOp 4312 ? FirstBinOp->getSourceRange() 4313 : SourceRange(ErrorLoc, ErrorLoc); 4314 } else { 4315 auto *SecondBinOp = dyn_cast<BinaryOperator>(Second); 4316 if (!SecondBinOp || SecondBinOp->getOpcode() != BO_Assign) { 4317 ErrorFound = NotAnAssignmentOp; 4318 NoteLoc = ErrorLoc = SecondBinOp ? SecondBinOp->getOperatorLoc() 4319 : Second->getLocStart(); 4320 NoteRange = ErrorRange = SecondBinOp 4321 ? SecondBinOp->getSourceRange() 4322 : SourceRange(ErrorLoc, ErrorLoc); 4323 } else { 4324 auto *PossibleXRHSInFirst = 4325 FirstBinOp->getRHS()->IgnoreParenImpCasts(); 4326 auto *PossibleXLHSInSecond = 4327 SecondBinOp->getLHS()->IgnoreParenImpCasts(); 4328 llvm::FoldingSetNodeID X1Id, X2Id; 4329 PossibleXRHSInFirst->Profile(X1Id, Context, /*Canonical=*/true); 4330 PossibleXLHSInSecond->Profile(X2Id, Context, 4331 /*Canonical=*/true); 4332 IsUpdateExprFound = X1Id == X2Id; 4333 if (IsUpdateExprFound) { 4334 V = FirstBinOp->getLHS(); 4335 X = SecondBinOp->getLHS(); 4336 E = SecondBinOp->getRHS(); 4337 UE = nullptr; 4338 IsXLHSInRHSPart = false; 4339 IsPostfixUpdate = true; 4340 } else { 4341 ErrorFound = NotASpecificExpression; 4342 ErrorLoc = FirstBinOp->getExprLoc(); 4343 ErrorRange = FirstBinOp->getSourceRange(); 4344 NoteLoc = SecondBinOp->getLHS()->getExprLoc(); 4345 NoteRange = SecondBinOp->getRHS()->getSourceRange(); 4346 } 4347 } 4348 } 4349 } 4350 } else { 4351 NoteLoc = ErrorLoc = Body->getLocStart(); 4352 NoteRange = ErrorRange = 4353 SourceRange(Body->getLocStart(), Body->getLocStart()); 4354 ErrorFound = NotTwoSubstatements; 4355 } 4356 } else { 4357 NoteLoc = ErrorLoc = Body->getLocStart(); 4358 NoteRange = ErrorRange = 4359 SourceRange(Body->getLocStart(), Body->getLocStart()); 4360 ErrorFound = NotACompoundStatement; 4361 } 4362 if (ErrorFound != NoError) { 4363 Diag(ErrorLoc, diag::err_omp_atomic_capture_not_compound_statement) 4364 << ErrorRange; 4365 Diag(NoteLoc, diag::note_omp_atomic_capture) << ErrorFound << NoteRange; 4366 return StmtError(); 4367 } else if (CurContext->isDependentContext()) { 4368 UE = V = E = X = nullptr; 4369 } 4370 } 4371 } 4372 4373 getCurFunction()->setHasBranchProtectedScope(); 4374 4375 return OMPAtomicDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt, 4376 X, V, E, UE, IsXLHSInRHSPart, 4377 IsPostfixUpdate); 4378 } 4379 4380 StmtResult Sema::ActOnOpenMPTargetDirective(ArrayRef<OMPClause *> Clauses, 4381 Stmt *AStmt, 4382 SourceLocation StartLoc, 4383 SourceLocation EndLoc) { 4384 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4385 4386 // OpenMP [2.16, Nesting of Regions] 4387 // If specified, a teams construct must be contained within a target 4388 // construct. That target construct must contain no statements or directives 4389 // outside of the teams construct. 4390 if (DSAStack->hasInnerTeamsRegion()) { 4391 auto S = AStmt->IgnoreContainers(/*IgnoreCaptured*/ true); 4392 bool OMPTeamsFound = true; 4393 if (auto *CS = dyn_cast<CompoundStmt>(S)) { 4394 auto I = CS->body_begin(); 4395 while (I != CS->body_end()) { 4396 auto OED = dyn_cast<OMPExecutableDirective>(*I); 4397 if (!OED || !isOpenMPTeamsDirective(OED->getDirectiveKind())) { 4398 OMPTeamsFound = false; 4399 break; 4400 } 4401 ++I; 4402 } 4403 assert(I != CS->body_end() && "Not found statement"); 4404 S = *I; 4405 } 4406 if (!OMPTeamsFound) { 4407 Diag(StartLoc, diag::err_omp_target_contains_not_only_teams); 4408 Diag(DSAStack->getInnerTeamsRegionLoc(), 4409 diag::note_omp_nested_teams_construct_here); 4410 Diag(S->getLocStart(), diag::note_omp_nested_statement_here) 4411 << isa<OMPExecutableDirective>(S); 4412 return StmtError(); 4413 } 4414 } 4415 4416 getCurFunction()->setHasBranchProtectedScope(); 4417 4418 return OMPTargetDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 4419 } 4420 4421 StmtResult Sema::ActOnOpenMPTargetDataDirective(ArrayRef<OMPClause *> Clauses, 4422 Stmt *AStmt, 4423 SourceLocation StartLoc, 4424 SourceLocation EndLoc) { 4425 getCurFunction()->setHasBranchProtectedScope(); 4426 4427 return OMPTargetDataDirective::Create(Context, StartLoc, EndLoc, Clauses, 4428 AStmt); 4429 } 4430 4431 StmtResult Sema::ActOnOpenMPTeamsDirective(ArrayRef<OMPClause *> Clauses, 4432 Stmt *AStmt, SourceLocation StartLoc, 4433 SourceLocation EndLoc) { 4434 assert(AStmt && isa<CapturedStmt>(AStmt) && "Captured statement expected"); 4435 CapturedStmt *CS = cast<CapturedStmt>(AStmt); 4436 // 1.2.2 OpenMP Language Terminology 4437 // Structured block - An executable statement with a single entry at the 4438 // top and a single exit at the bottom. 4439 // The point of exit cannot be a branch out of the structured block. 4440 // longjmp() and throw() must not violate the entry/exit criteria. 4441 CS->getCapturedDecl()->setNothrow(); 4442 4443 getCurFunction()->setHasBranchProtectedScope(); 4444 4445 return OMPTeamsDirective::Create(Context, StartLoc, EndLoc, Clauses, AStmt); 4446 } 4447 4448 StmtResult 4449 Sema::ActOnOpenMPCancellationPointDirective(SourceLocation StartLoc, 4450 SourceLocation EndLoc, 4451 OpenMPDirectiveKind CancelRegion) { 4452 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for && 4453 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) { 4454 Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4455 << getOpenMPDirectiveName(CancelRegion); 4456 return StmtError(); 4457 } 4458 if (DSAStack->isParentNowaitRegion()) { 4459 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 0; 4460 return StmtError(); 4461 } 4462 if (DSAStack->isParentOrderedRegion()) { 4463 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 0; 4464 return StmtError(); 4465 } 4466 return OMPCancellationPointDirective::Create(Context, StartLoc, EndLoc, 4467 CancelRegion); 4468 } 4469 4470 StmtResult Sema::ActOnOpenMPCancelDirective(SourceLocation StartLoc, 4471 SourceLocation EndLoc, 4472 OpenMPDirectiveKind CancelRegion) { 4473 if (CancelRegion != OMPD_parallel && CancelRegion != OMPD_for && 4474 CancelRegion != OMPD_sections && CancelRegion != OMPD_taskgroup) { 4475 Diag(StartLoc, diag::err_omp_wrong_cancel_region) 4476 << getOpenMPDirectiveName(CancelRegion); 4477 return StmtError(); 4478 } 4479 if (DSAStack->isParentNowaitRegion()) { 4480 Diag(StartLoc, diag::err_omp_parent_cancel_region_nowait) << 1; 4481 return StmtError(); 4482 } 4483 if (DSAStack->isParentOrderedRegion()) { 4484 Diag(StartLoc, diag::err_omp_parent_cancel_region_ordered) << 1; 4485 return StmtError(); 4486 } 4487 return OMPCancelDirective::Create(Context, StartLoc, EndLoc, CancelRegion); 4488 } 4489 4490 OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr, 4491 SourceLocation StartLoc, 4492 SourceLocation LParenLoc, 4493 SourceLocation EndLoc) { 4494 OMPClause *Res = nullptr; 4495 switch (Kind) { 4496 case OMPC_if: 4497 Res = ActOnOpenMPIfClause(Expr, StartLoc, LParenLoc, EndLoc); 4498 break; 4499 case OMPC_final: 4500 Res = ActOnOpenMPFinalClause(Expr, StartLoc, LParenLoc, EndLoc); 4501 break; 4502 case OMPC_num_threads: 4503 Res = ActOnOpenMPNumThreadsClause(Expr, StartLoc, LParenLoc, EndLoc); 4504 break; 4505 case OMPC_safelen: 4506 Res = ActOnOpenMPSafelenClause(Expr, StartLoc, LParenLoc, EndLoc); 4507 break; 4508 case OMPC_collapse: 4509 Res = ActOnOpenMPCollapseClause(Expr, StartLoc, LParenLoc, EndLoc); 4510 break; 4511 case OMPC_ordered: 4512 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc, LParenLoc, Expr); 4513 break; 4514 case OMPC_device: 4515 Res = ActOnOpenMPDeviceClause(Expr, StartLoc, LParenLoc, EndLoc); 4516 break; 4517 case OMPC_default: 4518 case OMPC_proc_bind: 4519 case OMPC_schedule: 4520 case OMPC_private: 4521 case OMPC_firstprivate: 4522 case OMPC_lastprivate: 4523 case OMPC_shared: 4524 case OMPC_reduction: 4525 case OMPC_linear: 4526 case OMPC_aligned: 4527 case OMPC_copyin: 4528 case OMPC_copyprivate: 4529 case OMPC_nowait: 4530 case OMPC_untied: 4531 case OMPC_mergeable: 4532 case OMPC_threadprivate: 4533 case OMPC_flush: 4534 case OMPC_read: 4535 case OMPC_write: 4536 case OMPC_update: 4537 case OMPC_capture: 4538 case OMPC_seq_cst: 4539 case OMPC_depend: 4540 case OMPC_unknown: 4541 llvm_unreachable("Clause is not allowed."); 4542 } 4543 return Res; 4544 } 4545 4546 OMPClause *Sema::ActOnOpenMPIfClause(Expr *Condition, SourceLocation StartLoc, 4547 SourceLocation LParenLoc, 4548 SourceLocation EndLoc) { 4549 Expr *ValExpr = Condition; 4550 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 4551 !Condition->isInstantiationDependent() && 4552 !Condition->containsUnexpandedParameterPack()) { 4553 ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(), 4554 Condition->getExprLoc(), Condition); 4555 if (Val.isInvalid()) 4556 return nullptr; 4557 4558 ValExpr = Val.get(); 4559 } 4560 4561 return new (Context) OMPIfClause(ValExpr, StartLoc, LParenLoc, EndLoc); 4562 } 4563 4564 OMPClause *Sema::ActOnOpenMPFinalClause(Expr *Condition, 4565 SourceLocation StartLoc, 4566 SourceLocation LParenLoc, 4567 SourceLocation EndLoc) { 4568 Expr *ValExpr = Condition; 4569 if (!Condition->isValueDependent() && !Condition->isTypeDependent() && 4570 !Condition->isInstantiationDependent() && 4571 !Condition->containsUnexpandedParameterPack()) { 4572 ExprResult Val = ActOnBooleanCondition(DSAStack->getCurScope(), 4573 Condition->getExprLoc(), Condition); 4574 if (Val.isInvalid()) 4575 return nullptr; 4576 4577 ValExpr = Val.get(); 4578 } 4579 4580 return new (Context) OMPFinalClause(ValExpr, StartLoc, LParenLoc, EndLoc); 4581 } 4582 ExprResult Sema::PerformOpenMPImplicitIntegerConversion(SourceLocation Loc, 4583 Expr *Op) { 4584 if (!Op) 4585 return ExprError(); 4586 4587 class IntConvertDiagnoser : public ICEConvertDiagnoser { 4588 public: 4589 IntConvertDiagnoser() 4590 : ICEConvertDiagnoser(/*AllowScopedEnumerations*/ false, false, true) {} 4591 SemaDiagnosticBuilder diagnoseNotInt(Sema &S, SourceLocation Loc, 4592 QualType T) override { 4593 return S.Diag(Loc, diag::err_omp_not_integral) << T; 4594 } 4595 SemaDiagnosticBuilder diagnoseIncomplete(Sema &S, SourceLocation Loc, 4596 QualType T) override { 4597 return S.Diag(Loc, diag::err_omp_incomplete_type) << T; 4598 } 4599 SemaDiagnosticBuilder diagnoseExplicitConv(Sema &S, SourceLocation Loc, 4600 QualType T, 4601 QualType ConvTy) override { 4602 return S.Diag(Loc, diag::err_omp_explicit_conversion) << T << ConvTy; 4603 } 4604 SemaDiagnosticBuilder noteExplicitConv(Sema &S, CXXConversionDecl *Conv, 4605 QualType ConvTy) override { 4606 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 4607 << ConvTy->isEnumeralType() << ConvTy; 4608 } 4609 SemaDiagnosticBuilder diagnoseAmbiguous(Sema &S, SourceLocation Loc, 4610 QualType T) override { 4611 return S.Diag(Loc, diag::err_omp_ambiguous_conversion) << T; 4612 } 4613 SemaDiagnosticBuilder noteAmbiguous(Sema &S, CXXConversionDecl *Conv, 4614 QualType ConvTy) override { 4615 return S.Diag(Conv->getLocation(), diag::note_omp_conversion_here) 4616 << ConvTy->isEnumeralType() << ConvTy; 4617 } 4618 SemaDiagnosticBuilder diagnoseConversion(Sema &, SourceLocation, QualType, 4619 QualType) override { 4620 llvm_unreachable("conversion functions are permitted"); 4621 } 4622 } ConvertDiagnoser; 4623 return PerformContextualImplicitConversion(Loc, Op, ConvertDiagnoser); 4624 } 4625 4626 OMPClause *Sema::ActOnOpenMPNumThreadsClause(Expr *NumThreads, 4627 SourceLocation StartLoc, 4628 SourceLocation LParenLoc, 4629 SourceLocation EndLoc) { 4630 Expr *ValExpr = NumThreads; 4631 if (!NumThreads->isValueDependent() && !NumThreads->isTypeDependent() && 4632 !NumThreads->containsUnexpandedParameterPack()) { 4633 SourceLocation NumThreadsLoc = NumThreads->getLocStart(); 4634 ExprResult Val = 4635 PerformOpenMPImplicitIntegerConversion(NumThreadsLoc, NumThreads); 4636 if (Val.isInvalid()) 4637 return nullptr; 4638 4639 ValExpr = Val.get(); 4640 4641 // OpenMP [2.5, Restrictions] 4642 // The num_threads expression must evaluate to a positive integer value. 4643 llvm::APSInt Result; 4644 if (ValExpr->isIntegerConstantExpr(Result, Context) && Result.isSigned() && 4645 !Result.isStrictlyPositive()) { 4646 Diag(NumThreadsLoc, diag::err_omp_negative_expression_in_clause) 4647 << "num_threads" << NumThreads->getSourceRange(); 4648 return nullptr; 4649 } 4650 } 4651 4652 return new (Context) 4653 OMPNumThreadsClause(ValExpr, StartLoc, LParenLoc, EndLoc); 4654 } 4655 4656 ExprResult Sema::VerifyPositiveIntegerConstantInClause(Expr *E, 4657 OpenMPClauseKind CKind) { 4658 if (!E) 4659 return ExprError(); 4660 if (E->isValueDependent() || E->isTypeDependent() || 4661 E->isInstantiationDependent() || E->containsUnexpandedParameterPack()) 4662 return E; 4663 llvm::APSInt Result; 4664 ExprResult ICE = VerifyIntegerConstantExpression(E, &Result); 4665 if (ICE.isInvalid()) 4666 return ExprError(); 4667 if (!Result.isStrictlyPositive()) { 4668 Diag(E->getExprLoc(), diag::err_omp_negative_expression_in_clause) 4669 << getOpenMPClauseName(CKind) << E->getSourceRange(); 4670 return ExprError(); 4671 } 4672 if (CKind == OMPC_aligned && !Result.isPowerOf2()) { 4673 Diag(E->getExprLoc(), diag::warn_omp_alignment_not_power_of_two) 4674 << E->getSourceRange(); 4675 return ExprError(); 4676 } 4677 if (CKind == OMPC_collapse) { 4678 DSAStack->setCollapseNumber(DSAStack->getCollapseNumber() - 1 + 4679 Result.getExtValue()); 4680 } else if (CKind == OMPC_ordered) { 4681 DSAStack->setCollapseNumber(DSAStack->getCollapseNumber() - 1 + 4682 Result.getExtValue()); 4683 } 4684 return ICE; 4685 } 4686 4687 OMPClause *Sema::ActOnOpenMPSafelenClause(Expr *Len, SourceLocation StartLoc, 4688 SourceLocation LParenLoc, 4689 SourceLocation EndLoc) { 4690 // OpenMP [2.8.1, simd construct, Description] 4691 // The parameter of the safelen clause must be a constant 4692 // positive integer expression. 4693 ExprResult Safelen = VerifyPositiveIntegerConstantInClause(Len, OMPC_safelen); 4694 if (Safelen.isInvalid()) 4695 return nullptr; 4696 return new (Context) 4697 OMPSafelenClause(Safelen.get(), StartLoc, LParenLoc, EndLoc); 4698 } 4699 4700 OMPClause *Sema::ActOnOpenMPCollapseClause(Expr *NumForLoops, 4701 SourceLocation StartLoc, 4702 SourceLocation LParenLoc, 4703 SourceLocation EndLoc) { 4704 // OpenMP [2.7.1, loop construct, Description] 4705 // OpenMP [2.8.1, simd construct, Description] 4706 // OpenMP [2.9.6, distribute construct, Description] 4707 // The parameter of the collapse clause must be a constant 4708 // positive integer expression. 4709 ExprResult NumForLoopsResult = 4710 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_collapse); 4711 if (NumForLoopsResult.isInvalid()) 4712 return nullptr; 4713 return new (Context) 4714 OMPCollapseClause(NumForLoopsResult.get(), StartLoc, LParenLoc, EndLoc); 4715 } 4716 4717 OMPClause *Sema::ActOnOpenMPOrderedClause(SourceLocation StartLoc, 4718 SourceLocation EndLoc, 4719 SourceLocation LParenLoc, 4720 Expr *NumForLoops) { 4721 DSAStack->setOrderedRegion(); 4722 // OpenMP [2.7.1, loop construct, Description] 4723 // OpenMP [2.8.1, simd construct, Description] 4724 // OpenMP [2.9.6, distribute construct, Description] 4725 // The parameter of the ordered clause must be a constant 4726 // positive integer expression if any. 4727 if (NumForLoops && LParenLoc.isValid()) { 4728 ExprResult NumForLoopsResult = 4729 VerifyPositiveIntegerConstantInClause(NumForLoops, OMPC_ordered); 4730 if (NumForLoopsResult.isInvalid()) 4731 return nullptr; 4732 NumForLoops = NumForLoopsResult.get(); 4733 } 4734 return new (Context) 4735 OMPOrderedClause(NumForLoops, StartLoc, LParenLoc, EndLoc); 4736 } 4737 4738 OMPClause *Sema::ActOnOpenMPSimpleClause( 4739 OpenMPClauseKind Kind, unsigned Argument, SourceLocation ArgumentLoc, 4740 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation EndLoc) { 4741 OMPClause *Res = nullptr; 4742 switch (Kind) { 4743 case OMPC_default: 4744 Res = 4745 ActOnOpenMPDefaultClause(static_cast<OpenMPDefaultClauseKind>(Argument), 4746 ArgumentLoc, StartLoc, LParenLoc, EndLoc); 4747 break; 4748 case OMPC_proc_bind: 4749 Res = ActOnOpenMPProcBindClause( 4750 static_cast<OpenMPProcBindClauseKind>(Argument), ArgumentLoc, StartLoc, 4751 LParenLoc, EndLoc); 4752 break; 4753 case OMPC_if: 4754 case OMPC_final: 4755 case OMPC_num_threads: 4756 case OMPC_safelen: 4757 case OMPC_collapse: 4758 case OMPC_schedule: 4759 case OMPC_private: 4760 case OMPC_firstprivate: 4761 case OMPC_lastprivate: 4762 case OMPC_shared: 4763 case OMPC_reduction: 4764 case OMPC_linear: 4765 case OMPC_aligned: 4766 case OMPC_copyin: 4767 case OMPC_copyprivate: 4768 case OMPC_ordered: 4769 case OMPC_nowait: 4770 case OMPC_untied: 4771 case OMPC_mergeable: 4772 case OMPC_threadprivate: 4773 case OMPC_flush: 4774 case OMPC_read: 4775 case OMPC_write: 4776 case OMPC_update: 4777 case OMPC_capture: 4778 case OMPC_seq_cst: 4779 case OMPC_depend: 4780 case OMPC_device: 4781 case OMPC_unknown: 4782 llvm_unreachable("Clause is not allowed."); 4783 } 4784 return Res; 4785 } 4786 4787 OMPClause *Sema::ActOnOpenMPDefaultClause(OpenMPDefaultClauseKind Kind, 4788 SourceLocation KindKwLoc, 4789 SourceLocation StartLoc, 4790 SourceLocation LParenLoc, 4791 SourceLocation EndLoc) { 4792 if (Kind == OMPC_DEFAULT_unknown) { 4793 std::string Values; 4794 static_assert(OMPC_DEFAULT_unknown > 0, 4795 "OMPC_DEFAULT_unknown not greater than 0"); 4796 std::string Sep(", "); 4797 for (unsigned i = 0; i < OMPC_DEFAULT_unknown; ++i) { 4798 Values += "'"; 4799 Values += getOpenMPSimpleClauseTypeName(OMPC_default, i); 4800 Values += "'"; 4801 switch (i) { 4802 case OMPC_DEFAULT_unknown - 2: 4803 Values += " or "; 4804 break; 4805 case OMPC_DEFAULT_unknown - 1: 4806 break; 4807 default: 4808 Values += Sep; 4809 break; 4810 } 4811 } 4812 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 4813 << Values << getOpenMPClauseName(OMPC_default); 4814 return nullptr; 4815 } 4816 switch (Kind) { 4817 case OMPC_DEFAULT_none: 4818 DSAStack->setDefaultDSANone(KindKwLoc); 4819 break; 4820 case OMPC_DEFAULT_shared: 4821 DSAStack->setDefaultDSAShared(KindKwLoc); 4822 break; 4823 case OMPC_DEFAULT_unknown: 4824 llvm_unreachable("Clause kind is not allowed."); 4825 break; 4826 } 4827 return new (Context) 4828 OMPDefaultClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 4829 } 4830 4831 OMPClause *Sema::ActOnOpenMPProcBindClause(OpenMPProcBindClauseKind Kind, 4832 SourceLocation KindKwLoc, 4833 SourceLocation StartLoc, 4834 SourceLocation LParenLoc, 4835 SourceLocation EndLoc) { 4836 if (Kind == OMPC_PROC_BIND_unknown) { 4837 std::string Values; 4838 std::string Sep(", "); 4839 for (unsigned i = 0; i < OMPC_PROC_BIND_unknown; ++i) { 4840 Values += "'"; 4841 Values += getOpenMPSimpleClauseTypeName(OMPC_proc_bind, i); 4842 Values += "'"; 4843 switch (i) { 4844 case OMPC_PROC_BIND_unknown - 2: 4845 Values += " or "; 4846 break; 4847 case OMPC_PROC_BIND_unknown - 1: 4848 break; 4849 default: 4850 Values += Sep; 4851 break; 4852 } 4853 } 4854 Diag(KindKwLoc, diag::err_omp_unexpected_clause_value) 4855 << Values << getOpenMPClauseName(OMPC_proc_bind); 4856 return nullptr; 4857 } 4858 return new (Context) 4859 OMPProcBindClause(Kind, KindKwLoc, StartLoc, LParenLoc, EndLoc); 4860 } 4861 4862 OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause( 4863 OpenMPClauseKind Kind, unsigned Argument, Expr *Expr, 4864 SourceLocation StartLoc, SourceLocation LParenLoc, 4865 SourceLocation ArgumentLoc, SourceLocation CommaLoc, 4866 SourceLocation EndLoc) { 4867 OMPClause *Res = nullptr; 4868 switch (Kind) { 4869 case OMPC_schedule: 4870 Res = ActOnOpenMPScheduleClause( 4871 static_cast<OpenMPScheduleClauseKind>(Argument), Expr, StartLoc, 4872 LParenLoc, ArgumentLoc, CommaLoc, EndLoc); 4873 break; 4874 case OMPC_if: 4875 case OMPC_final: 4876 case OMPC_num_threads: 4877 case OMPC_safelen: 4878 case OMPC_collapse: 4879 case OMPC_default: 4880 case OMPC_proc_bind: 4881 case OMPC_private: 4882 case OMPC_firstprivate: 4883 case OMPC_lastprivate: 4884 case OMPC_shared: 4885 case OMPC_reduction: 4886 case OMPC_linear: 4887 case OMPC_aligned: 4888 case OMPC_copyin: 4889 case OMPC_copyprivate: 4890 case OMPC_ordered: 4891 case OMPC_nowait: 4892 case OMPC_untied: 4893 case OMPC_mergeable: 4894 case OMPC_threadprivate: 4895 case OMPC_flush: 4896 case OMPC_read: 4897 case OMPC_write: 4898 case OMPC_update: 4899 case OMPC_capture: 4900 case OMPC_seq_cst: 4901 case OMPC_depend: 4902 case OMPC_device: 4903 case OMPC_unknown: 4904 llvm_unreachable("Clause is not allowed."); 4905 } 4906 return Res; 4907 } 4908 4909 OMPClause *Sema::ActOnOpenMPScheduleClause( 4910 OpenMPScheduleClauseKind Kind, Expr *ChunkSize, SourceLocation StartLoc, 4911 SourceLocation LParenLoc, SourceLocation KindLoc, SourceLocation CommaLoc, 4912 SourceLocation EndLoc) { 4913 if (Kind == OMPC_SCHEDULE_unknown) { 4914 std::string Values; 4915 std::string Sep(", "); 4916 for (unsigned i = 0; i < OMPC_SCHEDULE_unknown; ++i) { 4917 Values += "'"; 4918 Values += getOpenMPSimpleClauseTypeName(OMPC_schedule, i); 4919 Values += "'"; 4920 switch (i) { 4921 case OMPC_SCHEDULE_unknown - 2: 4922 Values += " or "; 4923 break; 4924 case OMPC_SCHEDULE_unknown - 1: 4925 break; 4926 default: 4927 Values += Sep; 4928 break; 4929 } 4930 } 4931 Diag(KindLoc, diag::err_omp_unexpected_clause_value) 4932 << Values << getOpenMPClauseName(OMPC_schedule); 4933 return nullptr; 4934 } 4935 Expr *ValExpr = ChunkSize; 4936 Expr *HelperValExpr = nullptr; 4937 if (ChunkSize) { 4938 if (!ChunkSize->isValueDependent() && !ChunkSize->isTypeDependent() && 4939 !ChunkSize->isInstantiationDependent() && 4940 !ChunkSize->containsUnexpandedParameterPack()) { 4941 SourceLocation ChunkSizeLoc = ChunkSize->getLocStart(); 4942 ExprResult Val = 4943 PerformOpenMPImplicitIntegerConversion(ChunkSizeLoc, ChunkSize); 4944 if (Val.isInvalid()) 4945 return nullptr; 4946 4947 ValExpr = Val.get(); 4948 4949 // OpenMP [2.7.1, Restrictions] 4950 // chunk_size must be a loop invariant integer expression with a positive 4951 // value. 4952 llvm::APSInt Result; 4953 if (ValExpr->isIntegerConstantExpr(Result, Context)) { 4954 if (Result.isSigned() && !Result.isStrictlyPositive()) { 4955 Diag(ChunkSizeLoc, diag::err_omp_negative_expression_in_clause) 4956 << "schedule" << ChunkSize->getSourceRange(); 4957 return nullptr; 4958 } 4959 } else if (isParallelOrTaskRegion(DSAStack->getCurrentDirective())) { 4960 auto *ImpVar = buildVarDecl(*this, ChunkSize->getExprLoc(), 4961 ChunkSize->getType(), ".chunk."); 4962 auto *ImpVarRef = buildDeclRefExpr(*this, ImpVar, ChunkSize->getType(), 4963 ChunkSize->getExprLoc(), 4964 /*RefersToCapture=*/true); 4965 HelperValExpr = ImpVarRef; 4966 } 4967 } 4968 } 4969 4970 return new (Context) OMPScheduleClause(StartLoc, LParenLoc, KindLoc, CommaLoc, 4971 EndLoc, Kind, ValExpr, HelperValExpr); 4972 } 4973 4974 OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind, 4975 SourceLocation StartLoc, 4976 SourceLocation EndLoc) { 4977 OMPClause *Res = nullptr; 4978 switch (Kind) { 4979 case OMPC_ordered: 4980 Res = ActOnOpenMPOrderedClause(StartLoc, EndLoc); 4981 break; 4982 case OMPC_nowait: 4983 Res = ActOnOpenMPNowaitClause(StartLoc, EndLoc); 4984 break; 4985 case OMPC_untied: 4986 Res = ActOnOpenMPUntiedClause(StartLoc, EndLoc); 4987 break; 4988 case OMPC_mergeable: 4989 Res = ActOnOpenMPMergeableClause(StartLoc, EndLoc); 4990 break; 4991 case OMPC_read: 4992 Res = ActOnOpenMPReadClause(StartLoc, EndLoc); 4993 break; 4994 case OMPC_write: 4995 Res = ActOnOpenMPWriteClause(StartLoc, EndLoc); 4996 break; 4997 case OMPC_update: 4998 Res = ActOnOpenMPUpdateClause(StartLoc, EndLoc); 4999 break; 5000 case OMPC_capture: 5001 Res = ActOnOpenMPCaptureClause(StartLoc, EndLoc); 5002 break; 5003 case OMPC_seq_cst: 5004 Res = ActOnOpenMPSeqCstClause(StartLoc, EndLoc); 5005 break; 5006 case OMPC_if: 5007 case OMPC_final: 5008 case OMPC_num_threads: 5009 case OMPC_safelen: 5010 case OMPC_collapse: 5011 case OMPC_schedule: 5012 case OMPC_private: 5013 case OMPC_firstprivate: 5014 case OMPC_lastprivate: 5015 case OMPC_shared: 5016 case OMPC_reduction: 5017 case OMPC_linear: 5018 case OMPC_aligned: 5019 case OMPC_copyin: 5020 case OMPC_copyprivate: 5021 case OMPC_default: 5022 case OMPC_proc_bind: 5023 case OMPC_threadprivate: 5024 case OMPC_flush: 5025 case OMPC_depend: 5026 case OMPC_device: 5027 case OMPC_unknown: 5028 llvm_unreachable("Clause is not allowed."); 5029 } 5030 return Res; 5031 } 5032 5033 OMPClause *Sema::ActOnOpenMPNowaitClause(SourceLocation StartLoc, 5034 SourceLocation EndLoc) { 5035 DSAStack->setNowaitRegion(); 5036 return new (Context) OMPNowaitClause(StartLoc, EndLoc); 5037 } 5038 5039 OMPClause *Sema::ActOnOpenMPUntiedClause(SourceLocation StartLoc, 5040 SourceLocation EndLoc) { 5041 return new (Context) OMPUntiedClause(StartLoc, EndLoc); 5042 } 5043 5044 OMPClause *Sema::ActOnOpenMPMergeableClause(SourceLocation StartLoc, 5045 SourceLocation EndLoc) { 5046 return new (Context) OMPMergeableClause(StartLoc, EndLoc); 5047 } 5048 5049 OMPClause *Sema::ActOnOpenMPReadClause(SourceLocation StartLoc, 5050 SourceLocation EndLoc) { 5051 return new (Context) OMPReadClause(StartLoc, EndLoc); 5052 } 5053 5054 OMPClause *Sema::ActOnOpenMPWriteClause(SourceLocation StartLoc, 5055 SourceLocation EndLoc) { 5056 return new (Context) OMPWriteClause(StartLoc, EndLoc); 5057 } 5058 5059 OMPClause *Sema::ActOnOpenMPUpdateClause(SourceLocation StartLoc, 5060 SourceLocation EndLoc) { 5061 return new (Context) OMPUpdateClause(StartLoc, EndLoc); 5062 } 5063 5064 OMPClause *Sema::ActOnOpenMPCaptureClause(SourceLocation StartLoc, 5065 SourceLocation EndLoc) { 5066 return new (Context) OMPCaptureClause(StartLoc, EndLoc); 5067 } 5068 5069 OMPClause *Sema::ActOnOpenMPSeqCstClause(SourceLocation StartLoc, 5070 SourceLocation EndLoc) { 5071 return new (Context) OMPSeqCstClause(StartLoc, EndLoc); 5072 } 5073 5074 OMPClause *Sema::ActOnOpenMPVarListClause( 5075 OpenMPClauseKind Kind, ArrayRef<Expr *> VarList, Expr *TailExpr, 5076 SourceLocation StartLoc, SourceLocation LParenLoc, SourceLocation ColonLoc, 5077 SourceLocation EndLoc, CXXScopeSpec &ReductionIdScopeSpec, 5078 const DeclarationNameInfo &ReductionId, OpenMPDependClauseKind DepKind, 5079 SourceLocation DepLoc) { 5080 OMPClause *Res = nullptr; 5081 switch (Kind) { 5082 case OMPC_private: 5083 Res = ActOnOpenMPPrivateClause(VarList, StartLoc, LParenLoc, EndLoc); 5084 break; 5085 case OMPC_firstprivate: 5086 Res = ActOnOpenMPFirstprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 5087 break; 5088 case OMPC_lastprivate: 5089 Res = ActOnOpenMPLastprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 5090 break; 5091 case OMPC_shared: 5092 Res = ActOnOpenMPSharedClause(VarList, StartLoc, LParenLoc, EndLoc); 5093 break; 5094 case OMPC_reduction: 5095 Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc, 5096 EndLoc, ReductionIdScopeSpec, ReductionId); 5097 break; 5098 case OMPC_linear: 5099 Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc, 5100 ColonLoc, EndLoc); 5101 break; 5102 case OMPC_aligned: 5103 Res = ActOnOpenMPAlignedClause(VarList, TailExpr, StartLoc, LParenLoc, 5104 ColonLoc, EndLoc); 5105 break; 5106 case OMPC_copyin: 5107 Res = ActOnOpenMPCopyinClause(VarList, StartLoc, LParenLoc, EndLoc); 5108 break; 5109 case OMPC_copyprivate: 5110 Res = ActOnOpenMPCopyprivateClause(VarList, StartLoc, LParenLoc, EndLoc); 5111 break; 5112 case OMPC_flush: 5113 Res = ActOnOpenMPFlushClause(VarList, StartLoc, LParenLoc, EndLoc); 5114 break; 5115 case OMPC_depend: 5116 Res = ActOnOpenMPDependClause(DepKind, DepLoc, ColonLoc, VarList, StartLoc, 5117 LParenLoc, EndLoc); 5118 break; 5119 case OMPC_if: 5120 case OMPC_final: 5121 case OMPC_num_threads: 5122 case OMPC_safelen: 5123 case OMPC_collapse: 5124 case OMPC_default: 5125 case OMPC_proc_bind: 5126 case OMPC_schedule: 5127 case OMPC_ordered: 5128 case OMPC_nowait: 5129 case OMPC_untied: 5130 case OMPC_mergeable: 5131 case OMPC_threadprivate: 5132 case OMPC_read: 5133 case OMPC_write: 5134 case OMPC_update: 5135 case OMPC_capture: 5136 case OMPC_seq_cst: 5137 case OMPC_device: 5138 case OMPC_unknown: 5139 llvm_unreachable("Clause is not allowed."); 5140 } 5141 return Res; 5142 } 5143 5144 OMPClause *Sema::ActOnOpenMPPrivateClause(ArrayRef<Expr *> VarList, 5145 SourceLocation StartLoc, 5146 SourceLocation LParenLoc, 5147 SourceLocation EndLoc) { 5148 SmallVector<Expr *, 8> Vars; 5149 SmallVector<Expr *, 8> PrivateCopies; 5150 for (auto &RefExpr : VarList) { 5151 assert(RefExpr && "NULL expr in OpenMP private clause."); 5152 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 5153 // It will be analyzed later. 5154 Vars.push_back(RefExpr); 5155 PrivateCopies.push_back(nullptr); 5156 continue; 5157 } 5158 5159 SourceLocation ELoc = RefExpr->getExprLoc(); 5160 // OpenMP [2.1, C/C++] 5161 // A list item is a variable name. 5162 // OpenMP [2.9.3.3, Restrictions, p.1] 5163 // A variable that is part of another variable (as an array or 5164 // structure element) cannot appear in a private clause. 5165 DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 5166 if (!DE || !isa<VarDecl>(DE->getDecl())) { 5167 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 5168 continue; 5169 } 5170 Decl *D = DE->getDecl(); 5171 VarDecl *VD = cast<VarDecl>(D); 5172 5173 QualType Type = VD->getType(); 5174 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 5175 // It will be analyzed later. 5176 Vars.push_back(DE); 5177 PrivateCopies.push_back(nullptr); 5178 continue; 5179 } 5180 5181 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 5182 // A variable that appears in a private clause must not have an incomplete 5183 // type or a reference type. 5184 if (RequireCompleteType(ELoc, Type, 5185 diag::err_omp_private_incomplete_type)) { 5186 continue; 5187 } 5188 if (Type->isReferenceType()) { 5189 Diag(ELoc, diag::err_omp_clause_ref_type_arg) 5190 << getOpenMPClauseName(OMPC_private) << Type; 5191 bool IsDecl = 5192 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5193 Diag(VD->getLocation(), 5194 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5195 << VD; 5196 continue; 5197 } 5198 5199 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 5200 // in a Construct] 5201 // Variables with the predetermined data-sharing attributes may not be 5202 // listed in data-sharing attributes clauses, except for the cases 5203 // listed below. For these exceptions only, listing a predetermined 5204 // variable in a data-sharing attribute clause is allowed and overrides 5205 // the variable's predetermined data-sharing attributes. 5206 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 5207 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_private) { 5208 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 5209 << getOpenMPClauseName(OMPC_private); 5210 ReportOriginalDSA(*this, DSAStack, VD, DVar); 5211 continue; 5212 } 5213 5214 // Variably modified types are not supported for tasks. 5215 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 5216 DSAStack->getCurrentDirective() == OMPD_task) { 5217 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 5218 << getOpenMPClauseName(OMPC_private) << Type 5219 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 5220 bool IsDecl = 5221 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5222 Diag(VD->getLocation(), 5223 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5224 << VD; 5225 continue; 5226 } 5227 5228 // OpenMP [2.9.3.3, Restrictions, C/C++, p.1] 5229 // A variable of class type (or array thereof) that appears in a private 5230 // clause requires an accessible, unambiguous default constructor for the 5231 // class type. 5232 // Generate helper private variable and initialize it with the default 5233 // value. The address of the original variable is replaced by the address of 5234 // the new private variable in CodeGen. This new variable is not added to 5235 // IdResolver, so the code in the OpenMP region uses original variable for 5236 // proper diagnostics. 5237 Type = Type.getUnqualifiedType(); 5238 auto VDPrivate = buildVarDecl(*this, DE->getExprLoc(), Type, VD->getName()); 5239 ActOnUninitializedDecl(VDPrivate, /*TypeMayContainAuto=*/false); 5240 if (VDPrivate->isInvalidDecl()) 5241 continue; 5242 auto VDPrivateRefExpr = buildDeclRefExpr( 5243 *this, VDPrivate, DE->getType().getUnqualifiedType(), DE->getExprLoc()); 5244 5245 DSAStack->addDSA(VD, DE, OMPC_private); 5246 Vars.push_back(DE); 5247 PrivateCopies.push_back(VDPrivateRefExpr); 5248 } 5249 5250 if (Vars.empty()) 5251 return nullptr; 5252 5253 return OMPPrivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 5254 PrivateCopies); 5255 } 5256 5257 namespace { 5258 class DiagsUninitializedSeveretyRAII { 5259 private: 5260 DiagnosticsEngine &Diags; 5261 SourceLocation SavedLoc; 5262 bool IsIgnored; 5263 5264 public: 5265 DiagsUninitializedSeveretyRAII(DiagnosticsEngine &Diags, SourceLocation Loc, 5266 bool IsIgnored) 5267 : Diags(Diags), SavedLoc(Loc), IsIgnored(IsIgnored) { 5268 if (!IsIgnored) { 5269 Diags.setSeverity(/*Diag*/ diag::warn_uninit_self_reference_in_init, 5270 /*Map*/ diag::Severity::Ignored, Loc); 5271 } 5272 } 5273 ~DiagsUninitializedSeveretyRAII() { 5274 if (!IsIgnored) 5275 Diags.popMappings(SavedLoc); 5276 } 5277 }; 5278 } 5279 5280 OMPClause *Sema::ActOnOpenMPFirstprivateClause(ArrayRef<Expr *> VarList, 5281 SourceLocation StartLoc, 5282 SourceLocation LParenLoc, 5283 SourceLocation EndLoc) { 5284 SmallVector<Expr *, 8> Vars; 5285 SmallVector<Expr *, 8> PrivateCopies; 5286 SmallVector<Expr *, 8> Inits; 5287 bool IsImplicitClause = 5288 StartLoc.isInvalid() && LParenLoc.isInvalid() && EndLoc.isInvalid(); 5289 auto ImplicitClauseLoc = DSAStack->getConstructLoc(); 5290 5291 for (auto &RefExpr : VarList) { 5292 assert(RefExpr && "NULL expr in OpenMP firstprivate clause."); 5293 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 5294 // It will be analyzed later. 5295 Vars.push_back(RefExpr); 5296 PrivateCopies.push_back(nullptr); 5297 Inits.push_back(nullptr); 5298 continue; 5299 } 5300 5301 SourceLocation ELoc = 5302 IsImplicitClause ? ImplicitClauseLoc : RefExpr->getExprLoc(); 5303 // OpenMP [2.1, C/C++] 5304 // A list item is a variable name. 5305 // OpenMP [2.9.3.3, Restrictions, p.1] 5306 // A variable that is part of another variable (as an array or 5307 // structure element) cannot appear in a private clause. 5308 DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 5309 if (!DE || !isa<VarDecl>(DE->getDecl())) { 5310 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 5311 continue; 5312 } 5313 Decl *D = DE->getDecl(); 5314 VarDecl *VD = cast<VarDecl>(D); 5315 5316 QualType Type = VD->getType(); 5317 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 5318 // It will be analyzed later. 5319 Vars.push_back(DE); 5320 PrivateCopies.push_back(nullptr); 5321 Inits.push_back(nullptr); 5322 continue; 5323 } 5324 5325 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 5326 // A variable that appears in a private clause must not have an incomplete 5327 // type or a reference type. 5328 if (RequireCompleteType(ELoc, Type, 5329 diag::err_omp_firstprivate_incomplete_type)) { 5330 continue; 5331 } 5332 if (Type->isReferenceType()) { 5333 if (IsImplicitClause) { 5334 Diag(ImplicitClauseLoc, 5335 diag::err_omp_task_predetermined_firstprivate_ref_type_arg) 5336 << Type; 5337 Diag(RefExpr->getExprLoc(), diag::note_used_here); 5338 } else { 5339 Diag(ELoc, diag::err_omp_clause_ref_type_arg) 5340 << getOpenMPClauseName(OMPC_firstprivate) << Type; 5341 } 5342 bool IsDecl = 5343 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5344 Diag(VD->getLocation(), 5345 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5346 << VD; 5347 continue; 5348 } 5349 5350 // OpenMP [2.9.3.4, Restrictions, C/C++, p.1] 5351 // A variable of class type (or array thereof) that appears in a private 5352 // clause requires an accessible, unambiguous copy constructor for the 5353 // class type. 5354 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 5355 5356 // If an implicit firstprivate variable found it was checked already. 5357 if (!IsImplicitClause) { 5358 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 5359 bool IsConstant = ElemType.isConstant(Context); 5360 // OpenMP [2.4.13, Data-sharing Attribute Clauses] 5361 // A list item that specifies a given variable may not appear in more 5362 // than one clause on the same directive, except that a variable may be 5363 // specified in both firstprivate and lastprivate clauses. 5364 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_firstprivate && 5365 DVar.CKind != OMPC_lastprivate && DVar.RefExpr) { 5366 Diag(ELoc, diag::err_omp_wrong_dsa) 5367 << getOpenMPClauseName(DVar.CKind) 5368 << getOpenMPClauseName(OMPC_firstprivate); 5369 ReportOriginalDSA(*this, DSAStack, VD, DVar); 5370 continue; 5371 } 5372 5373 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 5374 // in a Construct] 5375 // Variables with the predetermined data-sharing attributes may not be 5376 // listed in data-sharing attributes clauses, except for the cases 5377 // listed below. For these exceptions only, listing a predetermined 5378 // variable in a data-sharing attribute clause is allowed and overrides 5379 // the variable's predetermined data-sharing attributes. 5380 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 5381 // in a Construct, C/C++, p.2] 5382 // Variables with const-qualified type having no mutable member may be 5383 // listed in a firstprivate clause, even if they are static data members. 5384 if (!(IsConstant || VD->isStaticDataMember()) && !DVar.RefExpr && 5385 DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared) { 5386 Diag(ELoc, diag::err_omp_wrong_dsa) 5387 << getOpenMPClauseName(DVar.CKind) 5388 << getOpenMPClauseName(OMPC_firstprivate); 5389 ReportOriginalDSA(*this, DSAStack, VD, DVar); 5390 continue; 5391 } 5392 5393 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 5394 // OpenMP [2.9.3.4, Restrictions, p.2] 5395 // A list item that is private within a parallel region must not appear 5396 // in a firstprivate clause on a worksharing construct if any of the 5397 // worksharing regions arising from the worksharing construct ever bind 5398 // to any of the parallel regions arising from the parallel construct. 5399 if (isOpenMPWorksharingDirective(CurrDir) && 5400 !isOpenMPParallelDirective(CurrDir)) { 5401 DVar = DSAStack->getImplicitDSA(VD, true); 5402 if (DVar.CKind != OMPC_shared && 5403 (isOpenMPParallelDirective(DVar.DKind) || 5404 DVar.DKind == OMPD_unknown)) { 5405 Diag(ELoc, diag::err_omp_required_access) 5406 << getOpenMPClauseName(OMPC_firstprivate) 5407 << getOpenMPClauseName(OMPC_shared); 5408 ReportOriginalDSA(*this, DSAStack, VD, DVar); 5409 continue; 5410 } 5411 } 5412 // OpenMP [2.9.3.4, Restrictions, p.3] 5413 // A list item that appears in a reduction clause of a parallel construct 5414 // must not appear in a firstprivate clause on a worksharing or task 5415 // construct if any of the worksharing or task regions arising from the 5416 // worksharing or task construct ever bind to any of the parallel regions 5417 // arising from the parallel construct. 5418 // OpenMP [2.9.3.4, Restrictions, p.4] 5419 // A list item that appears in a reduction clause in worksharing 5420 // construct must not appear in a firstprivate clause in a task construct 5421 // encountered during execution of any of the worksharing regions arising 5422 // from the worksharing construct. 5423 if (CurrDir == OMPD_task) { 5424 DVar = 5425 DSAStack->hasInnermostDSA(VD, MatchesAnyClause(OMPC_reduction), 5426 [](OpenMPDirectiveKind K) -> bool { 5427 return isOpenMPParallelDirective(K) || 5428 isOpenMPWorksharingDirective(K); 5429 }, 5430 false); 5431 if (DVar.CKind == OMPC_reduction && 5432 (isOpenMPParallelDirective(DVar.DKind) || 5433 isOpenMPWorksharingDirective(DVar.DKind))) { 5434 Diag(ELoc, diag::err_omp_parallel_reduction_in_task_firstprivate) 5435 << getOpenMPDirectiveName(DVar.DKind); 5436 ReportOriginalDSA(*this, DSAStack, VD, DVar); 5437 continue; 5438 } 5439 } 5440 } 5441 5442 // Variably modified types are not supported for tasks. 5443 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType() && 5444 DSAStack->getCurrentDirective() == OMPD_task) { 5445 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 5446 << getOpenMPClauseName(OMPC_firstprivate) << Type 5447 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 5448 bool IsDecl = 5449 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5450 Diag(VD->getLocation(), 5451 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5452 << VD; 5453 continue; 5454 } 5455 5456 Type = Type.getUnqualifiedType(); 5457 auto VDPrivate = buildVarDecl(*this, ELoc, Type, VD->getName()); 5458 // Generate helper private variable and initialize it with the value of the 5459 // original variable. The address of the original variable is replaced by 5460 // the address of the new private variable in the CodeGen. This new variable 5461 // is not added to IdResolver, so the code in the OpenMP region uses 5462 // original variable for proper diagnostics and variable capturing. 5463 Expr *VDInitRefExpr = nullptr; 5464 // For arrays generate initializer for single element and replace it by the 5465 // original array element in CodeGen. 5466 if (Type->isArrayType()) { 5467 auto VDInit = 5468 buildVarDecl(*this, DE->getExprLoc(), ElemType, VD->getName()); 5469 VDInitRefExpr = buildDeclRefExpr(*this, VDInit, ElemType, ELoc); 5470 auto Init = DefaultLvalueConversion(VDInitRefExpr).get(); 5471 ElemType = ElemType.getUnqualifiedType(); 5472 auto *VDInitTemp = buildVarDecl(*this, DE->getLocStart(), ElemType, 5473 ".firstprivate.temp"); 5474 InitializedEntity Entity = 5475 InitializedEntity::InitializeVariable(VDInitTemp); 5476 InitializationKind Kind = InitializationKind::CreateCopy(ELoc, ELoc); 5477 5478 InitializationSequence InitSeq(*this, Entity, Kind, Init); 5479 ExprResult Result = InitSeq.Perform(*this, Entity, Kind, Init); 5480 if (Result.isInvalid()) 5481 VDPrivate->setInvalidDecl(); 5482 else 5483 VDPrivate->setInit(Result.getAs<Expr>()); 5484 } else { 5485 auto *VDInit = 5486 buildVarDecl(*this, DE->getLocStart(), Type, ".firstprivate.temp"); 5487 VDInitRefExpr = 5488 buildDeclRefExpr(*this, VDInit, DE->getType(), DE->getExprLoc()); 5489 AddInitializerToDecl(VDPrivate, 5490 DefaultLvalueConversion(VDInitRefExpr).get(), 5491 /*DirectInit=*/false, /*TypeMayContainAuto=*/false); 5492 } 5493 if (VDPrivate->isInvalidDecl()) { 5494 if (IsImplicitClause) { 5495 Diag(DE->getExprLoc(), 5496 diag::note_omp_task_predetermined_firstprivate_here); 5497 } 5498 continue; 5499 } 5500 CurContext->addDecl(VDPrivate); 5501 auto VDPrivateRefExpr = buildDeclRefExpr( 5502 *this, VDPrivate, DE->getType().getUnqualifiedType(), DE->getExprLoc()); 5503 DSAStack->addDSA(VD, DE, OMPC_firstprivate); 5504 Vars.push_back(DE); 5505 PrivateCopies.push_back(VDPrivateRefExpr); 5506 Inits.push_back(VDInitRefExpr); 5507 } 5508 5509 if (Vars.empty()) 5510 return nullptr; 5511 5512 return OMPFirstprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 5513 Vars, PrivateCopies, Inits); 5514 } 5515 5516 OMPClause *Sema::ActOnOpenMPLastprivateClause(ArrayRef<Expr *> VarList, 5517 SourceLocation StartLoc, 5518 SourceLocation LParenLoc, 5519 SourceLocation EndLoc) { 5520 SmallVector<Expr *, 8> Vars; 5521 SmallVector<Expr *, 8> SrcExprs; 5522 SmallVector<Expr *, 8> DstExprs; 5523 SmallVector<Expr *, 8> AssignmentOps; 5524 for (auto &RefExpr : VarList) { 5525 assert(RefExpr && "NULL expr in OpenMP lastprivate clause."); 5526 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 5527 // It will be analyzed later. 5528 Vars.push_back(RefExpr); 5529 SrcExprs.push_back(nullptr); 5530 DstExprs.push_back(nullptr); 5531 AssignmentOps.push_back(nullptr); 5532 continue; 5533 } 5534 5535 SourceLocation ELoc = RefExpr->getExprLoc(); 5536 // OpenMP [2.1, C/C++] 5537 // A list item is a variable name. 5538 // OpenMP [2.14.3.5, Restrictions, p.1] 5539 // A variable that is part of another variable (as an array or structure 5540 // element) cannot appear in a lastprivate clause. 5541 DeclRefExpr *DE = dyn_cast_or_null<DeclRefExpr>(RefExpr); 5542 if (!DE || !isa<VarDecl>(DE->getDecl())) { 5543 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 5544 continue; 5545 } 5546 Decl *D = DE->getDecl(); 5547 VarDecl *VD = cast<VarDecl>(D); 5548 5549 QualType Type = VD->getType(); 5550 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 5551 // It will be analyzed later. 5552 Vars.push_back(DE); 5553 SrcExprs.push_back(nullptr); 5554 DstExprs.push_back(nullptr); 5555 AssignmentOps.push_back(nullptr); 5556 continue; 5557 } 5558 5559 // OpenMP [2.14.3.5, Restrictions, C/C++, p.2] 5560 // A variable that appears in a lastprivate clause must not have an 5561 // incomplete type or a reference type. 5562 if (RequireCompleteType(ELoc, Type, 5563 diag::err_omp_lastprivate_incomplete_type)) { 5564 continue; 5565 } 5566 if (Type->isReferenceType()) { 5567 Diag(ELoc, diag::err_omp_clause_ref_type_arg) 5568 << getOpenMPClauseName(OMPC_lastprivate) << Type; 5569 bool IsDecl = 5570 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5571 Diag(VD->getLocation(), 5572 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5573 << VD; 5574 continue; 5575 } 5576 5577 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 5578 // in a Construct] 5579 // Variables with the predetermined data-sharing attributes may not be 5580 // listed in data-sharing attributes clauses, except for the cases 5581 // listed below. 5582 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 5583 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_lastprivate && 5584 DVar.CKind != OMPC_firstprivate && 5585 (DVar.CKind != OMPC_private || DVar.RefExpr != nullptr)) { 5586 Diag(ELoc, diag::err_omp_wrong_dsa) 5587 << getOpenMPClauseName(DVar.CKind) 5588 << getOpenMPClauseName(OMPC_lastprivate); 5589 ReportOriginalDSA(*this, DSAStack, VD, DVar); 5590 continue; 5591 } 5592 5593 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 5594 // OpenMP [2.14.3.5, Restrictions, p.2] 5595 // A list item that is private within a parallel region, or that appears in 5596 // the reduction clause of a parallel construct, must not appear in a 5597 // lastprivate clause on a worksharing construct if any of the corresponding 5598 // worksharing regions ever binds to any of the corresponding parallel 5599 // regions. 5600 DSAStackTy::DSAVarData TopDVar = DVar; 5601 if (isOpenMPWorksharingDirective(CurrDir) && 5602 !isOpenMPParallelDirective(CurrDir)) { 5603 DVar = DSAStack->getImplicitDSA(VD, true); 5604 if (DVar.CKind != OMPC_shared) { 5605 Diag(ELoc, diag::err_omp_required_access) 5606 << getOpenMPClauseName(OMPC_lastprivate) 5607 << getOpenMPClauseName(OMPC_shared); 5608 ReportOriginalDSA(*this, DSAStack, VD, DVar); 5609 continue; 5610 } 5611 } 5612 // OpenMP [2.14.3.5, Restrictions, C++, p.1,2] 5613 // A variable of class type (or array thereof) that appears in a 5614 // lastprivate clause requires an accessible, unambiguous default 5615 // constructor for the class type, unless the list item is also specified 5616 // in a firstprivate clause. 5617 // A variable of class type (or array thereof) that appears in a 5618 // lastprivate clause requires an accessible, unambiguous copy assignment 5619 // operator for the class type. 5620 Type = Context.getBaseElementType(Type).getNonReferenceType(); 5621 auto *SrcVD = buildVarDecl(*this, DE->getLocStart(), 5622 Type.getUnqualifiedType(), ".lastprivate.src"); 5623 auto *PseudoSrcExpr = buildDeclRefExpr( 5624 *this, SrcVD, Type.getUnqualifiedType(), DE->getExprLoc()); 5625 auto *DstVD = 5626 buildVarDecl(*this, DE->getLocStart(), Type, ".lastprivate.dst"); 5627 auto *PseudoDstExpr = 5628 buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc()); 5629 // For arrays generate assignment operation for single element and replace 5630 // it by the original array element in CodeGen. 5631 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 5632 PseudoDstExpr, PseudoSrcExpr); 5633 if (AssignmentOp.isInvalid()) 5634 continue; 5635 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 5636 /*DiscardedValue=*/true); 5637 if (AssignmentOp.isInvalid()) 5638 continue; 5639 5640 if (TopDVar.CKind != OMPC_firstprivate) 5641 DSAStack->addDSA(VD, DE, OMPC_lastprivate); 5642 Vars.push_back(DE); 5643 SrcExprs.push_back(PseudoSrcExpr); 5644 DstExprs.push_back(PseudoDstExpr); 5645 AssignmentOps.push_back(AssignmentOp.get()); 5646 } 5647 5648 if (Vars.empty()) 5649 return nullptr; 5650 5651 return OMPLastprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 5652 Vars, SrcExprs, DstExprs, AssignmentOps); 5653 } 5654 5655 OMPClause *Sema::ActOnOpenMPSharedClause(ArrayRef<Expr *> VarList, 5656 SourceLocation StartLoc, 5657 SourceLocation LParenLoc, 5658 SourceLocation EndLoc) { 5659 SmallVector<Expr *, 8> Vars; 5660 for (auto &RefExpr : VarList) { 5661 assert(RefExpr && "NULL expr in OpenMP shared clause."); 5662 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 5663 // It will be analyzed later. 5664 Vars.push_back(RefExpr); 5665 continue; 5666 } 5667 5668 SourceLocation ELoc = RefExpr->getExprLoc(); 5669 // OpenMP [2.1, C/C++] 5670 // A list item is a variable name. 5671 // OpenMP [2.14.3.2, Restrictions, p.1] 5672 // A variable that is part of another variable (as an array or structure 5673 // element) cannot appear in a shared unless it is a static data member 5674 // of a C++ class. 5675 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 5676 if (!DE || !isa<VarDecl>(DE->getDecl())) { 5677 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 5678 continue; 5679 } 5680 Decl *D = DE->getDecl(); 5681 VarDecl *VD = cast<VarDecl>(D); 5682 5683 QualType Type = VD->getType(); 5684 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 5685 // It will be analyzed later. 5686 Vars.push_back(DE); 5687 continue; 5688 } 5689 5690 // OpenMP [2.9.1.1, Data-sharing Attribute Rules for Variables Referenced 5691 // in a Construct] 5692 // Variables with the predetermined data-sharing attributes may not be 5693 // listed in data-sharing attributes clauses, except for the cases 5694 // listed below. For these exceptions only, listing a predetermined 5695 // variable in a data-sharing attribute clause is allowed and overrides 5696 // the variable's predetermined data-sharing attributes. 5697 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 5698 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_shared && 5699 DVar.RefExpr) { 5700 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 5701 << getOpenMPClauseName(OMPC_shared); 5702 ReportOriginalDSA(*this, DSAStack, VD, DVar); 5703 continue; 5704 } 5705 5706 DSAStack->addDSA(VD, DE, OMPC_shared); 5707 Vars.push_back(DE); 5708 } 5709 5710 if (Vars.empty()) 5711 return nullptr; 5712 5713 return OMPSharedClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars); 5714 } 5715 5716 namespace { 5717 class DSARefChecker : public StmtVisitor<DSARefChecker, bool> { 5718 DSAStackTy *Stack; 5719 5720 public: 5721 bool VisitDeclRefExpr(DeclRefExpr *E) { 5722 if (VarDecl *VD = dyn_cast<VarDecl>(E->getDecl())) { 5723 DSAStackTy::DSAVarData DVar = Stack->getTopDSA(VD, false); 5724 if (DVar.CKind == OMPC_shared && !DVar.RefExpr) 5725 return false; 5726 if (DVar.CKind != OMPC_unknown) 5727 return true; 5728 DSAStackTy::DSAVarData DVarPrivate = 5729 Stack->hasDSA(VD, isOpenMPPrivate, MatchesAlways(), false); 5730 if (DVarPrivate.CKind != OMPC_unknown) 5731 return true; 5732 return false; 5733 } 5734 return false; 5735 } 5736 bool VisitStmt(Stmt *S) { 5737 for (auto Child : S->children()) { 5738 if (Child && Visit(Child)) 5739 return true; 5740 } 5741 return false; 5742 } 5743 explicit DSARefChecker(DSAStackTy *S) : Stack(S) {} 5744 }; 5745 } // namespace 5746 5747 OMPClause *Sema::ActOnOpenMPReductionClause( 5748 ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc, 5749 SourceLocation ColonLoc, SourceLocation EndLoc, 5750 CXXScopeSpec &ReductionIdScopeSpec, 5751 const DeclarationNameInfo &ReductionId) { 5752 // TODO: Allow scope specification search when 'declare reduction' is 5753 // supported. 5754 assert(ReductionIdScopeSpec.isEmpty() && 5755 "No support for scoped reduction identifiers yet."); 5756 5757 auto DN = ReductionId.getName(); 5758 auto OOK = DN.getCXXOverloadedOperator(); 5759 BinaryOperatorKind BOK = BO_Comma; 5760 5761 // OpenMP [2.14.3.6, reduction clause] 5762 // C 5763 // reduction-identifier is either an identifier or one of the following 5764 // operators: +, -, *, &, |, ^, && and || 5765 // C++ 5766 // reduction-identifier is either an id-expression or one of the following 5767 // operators: +, -, *, &, |, ^, && and || 5768 // FIXME: Only 'min' and 'max' identifiers are supported for now. 5769 switch (OOK) { 5770 case OO_Plus: 5771 case OO_Minus: 5772 BOK = BO_Add; 5773 break; 5774 case OO_Star: 5775 BOK = BO_Mul; 5776 break; 5777 case OO_Amp: 5778 BOK = BO_And; 5779 break; 5780 case OO_Pipe: 5781 BOK = BO_Or; 5782 break; 5783 case OO_Caret: 5784 BOK = BO_Xor; 5785 break; 5786 case OO_AmpAmp: 5787 BOK = BO_LAnd; 5788 break; 5789 case OO_PipePipe: 5790 BOK = BO_LOr; 5791 break; 5792 case OO_New: 5793 case OO_Delete: 5794 case OO_Array_New: 5795 case OO_Array_Delete: 5796 case OO_Slash: 5797 case OO_Percent: 5798 case OO_Tilde: 5799 case OO_Exclaim: 5800 case OO_Equal: 5801 case OO_Less: 5802 case OO_Greater: 5803 case OO_LessEqual: 5804 case OO_GreaterEqual: 5805 case OO_PlusEqual: 5806 case OO_MinusEqual: 5807 case OO_StarEqual: 5808 case OO_SlashEqual: 5809 case OO_PercentEqual: 5810 case OO_CaretEqual: 5811 case OO_AmpEqual: 5812 case OO_PipeEqual: 5813 case OO_LessLess: 5814 case OO_GreaterGreater: 5815 case OO_LessLessEqual: 5816 case OO_GreaterGreaterEqual: 5817 case OO_EqualEqual: 5818 case OO_ExclaimEqual: 5819 case OO_PlusPlus: 5820 case OO_MinusMinus: 5821 case OO_Comma: 5822 case OO_ArrowStar: 5823 case OO_Arrow: 5824 case OO_Call: 5825 case OO_Subscript: 5826 case OO_Conditional: 5827 case NUM_OVERLOADED_OPERATORS: 5828 llvm_unreachable("Unexpected reduction identifier"); 5829 case OO_None: 5830 if (auto II = DN.getAsIdentifierInfo()) { 5831 if (II->isStr("max")) 5832 BOK = BO_GT; 5833 else if (II->isStr("min")) 5834 BOK = BO_LT; 5835 } 5836 break; 5837 } 5838 SourceRange ReductionIdRange; 5839 if (ReductionIdScopeSpec.isValid()) { 5840 ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc()); 5841 } 5842 ReductionIdRange.setEnd(ReductionId.getEndLoc()); 5843 if (BOK == BO_Comma) { 5844 // Not allowed reduction identifier is found. 5845 Diag(ReductionId.getLocStart(), diag::err_omp_unknown_reduction_identifier) 5846 << ReductionIdRange; 5847 return nullptr; 5848 } 5849 5850 SmallVector<Expr *, 8> Vars; 5851 SmallVector<Expr *, 8> LHSs; 5852 SmallVector<Expr *, 8> RHSs; 5853 SmallVector<Expr *, 8> ReductionOps; 5854 for (auto RefExpr : VarList) { 5855 assert(RefExpr && "nullptr expr in OpenMP reduction clause."); 5856 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 5857 // It will be analyzed later. 5858 Vars.push_back(RefExpr); 5859 LHSs.push_back(nullptr); 5860 RHSs.push_back(nullptr); 5861 ReductionOps.push_back(nullptr); 5862 continue; 5863 } 5864 5865 if (RefExpr->isTypeDependent() || RefExpr->isValueDependent() || 5866 RefExpr->isInstantiationDependent() || 5867 RefExpr->containsUnexpandedParameterPack()) { 5868 // It will be analyzed later. 5869 Vars.push_back(RefExpr); 5870 LHSs.push_back(nullptr); 5871 RHSs.push_back(nullptr); 5872 ReductionOps.push_back(nullptr); 5873 continue; 5874 } 5875 5876 auto ELoc = RefExpr->getExprLoc(); 5877 auto ERange = RefExpr->getSourceRange(); 5878 // OpenMP [2.1, C/C++] 5879 // A list item is a variable or array section, subject to the restrictions 5880 // specified in Section 2.4 on page 42 and in each of the sections 5881 // describing clauses and directives for which a list appears. 5882 // OpenMP [2.14.3.3, Restrictions, p.1] 5883 // A variable that is part of another variable (as an array or 5884 // structure element) cannot appear in a private clause. 5885 auto DE = dyn_cast<DeclRefExpr>(RefExpr); 5886 if (!DE || !isa<VarDecl>(DE->getDecl())) { 5887 Diag(ELoc, diag::err_omp_expected_var_name) << ERange; 5888 continue; 5889 } 5890 auto D = DE->getDecl(); 5891 auto VD = cast<VarDecl>(D); 5892 auto Type = VD->getType(); 5893 // OpenMP [2.9.3.3, Restrictions, C/C++, p.3] 5894 // A variable that appears in a private clause must not have an incomplete 5895 // type or a reference type. 5896 if (RequireCompleteType(ELoc, Type, 5897 diag::err_omp_reduction_incomplete_type)) 5898 continue; 5899 // OpenMP [2.14.3.6, reduction clause, Restrictions] 5900 // Arrays may not appear in a reduction clause. 5901 if (Type.getNonReferenceType()->isArrayType()) { 5902 Diag(ELoc, diag::err_omp_reduction_type_array) << Type << ERange; 5903 bool IsDecl = 5904 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5905 Diag(VD->getLocation(), 5906 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5907 << VD; 5908 continue; 5909 } 5910 // OpenMP [2.14.3.6, reduction clause, Restrictions] 5911 // A list item that appears in a reduction clause must not be 5912 // const-qualified. 5913 if (Type.getNonReferenceType().isConstant(Context)) { 5914 Diag(ELoc, diag::err_omp_const_variable) 5915 << getOpenMPClauseName(OMPC_reduction) << Type << ERange; 5916 bool IsDecl = 5917 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5918 Diag(VD->getLocation(), 5919 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5920 << VD; 5921 continue; 5922 } 5923 // OpenMP [2.9.3.6, Restrictions, C/C++, p.4] 5924 // If a list-item is a reference type then it must bind to the same object 5925 // for all threads of the team. 5926 VarDecl *VDDef = VD->getDefinition(); 5927 if (Type->isReferenceType() && VDDef) { 5928 DSARefChecker Check(DSAStack); 5929 if (Check.Visit(VDDef->getInit())) { 5930 Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange; 5931 Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef; 5932 continue; 5933 } 5934 } 5935 // OpenMP [2.14.3.6, reduction clause, Restrictions] 5936 // The type of a list item that appears in a reduction clause must be valid 5937 // for the reduction-identifier. For a max or min reduction in C, the type 5938 // of the list item must be an allowed arithmetic data type: char, int, 5939 // float, double, or _Bool, possibly modified with long, short, signed, or 5940 // unsigned. For a max or min reduction in C++, the type of the list item 5941 // must be an allowed arithmetic data type: char, wchar_t, int, float, 5942 // double, or bool, possibly modified with long, short, signed, or unsigned. 5943 if ((BOK == BO_GT || BOK == BO_LT) && 5944 !(Type->isScalarType() || 5945 (getLangOpts().CPlusPlus && Type->isArithmeticType()))) { 5946 Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg) 5947 << getLangOpts().CPlusPlus; 5948 bool IsDecl = 5949 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5950 Diag(VD->getLocation(), 5951 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5952 << VD; 5953 continue; 5954 } 5955 if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) && 5956 !getLangOpts().CPlusPlus && Type->isFloatingType()) { 5957 Diag(ELoc, diag::err_omp_clause_floating_type_arg); 5958 bool IsDecl = 5959 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 5960 Diag(VD->getLocation(), 5961 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 5962 << VD; 5963 continue; 5964 } 5965 // OpenMP [2.14.1.1, Data-sharing Attribute Rules for Variables Referenced 5966 // in a Construct] 5967 // Variables with the predetermined data-sharing attributes may not be 5968 // listed in data-sharing attributes clauses, except for the cases 5969 // listed below. For these exceptions only, listing a predetermined 5970 // variable in a data-sharing attribute clause is allowed and overrides 5971 // the variable's predetermined data-sharing attributes. 5972 // OpenMP [2.14.3.6, Restrictions, p.3] 5973 // Any number of reduction clauses can be specified on the directive, 5974 // but a list item can appear only once in the reduction clauses for that 5975 // directive. 5976 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 5977 if (DVar.CKind == OMPC_reduction) { 5978 Diag(ELoc, diag::err_omp_once_referenced) 5979 << getOpenMPClauseName(OMPC_reduction); 5980 if (DVar.RefExpr) { 5981 Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced); 5982 } 5983 } else if (DVar.CKind != OMPC_unknown) { 5984 Diag(ELoc, diag::err_omp_wrong_dsa) 5985 << getOpenMPClauseName(DVar.CKind) 5986 << getOpenMPClauseName(OMPC_reduction); 5987 ReportOriginalDSA(*this, DSAStack, VD, DVar); 5988 continue; 5989 } 5990 5991 // OpenMP [2.14.3.6, Restrictions, p.1] 5992 // A list item that appears in a reduction clause of a worksharing 5993 // construct must be shared in the parallel regions to which any of the 5994 // worksharing regions arising from the worksharing construct bind. 5995 OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective(); 5996 if (isOpenMPWorksharingDirective(CurrDir) && 5997 !isOpenMPParallelDirective(CurrDir)) { 5998 DVar = DSAStack->getImplicitDSA(VD, true); 5999 if (DVar.CKind != OMPC_shared) { 6000 Diag(ELoc, diag::err_omp_required_access) 6001 << getOpenMPClauseName(OMPC_reduction) 6002 << getOpenMPClauseName(OMPC_shared); 6003 ReportOriginalDSA(*this, DSAStack, VD, DVar); 6004 continue; 6005 } 6006 } 6007 Type = Type.getNonLValueExprType(Context).getUnqualifiedType(); 6008 auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs"); 6009 auto *RHSVD = buildVarDecl(*this, ELoc, Type, VD->getName()); 6010 // Add initializer for private variable. 6011 Expr *Init = nullptr; 6012 switch (BOK) { 6013 case BO_Add: 6014 case BO_Xor: 6015 case BO_Or: 6016 case BO_LOr: 6017 // '+', '-', '^', '|', '||' reduction ops - initializer is '0'. 6018 if (Type->isScalarType() || Type->isAnyComplexType()) { 6019 Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get(); 6020 } 6021 break; 6022 case BO_Mul: 6023 case BO_LAnd: 6024 if (Type->isScalarType() || Type->isAnyComplexType()) { 6025 // '*' and '&&' reduction ops - initializer is '1'. 6026 Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get(); 6027 } 6028 break; 6029 case BO_And: { 6030 // '&' reduction op - initializer is '~0'. 6031 QualType OrigType = Type; 6032 if (auto *ComplexTy = OrigType->getAs<ComplexType>()) { 6033 Type = ComplexTy->getElementType(); 6034 } 6035 if (Type->isRealFloatingType()) { 6036 llvm::APFloat InitValue = 6037 llvm::APFloat::getAllOnesValue(Context.getTypeSize(Type), 6038 /*isIEEE=*/true); 6039 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 6040 Type, ELoc); 6041 } else if (Type->isScalarType()) { 6042 auto Size = Context.getTypeSize(Type); 6043 QualType IntTy = Context.getIntTypeForBitwidth(Size, /*Signed=*/0); 6044 llvm::APInt InitValue = llvm::APInt::getAllOnesValue(Size); 6045 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 6046 } 6047 if (Init && OrigType->isAnyComplexType()) { 6048 // Init = 0xFFFF + 0xFFFFi; 6049 auto *Im = new (Context) ImaginaryLiteral(Init, OrigType); 6050 Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get(); 6051 } 6052 Type = OrigType; 6053 break; 6054 } 6055 case BO_LT: 6056 case BO_GT: { 6057 // 'min' reduction op - initializer is 'Largest representable number in 6058 // the reduction list item type'. 6059 // 'max' reduction op - initializer is 'Least representable number in 6060 // the reduction list item type'. 6061 if (Type->isIntegerType() || Type->isPointerType()) { 6062 bool IsSigned = Type->hasSignedIntegerRepresentation(); 6063 auto Size = Context.getTypeSize(Type); 6064 QualType IntTy = 6065 Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned); 6066 llvm::APInt InitValue = 6067 (BOK != BO_LT) 6068 ? IsSigned ? llvm::APInt::getSignedMinValue(Size) 6069 : llvm::APInt::getMinValue(Size) 6070 : IsSigned ? llvm::APInt::getSignedMaxValue(Size) 6071 : llvm::APInt::getMaxValue(Size); 6072 Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc); 6073 if (Type->isPointerType()) { 6074 // Cast to pointer type. 6075 auto CastExpr = BuildCStyleCastExpr( 6076 SourceLocation(), Context.getTrivialTypeSourceInfo(Type, ELoc), 6077 SourceLocation(), Init); 6078 if (CastExpr.isInvalid()) 6079 continue; 6080 Init = CastExpr.get(); 6081 } 6082 } else if (Type->isRealFloatingType()) { 6083 llvm::APFloat InitValue = llvm::APFloat::getLargest( 6084 Context.getFloatTypeSemantics(Type), BOK != BO_LT); 6085 Init = FloatingLiteral::Create(Context, InitValue, /*isexact=*/true, 6086 Type, ELoc); 6087 } 6088 break; 6089 } 6090 case BO_PtrMemD: 6091 case BO_PtrMemI: 6092 case BO_MulAssign: 6093 case BO_Div: 6094 case BO_Rem: 6095 case BO_Sub: 6096 case BO_Shl: 6097 case BO_Shr: 6098 case BO_LE: 6099 case BO_GE: 6100 case BO_EQ: 6101 case BO_NE: 6102 case BO_AndAssign: 6103 case BO_XorAssign: 6104 case BO_OrAssign: 6105 case BO_Assign: 6106 case BO_AddAssign: 6107 case BO_SubAssign: 6108 case BO_DivAssign: 6109 case BO_RemAssign: 6110 case BO_ShlAssign: 6111 case BO_ShrAssign: 6112 case BO_Comma: 6113 llvm_unreachable("Unexpected reduction operation"); 6114 } 6115 if (Init) { 6116 AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false, 6117 /*TypeMayContainAuto=*/false); 6118 } else { 6119 ActOnUninitializedDecl(RHSVD, /*TypeMayContainAuto=*/false); 6120 } 6121 if (!RHSVD->hasInit()) { 6122 Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type 6123 << ReductionIdRange; 6124 bool IsDecl = 6125 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 6126 Diag(VD->getLocation(), 6127 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 6128 << VD; 6129 continue; 6130 } 6131 auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc); 6132 auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc); 6133 ExprResult ReductionOp = 6134 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), BOK, 6135 LHSDRE, RHSDRE); 6136 if (ReductionOp.isUsable()) { 6137 if (BOK != BO_LT && BOK != BO_GT) { 6138 ReductionOp = 6139 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 6140 BO_Assign, LHSDRE, ReductionOp.get()); 6141 } else { 6142 auto *ConditionalOp = new (Context) ConditionalOperator( 6143 ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(), 6144 RHSDRE, Type, VK_LValue, OK_Ordinary); 6145 ReductionOp = 6146 BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(), 6147 BO_Assign, LHSDRE, ConditionalOp); 6148 } 6149 if (ReductionOp.isUsable()) { 6150 ReductionOp = ActOnFinishFullExpr(ReductionOp.get()); 6151 } 6152 } 6153 if (ReductionOp.isInvalid()) 6154 continue; 6155 6156 DSAStack->addDSA(VD, DE, OMPC_reduction); 6157 Vars.push_back(DE); 6158 LHSs.push_back(LHSDRE); 6159 RHSs.push_back(RHSDRE); 6160 ReductionOps.push_back(ReductionOp.get()); 6161 } 6162 6163 if (Vars.empty()) 6164 return nullptr; 6165 6166 return OMPReductionClause::Create( 6167 Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars, 6168 ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, LHSs, 6169 RHSs, ReductionOps); 6170 } 6171 6172 OMPClause *Sema::ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step, 6173 SourceLocation StartLoc, 6174 SourceLocation LParenLoc, 6175 SourceLocation ColonLoc, 6176 SourceLocation EndLoc) { 6177 SmallVector<Expr *, 8> Vars; 6178 SmallVector<Expr *, 8> Inits; 6179 for (auto &RefExpr : VarList) { 6180 assert(RefExpr && "NULL expr in OpenMP linear clause."); 6181 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 6182 // It will be analyzed later. 6183 Vars.push_back(RefExpr); 6184 Inits.push_back(nullptr); 6185 continue; 6186 } 6187 6188 // OpenMP [2.14.3.7, linear clause] 6189 // A list item that appears in a linear clause is subject to the private 6190 // clause semantics described in Section 2.14.3.3 on page 159 except as 6191 // noted. In addition, the value of the new list item on each iteration 6192 // of the associated loop(s) corresponds to the value of the original 6193 // list item before entering the construct plus the logical number of 6194 // the iteration times linear-step. 6195 6196 SourceLocation ELoc = RefExpr->getExprLoc(); 6197 // OpenMP [2.1, C/C++] 6198 // A list item is a variable name. 6199 // OpenMP [2.14.3.3, Restrictions, p.1] 6200 // A variable that is part of another variable (as an array or 6201 // structure element) cannot appear in a private clause. 6202 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 6203 if (!DE || !isa<VarDecl>(DE->getDecl())) { 6204 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 6205 continue; 6206 } 6207 6208 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 6209 6210 // OpenMP [2.14.3.7, linear clause] 6211 // A list-item cannot appear in more than one linear clause. 6212 // A list-item that appears in a linear clause cannot appear in any 6213 // other data-sharing attribute clause. 6214 DSAStackTy::DSAVarData DVar = DSAStack->getTopDSA(VD, false); 6215 if (DVar.RefExpr) { 6216 Diag(ELoc, diag::err_omp_wrong_dsa) << getOpenMPClauseName(DVar.CKind) 6217 << getOpenMPClauseName(OMPC_linear); 6218 ReportOriginalDSA(*this, DSAStack, VD, DVar); 6219 continue; 6220 } 6221 6222 QualType QType = VD->getType(); 6223 if (QType->isDependentType() || QType->isInstantiationDependentType()) { 6224 // It will be analyzed later. 6225 Vars.push_back(DE); 6226 Inits.push_back(nullptr); 6227 continue; 6228 } 6229 6230 // A variable must not have an incomplete type or a reference type. 6231 if (RequireCompleteType(ELoc, QType, 6232 diag::err_omp_linear_incomplete_type)) { 6233 continue; 6234 } 6235 if (QType->isReferenceType()) { 6236 Diag(ELoc, diag::err_omp_clause_ref_type_arg) 6237 << getOpenMPClauseName(OMPC_linear) << QType; 6238 bool IsDecl = 6239 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 6240 Diag(VD->getLocation(), 6241 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 6242 << VD; 6243 continue; 6244 } 6245 6246 // A list item must not be const-qualified. 6247 if (QType.isConstant(Context)) { 6248 Diag(ELoc, diag::err_omp_const_variable) 6249 << getOpenMPClauseName(OMPC_linear); 6250 bool IsDecl = 6251 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 6252 Diag(VD->getLocation(), 6253 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 6254 << VD; 6255 continue; 6256 } 6257 6258 // A list item must be of integral or pointer type. 6259 QType = QType.getUnqualifiedType().getCanonicalType(); 6260 const Type *Ty = QType.getTypePtrOrNull(); 6261 if (!Ty || (!Ty->isDependentType() && !Ty->isIntegralType(Context) && 6262 !Ty->isPointerType())) { 6263 Diag(ELoc, diag::err_omp_linear_expected_int_or_ptr) << QType; 6264 bool IsDecl = 6265 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 6266 Diag(VD->getLocation(), 6267 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 6268 << VD; 6269 continue; 6270 } 6271 6272 // Build var to save initial value. 6273 VarDecl *Init = buildVarDecl(*this, ELoc, QType, ".linear.start"); 6274 AddInitializerToDecl(Init, DefaultLvalueConversion(DE).get(), 6275 /*DirectInit*/ false, /*TypeMayContainAuto*/ false); 6276 auto InitRef = buildDeclRefExpr( 6277 *this, Init, DE->getType().getUnqualifiedType(), DE->getExprLoc()); 6278 DSAStack->addDSA(VD, DE, OMPC_linear); 6279 Vars.push_back(DE); 6280 Inits.push_back(InitRef); 6281 } 6282 6283 if (Vars.empty()) 6284 return nullptr; 6285 6286 Expr *StepExpr = Step; 6287 Expr *CalcStepExpr = nullptr; 6288 if (Step && !Step->isValueDependent() && !Step->isTypeDependent() && 6289 !Step->isInstantiationDependent() && 6290 !Step->containsUnexpandedParameterPack()) { 6291 SourceLocation StepLoc = Step->getLocStart(); 6292 ExprResult Val = PerformOpenMPImplicitIntegerConversion(StepLoc, Step); 6293 if (Val.isInvalid()) 6294 return nullptr; 6295 StepExpr = Val.get(); 6296 6297 // Build var to save the step value. 6298 VarDecl *SaveVar = 6299 buildVarDecl(*this, StepLoc, StepExpr->getType(), ".linear.step"); 6300 ExprResult SaveRef = 6301 buildDeclRefExpr(*this, SaveVar, StepExpr->getType(), StepLoc); 6302 ExprResult CalcStep = 6303 BuildBinOp(CurScope, StepLoc, BO_Assign, SaveRef.get(), StepExpr); 6304 6305 // Warn about zero linear step (it would be probably better specified as 6306 // making corresponding variables 'const'). 6307 llvm::APSInt Result; 6308 bool IsConstant = StepExpr->isIntegerConstantExpr(Result, Context); 6309 if (IsConstant && !Result.isNegative() && !Result.isStrictlyPositive()) 6310 Diag(StepLoc, diag::warn_omp_linear_step_zero) << Vars[0] 6311 << (Vars.size() > 1); 6312 if (!IsConstant && CalcStep.isUsable()) { 6313 // Calculate the step beforehand instead of doing this on each iteration. 6314 // (This is not used if the number of iterations may be kfold-ed). 6315 CalcStepExpr = CalcStep.get(); 6316 } 6317 } 6318 6319 return OMPLinearClause::Create(Context, StartLoc, LParenLoc, ColonLoc, EndLoc, 6320 Vars, Inits, StepExpr, CalcStepExpr); 6321 } 6322 6323 static bool FinishOpenMPLinearClause(OMPLinearClause &Clause, DeclRefExpr *IV, 6324 Expr *NumIterations, Sema &SemaRef, 6325 Scope *S) { 6326 // Walk the vars and build update/final expressions for the CodeGen. 6327 SmallVector<Expr *, 8> Updates; 6328 SmallVector<Expr *, 8> Finals; 6329 Expr *Step = Clause.getStep(); 6330 Expr *CalcStep = Clause.getCalcStep(); 6331 // OpenMP [2.14.3.7, linear clause] 6332 // If linear-step is not specified it is assumed to be 1. 6333 if (Step == nullptr) 6334 Step = SemaRef.ActOnIntegerConstant(SourceLocation(), 1).get(); 6335 else if (CalcStep) 6336 Step = cast<BinaryOperator>(CalcStep)->getLHS(); 6337 bool HasErrors = false; 6338 auto CurInit = Clause.inits().begin(); 6339 for (auto &RefExpr : Clause.varlists()) { 6340 Expr *InitExpr = *CurInit; 6341 6342 // Build privatized reference to the current linear var. 6343 auto DE = cast<DeclRefExpr>(RefExpr); 6344 auto PrivateRef = 6345 buildDeclRefExpr(SemaRef, cast<VarDecl>(DE->getDecl()), 6346 DE->getType().getUnqualifiedType(), DE->getExprLoc(), 6347 /*RefersToCapture=*/true); 6348 6349 // Build update: Var = InitExpr + IV * Step 6350 ExprResult Update = 6351 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), PrivateRef, 6352 InitExpr, IV, Step, /* Subtract */ false); 6353 Update = SemaRef.ActOnFinishFullExpr(Update.get()); 6354 6355 // Build final: Var = InitExpr + NumIterations * Step 6356 ExprResult Final = 6357 BuildCounterUpdate(SemaRef, S, RefExpr->getExprLoc(), PrivateRef, 6358 InitExpr, NumIterations, Step, /* Subtract */ false); 6359 Final = SemaRef.ActOnFinishFullExpr(Final.get()); 6360 if (!Update.isUsable() || !Final.isUsable()) { 6361 Updates.push_back(nullptr); 6362 Finals.push_back(nullptr); 6363 HasErrors = true; 6364 } else { 6365 Updates.push_back(Update.get()); 6366 Finals.push_back(Final.get()); 6367 } 6368 ++CurInit; 6369 } 6370 Clause.setUpdates(Updates); 6371 Clause.setFinals(Finals); 6372 return HasErrors; 6373 } 6374 6375 OMPClause *Sema::ActOnOpenMPAlignedClause( 6376 ArrayRef<Expr *> VarList, Expr *Alignment, SourceLocation StartLoc, 6377 SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc) { 6378 6379 SmallVector<Expr *, 8> Vars; 6380 for (auto &RefExpr : VarList) { 6381 assert(RefExpr && "NULL expr in OpenMP aligned clause."); 6382 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 6383 // It will be analyzed later. 6384 Vars.push_back(RefExpr); 6385 continue; 6386 } 6387 6388 SourceLocation ELoc = RefExpr->getExprLoc(); 6389 // OpenMP [2.1, C/C++] 6390 // A list item is a variable name. 6391 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 6392 if (!DE || !isa<VarDecl>(DE->getDecl())) { 6393 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 6394 continue; 6395 } 6396 6397 VarDecl *VD = cast<VarDecl>(DE->getDecl()); 6398 6399 // OpenMP [2.8.1, simd construct, Restrictions] 6400 // The type of list items appearing in the aligned clause must be 6401 // array, pointer, reference to array, or reference to pointer. 6402 QualType QType = VD->getType(); 6403 QType = QType.getNonReferenceType().getUnqualifiedType().getCanonicalType(); 6404 const Type *Ty = QType.getTypePtrOrNull(); 6405 if (!Ty || (!Ty->isDependentType() && !Ty->isArrayType() && 6406 !Ty->isPointerType())) { 6407 Diag(ELoc, diag::err_omp_aligned_expected_array_or_ptr) 6408 << QType << getLangOpts().CPlusPlus << RefExpr->getSourceRange(); 6409 bool IsDecl = 6410 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 6411 Diag(VD->getLocation(), 6412 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 6413 << VD; 6414 continue; 6415 } 6416 6417 // OpenMP [2.8.1, simd construct, Restrictions] 6418 // A list-item cannot appear in more than one aligned clause. 6419 if (DeclRefExpr *PrevRef = DSAStack->addUniqueAligned(VD, DE)) { 6420 Diag(ELoc, diag::err_omp_aligned_twice) << RefExpr->getSourceRange(); 6421 Diag(PrevRef->getExprLoc(), diag::note_omp_explicit_dsa) 6422 << getOpenMPClauseName(OMPC_aligned); 6423 continue; 6424 } 6425 6426 Vars.push_back(DE); 6427 } 6428 6429 // OpenMP [2.8.1, simd construct, Description] 6430 // The parameter of the aligned clause, alignment, must be a constant 6431 // positive integer expression. 6432 // If no optional parameter is specified, implementation-defined default 6433 // alignments for SIMD instructions on the target platforms are assumed. 6434 if (Alignment != nullptr) { 6435 ExprResult AlignResult = 6436 VerifyPositiveIntegerConstantInClause(Alignment, OMPC_aligned); 6437 if (AlignResult.isInvalid()) 6438 return nullptr; 6439 Alignment = AlignResult.get(); 6440 } 6441 if (Vars.empty()) 6442 return nullptr; 6443 6444 return OMPAlignedClause::Create(Context, StartLoc, LParenLoc, ColonLoc, 6445 EndLoc, Vars, Alignment); 6446 } 6447 6448 OMPClause *Sema::ActOnOpenMPCopyinClause(ArrayRef<Expr *> VarList, 6449 SourceLocation StartLoc, 6450 SourceLocation LParenLoc, 6451 SourceLocation EndLoc) { 6452 SmallVector<Expr *, 8> Vars; 6453 SmallVector<Expr *, 8> SrcExprs; 6454 SmallVector<Expr *, 8> DstExprs; 6455 SmallVector<Expr *, 8> AssignmentOps; 6456 for (auto &RefExpr : VarList) { 6457 assert(RefExpr && "NULL expr in OpenMP copyin clause."); 6458 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 6459 // It will be analyzed later. 6460 Vars.push_back(RefExpr); 6461 SrcExprs.push_back(nullptr); 6462 DstExprs.push_back(nullptr); 6463 AssignmentOps.push_back(nullptr); 6464 continue; 6465 } 6466 6467 SourceLocation ELoc = RefExpr->getExprLoc(); 6468 // OpenMP [2.1, C/C++] 6469 // A list item is a variable name. 6470 // OpenMP [2.14.4.1, Restrictions, p.1] 6471 // A list item that appears in a copyin clause must be threadprivate. 6472 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 6473 if (!DE || !isa<VarDecl>(DE->getDecl())) { 6474 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 6475 continue; 6476 } 6477 6478 Decl *D = DE->getDecl(); 6479 VarDecl *VD = cast<VarDecl>(D); 6480 6481 QualType Type = VD->getType(); 6482 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 6483 // It will be analyzed later. 6484 Vars.push_back(DE); 6485 SrcExprs.push_back(nullptr); 6486 DstExprs.push_back(nullptr); 6487 AssignmentOps.push_back(nullptr); 6488 continue; 6489 } 6490 6491 // OpenMP [2.14.4.1, Restrictions, C/C++, p.1] 6492 // A list item that appears in a copyin clause must be threadprivate. 6493 if (!DSAStack->isThreadPrivate(VD)) { 6494 Diag(ELoc, diag::err_omp_required_access) 6495 << getOpenMPClauseName(OMPC_copyin) 6496 << getOpenMPDirectiveName(OMPD_threadprivate); 6497 continue; 6498 } 6499 6500 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 6501 // A variable of class type (or array thereof) that appears in a 6502 // copyin clause requires an accessible, unambiguous copy assignment 6503 // operator for the class type. 6504 auto ElemType = Context.getBaseElementType(Type).getNonReferenceType(); 6505 auto *SrcVD = buildVarDecl(*this, DE->getLocStart(), 6506 ElemType.getUnqualifiedType(), ".copyin.src"); 6507 auto *PseudoSrcExpr = buildDeclRefExpr( 6508 *this, SrcVD, ElemType.getUnqualifiedType(), DE->getExprLoc()); 6509 auto *DstVD = 6510 buildVarDecl(*this, DE->getLocStart(), ElemType, ".copyin.dst"); 6511 auto *PseudoDstExpr = 6512 buildDeclRefExpr(*this, DstVD, ElemType, DE->getExprLoc()); 6513 // For arrays generate assignment operation for single element and replace 6514 // it by the original array element in CodeGen. 6515 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 6516 PseudoDstExpr, PseudoSrcExpr); 6517 if (AssignmentOp.isInvalid()) 6518 continue; 6519 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 6520 /*DiscardedValue=*/true); 6521 if (AssignmentOp.isInvalid()) 6522 continue; 6523 6524 DSAStack->addDSA(VD, DE, OMPC_copyin); 6525 Vars.push_back(DE); 6526 SrcExprs.push_back(PseudoSrcExpr); 6527 DstExprs.push_back(PseudoDstExpr); 6528 AssignmentOps.push_back(AssignmentOp.get()); 6529 } 6530 6531 if (Vars.empty()) 6532 return nullptr; 6533 6534 return OMPCopyinClause::Create(Context, StartLoc, LParenLoc, EndLoc, Vars, 6535 SrcExprs, DstExprs, AssignmentOps); 6536 } 6537 6538 OMPClause *Sema::ActOnOpenMPCopyprivateClause(ArrayRef<Expr *> VarList, 6539 SourceLocation StartLoc, 6540 SourceLocation LParenLoc, 6541 SourceLocation EndLoc) { 6542 SmallVector<Expr *, 8> Vars; 6543 SmallVector<Expr *, 8> SrcExprs; 6544 SmallVector<Expr *, 8> DstExprs; 6545 SmallVector<Expr *, 8> AssignmentOps; 6546 for (auto &RefExpr : VarList) { 6547 assert(RefExpr && "NULL expr in OpenMP copyprivate clause."); 6548 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 6549 // It will be analyzed later. 6550 Vars.push_back(RefExpr); 6551 SrcExprs.push_back(nullptr); 6552 DstExprs.push_back(nullptr); 6553 AssignmentOps.push_back(nullptr); 6554 continue; 6555 } 6556 6557 SourceLocation ELoc = RefExpr->getExprLoc(); 6558 // OpenMP [2.1, C/C++] 6559 // A list item is a variable name. 6560 // OpenMP [2.14.4.1, Restrictions, p.1] 6561 // A list item that appears in a copyin clause must be threadprivate. 6562 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(RefExpr); 6563 if (!DE || !isa<VarDecl>(DE->getDecl())) { 6564 Diag(ELoc, diag::err_omp_expected_var_name) << RefExpr->getSourceRange(); 6565 continue; 6566 } 6567 6568 Decl *D = DE->getDecl(); 6569 VarDecl *VD = cast<VarDecl>(D); 6570 6571 QualType Type = VD->getType(); 6572 if (Type->isDependentType() || Type->isInstantiationDependentType()) { 6573 // It will be analyzed later. 6574 Vars.push_back(DE); 6575 SrcExprs.push_back(nullptr); 6576 DstExprs.push_back(nullptr); 6577 AssignmentOps.push_back(nullptr); 6578 continue; 6579 } 6580 6581 // OpenMP [2.14.4.2, Restrictions, p.2] 6582 // A list item that appears in a copyprivate clause may not appear in a 6583 // private or firstprivate clause on the single construct. 6584 if (!DSAStack->isThreadPrivate(VD)) { 6585 auto DVar = DSAStack->getTopDSA(VD, false); 6586 if (DVar.CKind != OMPC_unknown && DVar.CKind != OMPC_copyprivate && 6587 DVar.RefExpr) { 6588 Diag(ELoc, diag::err_omp_wrong_dsa) 6589 << getOpenMPClauseName(DVar.CKind) 6590 << getOpenMPClauseName(OMPC_copyprivate); 6591 ReportOriginalDSA(*this, DSAStack, VD, DVar); 6592 continue; 6593 } 6594 6595 // OpenMP [2.11.4.2, Restrictions, p.1] 6596 // All list items that appear in a copyprivate clause must be either 6597 // threadprivate or private in the enclosing context. 6598 if (DVar.CKind == OMPC_unknown) { 6599 DVar = DSAStack->getImplicitDSA(VD, false); 6600 if (DVar.CKind == OMPC_shared) { 6601 Diag(ELoc, diag::err_omp_required_access) 6602 << getOpenMPClauseName(OMPC_copyprivate) 6603 << "threadprivate or private in the enclosing context"; 6604 ReportOriginalDSA(*this, DSAStack, VD, DVar); 6605 continue; 6606 } 6607 } 6608 } 6609 6610 // Variably modified types are not supported. 6611 if (!Type->isAnyPointerType() && Type->isVariablyModifiedType()) { 6612 Diag(ELoc, diag::err_omp_variably_modified_type_not_supported) 6613 << getOpenMPClauseName(OMPC_copyprivate) << Type 6614 << getOpenMPDirectiveName(DSAStack->getCurrentDirective()); 6615 bool IsDecl = 6616 VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly; 6617 Diag(VD->getLocation(), 6618 IsDecl ? diag::note_previous_decl : diag::note_defined_here) 6619 << VD; 6620 continue; 6621 } 6622 6623 // OpenMP [2.14.4.1, Restrictions, C/C++, p.2] 6624 // A variable of class type (or array thereof) that appears in a 6625 // copyin clause requires an accessible, unambiguous copy assignment 6626 // operator for the class type. 6627 Type = Context.getBaseElementType(Type).getUnqualifiedType(); 6628 auto *SrcVD = 6629 buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.src"); 6630 auto *PseudoSrcExpr = 6631 buildDeclRefExpr(*this, SrcVD, Type, DE->getExprLoc()); 6632 auto *DstVD = 6633 buildVarDecl(*this, DE->getLocStart(), Type, ".copyprivate.dst"); 6634 auto *PseudoDstExpr = 6635 buildDeclRefExpr(*this, DstVD, Type, DE->getExprLoc()); 6636 auto AssignmentOp = BuildBinOp(/*S=*/nullptr, DE->getExprLoc(), BO_Assign, 6637 PseudoDstExpr, PseudoSrcExpr); 6638 if (AssignmentOp.isInvalid()) 6639 continue; 6640 AssignmentOp = ActOnFinishFullExpr(AssignmentOp.get(), DE->getExprLoc(), 6641 /*DiscardedValue=*/true); 6642 if (AssignmentOp.isInvalid()) 6643 continue; 6644 6645 // No need to mark vars as copyprivate, they are already threadprivate or 6646 // implicitly private. 6647 Vars.push_back(DE); 6648 SrcExprs.push_back(PseudoSrcExpr); 6649 DstExprs.push_back(PseudoDstExpr); 6650 AssignmentOps.push_back(AssignmentOp.get()); 6651 } 6652 6653 if (Vars.empty()) 6654 return nullptr; 6655 6656 return OMPCopyprivateClause::Create(Context, StartLoc, LParenLoc, EndLoc, 6657 Vars, SrcExprs, DstExprs, AssignmentOps); 6658 } 6659 6660 OMPClause *Sema::ActOnOpenMPFlushClause(ArrayRef<Expr *> VarList, 6661 SourceLocation StartLoc, 6662 SourceLocation LParenLoc, 6663 SourceLocation EndLoc) { 6664 if (VarList.empty()) 6665 return nullptr; 6666 6667 return OMPFlushClause::Create(Context, StartLoc, LParenLoc, EndLoc, VarList); 6668 } 6669 6670 OMPClause * 6671 Sema::ActOnOpenMPDependClause(OpenMPDependClauseKind DepKind, 6672 SourceLocation DepLoc, SourceLocation ColonLoc, 6673 ArrayRef<Expr *> VarList, SourceLocation StartLoc, 6674 SourceLocation LParenLoc, SourceLocation EndLoc) { 6675 if (DepKind == OMPC_DEPEND_unknown) { 6676 std::string Values; 6677 std::string Sep(", "); 6678 for (unsigned i = 0; i < OMPC_DEPEND_unknown; ++i) { 6679 Values += "'"; 6680 Values += getOpenMPSimpleClauseTypeName(OMPC_depend, i); 6681 Values += "'"; 6682 switch (i) { 6683 case OMPC_DEPEND_unknown - 2: 6684 Values += " or "; 6685 break; 6686 case OMPC_DEPEND_unknown - 1: 6687 break; 6688 default: 6689 Values += Sep; 6690 break; 6691 } 6692 } 6693 Diag(DepLoc, diag::err_omp_unexpected_clause_value) 6694 << Values << getOpenMPClauseName(OMPC_depend); 6695 return nullptr; 6696 } 6697 SmallVector<Expr *, 8> Vars; 6698 for (auto &RefExpr : VarList) { 6699 assert(RefExpr && "NULL expr in OpenMP shared clause."); 6700 if (isa<DependentScopeDeclRefExpr>(RefExpr)) { 6701 // It will be analyzed later. 6702 Vars.push_back(RefExpr); 6703 continue; 6704 } 6705 6706 SourceLocation ELoc = RefExpr->getExprLoc(); 6707 // OpenMP [2.11.1.1, Restrictions, p.3] 6708 // A variable that is part of another variable (such as a field of a 6709 // structure) but is not an array element or an array section cannot appear 6710 // in a depend clause. 6711 auto *SimpleExpr = RefExpr->IgnoreParenCasts(); 6712 DeclRefExpr *DE = dyn_cast<DeclRefExpr>(SimpleExpr); 6713 ArraySubscriptExpr *ASE = dyn_cast<ArraySubscriptExpr>(SimpleExpr); 6714 if (!RefExpr->IgnoreParenImpCasts()->isLValue() || (!ASE && !DE) || 6715 (DE && !isa<VarDecl>(DE->getDecl())) || 6716 (ASE && !ASE->getBase()->getType()->isAnyPointerType() && 6717 !ASE->getBase()->getType()->isArrayType())) { 6718 Diag(ELoc, diag::err_omp_expected_var_name_or_array_item) 6719 << RefExpr->getSourceRange(); 6720 continue; 6721 } 6722 6723 Vars.push_back(RefExpr->IgnoreParenImpCasts()); 6724 } 6725 6726 if (Vars.empty()) 6727 return nullptr; 6728 6729 return OMPDependClause::Create(Context, StartLoc, LParenLoc, EndLoc, DepKind, 6730 DepLoc, ColonLoc, Vars); 6731 } 6732 6733 OMPClause *Sema::ActOnOpenMPDeviceClause(Expr *Device, SourceLocation StartLoc, 6734 SourceLocation LParenLoc, 6735 SourceLocation EndLoc) { 6736 Expr *ValExpr = Device; 6737 if (!ValExpr->isTypeDependent() && !ValExpr->isValueDependent() && 6738 !ValExpr->isInstantiationDependent()) { 6739 SourceLocation Loc = ValExpr->getExprLoc(); 6740 ExprResult Value = PerformOpenMPImplicitIntegerConversion(Loc, ValExpr); 6741 if (Value.isInvalid()) 6742 return nullptr; 6743 6744 // OpenMP [2.9.1, Restrictions] 6745 // The device expression must evaluate to a non-negative integer value. 6746 llvm::APSInt Result; 6747 if (Value.get()->isIntegerConstantExpr(Result, Context) && 6748 Result.isSigned() && !Result.isStrictlyPositive()) { 6749 Diag(Loc, diag::err_omp_negative_expression_in_clause) 6750 << "device" << ValExpr->getSourceRange(); 6751 return nullptr; 6752 } 6753 } 6754 6755 return new (Context) OMPDeviceClause(ValExpr, StartLoc, LParenLoc, EndLoc); 6756 } 6757